diff options
| author | chemicstry <[email protected]> | 2023-07-31 10:29:20 +0300 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2023-07-31 10:29:20 +0300 |
| commit | 780569c08ab089dae67c5d57dd1852d5419d4577 (patch) | |
| tree | 021965b7c9ac34fb33507c3998b3a6b6e7cecae7 | |
| parent | a56ef685f3bfd9148a79c9dbbdde83a2c1642ba5 (diff) | |
| parent | 6c6bd11c1a28eb8985518a10bd723c622d82f4b6 (diff) | |
Merge remote-tracking branch 'origin/main' into bxcan_timestamp
237 files changed, 3310 insertions, 1867 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 | ||
| 14 | cargo test --manifest-path ./embassy-sync/Cargo.toml | 14 | cargo test --manifest-path ./embassy-sync/Cargo.toml |
| 15 | cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml | 15 | cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml |
| 16 | cargo test --manifest-path ./embassy-hal-common/Cargo.toml | 16 | cargo test --manifest-path ./embassy-hal-internal/Cargo.toml |
| 17 | cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue | 17 | cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue |
| 18 | 18 | ||
| 19 | cargo test --manifest-path ./embassy-boot/boot/Cargo.toml | 19 | cargo test --manifest-path ./embassy-boot/boot/Cargo.toml |
diff --git a/.vscode/settings.json b/.vscode/settings.json index 725fb69d0..29e8812e3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | // "examples/stm32f1/Cargo.toml", | 25 | // "examples/stm32f1/Cargo.toml", |
| 26 | // "examples/stm32f2/Cargo.toml", | 26 | // "examples/stm32f2/Cargo.toml", |
| 27 | // "examples/stm32f3/Cargo.toml", | 27 | // "examples/stm32f3/Cargo.toml", |
| 28 | // "examples/stm32f334/Cargo.toml", | ||
| 28 | // "examples/stm32f4/Cargo.toml", | 29 | // "examples/stm32f4/Cargo.toml", |
| 29 | // "examples/stm32f7/Cargo.toml", | 30 | // "examples/stm32f7/Cargo.toml", |
| 30 | // "examples/stm32g0/Cargo.toml", | 31 | // "examples/stm32g0/Cargo.toml", |
| @@ -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 \ |
| @@ -115,6 +117,7 @@ cargo batch \ | |||
| 115 | --- build --release --manifest-path examples/stm32f1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f1 \ | 117 | --- build --release --manifest-path examples/stm32f1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f1 \ |
| 116 | --- build --release --manifest-path examples/stm32f2/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f2 \ | 118 | --- build --release --manifest-path examples/stm32f2/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f2 \ |
| 117 | --- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f3 \ | 119 | --- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f3 \ |
| 120 | --- build --release --manifest-path examples/stm32f334/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f334 \ | ||
| 118 | --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \ | 121 | --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \ |
| 119 | --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \ | 122 | --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \ |
| 120 | --- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \ | 123 | --- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \ |
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 | ||
| 3 | Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439 | 3 | Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439 |
| 4 | 4 | ||
| 5 | Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt) \ No newline at end of file | 5 | Licensed 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; | |||
| 8 | use embassy_rp::dma::Channel; | 8 | use embassy_rp::dma::Channel; |
| 9 | use embassy_rp::gpio::{Drive, Level, Output, Pin, Pull, SlewRate}; | 9 | use embassy_rp::gpio::{Drive, Level, Output, Pin, Pull, SlewRate}; |
| 10 | use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; | 10 | use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; |
| 11 | use embassy_rp::relocate::RelocatedProgram; | ||
| 12 | use embassy_rp::{pio_instr_util, Peripheral, PeripheralRef}; | 11 | use embassy_rp::{pio_instr_util, Peripheral, PeripheralRef}; |
| 13 | use fixed::FixedU32; | 12 | use fixed::FixedU32; |
| 14 | use pio_proc::pio_asm; | 13 | use 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-boot/rp/src/lib.rs b/embassy-boot/rp/src/lib.rs index 25329f9e9..35fc104ec 100644 --- a/embassy-boot/rp/src/lib.rs +++ b/embassy-boot/rp/src/lib.rs | |||
| @@ -6,7 +6,7 @@ mod fmt; | |||
| 6 | #[cfg(feature = "nightly")] | 6 | #[cfg(feature = "nightly")] |
| 7 | pub use embassy_boot::FirmwareUpdater; | 7 | pub use embassy_boot::FirmwareUpdater; |
| 8 | pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State}; | 8 | pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State}; |
| 9 | use embassy_rp::flash::{Flash, ERASE_SIZE}; | 9 | use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE}; |
| 10 | use embassy_rp::peripherals::{FLASH, WATCHDOG}; | 10 | use embassy_rp::peripherals::{FLASH, WATCHDOG}; |
| 11 | use embassy_rp::watchdog::Watchdog; | 11 | use embassy_rp::watchdog::Watchdog; |
| 12 | use embassy_time::Duration; | 12 | use embassy_time::Duration; |
| @@ -58,14 +58,14 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize> | |||
| 58 | 58 | ||
| 59 | /// A flash implementation that will feed a watchdog when touching flash. | 59 | /// A flash implementation that will feed a watchdog when touching flash. |
| 60 | pub struct WatchdogFlash<'d, const SIZE: usize> { | 60 | pub struct WatchdogFlash<'d, const SIZE: usize> { |
| 61 | flash: Flash<'d, FLASH, SIZE>, | 61 | flash: Flash<'d, FLASH, Blocking, SIZE>, |
| 62 | watchdog: Watchdog, | 62 | watchdog: Watchdog, |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { | 65 | impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { |
| 66 | /// Start a new watchdog with a given flash and watchdog peripheral and a timeout | 66 | /// Start a new watchdog with a given flash and watchdog peripheral and a timeout |
| 67 | pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self { | 67 | pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self { |
| 68 | let flash: Flash<'_, FLASH, SIZE> = Flash::new(flash); | 68 | let flash = Flash::<_, Blocking, SIZE>::new(flash); |
| 69 | let mut watchdog = Watchdog::new(watchdog); | 69 | let mut watchdog = Watchdog::new(watchdog); |
| 70 | watchdog.start(timeout); | 70 | watchdog.start(timeout); |
| 71 | Self { flash, watchdog } | 71 | Self { flash, watchdog } |
| @@ -73,12 +73,12 @@ impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | impl<'d, const SIZE: usize> ErrorType for WatchdogFlash<'d, SIZE> { | 75 | impl<'d, const SIZE: usize> ErrorType for WatchdogFlash<'d, SIZE> { |
| 76 | type Error = <Flash<'d, FLASH, SIZE> as ErrorType>::Error; | 76 | type Error = <Flash<'d, FLASH, Blocking, SIZE> as ErrorType>::Error; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> { | 79 | impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> { |
| 80 | const WRITE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::WRITE_SIZE; | 80 | const WRITE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::WRITE_SIZE; |
| 81 | const ERASE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::ERASE_SIZE; | 81 | const ERASE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::ERASE_SIZE; |
| 82 | 82 | ||
| 83 | fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { | 83 | fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { |
| 84 | self.watchdog.feed(); | 84 | self.watchdog.feed(); |
| @@ -91,7 +91,7 @@ impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | impl<'d, const SIZE: usize> ReadNorFlash for WatchdogFlash<'d, SIZE> { | 93 | impl<'d, const SIZE: usize> ReadNorFlash for WatchdogFlash<'d, SIZE> { |
| 94 | const READ_SIZE: usize = <Flash<'d, FLASH, SIZE> as ReadNorFlash>::READ_SIZE; | 94 | const READ_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as ReadNorFlash>::READ_SIZE; |
| 95 | fn read(&mut self, offset: u32, data: &mut [u8]) -> Result<(), Self::Error> { | 95 | fn read(&mut self, offset: u32, data: &mut [u8]) -> Result<(), Self::Error> { |
| 96 | self.watchdog.feed(); | 96 | self.watchdog.feed(); |
| 97 | self.flash.read(offset, data) | 97 | self.flash.read(offset, data) |
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] |
| 2 | name = "embassy-hal-common" | 2 | name = "embassy-hal-internal" |
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2021" | 4 | edition = "2021" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "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 | |||
| 3 | An [Embassy](https://embassy.dev) project. | ||
| 4 | |||
| 5 | Internal implementation details for Embassy HALs. DO NOT USE DIRECTLY. Embassy HALs (`embassy-nrf`, `embassy-stm32`, `embassy-rp`) already reexport | ||
| 6 | everything you need to use them effectively. | ||
| 7 | |||
| 8 | ## License | ||
| 9 | |||
| 10 | This 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 | |||
| 16 | at 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. |
| 5 | pub(crate) mod fmt; | 6 | pub(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] |
| 14 | stm32wl = ["dep:embassy-stm32"] | 14 | stm32wl = ["dep:embassy-stm32"] |
| 15 | time = [] | 15 | time = ["embassy-time", "lorawan-device"] |
| 16 | defmt = ["dep:defmt", "lorawan-device/defmt"] | 16 | defmt = ["dep:defmt", "lorawan-device/defmt"] |
| 17 | 17 | ||
| 18 | [dependencies] | 18 | [dependencies] |
| @@ -20,18 +20,12 @@ defmt = ["dep:defmt", "lorawan-device/defmt"] | |||
| 20 | defmt = { version = "0.3", optional = true } | 20 | defmt = { version = "0.3", optional = true } |
| 21 | log = { version = "0.4.14", optional = true } | 21 | log = { version = "0.4.14", optional = true } |
| 22 | 22 | ||
| 23 | embassy-time = { version = "0.1.2", path = "../embassy-time" } | 23 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } |
| 24 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 24 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 25 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } | 25 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } |
| 26 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } | ||
| 27 | embedded-hal-async = { version = "=0.2.0-alpha.2" } | 26 | embedded-hal-async = { version = "=0.2.0-alpha.2" } |
| 28 | embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false } | ||
| 29 | futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } | ||
| 30 | embedded-hal = { version = "0.2", features = ["unproven"] } | 27 | embedded-hal = { version = "0.2", features = ["unproven"] } |
| 31 | bit_field = { version = "0.10" } | ||
| 32 | 28 | ||
| 29 | futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] } | ||
| 33 | lora-phy = { version = "1" } | 30 | lora-phy = { version = "1" } |
| 34 | lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] } | 31 | lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true } |
| 35 | |||
| 36 | [patch.crates-io] | ||
| 37 | lora-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 @@ | |||
| 1 | use ch::driver::LinkState; | 1 | use ch::driver::LinkState; |
| 2 | use defmt::Debug2Format; | ||
| 3 | use embassy_net_driver_channel as ch; | 2 | use embassy_net_driver_channel as ch; |
| 4 | use heapless::String; | 3 | use 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; | |||
| 32 | use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; | 32 | use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; |
| 33 | #[cfg(feature = "dhcpv4")] | 33 | #[cfg(feature = "dhcpv4")] |
| 34 | use smoltcp::socket::dhcpv4::{self, RetryConfig}; | 34 | use smoltcp::socket::dhcpv4::{self, RetryConfig}; |
| 35 | #[cfg(feature = "medium-ethernet")] | ||
| 36 | pub use smoltcp::wire::EthernetAddress; | ||
| 37 | #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] | ||
| 38 | pub use smoltcp::wire::HardwareAddress; | ||
| 35 | #[cfg(feature = "udp")] | 39 | #[cfg(feature = "udp")] |
| 36 | pub use smoltcp::wire::IpListenEndpoint; | 40 | pub use smoltcp::wire::IpListenEndpoint; |
| 37 | #[cfg(feature = "medium-ethernet")] | ||
| 38 | pub use smoltcp::wire::{EthernetAddress, HardwareAddress}; | ||
| 39 | #[cfg(feature = "medium-ieee802154")] | 41 | #[cfg(feature = "medium-ieee802154")] |
| 40 | pub use smoltcp::wire::{HardwareAddress, Ieee802154Address}; | 42 | pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame}; |
| 41 | pub use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint}; | 43 | pub use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint}; |
| 42 | #[cfg(feature = "proto-ipv4")] | 44 | #[cfg(feature = "proto-ipv4")] |
| 43 | pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; | 45 | pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; |
| @@ -583,7 +585,7 @@ impl SocketStack { | |||
| 583 | impl<D: Driver + 'static> Inner<D> { | 585 | impl<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] |
| 94 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } | 94 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } |
| 95 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 95 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 96 | embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-3"] } | 96 | embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } |
| 97 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } | 97 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } |
| 98 | embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true } | 98 | embassy-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; | |||
| 15 | use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; | 15 | use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; |
| 16 | use core::task::Poll; | 16 | use core::task::Poll; |
| 17 | 17 | ||
| 18 | use embassy_hal_common::atomic_ring_buffer::RingBuffer; | 18 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 19 | use embassy_hal_common::{into_ref, PeripheralRef}; | 19 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 20 | use embassy_sync::waitqueue::AtomicWaker; | 20 | use 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 |
| 22 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 22 | pub 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 | ||
| 9 | pub const RESET_PIN: u32 = 21; | 9 | pub const RESET_PIN: u32 = 21; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_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); | |||
| 208 | impl_saadc_input!(P0_04, ANALOG_INPUT2); | 208 | impl_saadc_input!(P0_04, ANALOG_INPUT2); |
| 209 | impl_saadc_input!(P0_05, ANALOG_INPUT3); | 209 | impl_saadc_input!(P0_05, ANALOG_INPUT3); |
| 210 | 210 | ||
| 211 | embassy_hal_common::interrupt_mod!( | 211 | embassy_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 | ||
| 9 | pub const RESET_PIN: u32 = 21; | 9 | pub const RESET_PIN: u32 = 21; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_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); | |||
| 234 | impl_saadc_input!(P0_30, ANALOG_INPUT6); | 234 | impl_saadc_input!(P0_30, ANALOG_INPUT6); |
| 235 | impl_saadc_input!(P0_31, ANALOG_INPUT7); | 235 | impl_saadc_input!(P0_31, ANALOG_INPUT7); |
| 236 | 236 | ||
| 237 | embassy_hal_common::interrupt_mod!( | 237 | embassy_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 | ||
| 9 | pub const RESET_PIN: u32 = 21; | 9 | pub const RESET_PIN: u32 = 21; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_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); | |||
| 236 | impl_saadc_input!(P0_30, ANALOG_INPUT6); | 236 | impl_saadc_input!(P0_30, ANALOG_INPUT6); |
| 237 | impl_saadc_input!(P0_31, ANALOG_INPUT7); | 237 | impl_saadc_input!(P0_31, ANALOG_INPUT7); |
| 238 | 238 | ||
| 239 | embassy_hal_common::interrupt_mod!( | 239 | embassy_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 | ||
| 9 | pub const RESET_PIN: u32 = 18; | 9 | pub const RESET_PIN: u32 = 18; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_hal_internal::peripherals! { |
| 12 | // USB | 12 | // USB |
| 13 | USBD, | 13 | USBD, |
| 14 | 14 | ||
| @@ -224,7 +224,7 @@ impl_ppi_channel!(PPI_CH29, 29 => static); | |||
| 224 | impl_ppi_channel!(PPI_CH30, 30 => static); | 224 | impl_ppi_channel!(PPI_CH30, 30 => static); |
| 225 | impl_ppi_channel!(PPI_CH31, 31 => static); | 225 | impl_ppi_channel!(PPI_CH31, 31 => static); |
| 226 | 226 | ||
| 227 | embassy_hal_common::interrupt_mod!( | 227 | embassy_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 | ||
| 13 | pub const RESET_PIN: u32 = 21; | 13 | pub const RESET_PIN: u32 = 21; |
| 14 | 14 | ||
| 15 | embassy_hal_common::peripherals! { | 15 | embassy_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 | ||
| 264 | impl_i2s!(I2S, I2S, I2S); | 264 | impl_i2s!(I2S, I2S, I2S); |
| 265 | 265 | ||
| 266 | embassy_hal_common::interrupt_mod!( | 266 | embassy_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 | ||
| 9 | pub const RESET_PIN: u32 = 18; | 9 | pub const RESET_PIN: u32 = 18; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_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 | ||
| 307 | impl_i2s!(I2S, I2S, I2S); | 307 | impl_i2s!(I2S, I2S, I2S); |
| 308 | 308 | ||
| 309 | embassy_hal_common::interrupt_mod!( | 309 | embassy_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 | ||
| 9 | pub const RESET_PIN: u32 = 18; | 9 | pub const RESET_PIN: u32 = 18; |
| 10 | 10 | ||
| 11 | embassy_hal_common::peripherals! { | 11 | embassy_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 | ||
| 312 | impl_i2s!(I2S, I2S, I2S); | 312 | impl_i2s!(I2S, I2S, I2S); |
| 313 | 313 | ||
| 314 | embassy_hal_common::interrupt_mod!( | 314 | embassy_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 | ||
| 219 | pub const FLASH_SIZE: usize = 1024 * 1024; | 219 | pub const FLASH_SIZE: usize = 1024 * 1024; |
| 220 | 220 | ||
| 221 | embassy_hal_common::peripherals! { | 221 | embassy_hal_internal::peripherals! { |
| 222 | // USB | 222 | // USB |
| 223 | USBD, | 223 | USBD, |
| 224 | 224 | ||
| @@ -506,7 +506,7 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5); | |||
| 506 | impl_saadc_input!(P0_19, ANALOG_INPUT6); | 506 | impl_saadc_input!(P0_19, ANALOG_INPUT6); |
| 507 | impl_saadc_input!(P0_20, ANALOG_INPUT7); | 507 | impl_saadc_input!(P0_20, ANALOG_INPUT7); |
| 508 | 508 | ||
| 509 | embassy_hal_common::interrupt_mod!( | 509 | embassy_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 | ||
| 110 | pub const FLASH_SIZE: usize = 256 * 1024; | 110 | pub const FLASH_SIZE: usize = 256 * 1024; |
| 111 | 111 | ||
| 112 | embassy_hal_common::peripherals! { | 112 | embassy_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); | |||
| 342 | impl_ppi_channel!(PPI_CH30, 30 => configurable); | 342 | impl_ppi_channel!(PPI_CH30, 30 => configurable); |
| 343 | impl_ppi_channel!(PPI_CH31, 31 => configurable); | 343 | impl_ppi_channel!(PPI_CH31, 31 => configurable); |
| 344 | 344 | ||
| 345 | embassy_hal_common::interrupt_mod!( | 345 | embassy_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 | ||
| 170 | pub const FLASH_SIZE: usize = 1024 * 1024; | 170 | pub const FLASH_SIZE: usize = 1024 * 1024; |
| 171 | 171 | ||
| 172 | embassy_hal_common::peripherals! { | 172 | embassy_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); | |||
| 368 | impl_saadc_input!(P0_19, ANALOG_INPUT6); | 368 | impl_saadc_input!(P0_19, ANALOG_INPUT6); |
| 369 | impl_saadc_input!(P0_20, ANALOG_INPUT7); | 369 | impl_saadc_input!(P0_20, ANALOG_INPUT7); |
| 370 | 370 | ||
| 371 | embassy_hal_common::interrupt_mod!( | 371 | embassy_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; | |||
| 5 | use core::hint::unreachable_unchecked; | 5 | use core::hint::unreachable_unchecked; |
| 6 | 6 | ||
| 7 | use cfg_if::cfg_if; | 7 | use cfg_if::cfg_if; |
| 8 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 9 | 9 | ||
| 10 | use self::sealed::Pin as _; | 10 | use self::sealed::Pin as _; |
| 11 | use crate::pac::p0 as gpio; | 11 | use 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; | |||
| 4 | use core::future::{poll_fn, Future}; | 4 | use core::future::{poll_fn, Future}; |
| 5 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 6 | 6 | ||
| 7 | use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; | 7 | use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 9 | ||
| 10 | use crate::gpio::sealed::Pin as _; | 10 | use 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}; | |||
| 9 | use core::sync::atomic::{compiler_fence, Ordering}; | 9 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 10 | use core::task::Poll; | 10 | use core::task::Poll; |
| 11 | 11 | ||
| 12 | use embassy_hal_common::drop::OnDrop; | 12 | use embassy_hal_internal::drop::OnDrop; |
| 13 | use embassy_hal_common::{into_ref, PeripheralRef}; | 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 14 | 14 | ||
| 15 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 15 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 16 | use crate::interrupt::typelevel::Interrupt; | 16 | use 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] |
| 103 | macro_rules! bind_interrupts { | 103 | macro_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"))] |
| 128 | pub(crate) use chip::pac; | 128 | pub(crate) use chip::pac; |
| 129 | pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; | 129 | pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; |
| 130 | pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 130 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 131 | 131 | ||
| 132 | pub use crate::chip::interrupt; | 132 | pub use crate::chip::interrupt; |
| 133 | pub use crate::pac::NVIC_PRIO_BITS; | 133 | pub 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 | ||
| 3 | use core::{ptr, slice}; | 3 | use core::{ptr, slice}; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use embedded_storage::nor_flash::{ | 6 | use 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; | |||
| 6 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 11 | use fixed::types::I7F1; | 11 | use fixed::types::I7F1; |
| 12 | use futures::future::poll_fn; | 12 | use 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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | 2 | ||
| 3 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 3 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 4 | use crate::{pac, Peripheral}; | 4 | use 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 @@ | |||
| 18 | use core::marker::PhantomData; | 18 | use core::marker::PhantomData; |
| 19 | use core::ptr::NonNull; | 19 | use core::ptr::NonNull; |
| 20 | 20 | ||
| 21 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 21 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 22 | 22 | ||
| 23 | use crate::{peripherals, Peripheral}; | 23 | use 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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | 2 | ||
| 3 | use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; | 3 | use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; |
| 4 | use crate::{pac, Peripheral}; | 4 | use 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 | ||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 6 | 6 | ||
| 7 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | 8 | ||
| 9 | use crate::gpio::sealed::Pin as _; | 9 | use crate::gpio::sealed::Pin as _; |
| 10 | use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; | 10 | use 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; | |||
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | 10 | ||
| 11 | use crate::gpio::sealed::Pin as _; | 11 | use crate::gpio::sealed::Pin as _; |
| 12 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 12 | use 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; | |||
| 7 | use core::ptr; | 7 | use core::ptr; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use embassy_hal_common::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| 11 | use embassy_hal_common::{into_ref, PeripheralRef}; | 11 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 12 | use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; | 12 | use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; |
| 13 | 13 | ||
| 14 | use crate::gpio::{self, Pin as GpioPin}; | 14 | use 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; | |||
| 8 | use core::sync::atomic::{AtomicPtr, Ordering}; | 8 | use core::sync::atomic::{AtomicPtr, Ordering}; |
| 9 | use core::task::Poll; | 9 | use core::task::Poll; |
| 10 | 10 | ||
| 11 | use embassy_hal_common::drop::OnDrop; | 11 | use embassy_hal_internal::drop::OnDrop; |
| 12 | use embassy_hal_common::{into_ref, PeripheralRef}; | 12 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 13 | use embassy_sync::waitqueue::AtomicWaker; | 13 | use embassy_sync::waitqueue::AtomicWaker; |
| 14 | 14 | ||
| 15 | use crate::interrupt::typelevel::Interrupt; | 15 | use 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; | |||
| 6 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 10 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | use pac::{saadc, SAADC}; | 12 | use pac::{saadc, SAADC}; |
| 13 | use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; | 13 | use 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}; | |||
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use embassy_embedded_hal::SetConfig; | 10 | use embassy_embedded_hal::SetConfig; |
| 11 | use embassy_hal_common::{into_ref, PeripheralRef}; | 11 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 12 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 12 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 13 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; | 13 | pub 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}; | |||
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_embedded_hal::SetConfig; | 9 | use embassy_embedded_hal::SetConfig; |
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 11 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 11 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 12 | 12 | ||
| 13 | use crate::chip::FORCE_COPY_BUFFER_SIZE; | 13 | use 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 @@ | |||
| 3 | use core::future::poll_fn; | 3 | use core::future::poll_fn; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::drop::OnDrop; | 6 | use embassy_hal_internal::drop::OnDrop; |
| 7 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | use fixed::types::I30F2; | 9 | use 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 | ||
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | 10 | ||
| 11 | use crate::ppi::{Event, Task}; | 11 | use crate::ppi::{Event, Task}; |
| 12 | use crate::{pac, Peripheral}; | 12 | use 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; | |||
| 9 | use core::task::Poll; | 9 | use core::task::Poll; |
| 10 | 10 | ||
| 11 | use embassy_embedded_hal::SetConfig; | 11 | use embassy_embedded_hal::SetConfig; |
| 12 | use embassy_hal_common::{into_ref, PeripheralRef}; | 12 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 13 | use embassy_sync::waitqueue::AtomicWaker; | 13 | use embassy_sync::waitqueue::AtomicWaker; |
| 14 | #[cfg(feature = "time")] | 14 | #[cfg(feature = "time")] |
| 15 | use embassy_time::{Duration, Instant}; | 15 | use 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; | |||
| 8 | use core::sync::atomic::Ordering::SeqCst; | 8 | use core::sync::atomic::Ordering::SeqCst; |
| 9 | use core::task::Poll; | 9 | use core::task::Poll; |
| 10 | 10 | ||
| 11 | use embassy_hal_common::{into_ref, PeripheralRef}; | 11 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 13 | #[cfg(feature = "time")] | 13 | #[cfg(feature = "time")] |
| 14 | use embassy_time::{Duration, Instant}; | 14 | use 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; | |||
| 18 | use core::sync::atomic::{compiler_fence, Ordering}; | 18 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 19 | use core::task::Poll; | 19 | use core::task::Poll; |
| 20 | 20 | ||
| 21 | use embassy_hal_common::drop::OnDrop; | 21 | use embassy_hal_internal::drop::OnDrop; |
| 22 | use embassy_hal_common::{into_ref, PeripheralRef}; | 22 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 23 | use pac::uarte0::RegisterBlock; | 23 | use 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. |
| 25 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 25 | pub 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}; | |||
| 11 | use core::task::Poll; | 11 | use core::task::Poll; |
| 12 | 12 | ||
| 13 | use cortex_m::peripheral::NVIC; | 13 | use cortex_m::peripheral::NVIC; |
| 14 | use embassy_hal_common::{into_ref, PeripheralRef}; | 14 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 15 | use embassy_sync::waitqueue::AtomicWaker; | 15 | use embassy_sync::waitqueue::AtomicWaker; |
| 16 | use embassy_usb_driver as driver; | 16 | use embassy_usb_driver as driver; |
| 17 | use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; | 17 | use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; |
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 8f3ed885d..6310ffb62 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -16,7 +16,7 @@ flavors = [ | |||
| 16 | default = [ "rt" ] | 16 | default = [ "rt" ] |
| 17 | rt = [ "rp-pac/rt" ] | 17 | rt = [ "rp-pac/rt" ] |
| 18 | 18 | ||
| 19 | defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"] | 19 | defmt = ["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 |
| 22 | critical-section-impl = ["critical-section/restore-state-u8"] | 22 | critical-section-impl = ["critical-section/restore-state-u8"] |
| @@ -48,7 +48,7 @@ boot2-w25x10cl = [] | |||
| 48 | run-from-ram = [] | 48 | run-from-ram = [] |
| 49 | 49 | ||
| 50 | # Enable nightly-only features | 50 | # Enable nightly-only features |
| 51 | nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] | 51 | nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] |
| 52 | 52 | ||
| 53 | # Implement embedded-hal 1.0 alpha traits. | 53 | # Implement embedded-hal 1.0 alpha traits. |
| 54 | # Implement embedded-hal-async traits if `nightly` is set as well. | 54 | # Implement embedded-hal-async traits if `nightly` is set as well. |
| @@ -58,7 +58,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"] | |||
| 58 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 58 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 59 | embassy-time = { version = "0.1.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } | 59 | embassy-time = { version = "0.1.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } |
| 60 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } | 60 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } |
| 61 | embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-2"] } | 61 | embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } |
| 62 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } | 62 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } |
| 63 | embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } | 63 | embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } |
| 64 | atomic-polyfill = "1.0.1" | 64 | atomic-polyfill = "1.0.1" |
| @@ -73,6 +73,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa | |||
| 73 | chrono = { version = "0.4", default-features = false, optional = true } | 73 | chrono = { version = "0.4", default-features = false, optional = true } |
| 74 | embedded-io = { version = "0.4.0", features = ["async"], optional = true } | 74 | embedded-io = { version = "0.4.0", features = ["async"], optional = true } |
| 75 | embedded-storage = { version = "0.3" } | 75 | embedded-storage = { version = "0.3" } |
| 76 | embedded-storage-async = { version = "0.4.0", optional = true } | ||
| 76 | rand_core = "0.6.4" | 77 | rand_core = "0.6.4" |
| 77 | fixed = "1.23.1" | 78 | fixed = "1.23.1" |
| 78 | 79 | ||
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; | |||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 8 | ||
| 9 | use crate::gpio::sealed::Pin as GpioPin; | 9 | use 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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | use core::sync::atomic::{AtomicU16, AtomicU32, Ordering}; | 2 | use core::sync::atomic::{AtomicU16, AtomicU32, Ordering}; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::{into_ref, PeripheralRef}; | 4 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 5 | use pac::clocks::vals::*; | 5 | use pac::clocks::vals::*; |
| 6 | 6 | ||
| 7 | use crate::gpio::sealed::Pin; | 7 | use 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; | |||
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 6 | 6 | ||
| 7 | use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; | 7 | use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | use pac::dma::vals::DataSize; | 9 | use pac::dma::vals::DataSize; |
| 10 | 10 | ||
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 96d2d4541..70d867319 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | use core::future::Future; | ||
| 1 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::pin::Pin; | ||
| 4 | use core::task::{Context, Poll}; | ||
| 2 | 5 | ||
| 3 | use embassy_hal_common::Peripheral; | 6 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 4 | use embedded_storage::nor_flash::{ | 7 | use embedded_storage::nor_flash::{ |
| 5 | check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, | 8 | check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, |
| 6 | ReadNorFlash, | 9 | ReadNorFlash, |
| 7 | }; | 10 | }; |
| 8 | 11 | ||
| 12 | use crate::dma::{AnyChannel, Channel, Transfer}; | ||
| 9 | use crate::pac; | 13 | use crate::pac; |
| 10 | use crate::peripherals::FLASH; | 14 | use crate::peripherals::FLASH; |
| 11 | 15 | ||
| @@ -24,6 +28,7 @@ pub const PAGE_SIZE: usize = 256; | |||
| 24 | pub const WRITE_SIZE: usize = 1; | 28 | pub const WRITE_SIZE: usize = 1; |
| 25 | pub const READ_SIZE: usize = 1; | 29 | pub const READ_SIZE: usize = 1; |
| 26 | pub const ERASE_SIZE: usize = 4096; | 30 | pub const ERASE_SIZE: usize = 4096; |
| 31 | pub const ASYNC_READ_SIZE: usize = 4; | ||
| 27 | 32 | ||
| 28 | /// Error type for NVMC operations. | 33 | /// Error type for NVMC operations. |
| 29 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] | 34 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
| @@ -57,13 +62,46 @@ impl NorFlashError for Error { | |||
| 57 | } | 62 | } |
| 58 | } | 63 | } |
| 59 | 64 | ||
| 60 | pub struct Flash<'d, T: Instance, const FLASH_SIZE: usize>(PhantomData<&'d mut T>); | 65 | /// Future that waits for completion of a background read |
| 66 | #[must_use = "futures do nothing unless you `.await` or poll them"] | ||
| 67 | pub struct BackgroundRead<'a, 'd, T: Instance, const FLASH_SIZE: usize> { | ||
| 68 | flash: PhantomData<&'a mut Flash<'d, T, Async, FLASH_SIZE>>, | ||
| 69 | transfer: Transfer<'a, AnyChannel>, | ||
| 70 | } | ||
| 61 | 71 | ||
| 62 | impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | 72 | impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Future for BackgroundRead<'a, 'd, T, FLASH_SIZE> { |
| 63 | pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self { | 73 | type Output = (); |
| 64 | Self(PhantomData) | 74 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 75 | Pin::new(&mut self.transfer).poll(cx) | ||
| 65 | } | 76 | } |
| 77 | } | ||
| 66 | 78 | ||
| 79 | impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, 'd, T, FLASH_SIZE> { | ||
| 80 | fn drop(&mut self) { | ||
| 81 | if pac::XIP_CTRL.stream_ctr().read().0 == 0 { | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | pac::XIP_CTRL | ||
| 85 | .stream_ctr() | ||
| 86 | .write_value(pac::xip_ctrl::regs::StreamCtr(0)); | ||
| 87 | core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); | ||
| 88 | // Errata RP2040-E8: Perform an uncached read to make sure there's not a transfer in | ||
| 89 | // flight that might effect an address written to start a new transfer. This stalls | ||
| 90 | // until after any transfer is complete, so the address will not change anymore. | ||
| 91 | const XIP_NOCACHE_NOALLOC_BASE: *const u32 = 0x13000000 as *const _; | ||
| 92 | unsafe { | ||
| 93 | core::ptr::read_volatile(XIP_NOCACHE_NOALLOC_BASE); | ||
| 94 | } | ||
| 95 | core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> { | ||
| 100 | dma: Option<PeripheralRef<'d, AnyChannel>>, | ||
| 101 | phantom: PhantomData<(&'d mut T, M)>, | ||
| 102 | } | ||
| 103 | |||
| 104 | impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SIZE> { | ||
| 67 | pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 105 | pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 68 | trace!( | 106 | trace!( |
| 69 | "Reading from 0x{:x} to 0x{:x}", | 107 | "Reading from 0x{:x} to 0x{:x}", |
| @@ -182,6 +220,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 182 | let ch = crate::pac::DMA.ch(n); | 220 | let ch = crate::pac::DMA.ch(n); |
| 183 | while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {} | 221 | while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {} |
| 184 | } | 222 | } |
| 223 | // Wait for completion of any background reads | ||
| 224 | while pac::XIP_CTRL.stream_ctr().read().0 > 0 {} | ||
| 185 | 225 | ||
| 186 | // Run our flash operation in RAM | 226 | // Run our flash operation in RAM |
| 187 | operation(); | 227 | operation(); |
| @@ -210,11 +250,73 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 210 | } | 250 | } |
| 211 | } | 251 | } |
| 212 | 252 | ||
| 213 | impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> { | 253 | impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> { |
| 254 | pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self { | ||
| 255 | Self { | ||
| 256 | dma: None, | ||
| 257 | phantom: PhantomData, | ||
| 258 | } | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { | ||
| 263 | pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self { | ||
| 264 | into_ref!(dma); | ||
| 265 | Self { | ||
| 266 | dma: Some(dma.map_into()), | ||
| 267 | phantom: PhantomData, | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | pub fn background_read<'a>( | ||
| 272 | &'a mut self, | ||
| 273 | offset: u32, | ||
| 274 | data: &'a mut [u32], | ||
| 275 | ) -> Result<BackgroundRead<'a, 'd, T, FLASH_SIZE>, Error> { | ||
| 276 | trace!( | ||
| 277 | "Reading in background from 0x{:x} to 0x{:x}", | ||
| 278 | FLASH_BASE as u32 + offset, | ||
| 279 | FLASH_BASE as u32 + offset + (data.len() * 4) as u32 | ||
| 280 | ); | ||
| 281 | // Can't use check_read because we need to enforce 4-byte alignment | ||
| 282 | let offset = offset as usize; | ||
| 283 | let length = data.len() * 4; | ||
| 284 | if length > self.capacity() || offset > self.capacity() - length { | ||
| 285 | return Err(Error::OutOfBounds); | ||
| 286 | } | ||
| 287 | if offset % 4 != 0 { | ||
| 288 | return Err(Error::Unaligned); | ||
| 289 | } | ||
| 290 | |||
| 291 | while !pac::XIP_CTRL.stat().read().fifo_empty() { | ||
| 292 | pac::XIP_CTRL.stream_fifo().read(); | ||
| 293 | } | ||
| 294 | |||
| 295 | pac::XIP_CTRL | ||
| 296 | .stream_addr() | ||
| 297 | .write_value(pac::xip_ctrl::regs::StreamAddr(FLASH_BASE as u32 + offset as u32)); | ||
| 298 | pac::XIP_CTRL | ||
| 299 | .stream_ctr() | ||
| 300 | .write_value(pac::xip_ctrl::regs::StreamCtr(data.len() as u32)); | ||
| 301 | |||
| 302 | // Use the XIP AUX bus port, rather than the FIFO register access (e.x. | ||
| 303 | // pac::XIP_CTRL.stream_fifo().as_ptr()) to avoid DMA stalling on | ||
| 304 | // general XIP access. | ||
| 305 | const XIP_AUX_BASE: *const u32 = 0x50400000 as *const _; | ||
| 306 | let transfer = unsafe { crate::dma::read(self.dma.as_mut().unwrap(), XIP_AUX_BASE, data, 37) }; | ||
| 307 | |||
| 308 | Ok(BackgroundRead { | ||
| 309 | flash: PhantomData, | ||
| 310 | transfer, | ||
| 311 | }) | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, M, FLASH_SIZE> { | ||
| 214 | type Error = Error; | 316 | type Error = Error; |
| 215 | } | 317 | } |
| 216 | 318 | ||
| 217 | impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> { | 319 | impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, M, FLASH_SIZE> { |
| 218 | const READ_SIZE: usize = READ_SIZE; | 320 | const READ_SIZE: usize = READ_SIZE; |
| 219 | 321 | ||
| 220 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | 322 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -226,9 +328,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLA | |||
| 226 | } | 328 | } |
| 227 | } | 329 | } |
| 228 | 330 | ||
| 229 | impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {} | 331 | impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, M, FLASH_SIZE> {} |
| 230 | 332 | ||
| 231 | impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> { | 333 | impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, M, FLASH_SIZE> { |
| 232 | const WRITE_SIZE: usize = WRITE_SIZE; | 334 | const WRITE_SIZE: usize = WRITE_SIZE; |
| 233 | 335 | ||
| 234 | const ERASE_SIZE: usize = ERASE_SIZE; | 336 | const ERASE_SIZE: usize = ERASE_SIZE; |
| @@ -242,6 +344,74 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S | |||
| 242 | } | 344 | } |
| 243 | } | 345 | } |
| 244 | 346 | ||
| 347 | #[cfg(feature = "nightly")] | ||
| 348 | impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::ReadNorFlash | ||
| 349 | for Flash<'d, T, Async, FLASH_SIZE> | ||
| 350 | { | ||
| 351 | const READ_SIZE: usize = ASYNC_READ_SIZE; | ||
| 352 | |||
| 353 | async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | ||
| 354 | use core::mem::MaybeUninit; | ||
| 355 | |||
| 356 | // Checked early to simplify address validity checks | ||
| 357 | if bytes.len() % 4 != 0 { | ||
| 358 | return Err(Error::Unaligned); | ||
| 359 | } | ||
| 360 | |||
| 361 | // If the destination address is already aligned, then we can just DMA directly | ||
| 362 | if (bytes.as_ptr() as u32) % 4 == 0 { | ||
| 363 | // Safety: alignment and size have been checked for compatibility | ||
| 364 | let mut buf: &mut [u32] = | ||
| 365 | unsafe { core::slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut u32, bytes.len() / 4) }; | ||
| 366 | self.background_read(offset, &mut buf)?.await; | ||
| 367 | return Ok(()); | ||
| 368 | } | ||
| 369 | |||
| 370 | // Destination address is unaligned, so use an intermediate buffer | ||
| 371 | const REALIGN_CHUNK: usize = PAGE_SIZE; | ||
| 372 | // Safety: MaybeUninit requires no initialization | ||
| 373 | let mut buf: [MaybeUninit<u32>; REALIGN_CHUNK / 4] = unsafe { MaybeUninit::uninit().assume_init() }; | ||
| 374 | let mut chunk_offset: usize = 0; | ||
| 375 | while chunk_offset < bytes.len() { | ||
| 376 | let chunk_size = (bytes.len() - chunk_offset).min(REALIGN_CHUNK); | ||
| 377 | let buf = &mut buf[..(chunk_size / 4)]; | ||
| 378 | |||
| 379 | // Safety: this is written to completely by DMA before any reads | ||
| 380 | let buf = unsafe { &mut *(buf as *mut [MaybeUninit<u32>] as *mut [u32]) }; | ||
| 381 | self.background_read(offset + chunk_offset as u32, buf)?.await; | ||
| 382 | |||
| 383 | // Safety: [u8] has more relaxed alignment and size requirements than [u32], so this is just aliasing | ||
| 384 | let buf = unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const _, buf.len() * 4) }; | ||
| 385 | bytes[chunk_offset..(chunk_offset + chunk_size)].copy_from_slice(&buf[..chunk_size]); | ||
| 386 | |||
| 387 | chunk_offset += chunk_size; | ||
| 388 | } | ||
| 389 | |||
| 390 | Ok(()) | ||
| 391 | } | ||
| 392 | |||
| 393 | fn capacity(&self) -> usize { | ||
| 394 | self.capacity() | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | #[cfg(feature = "nightly")] | ||
| 399 | impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::NorFlash | ||
| 400 | for Flash<'d, T, Async, FLASH_SIZE> | ||
| 401 | { | ||
| 402 | const WRITE_SIZE: usize = WRITE_SIZE; | ||
| 403 | |||
| 404 | const ERASE_SIZE: usize = ERASE_SIZE; | ||
| 405 | |||
| 406 | async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { | ||
| 407 | self.erase(from, to) | ||
| 408 | } | ||
| 409 | |||
| 410 | async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { | ||
| 411 | self.write(offset, bytes) | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 245 | #[allow(dead_code)] | 415 | #[allow(dead_code)] |
| 246 | mod ram_helpers { | 416 | mod ram_helpers { |
| 247 | use core::marker::PhantomData; | 417 | use core::marker::PhantomData; |
| @@ -699,9 +869,24 @@ mod ram_helpers { | |||
| 699 | 869 | ||
| 700 | mod sealed { | 870 | mod sealed { |
| 701 | pub trait Instance {} | 871 | pub trait Instance {} |
| 872 | pub trait Mode {} | ||
| 702 | } | 873 | } |
| 703 | 874 | ||
| 704 | pub trait Instance: sealed::Instance {} | 875 | pub trait Instance: sealed::Instance {} |
| 876 | pub trait Mode: sealed::Mode {} | ||
| 705 | 877 | ||
| 706 | impl sealed::Instance for FLASH {} | 878 | impl sealed::Instance for FLASH {} |
| 707 | impl Instance for FLASH {} | 879 | impl Instance for FLASH {} |
| 880 | |||
| 881 | macro_rules! impl_mode { | ||
| 882 | ($name:ident) => { | ||
| 883 | impl sealed::Mode for $name {} | ||
| 884 | impl Mode for $name {} | ||
| 885 | }; | ||
| 886 | } | ||
| 887 | |||
| 888 | pub struct Blocking; | ||
| 889 | pub struct Async; | ||
| 890 | |||
| 891 | impl_mode!(Blocking); | ||
| 892 | impl_mode!(Async); | ||
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; | |||
| 3 | use core::pin::Pin as FuturePin; | 3 | use core::pin::Pin as FuturePin; |
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 8 | ||
| 9 | use crate::interrupt::InterruptExt; | 9 | use 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; | |||
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | use pac::i2c; | 7 | use 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` |
| 34 | pub mod pio; | 34 | pub mod pio; |
| 35 | pub mod pio_instr_util; | 35 | pub mod pio_instr_util; |
| 36 | pub mod relocate; | 36 | pub(crate) mod relocate; |
| 37 | 37 | ||
| 38 | // Reexports | 38 | // Reexports |
| 39 | pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 39 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 40 | #[cfg(feature = "unstable-pac")] | 40 | #[cfg(feature = "unstable-pac")] |
| 41 | pub use rp_pac as pac; | 41 | pub 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")] |
| 46 | pub use crate::pac::NVIC_PRIO_BITS; | 46 | pub use crate::pac::NVIC_PRIO_BITS; |
| 47 | 47 | ||
| 48 | embassy_hal_common::interrupt_mod!( | 48 | embassy_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] |
| 90 | macro_rules! bind_interrupts { | 90 | macro_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 | ||
| 110 | embassy_hal_common::peripherals! { | 110 | embassy_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 | /// ``` | ||
| 256 | pub 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)] | ||
| 264 | fn 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 | |||
| 222 | pub mod config { | 290 | pub 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 | ||
| 53 | use crate::interrupt::InterruptExt; | 53 | use crate::interrupt::InterruptExt; |
| 54 | use crate::peripherals::CORE1; | 54 | use crate::peripherals::CORE1; |
| 55 | use crate::{gpio, interrupt, pac}; | 55 | use crate::{gpio, install_stack_guard, interrupt, pac}; |
| 56 | 56 | ||
| 57 | const PAUSE_TOKEN: u32 = 0xDEADBEEF; | 57 | const PAUSE_TOKEN: u32 = 0xDEADBEEF; |
| 58 | const RESUME_TOKEN: u32 = !0xDEADBEEF; | 58 | const RESUME_TOKEN: u32 = !0xDEADBEEF; |
| 59 | static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false); | 59 | static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false); |
| 60 | 60 | ||
| 61 | #[inline(always)] | 61 | #[inline(always)] |
| 62 | fn install_stack_guard(stack_bottom: *mut usize) { | 62 | fn 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)] | ||
| 88 | fn 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}; | |||
| 5 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 6 | 6 | ||
| 7 | use atomic_polyfill::{AtomicU32, AtomicU8}; | 7 | use atomic_polyfill::{AtomicU32, AtomicU8}; |
| 8 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use fixed::types::extra::U8; | 10 | use fixed::types::extra::U8; |
| 11 | use fixed::FixedU32; | 11 | use fixed::FixedU32; |
| 12 | use pac::io::vals::Gpio0ctrlFuncsel; | 12 | use pac::io::vals::Gpio0ctrlFuncsel; |
| 13 | use pac::pio::vals::SmExecctrlStatusSel; | 13 | use pac::pio::vals::SmExecctrlStatusSel; |
| 14 | use pio::{SideSet, Wrap}; | 14 | use pio::{Program, SideSet, Wrap}; |
| 15 | 15 | ||
| 16 | use crate::dma::{Channel, Transfer, Word}; | 16 | use crate::dma::{Channel, Transfer, Word}; |
| 17 | use crate::gpio::sealed::Pin as SealedPin; | 17 | use crate::gpio::sealed::Pin as SealedPin; |
| @@ -734,23 +734,67 @@ pub struct InstanceMemory<'d, PIO: Instance> { | |||
| 734 | 734 | ||
| 735 | pub struct LoadedProgram<'d, PIO: Instance> { | 735 | pub 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))] | ||
| 744 | pub 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 | ||
| 742 | impl<'d, PIO: Instance> Common<'d, PIO> { | 752 | impl<'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 | ||
| 3 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 4 | use fixed::traits::ToFixed; | 4 | use fixed::traits::ToFixed; |
| 5 | use fixed::FixedU16; | 5 | use fixed::FixedU16; |
| 6 | use pac::pwm::regs::{ChDiv, Intr}; | 6 | use 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 | ||
| 43 | impl<'a, const PROGRAM_SIZE: usize> RelocatedProgram<'a, PROGRAM_SIZE> { | 43 | impl<'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 @@ | |||
| 1 | mod filter; | 1 | mod filter; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 4 | 4 | ||
| 5 | pub use self::filter::DateTimeFilter; | 5 | pub 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 | ||
| 4 | use embassy_embedded_hal::SetConfig; | 4 | use embassy_embedded_hal::SetConfig; |
| 5 | use embassy_futures::join::join; | 5 | use embassy_futures::join::join; |
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | pub use embedded_hal_02::spi::{Phase, Polarity}; | 7 | pub use embedded_hal_02::spi::{Phase, Polarity}; |
| 8 | 8 | ||
| 9 | use crate::dma::{AnyChannel, Channel}; | 9 | use 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; | |||
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use atomic_polyfill::{AtomicU8, Ordering}; | 5 | use atomic_polyfill::{AtomicU8, Ordering}; |
| 6 | use embassy_hal_common::atomic_ring_buffer::RingBuffer; | 6 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use embassy_time::{Duration, Timer}; | 8 | use 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 | ||
| 5 | use atomic_polyfill::{AtomicU16, Ordering}; | 5 | use atomic_polyfill::{AtomicU16, Ordering}; |
| 6 | use embassy_futures::select::{select, Either}; | 6 | use embassy_futures::select::{select, Either}; |
| 7 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 10 | use pac::uart::regs::Uartris; | 10 | use 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" } | |||
| 15 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 15 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 16 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } | 16 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } |
| 17 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } | 17 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } |
| 18 | embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common" } | 18 | embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" } |
| 19 | embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } | 19 | embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } |
| 20 | embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } | 20 | embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } |
| 21 | 21 | ||
| @@ -26,12 +26,12 @@ aligned = "0.4.1" | |||
| 26 | 26 | ||
| 27 | bit_field = "0.10.2" | 27 | bit_field = "0.10.2" |
| 28 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } | 28 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } |
| 29 | stm32wb-hci = { version = "0.1.3", optional = true } | 29 | stm32wb-hci = { version = "0.1.4", optional = true } |
| 30 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 30 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 31 | bitflags = { version = "2.3.3", optional = true } | 31 | bitflags = { version = "2.3.3", optional = true } |
| 32 | 32 | ||
| 33 | [features] | 33 | [features] |
| 34 | defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "stm32wb-hci?/defmt"] | 34 | defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "stm32wb-hci?/defmt"] |
| 35 | 35 | ||
| 36 | ble = ["dep:stm32wb-hci"] | 36 | ble = ["dep:stm32wb-hci"] |
| 37 | mac = ["dep:bitflags", "dep:embassy-net-driver" ] | 37 | mac = ["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; | |||
| 8 | use core::mem::MaybeUninit; | 8 | use core::mem::MaybeUninit; |
| 9 | use core::sync::atomic::{compiler_fence, Ordering}; | 9 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 10 | 10 | ||
| 11 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 11 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 12 | use embassy_stm32::interrupt; | 12 | use embassy_stm32::interrupt; |
| 13 | use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; | 13 | use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 14 | use embassy_stm32::peripherals::IPCC; | 14 | use embassy_stm32::peripherals::IPCC; |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index cb0644338..8c7dd38c2 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -34,7 +34,7 @@ flavors = [ | |||
| 34 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | 34 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } |
| 35 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } | 35 | embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true } |
| 36 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } | 36 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } |
| 37 | embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-4"] } | 37 | embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } |
| 38 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } | 38 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } |
| 39 | embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } | 39 | embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } |
| 40 | embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } | 40 | embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } |
| @@ -57,7 +57,7 @@ sdio-host = "0.5.0" | |||
| 57 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 57 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 58 | critical-section = "1.1" | 58 | critical-section = "1.1" |
| 59 | atomic-polyfill = "1.0.1" | 59 | atomic-polyfill = "1.0.1" |
| 60 | stm32-metapac = "13" | 60 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe" } |
| 61 | vcell = "0.1.3" | 61 | vcell = "0.1.3" |
| 62 | bxcan = "0.7.0" | 62 | bxcan = "0.7.0" |
| 63 | nb = "1.0.0" | 63 | nb = "1.0.0" |
| @@ -67,6 +67,7 @@ cfg-if = "1.0.0" | |||
| 67 | embedded-io = { version = "0.4.0", features = ["async"], optional = true } | 67 | embedded-io = { version = "0.4.0", features = ["async"], optional = true } |
| 68 | chrono = { version = "^0.4", default-features = false, optional = true} | 68 | chrono = { version = "^0.4", default-features = false, optional = true} |
| 69 | bit_field = "0.10.2" | 69 | bit_field = "0.10.2" |
| 70 | document-features = "0.2.7" | ||
| 70 | 71 | ||
| 71 | [dev-dependencies] | 72 | [dev-dependencies] |
| 72 | critical-section = { version = "1.1", features = ["std"] } | 73 | critical-section = { version = "1.1", features = ["std"] } |
| @@ -74,44 +75,67 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 74 | [build-dependencies] | 75 | [build-dependencies] |
| 75 | proc-macro2 = "1.0.36" | 76 | proc-macro2 = "1.0.36" |
| 76 | quote = "1.0.15" | 77 | quote = "1.0.15" |
| 77 | stm32-metapac = { version = "13", default-features = false, features = ["metadata"]} | 78 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe", default-features = false, features = ["metadata"]} |
| 78 | 79 | ||
| 79 | [features] | 80 | [features] |
| 80 | default = ["rt"] | 81 | default = ["rt"] |
| 82 | |||
| 83 | ## Enable `stm32-metapac`'s `rt` feature | ||
| 81 | rt = ["stm32-metapac/rt"] | 84 | rt = ["stm32-metapac/rt"] |
| 82 | 85 | ||
| 83 | defmt = ["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", "embassy-time?/defmt"] | 86 | ## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging |
| 84 | memory-x = ["stm32-metapac/memory-x"] | 87 | defmt = ["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", "embassy-time?/defmt"] |
| 88 | |||
| 85 | exti = [] | 89 | exti = [] |
| 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/) |
| 92 | memory-x = ["stm32-metapac/memory-x"] | ||
| 93 | |||
| 94 | ## Enable nightly-only features | ||
| 95 | nightly = ["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. | ||
| 101 | unstable-pac = [] | ||
| 102 | |||
| 103 | ## Implement embedded-hal 1.0 alpha traits. | ||
| 104 | ## Implement embedded-hal-async traits if `nightly` is set as well. | ||
| 105 | unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"] | ||
| 106 | |||
| 107 | #! ## Time | ||
| 108 | |||
| 109 | ## Enables additional driver features that depend on embassy-time | ||
| 88 | time = ["dep:embassy-time"] | 110 | time = ["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 | ||
| 93 | time-driver-any = ["_time-driver"] | 117 | time-driver-any = ["_time-driver"] |
| 118 | ## Use TIM2 as time driver | ||
| 94 | time-driver-tim2 = ["_time-driver"] | 119 | time-driver-tim2 = ["_time-driver"] |
| 120 | ## Use TIM3 as time driver | ||
| 95 | time-driver-tim3 = ["_time-driver"] | 121 | time-driver-tim3 = ["_time-driver"] |
| 122 | ## Use TIM4 as time driver | ||
| 96 | time-driver-tim4 = ["_time-driver"] | 123 | time-driver-tim4 = ["_time-driver"] |
| 124 | ## Use TIM5 as time driver | ||
| 97 | time-driver-tim5 = ["_time-driver"] | 125 | time-driver-tim5 = ["_time-driver"] |
| 126 | ## Use TIM12 as time driver | ||
| 98 | time-driver-tim12 = ["_time-driver"] | 127 | time-driver-tim12 = ["_time-driver"] |
| 128 | ## Use TIM15 as time driver | ||
| 99 | time-driver-tim15 = ["_time-driver"] | 129 | time-driver-tim15 = ["_time-driver"] |
| 100 | 130 | ||
| 101 | # Enable nightly-only features | ||
| 102 | nightly = ["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. | ||
| 108 | unstable-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`. |
| 112 | unstable-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 | ||
| 115 | stm32c011d6 = [ "stm32-metapac/stm32c011d6" ] | 139 | stm32c011d6 = [ "stm32-metapac/stm32c011d6" ] |
| 116 | stm32c011f4 = [ "stm32-metapac/stm32c011f4" ] | 140 | stm32c011f4 = [ "stm32-metapac/stm32c011f4" ] |
| 117 | stm32c011f6 = [ "stm32-metapac/stm32c011f6" ] | 141 | stm32c011f6 = [ "stm32-metapac/stm32c011f6" ] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 995ad1443..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,31 @@ 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)), | ||
| 591 | (("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)), | ||
| 592 | (("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)), | ||
| 593 | (("hrtim", "CHB2"), quote!(crate::hrtim::ChannelBComplementaryPin)), | ||
| 594 | (("hrtim", "CHC1"), quote!(crate::hrtim::ChannelCPin)), | ||
| 595 | (("hrtim", "CHC2"), quote!(crate::hrtim::ChannelCComplementaryPin)), | ||
| 596 | (("hrtim", "CHD1"), quote!(crate::hrtim::ChannelDPin)), | ||
| 597 | (("hrtim", "CHD2"), quote!(crate::hrtim::ChannelDComplementaryPin)), | ||
| 598 | (("hrtim", "CHE1"), quote!(crate::hrtim::ChannelEPin)), | ||
| 599 | (("hrtim", "CHE2"), quote!(crate::hrtim::ChannelEComplementaryPin)), | ||
| 590 | (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)), | 600 | (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)), |
| 591 | (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)), | 601 | (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)), |
| 592 | (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)), | 602 | (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)), |
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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, SampleTime}; | 4 | use 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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; | 4 | use 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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use super::InternalChannel; | 4 | use 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 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 3 | 3 | ||
| 4 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; | 4 | use 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 | ||
| 227 | impl<'d, T: Instance> Adc<'d, T> { | 227 | impl<'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 795becabf..448be1cdd 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 | ||
| 7 | pub use bxcan; | 7 | pub use bxcan; |
| 8 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; | 8 | use bxcan::{Data, ExtendedId, Frame, Id, StandardId}; |
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use futures::FutureExt; | 10 | use futures::FutureExt; |
| 11 | 11 | ||
| 12 | use crate::gpio::sealed::AFType; | 12 | use crate::gpio::sealed::AFType; |
| @@ -88,6 +88,7 @@ pub struct Can<'d, T: Instance> { | |||
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | #[derive(Debug)] | 90 | #[derive(Debug)] |
| 91 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 91 | pub enum BusError { | 92 | pub enum BusError { |
| 92 | Stuff, | 93 | Stuff, |
| 93 | Form, | 94 | Form, |
| @@ -101,6 +102,22 @@ pub enum BusError { | |||
| 101 | BusWarning, | 102 | BusWarning, |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 105 | #[derive(Debug)] | ||
| 106 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 107 | pub enum TryReadError { | ||
| 108 | /// Bus error | ||
| 109 | BusError(BusError), | ||
| 110 | /// Receive buffer is empty | ||
| 111 | Empty, | ||
| 112 | } | ||
| 113 | |||
| 114 | #[derive(Debug)] | ||
| 115 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 116 | pub enum TryWriteError { | ||
| 117 | /// All transmit mailboxes are full | ||
| 118 | Full, | ||
| 119 | } | ||
| 120 | |||
| 104 | impl<'d, T: Instance> Can<'d, T> { | 121 | impl<'d, T: Instance> Can<'d, T> { |
| 105 | /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. | 122 | /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. |
| 106 | /// You must call [Can::enable_non_blocking] to use the peripheral. | 123 | /// You must call [Can::enable_non_blocking] to use the peripheral. |
| @@ -186,56 +203,46 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 186 | 203 | ||
| 187 | /// Queues the message to be sent but exerts backpressure | 204 | /// Queues the message to be sent but exerts backpressure |
| 188 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { | 205 | pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus { |
| 189 | poll_fn(|cx| { | 206 | CanTx { can: &self.can }.write(frame).await |
| 190 | T::state().tx_waker.register(cx.waker()); | 207 | } |
| 191 | if let Ok(status) = self.can.borrow_mut().transmit(frame) { | ||
| 192 | return Poll::Ready(status); | ||
| 193 | } | ||
| 194 | 208 | ||
| 195 | Poll::Pending | 209 | /// Attempts to transmit a frame without blocking. |
| 196 | }) | 210 | /// |
| 197 | .await | 211 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. |
| 212 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | ||
| 213 | CanTx { can: &self.can }.try_write(frame) | ||
| 198 | } | 214 | } |
| 199 | 215 | ||
| 216 | /// Waits for a specific transmit mailbox to become empty | ||
| 200 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 217 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 201 | poll_fn(|cx| { | 218 | CanTx { can: &self.can }.flush(mb).await |
| 202 | T::state().tx_waker.register(cx.waker()); | 219 | } |
| 203 | if T::regs().tsr().read().tme(mb.index()) { | ||
| 204 | return Poll::Ready(()); | ||
| 205 | } | ||
| 206 | 220 | ||
| 207 | Poll::Pending | 221 | /// Waits until any of the transmit mailboxes become empty |
| 208 | }) | 222 | pub async fn flush_any(&self) { |
| 209 | .await; | 223 | CanTx { can: &self.can }.flush_any().await |
| 224 | } | ||
| 225 | |||
| 226 | /// Waits until all of the transmit mailboxes become empty | ||
| 227 | pub async fn flush_all(&self) { | ||
| 228 | CanTx { can: &self.can }.flush_all().await | ||
| 210 | } | 229 | } |
| 211 | 230 | ||
| 212 | /// Returns a tuple of the time the message was received and the message frame | 231 | /// Returns a tuple of the time the message was received and the message frame |
| 213 | pub async fn read(&mut self) -> Result<Envelope, BusError> { | 232 | pub async fn read(&mut self) -> Result<Envelope, BusError> { |
| 214 | poll_fn(|cx| { | 233 | CanRx { can: &self.can }.read().await |
| 215 | T::state().err_waker.register(cx.waker()); | 234 | } |
| 216 | if let Poll::Ready(envelope) = T::state().rx_queue.recv().poll_unpin(cx) { | ||
| 217 | return Poll::Ready(Ok(envelope)); | ||
| 218 | } else if let Some(err) = self.curr_error() { | ||
| 219 | return Poll::Ready(Err(err)); | ||
| 220 | } | ||
| 221 | 235 | ||
| 222 | Poll::Pending | 236 | /// Attempts to read a can frame without blocking. |
| 223 | }) | 237 | /// |
| 224 | .await | 238 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. |
| 239 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | ||
| 240 | CanRx { can: &self.can }.try_read() | ||
| 225 | } | 241 | } |
| 226 | 242 | ||
| 227 | fn curr_error(&self) -> Option<BusError> { | 243 | /// Waits while receive queue is empty. |
| 228 | let err = { T::regs().esr().read() }; | 244 | pub async fn wait_not_empty(&mut self) { |
| 229 | if err.boff() { | 245 | CanRx { can: &self.can }.wait_not_empty().await |
| 230 | return Some(BusError::BusOff); | ||
| 231 | } else if err.epvf() { | ||
| 232 | return Some(BusError::BusPassive); | ||
| 233 | } else if err.ewgf() { | ||
| 234 | return Some(BusError::BusWarning); | ||
| 235 | } else if let Some(err) = err.lec().into_bus_err() { | ||
| 236 | return Some(err); | ||
| 237 | } | ||
| 238 | None | ||
| 239 | } | 246 | } |
| 240 | 247 | ||
| 241 | unsafe fn receive_fifo(fifo: RxFifo) { | 248 | unsafe fn receive_fifo(fifo: RxFifo) { |
| @@ -405,6 +412,14 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 405 | .await | 412 | .await |
| 406 | } | 413 | } |
| 407 | 414 | ||
| 415 | /// Attempts to transmit a frame without blocking. | ||
| 416 | /// | ||
| 417 | /// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full. | ||
| 418 | pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> { | ||
| 419 | self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full) | ||
| 420 | } | ||
| 421 | |||
| 422 | /// Waits for a specific transmit mailbox to become empty | ||
| 408 | pub async fn flush(&self, mb: bxcan::Mailbox) { | 423 | pub async fn flush(&self, mb: bxcan::Mailbox) { |
| 409 | poll_fn(|cx| { | 424 | poll_fn(|cx| { |
| 410 | T::state().tx_waker.register(cx.waker()); | 425 | T::state().tx_waker.register(cx.waker()); |
| @@ -416,6 +431,42 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 416 | }) | 431 | }) |
| 417 | .await; | 432 | .await; |
| 418 | } | 433 | } |
| 434 | |||
| 435 | /// Waits until any of the transmit mailboxes become empty | ||
| 436 | pub async fn flush_any(&self) { | ||
| 437 | poll_fn(|cx| { | ||
| 438 | T::state().tx_waker.register(cx.waker()); | ||
| 439 | |||
| 440 | let tsr = T::regs().tsr().read(); | ||
| 441 | if tsr.tme(bxcan::Mailbox::Mailbox0.index()) | ||
| 442 | || tsr.tme(bxcan::Mailbox::Mailbox1.index()) | ||
| 443 | || tsr.tme(bxcan::Mailbox::Mailbox2.index()) | ||
| 444 | { | ||
| 445 | return Poll::Ready(()); | ||
| 446 | } | ||
| 447 | |||
| 448 | Poll::Pending | ||
| 449 | }) | ||
| 450 | .await; | ||
| 451 | } | ||
| 452 | |||
| 453 | /// Waits until all of the transmit mailboxes become empty | ||
| 454 | pub async fn flush_all(&self) { | ||
| 455 | poll_fn(|cx| { | ||
| 456 | T::state().tx_waker.register(cx.waker()); | ||
| 457 | |||
| 458 | let tsr = T::regs().tsr().read(); | ||
| 459 | if tsr.tme(bxcan::Mailbox::Mailbox0.index()) | ||
| 460 | && tsr.tme(bxcan::Mailbox::Mailbox1.index()) | ||
| 461 | && tsr.tme(bxcan::Mailbox::Mailbox2.index()) | ||
| 462 | { | ||
| 463 | return Poll::Ready(()); | ||
| 464 | } | ||
| 465 | |||
| 466 | Poll::Pending | ||
| 467 | }) | ||
| 468 | .await; | ||
| 469 | } | ||
| 419 | } | 470 | } |
| 420 | 471 | ||
| 421 | #[allow(dead_code)] | 472 | #[allow(dead_code)] |
| @@ -438,6 +489,33 @@ impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { | |||
| 438 | .await | 489 | .await |
| 439 | } | 490 | } |
| 440 | 491 | ||
| 492 | /// Attempts to read a CAN frame without blocking. | ||
| 493 | /// | ||
| 494 | /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. | ||
| 495 | pub fn try_read(&mut self) -> Result<Envelope, TryReadError> { | ||
| 496 | if let Ok(envelope) = T::state().rx_queue.try_recv() { | ||
| 497 | return Ok(envelope); | ||
| 498 | } | ||
| 499 | |||
| 500 | if let Some(err) = self.curr_error() { | ||
| 501 | return Err(TryReadError::BusError(err)); | ||
| 502 | } | ||
| 503 | |||
| 504 | Err(TryReadError::Empty) | ||
| 505 | } | ||
| 506 | |||
| 507 | /// Waits while receive queue is empty. | ||
| 508 | pub async fn wait_not_empty(&mut self) { | ||
| 509 | poll_fn(|cx| { | ||
| 510 | if T::state().rx_queue.poll_ready_to_receive(cx) { | ||
| 511 | Poll::Ready(()) | ||
| 512 | } else { | ||
| 513 | Poll::Pending | ||
| 514 | } | ||
| 515 | }) | ||
| 516 | .await | ||
| 517 | } | ||
| 518 | |||
| 441 | fn curr_error(&self) -> Option<BusError> { | 519 | fn curr_error(&self) -> Option<BusError> { |
| 442 | let err = { T::regs().esr().read() }; | 520 | let err = { T::regs().esr().read() }; |
| 443 | if err.boff() { | 521 | 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 @@ | |||
| 1 | pub use bxcan; | 1 | pub use bxcan; |
| 2 | use embassy_hal_common::PeripheralRef; | 2 | use embassy_hal_internal::PeripheralRef; |
| 3 | 3 | ||
| 4 | use crate::peripherals; | 4 | use 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 @@ | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 1 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 2 | 2 | ||
| 3 | use crate::pac::CRC as PAC_CRC; | 3 | use crate::pac::CRC as PAC_CRC; |
| 4 | use crate::peripherals::CRC; | 4 | use 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 @@ | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 1 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 2 | 2 | ||
| 3 | use crate::pac::crc::vals; | 3 | use crate::pac::crc::vals; |
| 4 | use crate::pac::CRC as PAC_CRC; | 4 | use crate::pac::CRC as PAC_CRC; |
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 979748bb4..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). |
| 4 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | 7 | ||
| 8 | use crate::pac::dac; | 8 | use crate::pac::dac; |
| 9 | use crate::rcc::RccPeripheral; | 9 | use crate::rcc::RccPeripheral; |
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; | |||
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | 7 | ||
| 8 | use crate::dma::Transfer; | 8 | use 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}; | |||
| 6 | use core::task::{Context, Poll, Waker}; | 6 | use core::task::{Context, Poll, Waker}; |
| 7 | 7 | ||
| 8 | use atomic_polyfill::AtomicUsize; | 8 | use atomic_polyfill::AtomicUsize; |
| 9 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 10 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | 11 | ||
| 12 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; | 12 | use 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 f14084599..219ef2eb0 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs | |||
| @@ -4,7 +4,7 @@ use core::pin::Pin; | |||
| 4 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; | 4 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; |
| 5 | use core::task::{Context, Poll, Waker}; | 5 | use core::task::{Context, Poll, Waker}; |
| 6 | 6 | ||
| 7 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 9 | ||
| 10 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; | 10 | use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; |
| @@ -711,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> { | |||
| 711 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); | 711 | self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow())); |
| 712 | } | 712 | } |
| 713 | 713 | ||
| 714 | /// Read bytes from the ring buffer | 714 | /// Read elements from the ring buffer |
| 715 | /// 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 |
| 716 | /// 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 |
| 717 | /// 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 |
| 718 | /// 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. |
| 719 | 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> { |
| 720 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) | 720 | self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf) |
| 721 | } | 721 | } |
| 722 | 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 | |||
| 723 | // The capacity of the ringbuffer | 761 | // The capacity of the ringbuffer |
| 724 | pub fn cap(&self) -> usize { | 762 | pub fn cap(&self) -> usize { |
| 725 | 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; | |||
| 5 | use core::sync::atomic::{fence, Ordering}; | 5 | use core::sync::atomic::{fence, Ordering}; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use super::word::{Word, WordSize}; | 11 | use 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 | ||
| 27 | use core::mem; | 27 | use core::mem; |
| 28 | 28 | ||
| 29 | use embassy_hal_common::impl_peripheral; | 29 | use embassy_hal_internal::impl_peripheral; |
| 30 | 30 | ||
| 31 | #[cfg(dmamux)] | 31 | #[cfg(dmamux)] |
| 32 | pub use self::dmamux::*; | 32 | pub 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; | |||
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::{fence, Ordering}; | 7 | use core::sync::atomic::{fence, Ordering}; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; | 10 | use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; |
| 11 | 11 | ||
| 12 | pub(crate) use self::rx_desc::{RDes, RDesRing}; | 12 | pub(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; | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{fence, Ordering}; | 4 | use core::sync::atomic::{fence, Ordering}; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | 7 | ||
| 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; | 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; |
| 9 | use super::*; | 9 | use 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; | |||
| 3 | use core::pin::Pin; | 3 | use core::pin::Pin; |
| 4 | use core::task::{Context, Poll}; | 4 | use core::task::{Context, Poll}; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::impl_peripheral; | 6 | use embassy_hal_internal::impl_peripheral; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 8 | ||
| 9 | use crate::gpio::{AnyPin, Input, Pin as GpioPin}; | 9 | use 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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::drop::OnDrop; | 4 | use embassy_hal_internal::drop::OnDrop; |
| 5 | use embassy_hal_common::into_ref; | 5 | use embassy_hal_internal::into_ref; |
| 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 7 | use embassy_sync::mutex::Mutex; | 7 | use 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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::drop::OnDrop; | 4 | use embassy_hal_internal::drop::OnDrop; |
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use stm32_metapac::FLASH_BASE; | 6 | use stm32_metapac::FLASH_BASE; |
| 7 | 7 | ||
| 8 | use super::{ | 8 | use 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; | |||
| 14 | mod alt_regions { | 14 | mod 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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | 4 | ||
| 5 | use crate::gpio::sealed::AFType; | 5 | use crate::gpio::sealed::AFType; |
| 6 | use crate::gpio::{Pull, Speed}; | 6 | use crate::gpio::{Pull, Speed}; |
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index af3a8eaca..0cc269cfd 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | use core::convert::Infallible; | 2 | use core::convert::Infallible; |
| 3 | 3 | ||
| 4 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 4 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 5 | 5 | ||
| 6 | use crate::pac::gpio::{self, vals}; | 6 | use crate::pac::gpio::{self, vals}; |
| 7 | use crate::{pac, peripherals, Peripheral}; | 7 | use crate::{pac, peripherals, Peripheral}; |
| @@ -502,6 +502,20 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { | |||
| 502 | } | 502 | } |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | pub enum OutputType { | ||
| 506 | PushPull, | ||
| 507 | OpenDrain, | ||
| 508 | } | ||
| 509 | |||
| 510 | impl From<OutputType> for sealed::AFType { | ||
| 511 | fn from(value: OutputType) -> Self { | ||
| 512 | match value { | ||
| 513 | OutputType::OpenDrain => sealed::AFType::OutputOpenDrain, | ||
| 514 | OutputType::PushPull => sealed::AFType::OutputPushPull, | ||
| 515 | } | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 505 | pub(crate) mod sealed { | 519 | pub(crate) mod sealed { |
| 506 | use super::*; | 520 | use super::*; |
| 507 | 521 | ||
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs new file mode 100644 index 000000000..a930ff73f --- /dev/null +++ b/embassy-stm32/src/hrtim/mod.rs | |||
| @@ -0,0 +1,409 @@ | |||
| 1 | mod traits; | ||
| 2 | |||
| 3 | use core::marker::PhantomData; | ||
| 4 | |||
| 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; | ||
| 6 | pub use traits::Instance; | ||
| 7 | |||
| 8 | #[allow(unused_imports)] | ||
| 9 | use crate::gpio::sealed::{AFType, Pin}; | ||
| 10 | use crate::gpio::AnyPin; | ||
| 11 | use crate::time::Hertz; | ||
| 12 | use crate::Peripheral; | ||
| 13 | |||
| 14 | pub enum Source { | ||
| 15 | Master, | ||
| 16 | ChA, | ||
| 17 | ChB, | ||
| 18 | ChC, | ||
| 19 | ChD, | ||
| 20 | ChE, | ||
| 21 | } | ||
| 22 | |||
| 23 | pub struct BurstController<T: Instance> { | ||
| 24 | phantom: PhantomData<T>, | ||
| 25 | } | ||
| 26 | pub struct Master<T: Instance> { | ||
| 27 | phantom: PhantomData<T>, | ||
| 28 | } | ||
| 29 | pub struct ChA<T: Instance> { | ||
| 30 | phantom: PhantomData<T>, | ||
| 31 | } | ||
| 32 | pub struct ChB<T: Instance> { | ||
| 33 | phantom: PhantomData<T>, | ||
| 34 | } | ||
| 35 | pub struct ChC<T: Instance> { | ||
| 36 | phantom: PhantomData<T>, | ||
| 37 | } | ||
| 38 | pub struct ChD<T: Instance> { | ||
| 39 | phantom: PhantomData<T>, | ||
| 40 | } | ||
| 41 | pub struct ChE<T: Instance> { | ||
| 42 | phantom: PhantomData<T>, | ||
| 43 | } | ||
| 44 | |||
| 45 | mod sealed { | ||
| 46 | use super::Instance; | ||
| 47 | |||
| 48 | pub trait AdvancedChannel<T: Instance> { | ||
| 49 | fn raw() -> usize; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | pub trait AdvancedChannel<T: Instance>: sealed::AdvancedChannel<T> {} | ||
| 54 | |||
| 55 | pub struct PwmPin<'d, Perip, Channel> { | ||
| 56 | _pin: PeripheralRef<'d, AnyPin>, | ||
| 57 | phantom: PhantomData<(Perip, Channel)>, | ||
| 58 | } | ||
| 59 | |||
| 60 | pub struct ComplementaryPwmPin<'d, Perip, Channel> { | ||
| 61 | _pin: PeripheralRef<'d, AnyPin>, | ||
| 62 | phantom: PhantomData<(Perip, Channel)>, | ||
| 63 | } | ||
| 64 | |||
| 65 | macro_rules! advanced_channel_impl { | ||
| 66 | ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => { | ||
| 67 | impl<'d, Perip: Instance> PwmPin<'d, Perip, $channel<Perip>> { | ||
| 68 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd) -> Self { | ||
| 69 | into_ref!(pin); | ||
| 70 | critical_section::with(|_| { | ||
| 71 | pin.set_low(); | ||
| 72 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); | ||
| 73 | #[cfg(gpio_v2)] | ||
| 74 | pin.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 75 | }); | ||
| 76 | PwmPin { | ||
| 77 | _pin: pin.map_into(), | ||
| 78 | phantom: PhantomData, | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | impl<'d, Perip: Instance> ComplementaryPwmPin<'d, Perip, $channel<Perip>> { | ||
| 84 | pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self { | ||
| 85 | into_ref!(pin); | ||
| 86 | critical_section::with(|_| { | ||
| 87 | pin.set_low(); | ||
| 88 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); | ||
| 89 | #[cfg(gpio_v2)] | ||
| 90 | pin.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 91 | }); | ||
| 92 | ComplementaryPwmPin { | ||
| 93 | _pin: pin.map_into(), | ||
| 94 | phantom: PhantomData, | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | impl<T: Instance> sealed::AdvancedChannel<T> for $channel<T> { | ||
| 100 | fn raw() -> usize { | ||
| 101 | $ch_num | ||
| 102 | } | ||
| 103 | } | ||
| 104 | impl<T: Instance> AdvancedChannel<T> for $channel<T> {} | ||
| 105 | }; | ||
| 106 | } | ||
| 107 | |||
| 108 | advanced_channel_impl!(new_cha, ChA, 0, ChannelAPin, ChannelAComplementaryPin); | ||
| 109 | advanced_channel_impl!(new_chb, ChB, 1, ChannelBPin, ChannelBComplementaryPin); | ||
| 110 | advanced_channel_impl!(new_chc, ChC, 2, ChannelCPin, ChannelCComplementaryPin); | ||
| 111 | advanced_channel_impl!(new_chd, ChD, 3, ChannelDPin, ChannelDComplementaryPin); | ||
| 112 | advanced_channel_impl!(new_che, ChE, 4, ChannelEPin, ChannelEComplementaryPin); | ||
| 113 | |||
| 114 | /// Struct used to divide a high resolution timer into multiple channels | ||
| 115 | pub struct AdvancedPwm<'d, T: Instance> { | ||
| 116 | _inner: PeripheralRef<'d, T>, | ||
| 117 | pub master: Master<T>, | ||
| 118 | pub burst_controller: BurstController<T>, | ||
| 119 | pub ch_a: ChA<T>, | ||
| 120 | pub ch_b: ChB<T>, | ||
| 121 | pub ch_c: ChC<T>, | ||
| 122 | pub ch_d: ChD<T>, | ||
| 123 | pub ch_e: ChE<T>, | ||
| 124 | } | ||
| 125 | |||
| 126 | impl<'d, T: Instance> AdvancedPwm<'d, T> { | ||
| 127 | pub fn new( | ||
| 128 | tim: impl Peripheral<P = T> + 'd, | ||
| 129 | _cha: Option<PwmPin<'d, T, ChA<T>>>, | ||
| 130 | _chan: Option<ComplementaryPwmPin<'d, T, ChA<T>>>, | ||
| 131 | _chb: Option<PwmPin<'d, T, ChB<T>>>, | ||
| 132 | _chbn: Option<ComplementaryPwmPin<'d, T, ChB<T>>>, | ||
| 133 | _chc: Option<PwmPin<'d, T, ChC<T>>>, | ||
| 134 | _chcn: Option<ComplementaryPwmPin<'d, T, ChC<T>>>, | ||
| 135 | _chd: Option<PwmPin<'d, T, ChD<T>>>, | ||
| 136 | _chdn: Option<ComplementaryPwmPin<'d, T, ChD<T>>>, | ||
| 137 | _che: Option<PwmPin<'d, T, ChE<T>>>, | ||
| 138 | _chen: Option<ComplementaryPwmPin<'d, T, ChE<T>>>, | ||
| 139 | ) -> Self { | ||
| 140 | Self::new_inner(tim) | ||
| 141 | } | ||
| 142 | |||
| 143 | fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { | ||
| 144 | into_ref!(tim); | ||
| 145 | |||
| 146 | T::enable(); | ||
| 147 | <T as crate::rcc::sealed::RccPeripheral>::reset(); | ||
| 148 | |||
| 149 | // // Enable and and stabilize the DLL | ||
| 150 | // T::regs().dllcr().modify(|w| { | ||
| 151 | // // w.set_calen(true); | ||
| 152 | // // w.set_calrte(11); | ||
| 153 | // w.set_cal(true); | ||
| 154 | // }); | ||
| 155 | // | ||
| 156 | // debug!("wait for dll calibration"); | ||
| 157 | // while !T::regs().isr().read().dllrdy() {} | ||
| 158 | // | ||
| 159 | // debug!("dll calibration complete"); | ||
| 160 | |||
| 161 | Self { | ||
| 162 | _inner: tim, | ||
| 163 | master: Master { phantom: PhantomData }, | ||
| 164 | burst_controller: BurstController { phantom: PhantomData }, | ||
| 165 | ch_a: ChA { phantom: PhantomData }, | ||
| 166 | ch_b: ChB { phantom: PhantomData }, | ||
| 167 | ch_c: ChC { phantom: PhantomData }, | ||
| 168 | ch_d: ChD { phantom: PhantomData }, | ||
| 169 | ch_e: ChE { phantom: PhantomData }, | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | impl<T: Instance> BurstController<T> { | ||
| 175 | pub fn set_source(&mut self, _source: Source) { | ||
| 176 | todo!("burst mode control registers not implemented") | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | /// Represents a fixed-frequency bridge converter | ||
| 181 | /// | ||
| 182 | /// Our implementation of the bridge converter uses a single channel and three compare registers, | ||
| 183 | /// allowing implementation of a synchronous buck or boost converter in continuous or discontinuous | ||
| 184 | /// conduction mode. | ||
| 185 | /// | ||
| 186 | /// It is important to remember that in synchronous topologies, energy can flow in reverse during | ||
| 187 | /// light loading conditions, and that the low-side switch must be active for a short time to drive | ||
| 188 | /// a bootstrapped high-side switch. | ||
| 189 | pub struct BridgeConverter<T: Instance, C: AdvancedChannel<T>> { | ||
| 190 | timer: PhantomData<T>, | ||
| 191 | channel: PhantomData<C>, | ||
| 192 | dead_time: u16, | ||
| 193 | primary_duty: u16, | ||
| 194 | min_secondary_duty: u16, | ||
| 195 | max_secondary_duty: u16, | ||
| 196 | } | ||
| 197 | |||
| 198 | impl<T: Instance, C: AdvancedChannel<T>> BridgeConverter<T, C> { | ||
| 199 | pub fn new(_channel: C, frequency: Hertz) -> Self { | ||
| 200 | use crate::pac::hrtim::vals::{Activeeffect, Inactiveeffect}; | ||
| 201 | |||
| 202 | T::set_channel_frequency(C::raw(), frequency); | ||
| 203 | |||
| 204 | // Always enable preload | ||
| 205 | T::regs().tim(C::raw()).cr().modify(|w| { | ||
| 206 | w.set_preen(true); | ||
| 207 | w.set_repu(true); | ||
| 208 | w.set_cont(true); | ||
| 209 | }); | ||
| 210 | |||
| 211 | // Enable timer outputs | ||
| 212 | T::regs().oenr().modify(|w| { | ||
| 213 | w.set_t1oen(C::raw(), true); | ||
| 214 | w.set_t2oen(C::raw(), true); | ||
| 215 | }); | ||
| 216 | |||
| 217 | // The dead-time generation unit cannot be used because it forces the other output | ||
| 218 | // to be completely complementary to the first output, which restricts certain waveforms | ||
| 219 | // Therefore, software-implemented dead time must be used when setting the duty cycles | ||
| 220 | |||
| 221 | // Set output 1 to active on a period event | ||
| 222 | T::regs() | ||
| 223 | .tim(C::raw()) | ||
| 224 | .setr(0) | ||
| 225 | .modify(|w| w.set_per(Activeeffect::SETACTIVE)); | ||
| 226 | |||
| 227 | // Set output 1 to inactive on a compare 1 event | ||
| 228 | T::regs() | ||
| 229 | .tim(C::raw()) | ||
| 230 | .rstr(0) | ||
| 231 | .modify(|w| w.set_cmp(0, Inactiveeffect::SETINACTIVE)); | ||
| 232 | |||
| 233 | // Set output 2 to active on a compare 2 event | ||
| 234 | T::regs() | ||
| 235 | .tim(C::raw()) | ||
| 236 | .setr(1) | ||
| 237 | .modify(|w| w.set_cmp(1, Activeeffect::SETACTIVE)); | ||
| 238 | |||
| 239 | // Set output 2 to inactive on a compare 3 event | ||
| 240 | T::regs() | ||
| 241 | .tim(C::raw()) | ||
| 242 | .rstr(1) | ||
| 243 | .modify(|w| w.set_cmp(2, Inactiveeffect::SETINACTIVE)); | ||
| 244 | |||
| 245 | Self { | ||
| 246 | timer: PhantomData, | ||
| 247 | channel: PhantomData, | ||
| 248 | dead_time: 0, | ||
| 249 | primary_duty: 0, | ||
| 250 | min_secondary_duty: 0, | ||
| 251 | max_secondary_duty: 0, | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | pub fn start(&mut self) { | ||
| 256 | T::regs().mcr().modify(|w| w.set_tcen(C::raw(), true)); | ||
| 257 | } | ||
| 258 | |||
| 259 | pub fn stop(&mut self) { | ||
| 260 | T::regs().mcr().modify(|w| w.set_tcen(C::raw(), false)); | ||
| 261 | } | ||
| 262 | |||
| 263 | pub fn enable_burst_mode(&mut self) { | ||
| 264 | T::regs().tim(C::raw()).outr().modify(|w| { | ||
| 265 | // Enable Burst Mode | ||
| 266 | w.set_idlem(0, true); | ||
| 267 | w.set_idlem(1, true); | ||
| 268 | |||
| 269 | // Set output to active during the burst | ||
| 270 | w.set_idles(0, true); | ||
| 271 | w.set_idles(1, true); | ||
| 272 | }) | ||
| 273 | } | ||
| 274 | |||
| 275 | pub fn disable_burst_mode(&mut self) { | ||
| 276 | T::regs().tim(C::raw()).outr().modify(|w| { | ||
| 277 | // Disable Burst Mode | ||
| 278 | w.set_idlem(0, false); | ||
| 279 | w.set_idlem(1, false); | ||
| 280 | }) | ||
| 281 | } | ||
| 282 | |||
| 283 | fn update_primary_duty_or_dead_time(&mut self) { | ||
| 284 | self.min_secondary_duty = self.primary_duty + self.dead_time; | ||
| 285 | |||
| 286 | T::regs().tim(C::raw()).cmp(0).modify(|w| w.set_cmp(self.primary_duty)); | ||
| 287 | T::regs() | ||
| 288 | .tim(C::raw()) | ||
| 289 | .cmp(1) | ||
| 290 | .modify(|w| w.set_cmp(self.min_secondary_duty)); | ||
| 291 | } | ||
| 292 | |||
| 293 | /// Set the dead time as a proportion of the maximum compare value | ||
| 294 | pub fn set_dead_time(&mut self, dead_time: u16) { | ||
| 295 | self.dead_time = dead_time; | ||
| 296 | self.max_secondary_duty = self.get_max_compare_value() - dead_time; | ||
| 297 | self.update_primary_duty_or_dead_time(); | ||
| 298 | } | ||
| 299 | |||
| 300 | /// Get the maximum compare value of a duty cycle | ||
| 301 | pub fn get_max_compare_value(&mut self) -> u16 { | ||
| 302 | T::regs().tim(C::raw()).per().read().per() | ||
| 303 | } | ||
| 304 | |||
| 305 | /// The primary duty is the period in which the primary switch is active | ||
| 306 | /// | ||
| 307 | /// In the case of a buck converter, this is the high-side switch | ||
| 308 | /// In the case of a boost converter, this is the low-side switch | ||
| 309 | pub fn set_primary_duty(&mut self, primary_duty: u16) { | ||
| 310 | self.primary_duty = primary_duty; | ||
| 311 | self.update_primary_duty_or_dead_time(); | ||
| 312 | } | ||
| 313 | |||
| 314 | /// The secondary duty is the period in any switch is active | ||
| 315 | /// | ||
| 316 | /// If less than or equal to the primary duty, the secondary switch will be active for one tick | ||
| 317 | /// If a fully complementary output is desired, the secondary duty can be set to the max compare | ||
| 318 | pub fn set_secondary_duty(&mut self, secondary_duty: u16) { | ||
| 319 | let secondary_duty = if secondary_duty > self.max_secondary_duty { | ||
| 320 | self.max_secondary_duty | ||
| 321 | } else if secondary_duty <= self.min_secondary_duty { | ||
| 322 | self.min_secondary_duty + 1 | ||
| 323 | } else { | ||
| 324 | secondary_duty | ||
| 325 | }; | ||
| 326 | |||
| 327 | T::regs().tim(C::raw()).cmp(2).modify(|w| w.set_cmp(secondary_duty)); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | /// Represents a variable-frequency resonant converter | ||
| 332 | /// | ||
| 333 | /// This implementation of a resonsant converter is appropriate for a half or full bridge, | ||
| 334 | /// but does not include secondary rectification, which is appropriate for applications | ||
| 335 | /// with a low-voltage on the secondary side. | ||
| 336 | pub struct ResonantConverter<T: Instance, C: AdvancedChannel<T>> { | ||
| 337 | timer: PhantomData<T>, | ||
| 338 | channel: PhantomData<C>, | ||
| 339 | min_period: u16, | ||
| 340 | max_period: u16, | ||
| 341 | } | ||
| 342 | |||
| 343 | impl<T: Instance, C: AdvancedChannel<T>> ResonantConverter<T, C> { | ||
| 344 | pub fn new(_channel: C, min_frequency: Hertz, max_frequency: Hertz) -> Self { | ||
| 345 | T::set_channel_frequency(C::raw(), min_frequency); | ||
| 346 | |||
| 347 | // Always enable preload | ||
| 348 | T::regs().tim(C::raw()).cr().modify(|w| { | ||
| 349 | w.set_preen(true); | ||
| 350 | w.set_repu(true); | ||
| 351 | |||
| 352 | w.set_cont(true); | ||
| 353 | w.set_half(true); | ||
| 354 | }); | ||
| 355 | |||
| 356 | // Enable timer outputs | ||
| 357 | T::regs().oenr().modify(|w| { | ||
| 358 | w.set_t1oen(C::raw(), true); | ||
| 359 | w.set_t2oen(C::raw(), true); | ||
| 360 | }); | ||
| 361 | |||
| 362 | // Dead-time generator can be used in this case because the primary fets | ||
| 363 | // of a resonant converter are always complementary | ||
| 364 | T::regs().tim(C::raw()).outr().modify(|w| w.set_dten(true)); | ||
| 365 | |||
| 366 | let max_period = T::regs().tim(C::raw()).per().read().per(); | ||
| 367 | let min_period = max_period * (min_frequency.0 / max_frequency.0) as u16; | ||
| 368 | |||
| 369 | Self { | ||
| 370 | timer: PhantomData, | ||
| 371 | channel: PhantomData, | ||
| 372 | min_period: min_period, | ||
| 373 | max_period: max_period, | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | /// Set the dead time as a proportion of the maximum compare value | ||
| 378 | pub fn set_dead_time(&mut self, value: u16) { | ||
| 379 | T::set_channel_dead_time(C::raw(), value); | ||
| 380 | } | ||
| 381 | |||
| 382 | pub fn set_period(&mut self, period: u16) { | ||
| 383 | assert!(period < self.max_period); | ||
| 384 | assert!(period > self.min_period); | ||
| 385 | |||
| 386 | T::regs().tim(C::raw()).per().modify(|w| w.set_per(period)); | ||
| 387 | } | ||
| 388 | |||
| 389 | /// Get the minimum compare value of a duty cycle | ||
| 390 | pub fn get_min_period(&mut self) -> u16 { | ||
| 391 | self.min_period | ||
| 392 | } | ||
| 393 | |||
| 394 | /// Get the maximum compare value of a duty cycle | ||
| 395 | pub fn get_max_period(&mut self) -> u16 { | ||
| 396 | self.max_period | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | pin_trait!(ChannelAPin, Instance); | ||
| 401 | pin_trait!(ChannelAComplementaryPin, Instance); | ||
| 402 | pin_trait!(ChannelBPin, Instance); | ||
| 403 | pin_trait!(ChannelBComplementaryPin, Instance); | ||
| 404 | pin_trait!(ChannelCPin, Instance); | ||
| 405 | pin_trait!(ChannelCComplementaryPin, Instance); | ||
| 406 | pin_trait!(ChannelDPin, Instance); | ||
| 407 | pin_trait!(ChannelDComplementaryPin, Instance); | ||
| 408 | pin_trait!(ChannelEPin, Instance); | ||
| 409 | pin_trait!(ChannelEComplementaryPin, Instance); | ||
diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs new file mode 100644 index 000000000..158a68862 --- /dev/null +++ b/embassy-stm32/src/hrtim/traits.rs | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | use crate::rcc::sealed::RccPeripheral; | ||
| 2 | use crate::time::Hertz; | ||
| 3 | |||
| 4 | #[derive(Clone, Copy)] | ||
| 5 | pub(crate) enum Prescaler { | ||
| 6 | Div1, | ||
| 7 | Div2, | ||
| 8 | Div4, | ||
| 9 | Div8, | ||
| 10 | Div16, | ||
| 11 | Div32, | ||
| 12 | Div64, | ||
| 13 | Div128, | ||
| 14 | } | ||
| 15 | |||
| 16 | impl From<Prescaler> for u32 { | ||
| 17 | fn from(val: Prescaler) -> Self { | ||
| 18 | match val { | ||
| 19 | Prescaler::Div1 => 1, | ||
| 20 | Prescaler::Div2 => 2, | ||
| 21 | Prescaler::Div4 => 4, | ||
| 22 | Prescaler::Div8 => 8, | ||
| 23 | Prescaler::Div16 => 16, | ||
| 24 | Prescaler::Div32 => 32, | ||
| 25 | Prescaler::Div64 => 64, | ||
| 26 | Prescaler::Div128 => 128, | ||
| 27 | } | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | impl From<Prescaler> for u8 { | ||
| 32 | fn from(val: Prescaler) -> Self { | ||
| 33 | match val { | ||
| 34 | Prescaler::Div1 => 0b000, | ||
| 35 | Prescaler::Div2 => 0b001, | ||
| 36 | Prescaler::Div4 => 0b010, | ||
| 37 | Prescaler::Div8 => 0b011, | ||
| 38 | Prescaler::Div16 => 0b100, | ||
| 39 | Prescaler::Div32 => 0b101, | ||
| 40 | Prescaler::Div64 => 0b110, | ||
| 41 | Prescaler::Div128 => 0b111, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | impl From<u8> for Prescaler { | ||
| 47 | fn from(val: u8) -> Self { | ||
| 48 | match val { | ||
| 49 | 0b000 => Prescaler::Div1, | ||
| 50 | 0b001 => Prescaler::Div2, | ||
| 51 | 0b010 => Prescaler::Div4, | ||
| 52 | 0b011 => Prescaler::Div8, | ||
| 53 | 0b100 => Prescaler::Div16, | ||
| 54 | 0b101 => Prescaler::Div32, | ||
| 55 | 0b110 => Prescaler::Div64, | ||
| 56 | 0b111 => Prescaler::Div128, | ||
| 57 | _ => unreachable!(), | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | impl Prescaler { | ||
| 63 | pub fn compute_min_high_res(val: u32) -> Self { | ||
| 64 | *[ | ||
| 65 | Prescaler::Div1, | ||
| 66 | Prescaler::Div2, | ||
| 67 | Prescaler::Div4, | ||
| 68 | Prescaler::Div8, | ||
| 69 | Prescaler::Div16, | ||
| 70 | Prescaler::Div32, | ||
| 71 | Prescaler::Div64, | ||
| 72 | Prescaler::Div128, | ||
| 73 | ] | ||
| 74 | .iter() | ||
| 75 | .skip_while(|psc| <Prescaler as Into<u32>>::into(**psc) <= val) | ||
| 76 | .next() | ||
| 77 | .unwrap() | ||
| 78 | } | ||
| 79 | |||
| 80 | pub fn compute_min_low_res(val: u32) -> Self { | ||
| 81 | *[Prescaler::Div32, Prescaler::Div64, Prescaler::Div128] | ||
| 82 | .iter() | ||
| 83 | .skip_while(|psc| <Prescaler as Into<u32>>::into(**psc) <= val) | ||
| 84 | .next() | ||
| 85 | .unwrap() | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | pub(crate) mod sealed { | ||
| 90 | use super::*; | ||
| 91 | |||
| 92 | pub trait Instance: RccPeripheral { | ||
| 93 | fn regs() -> crate::pac::hrtim::Hrtim; | ||
| 94 | |||
| 95 | fn set_master_frequency(frequency: Hertz); | ||
| 96 | |||
| 97 | fn set_channel_frequency(channnel: usize, frequency: Hertz); | ||
| 98 | |||
| 99 | /// Set the dead time as a proportion of max_duty | ||
| 100 | fn set_channel_dead_time(channnel: usize, dead_time: u16); | ||
| 101 | |||
| 102 | // fn enable_outputs(enable: bool); | ||
| 103 | // | ||
| 104 | // fn enable_channel(&mut self, channel: usize, enable: bool); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | pub trait Instance: sealed::Instance + 'static {} | ||
| 109 | |||
| 110 | foreach_interrupt! { | ||
| 111 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { | ||
| 112 | impl sealed::Instance for crate::peripherals::$inst { | ||
| 113 | fn regs() -> crate::pac::hrtim::Hrtim { | ||
| 114 | crate::pac::$inst | ||
| 115 | } | ||
| 116 | |||
| 117 | fn set_master_frequency(frequency: Hertz) { | ||
| 118 | use crate::rcc::sealed::RccPeripheral; | ||
| 119 | |||
| 120 | let f = frequency.0; | ||
| 121 | let timer_f = Self::frequency().0; | ||
| 122 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 123 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 124 | Prescaler::compute_min_high_res(psc_min) | ||
| 125 | } else { | ||
| 126 | Prescaler::compute_min_low_res(psc_min) | ||
| 127 | }; | ||
| 128 | |||
| 129 | let psc_val: u32 = psc.into(); | ||
| 130 | let timer_f = 32 * (timer_f / psc_val); | ||
| 131 | let per: u16 = (timer_f / f) as u16; | ||
| 132 | |||
| 133 | let regs = Self::regs(); | ||
| 134 | |||
| 135 | regs.mcr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 136 | regs.mper().modify(|w| w.set_mper(per)); | ||
| 137 | } | ||
| 138 | |||
| 139 | fn set_channel_frequency(channel: usize, frequency: Hertz) { | ||
| 140 | use crate::rcc::sealed::RccPeripheral; | ||
| 141 | |||
| 142 | let f = frequency.0; | ||
| 143 | let timer_f = Self::frequency().0; | ||
| 144 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 145 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 146 | Prescaler::compute_min_high_res(psc_min) | ||
| 147 | } else { | ||
| 148 | Prescaler::compute_min_low_res(psc_min) | ||
| 149 | }; | ||
| 150 | |||
| 151 | let psc_val: u32 = psc.into(); | ||
| 152 | let timer_f = 32 * (timer_f / psc_val); | ||
| 153 | let per: u16 = (timer_f / f) as u16; | ||
| 154 | |||
| 155 | let regs = Self::regs(); | ||
| 156 | |||
| 157 | regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 158 | regs.tim(channel).per().modify(|w| w.set_per(per)); | ||
| 159 | } | ||
| 160 | |||
| 161 | fn set_channel_dead_time(channel: usize, dead_time: u16) { | ||
| 162 | |||
| 163 | let regs = Self::regs(); | ||
| 164 | |||
| 165 | let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into(); | ||
| 166 | let psc_val: u32 = channel_psc.into(); | ||
| 167 | |||
| 168 | |||
| 169 | // The dead-time base clock runs 4 times slower than the hrtim base clock | ||
| 170 | // u9::MAX = 511 | ||
| 171 | let psc_min = (psc_val * dead_time as u32) / (4 * 511); | ||
| 172 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 173 | Prescaler::compute_min_high_res(psc_min) | ||
| 174 | } else { | ||
| 175 | Prescaler::compute_min_low_res(psc_min) | ||
| 176 | }; | ||
| 177 | |||
| 178 | let dt_psc_val: u32 = psc.into(); | ||
| 179 | let dt_val = (dt_psc_val * dead_time as u32) / (4 * psc_val); | ||
| 180 | |||
| 181 | regs.tim(channel).dt().modify(|w| { | ||
| 182 | w.set_dtprsc(psc.into()); | ||
| 183 | w.set_dtf(dt_val as u16); | ||
| 184 | w.set_dtr(dt_val as u16); | ||
| 185 | }); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | impl Instance for crate::peripherals::$inst { | ||
| 190 | |||
| 191 | } | ||
| 192 | }; | ||
| 193 | } | ||
diff --git a/embassy-stm32/src/i2c/timeout.rs b/embassy-stm32/src/i2c/timeout.rs index 939e2750e..8dc228b34 100644 --- a/embassy-stm32/src/i2c/timeout.rs +++ b/embassy-stm32/src/i2c/timeout.rs | |||
| @@ -6,8 +6,8 @@ use super::{Error, I2c, Instance}; | |||
| 6 | /// | 6 | /// |
| 7 | /// This is useful for recovering from a shorted bus or a device stuck in a clock stretching state. | 7 | /// This is useful for recovering from a shorted bus or a device stuck in a clock stretching state. |
| 8 | /// A regular [I2c] would freeze until condition is removed. | 8 | /// A regular [I2c] would freeze until condition is removed. |
| 9 | pub struct TimeoutI2c<'d, T: Instance, TXDMA, RXDMA> { | 9 | pub struct TimeoutI2c<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> { |
| 10 | i2c: &'d mut I2c<'d, T, TXDMA, RXDMA>, | 10 | i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, |
| 11 | timeout: Duration, | 11 | timeout: Duration, |
| 12 | } | 12 | } |
| 13 | 13 | ||
| @@ -22,8 +22,8 @@ fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> { | |||
| 22 | } | 22 | } |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | impl<'d, T: Instance, TXDMA, RXDMA> TimeoutI2c<'d, T, TXDMA, RXDMA> { | 25 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { |
| 26 | pub fn new(i2c: &'d mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self { | 26 | pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self { |
| 27 | Self { i2c, timeout } | 27 | Self { i2c, timeout } |
| 28 | } | 28 | } |
| 29 | 29 | ||
| @@ -65,7 +65,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> TimeoutI2c<'d, T, TXDMA, RXDMA> { | |||
| 65 | } | 65 | } |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for TimeoutI2c<'d, T, TXDMA, RXDMA> { | 68 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { |
| 69 | type Error = Error; | 69 | type Error = Error; |
| 70 | 70 | ||
| 71 | fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> { | 71 | fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -73,7 +73,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for Tim | |||
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write for TimeoutI2c<'d, T, TXDMA, RXDMA> { | 76 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { |
| 77 | type Error = Error; | 77 | type Error = Error; |
| 78 | 78 | ||
| 79 | fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { | 79 | fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { |
| @@ -81,7 +81,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write for Ti | |||
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead for TimeoutI2c<'d, T, TXDMA, RXDMA> { | 84 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead |
| 85 | for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> | ||
| 86 | { | ||
| 85 | type Error = Error; | 87 | type Error = Error; |
| 86 | 88 | ||
| 87 | fn write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { | 89 | fn write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -93,11 +95,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead fo | |||
| 93 | mod eh1 { | 95 | mod eh1 { |
| 94 | use super::*; | 96 | use super::*; |
| 95 | 97 | ||
| 96 | impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'d, T, TXDMA, RXDMA> { | 98 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { |
| 97 | type Error = Error; | 99 | type Error = Error; |
| 98 | } | 100 | } |
| 99 | 101 | ||
| 100 | impl<'d, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'d, T, TXDMA, RXDMA> { | 102 | impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> { |
| 101 | fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { | 103 | fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { |
| 102 | self.blocking_read(address, read) | 104 | self.blocking_read(address, read) |
| 103 | } | 105 | } |
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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_embedded_hal::SetConfig; | 3 | use embassy_embedded_hal::SetConfig; |
| 4 | use embassy_hal_common::{into_ref, PeripheralRef}; | 4 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 5 | 5 | ||
| 6 | use crate::dma::NoDma; | 6 | use crate::dma::NoDma; |
| 7 | use crate::gpio::sealed::AFType; | 7 | use 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; | |||
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_embedded_hal::SetConfig; | 6 | use embassy_embedded_hal::SetConfig; |
| 7 | use embassy_hal_common::drop::OnDrop; | 7 | use embassy_hal_internal::drop::OnDrop; |
| 8 | use embassy_hal_common::{into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use crate::dma::{NoDma, Transfer}; | 11 | use crate::dma::{NoDma, Transfer}; |
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index 62dda69b4..8fd3a8c6a 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_internal::into_ref; |
| 2 | 2 | ||
| 3 | use crate::gpio::sealed::{AFType, Pin as _}; | 3 | use crate::gpio::sealed::{AFType, Pin as _}; |
| 4 | use crate::gpio::AnyPin; | 4 | use crate::gpio::AnyPin; |
| @@ -165,7 +165,9 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { | |||
| 165 | mck.set_as_af(mck.af_num(), AFType::OutputPushPull); | 165 | mck.set_as_af(mck.af_num(), AFType::OutputPushPull); |
| 166 | mck.set_speed(crate::gpio::Speed::VeryHigh); | 166 | mck.set_speed(crate::gpio::Speed::VeryHigh); |
| 167 | 167 | ||
| 168 | let spi = Spi::new_internal(peri, txdma, rxdma, freq, SpiConfig::default()); | 168 | let mut spi_cfg = SpiConfig::default(); |
| 169 | spi_cfg.frequency = freq; | ||
| 170 | let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg); | ||
| 169 | 171 | ||
| 170 | #[cfg(all(rcc_f4, not(stm32f410)))] | 172 | #[cfg(all(rcc_f4, not(stm32f410)))] |
| 171 | let pclk = unsafe { get_freqs() }.plli2s.unwrap(); | 173 | let pclk = unsafe { get_freqs() }.plli2s.unwrap(); |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 45a7b5476..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. |
| 5 | pub mod fmt; | 8 | pub mod fmt; |
| 6 | include!(concat!(env!("OUT_DIR"), "/_macros.rs")); | 9 | include!(concat!(env!("OUT_DIR"), "/_macros.rs")); |
| @@ -23,6 +26,8 @@ pub mod timer; | |||
| 23 | pub mod adc; | 26 | pub mod adc; |
| 24 | #[cfg(can)] | 27 | #[cfg(can)] |
| 25 | pub mod can; | 28 | pub mod can; |
| 29 | #[cfg(crc)] | ||
| 30 | pub mod crc; | ||
| 26 | #[cfg(dac)] | 31 | #[cfg(dac)] |
| 27 | pub mod dac; | 32 | pub mod dac; |
| 28 | #[cfg(dcmi)] | 33 | #[cfg(dcmi)] |
| @@ -31,19 +36,17 @@ pub mod dcmi; | |||
| 31 | pub mod eth; | 36 | pub mod eth; |
| 32 | #[cfg(feature = "exti")] | 37 | #[cfg(feature = "exti")] |
| 33 | pub mod exti; | 38 | pub mod exti; |
| 39 | pub mod flash; | ||
| 34 | #[cfg(fmc)] | 40 | #[cfg(fmc)] |
| 35 | pub mod fmc; | 41 | pub mod fmc; |
| 42 | #[cfg(hrtim_v1)] | ||
| 43 | pub mod hrtim; | ||
| 36 | #[cfg(i2c)] | 44 | #[cfg(i2c)] |
| 37 | pub mod i2c; | 45 | pub mod i2c; |
| 38 | |||
| 39 | #[cfg(crc)] | ||
| 40 | pub mod crc; | ||
| 41 | pub mod flash; | ||
| 42 | #[cfg(all(spi_v1, rcc_f4))] | 46 | #[cfg(all(spi_v1, rcc_f4))] |
| 43 | pub mod i2s; | 47 | pub mod i2s; |
| 44 | #[cfg(stm32wb)] | 48 | #[cfg(stm32wb)] |
| 45 | pub mod ipcc; | 49 | pub mod ipcc; |
| 46 | pub mod pwm; | ||
| 47 | #[cfg(quadspi)] | 50 | #[cfg(quadspi)] |
| 48 | pub mod qspi; | 51 | pub mod qspi; |
| 49 | #[cfg(rng)] | 52 | #[cfg(rng)] |
| @@ -79,7 +82,7 @@ pub use crate::_generated::interrupt; | |||
| 79 | /// 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;`) |
| 80 | /// 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 |
| 81 | /// prove at compile-time that the right interrupts have been bound. | 84 | /// prove at compile-time that the right interrupts have been bound. |
| 82 | // 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`. |
| 83 | #[macro_export] | 86 | #[macro_export] |
| 84 | macro_rules! bind_interrupts { | 87 | macro_rules! bind_interrupts { |
| 85 | ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { | 88 | ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { |
| @@ -103,7 +106,7 @@ macro_rules! bind_interrupts { | |||
| 103 | 106 | ||
| 104 | // Reexports | 107 | // Reexports |
| 105 | pub use _generated::{peripherals, Peripherals}; | 108 | pub use _generated::{peripherals, Peripherals}; |
| 106 | pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 109 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 107 | #[cfg(feature = "unstable-pac")] | 110 | #[cfg(feature = "unstable-pac")] |
| 108 | pub use stm32_metapac as pac; | 111 | pub use stm32_metapac as pac; |
| 109 | #[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 @@ | |||
| 1 | pub mod complementary_pwm; | ||
| 2 | pub mod simple_pwm; | ||
| 3 | |||
| 4 | use stm32_metapac::timer::vals::Ckd; | ||
| 5 | |||
| 6 | #[cfg(feature = "unstable-pac")] | ||
| 7 | pub mod low_level { | ||
| 8 | pub use super::sealed::*; | ||
| 9 | } | ||
| 10 | |||
| 11 | #[derive(Clone, Copy)] | ||
| 12 | pub enum Channel { | ||
| 13 | Ch1, | ||
| 14 | Ch2, | ||
| 15 | Ch3, | ||
| 16 | Ch4, | ||
| 17 | } | ||
| 18 | |||
| 19 | impl 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)] | ||
| 31 | pub enum OutputCompareMode { | ||
| 32 | Frozen, | ||
| 33 | ActiveOnMatch, | ||
| 34 | InactiveOnMatch, | ||
| 35 | Toggle, | ||
| 36 | ForceInactive, | ||
| 37 | ForceActive, | ||
| 38 | PwmMode1, | ||
| 39 | PwmMode2, | ||
| 40 | } | ||
| 41 | |||
| 42 | impl 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 | |||
| 57 | pub(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 | |||
| 92 | pub trait CaptureCompare16bitInstance: | ||
| 93 | sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static | ||
| 94 | { | ||
| 95 | } | ||
| 96 | |||
| 97 | pub trait ComplementaryCaptureCompare16bitInstance: | ||
| 98 | sealed::ComplementaryCaptureCompare16bitInstance + crate::timer::AdvancedControlInstance + 'static | ||
| 99 | { | ||
| 100 | } | ||
| 101 | |||
| 102 | pub trait CaptureCompare32bitInstance: | ||
| 103 | sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static | ||
| 104 | { | ||
| 105 | } | ||
| 106 | |||
| 107 | #[allow(unused)] | ||
| 108 | macro_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 | |||
| 141 | foreach_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 | |||
| 255 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | ||
| 256 | pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); | ||
| 257 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | ||
| 258 | pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); | ||
| 259 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | ||
| 260 | pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); | ||
| 261 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | ||
| 262 | pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); | ||
| 263 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | ||
| 264 | pin_trait!(BreakInputPin, CaptureCompare16bitInstance); | ||
| 265 | pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); | ||
| 266 | pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); | ||
| 267 | pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); | ||
| 268 | pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | ||
| 269 | pin_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 | ||
| 3 | pub mod enums; | 3 | pub mod enums; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use enums::*; | 6 | use enums::*; |
| 7 | 7 | ||
| 8 | use crate::dma::Transfer; | 8 | use crate::dma::Transfer; |
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index df6e9047c..6a9326347 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 1 | use crate::pac::flash::vals::Latency; | 2 | use crate::pac::flash::vals::Latency; |
| 2 | use crate::pac::rcc::vals::{Hpre, Hsidiv, Ppre, Sw}; | 3 | use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; |
| 3 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 5 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -45,58 +46,6 @@ impl Into<Hsidiv> for HSIPrescaler { | |||
| 45 | } | 46 | } |
| 46 | } | 47 | } |
| 47 | 48 | ||
| 48 | /// AHB prescaler | ||
| 49 | #[derive(Clone, Copy, PartialEq)] | ||
| 50 | pub enum AHBPrescaler { | ||
| 51 | NotDivided, | ||
| 52 | Div2, | ||
| 53 | Div4, | ||
| 54 | Div8, | ||
| 55 | Div16, | ||
| 56 | Div64, | ||
| 57 | Div128, | ||
| 58 | Div256, | ||
| 59 | Div512, | ||
| 60 | } | ||
| 61 | |||
| 62 | /// APB prescaler | ||
| 63 | #[derive(Clone, Copy)] | ||
| 64 | pub enum APBPrescaler { | ||
| 65 | NotDivided, | ||
| 66 | Div2, | ||
| 67 | Div4, | ||
| 68 | Div8, | ||
| 69 | Div16, | ||
| 70 | } | ||
| 71 | |||
| 72 | impl Into<Ppre> for APBPrescaler { | ||
| 73 | fn into(self) -> Ppre { | ||
| 74 | match self { | ||
| 75 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 76 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 77 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 78 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 79 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | impl Into<Hpre> for AHBPrescaler { | ||
| 85 | fn into(self) -> Hpre { | ||
| 86 | match self { | ||
| 87 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 88 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 89 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 90 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 91 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 92 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 93 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 94 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 95 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /// Clocks configutation | 49 | /// Clocks configutation |
| 101 | pub struct Config { | 50 | pub struct Config { |
| 102 | pub mux: ClockSrc, | 51 | pub mux: ClockSrc, |
diff --git a/embassy-stm32/src/rcc/common.rs b/embassy-stm32/src/rcc/common.rs new file mode 100644 index 000000000..62736a43a --- /dev/null +++ b/embassy-stm32/src/rcc/common.rs | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | use core::ops::Div; | ||
| 2 | |||
| 3 | #[allow(unused_imports)] | ||
| 4 | use crate::pac::rcc; | ||
| 5 | use crate::time::Hertz; | ||
| 6 | |||
| 7 | /// Voltage Scale | ||
| 8 | /// | ||
| 9 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 10 | /// clock frequency depends on this value. | ||
| 11 | /// | ||
| 12 | /// Scale0 represents the highest voltage range | ||
| 13 | #[derive(Copy, Clone, PartialEq)] | ||
| 14 | pub enum VoltageScale { | ||
| 15 | Scale0, | ||
| 16 | Scale1, | ||
| 17 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | ||
| 18 | Scale2, | ||
| 19 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | ||
| 20 | Scale3, | ||
| 21 | } | ||
| 22 | |||
| 23 | /// AHB prescaler | ||
| 24 | #[derive(Clone, Copy, PartialEq)] | ||
| 25 | pub enum AHBPrescaler { | ||
| 26 | NotDivided, | ||
| 27 | Div2, | ||
| 28 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 29 | Div3, | ||
| 30 | Div4, | ||
| 31 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 32 | Div5, | ||
| 33 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 34 | Div6, | ||
| 35 | Div8, | ||
| 36 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 37 | Div10, | ||
| 38 | Div16, | ||
| 39 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 40 | Div32, | ||
| 41 | Div64, | ||
| 42 | Div128, | ||
| 43 | Div256, | ||
| 44 | Div512, | ||
| 45 | } | ||
| 46 | |||
| 47 | impl Div<AHBPrescaler> for Hertz { | ||
| 48 | type Output = Hertz; | ||
| 49 | |||
| 50 | fn div(self, rhs: AHBPrescaler) -> Self::Output { | ||
| 51 | let divisor = match rhs { | ||
| 52 | AHBPrescaler::NotDivided => 1, | ||
| 53 | AHBPrescaler::Div2 => 2, | ||
| 54 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 55 | AHBPrescaler::Div3 => 3, | ||
| 56 | AHBPrescaler::Div4 => 4, | ||
| 57 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 58 | AHBPrescaler::Div5 => 5, | ||
| 59 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 60 | AHBPrescaler::Div6 => 6, | ||
| 61 | AHBPrescaler::Div8 => 8, | ||
| 62 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 63 | AHBPrescaler::Div10 => 10, | ||
| 64 | AHBPrescaler::Div16 => 16, | ||
| 65 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 66 | AHBPrescaler::Div32 => 32, | ||
| 67 | AHBPrescaler::Div64 => 64, | ||
| 68 | AHBPrescaler::Div128 => 128, | ||
| 69 | AHBPrescaler::Div256 => 256, | ||
| 70 | AHBPrescaler::Div512 => 512, | ||
| 71 | }; | ||
| 72 | Hertz(self.0 / divisor) | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | #[cfg(not(any(rcc_g4, rcc_wb, rcc_wl5, rcc_wle)))] | ||
| 77 | impl From<AHBPrescaler> for rcc::vals::Hpre { | ||
| 78 | fn from(val: AHBPrescaler) -> rcc::vals::Hpre { | ||
| 79 | use rcc::vals::Hpre; | ||
| 80 | |||
| 81 | match val { | ||
| 82 | #[cfg(not(rcc_u5))] | ||
| 83 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 84 | #[cfg(rcc_u5)] | ||
| 85 | AHBPrescaler::NotDivided => Hpre::NONE, | ||
| 86 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 87 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 88 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 89 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 90 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 91 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 92 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 93 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 99 | impl From<AHBPrescaler> for u8 { | ||
| 100 | fn from(val: AHBPrescaler) -> u8 { | ||
| 101 | match val { | ||
| 102 | AHBPrescaler::NotDivided => 0x0, | ||
| 103 | AHBPrescaler::Div2 => 0x08, | ||
| 104 | AHBPrescaler::Div3 => 0x01, | ||
| 105 | AHBPrescaler::Div4 => 0x09, | ||
| 106 | AHBPrescaler::Div5 => 0x02, | ||
| 107 | AHBPrescaler::Div6 => 0x05, | ||
| 108 | AHBPrescaler::Div8 => 0x0a, | ||
| 109 | AHBPrescaler::Div10 => 0x06, | ||
| 110 | AHBPrescaler::Div16 => 0x0b, | ||
| 111 | AHBPrescaler::Div32 => 0x07, | ||
| 112 | AHBPrescaler::Div64 => 0x0c, | ||
| 113 | AHBPrescaler::Div128 => 0x0d, | ||
| 114 | AHBPrescaler::Div256 => 0x0e, | ||
| 115 | AHBPrescaler::Div512 => 0x0f, | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | /// APB prescaler | ||
| 121 | #[derive(Clone, Copy)] | ||
| 122 | pub enum APBPrescaler { | ||
| 123 | NotDivided, | ||
| 124 | Div2, | ||
| 125 | Div4, | ||
| 126 | Div8, | ||
| 127 | Div16, | ||
| 128 | } | ||
| 129 | |||
| 130 | impl Div<APBPrescaler> for Hertz { | ||
| 131 | type Output = Hertz; | ||
| 132 | |||
| 133 | fn div(self, rhs: APBPrescaler) -> Self::Output { | ||
| 134 | let divisor = match rhs { | ||
| 135 | APBPrescaler::NotDivided => 1, | ||
| 136 | APBPrescaler::Div2 => 2, | ||
| 137 | APBPrescaler::Div4 => 4, | ||
| 138 | APBPrescaler::Div8 => 8, | ||
| 139 | APBPrescaler::Div16 => 16, | ||
| 140 | }; | ||
| 141 | Hertz(self.0 / divisor) | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | #[cfg(not(any(rcc_f1, rcc_f100, rcc_f1cl, rcc_g4, rcc_h7, rcc_h7ab, rcc_wb, rcc_wl5, rcc_wle)))] | ||
| 146 | impl From<APBPrescaler> for rcc::vals::Ppre { | ||
| 147 | fn from(val: APBPrescaler) -> rcc::vals::Ppre { | ||
| 148 | use rcc::vals::Ppre; | ||
| 149 | |||
| 150 | match val { | ||
| 151 | #[cfg(not(rcc_u5))] | ||
| 152 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 153 | #[cfg(rcc_u5)] | ||
| 154 | APBPrescaler::NotDivided => Ppre::NONE, | ||
| 155 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 156 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 157 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 158 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | #[cfg(any(rcc_wb, rcc_wl5, rcc_wle))] | ||
| 164 | impl From<APBPrescaler> for u8 { | ||
| 165 | fn from(val: APBPrescaler) -> u8 { | ||
| 166 | match val { | ||
| 167 | APBPrescaler::NotDivided => 1, | ||
| 168 | APBPrescaler::Div2 => 0x04, | ||
| 169 | APBPrescaler::Div4 => 0x05, | ||
| 170 | APBPrescaler::Div8 => 0x06, | ||
| 171 | APBPrescaler::Div16 => 0x07, | ||
| 172 | } | ||
| 173 | } | ||
| 174 | } | ||
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 1525cc3c3..d016d1dea 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | use core::convert::TryFrom; | 1 | use core::convert::TryFrom; |
| 2 | use core::ops::{Div, Mul}; | 2 | use core::ops::{Div, Mul}; |
| 3 | 3 | ||
| 4 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 4 | use crate::pac::flash::vals::Latency; | 5 | use crate::pac::flash::vals::Latency; |
| 5 | use crate::pac::rcc::vals::{Hpre, Pllp, Pllsrc, Ppre, Sw}; | 6 | use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; |
| 6 | use crate::pac::{FLASH, RCC}; | 7 | use crate::pac::{FLASH, RCC}; |
| 7 | use crate::rcc::{set_freqs, Clocks}; | 8 | use crate::rcc::{set_freqs, Clocks}; |
| 8 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| @@ -58,7 +59,7 @@ impl Default for PLLConfig { | |||
| 58 | impl PLLConfig { | 59 | impl PLLConfig { |
| 59 | pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { | 60 | pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { |
| 60 | let in_freq = src_freq / self.pre_div; | 61 | let in_freq = src_freq / self.pre_div; |
| 61 | let vco_freq = src_freq * self.mul / self.pre_div; | 62 | let vco_freq = Hertz((src_freq.0 as u64 * self.mul.0 as u64 / self.pre_div.0 as u64) as u32); |
| 62 | let main_freq = vco_freq / self.main_div; | 63 | let main_freq = vco_freq / self.main_div; |
| 63 | let pll48_freq = vco_freq / self.pll48_div; | 64 | let pll48_freq = vco_freq / self.pll48_div; |
| 64 | PLLClocks { | 65 | PLLClocks { |
| @@ -200,114 +201,15 @@ pub struct PLLClocks { | |||
| 200 | pub pll48_freq: Hertz, | 201 | pub pll48_freq: Hertz, |
| 201 | } | 202 | } |
| 202 | 203 | ||
| 203 | /// AHB prescaler | 204 | pub use super::common::VoltageScale; |
| 204 | #[derive(Clone, Copy, PartialEq)] | ||
| 205 | pub enum AHBPrescaler { | ||
| 206 | NotDivided, | ||
| 207 | Div2, | ||
| 208 | Div4, | ||
| 209 | Div8, | ||
| 210 | Div16, | ||
| 211 | Div64, | ||
| 212 | Div128, | ||
| 213 | Div256, | ||
| 214 | Div512, | ||
| 215 | } | ||
| 216 | |||
| 217 | impl Div<AHBPrescaler> for Hertz { | ||
| 218 | type Output = Hertz; | ||
| 219 | |||
| 220 | fn div(self, rhs: AHBPrescaler) -> Self::Output { | ||
| 221 | let divisor = match rhs { | ||
| 222 | AHBPrescaler::NotDivided => 1, | ||
| 223 | AHBPrescaler::Div2 => 2, | ||
| 224 | AHBPrescaler::Div4 => 4, | ||
| 225 | AHBPrescaler::Div8 => 8, | ||
| 226 | AHBPrescaler::Div16 => 16, | ||
| 227 | AHBPrescaler::Div64 => 64, | ||
| 228 | AHBPrescaler::Div128 => 128, | ||
| 229 | AHBPrescaler::Div256 => 256, | ||
| 230 | AHBPrescaler::Div512 => 512, | ||
| 231 | }; | ||
| 232 | Hertz(self.0 / divisor) | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | /// APB prescaler | ||
| 237 | #[derive(Clone, Copy)] | ||
| 238 | pub enum APBPrescaler { | ||
| 239 | NotDivided, | ||
| 240 | Div2, | ||
| 241 | Div4, | ||
| 242 | Div8, | ||
| 243 | Div16, | ||
| 244 | } | ||
| 245 | |||
| 246 | impl Div<APBPrescaler> for Hertz { | ||
| 247 | type Output = Hertz; | ||
| 248 | |||
| 249 | fn div(self, rhs: APBPrescaler) -> Self::Output { | ||
| 250 | let divisor = match rhs { | ||
| 251 | APBPrescaler::NotDivided => 1, | ||
| 252 | APBPrescaler::Div2 => 2, | ||
| 253 | APBPrescaler::Div4 => 4, | ||
| 254 | APBPrescaler::Div8 => 8, | ||
| 255 | APBPrescaler::Div16 => 16, | ||
| 256 | }; | ||
| 257 | Hertz(self.0 / divisor) | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | impl Into<Ppre> for APBPrescaler { | ||
| 262 | fn into(self) -> Ppre { | ||
| 263 | match self { | ||
| 264 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 265 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 266 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 267 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 268 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | impl Into<Hpre> for AHBPrescaler { | ||
| 274 | fn into(self) -> Hpre { | ||
| 275 | match self { | ||
| 276 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 277 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 278 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 279 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 280 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 281 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 282 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 283 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 284 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | /// Voltage Range | ||
| 290 | /// | ||
| 291 | /// Represents the system supply voltage range | ||
| 292 | #[derive(Copy, Clone, PartialEq)] | ||
| 293 | pub enum VoltageRange { | ||
| 294 | /// 1.8 to 3.6 V | ||
| 295 | Min1V8, | ||
| 296 | /// 2.1 to 3.6 V | ||
| 297 | Min2V1, | ||
| 298 | /// 2.4 to 3.6 V | ||
| 299 | Min2V4, | ||
| 300 | /// 2.7 to 3.6 V | ||
| 301 | Min2V7, | ||
| 302 | } | ||
| 303 | 205 | ||
| 304 | impl VoltageRange { | 206 | impl VoltageScale { |
| 305 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { | 207 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { |
| 306 | let ahb_freq = ahb_freq.0; | 208 | let ahb_freq = ahb_freq.0; |
| 307 | // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock | 209 | // Reference: RM0033 - Table 3. Number of wait states according to Cortex®-M3 clock |
| 308 | // frequency | 210 | // frequency |
| 309 | match self { | 211 | match self { |
| 310 | VoltageRange::Min1V8 => { | 212 | VoltageScale::Scale3 => { |
| 311 | if ahb_freq <= 16_000_000 { | 213 | if ahb_freq <= 16_000_000 { |
| 312 | Some(Latency::WS0) | 214 | Some(Latency::WS0) |
| 313 | } else if ahb_freq <= 32_000_000 { | 215 | } else if ahb_freq <= 32_000_000 { |
| @@ -328,7 +230,7 @@ impl VoltageRange { | |||
| 328 | None | 230 | None |
| 329 | } | 231 | } |
| 330 | } | 232 | } |
| 331 | VoltageRange::Min2V1 => { | 233 | VoltageScale::Scale2 => { |
| 332 | if ahb_freq <= 18_000_000 { | 234 | if ahb_freq <= 18_000_000 { |
| 333 | Some(Latency::WS0) | 235 | Some(Latency::WS0) |
| 334 | } else if ahb_freq <= 36_000_000 { | 236 | } else if ahb_freq <= 36_000_000 { |
| @@ -347,7 +249,7 @@ impl VoltageRange { | |||
| 347 | None | 249 | None |
| 348 | } | 250 | } |
| 349 | } | 251 | } |
| 350 | VoltageRange::Min2V4 => { | 252 | VoltageScale::Scale1 => { |
| 351 | if ahb_freq <= 24_000_000 { | 253 | if ahb_freq <= 24_000_000 { |
| 352 | Some(Latency::WS0) | 254 | Some(Latency::WS0) |
| 353 | } else if ahb_freq <= 48_000_000 { | 255 | } else if ahb_freq <= 48_000_000 { |
| @@ -362,7 +264,7 @@ impl VoltageRange { | |||
| 362 | None | 264 | None |
| 363 | } | 265 | } |
| 364 | } | 266 | } |
| 365 | VoltageRange::Min2V7 => { | 267 | VoltageScale::Scale0 => { |
| 366 | if ahb_freq <= 30_000_000 { | 268 | if ahb_freq <= 30_000_000 { |
| 367 | Some(Latency::WS0) | 269 | Some(Latency::WS0) |
| 368 | } else if ahb_freq <= 60_000_000 { | 270 | } else if ahb_freq <= 60_000_000 { |
| @@ -386,7 +288,7 @@ pub struct Config { | |||
| 386 | pub pll_mux: PLLSrc, | 288 | pub pll_mux: PLLSrc, |
| 387 | pub pll: PLLConfig, | 289 | pub pll: PLLConfig, |
| 388 | pub mux: ClockSrc, | 290 | pub mux: ClockSrc, |
| 389 | pub voltage: VoltageRange, | 291 | pub voltage: VoltageScale, |
| 390 | pub ahb_pre: AHBPrescaler, | 292 | pub ahb_pre: AHBPrescaler, |
| 391 | pub apb1_pre: APBPrescaler, | 293 | pub apb1_pre: APBPrescaler, |
| 392 | pub apb2_pre: APBPrescaler, | 294 | pub apb2_pre: APBPrescaler, |
| @@ -400,7 +302,7 @@ impl Default for Config { | |||
| 400 | hsi: true, | 302 | hsi: true, |
| 401 | pll_mux: PLLSrc::HSI, | 303 | pll_mux: PLLSrc::HSI, |
| 402 | pll: PLLConfig::default(), | 304 | pll: PLLConfig::default(), |
| 403 | voltage: VoltageRange::Min1V8, | 305 | voltage: VoltageScale::Scale3, |
| 404 | mux: ClockSrc::HSI, | 306 | mux: ClockSrc::HSI, |
| 405 | ahb_pre: AHBPrescaler::NotDivided, | 307 | ahb_pre: AHBPrescaler::NotDivided, |
| 406 | apb1_pre: APBPrescaler::NotDivided, | 308 | apb1_pre: APBPrescaler::NotDivided, |
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 2deee80d6..321270a70 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs | |||
| @@ -264,6 +264,7 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { | |||
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | #[inline] | 266 | #[inline] |
| 267 | #[allow(unused_variables)] | ||
| 267 | fn get_usb_pre(config: &Config, sysclk: u32, pclk1: u32, pll_config: &Option<PllConfig>) -> Usbpre { | 268 | fn get_usb_pre(config: &Config, sysclk: u32, pclk1: u32, pll_config: &Option<PllConfig>) -> Usbpre { |
| 268 | cfg_if::cfg_if! { | 269 | cfg_if::cfg_if! { |
| 269 | // Some chips do not have USB | 270 | // Some chips do not have USB |
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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; | 4 | use stm32_metapac::rcc::vals::{Mco1, Mco2, Mcopre}; |
| 5 | 5 | ||
| 6 | use super::sealed::RccPeripheral; | 6 | use super::sealed::RccPeripheral; |
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 5e3a7911a..bf2d5199e 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 1 | use crate::pac::flash::vals::Latency; | 2 | use crate::pac::flash::vals::Latency; |
| 2 | use crate::pac::rcc::vals::{self, Hpre, Hsidiv, Ppre, Sw}; | 3 | use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; |
| 3 | use crate::pac::{FLASH, PWR, RCC}; | 4 | use crate::pac::{FLASH, PWR, RCC}; |
| 4 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 5 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -172,58 +173,6 @@ impl From<Pllr> for u32 { | |||
| 172 | } | 173 | } |
| 173 | } | 174 | } |
| 174 | 175 | ||
| 175 | /// AHB prescaler | ||
| 176 | #[derive(Clone, Copy, PartialEq)] | ||
| 177 | pub enum AHBPrescaler { | ||
| 178 | NotDivided, | ||
| 179 | Div2, | ||
| 180 | Div4, | ||
| 181 | Div8, | ||
| 182 | Div16, | ||
| 183 | Div64, | ||
| 184 | Div128, | ||
| 185 | Div256, | ||
| 186 | Div512, | ||
| 187 | } | ||
| 188 | |||
| 189 | /// APB prescaler | ||
| 190 | #[derive(Clone, Copy)] | ||
| 191 | pub enum APBPrescaler { | ||
| 192 | NotDivided, | ||
| 193 | Div2, | ||
| 194 | Div4, | ||
| 195 | Div8, | ||
| 196 | Div16, | ||
| 197 | } | ||
| 198 | |||
| 199 | impl Into<Ppre> for APBPrescaler { | ||
| 200 | fn into(self) -> Ppre { | ||
| 201 | match self { | ||
| 202 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 203 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 204 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 205 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 206 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | impl Into<Hpre> for AHBPrescaler { | ||
| 212 | fn into(self) -> Hpre { | ||
| 213 | match self { | ||
| 214 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 215 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 216 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 217 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 218 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 219 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 220 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 221 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 222 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 223 | } | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | /// Clocks configutation | 176 | /// Clocks configutation |
| 228 | pub struct Config { | 177 | pub struct Config { |
| 229 | pub mux: ClockSrc, | 178 | pub mux: ClockSrc, |
| @@ -425,25 +374,14 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 425 | FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); | 374 | FLASH.acr().modify(|w| w.set_latency(target_flash_latency)); |
| 426 | } | 375 | } |
| 427 | 376 | ||
| 428 | let ahb_div = match config.ahb_pre { | 377 | let ahb_freq = Hertz(sys_clk) / config.ahb_pre; |
| 429 | AHBPrescaler::NotDivided => 1, | ||
| 430 | AHBPrescaler::Div2 => 2, | ||
| 431 | AHBPrescaler::Div4 => 4, | ||
| 432 | AHBPrescaler::Div8 => 8, | ||
| 433 | AHBPrescaler::Div16 => 16, | ||
| 434 | AHBPrescaler::Div64 => 64, | ||
| 435 | AHBPrescaler::Div128 => 128, | ||
| 436 | AHBPrescaler::Div256 => 256, | ||
| 437 | AHBPrescaler::Div512 => 512, | ||
| 438 | }; | ||
| 439 | let ahb_freq = sys_clk / ahb_div; | ||
| 440 | 378 | ||
| 441 | let (apb_freq, apb_tim_freq) = match config.apb_pre { | 379 | let (apb_freq, apb_tim_freq) = match config.apb_pre { |
| 442 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | 380 | APBPrescaler::NotDivided => (ahb_freq.0, ahb_freq.0), |
| 443 | pre => { | 381 | pre => { |
| 444 | let pre: Ppre = pre.into(); | 382 | let pre: Ppre = pre.into(); |
| 445 | let pre: u8 = 1 << (pre.to_bits() - 3); | 383 | let pre: u8 = 1 << (pre.to_bits() - 3); |
| 446 | let freq = ahb_freq / pre as u32; | 384 | let freq = ahb_freq.0 / pre as u32; |
| 447 | (freq, freq * 2) | 385 | (freq, freq * 2) |
| 448 | } | 386 | } |
| 449 | }; | 387 | }; |
| @@ -455,7 +393,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 455 | 393 | ||
| 456 | set_freqs(Clocks { | 394 | set_freqs(Clocks { |
| 457 | sys: Hertz(sys_clk), | 395 | sys: Hertz(sys_clk), |
| 458 | ahb1: Hertz(ahb_freq), | 396 | ahb1: ahb_freq, |
| 459 | apb1: Hertz(apb_freq), | 397 | apb1: Hertz(apb_freq), |
| 460 | apb1_tim: Hertz(apb_tim_freq), | 398 | apb1_tim: Hertz(apb_tim_freq), |
| 461 | }); | 399 | }); |
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index ff8f97541..dff04023e 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs | |||
| @@ -2,6 +2,7 @@ use stm32_metapac::flash::vals::Latency; | |||
| 2 | use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; | 2 | use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; |
| 3 | use stm32_metapac::FLASH; | 3 | use stm32_metapac::FLASH; |
| 4 | 4 | ||
| 5 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 5 | use crate::pac::{PWR, RCC}; | 6 | use crate::pac::{PWR, RCC}; |
| 6 | use crate::rcc::sealed::RccPeripheral; | 7 | use crate::rcc::sealed::RccPeripheral; |
| 7 | use crate::rcc::{set_freqs, Clocks}; | 8 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -21,30 +22,6 @@ pub enum ClockSrc { | |||
| 21 | PLL, | 22 | PLL, |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | /// AHB prescaler | ||
| 25 | #[derive(Clone, Copy, PartialEq)] | ||
| 26 | pub enum AHBPrescaler { | ||
| 27 | NotDivided, | ||
| 28 | Div2, | ||
| 29 | Div4, | ||
| 30 | Div8, | ||
| 31 | Div16, | ||
| 32 | Div64, | ||
| 33 | Div128, | ||
| 34 | Div256, | ||
| 35 | Div512, | ||
| 36 | } | ||
| 37 | |||
| 38 | /// APB prescaler | ||
| 39 | #[derive(Clone, Copy)] | ||
| 40 | pub enum APBPrescaler { | ||
| 41 | NotDivided, | ||
| 42 | Div2, | ||
| 43 | Div4, | ||
| 44 | Div8, | ||
| 45 | Div16, | ||
| 46 | } | ||
| 47 | |||
| 48 | /// PLL clock input source | 25 | /// PLL clock input source |
| 49 | #[derive(Clone, Copy, Debug)] | 26 | #[derive(Clone, Copy, Debug)] |
| 50 | pub enum PllSrc { | 27 | pub enum PllSrc { |
diff --git a/embassy-stm32/src/rcc/h5.rs b/embassy-stm32/src/rcc/h5.rs index 7e2f75ab7..2e72b1931 100644 --- a/embassy-stm32/src/rcc/h5.rs +++ b/embassy-stm32/src/rcc/h5.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use stm32_metapac::rcc::vals::{Hpre, Ppre, Timpre}; | 3 | use stm32_metapac::rcc::vals::Timpre; |
| 4 | 4 | ||
| 5 | use crate::pac::pwr::vals::Vos; | 5 | use crate::pac::pwr::vals::Vos; |
| 6 | use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; | 6 | use crate::pac::rcc::vals::{Hseext, Hsidiv, Mco1, Mco2, Pllrge, Pllsrc, Pllvcosel, Sw}; |
| @@ -26,21 +26,7 @@ const VCO_MAX: u32 = 420_000_000; | |||
| 26 | const VCO_WIDE_MIN: u32 = 128_000_000; | 26 | const VCO_WIDE_MIN: u32 = 128_000_000; |
| 27 | const VCO_WIDE_MAX: u32 = 560_000_000; | 27 | const VCO_WIDE_MAX: u32 = 560_000_000; |
| 28 | 28 | ||
| 29 | /// Voltage Scale | 29 | pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; |
| 30 | /// | ||
| 31 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 32 | /// clock frequency depends on this value. | ||
| 33 | #[derive(Copy, Clone, PartialEq)] | ||
| 34 | pub enum VoltageScale { | ||
| 35 | /// VOS 0 range VCORE 1.30V - 1.40V | ||
| 36 | Scale0, | ||
| 37 | /// VOS 1 range VCORE 1.15V - 1.26V | ||
| 38 | Scale1, | ||
| 39 | /// VOS 2 range VCORE 1.05V - 1.15V | ||
| 40 | Scale2, | ||
| 41 | /// VOS 3 range VCORE 0.95V - 1.05V | ||
| 42 | Scale3, | ||
| 43 | } | ||
| 44 | 30 | ||
| 45 | pub enum HseMode { | 31 | pub enum HseMode { |
| 46 | /// crystal/ceramic oscillator (HSEBYP=0) | 32 | /// crystal/ceramic oscillator (HSEBYP=0) |
| @@ -105,57 +91,7 @@ pub struct Pll { | |||
| 105 | pub divr: Option<u16>, | 91 | pub divr: Option<u16>, |
| 106 | } | 92 | } |
| 107 | 93 | ||
| 108 | /// AHB prescaler | ||
| 109 | #[derive(Clone, Copy, PartialEq)] | ||
| 110 | pub enum AHBPrescaler { | ||
| 111 | NotDivided, | ||
| 112 | Div2, | ||
| 113 | Div4, | ||
| 114 | Div8, | ||
| 115 | Div16, | ||
| 116 | Div64, | ||
| 117 | Div128, | ||
| 118 | Div256, | ||
| 119 | Div512, | ||
| 120 | } | ||
| 121 | |||
| 122 | impl AHBPrescaler { | ||
| 123 | fn div(&self, clk: Hertz) -> Hertz { | ||
| 124 | match self { | ||
| 125 | Self::NotDivided => clk, | ||
| 126 | Self::Div2 => clk / 2u32, | ||
| 127 | Self::Div4 => clk / 4u32, | ||
| 128 | Self::Div8 => clk / 8u32, | ||
| 129 | Self::Div16 => clk / 16u32, | ||
| 130 | Self::Div64 => clk / 64u32, | ||
| 131 | Self::Div128 => clk / 128u32, | ||
| 132 | Self::Div256 => clk / 256u32, | ||
| 133 | Self::Div512 => clk / 512u32, | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | /// APB prescaler | ||
| 139 | #[derive(Clone, Copy)] | ||
| 140 | pub enum APBPrescaler { | ||
| 141 | NotDivided, | ||
| 142 | Div2, | ||
| 143 | Div4, | ||
| 144 | Div8, | ||
| 145 | Div16, | ||
| 146 | } | ||
| 147 | |||
| 148 | impl APBPrescaler { | 94 | impl APBPrescaler { |
| 149 | fn div(&self, clk: Hertz) -> Hertz { | ||
| 150 | match self { | ||
| 151 | Self::NotDivided => clk, | ||
| 152 | Self::Div2 => clk / 2u32, | ||
| 153 | Self::Div4 => clk / 4u32, | ||
| 154 | Self::Div8 => clk / 8u32, | ||
| 155 | Self::Div16 => clk / 16u32, | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | fn div_tim(&self, clk: Hertz, tim: TimerPrescaler) -> Hertz { | 95 | fn div_tim(&self, clk: Hertz, tim: TimerPrescaler) -> Hertz { |
| 160 | match (tim, self) { | 96 | match (tim, self) { |
| 161 | // The timers kernel clock is equal to rcc_hclk1 if PPRE1 or PPRE2 corresponds to a | 97 | // The timers kernel clock is equal to rcc_hclk1 if PPRE1 or PPRE2 corresponds to a |
| @@ -193,34 +129,6 @@ impl From<TimerPrescaler> for Timpre { | |||
| 193 | } | 129 | } |
| 194 | } | 130 | } |
| 195 | 131 | ||
| 196 | impl From<APBPrescaler> for Ppre { | ||
| 197 | fn from(val: APBPrescaler) -> Ppre { | ||
| 198 | match val { | ||
| 199 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 200 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 201 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 202 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 203 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | impl From<AHBPrescaler> for Hpre { | ||
| 209 | fn from(val: AHBPrescaler) -> Hpre { | ||
| 210 | match val { | ||
| 211 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 212 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 213 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 214 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 215 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 216 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 217 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 218 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 219 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | /// Configuration of the core clocks | 132 | /// Configuration of the core clocks |
| 225 | #[non_exhaustive] | 133 | #[non_exhaustive] |
| 226 | pub struct Config { | 134 | pub struct Config { |
| @@ -406,13 +314,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 406 | }; | 314 | }; |
| 407 | assert!(sys <= max_clk); | 315 | assert!(sys <= max_clk); |
| 408 | 316 | ||
| 409 | let hclk = config.ahb_pre.div(sys); | 317 | let hclk = sys / config.ahb_pre; |
| 410 | 318 | ||
| 411 | let apb1 = config.apb1_pre.div(hclk); | 319 | let apb1 = hclk / config.apb1_pre; |
| 412 | let apb1_tim = config.apb1_pre.div_tim(hclk, config.timer_prescaler); | 320 | let apb1_tim = config.apb1_pre.div_tim(hclk, config.timer_prescaler); |
| 413 | let apb2 = config.apb2_pre.div(hclk); | 321 | let apb2 = hclk / config.apb2_pre; |
| 414 | let apb2_tim = config.apb2_pre.div_tim(hclk, config.timer_prescaler); | 322 | let apb2_tim = config.apb2_pre.div_tim(hclk, config.timer_prescaler); |
| 415 | let apb3 = config.apb3_pre.div(hclk); | 323 | let apb3 = hclk / config.apb3_pre; |
| 416 | 324 | ||
| 417 | flash_setup(hclk, config.voltage_scale); | 325 | flash_setup(hclk, config.voltage_scale); |
| 418 | 326 | ||
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index 7e5cd0d1a..0788b0640 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | pub use pll::PllConfig; | 4 | pub use pll::PllConfig; |
| 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; | 5 | use stm32_metapac::rcc::vals::{Mco1, Mco2}; |
| 6 | 6 | ||
| @@ -24,21 +24,7 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); | |||
| 24 | /// LSI speed | 24 | /// LSI speed |
| 25 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 25 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 26 | 26 | ||
| 27 | /// Voltage Scale | 27 | pub use super::common::VoltageScale; |
| 28 | /// | ||
| 29 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 30 | /// clock frequency depends on this value. | ||
| 31 | #[derive(Copy, Clone, PartialEq)] | ||
| 32 | pub enum VoltageScale { | ||
| 33 | /// VOS 0 range VCORE 1.26V - 1.40V | ||
| 34 | Scale0, | ||
| 35 | /// VOS 1 range VCORE 1.15V - 1.26V | ||
| 36 | Scale1, | ||
| 37 | /// VOS 2 range VCORE 1.05V - 1.15V | ||
| 38 | Scale2, | ||
| 39 | /// VOS 3 range VCORE 0.95V - 1.05V | ||
| 40 | Scale3, | ||
| 41 | } | ||
| 42 | 28 | ||
| 43 | #[derive(Clone, Copy)] | 29 | #[derive(Clone, Copy)] |
| 44 | pub enum AdcClockSource { | 30 | pub enum AdcClockSource { |
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 46a528e31..46b58ca7c 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 1 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; |
| 2 | use crate::pac::RCC; | 3 | use crate::pac::RCC; |
| 3 | #[cfg(crs)] | 4 | #[cfg(crs)] |
| @@ -70,30 +71,6 @@ pub enum PLLMul { | |||
| 70 | Mul48, | 71 | Mul48, |
| 71 | } | 72 | } |
| 72 | 73 | ||
| 73 | /// AHB prescaler | ||
| 74 | #[derive(Clone, Copy, PartialEq)] | ||
| 75 | pub enum AHBPrescaler { | ||
| 76 | NotDivided, | ||
| 77 | Div2, | ||
| 78 | Div4, | ||
| 79 | Div8, | ||
| 80 | Div16, | ||
| 81 | Div64, | ||
| 82 | Div128, | ||
| 83 | Div256, | ||
| 84 | Div512, | ||
| 85 | } | ||
| 86 | |||
| 87 | /// APB prescaler | ||
| 88 | #[derive(Clone, Copy)] | ||
| 89 | pub enum APBPrescaler { | ||
| 90 | NotDivided, | ||
| 91 | Div2, | ||
| 92 | Div4, | ||
| 93 | Div8, | ||
| 94 | Div16, | ||
| 95 | } | ||
| 96 | |||
| 97 | /// PLL clock input source | 74 | /// PLL clock input source |
| 98 | #[derive(Clone, Copy)] | 75 | #[derive(Clone, Copy)] |
| 99 | pub enum PLLSource { | 76 | pub enum PLLSource { |
| @@ -136,34 +113,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 136 | } | 113 | } |
| 137 | } | 114 | } |
| 138 | 115 | ||
| 139 | impl From<APBPrescaler> for Ppre { | ||
| 140 | fn from(val: APBPrescaler) -> Ppre { | ||
| 141 | match val { | ||
| 142 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 143 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 144 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 145 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 146 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | impl From<AHBPrescaler> for Hpre { | ||
| 152 | fn from(val: AHBPrescaler) -> Hpre { | ||
| 153 | match val { | ||
| 154 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 155 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 156 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 157 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 158 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 159 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 160 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 161 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 162 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | impl From<MSIRange> for Msirange { | 116 | impl From<MSIRange> for Msirange { |
| 168 | fn from(val: MSIRange) -> Msirange { | 117 | fn from(val: MSIRange) -> Msirange { |
| 169 | match val { | 118 | match val { |
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index 59a6eac8f..bdfc5b87a 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 1 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; |
| 2 | use crate::pac::{FLASH, RCC}; | 3 | use crate::pac::{FLASH, RCC}; |
| 3 | use crate::rcc::{set_freqs, Clocks}; | 4 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -68,30 +69,6 @@ pub enum PLLMul { | |||
| 68 | Mul48, | 69 | Mul48, |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | /// AHB prescaler | ||
| 72 | #[derive(Clone, Copy, PartialEq)] | ||
| 73 | pub enum AHBPrescaler { | ||
| 74 | NotDivided, | ||
| 75 | Div2, | ||
| 76 | Div4, | ||
| 77 | Div8, | ||
| 78 | Div16, | ||
| 79 | Div64, | ||
| 80 | Div128, | ||
| 81 | Div256, | ||
| 82 | Div512, | ||
| 83 | } | ||
| 84 | |||
| 85 | /// APB prescaler | ||
| 86 | #[derive(Clone, Copy)] | ||
| 87 | pub enum APBPrescaler { | ||
| 88 | NotDivided, | ||
| 89 | Div2, | ||
| 90 | Div4, | ||
| 91 | Div8, | ||
| 92 | Div16, | ||
| 93 | } | ||
| 94 | |||
| 95 | /// PLL clock input source | 72 | /// PLL clock input source |
| 96 | #[derive(Clone, Copy)] | 73 | #[derive(Clone, Copy)] |
| 97 | pub enum PLLSource { | 74 | pub enum PLLSource { |
| @@ -134,34 +111,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 134 | } | 111 | } |
| 135 | } | 112 | } |
| 136 | 113 | ||
| 137 | impl From<APBPrescaler> for Ppre { | ||
| 138 | fn from(val: APBPrescaler) -> Ppre { | ||
| 139 | match val { | ||
| 140 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 141 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 142 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 143 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 144 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | impl From<AHBPrescaler> for Hpre { | ||
| 150 | fn from(val: AHBPrescaler) -> Hpre { | ||
| 151 | match val { | ||
| 152 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 153 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 154 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 155 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 156 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 157 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 158 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 159 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 160 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 161 | } | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | impl From<MSIRange> for Msirange { | 114 | impl From<MSIRange> for Msirange { |
| 166 | fn from(val: MSIRange) -> Msirange { | 115 | fn from(val: MSIRange) -> Msirange { |
| 167 | match val { | 116 | match val { |
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 8a9b4adbf..237b7bc91 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | use stm32_metapac::rcc::regs::Cfgr; | 4 | use stm32_metapac::rcc::regs::Cfgr; |
| 5 | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; | 5 | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; |
| 6 | 6 | ||
| 7 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 7 | use crate::gpio::sealed::AFType; | 8 | use crate::gpio::sealed::AFType; |
| 8 | use crate::gpio::Speed; | 9 | use crate::gpio::Speed; |
| 9 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | 10 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; |
| @@ -78,30 +79,6 @@ pub enum PLLDiv { | |||
| 78 | Div4, | 79 | Div4, |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | /// AHB prescaler | ||
| 82 | #[derive(Clone, Copy, PartialEq)] | ||
| 83 | pub enum AHBPrescaler { | ||
| 84 | NotDivided, | ||
| 85 | Div2, | ||
| 86 | Div4, | ||
| 87 | Div8, | ||
| 88 | Div16, | ||
| 89 | Div64, | ||
| 90 | Div128, | ||
| 91 | Div256, | ||
| 92 | Div512, | ||
| 93 | } | ||
| 94 | |||
| 95 | /// APB prescaler | ||
| 96 | #[derive(Clone, Copy)] | ||
| 97 | pub enum APBPrescaler { | ||
| 98 | NotDivided, | ||
| 99 | Div2, | ||
| 100 | Div4, | ||
| 101 | Div8, | ||
| 102 | Div16, | ||
| 103 | } | ||
| 104 | |||
| 105 | /// PLL clock input source | 82 | /// PLL clock input source |
| 106 | #[derive(Clone, Copy)] | 83 | #[derive(Clone, Copy)] |
| 107 | pub enum PLLSource { | 84 | pub enum PLLSource { |
| @@ -209,34 +186,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 209 | } | 186 | } |
| 210 | } | 187 | } |
| 211 | 188 | ||
| 212 | impl From<APBPrescaler> for Ppre { | ||
| 213 | fn from(val: APBPrescaler) -> Ppre { | ||
| 214 | match val { | ||
| 215 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 216 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 217 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 218 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 219 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | impl From<AHBPrescaler> for Hpre { | ||
| 225 | fn from(val: AHBPrescaler) -> Hpre { | ||
| 226 | match val { | ||
| 227 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 228 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 229 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 230 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 231 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 232 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 233 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 234 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 235 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 236 | } | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | impl From<MSIRange> for Msirange { | 189 | impl From<MSIRange> for Msirange { |
| 241 | fn from(val: MSIRange) -> Msirange { | 190 | fn from(val: MSIRange) -> Msirange { |
| 242 | match val { | 191 | match val { |
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index 16da65d5e..a85e14889 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | use stm32_metapac::PWR; | 1 | use stm32_metapac::PWR; |
| 2 | 2 | ||
| 3 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 3 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | 4 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; |
| 4 | use crate::pac::{FLASH, RCC}; | 5 | use crate::pac::{FLASH, RCC}; |
| 5 | use crate::rcc::{set_freqs, Clocks}; | 6 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -71,30 +72,6 @@ pub enum PLLDiv { | |||
| 71 | Div4, | 72 | Div4, |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | /// AHB prescaler | ||
| 75 | #[derive(Clone, Copy, PartialEq)] | ||
| 76 | pub enum AHBPrescaler { | ||
| 77 | NotDivided, | ||
| 78 | Div2, | ||
| 79 | Div4, | ||
| 80 | Div8, | ||
| 81 | Div16, | ||
| 82 | Div64, | ||
| 83 | Div128, | ||
| 84 | Div256, | ||
| 85 | Div512, | ||
| 86 | } | ||
| 87 | |||
| 88 | /// APB prescaler | ||
| 89 | #[derive(Clone, Copy)] | ||
| 90 | pub enum APBPrescaler { | ||
| 91 | NotDivided, | ||
| 92 | Div2, | ||
| 93 | Div4, | ||
| 94 | Div8, | ||
| 95 | Div16, | ||
| 96 | } | ||
| 97 | |||
| 98 | /// PLL clock input source | 75 | /// PLL clock input source |
| 99 | #[derive(Clone, Copy)] | 76 | #[derive(Clone, Copy)] |
| 100 | pub enum PLLSource { | 77 | pub enum PLLSource { |
| @@ -202,34 +179,6 @@ impl From<PLLSource> for Pllsrc { | |||
| 202 | } | 179 | } |
| 203 | } | 180 | } |
| 204 | 181 | ||
| 205 | impl From<APBPrescaler> for Ppre { | ||
| 206 | fn from(val: APBPrescaler) -> Ppre { | ||
| 207 | match val { | ||
| 208 | APBPrescaler::NotDivided => Ppre::DIV1, | ||
| 209 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 210 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 211 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 212 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | impl From<AHBPrescaler> for Hpre { | ||
| 218 | fn from(val: AHBPrescaler) -> Hpre { | ||
| 219 | match val { | ||
| 220 | AHBPrescaler::NotDivided => Hpre::DIV1, | ||
| 221 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 222 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 223 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 224 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 225 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 226 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 227 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 228 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 229 | } | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | impl From<MSIRange> for Msirange { | 182 | impl From<MSIRange> for Msirange { |
| 234 | fn from(val: MSIRange) -> Msirange { | 183 | fn from(val: MSIRange) -> Msirange { |
| 235 | match val { | 184 | match val { |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 4ae65d3e6..5c69037ed 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | pub mod common; | ||
| 4 | |||
| 3 | use core::mem::MaybeUninit; | 5 | use core::mem::MaybeUninit; |
| 4 | 6 | ||
| 5 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index cfc07f069..b5feeb0c4 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | use stm32_metapac::rcc::vals::{Hpre, Msirange, Msirgsel, Pllm, Pllsrc, Ppre, Sw}; | 1 | use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; |
| 2 | 2 | ||
| 3 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 3 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 5 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -10,19 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||
| 10 | /// LSI speed | 11 | /// LSI speed |
| 11 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 12 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 12 | 13 | ||
| 13 | /// Voltage Scale | 14 | pub use super::common::VoltageScale; |
| 14 | /// | ||
| 15 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 16 | /// clock frequency depends on this value. | ||
| 17 | #[derive(Copy, Clone, PartialEq)] | ||
| 18 | pub enum VoltageScale { | ||
| 19 | // Highest frequency | ||
| 20 | Range1, | ||
| 21 | Range2, | ||
| 22 | Range3, | ||
| 23 | // Lowest power | ||
| 24 | Range4, | ||
| 25 | } | ||
| 26 | 15 | ||
| 27 | #[derive(Copy, Clone)] | 16 | #[derive(Copy, Clone)] |
| 28 | pub enum ClockSrc { | 17 | pub enum ClockSrc { |
| @@ -130,36 +119,6 @@ impl Into<Pllm> for PllM { | |||
| 130 | } | 119 | } |
| 131 | } | 120 | } |
| 132 | 121 | ||
| 133 | /// AHB prescaler | ||
| 134 | #[derive(Clone, Copy, PartialEq)] | ||
| 135 | pub enum AHBPrescaler { | ||
| 136 | NotDivided, | ||
| 137 | Div2, | ||
| 138 | Div4, | ||
| 139 | Div8, | ||
| 140 | Div16, | ||
| 141 | Div64, | ||
| 142 | Div128, | ||
| 143 | Div256, | ||
| 144 | Div512, | ||
| 145 | } | ||
| 146 | |||
| 147 | impl Into<Hpre> for AHBPrescaler { | ||
| 148 | fn into(self) -> Hpre { | ||
| 149 | match self { | ||
| 150 | AHBPrescaler::NotDivided => Hpre::NONE, | ||
| 151 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 152 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 153 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 154 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 155 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 156 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 157 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 158 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | impl Into<u8> for AHBPrescaler { | 122 | impl Into<u8> for AHBPrescaler { |
| 164 | fn into(self) -> u8 { | 123 | fn into(self) -> u8 { |
| 165 | match self { | 124 | match self { |
| @@ -182,28 +141,6 @@ impl Default for AHBPrescaler { | |||
| 182 | } | 141 | } |
| 183 | } | 142 | } |
| 184 | 143 | ||
| 185 | /// APB prescaler | ||
| 186 | #[derive(Clone, Copy)] | ||
| 187 | pub enum APBPrescaler { | ||
| 188 | NotDivided, | ||
| 189 | Div2, | ||
| 190 | Div4, | ||
| 191 | Div8, | ||
| 192 | Div16, | ||
| 193 | } | ||
| 194 | |||
| 195 | impl Into<Ppre> for APBPrescaler { | ||
| 196 | fn into(self) -> Ppre { | ||
| 197 | match self { | ||
| 198 | APBPrescaler::NotDivided => Ppre::NONE, | ||
| 199 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 200 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 201 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 202 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 203 | } | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | impl Default for APBPrescaler { | 144 | impl Default for APBPrescaler { |
| 208 | fn default() -> Self { | 145 | fn default() -> Self { |
| 209 | APBPrescaler::NotDivided | 146 | APBPrescaler::NotDivided |
| @@ -389,12 +326,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 389 | } | 326 | } |
| 390 | 327 | ||
| 391 | // TODO make configurable | 328 | // TODO make configurable |
| 392 | let power_vos = VoltageScale::Range4; | 329 | let power_vos = VoltageScale::Scale3; |
| 393 | 330 | ||
| 394 | // states and programming delay | 331 | // states and programming delay |
| 395 | let wait_states = match power_vos { | 332 | let wait_states = match power_vos { |
| 396 | // VOS 0 range VCORE 1.26V - 1.40V | 333 | // VOS 0 range VCORE 1.26V - 1.40V |
| 397 | VoltageScale::Range1 => { | 334 | VoltageScale::Scale0 => { |
| 398 | if sys_clk < 32_000_000 { | 335 | if sys_clk < 32_000_000 { |
| 399 | 0 | 336 | 0 |
| 400 | } else if sys_clk < 64_000_000 { | 337 | } else if sys_clk < 64_000_000 { |
| @@ -408,7 +345,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 408 | } | 345 | } |
| 409 | } | 346 | } |
| 410 | // VOS 1 range VCORE 1.15V - 1.26V | 347 | // VOS 1 range VCORE 1.15V - 1.26V |
| 411 | VoltageScale::Range2 => { | 348 | VoltageScale::Scale1 => { |
| 412 | if sys_clk < 30_000_000 { | 349 | if sys_clk < 30_000_000 { |
| 413 | 0 | 350 | 0 |
| 414 | } else if sys_clk < 60_000_000 { | 351 | } else if sys_clk < 60_000_000 { |
| @@ -420,7 +357,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 420 | } | 357 | } |
| 421 | } | 358 | } |
| 422 | // VOS 2 range VCORE 1.05V - 1.15V | 359 | // VOS 2 range VCORE 1.05V - 1.15V |
| 423 | VoltageScale::Range3 => { | 360 | VoltageScale::Scale2 => { |
| 424 | if sys_clk < 24_000_000 { | 361 | if sys_clk < 24_000_000 { |
| 425 | 0 | 362 | 0 |
| 426 | } else if sys_clk < 48_000_000 { | 363 | } else if sys_clk < 48_000_000 { |
| @@ -430,7 +367,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 430 | } | 367 | } |
| 431 | } | 368 | } |
| 432 | // VOS 3 range VCORE 0.95V - 1.05V | 369 | // VOS 3 range VCORE 0.95V - 1.05V |
| 433 | VoltageScale::Range4 => { | 370 | VoltageScale::Scale3 => { |
| 434 | if sys_clk < 12_000_000 { | 371 | if sys_clk < 12_000_000 { |
| 435 | 0 | 372 | 0 |
| 436 | } else { | 373 | } else { |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 4322b950a..21aacec58 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | ||
| 1 | use crate::rcc::Clocks; | 2 | use crate::rcc::Clocks; |
| 2 | use crate::time::{khz, mhz, Hertz}; | 3 | use crate::time::{khz, mhz, Hertz}; |
| 3 | 4 | ||
| @@ -102,68 +103,6 @@ pub struct Pll { | |||
| 102 | pub divr: Option<u16>, | 103 | pub divr: Option<u16>, |
| 103 | } | 104 | } |
| 104 | 105 | ||
| 105 | /// AHB prescaler | ||
| 106 | #[derive(Clone, Copy, PartialEq)] | ||
| 107 | pub enum AHBPrescaler { | ||
| 108 | NotDivided, | ||
| 109 | Div2, | ||
| 110 | Div3, | ||
| 111 | Div4, | ||
| 112 | Div5, | ||
| 113 | Div6, | ||
| 114 | Div8, | ||
| 115 | Div10, | ||
| 116 | Div16, | ||
| 117 | Div32, | ||
| 118 | Div64, | ||
| 119 | Div128, | ||
| 120 | Div256, | ||
| 121 | Div512, | ||
| 122 | } | ||
| 123 | |||
| 124 | /// APB prescaler | ||
| 125 | #[derive(Clone, Copy)] | ||
| 126 | pub enum APBPrescaler { | ||
| 127 | NotDivided, | ||
| 128 | Div2, | ||
| 129 | Div4, | ||
| 130 | Div8, | ||
| 131 | Div16, | ||
| 132 | } | ||
| 133 | |||
| 134 | impl Into<u8> for APBPrescaler { | ||
| 135 | fn into(self) -> u8 { | ||
| 136 | match self { | ||
| 137 | APBPrescaler::NotDivided => 1, | ||
| 138 | APBPrescaler::Div2 => 0x04, | ||
| 139 | APBPrescaler::Div4 => 0x05, | ||
| 140 | APBPrescaler::Div8 => 0x06, | ||
| 141 | APBPrescaler::Div16 => 0x07, | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | impl Into<u8> for AHBPrescaler { | ||
| 147 | fn into(self) -> u8 { | ||
| 148 | match self { | ||
| 149 | AHBPrescaler::NotDivided => 0x0, | ||
| 150 | AHBPrescaler::Div2 => 0x08, | ||
| 151 | AHBPrescaler::Div3 => 0x01, | ||
| 152 | AHBPrescaler::Div4 => 0x09, | ||
| 153 | AHBPrescaler::Div5 => 0x02, | ||
| 154 | AHBPrescaler::Div6 => 0x05, | ||
| 155 | AHBPrescaler::Div8 => 0x0a, | ||
| 156 | AHBPrescaler::Div10 => 0x06, | ||
| 157 | AHBPrescaler::Div16 => 0x0b, | ||
| 158 | AHBPrescaler::Div32 => 0x07, | ||
| 159 | AHBPrescaler::Div64 => 0x0c, | ||
| 160 | AHBPrescaler::Div128 => 0x0d, | ||
| 161 | AHBPrescaler::Div256 => 0x0e, | ||
| 162 | AHBPrescaler::Div512 => 0x0f, | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | /// Clocks configutation | 106 | /// Clocks configutation |
| 168 | pub struct Config { | 107 | pub struct Config { |
| 169 | pub hse: Option<Hse>, | 108 | pub hse: Option<Hse>, |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 6b69bb1cb..ea6e8dde6 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; | ||
| 1 | use crate::pac::pwr::vals::Dbp; | 2 | use crate::pac::pwr::vals::Dbp; |
| 2 | use crate::pac::{FLASH, PWR, RCC}; | 3 | use crate::pac::{FLASH, PWR, RCC}; |
| 3 | use crate::rcc::{set_freqs, Clocks}; | 4 | use crate::rcc::{set_freqs, Clocks}; |
| @@ -73,9 +74,9 @@ impl MSIRange { | |||
| 73 | 74 | ||
| 74 | fn vos(&self) -> VoltageScale { | 75 | fn vos(&self) -> VoltageScale { |
| 75 | if self > &MSIRange::Range8 { | 76 | if self > &MSIRange::Range8 { |
| 76 | VoltageScale::Range1 | 77 | VoltageScale::Scale0 |
| 77 | } else { | 78 | } else { |
| 78 | VoltageScale::Range2 | 79 | VoltageScale::Scale1 |
| 79 | } | 80 | } |
| 80 | } | 81 | } |
| 81 | } | 82 | } |
| @@ -105,78 +106,6 @@ impl Into<u8> for MSIRange { | |||
| 105 | } | 106 | } |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | /// Voltage Scale | ||
| 109 | /// | ||
| 110 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 111 | /// clock frequency depends on this value. | ||
| 112 | #[derive(Copy, Clone, PartialEq)] | ||
| 113 | pub enum VoltageScale { | ||
| 114 | Range1, | ||
| 115 | Range2, | ||
| 116 | } | ||
| 117 | |||
| 118 | /// AHB prescaler | ||
| 119 | #[derive(Clone, Copy, PartialEq)] | ||
| 120 | pub enum AHBPrescaler { | ||
| 121 | NotDivided, | ||
| 122 | Div2, | ||
| 123 | Div3, | ||
| 124 | Div4, | ||
| 125 | Div5, | ||
| 126 | Div6, | ||
| 127 | Div8, | ||
| 128 | Div10, | ||
| 129 | Div16, | ||
| 130 | Div32, | ||
| 131 | Div64, | ||
| 132 | Div128, | ||
| 133 | Div256, | ||
| 134 | Div512, | ||
| 135 | } | ||
| 136 | |||
| 137 | /// APB prescaler | ||
| 138 | #[derive(Clone, Copy)] | ||
| 139 | pub enum APBPrescaler { | ||
| 140 | NotDivided, | ||
| 141 | Div2, | ||
| 142 | Div4, | ||
| 143 | Div8, | ||
| 144 | Div16, | ||
| 145 | } | ||
| 146 | |||
| 147 | impl Into<u8> for APBPrescaler { | ||
| 148 | fn into(self) -> u8 { | ||
| 149 | match self { | ||
| 150 | APBPrescaler::NotDivided => 1, | ||
| 151 | APBPrescaler::Div2 => 0x04, | ||
| 152 | APBPrescaler::Div4 => 0x05, | ||
| 153 | APBPrescaler::Div8 => 0x06, | ||
| 154 | APBPrescaler::Div16 => 0x07, | ||
| 155 | } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | impl Into<u8> for AHBPrescaler { | ||
| 160 | fn into(self) -> u8 { | ||
| 161 | match self { | ||
| 162 | AHBPrescaler::NotDivided => 0x0, | ||
| 163 | AHBPrescaler::Div2 => 0x08, | ||
| 164 | AHBPrescaler::Div3 => 0x01, | ||
| 165 | AHBPrescaler::Div4 => 0x09, | ||
| 166 | AHBPrescaler::Div5 => 0x02, | ||
| 167 | AHBPrescaler::Div6 => 0x05, | ||
| 168 | AHBPrescaler::Div8 => 0x0a, | ||
| 169 | AHBPrescaler::Div10 => 0x06, | ||
| 170 | AHBPrescaler::Div16 => 0x0b, | ||
| 171 | AHBPrescaler::Div32 => 0x07, | ||
| 172 | AHBPrescaler::Div64 => 0x0c, | ||
| 173 | AHBPrescaler::Div128 => 0x0d, | ||
| 174 | AHBPrescaler::Div256 => 0x0e, | ||
| 175 | AHBPrescaler::Div512 => 0x0f, | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | /// Clocks configutation | 109 | /// Clocks configutation |
| 181 | pub struct Config { | 110 | pub struct Config { |
| 182 | pub mux: ClockSrc, | 111 | pub mux: ClockSrc, |
| @@ -220,8 +149,8 @@ pub enum Lsedrv { | |||
| 220 | 149 | ||
| 221 | pub(crate) unsafe fn init(config: Config) { | 150 | pub(crate) unsafe fn init(config: Config) { |
| 222 | let (sys_clk, sw, vos) = match config.mux { | 151 | let (sys_clk, sw, vos) = match config.mux { |
| 223 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Range2), | 152 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Scale1), |
| 224 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Range1), | 153 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Scale0), |
| 225 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), | 154 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), |
| 226 | }; | 155 | }; |
| 227 | 156 | ||
| @@ -266,12 +195,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 266 | // Adjust flash latency | 195 | // Adjust flash latency |
| 267 | let flash_clk_src_freq: u32 = shd_ahb_freq; | 196 | let flash_clk_src_freq: u32 = shd_ahb_freq; |
| 268 | let ws = match vos { | 197 | let ws = match vos { |
| 269 | VoltageScale::Range1 => match flash_clk_src_freq { | 198 | VoltageScale::Scale0 => match flash_clk_src_freq { |
| 270 | 0..=18_000_000 => 0b000, | 199 | 0..=18_000_000 => 0b000, |
| 271 | 18_000_001..=36_000_000 => 0b001, | 200 | 18_000_001..=36_000_000 => 0b001, |
| 272 | _ => 0b010, | 201 | _ => 0b010, |
| 273 | }, | 202 | }, |
| 274 | VoltageScale::Range2 => match flash_clk_src_freq { | 203 | VoltageScale::Scale1 => match flash_clk_src_freq { |
| 275 | 0..=6_000_000 => 0b000, | 204 | 0..=6_000_000 => 0b000, |
| 276 | 6_000_001..=12_000_000 => 0b001, | 205 | 6_000_001..=12_000_000 => 0b001, |
| 277 | _ => 0b010, | 206 | _ => 0b010, |
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index b2faec53d..2a4978ec5 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -1,15 +1,17 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use core::future::poll_fn; | 3 | use core::future::poll_fn; |
| 4 | use core::marker::PhantomData; | ||
| 4 | use core::task::Poll; | 5 | use core::task::Poll; |
| 5 | 6 | ||
| 6 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use rand_core::{CryptoRng, RngCore}; | 9 | use rand_core::{CryptoRng, RngCore}; |
| 9 | 10 | ||
| 10 | use crate::{pac, peripherals, Peripheral}; | 11 | use crate::interrupt::typelevel::Interrupt; |
| 12 | use crate::{interrupt, pac, peripherals, Peripheral}; | ||
| 11 | 13 | ||
| 12 | pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new(); | 14 | static RNG_WAKER: AtomicWaker = AtomicWaker::new(); |
| 13 | 15 | ||
| 14 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 15 | pub enum Error { | 17 | pub enum Error { |
| @@ -17,68 +19,145 @@ pub enum Error { | |||
| 17 | ClockError, | 19 | ClockError, |
| 18 | } | 20 | } |
| 19 | 21 | ||
| 22 | pub struct InterruptHandler<T: Instance> { | ||
| 23 | _phantom: PhantomData<T>, | ||
| 24 | } | ||
| 25 | |||
| 26 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { | ||
| 27 | unsafe fn on_interrupt() { | ||
| 28 | let bits = T::regs().sr().read(); | ||
| 29 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 30 | T::regs().cr().modify(|reg| reg.set_ie(false)); | ||
| 31 | RNG_WAKER.wake(); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 20 | pub struct Rng<'d, T: Instance> { | 36 | pub struct Rng<'d, T: Instance> { |
| 21 | _inner: PeripheralRef<'d, T>, | 37 | _inner: PeripheralRef<'d, T>, |
| 22 | } | 38 | } |
| 23 | 39 | ||
| 24 | impl<'d, T: Instance> Rng<'d, T> { | 40 | impl<'d, T: Instance> Rng<'d, T> { |
| 25 | pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self { | 41 | pub fn new( |
| 42 | inner: impl Peripheral<P = T> + 'd, | ||
| 43 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||
| 44 | ) -> Self { | ||
| 26 | T::enable(); | 45 | T::enable(); |
| 27 | T::reset(); | 46 | T::reset(); |
| 28 | into_ref!(inner); | 47 | into_ref!(inner); |
| 29 | let mut random = Self { _inner: inner }; | 48 | let mut random = Self { _inner: inner }; |
| 30 | random.reset(); | 49 | random.reset(); |
| 50 | |||
| 51 | T::Interrupt::unpend(); | ||
| 52 | unsafe { T::Interrupt::enable() }; | ||
| 53 | |||
| 31 | random | 54 | random |
| 32 | } | 55 | } |
| 33 | 56 | ||
| 57 | #[cfg(rng_v1)] | ||
| 34 | pub fn reset(&mut self) { | 58 | pub fn reset(&mut self) { |
| 35 | // rng_v2 locks up on seed error, needs reset | 59 | T::regs().cr().write(|reg| { |
| 36 | #[cfg(rng_v2)] | 60 | reg.set_rngen(false); |
| 37 | if T::regs().sr().read().seis() { | ||
| 38 | T::reset(); | ||
| 39 | } | ||
| 40 | T::regs().cr().modify(|reg| { | ||
| 41 | reg.set_rngen(true); | ||
| 42 | reg.set_ie(true); | ||
| 43 | }); | 61 | }); |
| 44 | T::regs().sr().modify(|reg| { | 62 | T::regs().sr().modify(|reg| { |
| 45 | reg.set_seis(false); | 63 | reg.set_seis(false); |
| 46 | reg.set_ceis(false); | 64 | reg.set_ceis(false); |
| 47 | }); | 65 | }); |
| 66 | T::regs().cr().modify(|reg| { | ||
| 67 | reg.set_rngen(true); | ||
| 68 | }); | ||
| 48 | // Reference manual says to discard the first. | 69 | // Reference manual says to discard the first. |
| 49 | let _ = self.next_u32(); | 70 | let _ = self.next_u32(); |
| 50 | } | 71 | } |
| 51 | 72 | ||
| 52 | pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { | 73 | #[cfg(not(rng_v1))] |
| 74 | pub fn reset(&mut self) { | ||
| 75 | T::regs().cr().write(|reg| { | ||
| 76 | reg.set_rngen(false); | ||
| 77 | reg.set_condrst(true); | ||
| 78 | // set RNG config "A" according to reference manual | ||
| 79 | // this has to be written within the same write access as setting the CONDRST bit | ||
| 80 | reg.set_nistc(pac::rng::vals::Nistc::DEFAULT); | ||
| 81 | reg.set_rng_config1(pac::rng::vals::RngConfig1::CONFIGA); | ||
| 82 | reg.set_rng_config2(pac::rng::vals::RngConfig2::CONFIGA_B); | ||
| 83 | reg.set_rng_config3(pac::rng::vals::RngConfig3::CONFIGA); | ||
| 84 | reg.set_clkdiv(pac::rng::vals::Clkdiv::NODIV); | ||
| 85 | }); | ||
| 86 | // wait for CONDRST to be set | ||
| 87 | while !T::regs().cr().read().condrst() {} | ||
| 88 | // magic number must be written immediately before every read or write access to HTCR | ||
| 89 | T::regs().htcr().write(|w| w.set_htcfg(pac::rng::vals::Htcfg::MAGIC)); | ||
| 90 | // write recommended value according to reference manual | ||
| 91 | // note: HTCR can only be written during conditioning | ||
| 92 | T::regs() | ||
| 93 | .htcr() | ||
| 94 | .write(|w| w.set_htcfg(pac::rng::vals::Htcfg::RECOMMENDED)); | ||
| 95 | // finish conditioning | ||
| 53 | T::regs().cr().modify(|reg| { | 96 | T::regs().cr().modify(|reg| { |
| 54 | reg.set_rngen(true); | 97 | reg.set_rngen(true); |
| 98 | reg.set_condrst(false); | ||
| 55 | }); | 99 | }); |
| 100 | // wait for CONDRST to be reset | ||
| 101 | while T::regs().cr().read().condrst() {} | ||
| 102 | } | ||
| 103 | |||
| 104 | pub fn recover_seed_error(&mut self) -> () { | ||
| 105 | self.reset(); | ||
| 106 | // reset should also clear the SEIS flag | ||
| 107 | if T::regs().sr().read().seis() { | ||
| 108 | warn!("recovering from seed error failed"); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | // wait for SECS to be cleared by RNG | ||
| 112 | while T::regs().sr().read().secs() {} | ||
| 113 | } | ||
| 56 | 114 | ||
| 115 | pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { | ||
| 57 | for chunk in dest.chunks_mut(4) { | 116 | for chunk in dest.chunks_mut(4) { |
| 58 | poll_fn(|cx| { | 117 | let bits = T::regs().sr().read(); |
| 59 | RNG_WAKER.register(cx.waker()); | 118 | if bits.seis() { |
| 60 | T::regs().cr().modify(|reg| { | 119 | // in case of noise-source or seed error we try to recover here |
| 61 | reg.set_ie(true); | 120 | // but we must not use the data in DR and we return an error |
| 62 | }); | 121 | // to leave retry-logic to the application |
| 63 | 122 | self.recover_seed_error(); | |
| 64 | let bits = T::regs().sr().read(); | 123 | return Err(Error::SeedError); |
| 65 | 124 | } else if bits.ceis() { | |
| 66 | if bits.drdy() { | 125 | // clock error detected, DR could still be used but keep it safe, |
| 67 | Poll::Ready(Ok(())) | 126 | // clear the error and abort |
| 68 | } else if bits.seis() { | 127 | T::regs().sr().modify(|sr| sr.set_ceis(false)); |
| 69 | self.reset(); | 128 | return Err(Error::ClockError); |
| 70 | Poll::Ready(Err(Error::SeedError)) | 129 | } else if bits.drdy() { |
| 71 | } else if bits.ceis() { | 130 | // DR can be read up to four times until the output buffer is empty |
| 72 | self.reset(); | 131 | // DRDY is cleared automatically when that happens |
| 73 | Poll::Ready(Err(Error::ClockError)) | 132 | let random_word = T::regs().dr().read(); |
| 74 | } else { | 133 | // reference manual: always check if DR is zero |
| 75 | Poll::Pending | 134 | if random_word == 0 { |
| 135 | return Err(Error::SeedError); | ||
| 136 | } | ||
| 137 | // write bytes to chunk | ||
| 138 | for (dest, src) in chunk.iter_mut().zip(random_word.to_be_bytes().iter()) { | ||
| 139 | *dest = *src | ||
| 76 | } | 140 | } |
| 77 | }) | 141 | } else { |
| 78 | .await?; | 142 | // wait for interrupt |
| 79 | let random_bytes = T::regs().dr().read().to_be_bytes(); | 143 | poll_fn(|cx| { |
| 80 | for (dest, src) in chunk.iter_mut().zip(random_bytes.iter()) { | 144 | // quick check to avoid registration if already done. |
| 81 | *dest = *src | 145 | let bits = T::regs().sr().read(); |
| 146 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 147 | return Poll::Ready(()); | ||
| 148 | } | ||
| 149 | RNG_WAKER.register(cx.waker()); | ||
| 150 | T::regs().cr().modify(|reg| reg.set_ie(true)); | ||
| 151 | // Need to check condition **after** `register` to avoid a race | ||
| 152 | // condition that would result in lost notifications. | ||
| 153 | let bits = T::regs().sr().read(); | ||
| 154 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 155 | Poll::Ready(()) | ||
| 156 | } else { | ||
| 157 | Poll::Pending | ||
| 158 | } | ||
| 159 | }) | ||
| 160 | .await; | ||
| 82 | } | 161 | } |
| 83 | } | 162 | } |
| 84 | 163 | ||
| @@ -129,57 +208,20 @@ pub(crate) mod sealed { | |||
| 129 | } | 208 | } |
| 130 | } | 209 | } |
| 131 | 210 | ||
| 132 | pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral {} | 211 | pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { |
| 212 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 213 | } | ||
| 133 | 214 | ||
| 134 | foreach_peripheral!( | 215 | foreach_interrupt!( |
| 135 | (rng, $inst:ident) => { | 216 | ($inst:ident, rng, RNG, GLOBAL, $irq:ident) => { |
| 136 | impl Instance for peripherals::$inst {} | 217 | impl Instance for peripherals::$inst { |
| 218 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 219 | } | ||
| 137 | 220 | ||
| 138 | impl sealed::Instance for peripherals::$inst { | 221 | impl sealed::Instance for peripherals::$inst { |
| 139 | fn regs() -> crate::pac::rng::Rng { | 222 | fn regs() -> crate::pac::rng::Rng { |
| 140 | crate::pac::RNG | 223 | crate::pac::$inst |
| 141 | } | ||
| 142 | } | ||
| 143 | }; | ||
| 144 | ); | ||
| 145 | |||
| 146 | #[cfg(feature = "rt")] | ||
| 147 | macro_rules! irq { | ||
| 148 | ($irq:ident) => { | ||
| 149 | mod rng_irq { | ||
| 150 | use crate::interrupt; | ||
| 151 | |||
| 152 | #[interrupt] | ||
| 153 | unsafe fn $irq() { | ||
| 154 | let bits = $crate::pac::RNG.sr().read(); | ||
| 155 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 156 | $crate::pac::RNG.cr().write(|reg| reg.set_ie(false)); | ||
| 157 | $crate::rng::RNG_WAKER.wake(); | ||
| 158 | } | ||
| 159 | } | 224 | } |
| 160 | } | 225 | } |
| 161 | }; | 226 | }; |
| 162 | } | ||
| 163 | |||
| 164 | #[cfg(feature = "rt")] | ||
| 165 | foreach_interrupt!( | ||
| 166 | (RNG) => { | ||
| 167 | irq!(RNG); | ||
| 168 | }; | ||
| 169 | |||
| 170 | (RNG_LPUART1) => { | ||
| 171 | irq!(RNG_LPUART1); | ||
| 172 | }; | ||
| 173 | |||
| 174 | (AES_RNG_LPUART1) => { | ||
| 175 | irq!(AES_RNG_LPUART1); | ||
| 176 | }; | ||
| 177 | |||
| 178 | (AES_RNG) => { | ||
| 179 | irq!(AES_RNG); | ||
| 180 | }; | ||
| 181 | |||
| 182 | (HASH_RNG) => { | ||
| 183 | irq!(HASH_RNG); | ||
| 184 | }; | ||
| 185 | ); | 227 | ); |
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")] |
| 16 | mod _version; | 16 | mod _version; |
| 17 | pub use _version::*; | 17 | pub use _version::*; |
| 18 | use embassy_hal_common::Peripheral; | 18 | use 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/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index a2eace6d3..e3b9dfb8b 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -39,9 +39,8 @@ impl<'d, T: Instance> super::Rtc<'d, T> { | |||
| 39 | let rtcsel = reg.rtcsel().to_bits(); | 39 | let rtcsel = reg.rtcsel().to_bits(); |
| 40 | 40 | ||
| 41 | if !reg.rtcen() || rtcsel != clock_config { | 41 | if !reg.rtcen() || rtcsel != clock_config { |
| 42 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | 42 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] |
| 43 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); | 43 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); |
| 44 | |||
| 45 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | 44 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |
| 46 | let cr = crate::pac::RCC.bdcr(); | 45 | let cr = crate::pac::RCC.bdcr(); |
| 47 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | 46 | #[cfg(any(rtc_v2l0, rtc_v2l1))] |
| @@ -201,6 +200,11 @@ impl sealed::Instance for crate::peripherals::RTC { | |||
| 201 | // read to allow the pwr clock to enable | 200 | // read to allow the pwr clock to enable |
| 202 | crate::pac::PWR.cr1().read(); | 201 | crate::pac::PWR.cr1().read(); |
| 203 | } | 202 | } |
| 203 | #[cfg(any(rtc_v2f2))] | ||
| 204 | { | ||
| 205 | crate::pac::RCC.apb1enr().modify(|w| w.set_pwren(true)); | ||
| 206 | crate::pac::PWR.cr().read(); | ||
| 207 | } | ||
| 204 | } | 208 | } |
| 205 | 209 | ||
| 206 | fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> { | 210 | fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32> { |
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 434c56a48..6b532363c 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -6,8 +6,8 @@ use core::marker::PhantomData; | |||
| 6 | use core::ops::{Deref, DerefMut}; | 6 | use core::ops::{Deref, DerefMut}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_hal_common::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; | 12 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; |
| 13 | 13 | ||
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index d5f63f84e..bbc7c3b91 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -4,7 +4,7 @@ use core::ptr; | |||
| 4 | 4 | ||
| 5 | use embassy_embedded_hal::SetConfig; | 5 | use embassy_embedded_hal::SetConfig; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_hal_common::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 8 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 9 | 9 | ||
| 10 | use crate::dma::{slice_ptr_parts, word, Transfer}; | 10 | use crate::dma::{slice_ptr_parts, word, Transfer}; |
| @@ -36,6 +36,7 @@ pub enum BitOrder { | |||
| 36 | pub struct Config { | 36 | pub struct Config { |
| 37 | pub mode: Mode, | 37 | pub mode: Mode, |
| 38 | pub bit_order: BitOrder, | 38 | pub bit_order: BitOrder, |
| 39 | pub frequency: Hertz, | ||
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | impl Default for Config { | 42 | impl Default for Config { |
| @@ -43,6 +44,7 @@ impl Default for Config { | |||
| 43 | Self { | 44 | Self { |
| 44 | mode: MODE_0, | 45 | mode: MODE_0, |
| 45 | bit_order: BitOrder::MsbFirst, | 46 | bit_order: BitOrder::MsbFirst, |
| 47 | frequency: Hertz(1_000_000), | ||
| 46 | } | 48 | } |
| 47 | } | 49 | } |
| 48 | } | 50 | } |
| @@ -88,7 +90,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 88 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, | 90 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, |
| 89 | txdma: impl Peripheral<P = Tx> + 'd, | 91 | txdma: impl Peripheral<P = Tx> + 'd, |
| 90 | rxdma: impl Peripheral<P = Rx> + 'd, | 92 | rxdma: impl Peripheral<P = Rx> + 'd, |
| 91 | freq: Hertz, | ||
| 92 | config: Config, | 93 | config: Config, |
| 93 | ) -> Self { | 94 | ) -> Self { |
| 94 | into_ref!(peri, sck, mosi, miso); | 95 | into_ref!(peri, sck, mosi, miso); |
| @@ -112,7 +113,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 112 | Some(miso.map_into()), | 113 | Some(miso.map_into()), |
| 113 | txdma, | 114 | txdma, |
| 114 | rxdma, | 115 | rxdma, |
| 115 | freq, | ||
| 116 | config, | 116 | config, |
| 117 | ) | 117 | ) |
| 118 | } | 118 | } |
| @@ -123,7 +123,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 123 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, | 123 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, |
| 124 | txdma: impl Peripheral<P = Tx> + 'd, // TODO remove | 124 | txdma: impl Peripheral<P = Tx> + 'd, // TODO remove |
| 125 | rxdma: impl Peripheral<P = Rx> + 'd, | 125 | rxdma: impl Peripheral<P = Rx> + 'd, |
| 126 | freq: Hertz, | ||
| 127 | config: Config, | 126 | config: Config, |
| 128 | ) -> Self { | 127 | ) -> Self { |
| 129 | into_ref!(sck, miso); | 128 | into_ref!(sck, miso); |
| @@ -139,7 +138,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 139 | Some(miso.map_into()), | 138 | Some(miso.map_into()), |
| 140 | txdma, | 139 | txdma, |
| 141 | rxdma, | 140 | rxdma, |
| 142 | freq, | ||
| 143 | config, | 141 | config, |
| 144 | ) | 142 | ) |
| 145 | } | 143 | } |
| @@ -150,7 +148,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 150 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 148 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| 151 | txdma: impl Peripheral<P = Tx> + 'd, | 149 | txdma: impl Peripheral<P = Tx> + 'd, |
| 152 | rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove | 150 | rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove |
| 153 | freq: Hertz, | ||
| 154 | config: Config, | 151 | config: Config, |
| 155 | ) -> Self { | 152 | ) -> Self { |
| 156 | into_ref!(sck, mosi); | 153 | into_ref!(sck, mosi); |
| @@ -166,7 +163,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 166 | None, | 163 | None, |
| 167 | txdma, | 164 | txdma, |
| 168 | rxdma, | 165 | rxdma, |
| 169 | freq, | ||
| 170 | config, | 166 | config, |
| 171 | ) | 167 | ) |
| 172 | } | 168 | } |
| @@ -176,14 +172,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 176 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 172 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| 177 | txdma: impl Peripheral<P = Tx> + 'd, | 173 | txdma: impl Peripheral<P = Tx> + 'd, |
| 178 | rxdma: impl Peripheral<P = Rx> + 'd, // TODO: remove | 174 | rxdma: impl Peripheral<P = Rx> + 'd, // TODO: remove |
| 179 | freq: Hertz, | ||
| 180 | config: Config, | 175 | config: Config, |
| 181 | ) -> Self { | 176 | ) -> Self { |
| 182 | into_ref!(mosi); | 177 | into_ref!(mosi); |
| 183 | mosi.set_as_af_pull(mosi.af_num(), AFType::OutputPushPull, Pull::Down); | 178 | mosi.set_as_af_pull(mosi.af_num(), AFType::OutputPushPull, Pull::Down); |
| 184 | mosi.set_speed(crate::gpio::Speed::Medium); | 179 | mosi.set_speed(crate::gpio::Speed::Medium); |
| 185 | 180 | ||
| 186 | Self::new_inner(peri, None, Some(mosi.map_into()), None, txdma, rxdma, freq, config) | 181 | Self::new_inner(peri, None, Some(mosi.map_into()), None, txdma, rxdma, config) |
| 187 | } | 182 | } |
| 188 | 183 | ||
| 189 | #[cfg(stm32wl)] | 184 | #[cfg(stm32wl)] |
| @@ -201,7 +196,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 201 | let mut config = Config::default(); | 196 | let mut config = Config::default(); |
| 202 | config.mode = MODE_0; | 197 | config.mode = MODE_0; |
| 203 | config.bit_order = BitOrder::MsbFirst; | 198 | config.bit_order = BitOrder::MsbFirst; |
| 204 | Self::new_inner(peri, None, None, None, txdma, rxdma, freq, config) | 199 | config.frequency = freq; |
| 200 | Self::new_inner(peri, None, None, None, txdma, rxdma, config) | ||
| 205 | } | 201 | } |
| 206 | 202 | ||
| 207 | #[allow(dead_code)] | 203 | #[allow(dead_code)] |
| @@ -209,10 +205,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 209 | peri: impl Peripheral<P = T> + 'd, | 205 | peri: impl Peripheral<P = T> + 'd, |
| 210 | txdma: impl Peripheral<P = Tx> + 'd, | 206 | txdma: impl Peripheral<P = Tx> + 'd, |
| 211 | rxdma: impl Peripheral<P = Rx> + 'd, | 207 | rxdma: impl Peripheral<P = Rx> + 'd, |
| 212 | freq: Hertz, | ||
| 213 | config: Config, | 208 | config: Config, |
| 214 | ) -> Self { | 209 | ) -> Self { |
| 215 | Self::new_inner(peri, None, None, None, txdma, rxdma, freq, config) | 210 | Self::new_inner(peri, None, None, None, txdma, rxdma, config) |
| 216 | } | 211 | } |
| 217 | 212 | ||
| 218 | fn new_inner( | 213 | fn new_inner( |
| @@ -222,12 +217,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 222 | miso: Option<PeripheralRef<'d, AnyPin>>, | 217 | miso: Option<PeripheralRef<'d, AnyPin>>, |
| 223 | txdma: impl Peripheral<P = Tx> + 'd, | 218 | txdma: impl Peripheral<P = Tx> + 'd, |
| 224 | rxdma: impl Peripheral<P = Rx> + 'd, | 219 | rxdma: impl Peripheral<P = Rx> + 'd, |
| 225 | freq: Hertz, | ||
| 226 | config: Config, | 220 | config: Config, |
| 227 | ) -> Self { | 221 | ) -> Self { |
| 228 | into_ref!(peri, txdma, rxdma); | 222 | into_ref!(peri, txdma, rxdma); |
| 229 | 223 | ||
| 230 | let pclk = T::frequency(); | 224 | let pclk = T::frequency(); |
| 225 | let freq = config.frequency; | ||
| 231 | let br = compute_baud_rate(pclk, freq.into()); | 226 | let br = compute_baud_rate(pclk, freq.into()); |
| 232 | 227 | ||
| 233 | let cpha = config.raw_phase(); | 228 | let cpha = config.raw_phase(); |
| @@ -334,19 +329,29 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 334 | 329 | ||
| 335 | let lsbfirst = config.raw_byte_order(); | 330 | let lsbfirst = config.raw_byte_order(); |
| 336 | 331 | ||
| 332 | let pclk = T::frequency(); | ||
| 333 | let freq = config.frequency; | ||
| 334 | let br = compute_baud_rate(pclk, freq.into()); | ||
| 335 | |||
| 337 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 336 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 338 | T::REGS.cr1().modify(|w| { | 337 | T::REGS.cr1().modify(|w| { |
| 339 | w.set_cpha(cpha); | 338 | w.set_cpha(cpha); |
| 340 | w.set_cpol(cpol); | 339 | w.set_cpol(cpol); |
| 340 | w.set_br(br); | ||
| 341 | w.set_lsbfirst(lsbfirst); | 341 | w.set_lsbfirst(lsbfirst); |
| 342 | }); | 342 | }); |
| 343 | 343 | ||
| 344 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 344 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 345 | T::REGS.cfg2().modify(|w| { | 345 | { |
| 346 | w.set_cpha(cpha); | 346 | T::REGS.cfg2().modify(|w| { |
| 347 | w.set_cpol(cpol); | 347 | w.set_cpha(cpha); |
| 348 | w.set_lsbfirst(lsbfirst); | 348 | w.set_cpol(cpol); |
| 349 | }); | 349 | w.set_lsbfirst(lsbfirst); |
| 350 | }); | ||
| 351 | T::REGS.cfg1().modify(|w| { | ||
| 352 | w.set_mbr(br); | ||
| 353 | }); | ||
| 354 | } | ||
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | pub fn get_current_config(&self) -> Config { | 357 | pub fn get_current_config(&self) -> Config { |
| @@ -354,6 +359,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 354 | let cfg = T::REGS.cr1().read(); | 359 | let cfg = T::REGS.cr1().read(); |
| 355 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 360 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 356 | let cfg = T::REGS.cfg2().read(); | 361 | let cfg = T::REGS.cfg2().read(); |
| 362 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | ||
| 363 | let cfg1 = T::REGS.cfg1().read(); | ||
| 364 | |||
| 357 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { | 365 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { |
| 358 | Polarity::IdleLow | 366 | Polarity::IdleLow |
| 359 | } else { | 367 | } else { |
| @@ -371,9 +379,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 371 | BitOrder::MsbFirst | 379 | BitOrder::MsbFirst |
| 372 | }; | 380 | }; |
| 373 | 381 | ||
| 382 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | ||
| 383 | let br = cfg.br(); | ||
| 384 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | ||
| 385 | let br = cfg1.mbr(); | ||
| 386 | |||
| 387 | let pclk = T::frequency(); | ||
| 388 | let frequency = compute_frequency(pclk, br); | ||
| 389 | |||
| 374 | Config { | 390 | Config { |
| 375 | mode: Mode { polarity, phase }, | 391 | mode: Mode { polarity, phase }, |
| 376 | bit_order, | 392 | bit_order, |
| 393 | frequency, | ||
| 377 | } | 394 | } |
| 378 | } | 395 | } |
| 379 | 396 | ||
| @@ -653,6 +670,21 @@ fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { | |||
| 653 | Br::from_bits(val) | 670 | Br::from_bits(val) |
| 654 | } | 671 | } |
| 655 | 672 | ||
| 673 | fn compute_frequency(clocks: Hertz, br: Br) -> Hertz { | ||
| 674 | let div: u16 = match br { | ||
| 675 | Br::DIV2 => 2, | ||
| 676 | Br::DIV4 => 4, | ||
| 677 | Br::DIV8 => 8, | ||
| 678 | Br::DIV16 => 16, | ||
| 679 | Br::DIV32 => 32, | ||
| 680 | Br::DIV64 => 64, | ||
| 681 | Br::DIV128 => 128, | ||
| 682 | Br::DIV256 => 256, | ||
| 683 | }; | ||
| 684 | |||
| 685 | clocks / div | ||
| 686 | } | ||
| 687 | |||
| 656 | trait RegsExt { | 688 | trait RegsExt { |
| 657 | fn tx_ptr<W>(&self) -> *mut W; | 689 | fn tx_ptr<W>(&self) -> *mut W; |
| 658 | fn rx_ptr<W>(&self) -> *mut W; | 690 | fn rx_ptr<W>(&self) -> *mut W; |
diff --git a/embassy-stm32/src/pwm/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 4d64d005c..48cb610f1 100644 --- a/embassy-stm32/src/pwm/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 4 | use stm32_metapac::timer::vals::Ckd; | 4 | use stm32_metapac::timer::vals::Ckd; |
| 5 | 5 | ||
| 6 | use super::simple_pwm::*; | 6 | use super::simple_pwm::*; |
| 7 | use super::*; | 7 | use super::*; |
| 8 | #[allow(unused_imports)] | 8 | #[allow(unused_imports)] |
| 9 | use crate::gpio::sealed::{AFType, Pin}; | 9 | use crate::gpio::sealed::{AFType, Pin}; |
| 10 | use crate::gpio::AnyPin; | 10 | use crate::gpio::{AnyPin, OutputType}; |
| 11 | use crate::time::Hertz; | 11 | use crate::time::Hertz; |
| 12 | use crate::Peripheral; | 12 | use crate::Peripheral; |
| 13 | 13 | ||
| @@ -17,13 +17,13 @@ pub struct ComplementaryPwmPin<'d, Perip, Channel> { | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | macro_rules! complementary_channel_impl { | 19 | macro_rules! complementary_channel_impl { |
| 20 | ($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => { | 20 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 21 | impl<'d, Perip: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> { | 21 | impl<'d, Perip: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> { |
| 22 | pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self { | 22 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd, output_type: OutputType) -> Self { |
| 23 | into_ref!(pin); | 23 | into_ref!(pin); |
| 24 | critical_section::with(|_| { | 24 | critical_section::with(|_| { |
| 25 | pin.set_low(); | 25 | pin.set_low(); |
| 26 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); | 26 | pin.set_as_af(pin.af_num(), output_type.into()); |
| 27 | #[cfg(gpio_v2)] | 27 | #[cfg(gpio_v2)] |
| 28 | pin.set_speed(crate::gpio::Speed::VeryHigh); | 28 | pin.set_speed(crate::gpio::Speed::VeryHigh); |
| 29 | }); | 29 | }); |
| @@ -36,10 +36,10 @@ macro_rules! complementary_channel_impl { | |||
| 36 | }; | 36 | }; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | complementary_channel_impl!(new_ch1, Ch1, Channel1Pin, Channel1ComplementaryPin); | 39 | complementary_channel_impl!(new_ch1, Ch1, Channel1ComplementaryPin); |
| 40 | complementary_channel_impl!(new_ch2, Ch2, Channel2Pin, Channel2ComplementaryPin); | 40 | complementary_channel_impl!(new_ch2, Ch2, Channel2ComplementaryPin); |
| 41 | complementary_channel_impl!(new_ch3, Ch3, Channel3Pin, Channel3ComplementaryPin); | 41 | complementary_channel_impl!(new_ch3, Ch3, Channel3ComplementaryPin); |
| 42 | complementary_channel_impl!(new_ch4, Ch4, Channel4Pin, Channel4ComplementaryPin); | 42 | complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin); |
| 43 | 43 | ||
| 44 | pub struct ComplementaryPwm<'d, T> { | 44 | pub struct ComplementaryPwm<'d, T> { |
| 45 | inner: PeripheralRef<'d, T>, | 45 | inner: PeripheralRef<'d, T>, |
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 09b7a3776..6c2d6d827 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | pub mod complementary_pwm; | ||
| 2 | pub mod simple_pwm; | ||
| 3 | |||
| 1 | use stm32_metapac::timer::vals; | 4 | use stm32_metapac::timer::vals; |
| 2 | 5 | ||
| 3 | use crate::interrupt; | 6 | use crate::interrupt; |
| @@ -43,15 +46,123 @@ pub(crate) mod sealed { | |||
| 43 | pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { | 46 | pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { |
| 44 | fn regs_advanced() -> crate::pac::timer::TimAdv; | 47 | fn regs_advanced() -> crate::pac::timer::TimAdv; |
| 45 | } | 48 | } |
| 49 | |||
| 50 | pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { | ||
| 51 | /// Global output enable. Does not do anything on non-advanced timers. | ||
| 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)] | ||
| 83 | pub enum Channel { | ||
| 84 | Ch1, | ||
| 85 | Ch2, | ||
| 86 | Ch3, | ||
| 87 | Ch4, | ||
| 46 | } | 88 | } |
| 47 | 89 | ||
| 90 | impl 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)] | ||
| 102 | pub enum OutputCompareMode { | ||
| 103 | Frozen, | ||
| 104 | ActiveOnMatch, | ||
| 105 | InactiveOnMatch, | ||
| 106 | Toggle, | ||
| 107 | ForceInactive, | ||
| 108 | ForceActive, | ||
| 109 | PwmMode1, | ||
| 110 | PwmMode2, | ||
| 111 | } | ||
| 112 | |||
| 113 | impl 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 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | ||
| 129 | |||
| 48 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} | 130 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} |
| 49 | 131 | ||
| 50 | pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {} | 132 | pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'static {} |
| 51 | 133 | ||
| 52 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} | 134 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} |
| 53 | 135 | ||
| 54 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | 136 | pub trait CaptureCompare16bitInstance: |
| 137 | sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static | ||
| 138 | { | ||
| 139 | } | ||
| 140 | |||
| 141 | pub trait ComplementaryCaptureCompare16bitInstance: | ||
| 142 | sealed::ComplementaryCaptureCompare16bitInstance + AdvancedControlInstance + 'static | ||
| 143 | { | ||
| 144 | } | ||
| 145 | |||
| 146 | pub trait CaptureCompare32bitInstance: | ||
| 147 | sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static | ||
| 148 | { | ||
| 149 | } | ||
| 150 | |||
| 151 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | ||
| 152 | pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); | ||
| 153 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | ||
| 154 | pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); | ||
| 155 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | ||
| 156 | pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); | ||
| 157 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | ||
| 158 | pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); | ||
| 159 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | ||
| 160 | pin_trait!(BreakInputPin, CaptureCompare16bitInstance); | ||
| 161 | pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); | ||
| 162 | pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); | ||
| 163 | pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); | ||
| 164 | pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | ||
| 165 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); | ||
| 55 | 166 | ||
| 56 | #[allow(unused)] | 167 | #[allow(unused)] |
| 57 | macro_rules! impl_basic_16bit_timer { | 168 | macro_rules! impl_basic_16bit_timer { |
| @@ -140,33 +251,94 @@ macro_rules! impl_32bit_timer { | |||
| 140 | }; | 251 | }; |
| 141 | } | 252 | } |
| 142 | 253 | ||
| 254 | #[allow(unused)] | ||
| 255 | macro_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 | |||
| 143 | foreach_interrupt! { | 288 | foreach_interrupt! { |
| 144 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | 289 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { |
| 145 | impl_basic_16bit_timer!($inst, $irq); | 290 | impl_basic_16bit_timer!($inst, $irq); |
| 146 | 291 | impl Basic16bitInstance for crate::peripherals::$inst {} | |
| 147 | impl Basic16bitInstance for crate::peripherals::$inst { | ||
| 148 | } | ||
| 149 | }; | 292 | }; |
| 150 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | 293 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { |
| 151 | impl_basic_16bit_timer!($inst, $irq); | 294 | impl_basic_16bit_timer!($inst, $irq); |
| 152 | 295 | impl_compare_capable_16bit!($inst); | |
| 153 | impl Basic16bitInstance for crate::peripherals::$inst { | 296 | impl Basic16bitInstance for crate::peripherals::$inst {} |
| 154 | } | 297 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} |
| 298 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 155 | 299 | ||
| 156 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 300 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| 157 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 301 | fn regs_gp16() -> crate::pac::timer::TimGp16 { |
| 158 | crate::pac::$inst | 302 | crate::pac::$inst |
| 159 | } | 303 | } |
| 160 | } | 304 | } |
| 161 | |||
| 162 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 163 | } | ||
| 164 | }; | 305 | }; |
| 165 | 306 | ||
| 166 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | 307 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { |
| 167 | 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 | } | ||
| 327 | |||
| 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 | } | ||
| 168 | 332 | ||
| 169 | impl Basic16bitInstance for crate::peripherals::$inst { | 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 | } | ||
| 170 | } | 342 | } |
| 171 | 343 | ||
| 172 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 344 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| @@ -174,21 +346,16 @@ foreach_interrupt! { | |||
| 174 | 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()) } |
| 175 | } | 347 | } |
| 176 | } | 348 | } |
| 177 | |||
| 178 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 179 | } | ||
| 180 | |||
| 181 | impl_32bit_timer!($inst); | ||
| 182 | |||
| 183 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst { | ||
| 184 | } | ||
| 185 | }; | 349 | }; |
| 186 | 350 | ||
| 187 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | 351 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { |
| 188 | impl_basic_16bit_timer!($inst, $irq); | 352 | impl_basic_16bit_timer!($inst, $irq); |
| 189 | 353 | ||
| 190 | impl Basic16bitInstance for crate::peripherals::$inst { | 354 | impl Basic16bitInstance for crate::peripherals::$inst {} |
| 191 | } | 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 {} | ||
| 192 | 359 | ||
| 193 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 360 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| 194 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 361 | fn regs_gp16() -> crate::pac::timer::TimGp16 { |
| @@ -196,16 +363,70 @@ foreach_interrupt! { | |||
| 196 | } | 363 | } |
| 197 | } | 364 | } |
| 198 | 365 | ||
| 199 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 200 | } | ||
| 201 | |||
| 202 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { | 366 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { |
| 203 | fn regs_advanced() -> crate::pac::timer::TimAdv { | 367 | fn regs_advanced() -> crate::pac::timer::TimAdv { |
| 204 | crate::pac::$inst | 368 | crate::pac::$inst |
| 205 | } | 369 | } |
| 206 | } | 370 | } |
| 207 | 371 | ||
| 208 | 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 | } | ||
| 209 | } | 428 | } |
| 429 | |||
| 430 | |||
| 210 | }; | 431 | }; |
| 211 | } | 432 | } |
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 995f59c23..e0a817929 100644 --- a/embassy-stm32/src/pwm/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 4 | 4 | ||
| 5 | use super::*; | 5 | use super::*; |
| 6 | #[allow(unused_imports)] | 6 | #[allow(unused_imports)] |
| 7 | use crate::gpio::sealed::{AFType, Pin}; | 7 | use crate::gpio::sealed::{AFType, Pin}; |
| 8 | use crate::gpio::AnyPin; | 8 | use crate::gpio::{AnyPin, OutputType}; |
| 9 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| 10 | use crate::Peripheral; | 10 | use crate::Peripheral; |
| 11 | 11 | ||
| @@ -22,11 +22,11 @@ pub struct PwmPin<'d, Perip, Channel> { | |||
| 22 | macro_rules! channel_impl { | 22 | macro_rules! channel_impl { |
| 23 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 23 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 24 | impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> { | 24 | impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> { |
| 25 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd) -> Self { | 25 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd, output_type: OutputType) -> Self { |
| 26 | into_ref!(pin); | 26 | into_ref!(pin); |
| 27 | critical_section::with(|_| { | 27 | critical_section::with(|_| { |
| 28 | pin.set_low(); | 28 | pin.set_low(); |
| 29 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); | 29 | pin.set_as_af(pin.af_num(), output_type.into()); |
| 30 | #[cfg(gpio_v2)] | 30 | #[cfg(gpio_v2)] |
| 31 | pin.set_speed(crate::gpio::Speed::VeryHigh); | 31 | pin.set_speed(crate::gpio::Speed::VeryHigh); |
| 32 | }); | 32 | }); |
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; | |||
| 2 | use core::slice; | 2 | use core::slice; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::atomic_ring_buffer::RingBuffer; | 5 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | 7 | ||
| 8 | use super::*; | 8 | use 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; | |||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::drop::OnDrop; | 8 | use embassy_hal_internal::drop::OnDrop; |
| 9 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use futures::future::{select, Either}; | 10 | use futures::future::{select, Either}; |
| 11 | 11 | ||
| 12 | use crate::dma::{NoDma, Transfer}; | 12 | use 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; | |||
| 2 | use core::sync::atomic::{compiler_fence, Ordering}; | 2 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use embassy_hal_common::PeripheralRef; | 5 | use embassy_hal_internal::PeripheralRef; |
| 6 | use futures::future::{select, Either}; | 6 | use futures::future::{select, Either}; |
| 7 | 7 | ||
| 8 | use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx}; | 8 | use 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; | |||
| 5 | use core::sync::atomic::{AtomicBool, Ordering}; | 5 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_common::into_ref; | 8 | use embassy_hal_internal::into_ref; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use embassy_usb_driver as driver; | 10 | use embassy_usb_driver as driver; |
| 11 | use embassy_usb_driver::{ | 11 | use 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; | |||
| 3 | use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; | 3 | use core::sync::atomic::{AtomicBool, AtomicU16, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::{into_ref, Peripheral}; | 6 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use embassy_usb_driver::{ | 8 | use 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 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | use core::marker::PhantomData; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::{into_ref, Peripheral}; | 3 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 4 | use stm32_metapac::iwdg::vals::{Key, Pr}; | 4 | use stm32_metapac::iwdg::vals::{Key, Pr}; |
| 5 | 5 | ||
| 6 | use crate::rcc::LSI_FREQ; | 6 | use crate::rcc::LSI_FREQ; |
diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs index c8497494c..b5e1950cc 100644 --- a/examples/boot/application/rp/src/bin/a.rs +++ b/examples/boot/application/rp/src/bin/a.rs | |||
| @@ -7,7 +7,7 @@ use core::cell::RefCell; | |||
| 7 | use defmt_rtt as _; | 7 | use defmt_rtt as _; |
| 8 | use embassy_boot_rp::*; | 8 | use embassy_boot_rp::*; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_rp::flash::Flash; | 10 | use embassy_rp::flash::{self, Flash}; |
| 11 | use embassy_rp::gpio::{Level, Output}; | 11 | use embassy_rp::gpio::{Level, Output}; |
| 12 | use embassy_rp::watchdog::Watchdog; | 12 | use embassy_rp::watchdog::Watchdog; |
| 13 | use embassy_sync::blocking_mutex::Mutex; | 13 | use embassy_sync::blocking_mutex::Mutex; |
| @@ -34,7 +34,7 @@ async fn main(_s: Spawner) { | |||
| 34 | let mut watchdog = Watchdog::new(p.WATCHDOG); | 34 | let mut watchdog = Watchdog::new(p.WATCHDOG); |
| 35 | watchdog.start(Duration::from_secs(8)); | 35 | watchdog.start(Duration::from_secs(8)); |
| 36 | 36 | ||
| 37 | let flash: Flash<_, FLASH_SIZE> = Flash::new(p.FLASH); | 37 | let flash = Flash::<_, flash::Blocking, FLASH_SIZE>::new(p.FLASH); |
| 38 | let flash = Mutex::new(RefCell::new(flash)); | 38 | let flash = Mutex::new(RefCell::new(flash)); |
| 39 | 39 | ||
| 40 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 40 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); |
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]] |
| 35 | name = "rtos_trace" | 35 | name = "rtos_trace" |
| 36 | required-features = ["nightly"] | 36 | required-features = ["nightly"] |
| 37 | |||
| 38 | [profile.release] | ||
| 39 | debug = 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 | |||
| 19 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | |||
| 23 | [profile.release] | ||
| 24 | debug = 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 } | |||
| 57 | num-integer = { version = "0.1.45", default-features = false } | 57 | num-integer = { version = "0.1.45", default-features = false } |
| 58 | microfft = "0.5.0" | 58 | microfft = "0.5.0" |
| 59 | 59 | ||
| 60 | [patch.crates-io] | 60 | [profile.release] |
| 61 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 61 | debug = 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 } | |||
| 53 | embedded-storage = "0.3.0" | 53 | embedded-storage = "0.3.0" |
| 54 | usbd-hid = "0.6.0" | 54 | usbd-hid = "0.6.0" |
| 55 | serde = { version = "1.0.136", default-features = false } | 55 | serde = { version = "1.0.136", default-features = false } |
| 56 | |||
| 57 | [profile.release] | ||
| 58 | debug = 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" | |||
| 53 | rand = { version = "0.8.5", default-features = false } | 53 | rand = { version = "0.8.5", default-features = false } |
| 54 | 54 | ||
| 55 | [profile.release] | 55 | [profile.release] |
| 56 | debug = true | 56 | debug = 2 |
| 57 | |||
| 58 | [patch.crates-io] | ||
| 59 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | ||
diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs index 4c4982acc..88bb931d2 100644 --- a/examples/rp/src/bin/flash.rs +++ b/examples/rp/src/bin/flash.rs | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE}; | 9 | use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; |
| 10 | use embassy_rp::peripherals::FLASH; | 10 | use embassy_rp::peripherals::FLASH; |
| 11 | use embassy_time::{Duration, Timer}; | 11 | use embassy_time::{Duration, Timer}; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { | |||
| 25 | // https://github.com/knurling-rs/defmt/pull/683 | 25 | // https://github.com/knurling-rs/defmt/pull/683 |
| 26 | Timer::after(Duration::from_millis(10)).await; | 26 | Timer::after(Duration::from_millis(10)).await; |
| 27 | 27 | ||
| 28 | let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH); | 28 | let mut flash = embassy_rp::flash::Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); |
| 29 | 29 | ||
| 30 | // Get JEDEC id | 30 | // Get JEDEC id |
| 31 | let jedec = flash.jedec_id().unwrap(); | 31 | let jedec = flash.jedec_id().unwrap(); |
| @@ -40,10 +40,12 @@ async fn main(_spawner: Spawner) { | |||
| 40 | 40 | ||
| 41 | multiwrite_bytes(&mut flash, ERASE_SIZE as u32); | 41 | multiwrite_bytes(&mut flash, ERASE_SIZE as u32); |
| 42 | 42 | ||
| 43 | background_read(&mut flash, (ERASE_SIZE * 2) as u32).await; | ||
| 44 | |||
| 43 | loop {} | 45 | loop {} |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>, offset: u32) { | 48 | fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) { |
| 47 | info!(">>>> [multiwrite_bytes]"); | 49 | info!(">>>> [multiwrite_bytes]"); |
| 48 | let mut read_buf = [0u8; ERASE_SIZE]; | 50 | let mut read_buf = [0u8; ERASE_SIZE]; |
| 49 | defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut read_buf)); | 51 | defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut read_buf)); |
| @@ -71,7 +73,7 @@ fn multiwrite_bytes(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>, | |||
| 71 | } | 73 | } |
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE>, offset: u32) { | 76 | fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) { |
| 75 | info!(">>>> [erase_write_sector]"); | 77 | info!(">>>> [erase_write_sector]"); |
| 76 | let mut buf = [0u8; ERASE_SIZE]; | 78 | let mut buf = [0u8; ERASE_SIZE]; |
| 77 | defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut buf)); | 79 | defmt::unwrap!(flash.read(ADDR_OFFSET + offset, &mut buf)); |
| @@ -99,3 +101,35 @@ fn erase_write_sector(flash: &mut embassy_rp::flash::Flash<'_, FLASH, FLASH_SIZE | |||
| 99 | defmt::panic!("unexpected"); | 101 | defmt::panic!("unexpected"); |
| 100 | } | 102 | } |
| 101 | } | 103 | } |
| 104 | |||
| 105 | async fn background_read(flash: &mut embassy_rp::flash::Flash<'_, FLASH, Async, FLASH_SIZE>, offset: u32) { | ||
| 106 | info!(">>>> [background_read]"); | ||
| 107 | |||
| 108 | let mut buf = [0u32; 8]; | ||
| 109 | defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await; | ||
| 110 | |||
| 111 | info!("Addr of flash block is {:x}", ADDR_OFFSET + offset + FLASH_BASE as u32); | ||
| 112 | info!("Contents start with {=u32:x}", buf[0]); | ||
| 113 | |||
| 114 | defmt::unwrap!(flash.erase(ADDR_OFFSET + offset, ADDR_OFFSET + offset + ERASE_SIZE as u32)); | ||
| 115 | |||
| 116 | defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await; | ||
| 117 | info!("Contents after erase starts with {=u32:x}", buf[0]); | ||
| 118 | if buf.iter().any(|x| *x != 0xFFFFFFFF) { | ||
| 119 | defmt::panic!("unexpected"); | ||
| 120 | } | ||
| 121 | |||
| 122 | for b in buf.iter_mut() { | ||
| 123 | *b = 0xDABA1234; | ||
| 124 | } | ||
| 125 | |||
| 126 | defmt::unwrap!(flash.write(ADDR_OFFSET + offset, unsafe { | ||
| 127 | core::slice::from_raw_parts(buf.as_ptr() as *const u8, buf.len() * 4) | ||
| 128 | })); | ||
| 129 | |||
| 130 | defmt::unwrap!(flash.background_read(ADDR_OFFSET + offset, &mut buf)).await; | ||
| 131 | info!("Contents after write starts with {=u32:x}", buf[0]); | ||
| 132 | if buf.iter().any(|x| *x != 0xDABA1234) { | ||
| 133 | defmt::panic!("unexpected"); | ||
| 134 | } | ||
| 135 | } | ||
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; | |||
| 8 | use embassy_rp::bind_interrupts; | 8 | use embassy_rp::bind_interrupts; |
| 9 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; | 10 | use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; |
| 11 | use embassy_rp::relocate::RelocatedProgram; | ||
| 12 | use fixed::traits::ToFixed; | 11 | use fixed::traits::ToFixed; |
| 13 | use fixed_macro::types::U56F8; | 12 | use fixed_macro::types::U56F8; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {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; | |||
| 8 | use embassy_futures::join::join; | 8 | use embassy_futures::join::join; |
| 9 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; | 10 | use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; |
| 11 | use embassy_rp::relocate::RelocatedProgram; | ||
| 12 | use embassy_rp::{bind_interrupts, Peripheral}; | 11 | use embassy_rp::{bind_interrupts, Peripheral}; |
| 13 | use fixed::traits::ToFixed; | 12 | use fixed::traits::ToFixed; |
| 14 | use fixed_macro::types::U56F8; | 13 | use 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 | }; |
| 16 | use embassy_rp::pwm::{self, Pwm}; | 16 | use embassy_rp::pwm::{self, Pwm}; |
| 17 | use embassy_rp::relocate::RelocatedProgram; | ||
| 18 | use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; | 17 | use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; |
| 19 | use embassy_time::{Duration, Instant, Timer}; | 18 | use embassy_time::{Duration, Instant, Timer}; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {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..4c382c2ee --- /dev/null +++ b/examples/rp/src/bin/pio_uart.rs | |||
| @@ -0,0 +1,394 @@ | |||
| 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 | |||
| 14 | use defmt::{info, panic, trace}; | ||
| 15 | use embassy_executor::Spawner; | ||
| 16 | use embassy_futures::join::{join, join3}; | ||
| 17 | use embassy_rp::bind_interrupts; | ||
| 18 | use embassy_rp::peripherals::{PIO0, USB}; | ||
| 19 | use embassy_rp::pio::InterruptHandler as PioInterruptHandler; | ||
| 20 | use embassy_rp::usb::{Driver, Instance, InterruptHandler}; | ||
| 21 | use embassy_sync::blocking_mutex::raw::NoopRawMutex; | ||
| 22 | use embassy_sync::pipe::Pipe; | ||
| 23 | use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State}; | ||
| 24 | use embassy_usb::driver::EndpointError; | ||
| 25 | use embassy_usb::{Builder, Config}; | ||
| 26 | use embedded_io::asynch::{Read, Write}; | ||
| 27 | use {defmt_rtt as _, panic_probe as _}; | ||
| 28 | |||
| 29 | use crate::uart::PioUart; | ||
| 30 | use crate::uart_rx::PioUartRx; | ||
| 31 | use crate::uart_tx::PioUartTx; | ||
| 32 | |||
| 33 | bind_interrupts!(struct Irqs { | ||
| 34 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 35 | PIO0_IRQ_0 => PioInterruptHandler<PIO0>; | ||
| 36 | }); | ||
| 37 | |||
| 38 | #[embassy_executor::main] | ||
| 39 | async 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 | |||
| 130 | struct Disconnected {} | ||
| 131 | |||
| 132 | impl 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 | ||
| 142 | async 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 | ||
| 156 | async 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 | ||
| 170 | async 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 | ||
| 187 | async 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 | |||
| 200 | mod 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 | |||
| 237 | mod 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 | |||
| 310 | mod 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 | in null 24 | ||
| 352 | push ; important in case the TX clock is slightly too fast. | ||
| 353 | "# | ||
| 354 | ); | ||
| 355 | let mut cfg = Config::default(); | ||
| 356 | cfg.use_program(&common.load_program(&prg.program), &[]); | ||
| 357 | |||
| 358 | let rx_pin = common.make_pio_pin(rx_pin); | ||
| 359 | sm_rx.set_pins(Level::High, &[&rx_pin]); | ||
| 360 | cfg.set_in_pins(&[&rx_pin]); | ||
| 361 | cfg.set_jmp_pin(&rx_pin); | ||
| 362 | sm_rx.set_pin_dirs(Direction::In, &[&rx_pin]); | ||
| 363 | |||
| 364 | cfg.clock_divider = (U56F8!(125_000_000) / (8 * baud)).to_fixed(); | ||
| 365 | cfg.shift_in.auto_fill = false; | ||
| 366 | cfg.shift_in.direction = ShiftDirection::Right; | ||
| 367 | cfg.shift_in.threshold = 32; | ||
| 368 | cfg.fifo_join = FifoJoin::RxOnly; | ||
| 369 | sm_rx.set_config(&cfg); | ||
| 370 | sm_rx.set_enable(true); | ||
| 371 | |||
| 372 | Self { sm_rx } | ||
| 373 | } | ||
| 374 | |||
| 375 | pub async fn read_u8(&mut self) -> u8 { | ||
| 376 | self.sm_rx.rx().wait_pull().await as u8 | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | impl Io for PioUartRx<'_> { | ||
| 381 | type Error = Infallible; | ||
| 382 | } | ||
| 383 | |||
| 384 | impl Read for PioUartRx<'_> { | ||
| 385 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> { | ||
| 386 | let mut i = 0; | ||
| 387 | while i < buf.len() { | ||
| 388 | buf[i] = self.read_u8().await; | ||
| 389 | i += 1; | ||
| 390 | } | ||
| 391 | Ok(i) | ||
| 392 | } | ||
| 393 | } | ||
| 394 | } | ||
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; | |||
| 12 | use embassy_rp::pio::{ | 12 | use 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 | }; |
| 15 | use embassy_rp::relocate::RelocatedProgram; | ||
| 16 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; | 15 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; |
| 17 | use embassy_time::{Duration, Timer}; | 16 | use embassy_time::{Duration, Timer}; |
| 18 | use fixed::types::U24F8; | 17 | use 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"] } | |||
| 23 | rand_core = { version = "0.6.3", features = ["std"] } | 23 | rand_core = { version = "0.6.3", features = ["std"] } |
| 24 | heapless = { version = "0.7.5", default-features = false } | 24 | heapless = { version = "0.7.5", default-features = false } |
| 25 | static_cell = { version = "1.1", features = ["nightly"]} | 25 | static_cell = { version = "1.1", features = ["nightly"]} |
| 26 | |||
| 27 | [profile.release] | ||
| 28 | debug = 2 | ||
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index e74c5357b..8534921ab 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml | |||
| @@ -20,3 +20,6 @@ embedded-hal = "0.2.6" | |||
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 620a139ae..46b6db45c 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml | |||
| @@ -18,3 +18,6 @@ embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["de | |||
| 18 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 18 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 19 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 19 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 20 | static_cell = { version = "1.1", features = ["nightly"]} | 20 | static_cell = { version = "1.1", features = ["nightly"]} |
| 21 | |||
| 22 | [profile.release] | ||
| 23 | debug = 2 | ||
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 8450c541f..5d32992cd 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml | |||
| @@ -26,3 +26,6 @@ nb = "1.0.0" | |||
| 26 | 26 | ||
| 27 | [profile.dev] | 27 | [profile.dev] |
| 28 | opt-level = "s" | 28 | opt-level = "s" |
| 29 | |||
| 30 | [profile.release] | ||
| 31 | debug = 2 | ||
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 147e2ecbf..9857fb631 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml | |||
| @@ -21,3 +21,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | nb = "1.0.0" | 23 | nb = "1.0.0" |
| 24 | |||
| 25 | [profile.release] | ||
| 26 | debug = 2 | ||
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 6ac5d57e9..bd594d16a 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml | |||
| @@ -25,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 25 | nb = "1.0.0" | 25 | nb = "1.0.0" |
| 26 | embedded-storage = "0.3.0" | 26 | embedded-storage = "0.3.0" |
| 27 | static_cell = { version = "1.1", features = ["nightly"]} | 27 | static_cell = { version = "1.1", features = ["nightly"]} |
| 28 | |||
| 29 | [profile.release] | ||
| 30 | debug = 2 | ||
diff --git a/examples/stm32f3/src/bin/spi_dma.rs b/examples/stm32f3/src/bin/spi_dma.rs index 95b2b6865..a27c1d547 100644 --- a/examples/stm32f3/src/bin/spi_dma.rs +++ b/examples/stm32f3/src/bin/spi_dma.rs | |||
| @@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 18 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 19 | 19 | ||
| 20 | let mut spi = Spi::new( | 20 | let mut spi_config = Config::default(); |
| 21 | p.SPI1, | 21 | spi_config.frequency = Hertz(1_000_000); |
| 22 | p.PB3, | 22 | |
| 23 | p.PB5, | 23 | let mut spi = Spi::new(p.SPI1, p.PB3, p.PB5, p.PB4, p.DMA1_CH3, p.DMA1_CH2, spi_config); |
| 24 | p.PB4, | ||
| 25 | p.DMA1_CH3, | ||
| 26 | p.DMA1_CH2, | ||
| 27 | Hertz(1_000_000), | ||
| 28 | Config::default(), | ||
| 29 | ); | ||
| 30 | 24 | ||
| 31 | for n in 0u32.. { | 25 | for n in 0u32.. { |
| 32 | let mut write: String<128> = String::new(); | 26 | let mut write: String<128> = String::new(); |
diff --git a/examples/stm32f334/.cargo/config.toml b/examples/stm32f334/.cargo/config.toml new file mode 100644 index 000000000..caf947be6 --- /dev/null +++ b/examples/stm32f334/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs-cli chip list` | ||
| 3 | runner = "probe-run --chip STM32F334R8" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabihf" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml new file mode 100644 index 000000000..6410891a1 --- /dev/null +++ b/examples/stm32f334/Cargo.toml | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-stm32f3-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | ||
| 9 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | ||
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | ||
| 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 14 | |||
| 15 | defmt = "0.3" | ||
| 16 | defmt-rtt = "0.4" | ||
| 17 | |||
| 18 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 19 | cortex-m-rt = "0.7.0" | ||
| 20 | embedded-hal = "0.2.6" | ||
| 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 23 | heapless = { version = "0.7.5", default-features = false } | ||
| 24 | nb = "1.0.0" | ||
| 25 | embedded-storage = "0.3.0" | ||
| 26 | static_cell = { version = "1.1", features = ["nightly"]} | ||
diff --git a/examples/stm32f334/build.rs b/examples/stm32f334/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32f334/build.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | fn main() { | ||
| 2 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 3 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 4 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 5 | } | ||
diff --git a/examples/stm32f334/src/bin/button.rs b/examples/stm32f334/src/bin/button.rs new file mode 100644 index 000000000..599c0f27d --- /dev/null +++ b/examples/stm32f334/src/bin/button.rs | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 8 | use embassy_time::{Duration, Timer}; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | info!("Hello World!"); | ||
| 14 | |||
| 15 | let p = embassy_stm32::init(Default::default()); | ||
| 16 | |||
| 17 | let mut out1 = Output::new(p.PA8, Level::Low, Speed::High); | ||
| 18 | |||
| 19 | out1.set_high(); | ||
| 20 | Timer::after(Duration::from_millis(500)).await; | ||
| 21 | out1.set_low(); | ||
| 22 | |||
| 23 | Timer::after(Duration::from_millis(500)).await; | ||
| 24 | info!("end program"); | ||
| 25 | |||
| 26 | cortex_m::asm::bkpt(); | ||
| 27 | } | ||
diff --git a/examples/stm32f334/src/bin/hello.rs b/examples/stm32f334/src/bin/hello.rs new file mode 100644 index 000000000..65773210d --- /dev/null +++ b/examples/stm32f334/src/bin/hello.rs | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::info; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use embassy_stm32::Config; | ||
| 9 | use embassy_time::{Duration, Timer}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) -> ! { | ||
| 14 | let mut config = Config::default(); | ||
| 15 | config.rcc.hse = Some(Hertz(8_000_000)); | ||
| 16 | config.rcc.sysclk = Some(Hertz(16_000_000)); | ||
| 17 | let _p = embassy_stm32::init(config); | ||
| 18 | |||
| 19 | loop { | ||
| 20 | info!("Hello World!"); | ||
| 21 | Timer::after(Duration::from_secs(1)).await; | ||
| 22 | } | ||
| 23 | } | ||
diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs new file mode 100644 index 000000000..2660b10c5 --- /dev/null +++ b/examples/stm32f334/src/bin/pwm.rs | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::hrtim::*; | ||
| 8 | use embassy_stm32::time::{khz, mhz}; | ||
| 9 | use embassy_stm32::Config; | ||
| 10 | use embassy_time::{Duration, Timer}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | #[embassy_executor::main] | ||
| 14 | async fn main(_spawner: Spawner) { | ||
| 15 | let mut config: Config = Default::default(); | ||
| 16 | config.rcc.sysclk = Some(mhz(64)); | ||
| 17 | config.rcc.hclk = Some(mhz(64)); | ||
| 18 | config.rcc.pclk1 = Some(mhz(32)); | ||
| 19 | config.rcc.pclk2 = Some(mhz(64)); | ||
| 20 | |||
| 21 | let p = embassy_stm32::init(config); | ||
| 22 | info!("Hello World!"); | ||
| 23 | |||
| 24 | let ch1 = PwmPin::new_cha(p.PA8); | ||
| 25 | let ch1n = ComplementaryPwmPin::new_cha(p.PA9); | ||
| 26 | let pwm = AdvancedPwm::new( | ||
| 27 | p.HRTIM1, | ||
| 28 | Some(ch1), | ||
| 29 | Some(ch1n), | ||
| 30 | None, | ||
| 31 | None, | ||
| 32 | None, | ||
| 33 | None, | ||
| 34 | None, | ||
| 35 | None, | ||
| 36 | None, | ||
| 37 | None, | ||
| 38 | ); | ||
| 39 | |||
| 40 | info!("pwm constructed"); | ||
| 41 | |||
| 42 | let mut buck_converter = BridgeConverter::new(pwm.ch_a, khz(5)); | ||
| 43 | |||
| 44 | // embassy_stm32::pac::HRTIM1 | ||
| 45 | // .tim(0) | ||
| 46 | // .setr(0) | ||
| 47 | // .modify(|w| w.set_sst(Activeeffect::SETACTIVE)); | ||
| 48 | // | ||
| 49 | // Timer::after(Duration::from_millis(500)).await; | ||
| 50 | // | ||
| 51 | // embassy_stm32::pac::HRTIM1 | ||
| 52 | // .tim(0) | ||
| 53 | // .rstr(0) | ||
| 54 | // .modify(|w| w.set_srt(Inactiveeffect::SETINACTIVE)); | ||
| 55 | |||
| 56 | let max_duty = buck_converter.get_max_compare_value(); | ||
| 57 | |||
| 58 | info!("max compare value: {}", max_duty); | ||
| 59 | |||
| 60 | buck_converter.set_dead_time(max_duty / 20); | ||
| 61 | buck_converter.set_primary_duty(max_duty / 2); | ||
| 62 | buck_converter.set_secondary_duty(3 * max_duty / 4); | ||
| 63 | |||
| 64 | buck_converter.start(); | ||
| 65 | |||
| 66 | Timer::after(Duration::from_millis(500)).await; | ||
| 67 | |||
| 68 | info!("end program"); | ||
| 69 | |||
| 70 | cortex_m::asm::bkpt(); | ||
| 71 | } | ||
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index d0b164393..496016687 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs | |||
| @@ -11,13 +11,15 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; | |||
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{bind_interrupts, eth, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use static_cell::make_static; | 17 | use static_cell::make_static; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | |||
| 19 | bind_interrupts!(struct Irqs { | 20 | bind_interrupts!(struct Irqs { |
| 20 | ETH => eth::InterruptHandler; | 21 | ETH => eth::InterruptHandler; |
| 22 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 21 | }); | 23 | }); |
| 22 | 24 | ||
| 23 | type Device = Ethernet<'static, ETH, GenericSMI>; | 25 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| @@ -36,7 +38,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 36 | info!("Hello World!"); | 38 | info!("Hello World!"); |
| 37 | 39 | ||
| 38 | // Generate random seed. | 40 | // Generate random seed. |
| 39 | let mut rng = Rng::new(p.RNG); | 41 | let mut rng = Rng::new(p.RNG, Irqs); |
| 40 | let mut seed = [0; 8]; | 42 | let mut seed = [0; 8]; |
| 41 | let _ = rng.async_fill_bytes(&mut seed).await; | 43 | let _ = rng.async_fill_bytes(&mut seed).await; |
| 42 | let seed = u64::from_le_bytes(seed); | 44 | let seed = u64::from_le_bytes(seed); |
diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index 7c5902052..1013a844e 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; | 7 | use embassy_stm32::gpio::OutputType; |
| 8 | use embassy_stm32::pwm::Channel; | ||
| 9 | use embassy_stm32::time::khz; | 8 | use embassy_stm32::time::khz; |
| 9 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | ||
| 10 | use embassy_stm32::timer::Channel; | ||
| 10 | use embassy_time::{Duration, Timer}; | 11 | use embassy_time::{Duration, Timer}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 13 | ||
| @@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) { | |||
| 15 | let p = embassy_stm32::init(Default::default()); | 16 | let p = embassy_stm32::init(Default::default()); |
| 16 | info!("Hello World!"); | 17 | info!("Hello World!"); |
| 17 | 18 | ||
| 18 | let ch1 = PwmPin::new_ch1(p.PE9); | 19 | let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull); |
| 19 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); | 20 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); |
| 20 | let max = pwm.get_max_duty(); | 21 | let max = pwm.get_max_duty(); |
| 21 | pwm.enable(Channel::Ch1); | 22 | pwm.enable(Channel::Ch1); |
diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs index a8a68ed6e..83a3c7537 100644 --- a/examples/stm32f4/src/bin/pwm_complementary.rs +++ b/examples/stm32f4/src/bin/pwm_complementary.rs | |||
| @@ -4,10 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::pwm::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | 7 | use embassy_stm32::gpio::OutputType; |
| 8 | use embassy_stm32::pwm::simple_pwm::PwmPin; | ||
| 9 | use embassy_stm32::pwm::Channel; | ||
| 10 | use embassy_stm32::time::khz; | 8 | use embassy_stm32::time::khz; |
| 9 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | ||
| 10 | use embassy_stm32::timer::simple_pwm::PwmPin; | ||
| 11 | use embassy_stm32::timer::Channel; | ||
| 11 | use embassy_time::{Duration, Timer}; | 12 | use embassy_time::{Duration, Timer}; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 14 | ||
| @@ -16,8 +17,8 @@ async fn main(_spawner: Spawner) { | |||
| 16 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 17 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 18 | 19 | ||
| 19 | let ch1 = PwmPin::new_ch1(p.PE9); | 20 | let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull); |
| 20 | let ch1n = ComplementaryPwmPin::new_ch1(p.PA7); | 21 | let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); |
| 21 | let mut pwm = ComplementaryPwm::new( | 22 | let mut pwm = ComplementaryPwm::new( |
| 22 | p.TIM1, | 23 | p.TIM1, |
| 23 | Some(ch1), | 24 | Some(ch1), |
diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs index 05b48f478..0919e9874 100644 --- a/examples/stm32f4/src/bin/spi.rs +++ b/examples/stm32f4/src/bin/spi.rs | |||
| @@ -16,16 +16,10 @@ fn main() -> ! { | |||
| 16 | 16 | ||
| 17 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 18 | 18 | ||
| 19 | let mut spi = Spi::new( | 19 | let mut spi_config = Config::default(); |
| 20 | p.SPI3, | 20 | spi_config.frequency = Hertz(1_000_000); |
| 21 | p.PC10, | 21 | |
| 22 | p.PC12, | 22 | let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); |
| 23 | p.PC11, | ||
| 24 | NoDma, | ||
| 25 | NoDma, | ||
| 26 | Hertz(1_000_000), | ||
| 27 | Config::default(), | ||
| 28 | ); | ||
| 29 | 23 | ||
| 30 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); | 24 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); |
| 31 | 25 | ||
diff --git a/examples/stm32f4/src/bin/spi_dma.rs b/examples/stm32f4/src/bin/spi_dma.rs index 3d2a1a1ae..f291f7dba 100644 --- a/examples/stm32f4/src/bin/spi_dma.rs +++ b/examples/stm32f4/src/bin/spi_dma.rs | |||
| @@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 18 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 19 | 19 | ||
| 20 | let mut spi = Spi::new( | 20 | let mut spi_config = Config::default(); |
| 21 | p.SPI1, | 21 | spi_config.frequency = Hertz(1_000_000); |
| 22 | p.PB3, | 22 | |
| 23 | p.PB5, | 23 | let mut spi = Spi::new(p.SPI1, p.PB3, p.PB5, p.PB4, p.DMA2_CH3, p.DMA2_CH2, spi_config); |
| 24 | p.PB4, | ||
| 25 | p.DMA2_CH3, | ||
| 26 | p.DMA2_CH2, | ||
| 27 | Hertz(1_000_000), | ||
| 28 | Config::default(), | ||
| 29 | ); | ||
| 30 | 24 | ||
| 31 | for n in 0u32.. { | 25 | for n in 0u32.. { |
| 32 | let mut write: String<128> = String::new(); | 26 | let mut write: String<128> = String::new(); |
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index b1f01417c..740d3018e 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs | |||
| @@ -6,7 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_net::tcp::TcpSocket; | 7 | use embassy_net::tcp::TcpSocket; |
| 8 | use embassy_net::{Stack, StackResources}; | 8 | use embassy_net::{Stack, StackResources}; |
| 9 | use embassy_stm32::rng::Rng; | 9 | use embassy_stm32::rng::{self, Rng}; |
| 10 | use embassy_stm32::time::mhz; | 10 | use embassy_stm32::time::mhz; |
| 11 | use embassy_stm32::usb_otg::Driver; | 11 | use embassy_stm32::usb_otg::Driver; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 12 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; |
| @@ -38,6 +38,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { | |||
| 38 | 38 | ||
| 39 | bind_interrupts!(struct Irqs { | 39 | bind_interrupts!(struct Irqs { |
| 40 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 40 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; |
| 41 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 41 | }); | 42 | }); |
| 42 | 43 | ||
| 43 | #[embassy_executor::main] | 44 | #[embassy_executor::main] |
| @@ -104,7 +105,7 @@ async fn main(spawner: Spawner) { | |||
| 104 | //}); | 105 | //}); |
| 105 | 106 | ||
| 106 | // Generate random seed | 107 | // Generate random seed |
| 107 | let mut rng = Rng::new(p.RNG); | 108 | let mut rng = Rng::new(p.RNG, Irqs); |
| 108 | let mut seed = [0; 8]; | 109 | let mut seed = [0; 8]; |
| 109 | unwrap!(rng.async_fill_bytes(&mut seed).await); | 110 | unwrap!(rng.async_fill_bytes(&mut seed).await); |
| 110 | let seed = u64::from_le_bytes(seed); | 111 | let seed = u64::from_le_bytes(seed); |
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index bbc99fee0..a379cbbe3 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f767zi to your chip name, if necessary. | 8 | # Change stm32f767zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } |
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| @@ -28,3 +28,6 @@ rand_core = "0.6.3" | |||
| 28 | critical-section = "1.1" | 28 | critical-section = "1.1" |
| 29 | embedded-storage = "0.3.0" | 29 | embedded-storage = "0.3.0" |
| 30 | static_cell = { version = "1.1", features = ["nightly"]} | 30 | static_cell = { version = "1.1", features = ["nightly"]} |
| 31 | |||
| 32 | [profile.release] | ||
| 33 | debug = 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 | 1 | fn main() { |
| 2 | use std::fs::File; | ||
| 3 | use std::io::prelude::*; | ||
| 4 | use std::path::PathBuf; | ||
| 5 | use std::{env, io}; | ||
| 6 | |||
| 7 | #[derive(Debug)] | ||
| 8 | enum Error { | ||
| 9 | Env(env::VarError), | ||
| 10 | Io(io::Error), | ||
| 11 | } | ||
| 12 | |||
| 13 | impl From<env::VarError> for Error { | ||
| 14 | fn from(error: env::VarError) -> Self { | ||
| 15 | Self::Env(error) | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | impl From<io::Error> for Error { | ||
| 20 | fn from(error: io::Error) -> Self { | ||
| 21 | Self::Io(error) | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | fn 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 */ | ||
| 2 | MEMORY | ||
| 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/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index c6b2ba45c..e5abf52bc 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs | |||
| @@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; | |||
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{bind_interrupts, eth, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use rand_core::RngCore; | 17 | use rand_core::RngCore; |
| 18 | use static_cell::make_static; | 18 | use static_cell::make_static; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | |||
| 20 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| 21 | ETH => eth::InterruptHandler; | 22 | ETH => eth::InterruptHandler; |
| 23 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 22 | }); | 24 | }); |
| 23 | 25 | ||
| 24 | type Device = Ethernet<'static, ETH, GenericSMI>; | 26 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| @@ -37,7 +39,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 37 | info!("Hello World!"); | 39 | info!("Hello World!"); |
| 38 | 40 | ||
| 39 | // Generate random seed. | 41 | // Generate random seed. |
| 40 | let mut rng = Rng::new(p.RNG); | 42 | let mut rng = Rng::new(p.RNG, Irqs); |
| 41 | let mut seed = [0; 8]; | 43 | let mut seed = [0; 8]; |
| 42 | rng.fill_bytes(&mut seed); | 44 | rng.fill_bytes(&mut seed); |
| 43 | let seed = u64::from_le_bytes(seed); | 45 | let seed = u64::from_le_bytes(seed); |
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 4a14568ac..b4dfe3c6b 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -20,3 +20,6 @@ embedded-hal = "0.2.6" | |||
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 22 | heapless = { version = "0.7.5", default-features = false } | 22 | heapless = { version = "0.7.5", default-features = false } |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs index 81fdd15cb..ee7aaf33f 100644 --- a/examples/stm32g0/src/bin/spi_neopixel.rs +++ b/examples/stm32g0/src/bin/spi_neopixel.rs | |||
| @@ -76,7 +76,9 @@ async fn main(_spawner: Spawner) { | |||
| 76 | let p = embassy_stm32::init(Default::default()); | 76 | let p = embassy_stm32::init(Default::default()); |
| 77 | info!("Start test using spi as neopixel driver"); | 77 | info!("Start test using spi as neopixel driver"); |
| 78 | 78 | ||
| 79 | let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, Hertz(4_000_000), Config::default()); | 79 | let mut config = Config::default(); |
| 80 | config.frequency = Hertz(4_000_000); | ||
| 81 | let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, config); | ||
| 80 | 82 | ||
| 81 | let mut neopixels = Ws2812::new(); | 83 | let mut neopixels = Ws2812::new(); |
| 82 | 84 | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 935997a74..cf3e2ce9b 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -10,7 +10,6 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" | |||
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | ||
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | 14 | ||
| 16 | defmt = "0.3" | 15 | defmt = "0.3" |
| @@ -22,3 +21,6 @@ embedded-hal = "0.2.6" | |||
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 24 | heapless = { version = "0.7.5", default-features = false } | 23 | heapless = { version = "0.7.5", default-features = false } |
| 24 | |||
| 25 | [profile.release] | ||
| 26 | debug = 2 | ||
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 8f7842ed7..01e9cb476 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; | 7 | use embassy_stm32::gpio::OutputType; |
| 8 | use embassy_stm32::pwm::Channel; | ||
| 9 | use embassy_stm32::time::khz; | 8 | use embassy_stm32::time::khz; |
| 9 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | ||
| 10 | use embassy_stm32::timer::Channel; | ||
| 10 | use embassy_time::{Duration, Timer}; | 11 | use embassy_time::{Duration, Timer}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 13 | ||
| @@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) { | |||
| 15 | let p = embassy_stm32::init(Default::default()); | 16 | let p = embassy_stm32::init(Default::default()); |
| 16 | info!("Hello World!"); | 17 | info!("Hello World!"); |
| 17 | 18 | ||
| 18 | let ch1 = PwmPin::new_ch1(p.PC0); | 19 | let ch1 = PwmPin::new_ch1(p.PC0, OutputType::PushPull); |
| 19 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); | 20 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); |
| 20 | let max = pwm.get_max_duty(); | 21 | let max = pwm.get_max_duty(); |
| 21 | pwm.enable(Channel::Ch1); | 22 | pwm.enable(Channel::Ch1); |
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index aebc795c1..51d3bad1f 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32h563zi to your chip name, if necessary. | 8 | # Change stm32h563zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } |
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } |
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 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x08000000, LENGTH = 0x200000 | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 0x50000 | ||
| 5 | } | ||
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 0bff85ed8..2aa2ab62b 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs | |||
| @@ -12,14 +12,16 @@ use embassy_stm32::peripherals::ETH; | |||
| 12 | use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; | 12 | use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; |
| 13 | use embassy_stm32::rng::Rng; | 13 | use embassy_stm32::rng::Rng; |
| 14 | use embassy_stm32::time::Hertz; | 14 | use embassy_stm32::time::Hertz; |
| 15 | use embassy_stm32::{bind_interrupts, eth, Config}; | 15 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; |
| 16 | use embassy_time::{Duration, Timer}; | 16 | use embassy_time::{Duration, Timer}; |
| 17 | use embedded_io::asynch::Write; | 17 | use embedded_io::asynch::Write; |
| 18 | use rand_core::RngCore; | 18 | use rand_core::RngCore; |
| 19 | use static_cell::make_static; | 19 | use static_cell::make_static; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | |||
| 21 | bind_interrupts!(struct Irqs { | 22 | bind_interrupts!(struct Irqs { |
| 22 | ETH => eth::InterruptHandler; | 23 | ETH => eth::InterruptHandler; |
| 24 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 23 | }); | 25 | }); |
| 24 | 26 | ||
| 25 | type Device = Ethernet<'static, ETH, GenericSMI>; | 27 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| @@ -56,7 +58,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 56 | info!("Hello World!"); | 58 | info!("Hello World!"); |
| 57 | 59 | ||
| 58 | // Generate random seed. | 60 | // Generate random seed. |
| 59 | let mut rng = Rng::new(p.RNG); | 61 | let mut rng = Rng::new(p.RNG, Irqs); |
| 60 | let mut seed = [0; 8]; | 62 | let mut seed = [0; 8]; |
| 61 | rng.fill_bytes(&mut seed); | 63 | rng.fill_bytes(&mut seed); |
| 62 | let seed = u64::from_le_bytes(seed); | 64 | let seed = u64::from_le_bytes(seed); |
diff --git a/examples/stm32h5/src/bin/rng.rs b/examples/stm32h5/src/bin/rng.rs index af9be0b62..7c8c50eca 100644 --- a/examples/stm32h5/src/bin/rng.rs +++ b/examples/stm32h5/src/bin/rng.rs | |||
| @@ -5,14 +5,19 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rng::Rng; | 7 | use embassy_stm32::rng::Rng; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, rng}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 10 | ||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 13 | }); | ||
| 14 | |||
| 10 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 11 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 12 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 14 | 19 | ||
| 15 | let mut rng = Rng::new(p.RNG); | 20 | let mut rng = Rng::new(p.RNG, Irqs); |
| 16 | 21 | ||
| 17 | let mut buf = [0u8; 16]; | 22 | let mut buf = [0u8; 16]; |
| 18 | unwrap!(rng.async_fill_bytes(&mut buf).await); | 23 | unwrap!(rng.async_fill_bytes(&mut buf).await); |
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] |
| 2 | runner = 'probe-rs run --chip STM32H743ZITx' | 2 | runner = 'probe-rs run --chip STM32H7A3ZITxQ' |
| 3 | 3 | ||
| 4 | [build] | 4 | [build] |
| 5 | target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) | 5 | target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) |
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 2d82c0d0d..3c1232e67 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32h743bi to your chip name, if necessary. | 8 | # Change stm32h743bi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits"] } |
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } |
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 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x8000000, LENGTH = 1024K | ||
| 4 | RAM : ORIGIN = 0x24000000, LENGTH = 384K | ||
| 5 | } | ||
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 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::dac::{DacChannel, ValueArray}; | ||
| 8 | use embassy_stm32::pac::timer::vals::{Mms, Opm}; | ||
| 9 | use embassy_stm32::peripherals::{TIM6, TIM7}; | ||
| 10 | use embassy_stm32::rcc::low_level::RccPeripheral; | ||
| 11 | use embassy_stm32::time::{mhz, Hertz}; | ||
| 12 | use embassy_stm32::timer::low_level::Basic16bitInstance; | ||
| 13 | use micromath::F32Ext; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | pub type Dac1Type = | ||
| 17 | embassy_stm32::dac::DacCh1<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH3>; | ||
| 18 | |||
| 19 | pub type Dac2Type = | ||
| 20 | embassy_stm32::dac::DacCh2<'static, embassy_stm32::peripherals::DAC1, embassy_stm32::peripherals::DMA1_CH4>; | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async 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] | ||
| 40 | async 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] | ||
| 84 | async 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 | |||
| 120 | fn 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 | |||
| 132 | fn 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/eth.rs b/examples/stm32h7/src/bin/eth.rs index cfafcaed1..c93be9f00 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs | |||
| @@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; | |||
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{bind_interrupts, eth, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use rand_core::RngCore; | 17 | use rand_core::RngCore; |
| 18 | use static_cell::make_static; | 18 | use static_cell::make_static; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | |||
| 20 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| 21 | ETH => eth::InterruptHandler; | 22 | ETH => eth::InterruptHandler; |
| 23 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 22 | }); | 24 | }); |
| 23 | 25 | ||
| 24 | type Device = Ethernet<'static, ETH, GenericSMI>; | 26 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| @@ -38,7 +40,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 38 | info!("Hello World!"); | 40 | info!("Hello World!"); |
| 39 | 41 | ||
| 40 | // Generate random seed. | 42 | // Generate random seed. |
| 41 | let mut rng = Rng::new(p.RNG); | 43 | let mut rng = Rng::new(p.RNG, Irqs); |
| 42 | let mut seed = [0; 8]; | 44 | let mut seed = [0; 8]; |
| 43 | rng.fill_bytes(&mut seed); | 45 | rng.fill_bytes(&mut seed); |
| 44 | let seed = u64::from_le_bytes(seed); | 46 | let seed = u64::from_le_bytes(seed); |
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 4ed737578..78005e91f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs | |||
| @@ -11,15 +11,17 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; | |||
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{bind_interrupts, eth, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | 17 | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; |
| 18 | use rand_core::RngCore; | 18 | use rand_core::RngCore; |
| 19 | use static_cell::make_static; | 19 | use static_cell::make_static; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | |||
| 21 | bind_interrupts!(struct Irqs { | 22 | bind_interrupts!(struct Irqs { |
| 22 | ETH => eth::InterruptHandler; | 23 | ETH => eth::InterruptHandler; |
| 24 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 23 | }); | 25 | }); |
| 24 | 26 | ||
| 25 | type Device = Ethernet<'static, ETH, GenericSMI>; | 27 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| @@ -39,7 +41,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 39 | info!("Hello World!"); | 41 | info!("Hello World!"); |
| 40 | 42 | ||
| 41 | // Generate random seed. | 43 | // Generate random seed. |
| 42 | let mut rng = Rng::new(p.RNG); | 44 | let mut rng = Rng::new(p.RNG, Irqs); |
| 43 | let mut seed = [0; 8]; | 45 | let mut seed = [0; 8]; |
| 44 | rng.fill_bytes(&mut seed); | 46 | rng.fill_bytes(&mut seed); |
| 45 | let seed = u64::from_le_bytes(seed); | 47 | let seed = u64::from_le_bytes(seed); |
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::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::gpio::low_level::AFType; | 7 | use embassy_stm32::gpio::low_level::AFType; |
| 8 | use embassy_stm32::gpio::Speed; | 8 | use embassy_stm32::gpio::Speed; |
| 9 | use embassy_stm32::pwm::*; | ||
| 10 | use embassy_stm32::time::{khz, mhz, Hertz}; | 9 | use embassy_stm32::time::{khz, mhz, Hertz}; |
| 10 | use embassy_stm32::timer::*; | ||
| 11 | use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; | 11 | use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; |
| 12 | use embassy_time::{Duration, Timer}; | 12 | use embassy_time::{Duration, Timer}; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index c5c0dd290..aa5ec1bcf 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; | 7 | use embassy_stm32::gpio::OutputType; |
| 8 | use embassy_stm32::pwm::Channel; | ||
| 9 | use embassy_stm32::time::{khz, mhz}; | 8 | use embassy_stm32::time::{khz, mhz}; |
| 9 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | ||
| 10 | use embassy_stm32::timer::Channel; | ||
| 10 | use embassy_stm32::Config; | 11 | use embassy_stm32::Config; |
| 11 | use embassy_time::{Duration, Timer}; | 12 | use embassy_time::{Duration, Timer}; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -24,7 +25,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let p = embassy_stm32::init(config); | 25 | let p = embassy_stm32::init(config); |
| 25 | info!("Hello World!"); | 26 | info!("Hello World!"); |
| 26 | 27 | ||
| 27 | let ch1 = PwmPin::new_ch1(p.PA6); | 28 | let ch1 = PwmPin::new_ch1(p.PA6, OutputType::PushPull); |
| 28 | let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); | 29 | let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); |
| 29 | let max = pwm.get_max_duty(); | 30 | let max = pwm.get_max_duty(); |
| 30 | pwm.enable(Channel::Ch1); | 31 | pwm.enable(Channel::Ch1); |
diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs index af9be0b62..7c8c50eca 100644 --- a/examples/stm32h7/src/bin/rng.rs +++ b/examples/stm32h7/src/bin/rng.rs | |||
| @@ -5,14 +5,19 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rng::Rng; | 7 | use embassy_stm32::rng::Rng; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, rng}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 10 | ||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 13 | }); | ||
| 14 | |||
| 10 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 11 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 12 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 14 | 19 | ||
| 15 | let mut rng = Rng::new(p.RNG); | 20 | let mut rng = Rng::new(p.RNG, Irqs); |
| 16 | 21 | ||
| 17 | let mut buf = [0u8; 16]; | 22 | let mut buf = [0u8; 16]; |
| 18 | unwrap!(rng.async_fill_bytes(&mut buf).await); | 23 | unwrap!(rng.async_fill_bytes(&mut buf).await); |
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index 1f407f002..28bba2b8d 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs | |||
| @@ -43,16 +43,10 @@ fn main() -> ! { | |||
| 43 | config.rcc.pll1.q_ck = Some(mhz(100)); | 43 | config.rcc.pll1.q_ck = Some(mhz(100)); |
| 44 | let p = embassy_stm32::init(config); | 44 | let p = embassy_stm32::init(config); |
| 45 | 45 | ||
| 46 | let spi = spi::Spi::new( | 46 | let mut spi_config = spi::Config::default(); |
| 47 | p.SPI3, | 47 | spi_config.frequency = mhz(1); |
| 48 | p.PB3, | 48 | |
| 49 | p.PB5, | 49 | let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, NoDma, NoDma, spi_config); |
| 50 | p.PB4, | ||
| 51 | NoDma, | ||
| 52 | NoDma, | ||
| 53 | mhz(1), | ||
| 54 | spi::Config::default(), | ||
| 55 | ); | ||
| 56 | 50 | ||
| 57 | let executor = EXECUTOR.init(Executor::new()); | 51 | let executor = EXECUTOR.init(Executor::new()); |
| 58 | 52 | ||
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 53004fc9b..f6e30cfa5 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs | |||
| @@ -39,16 +39,10 @@ fn main() -> ! { | |||
| 39 | config.rcc.pll1.q_ck = Some(mhz(100)); | 39 | config.rcc.pll1.q_ck = Some(mhz(100)); |
| 40 | let p = embassy_stm32::init(config); | 40 | let p = embassy_stm32::init(config); |
| 41 | 41 | ||
| 42 | let spi = spi::Spi::new( | 42 | let mut spi_config = spi::Config::default(); |
| 43 | p.SPI3, | 43 | spi_config.frequency = mhz(1); |
| 44 | p.PB3, | 44 | |
| 45 | p.PB5, | 45 | let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, p.DMA1_CH3, p.DMA1_CH4, spi_config); |
| 46 | p.PB4, | ||
| 47 | p.DMA1_CH3, | ||
| 48 | p.DMA1_CH4, | ||
| 49 | mhz(1), | ||
| 50 | spi::Config::default(), | ||
| 51 | ); | ||
| 52 | 46 | ||
| 53 | let executor = EXECUTOR.init(Executor::new()); | 47 | let executor = EXECUTOR.init(Executor::new()); |
| 54 | 48 | ||
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index e6a5a4c14..c325751c6 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -34,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 34 | embedded-hal = "0.2.6" | 34 | embedded-hal = "0.2.6" |
| 35 | static_cell = "1.1" | 35 | static_cell = "1.1" |
| 36 | 36 | ||
| 37 | [patch.crates-io] | 37 | [profile.release] |
| 38 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 38 | debug = 2 |
diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 588cea1e5..7729b4163 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs | |||
| @@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) { | |||
| 27 | config.rcc.enable_hsi48 = true; | 27 | config.rcc.enable_hsi48 = true; |
| 28 | let p = embassy_stm32::init(config); | 28 | let p = embassy_stm32::init(config); |
| 29 | 29 | ||
| 30 | let mut spi_config = spi::Config::default(); | ||
| 31 | spi_config.frequency = khz(200); | ||
| 32 | |||
| 30 | // SPI for sx1276 | 33 | // SPI for sx1276 |
| 31 | let spi = spi::Spi::new( | 34 | let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config); |
| 32 | p.SPI1, | ||
| 33 | p.PB3, | ||
| 34 | p.PA7, | ||
| 35 | p.PA6, | ||
| 36 | p.DMA1_CH3, | ||
| 37 | p.DMA1_CH2, | ||
| 38 | khz(200), | ||
| 39 | spi::Config::default(), | ||
| 40 | ); | ||
| 41 | 35 | ||
| 42 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); | 36 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); |
| 43 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); | 37 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); |
diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index c397edd58..10608aebf 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs | |||
| @@ -12,8 +12,8 @@ use embassy_lora::LoraTimer; | |||
| 12 | use embassy_stm32::exti::{Channel, ExtiInput}; | 12 | use embassy_stm32::exti::{Channel, ExtiInput}; |
| 13 | use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; | 13 | use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; |
| 14 | use embassy_stm32::rng::Rng; | 14 | use embassy_stm32::rng::Rng; |
| 15 | use embassy_stm32::spi; | ||
| 16 | use embassy_stm32::time::khz; | 15 | use embassy_stm32::time::khz; |
| 16 | use embassy_stm32::{bind_interrupts, peripherals, rng, spi}; | ||
| 17 | use embassy_time::Delay; | 17 | use embassy_time::Delay; |
| 18 | use lora_phy::mod_params::*; | 18 | use lora_phy::mod_params::*; |
| 19 | use lora_phy::sx1276_7_8_9::SX1276_7_8_9; | 19 | use lora_phy::sx1276_7_8_9::SX1276_7_8_9; |
| @@ -23,6 +23,10 @@ use lorawan_device::async_device::lora_radio::LoRaRadio; | |||
| 23 | use lorawan_device::async_device::{region, Device, JoinMode}; | 23 | use lorawan_device::async_device::{region, Device, JoinMode}; |
| 24 | use {defmt_rtt as _, panic_probe as _}; | 24 | use {defmt_rtt as _, panic_probe as _}; |
| 25 | 25 | ||
| 26 | bind_interrupts!(struct Irqs { | ||
| 27 | RNG_LPUART1 => rng::InterruptHandler<peripherals::RNG>; | ||
| 28 | }); | ||
| 29 | |||
| 26 | const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set this appropriately for the region | 30 | const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set this appropriately for the region |
| 27 | 31 | ||
| 28 | #[embassy_executor::main] | 32 | #[embassy_executor::main] |
| @@ -32,17 +36,11 @@ async fn main(_spawner: Spawner) { | |||
| 32 | config.rcc.enable_hsi48 = true; | 36 | config.rcc.enable_hsi48 = true; |
| 33 | let p = embassy_stm32::init(config); | 37 | let p = embassy_stm32::init(config); |
| 34 | 38 | ||
| 39 | let mut spi_config = spi::Config::default(); | ||
| 40 | spi_config.frequency = khz(200); | ||
| 41 | |||
| 35 | // SPI for sx1276 | 42 | // SPI for sx1276 |
| 36 | let spi = spi::Spi::new( | 43 | let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config); |
| 37 | p.SPI1, | ||
| 38 | p.PB3, | ||
| 39 | p.PA7, | ||
| 40 | p.PA6, | ||
| 41 | p.DMA1_CH3, | ||
| 42 | p.DMA1_CH2, | ||
| 43 | khz(200), | ||
| 44 | spi::Config::default(), | ||
| 45 | ); | ||
| 46 | 44 | ||
| 47 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); | 45 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); |
| 48 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); | 46 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); |
| @@ -66,7 +64,7 @@ async fn main(_spawner: Spawner) { | |||
| 66 | 64 | ||
| 67 | let radio = LoRaRadio::new(lora); | 65 | let radio = LoRaRadio::new(lora); |
| 68 | let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); | 66 | let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); |
| 69 | let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG)); | 67 | let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs)); |
| 70 | 68 | ||
| 71 | defmt::info!("Joining LoRaWAN network"); | 69 | defmt::info!("Joining LoRaWAN network"); |
| 72 | 70 | ||
diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index bb7509509..0f9f60952 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs | |||
| @@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) { | |||
| 27 | config.rcc.enable_hsi48 = true; | 27 | config.rcc.enable_hsi48 = true; |
| 28 | let p = embassy_stm32::init(config); | 28 | let p = embassy_stm32::init(config); |
| 29 | 29 | ||
| 30 | let mut spi_config = spi::Config::default(); | ||
| 31 | spi_config.frequency = khz(200); | ||
| 32 | |||
| 30 | // SPI for sx1276 | 33 | // SPI for sx1276 |
| 31 | let spi = spi::Spi::new( | 34 | let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config); |
| 32 | p.SPI1, | ||
| 33 | p.PB3, | ||
| 34 | p.PA7, | ||
| 35 | p.PA6, | ||
| 36 | p.DMA1_CH3, | ||
| 37 | p.DMA1_CH2, | ||
| 38 | khz(200), | ||
| 39 | spi::Config::default(), | ||
| 40 | ); | ||
| 41 | 35 | ||
| 42 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); | 36 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); |
| 43 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); | 37 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); |
diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs index e6fadc01d..c85c3c2b6 100644 --- a/examples/stm32l0/src/bin/lora_p2p_send.rs +++ b/examples/stm32l0/src/bin/lora_p2p_send.rs | |||
| @@ -27,17 +27,11 @@ async fn main(_spawner: Spawner) { | |||
| 27 | config.rcc.enable_hsi48 = true; | 27 | config.rcc.enable_hsi48 = true; |
| 28 | let p = embassy_stm32::init(config); | 28 | let p = embassy_stm32::init(config); |
| 29 | 29 | ||
| 30 | let mut spi_config = spi::Config::default(); | ||
| 31 | spi_config.frequency = khz(200); | ||
| 32 | |||
| 30 | // SPI for sx1276 | 33 | // SPI for sx1276 |
| 31 | let spi = spi::Spi::new( | 34 | let spi = spi::Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2, spi_config); |
| 32 | p.SPI1, | ||
| 33 | p.PB3, | ||
| 34 | p.PA7, | ||
| 35 | p.PA6, | ||
| 36 | p.DMA1_CH3, | ||
| 37 | p.DMA1_CH2, | ||
| 38 | khz(200), | ||
| 39 | spi::Config::default(), | ||
| 40 | ); | ||
| 41 | 35 | ||
| 42 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); | 36 | let nss = Output::new(p.PA15.degrade(), Level::High, Speed::Low); |
| 43 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); | 37 | let reset = Output::new(p.PC0.degrade(), Level::High, Speed::Low); |
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs index 9b5b3e27d..583e3d127 100644 --- a/examples/stm32l0/src/bin/spi.rs +++ b/examples/stm32l0/src/bin/spi.rs | |||
| @@ -15,16 +15,10 @@ async fn main(_spawner: Spawner) { | |||
| 15 | let p = embassy_stm32::init(Default::default()); | 15 | let p = embassy_stm32::init(Default::default()); |
| 16 | info!("Hello World, folks!"); | 16 | info!("Hello World, folks!"); |
| 17 | 17 | ||
| 18 | let mut spi = Spi::new( | 18 | let mut spi_config = Config::default(); |
| 19 | p.SPI1, | 19 | spi_config.frequency = Hertz(1_000_000); |
| 20 | p.PB3, | 20 | |
| 21 | p.PA7, | 21 | let mut spi = Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, NoDma, NoDma, spi_config); |
| 22 | p.PA6, | ||
| 23 | NoDma, | ||
| 24 | NoDma, | ||
| 25 | Hertz(1_000_000), | ||
| 26 | Config::default(), | ||
| 27 | ); | ||
| 28 | 22 | ||
| 29 | let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); | 23 | let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); |
| 30 | 24 | ||
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"] } | |||
| 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 21 | heapless = { version = "0.7.5", default-features = false } | 21 | heapless = { version = "0.7.5", default-features = false } |
| 22 | embedded-storage = "0.3.0" | 22 | embedded-storage = "0.3.0" |
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs index 0a532e8e3..905b4d75c 100644 --- a/examples/stm32l1/src/bin/spi.rs +++ b/examples/stm32l1/src/bin/spi.rs | |||
| @@ -15,16 +15,10 @@ async fn main(_spawner: Spawner) { | |||
| 15 | let p = embassy_stm32::init(Default::default()); | 15 | let p = embassy_stm32::init(Default::default()); |
| 16 | info!("Hello World, folks!"); | 16 | info!("Hello World, folks!"); |
| 17 | 17 | ||
| 18 | let mut spi = Spi::new( | 18 | let mut spi_config = Config::default(); |
| 19 | p.SPI1, | 19 | spi_config.frequency = Hertz(1_000_000); |
| 20 | p.PA5, | 20 | |
| 21 | p.PA7, | 21 | let mut spi = Spi::new(p.SPI1, p.PA5, p.PA7, p.PA6, NoDma, NoDma, spi_config); |
| 22 | p.PA6, | ||
| 23 | NoDma, | ||
| 24 | NoDma, | ||
| 25 | Hertz(1_000_000), | ||
| 26 | Config::default(), | ||
| 27 | ); | ||
| 28 | 22 | ||
| 29 | let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); | 23 | let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); |
| 30 | 24 | ||
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 41c9869bf..3b27d8e81 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32l4s5vi to your chip name, if necessary. | 8 | # Change stm32l4s5vi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits", "chrono"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "memory-x", "time-driver-any", "exti", "unstable-traits", "chrono"] } |
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 27 | chrono = { version = "^0.4", default-features = false } | 27 | chrono = { version = "^0.4", default-features = false } |
| 28 | 28 | ||
| 29 | micromath = "2.0.0" | 29 | micromath = "2.0.0" |
| 30 | |||
| 31 | [profile.release] | ||
| 32 | debug = 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 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 16 | fn main() { | 1 | fn 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 @@ | |||
| 1 | MEMORY | ||
| 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/rng.rs b/examples/stm32l4/src/bin/rng.rs index c9302bb99..806e49f59 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs | |||
| @@ -6,9 +6,13 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; | 7 | use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; |
| 8 | use embassy_stm32::rng::Rng; | 8 | use embassy_stm32::rng::Rng; |
| 9 | use embassy_stm32::Config; | 9 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 14 | }); | ||
| 15 | |||
| 12 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 14 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| @@ -24,7 +28,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | 28 | ||
| 25 | info!("Hello World!"); | 29 | info!("Hello World!"); |
| 26 | 30 | ||
| 27 | let mut rng = Rng::new(p.RNG); | 31 | let mut rng = Rng::new(p.RNG, Irqs); |
| 28 | 32 | ||
| 29 | let mut buf = [0u8; 16]; | 33 | let mut buf = [0u8; 16]; |
| 30 | unwrap!(rng.async_fill_bytes(&mut buf).await); | 34 | unwrap!(rng.async_fill_bytes(&mut buf).await); |
diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs index 76e316a25..54cf68f7b 100644 --- a/examples/stm32l4/src/bin/spi.rs +++ b/examples/stm32l4/src/bin/spi.rs | |||
| @@ -15,16 +15,10 @@ fn main() -> ! { | |||
| 15 | 15 | ||
| 16 | let p = embassy_stm32::init(Default::default()); | 16 | let p = embassy_stm32::init(Default::default()); |
| 17 | 17 | ||
| 18 | let mut spi = Spi::new( | 18 | let mut spi_config = Config::default(); |
| 19 | p.SPI3, | 19 | spi_config.frequency = Hertz(1_000_000); |
| 20 | p.PC10, | 20 | |
| 21 | p.PC12, | 21 | let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); |
| 22 | p.PC11, | ||
| 23 | NoDma, | ||
| 24 | NoDma, | ||
| 25 | Hertz(1_000_000), | ||
| 26 | Config::default(), | ||
| 27 | ); | ||
| 28 | 22 | ||
| 29 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); | 23 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); |
| 30 | 24 | ||
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs index 62ef0130e..f1b80087c 100644 --- a/examples/stm32l4/src/bin/spi_blocking_async.rs +++ b/examples/stm32l4/src/bin/spi_blocking_async.rs | |||
| @@ -17,16 +17,10 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 18 | info!("Hello World!"); | 18 | info!("Hello World!"); |
| 19 | 19 | ||
| 20 | let spi = Spi::new( | 20 | let mut spi_config = Config::default(); |
| 21 | p.SPI3, | 21 | spi_config.frequency = Hertz(1_000_000); |
| 22 | p.PC10, | 22 | |
| 23 | p.PC12, | 23 | let spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); |
| 24 | p.PC11, | ||
| 25 | NoDma, | ||
| 26 | NoDma, | ||
| 27 | Hertz(1_000_000), | ||
| 28 | Config::default(), | ||
| 29 | ); | ||
| 30 | 24 | ||
| 31 | let mut spi = BlockingAsync::new(spi); | 25 | let mut spi = BlockingAsync::new(spi); |
| 32 | 26 | ||
diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs index 89471db5a..ff9b5b43b 100644 --- a/examples/stm32l4/src/bin/spi_dma.rs +++ b/examples/stm32l4/src/bin/spi_dma.rs | |||
| @@ -14,16 +14,10 @@ async fn main(_spawner: Spawner) { | |||
| 14 | let p = embassy_stm32::init(Default::default()); | 14 | let p = embassy_stm32::init(Default::default()); |
| 15 | info!("Hello World!"); | 15 | info!("Hello World!"); |
| 16 | 16 | ||
| 17 | let mut spi = Spi::new( | 17 | let mut spi_config = Config::default(); |
| 18 | p.SPI3, | 18 | spi_config.frequency = Hertz(1_000_000); |
| 19 | p.PC10, | 19 | |
| 20 | p.PC12, | 20 | let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, p.DMA1_CH1, p.DMA1_CH2, spi_config); |
| 21 | p.PC11, | ||
| 22 | p.DMA1_CH1, | ||
| 23 | p.DMA1_CH2, | ||
| 24 | Hertz(1_000_000), | ||
| 25 | Config::default(), | ||
| 26 | ); | ||
| 27 | 21 | ||
| 28 | // These are the pins for the Inventek eS-Wifi SPI Wifi Adapter. | 22 | // These are the pins for the Inventek eS-Wifi SPI Wifi Adapter. |
| 29 | 23 | ||
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5d66c59c3..1afd00398 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 27 | rand_core = { version = "0.6.3", default-features = false } | 27 | rand_core = { version = "0.6.3", default-features = false } |
| 28 | embedded-io = { version = "0.4.0", features = ["async"] } | 28 | embedded-io = { version = "0.4.0", features = ["async"] } |
| 29 | static_cell = { version = "1.1", features = ["nightly"]} | 29 | static_cell = { version = "1.1", features = ["nightly"]} |
| 30 | |||
| 31 | [profile.release] | ||
| 32 | debug = 2 | ||
diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index d359847e8..9549d64d8 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs | |||
| @@ -6,9 +6,13 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; | 7 | use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; |
| 8 | use embassy_stm32::rng::Rng; | 8 | use embassy_stm32::rng::Rng; |
| 9 | use embassy_stm32::Config; | 9 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 14 | }); | ||
| 15 | |||
| 12 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 14 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| @@ -23,7 +27,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | 27 | ||
| 24 | info!("Hello World!"); | 28 | info!("Hello World!"); |
| 25 | 29 | ||
| 26 | let mut rng = Rng::new(p.RNG); | 30 | let mut rng = Rng::new(p.RNG, Irqs); |
| 27 | 31 | ||
| 28 | let mut buf = [0u8; 16]; | 32 | let mut buf = [0u8; 16]; |
| 29 | unwrap!(rng.async_fill_bytes(&mut buf).await); | 33 | unwrap!(rng.async_fill_bytes(&mut buf).await); |
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 32eba4277..5e75b21c9 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs | |||
| @@ -9,7 +9,7 @@ use embassy_net::{Stack, StackResources}; | |||
| 9 | use embassy_stm32::rcc::*; | 9 | use embassy_stm32::rcc::*; |
| 10 | use embassy_stm32::rng::Rng; | 10 | use embassy_stm32::rng::Rng; |
| 11 | use embassy_stm32::usb::Driver; | 11 | use embassy_stm32::usb::Driver; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 12 | use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; |
| 13 | use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; | 13 | use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; |
| 14 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | 14 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; |
| 15 | use embassy_usb::{Builder, UsbDevice}; | 15 | use embassy_usb::{Builder, UsbDevice}; |
| @@ -24,6 +24,7 @@ const MTU: usize = 1514; | |||
| 24 | 24 | ||
| 25 | bind_interrupts!(struct Irqs { | 25 | bind_interrupts!(struct Irqs { |
| 26 | USB_FS => usb::InterruptHandler<peripherals::USB>; | 26 | USB_FS => usb::InterruptHandler<peripherals::USB>; |
| 27 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 27 | }); | 28 | }); |
| 28 | 29 | ||
| 29 | #[embassy_executor::task] | 30 | #[embassy_executor::task] |
| @@ -99,7 +100,7 @@ async fn main(spawner: Spawner) { | |||
| 99 | //}); | 100 | //}); |
| 100 | 101 | ||
| 101 | // Generate random seed | 102 | // Generate random seed |
| 102 | let mut rng = Rng::new(p.RNG); | 103 | let mut rng = Rng::new(p.RNG, Irqs); |
| 103 | let seed = rng.next_u64(); | 104 | let seed = rng.next_u64(); |
| 104 | 105 | ||
| 105 | // Init network stack | 106 | // Init network stack |
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index a43a55909..db251eafe 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml | |||
| @@ -23,3 +23,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa | |||
| 23 | heapless = { version = "0.7.5", default-features = false } | 23 | heapless = { version = "0.7.5", default-features = false } |
| 24 | 24 | ||
| 25 | micromath = "2.0.0" | 25 | micromath = "2.0.0" |
| 26 | |||
| 27 | [profile.release] | ||
| 28 | debug = 2 | ||
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 48e340264..1a5aff352 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -52,3 +52,6 @@ required-features = ["ble"] | |||
| 52 | [[bin]] | 52 | [[bin]] |
| 53 | name = "gatt_server" | 53 | name = "gatt_server" |
| 54 | required-features = ["ble"] | 54 | required-features = ["ble"] |
| 55 | |||
| 56 | [profile.release] | ||
| 57 | debug = 2 | ||
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs index 451bd7d29..ea150c67e 100644 --- a/examples/stm32wb/src/bin/eddystone_beacon.rs +++ b/examples/stm32wb/src/bin/eddystone_beacon.rs | |||
| @@ -8,6 +8,7 @@ use defmt::*; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::bind_interrupts; | 9 | use embassy_stm32::bind_interrupts; |
| 10 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 10 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 11 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 11 | use embassy_stm32_wpan::hci::host::uart::UartHci; | 12 | use embassy_stm32_wpan::hci::host::uart::UartHci; |
| 12 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; | 13 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; |
| 13 | use embassy_stm32_wpan::hci::types::AdvertisingType; | 14 | use embassy_stm32_wpan::hci::types::AdvertisingType; |
| @@ -54,7 +55,9 @@ async fn main(_spawner: Spawner) { | |||
| 54 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 55 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 55 | */ | 56 | */ |
| 56 | 57 | ||
| 57 | let p = embassy_stm32::init(Default::default()); | 58 | let mut config = embassy_stm32::Config::default(); |
| 59 | config.rcc = WPAN_DEFAULT; | ||
| 60 | let p = embassy_stm32::init(config); | ||
| 58 | info!("Hello World!"); | 61 | info!("Hello World!"); |
| 59 | 62 | ||
| 60 | let config = Config::default(); | 63 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/gatt_server.rs b/examples/stm32wb/src/bin/gatt_server.rs index 0f6419d45..dd67249c7 100644 --- a/examples/stm32wb/src/bin/gatt_server.rs +++ b/examples/stm32wb/src/bin/gatt_server.rs | |||
| @@ -8,6 +8,7 @@ use defmt::*; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::bind_interrupts; | 9 | use embassy_stm32::bind_interrupts; |
| 10 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 10 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 11 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 11 | use embassy_stm32_wpan::hci::event::command::{CommandComplete, ReturnParameters}; | 12 | use embassy_stm32_wpan::hci::event::command::{CommandComplete, ReturnParameters}; |
| 12 | use embassy_stm32_wpan::hci::host::uart::{Packet, UartHci}; | 13 | use embassy_stm32_wpan::hci::host::uart::{Packet, UartHci}; |
| 13 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; | 14 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; |
| @@ -62,7 +63,9 @@ async fn main(_spawner: Spawner) { | |||
| 62 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 63 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 63 | */ | 64 | */ |
| 64 | 65 | ||
| 65 | let p = embassy_stm32::init(Default::default()); | 66 | let mut config = embassy_stm32::Config::default(); |
| 67 | config.rcc = WPAN_DEFAULT; | ||
| 68 | let p = embassy_stm32::init(config); | ||
| 66 | info!("Hello World!"); | 69 | info!("Hello World!"); |
| 67 | 70 | ||
| 68 | let config = Config::default(); | 71 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index 1379ac6ba..881dc488d 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::mac::commands::{AssociateResponse, ResetRequest, SetRequest, StartRequest}; | 10 | use embassy_stm32_wpan::mac::commands::{AssociateResponse, ResetRequest, SetRequest, StartRequest}; |
| 10 | use embassy_stm32_wpan::mac::event::MacEvent; | 11 | use embassy_stm32_wpan::mac::event::MacEvent; |
| 11 | use embassy_stm32_wpan::mac::typedefs::{MacChannel, MacStatus, PanId, PibId, SecurityLevel}; | 12 | use embassy_stm32_wpan::mac::typedefs::{MacChannel, MacStatus, PanId, PibId, SecurityLevel}; |
| @@ -30,7 +31,7 @@ async fn main(spawner: Spawner) { | |||
| 30 | 31 | ||
| 31 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. | 32 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. |
| 32 | - Download and Install STM32CubeProgrammer. | 33 | - Download and Install STM32CubeProgrammer. |
| 33 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from | 34 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_fw.bin, and Release_Notes.html from |
| 34 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x | 35 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x |
| 35 | - Open STM32CubeProgrammer | 36 | - Open STM32CubeProgrammer |
| 36 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. | 37 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. |
| @@ -39,7 +40,7 @@ async fn main(spawner: Spawner) { | |||
| 39 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file | 40 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file |
| 40 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 41 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 41 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the | 42 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the |
| 42 | stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. | 43 | stm32wb5x_BLE_Mac_802_15_4_fw.bin file. It should not be the same memory address. |
| 43 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 44 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 44 | - Select "Start Wireless Stack". | 45 | - Select "Start Wireless Stack". |
| 45 | - Disconnect from the device. | 46 | - Disconnect from the device. |
| @@ -49,7 +50,9 @@ async fn main(spawner: Spawner) { | |||
| 49 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 50 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 50 | */ | 51 | */ |
| 51 | 52 | ||
| 52 | let p = embassy_stm32::init(Default::default()); | 53 | let mut config = embassy_stm32::Config::default(); |
| 54 | config.rcc = WPAN_DEFAULT; | ||
| 55 | let p = embassy_stm32::init(config); | ||
| 53 | info!("Hello World!"); | 56 | info!("Hello World!"); |
| 54 | 57 | ||
| 55 | let config = Config::default(); | 58 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs index bbcd0a70f..f8c76b5a4 100644 --- a/examples/stm32wb/src/bin/mac_ffd_net.rs +++ b/examples/stm32wb/src/bin/mac_ffd_net.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::mac::commands::{ResetRequest, SetRequest, StartRequest}; | 10 | use embassy_stm32_wpan::mac::commands::{ResetRequest, SetRequest, StartRequest}; |
| 10 | use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId}; | 11 | use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId}; |
| 11 | use embassy_stm32_wpan::mac::{self, Runner}; | 12 | use embassy_stm32_wpan::mac::{self, Runner}; |
| @@ -36,7 +37,7 @@ async fn main(spawner: Spawner) { | |||
| 36 | 37 | ||
| 37 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. | 38 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. |
| 38 | - Download and Install STM32CubeProgrammer. | 39 | - Download and Install STM32CubeProgrammer. |
| 39 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from | 40 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_fw.bin, and Release_Notes.html from |
| 40 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x | 41 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x |
| 41 | - Open STM32CubeProgrammer | 42 | - Open STM32CubeProgrammer |
| 42 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. | 43 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. |
| @@ -45,7 +46,7 @@ async fn main(spawner: Spawner) { | |||
| 45 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file | 46 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file |
| 46 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 47 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 47 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the | 48 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the |
| 48 | stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. | 49 | stm32wb5x_BLE_Mac_802_15_4_fw.bin file. It should not be the same memory address. |
| 49 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 50 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 50 | - Select "Start Wireless Stack". | 51 | - Select "Start Wireless Stack". |
| 51 | - Disconnect from the device. | 52 | - Disconnect from the device. |
| @@ -55,7 +56,9 @@ async fn main(spawner: Spawner) { | |||
| 55 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 56 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 56 | */ | 57 | */ |
| 57 | 58 | ||
| 58 | let p = embassy_stm32::init(Default::default()); | 59 | let mut config = embassy_stm32::Config::default(); |
| 60 | config.rcc = WPAN_DEFAULT; | ||
| 61 | let p = embassy_stm32::init(config); | ||
| 59 | info!("Hello World!"); | 62 | info!("Hello World!"); |
| 60 | 63 | ||
| 61 | let config = Config::default(); | 64 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs index 4d8b6601a..000355de6 100644 --- a/examples/stm32wb/src/bin/mac_rfd.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, DataRequest, GetRequest, ResetRequest, SetRequest}; | 10 | use embassy_stm32_wpan::mac::commands::{AssociateRequest, DataRequest, GetRequest, ResetRequest, SetRequest}; |
| 10 | use embassy_stm32_wpan::mac::event::MacEvent; | 11 | use embassy_stm32_wpan::mac::event::MacEvent; |
| 11 | use embassy_stm32_wpan::mac::typedefs::{ | 12 | use embassy_stm32_wpan::mac::typedefs::{ |
| @@ -32,7 +33,7 @@ async fn main(spawner: Spawner) { | |||
| 32 | 33 | ||
| 33 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. | 34 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. |
| 34 | - Download and Install STM32CubeProgrammer. | 35 | - Download and Install STM32CubeProgrammer. |
| 35 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from | 36 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_fw.bin, and Release_Notes.html from |
| 36 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x | 37 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x |
| 37 | - Open STM32CubeProgrammer | 38 | - Open STM32CubeProgrammer |
| 38 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. | 39 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. |
| @@ -41,7 +42,7 @@ async fn main(spawner: Spawner) { | |||
| 41 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file | 42 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file |
| 42 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 43 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 43 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the | 44 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the |
| 44 | stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. | 45 | stm32wb5x_BLE_Mac_802_15_4_fw.bin file. It should not be the same memory address. |
| 45 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 46 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 46 | - Select "Start Wireless Stack". | 47 | - Select "Start Wireless Stack". |
| 47 | - Disconnect from the device. | 48 | - Disconnect from the device. |
| @@ -51,7 +52,9 @@ async fn main(spawner: Spawner) { | |||
| 51 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 52 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 52 | */ | 53 | */ |
| 53 | 54 | ||
| 54 | let p = embassy_stm32::init(Default::default()); | 55 | let mut config = embassy_stm32::Config::default(); |
| 56 | config.rcc = WPAN_DEFAULT; | ||
| 57 | let p = embassy_stm32::init(config); | ||
| 55 | info!("Hello World!"); | 58 | info!("Hello World!"); |
| 56 | 59 | ||
| 57 | let config = Config::default(); | 60 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 9fc4b8aac..fc49c3c4a 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::TlMbox; | 10 | use embassy_stm32_wpan::TlMbox; |
| 10 | use embassy_time::{Duration, Timer}; | 11 | use embassy_time::{Duration, Timer}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -41,7 +42,9 @@ async fn main(_spawner: Spawner) { | |||
| 41 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 42 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 42 | */ | 43 | */ |
| 43 | 44 | ||
| 44 | let p = embassy_stm32::init(Default::default()); | 45 | let mut config = embassy_stm32::Config::default(); |
| 46 | config.rcc = WPAN_DEFAULT; | ||
| 47 | let p = embassy_stm32::init(config); | ||
| 45 | info!("Hello World!"); | 48 | info!("Hello World!"); |
| 46 | 49 | ||
| 47 | let config = Config::default(); | 50 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs index 90349422e..5745ebd02 100644 --- a/examples/stm32wb/src/bin/tl_mbox_ble.rs +++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::TlMbox; | 10 | use embassy_stm32_wpan::TlMbox; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 12 | ||
| @@ -40,7 +41,9 @@ async fn main(_spawner: Spawner) { | |||
| 40 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 41 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 41 | */ | 42 | */ |
| 42 | 43 | ||
| 43 | let p = embassy_stm32::init(Default::default()); | 44 | let mut config = embassy_stm32::Config::default(); |
| 45 | config.rcc = WPAN_DEFAULT; | ||
| 46 | let p = embassy_stm32::init(config); | ||
| 44 | info!("Hello World!"); | 47 | info!("Hello World!"); |
| 45 | 48 | ||
| 46 | let config = Config::default(); | 49 | let config = Config::default(); |
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs index 5931c392b..f32e07d96 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac.rs +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs | |||
| @@ -6,6 +6,7 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::bind_interrupts; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | 8 | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; |
| 9 | use embassy_stm32::rcc::WPAN_DEFAULT; | ||
| 9 | use embassy_stm32_wpan::sub::mm; | 10 | use embassy_stm32_wpan::sub::mm; |
| 10 | use embassy_stm32_wpan::TlMbox; | 11 | use embassy_stm32_wpan::TlMbox; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -27,7 +28,7 @@ async fn main(spawner: Spawner) { | |||
| 27 | 28 | ||
| 28 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. | 29 | - Obtain a NUCLEO-STM32WB55 from your preferred supplier. |
| 29 | - Download and Install STM32CubeProgrammer. | 30 | - Download and Install STM32CubeProgrammer. |
| 30 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from | 31 | - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Mac_802_15_4_fw.bin, and Release_Notes.html from |
| 31 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x | 32 | gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x |
| 32 | - Open STM32CubeProgrammer | 33 | - Open STM32CubeProgrammer |
| 33 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. | 34 | - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. |
| @@ -36,7 +37,7 @@ async fn main(spawner: Spawner) { | |||
| 36 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file | 37 | - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file |
| 37 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 38 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 38 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the | 39 | - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the |
| 39 | stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. | 40 | stm32wb5x_BLE_Mac_802_15_4_fw.bin file. It should not be the same memory address. |
| 40 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". | 41 | - Select that file, the memory address, "verify download", and then "Firmware Upgrade". |
| 41 | - Select "Start Wireless Stack". | 42 | - Select "Start Wireless Stack". |
| 42 | - Disconnect from the device. | 43 | - Disconnect from the device. |
| @@ -46,7 +47,9 @@ async fn main(spawner: Spawner) { | |||
| 46 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 47 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 47 | */ | 48 | */ |
| 48 | 49 | ||
| 49 | let p = embassy_stm32::init(Default::default()); | 50 | let mut config = embassy_stm32::Config::default(); |
| 51 | config.rcc = WPAN_DEFAULT; | ||
| 52 | let p = embassy_stm32::init(config); | ||
| 50 | info!("Hello World!"); | 53 | info!("Hello World!"); |
| 51 | 54 | ||
| 52 | let config = Config::default(); | 55 | let config = Config::default(); |
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 6e6f269aa..48b69c8d0 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml | |||
| @@ -28,5 +28,5 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa | |||
| 28 | heapless = { version = "0.7.5", default-features = false } | 28 | heapless = { version = "0.7.5", default-features = false } |
| 29 | chrono = { version = "^0.4", default-features = false } | 29 | chrono = { version = "^0.4", default-features = false } |
| 30 | 30 | ||
| 31 | [patch.crates-io] | 31 | [profile.release] |
| 32 | lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" } | 32 | debug = 2 |
diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 805d21418..2c9c98861 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs | |||
| @@ -10,9 +10,9 @@ use embassy_executor::Spawner; | |||
| 10 | use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; | 10 | use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; |
| 11 | use embassy_lora::LoraTimer; | 11 | use embassy_lora::LoraTimer; |
| 12 | use embassy_stm32::gpio::{Level, Output, Pin, Speed}; | 12 | use embassy_stm32::gpio::{Level, Output, Pin, Speed}; |
| 13 | use embassy_stm32::rng::Rng; | 13 | use embassy_stm32::rng::{self, Rng}; |
| 14 | use embassy_stm32::spi::Spi; | 14 | use embassy_stm32::spi::Spi; |
| 15 | use embassy_stm32::{bind_interrupts, pac}; | 15 | use embassy_stm32::{bind_interrupts, pac, peripherals}; |
| 16 | use embassy_time::Delay; | 16 | use embassy_time::Delay; |
| 17 | use lora_phy::mod_params::*; | 17 | use lora_phy::mod_params::*; |
| 18 | use lora_phy::sx1261_2::SX1261_2; | 18 | use lora_phy::sx1261_2::SX1261_2; |
| @@ -26,6 +26,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th | |||
| 26 | 26 | ||
| 27 | bind_interrupts!(struct Irqs{ | 27 | bind_interrupts!(struct Irqs{ |
| 28 | SUBGHZ_RADIO => InterruptHandler; | 28 | SUBGHZ_RADIO => InterruptHandler; |
| 29 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 29 | }); | 30 | }); |
| 30 | 31 | ||
| 31 | #[embassy_executor::main] | 32 | #[embassy_executor::main] |
| @@ -58,7 +59,7 @@ async fn main(_spawner: Spawner) { | |||
| 58 | }; | 59 | }; |
| 59 | let radio = LoRaRadio::new(lora); | 60 | let radio = LoRaRadio::new(lora); |
| 60 | let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); | 61 | let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); |
| 61 | let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG)); | 62 | let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs)); |
| 62 | 63 | ||
| 63 | defmt::info!("Joining LoRaWAN network"); | 64 | defmt::info!("Joining LoRaWAN network"); |
| 64 | 65 | ||
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index d8562fca5..592e65f40 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs | |||
| @@ -4,10 +4,14 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::pac; | 7 | use embassy_stm32::rng::{self, Rng}; |
| 8 | use embassy_stm32::rng::Rng; | 8 | use embassy_stm32::{bind_interrupts, pac, peripherals}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | bind_interrupts!(struct Irqs{ | ||
| 12 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 13 | }); | ||
| 14 | |||
| 11 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 13 | let mut config = embassy_stm32::Config::default(); | 17 | let mut config = embassy_stm32::Config::default(); |
| @@ -21,7 +25,7 @@ async fn main(_spawner: Spawner) { | |||
| 21 | 25 | ||
| 22 | info!("Hello World!"); | 26 | info!("Hello World!"); |
| 23 | 27 | ||
| 24 | let mut rng = Rng::new(p.RNG); | 28 | let mut rng = Rng::new(p.RNG, Irqs); |
| 25 | 29 | ||
| 26 | let mut buf = [0u8; 16]; | 30 | let mut buf = [0u8; 16]; |
| 27 | unwrap!(rng.async_fill_bytes(&mut buf).await); | 31 | unwrap!(rng.async_fill_bytes(&mut buf).await); |
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" | |||
| 17 | web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } | 17 | web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] } |
| 18 | log = "0.4.11" | 18 | log = "0.4.11" |
| 19 | critical-section = { version = "1.1", features = ["std"] } | 19 | critical-section = { version = "1.1", features = ["std"] } |
| 20 | |||
| 21 | [profile.release] | ||
| 22 | debug = 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"; | |||
| 118 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | 118 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; |
| 119 | 119 | ||
| 120 | const TEST_DURATION: usize = 10; | 120 | const TEST_DURATION: usize = 10; |
| 121 | const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 150; | 121 | const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 50; |
| 122 | const TEST_EXPECTED_UPLOAD_KBPS: usize = 150; | 122 | const TEST_EXPECTED_UPLOAD_KBPS: usize = 50; |
| 123 | const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 150; | 123 | const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 50; |
| 124 | const RX_BUFFER_SIZE: usize = 4096; | 124 | const RX_BUFFER_SIZE: usize = 4096; |
| 125 | const TX_BUFFER_SIZE: usize = 4096; | 125 | const TX_BUFFER_SIZE: usize = 4096; |
| 126 | const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); | 126 | const 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/flash.rs b/tests/rp/src/bin/flash.rs index cf9b86df5..c31d6decf 100644 --- a/tests/rp/src/bin/flash.rs +++ b/tests/rp/src/bin/flash.rs | |||
| @@ -6,11 +6,11 @@ mod common; | |||
| 6 | 6 | ||
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE}; | 9 | use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; |
| 10 | use embassy_time::{Duration, Timer}; | 10 | use embassy_time::{Duration, Timer}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 12 | ||
| 13 | const ADDR_OFFSET: u32 = 0x4000; | 13 | const ADDR_OFFSET: u32 = 0x8000; |
| 14 | 14 | ||
| 15 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 16 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | // https://github.com/knurling-rs/defmt/pull/683 | 23 | // https://github.com/knurling-rs/defmt/pull/683 |
| 24 | Timer::after(Duration::from_millis(10)).await; | 24 | Timer::after(Duration::from_millis(10)).await; |
| 25 | 25 | ||
| 26 | let mut flash = embassy_rp::flash::Flash::<_, { 2 * 1024 * 1024 }>::new(p.FLASH); | 26 | let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); |
| 27 | 27 | ||
| 28 | // Get JEDEC id | 28 | // Get JEDEC id |
| 29 | let jedec = defmt::unwrap!(flash.jedec_id()); | 29 | let jedec = defmt::unwrap!(flash.jedec_id()); |
| @@ -60,6 +60,14 @@ async fn main(_spawner: Spawner) { | |||
| 60 | defmt::panic!("unexpected"); | 60 | defmt::panic!("unexpected"); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | let mut buf = [0u32; ERASE_SIZE / 4]; | ||
| 64 | |||
| 65 | defmt::unwrap!(flash.background_read(ADDR_OFFSET, &mut buf)).await; | ||
| 66 | info!("Contents after write starts with {=u32:x}", buf[0]); | ||
| 67 | if buf.iter().any(|x| *x != 0xDADADADA) { | ||
| 68 | defmt::panic!("unexpected"); | ||
| 69 | } | ||
| 70 | |||
| 63 | info!("Test OK"); | 71 | info!("Test OK"); |
| 64 | cortex_m::asm::bkpt(); | 72 | cortex_m::asm::bkpt(); |
| 65 | } | 73 | } |
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; | |||
| 9 | use embassy_rp::bind_interrupts; | 9 | use embassy_rp::bind_interrupts; |
| 10 | use embassy_rp::peripherals::PIO0; | 10 | use embassy_rp::peripherals::PIO0; |
| 11 | use embassy_rp::pio::{Config, InterruptHandler, Pio}; | 11 | use embassy_rp::pio::{Config, InterruptHandler, Pio}; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 13 | ||
| 15 | bind_interrupts!(struct Irqs { | 14 | bind_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"] | ||
| 5 | mod common; | ||
| 6 | |||
| 7 | use defmt::info; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_rp::bind_interrupts; | ||
| 10 | use embassy_rp::peripherals::PIO0; | ||
| 11 | use embassy_rp::pio::{Config, InterruptHandler, LoadError, Pio}; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | bind_interrupts!(struct Irqs { | ||
| 15 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 16 | }); | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async 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] |
| 9 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill | 9 | stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill |
| 10 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma"] # Nucleo "sdmmc" | 10 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" |
| 11 | stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo | 11 | stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo |
| 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo | 12 | stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo |
| 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo | 13 | stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo |
| 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo | 14 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "dac-adc-pin"] # Nucleo |
| 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo | 15 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo |
| 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo | 16 | stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo |
| 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board | 17 | stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board |
| @@ -23,6 +23,7 @@ ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] | |||
| 23 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | 23 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] |
| 24 | embassy-stm32-wpan = [] | 24 | embassy-stm32-wpan = [] |
| 25 | not-gpdma = [] | 25 | not-gpdma = [] |
| 26 | dac-adc-pin = [] | ||
| 26 | 27 | ||
| 27 | [dependencies] | 28 | [dependencies] |
| 28 | teleprobe-meta = "1" | 29 | teleprobe-meta = "1" |
| @@ -42,6 +43,7 @@ cortex-m-rt = "0.7.0" | |||
| 42 | embedded-hal = "0.2.6" | 43 | embedded-hal = "0.2.6" |
| 43 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } | 44 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } |
| 44 | embedded-hal-async = { version = "=0.2.0-alpha.2" } | 45 | embedded-hal-async = { version = "=0.2.0-alpha.2" } |
| 46 | micromath = "2.0.0" | ||
| 45 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 47 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 46 | rand_core = { version = "0.6", default-features = false } | 48 | rand_core = { version = "0.6", default-features = false } |
| 47 | rand_chacha = { version = "0.3", default-features = false } | 49 | rand_chacha = { version = "0.3", default-features = false } |
| @@ -56,6 +58,11 @@ path = "src/bin/can.rs" | |||
| 56 | required-features = [ "can",] | 58 | required-features = [ "can",] |
| 57 | 59 | ||
| 58 | [[bin]] | 60 | [[bin]] |
| 61 | name = "dac" | ||
| 62 | path = "src/bin/dac.rs" | ||
| 63 | required-features = [ "dac-adc-pin",] | ||
| 64 | |||
| 65 | [[bin]] | ||
| 59 | name = "gpio" | 66 | name = "gpio" |
| 60 | path = "src/bin/gpio.rs" | 67 | path = "src/bin/gpio.rs" |
| 61 | required-features = [] | 68 | required-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"] | ||
| 8 | mod common; | ||
| 9 | use common::*; | ||
| 10 | use defmt::assert; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::adc::Adc; | ||
| 13 | use embassy_stm32::dac::{DacCh1, DacChannel, Value}; | ||
| 14 | use embassy_stm32::dma::NoDma; | ||
| 15 | use embassy_time::{Delay, Duration, Timer}; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | #[embassy_executor::main] | ||
| 19 | async 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 | |||
| 67 | use core::f32::consts::PI; | ||
| 68 | |||
| 69 | use micromath::F32Ext; | ||
| 70 | |||
| 71 | fn 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/spi.rs b/tests/stm32/src/bin/spi.rs index 819ecae3c..e51dd5bf2 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs | |||
| @@ -35,15 +35,14 @@ async fn main(_spawner: Spawner) { | |||
| 35 | #[cfg(feature = "stm32c031c6")] | 35 | #[cfg(feature = "stm32c031c6")] |
| 36 | let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6); | 36 | let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6); |
| 37 | 37 | ||
| 38 | let mut spi_config = spi::Config::default(); | ||
| 39 | spi_config.frequency = Hertz(1_000_000); | ||
| 40 | |||
| 38 | let mut spi = Spi::new( | 41 | let mut spi = Spi::new( |
| 39 | spi, | 42 | spi, sck, // Arduino D13 |
| 40 | sck, // Arduino D13 | ||
| 41 | mosi, // Arduino D11 | 43 | mosi, // Arduino D11 |
| 42 | miso, // Arduino D12 | 44 | miso, // Arduino D12 |
| 43 | NoDma, | 45 | NoDma, NoDma, spi_config, |
| 44 | NoDma, | ||
| 45 | Hertz(1_000_000), | ||
| 46 | spi::Config::default(), | ||
| 47 | ); | 46 | ); |
| 48 | 47 | ||
| 49 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 48 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; |
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index 78aad24e1..d45cbe45b 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs | |||
| @@ -34,15 +34,14 @@ async fn main(_spawner: Spawner) { | |||
| 34 | #[cfg(feature = "stm32c031c6")] | 34 | #[cfg(feature = "stm32c031c6")] |
| 35 | let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2); | 35 | let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2); |
| 36 | 36 | ||
| 37 | let mut spi_config = spi::Config::default(); | ||
| 38 | spi_config.frequency = Hertz(1_000_000); | ||
| 39 | |||
| 37 | let mut spi = Spi::new( | 40 | let mut spi = Spi::new( |
| 38 | spi, | 41 | spi, sck, // Arduino D13 |
| 39 | sck, // Arduino D13 | ||
| 40 | mosi, // Arduino D11 | 42 | mosi, // Arduino D11 |
| 41 | miso, // Arduino D12 | 43 | miso, // Arduino D12 |
| 42 | tx_dma, | 44 | tx_dma, rx_dma, spi_config, |
| 43 | rx_dma, | ||
| 44 | Hertz(1_000_000), | ||
| 45 | spi::Config::default(), | ||
| 46 | ); | 45 | ); |
| 47 | 46 | ||
| 48 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; | 47 | let data: [u8; 9] = [0x00, 0xFF, 0xAA, 0x55, 0xC0, 0xFF, 0xEE, 0xC0, 0xDE]; |
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")] |
