diff --git a/README.md b/README.md index c4c01dfb..e5a97062 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,9 @@ async fn blink(pin: AnyPin) { loop { // Timekeeping is globally available, no need to mess with hardware timers. led.set_high(); - Timer::after(Duration::from_millis(150)).await; + Timer::after_millis(150).await; led.set_low(); - Timer::after(Duration::from_millis(150)).await; + Timer::after_millis(150).await; } } diff --git a/ci.sh b/ci.sh index c246e6a9..eac4d371 100755 --- a/ci.sh +++ b/ci.sh @@ -192,9 +192,13 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32g071rb --out-dir out/tests/stm32g071rb \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32c031c6 --out-dir out/tests/stm32c031c6 \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi --out-dir out/tests/stm32h755zi \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi --out-dir out/tests/stm32h753zi \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7a3zi --out-dir out/tests/stm32h7a3zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u5a5zj --out-dir out/tests/stm32u5a5zj \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wba52cg --out-dir out/tests/stm32wba52cg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l073rz --out-dir out/tests/stm32l073rz \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l152re --out-dir out/tests/stm32l152re \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \ @@ -204,6 +208,7 @@ cargo batch \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f207zg --out-dir out/tests/stm32f207zg \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \ + --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55jc --out-dir out/tests/stm32wl55jc \ --- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \ --- build --release --manifest-path tests/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \ --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ @@ -212,8 +217,13 @@ cargo batch \ rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble + +# unstable, I think it's running out of RAM? rm out/tests/stm32f207zg/eth +# doesn't work, gives "noise error", no idea why. usart_dma does pass. +rm out/tests/stm32u5a5zj/usart + if [[ -z "${TELEPROBE_TOKEN-}" ]]; then echo No teleprobe token found, skipping running HIL tests exit diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index d7bba6b6..b19cabfe 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -11,10 +11,10 @@ log = ["dep:log"] firmware-logs = [] [dependencies] -embassy-time = { version = "0.1.4", path = "../embassy-time"} +embassy-time = { version = "0.1.5", path = "../embassy-time"} embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} defmt = { version = "0.3", optional = true } log = { version = "0.4.17", optional = true } diff --git a/cyw43/src/bus.rs b/cyw43/src/bus.rs index 0b5632cf..01410903 100644 --- a/cyw43/src/bus.rs +++ b/cyw43/src/bus.rs @@ -1,5 +1,5 @@ use embassy_futures::yield_now; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::digital::OutputPin; use futures::FutureExt; @@ -51,9 +51,9 @@ where pub async fn init(&mut self) { // Reset self.pwr.set_low().unwrap(); - Timer::after(Duration::from_millis(20)).await; + Timer::after_millis(20).await; self.pwr.set_high().unwrap(); - Timer::after(Duration::from_millis(250)).await; + Timer::after_millis(250).await; while self .read32_swapped(REG_BUS_TEST_RO) diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index a6d1f0bf..d2709304 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs @@ -1,8 +1,8 @@ use core::cmp::{max, min}; -use ch::driver::LinkState; use embassy_net_driver_channel as ch; -use embassy_time::{Duration, Timer}; +use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; +use embassy_time::Timer; pub use crate::bus::SpiBusCyw43; use crate::consts::*; @@ -87,22 +87,22 @@ impl<'a> Control<'a> { self.set_iovar("country", &country_info.to_bytes()).await; // set country takes some time, next ioctls fail if we don't wait. - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // Set antenna to chip antenna self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await; self.set_iovar_u32("bus:txglom", 0).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; //self.set_iovar_u32("apsta", 1).await; // this crashes, also we already did it before...?? - //Timer::after(Duration::from_millis(100)).await; + //Timer::after_millis(100).await; self.set_iovar_u32("ampdu_ba_wsize", 8).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.set_iovar_u32("ampdu_mpdu", 4).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; //self.set_iovar_u32("ampdu_rx_factor", 0).await; // this crashes - //Timer::after(Duration::from_millis(100)).await; + //Timer::after_millis(100).await; // evts let mut evts = EventMask { @@ -121,19 +121,19 @@ impl<'a> Control<'a> { self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // set wifi up self.up().await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; - self.state_ch.set_ethernet_address(mac_addr); + self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr)); debug!("INIT DONE"); } @@ -185,7 +185,7 @@ impl<'a> Control<'a> { self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await; self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let mut pfi = PassphraseInfo { len: passphrase.len() as _, @@ -297,7 +297,7 @@ impl<'a> Control<'a> { if security != Security::OPEN { self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; // Set passphrase let mut pfi = PassphraseInfo { diff --git a/cyw43/src/runner.rs b/cyw43/src/runner.rs index 1c187faa..83aee6b4 100644 --- a/cyw43/src/runner.rs +++ b/cyw43/src/runner.rs @@ -555,14 +555,14 @@ where self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await; - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; self.bus .bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN) .await; let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await; - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } async fn core_is_up(&mut self, core: Core) -> bool { diff --git a/docs/modules/ROOT/pages/basic_application.adoc b/docs/modules/ROOT/pages/basic_application.adoc index 3f4f16e2..73774c71 100644 --- a/docs/modules/ROOT/pages/basic_application.adoc +++ b/docs/modules/ROOT/pages/basic_application.adoc @@ -48,7 +48,7 @@ The `Spawner` is the way the main application spawns other tasks. The `Periphera include::example$basic/src/main.rs[lines="22..-1"] ---- -What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy::main]` macro. The macro does the following: +What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy_executor::main]` macro. The macro does the following: . Creates an Embassy Executor . Initializes the microcontroller HAL to get the `Peripherals` diff --git a/docs/modules/ROOT/pages/runtime.adoc b/docs/modules/ROOT/pages/runtime.adoc index cb8afef2..8f4921f6 100644 --- a/docs/modules/ROOT/pages/runtime.adoc +++ b/docs/modules/ROOT/pages/runtime.adoc @@ -6,7 +6,7 @@ The Embassy executor is an async/await executor designed for embedded usage alon * No `alloc`, no heap needed. Task are statically allocated. * No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. -* Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`. +* Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. * No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. * Efficient polling: a wake will only poll the woken task, not all of them. * Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index 040e2356..55ef734e 100644 --- a/embassy-embedded-hal/Cargo.toml +++ b/embassy-embedded-hal/Cargo.toml @@ -21,7 +21,7 @@ default = ["time"] [dependencies] embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ "unproven", ] } diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index b2a9f1e3..5d3cf658 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -76,9 +76,7 @@ where #[cfg(not(feature = "time"))] Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => { - embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await - } + Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, } } }; @@ -143,9 +141,7 @@ where #[cfg(not(feature = "time"))] Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), #[cfg(feature = "time")] - Operation::DelayUs(us) => { - embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await - } + Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await, } } }; diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 4869bf3e..a793a198 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -59,7 +59,7 @@ rtos-trace = { version = "0.1.2", optional = true } futures-util = { version = "0.3.17", default-features = false } embassy-macros = { version = "0.2.1", path = "../embassy-macros" } -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true} +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true} atomic-polyfill = "1.0.1" critical-section = "1.1" static_cell = "1.1" diff --git a/embassy-executor/README.md b/embassy-executor/README.md index 47d0cb8a..3c1448a1 100644 --- a/embassy-executor/README.md +++ b/embassy-executor/README.md @@ -4,7 +4,7 @@ An async/await executor designed for embedded usage. - No `alloc`, no heap needed. Task futures are statically allocated. - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. -- Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`. +- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. - No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. - Efficient polling: a wake will only poll the woken task, not all of them. - Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs index 400b37fa..522853e3 100644 --- a/embassy-executor/src/raw/waker.rs +++ b/embassy-executor/src/raw/waker.rs @@ -3,7 +3,7 @@ use core::task::{RawWaker, RawWakerVTable, Waker}; use super::{wake_task, TaskHeader, TaskRef}; -const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); +static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); unsafe fn clone(p: *const ()) -> RawWaker { RawWaker::new(p, &VTABLE) diff --git a/embassy-lora/Cargo.toml b/embassy-lora/Cargo.toml index 6cdacd9c..846c3919 100644 --- a/embassy-lora/Cargo.toml +++ b/embassy-lora/Cargo.toml @@ -20,7 +20,7 @@ defmt = ["dep:defmt", "lorawan-device/defmt"] defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true } embedded-hal-async = { version = "=1.0.0-rc.1" } diff --git a/embassy-lora/src/lib.rs b/embassy-lora/src/lib.rs index 0a9cea16..5637802b 100644 --- a/embassy-lora/src/lib.rs +++ b/embassy-lora/src/lib.rs @@ -34,6 +34,6 @@ impl lorawan_device::async_device::radio::Timer for LoraTimer { } async fn delay_ms(&mut self, millis: u64) { - Timer::after(Duration::from_millis(millis)).await + Timer::after_millis(millis).await } } diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index b93716d0..a781f3bd 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -16,8 +16,8 @@ log = { version = "0.4", default-features = false, optional = true } embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } -embassy-time = { version = "0.1.4", path = "../embassy-time" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } +embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } bitfield = "0.14.0" diff --git a/embassy-net-adin1110/src/lib.rs b/embassy-net-adin1110/src/lib.rs index 53f36128..edee3438 100644 --- a/embassy-net-adin1110/src/lib.rs +++ b/embassy-net-adin1110/src/lib.rs @@ -20,7 +20,7 @@ pub use crc32::ETH_FCS; use crc8::crc8; use embassy_futures::select::{select, Either}; use embassy_net_driver_channel as ch; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::{Error, Operation, SpiDevice}; @@ -609,12 +609,12 @@ pub async fn new { // a packet is ready to be received! let buf = rx_chan.rx_buf().await; // allocate a rx buf from the packet queue - let n = receive_packet_over_spi(buf).await; + let n = receive_packet_over_spi(buf).await; rx_chan.rx_done(n); } Either::Second(buf) => { // a packet is ready to be sent! - send_packet_over_spi(buf).await; + send_packet_over_spi(buf).await; tx_chan.tx_done(); } } @@ -41,7 +43,7 @@ However, this code has a latent deadlock bug. The symptom is it can hang at `rx_ The reason is that, under load, both the TX and RX queues can get full at the same time. When this happens, the `embassy-net` task stalls trying to send because the TX queue is full, therefore it stops processing packets in the RX queue. Your driver task also stalls because the RX queue is full, therefore it stops processing packets in the TX queue. -The fix is to make sure to always service the TX queue while you're waiting for space to become available in the TX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available": +The fix is to make sure to always service the TX queue while you're waiting for space to become available in the RX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available": ```rust,ignore loop { @@ -58,12 +60,12 @@ loop { ).await { Either::First(buf) => { // a packet is ready to be received! - let n = receive_packet_over_spi(buf).await; + let n = receive_packet_over_spi(buf).await; rx_chan.rx_done(n); } Either::Second(buf) => { // a packet is ready to be sent! - send_packet_over_spi(buf).await; + send_packet_over_spi(buf).await; tx_chan.tx_done(); } } @@ -79,12 +81,10 @@ These `embassy-net` drivers are implemented using this crate. You can look at th - [`embassy-net-wiznet`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-wiznet) for Wiznet SPI Ethernet MAC+PHY chips. - [`embassy-net-esp-hosted`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-esp-hosted) for using ESP32 chips with the [`esp-hosted`](https://github.com/espressif/esp-hosted) firmware as WiFi adapters for another non-ESP32 MCU. - ## Interoperability This crate can run on any executor. - ## License This work is licensed under either of diff --git a/embassy-net-driver-channel/src/lib.rs b/embassy-net-driver-channel/src/lib.rs index bf7ae521..bfb2c9c0 100644 --- a/embassy-net-driver-channel/src/lib.rs +++ b/embassy-net-driver-channel/src/lib.rs @@ -8,9 +8,8 @@ use core::cell::RefCell; use core::mem::MaybeUninit; use core::task::{Context, Poll}; -use driver::HardwareAddress; pub use embassy_net_driver as driver; -use embassy_net_driver::{Capabilities, LinkState, Medium}; +use embassy_net_driver::{Capabilities, LinkState}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::blocking_mutex::Mutex; use embassy_sync::waitqueue::WakerRegistration; @@ -161,18 +160,10 @@ impl<'d> StateRunner<'d> { }); } - pub fn set_ethernet_address(&self, address: [u8; 6]) { + pub fn set_hardware_address(&self, address: driver::HardwareAddress) { self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.hardware_address = driver::HardwareAddress::Ethernet(address); - s.waker.wake(); - }); - } - - pub fn set_ieee802154_address(&self, address: [u8; 8]) { - self.shared.lock(|s| { - let s = &mut *s.borrow_mut(); - s.hardware_address = driver::HardwareAddress::Ieee802154(address); + s.hardware_address = address; s.waker.wake(); }); } @@ -232,11 +223,6 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( ) -> (Runner<'d, MTU>, Device<'d, MTU>) { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; - caps.medium = match &hardware_address { - HardwareAddress::Ethernet(_) => Medium::Ethernet, - HardwareAddress::Ieee802154(_) => Medium::Ieee802154, - HardwareAddress::Ip => Medium::Ip, - }; // safety: this is a self-referential struct, however: // - it can't move while the `'d` borrow is active. diff --git a/embassy-net-driver/CHANGELOG.md b/embassy-net-driver/CHANGELOG.md new file mode 100644 index 00000000..165461ef --- /dev/null +++ b/embassy-net-driver/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.2.0 - 2023-10-18 + +- Added support for IEEE 802.15.4 mediums. +- Added `Driver::hardware_address()`, `HardwareAddress`. +- Removed `Medium` enum. The medium is deduced out of the hardware address. +- Removed `Driver::ethernet_address()`. Replacement is `hardware_address()`. + +## 0.1.0 - 2023-06-29 + +- First release diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml index e25950b6..9cd6a2ea 100644 --- a/embassy-net-driver/Cargo.toml +++ b/embassy-net-driver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net-driver" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Driver trait for the `embassy-net` async TCP/IP network stack." diff --git a/embassy-net-driver/src/lib.rs b/embassy-net-driver/src/lib.rs index b64c1000..87f9f6ed 100644 --- a/embassy-net-driver/src/lib.rs +++ b/embassy-net-driver/src/lib.rs @@ -7,12 +7,23 @@ use core::task::Context; /// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum HardwareAddress { - /// A six-octet Ethernet address + /// Ethernet medium, with a A six-octet Ethernet address. + /// + /// Devices of this type send and receive Ethernet frames, + /// and interfaces using it must do neighbor discovery via ARP or NDISC. + /// + /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode. Ethernet([u8; 6]), - /// An eight-octet IEEE802.15.4 address + /// 6LoWPAN over IEEE802.15.4, with an eight-octet address. Ieee802154([u8; 8]), - /// Indicates that a Driver is IP-native, and has no hardware address + /// Indicates that a Driver is IP-native, and has no hardware address. + /// + /// Devices of this type send and receive IP frames, without an + /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done. + /// + /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode. Ip, } @@ -64,6 +75,10 @@ pub trait Driver { fn capabilities(&self) -> Capabilities; /// Get the device's hardware address. + /// + /// The returned hardware address also determines the "medium" of this driver. This indicates + /// what kind of packet the sent/received bytes are, and determines some behaviors of + /// the interface. For example, ARP/NDISC address resolution is only done for Ethernet mediums. fn hardware_address(&self) -> HardwareAddress; } @@ -124,13 +139,6 @@ pub trait TxToken { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] pub struct Capabilities { - /// Medium of the device. - /// - /// This indicates what kind of packet the sent/received bytes are, and determines - /// some behaviors of Interface. For example, ARP/NDISC address resolution is only done - /// for Ethernet mediums. - pub medium: Medium, - /// Maximum transmission unit. /// /// The network device is unable to send or receive frames larger than the value returned @@ -161,32 +169,6 @@ pub struct Capabilities { pub checksum: ChecksumCapabilities, } -/// Type of medium of a device. -#[derive(Debug, Eq, PartialEq, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Medium { - /// Ethernet medium. Devices of this type send and receive Ethernet frames, - /// and interfaces using it must do neighbor discovery via ARP or NDISC. - /// - /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode. - Ethernet, - - /// IP medium. Devices of this type send and receive IP frames, without an - /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done. - /// - /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode. - Ip, - - /// IEEE 802_15_4 medium - Ieee802154, -} - -impl Default for Medium { - fn default() -> Medium { - Medium::Ethernet - } -} - /// A description of checksum behavior for every supported protocol. #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-net-enc28j60/Cargo.toml b/embassy-net-enc28j60/Cargo.toml index e50fd0e6..ea2ed1f7 100644 --- a/embassy-net-enc28j60/Cargo.toml +++ b/embassy-net-enc28j60/Cargo.toml @@ -10,8 +10,8 @@ edition = "2021" [dependencies] embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } -embassy-time = { version = "0.1.4", path = "../embassy-time" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } +embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } defmt = { version = "0.3", optional = true } diff --git a/embassy-net-enc28j60/src/lib.rs b/embassy-net-enc28j60/src/lib.rs index f96a6ff1..f1813492 100644 --- a/embassy-net-enc28j60/src/lib.rs +++ b/embassy-net-enc28j60/src/lib.rs @@ -19,7 +19,7 @@ mod traits; use core::cmp; use core::convert::TryInto; -use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_time::Duration; use embedded_hal::digital::OutputPin; use embedded_hal::spi::{Operation, SpiDevice}; @@ -671,7 +671,6 @@ where fn capabilities(&self) -> Capabilities { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; - caps.medium = Medium::Ethernet; caps } diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index a0f53c6a..5f901bb9 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -7,10 +7,10 @@ edition = "2021" defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } -embassy-time = { version = "0.1.4", path = "../embassy-time" } +embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-sync = { version = "0.3.0", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"} embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs index a4996b58..50030f43 100644 --- a/embassy-net-esp-hosted/src/control.rs +++ b/embassy-net-esp-hosted/src/control.rs @@ -1,5 +1,5 @@ -use ch::driver::LinkState; use embassy_net_driver_channel as ch; +use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; use heapless::String; use crate::ioctl::Shared; @@ -77,7 +77,7 @@ impl<'a> Control<'a> { let mac_addr = self.get_mac_addr().await?; debug!("mac addr: {:02x}", mac_addr); - self.state_ch.set_ethernet_address(mac_addr); + self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr)); Ok(()) } diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs index 4a318b20..d61eaef3 100644 --- a/embassy-net-esp-hosted/src/lib.rs +++ b/embassy-net-esp-hosted/src/lib.rs @@ -169,9 +169,9 @@ where pub async fn run(mut self) -> ! { debug!("resetting..."); self.reset.set_low().unwrap(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; self.reset.set_high().unwrap(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; let mut tx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index 453da436..bd992de0 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -16,7 +16,7 @@ defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } embedded-io-async = { version = "0.6.0" } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } ppproto = { version = "0.1.2"} embassy-sync = { version = "0.3.0", path = "../embassy-sync" } diff --git a/embassy-net-tuntap/Cargo.toml b/embassy-net-tuntap/Cargo.toml index 08d30968..4e374c36 100644 --- a/embassy-net-tuntap/Cargo.toml +++ b/embassy-net-tuntap/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" edition = "2021" [dependencies] -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } async-io = "1.6.0" log = "0.4.14" libc = "0.2.101" diff --git a/embassy-net-wiznet/Cargo.toml b/embassy-net-wiznet/Cargo.toml index 31836e1d..0cc086b7 100644 --- a/embassy-net-wiznet/Cargo.toml +++ b/embassy-net-wiznet/Cargo.toml @@ -10,8 +10,8 @@ edition = "2021" [dependencies] embedded-hal = { version = "1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } -embassy-time = { version = "0.1.4", path = "../embassy-time" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } +embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } defmt = { version = "0.3", optional = true } diff --git a/embassy-net-wiznet/src/lib.rs b/embassy-net-wiznet/src/lib.rs index 3030dfb9..afdb6729 100644 --- a/embassy-net-wiznet/src/lib.rs +++ b/embassy-net-wiznet/src/lib.rs @@ -1,14 +1,14 @@ -//! [`embassy-net`](https://crates.io/crates/embassy-net) driver for WIZnet ethernet chips. #![no_std] #![feature(async_fn_in_trait)] +#![doc = include_str!("../README.md")] pub mod chip; mod device; -use embassy_futures::select::{select, Either}; +use embassy_futures::select::{select3, Either3}; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::LinkState; -use embassy_time::{Duration, Timer}; +use embassy_time::{Duration, Ticker, Timer}; use embedded_hal::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::SpiDevice; @@ -49,32 +49,34 @@ pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> { impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> { pub async fn run(mut self) -> ! { let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); + let mut tick = Ticker::every(Duration::from_millis(500)); loop { - if self.mac.is_link_up().await { - state_chan.set_link_state(LinkState::Up); - loop { - match select( - async { - self.int.wait_for_low().await.ok(); - rx_chan.rx_buf().await - }, - tx_chan.tx_buf(), - ) - .await - { - Either::First(p) => { - if let Ok(n) = self.mac.read_frame(p).await { - rx_chan.rx_done(n); - } - } - Either::Second(p) => { - self.mac.write_frame(p).await.ok(); - tx_chan.tx_done(); - } + match select3( + async { + self.int.wait_for_low().await.ok(); + rx_chan.rx_buf().await + }, + tx_chan.tx_buf(), + tick.next(), + ) + .await + { + Either3::First(p) => { + if let Ok(n) = self.mac.read_frame(p).await { + rx_chan.rx_done(n); + } + } + Either3::Second(p) => { + self.mac.write_frame(p).await.ok(); + tx_chan.tx_done(); + } + Either3::Third(()) => { + if self.mac.is_link_up().await { + state_chan.set_link_state(LinkState::Up); + } else { + state_chan.set_link_state(LinkState::Down); } } - } else { - state_chan.set_link_state(LinkState::Down); } } } @@ -95,12 +97,12 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi // Reset the chip. reset.set_low().ok(); // Ensure the reset is registered. - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; reset.set_high().ok(); // Wait for PLL lock. Some chips are slower than others. // Slowest is w5100s which is 100ms, so let's just wait that. - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap(); diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md new file mode 100644 index 00000000..7b91b844 --- /dev/null +++ b/embassy-net/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.2.0 - 2023-10-18 + +- Re-export `smoltcp::wire::IpEndpoint` +- Add poll functions on UdpSocket +- Make dual-stack work in embassy-net +- Fix multicast support +- Allow ethernet and 802.15.4 to coexist +- Add IEEE802.15.4 address to embassy net Stack +- Use HardwareAddress in Driver +- Add async versions of smoltcp's `send` and `recv` closure based API +- add error translation to tcp errors +- Forward TCP/UDP socket capacity impls +- allow changing IP config at runtime +- allow non-'static drivers +- Remove impl_trait_projections +- update embedded-io, embedded-nal-async +- add support for dhcp hostname option +- Wake stack's task after queueing a DNS query + +## 0.1.0 - 2023-06-29 + +- First release diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 8fcbef83..573d20fb 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-net" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Async TCP/IP network stack for embedded systems" @@ -51,8 +51,8 @@ smoltcp = { version = "0.10.0", default-features = false, features = [ "async", ] } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } -embassy-time = { version = "0.1.4", path = "../embassy-time" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } +embassy-time = { version = "0.1.5", path = "../embassy-time" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embedded-io-async = { version = "0.6.0", optional = true } diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs index 8c2b7d31..54a0c47e 100644 --- a/embassy-net/src/device.rs +++ b/embassy-net/src/device.rs @@ -1,7 +1,7 @@ use core::task::Context; -use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken}; -use smoltcp::phy; +use embassy_net_driver::{Capabilities, Checksum, Driver, RxToken, TxToken}; +use smoltcp::phy::{self, Medium}; use smoltcp::time::Instant; pub(crate) struct DriverAdapter<'d, 'c, T> @@ -11,6 +11,7 @@ where // must be Some when actually using this to rx/tx pub cx: Option<&'d mut Context<'c>>, pub inner: &'d mut T, + pub medium: Medium, } impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T> @@ -46,19 +47,7 @@ where smolcaps.max_transmission_unit = caps.max_transmission_unit; smolcaps.max_burst_size = caps.max_burst_size; - smolcaps.medium = match caps.medium { - #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => phy::Medium::Ethernet, - #[cfg(feature = "medium-ip")] - Medium::Ip => phy::Medium::Ip, - #[cfg(feature = "medium-ieee802154")] - Medium::Ieee802154 => phy::Medium::Ieee802154, - #[allow(unreachable_patterns)] - _ => panic!( - "Unsupported medium {:?}. Make sure to enable it in embassy-net's Cargo features.", - caps.medium - ), - }; + smolcaps.medium = self.medium; smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4); smolcaps.checksum.tcp = convert(caps.checksum.tcp); smolcaps.checksum.udp = convert(caps.checksum.udp); diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index ef67935e..79896287 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -33,6 +33,7 @@ use heapless::Vec; pub use smoltcp::iface::MulticastError; #[allow(unused_imports)] use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; +use smoltcp::phy::Medium; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4::{self, RetryConfig}; #[cfg(feature = "medium-ethernet")] @@ -264,14 +265,17 @@ pub(crate) struct SocketStack { next_local_port: u16, } -fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> HardwareAddress { +fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddress, Medium) { match addr { #[cfg(feature = "medium-ethernet")] - driver::HardwareAddress::Ethernet(eth) => HardwareAddress::Ethernet(EthernetAddress(eth)), + driver::HardwareAddress::Ethernet(eth) => (HardwareAddress::Ethernet(EthernetAddress(eth)), Medium::Ethernet), #[cfg(feature = "medium-ieee802154")] - driver::HardwareAddress::Ieee802154(ieee) => HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)), + driver::HardwareAddress::Ieee802154(ieee) => ( + HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)), + Medium::Ieee802154, + ), #[cfg(feature = "medium-ip")] - driver::HardwareAddress::Ip => HardwareAddress::Ip, + driver::HardwareAddress::Ip => (HardwareAddress::Ip, Medium::Ip), #[allow(unreachable_patterns)] _ => panic!( @@ -289,7 +293,8 @@ impl Stack { resources: &'static mut StackResources, random_seed: u64, ) -> Self { - let mut iface_cfg = smoltcp::iface::Config::new(to_smoltcp_hardware_address(device.hardware_address())); + let (hardware_addr, medium) = to_smoltcp_hardware_address(device.hardware_address()); + let mut iface_cfg = smoltcp::iface::Config::new(hardware_addr); iface_cfg.random_seed = random_seed; let iface = Interface::new( @@ -297,6 +302,7 @@ impl Stack { &mut DriverAdapter { inner: &mut device, cx: None, + medium, }, instant_to_smoltcp(Instant::now()), ); @@ -356,7 +362,7 @@ impl Stack { /// Get the hardware address of the network interface. pub fn hardware_address(&self) -> HardwareAddress { - self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address())) + self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address()).0) } /// Get whether the link is up. @@ -509,7 +515,10 @@ impl Stack { self.with_mut(|s, i| { let socket = s.sockets.get_mut::(i.dns_socket); match socket.start_query(s.iface.context(), name, qtype) { - Ok(handle) => Poll::Ready(Ok(handle)), + Ok(handle) => { + s.waker.wake(); + Poll::Ready(Ok(handle)) + } Err(dns::StartQueryError::NoFreeSlot) => { i.dns_waker.register(cx.waker()); Poll::Pending @@ -809,18 +818,28 @@ impl Inner { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { s.waker.register(cx.waker()); + let (_hardware_addr, medium) = to_smoltcp_hardware_address(self.device.hardware_address()); + #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] - if self.device.capabilities().medium == embassy_net_driver::Medium::Ethernet - || self.device.capabilities().medium == embassy_net_driver::Medium::Ieee802154 { - s.iface - .set_hardware_addr(to_smoltcp_hardware_address(self.device.hardware_address())); + let do_set = match medium { + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => true, + #[cfg(feature = "medium-ieee802154")] + Medium::Ieee802154 => true, + #[allow(unreachable_patterns)] + _ => false, + }; + if do_set { + s.iface.set_hardware_addr(_hardware_addr); + } } let timestamp = instant_to_smoltcp(Instant::now()); let mut smoldev = DriverAdapter { cx: Some(cx), inner: &mut self.device, + medium, }; s.iface.poll(timestamp, &mut smoldev, &mut s.sockets); @@ -841,6 +860,9 @@ impl Inner { let socket = s.sockets.get_mut::(dhcp_handle); if self.link_up { + if old_link_up != self.link_up { + socket.reset(); + } match socket.poll() { None => {} Some(dhcpv4::Event::Deconfigured) => { diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index bd96bc15..360f77c1 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -94,7 +94,7 @@ _gpio-p1 = [] _nrf52832_anomaly_109 = [] [dependencies] -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index afc2c4a7..5e9a8ed0 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -6,10 +6,13 @@ pub mod pac { // To avoid cfg spam, we remove _ns or _s suffixes here. pub use nrf5340_app_pac::NVIC_PRIO_BITS; - + + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf5340_app_pac::interrupt; + #[doc(no_inline)] pub use nrf5340_app_pac::{ - interrupt, Interrupt, Peripherals, @@ -60,156 +63,167 @@ pub mod pac { wdt0_ns as wdt0, }; - #[cfg(feature = "nrf5340-app-ns")] - #[doc(no_inline)] - pub use nrf5340_app_pac::{ - CLOCK_NS as CLOCK, - COMP_NS as COMP, - CTRLAP_NS as CTRLAP, - DCNF_NS as DCNF, - DPPIC_NS as DPPIC, - EGU0_NS as EGU0, - EGU1_NS as EGU1, - EGU2_NS as EGU2, - EGU3_NS as EGU3, - EGU4_NS as EGU4, - EGU5_NS as EGU5, - FPU_NS as FPU, - GPIOTE1_NS as GPIOTE1, - I2S0_NS as I2S0, - IPC_NS as IPC, - KMU_NS as KMU, - LPCOMP_NS as LPCOMP, - MUTEX_NS as MUTEX, - NFCT_NS as NFCT, - NVMC_NS as NVMC, - OSCILLATORS_NS as OSCILLATORS, - P0_NS as P0, - P1_NS as P1, - PDM0_NS as PDM0, - POWER_NS as POWER, - PWM0_NS as PWM0, - PWM1_NS as PWM1, - PWM2_NS as PWM2, - PWM3_NS as PWM3, - QDEC0_NS as QDEC0, - QDEC1_NS as QDEC1, - QSPI_NS as QSPI, - REGULATORS_NS as REGULATORS, - RESET_NS as RESET, - RTC0_NS as RTC0, - RTC1_NS as RTC1, - SAADC_NS as SAADC, - SPIM0_NS as SPIM0, - SPIM1_NS as SPIM1, - SPIM2_NS as SPIM2, - SPIM3_NS as SPIM3, - SPIM4_NS as SPIM4, - SPIS0_NS as SPIS0, - SPIS1_NS as SPIS1, - SPIS2_NS as SPIS2, - SPIS3_NS as SPIS3, - TIMER0_NS as TIMER0, - TIMER1_NS as TIMER1, - TIMER2_NS as TIMER2, - TWIM0_NS as TWIM0, - TWIM1_NS as TWIM1, - TWIM2_NS as TWIM2, - TWIM3_NS as TWIM3, - TWIS0_NS as TWIS0, - TWIS1_NS as TWIS1, - TWIS2_NS as TWIS2, - TWIS3_NS as TWIS3, - UARTE0_NS as UARTE0, - UARTE1_NS as UARTE1, - UARTE2_NS as UARTE2, - UARTE3_NS as UARTE3, - USBD_NS as USBD, - USBREGULATOR_NS as USBREGULATOR, - VMC_NS as VMC, - WDT0_NS as WDT0, - WDT1_NS as WDT1, - }; + /// Non-Secure mode (NS) peripherals + pub mod ns { + #[cfg(feature = "nrf5340-app-ns")] + #[doc(no_inline)] + pub use nrf5340_app_pac::{ + CLOCK_NS as CLOCK, + COMP_NS as COMP, + CTRLAP_NS as CTRLAP, + DCNF_NS as DCNF, + DPPIC_NS as DPPIC, + EGU0_NS as EGU0, + EGU1_NS as EGU1, + EGU2_NS as EGU2, + EGU3_NS as EGU3, + EGU4_NS as EGU4, + EGU5_NS as EGU5, + FPU_NS as FPU, + GPIOTE1_NS as GPIOTE1, + I2S0_NS as I2S0, + IPC_NS as IPC, + KMU_NS as KMU, + LPCOMP_NS as LPCOMP, + MUTEX_NS as MUTEX, + NFCT_NS as NFCT, + NVMC_NS as NVMC, + OSCILLATORS_NS as OSCILLATORS, + P0_NS as P0, + P1_NS as P1, + PDM0_NS as PDM0, + POWER_NS as POWER, + PWM0_NS as PWM0, + PWM1_NS as PWM1, + PWM2_NS as PWM2, + PWM3_NS as PWM3, + QDEC0_NS as QDEC0, + QDEC1_NS as QDEC1, + QSPI_NS as QSPI, + REGULATORS_NS as REGULATORS, + RESET_NS as RESET, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SAADC_NS as SAADC, + SPIM0_NS as SPIM0, + SPIM1_NS as SPIM1, + SPIM2_NS as SPIM2, + SPIM3_NS as SPIM3, + SPIM4_NS as SPIM4, + SPIS0_NS as SPIS0, + SPIS1_NS as SPIS1, + SPIS2_NS as SPIS2, + SPIS3_NS as SPIS3, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TWIM0_NS as TWIM0, + TWIM1_NS as TWIM1, + TWIM2_NS as TWIM2, + TWIM3_NS as TWIM3, + TWIS0_NS as TWIS0, + TWIS1_NS as TWIS1, + TWIS2_NS as TWIS2, + TWIS3_NS as TWIS3, + UARTE0_NS as UARTE0, + UARTE1_NS as UARTE1, + UARTE2_NS as UARTE2, + UARTE3_NS as UARTE3, + USBD_NS as USBD, + USBREGULATOR_NS as USBREGULATOR, + VMC_NS as VMC, + WDT0_NS as WDT0, + WDT1_NS as WDT1, + }; + } - #[cfg(feature = "nrf5340-app-s")] - #[doc(no_inline)] - pub use nrf5340_app_pac::{ - CACHEDATA_S as CACHEDATA, - CACHEINFO_S as CACHEINFO, - CACHE_S as CACHE, - CLOCK_S as CLOCK, - COMP_S as COMP, - CRYPTOCELL_S as CRYPTOCELL, - CTI_S as CTI, - CTRLAP_S as CTRLAP, - DCNF_S as DCNF, - DPPIC_S as DPPIC, - EGU0_S as EGU0, - EGU1_S as EGU1, - EGU2_S as EGU2, - EGU3_S as EGU3, - EGU4_S as EGU4, - EGU5_S as EGU5, - FICR_S as FICR, - FPU_S as FPU, - GPIOTE0_S as GPIOTE0, - I2S0_S as I2S0, - IPC_S as IPC, - KMU_S as KMU, - LPCOMP_S as LPCOMP, - MUTEX_S as MUTEX, - NFCT_S as NFCT, - NVMC_S as NVMC, - OSCILLATORS_S as OSCILLATORS, - P0_S as P0, - P1_S as P1, - PDM0_S as PDM0, - POWER_S as POWER, - PWM0_S as PWM0, - PWM1_S as PWM1, - PWM2_S as PWM2, - PWM3_S as PWM3, - QDEC0_S as QDEC0, - QDEC1_S as QDEC1, - QSPI_S as QSPI, - REGULATORS_S as REGULATORS, - RESET_S as RESET, - RTC0_S as RTC0, - RTC1_S as RTC1, - SAADC_S as SAADC, - SPIM0_S as SPIM0, - SPIM1_S as SPIM1, - SPIM2_S as SPIM2, - SPIM3_S as SPIM3, - SPIM4_S as SPIM4, - SPIS0_S as SPIS0, - SPIS1_S as SPIS1, - SPIS2_S as SPIS2, - SPIS3_S as SPIS3, - SPU_S as SPU, - TAD_S as TAD, - TIMER0_S as TIMER0, - TIMER1_S as TIMER1, - TIMER2_S as TIMER2, - TWIM0_S as TWIM0, - TWIM1_S as TWIM1, - TWIM2_S as TWIM2, - TWIM3_S as TWIM3, - TWIS0_S as TWIS0, - TWIS1_S as TWIS1, - TWIS2_S as TWIS2, - TWIS3_S as TWIS3, - UARTE0_S as UARTE0, - UARTE1_S as UARTE1, - UARTE2_S as UARTE2, - UARTE3_S as UARTE3, - UICR_S as UICR, - USBD_S as USBD, - USBREGULATOR_S as USBREGULATOR, - VMC_S as VMC, - WDT0_S as WDT0, - WDT1_S as WDT1, - }; + /// Secure mode (S) peripherals + pub mod s { + #[cfg(feature = "nrf5340-app-s")] + #[doc(no_inline)] + pub use nrf5340_app_pac::{ + CACHEDATA_S as CACHEDATA, + CACHEINFO_S as CACHEINFO, + CACHE_S as CACHE, + CLOCK_S as CLOCK, + COMP_S as COMP, + CRYPTOCELL_S as CRYPTOCELL, + CTI_S as CTI, + CTRLAP_S as CTRLAP, + DCNF_S as DCNF, + DPPIC_S as DPPIC, + EGU0_S as EGU0, + EGU1_S as EGU1, + EGU2_S as EGU2, + EGU3_S as EGU3, + EGU4_S as EGU4, + EGU5_S as EGU5, + FICR_S as FICR, + FPU_S as FPU, + GPIOTE0_S as GPIOTE0, + I2S0_S as I2S0, + IPC_S as IPC, + KMU_S as KMU, + LPCOMP_S as LPCOMP, + MUTEX_S as MUTEX, + NFCT_S as NFCT, + NVMC_S as NVMC, + OSCILLATORS_S as OSCILLATORS, + P0_S as P0, + P1_S as P1, + PDM0_S as PDM0, + POWER_S as POWER, + PWM0_S as PWM0, + PWM1_S as PWM1, + PWM2_S as PWM2, + PWM3_S as PWM3, + QDEC0_S as QDEC0, + QDEC1_S as QDEC1, + QSPI_S as QSPI, + REGULATORS_S as REGULATORS, + RESET_S as RESET, + RTC0_S as RTC0, + RTC1_S as RTC1, + SAADC_S as SAADC, + SPIM0_S as SPIM0, + SPIM1_S as SPIM1, + SPIM2_S as SPIM2, + SPIM3_S as SPIM3, + SPIM4_S as SPIM4, + SPIS0_S as SPIS0, + SPIS1_S as SPIS1, + SPIS2_S as SPIS2, + SPIS3_S as SPIS3, + SPU_S as SPU, + TAD_S as TAD, + TIMER0_S as TIMER0, + TIMER1_S as TIMER1, + TIMER2_S as TIMER2, + TWIM0_S as TWIM0, + TWIM1_S as TWIM1, + TWIM2_S as TWIM2, + TWIM3_S as TWIM3, + TWIS0_S as TWIS0, + TWIS1_S as TWIS1, + TWIS2_S as TWIS2, + TWIS3_S as TWIS3, + UARTE0_S as UARTE0, + UARTE1_S as UARTE1, + UARTE2_S as UARTE2, + UARTE3_S as UARTE3, + UICR_S as UICR, + USBD_S as USBD, + USBREGULATOR_S as USBREGULATOR, + VMC_S as VMC, + WDT0_S as WDT0, + WDT1_S as WDT1, + }; + } + + #[cfg(feature = "_ns")] + pub use ns::*; + #[cfg(feature = "_s")] + pub use s::*; } /// The maximum buffer size that the EasyDMA can send/recv in one operation. diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index dee666a6..a7cf8287 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -7,9 +7,12 @@ pub mod pac { pub use nrf5340_net_pac::NVIC_PRIO_BITS; + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf5340_net_pac::interrupt; + #[doc(no_inline)] pub use nrf5340_net_pac::{ - interrupt, Interrupt, Peripherals, diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 495285ba..8b1356ef 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs @@ -7,9 +7,12 @@ pub mod pac { pub use nrf9160_pac::NVIC_PRIO_BITS; + #[cfg(feature="rt")] + #[doc(no_inline)] + pub use nrf9160_pac::interrupt; + #[doc(no_inline)] pub use nrf9160_pac::{ - interrupt, Interrupt, cc_host_rgf_s as cc_host_rgf, @@ -45,122 +48,131 @@ pub mod pac { wdt_ns as wdt, }; - #[cfg(feature = "nrf9160-ns")] - #[doc(no_inline)] - pub use nrf9160_pac::{ - CLOCK_NS as CLOCK, - DPPIC_NS as DPPIC, - EGU0_NS as EGU0, - EGU1_NS as EGU1, - EGU2_NS as EGU2, - EGU3_NS as EGU3, - EGU4_NS as EGU4, - EGU5_NS as EGU5, - FPU_NS as FPU, - GPIOTE1_NS as GPIOTE1, - I2S_NS as I2S, - IPC_NS as IPC, - KMU_NS as KMU, - NVMC_NS as NVMC, - P0_NS as P0, - PDM_NS as PDM, - POWER_NS as POWER, - PWM0_NS as PWM0, - PWM1_NS as PWM1, - PWM2_NS as PWM2, - PWM3_NS as PWM3, - REGULATORS_NS as REGULATORS, - RTC0_NS as RTC0, - RTC1_NS as RTC1, - SAADC_NS as SAADC, - SPIM0_NS as SPIM0, - SPIM1_NS as SPIM1, - SPIM2_NS as SPIM2, - SPIM3_NS as SPIM3, - SPIS0_NS as SPIS0, - SPIS1_NS as SPIS1, - SPIS2_NS as SPIS2, - SPIS3_NS as SPIS3, - TIMER0_NS as TIMER0, - TIMER1_NS as TIMER1, - TIMER2_NS as TIMER2, - TWIM0_NS as TWIM0, - TWIM1_NS as TWIM1, - TWIM2_NS as TWIM2, - TWIM3_NS as TWIM3, - TWIS0_NS as TWIS0, - TWIS1_NS as TWIS1, - TWIS2_NS as TWIS2, - TWIS3_NS as TWIS3, - UARTE0_NS as UARTE0, - UARTE1_NS as UARTE1, - UARTE2_NS as UARTE2, - UARTE3_NS as UARTE3, - VMC_NS as VMC, - WDT_NS as WDT, - }; + /// Non-Secure mode (NS) peripherals + pub mod ns { + #[doc(no_inline)] + pub use nrf9160_pac::{ + CLOCK_NS as CLOCK, + DPPIC_NS as DPPIC, + EGU0_NS as EGU0, + EGU1_NS as EGU1, + EGU2_NS as EGU2, + EGU3_NS as EGU3, + EGU4_NS as EGU4, + EGU5_NS as EGU5, + FPU_NS as FPU, + GPIOTE1_NS as GPIOTE1, + I2S_NS as I2S, + IPC_NS as IPC, + KMU_NS as KMU, + NVMC_NS as NVMC, + P0_NS as P0, + PDM_NS as PDM, + POWER_NS as POWER, + PWM0_NS as PWM0, + PWM1_NS as PWM1, + PWM2_NS as PWM2, + PWM3_NS as PWM3, + REGULATORS_NS as REGULATORS, + RTC0_NS as RTC0, + RTC1_NS as RTC1, + SAADC_NS as SAADC, + SPIM0_NS as SPIM0, + SPIM1_NS as SPIM1, + SPIM2_NS as SPIM2, + SPIM3_NS as SPIM3, + SPIS0_NS as SPIS0, + SPIS1_NS as SPIS1, + SPIS2_NS as SPIS2, + SPIS3_NS as SPIS3, + TIMER0_NS as TIMER0, + TIMER1_NS as TIMER1, + TIMER2_NS as TIMER2, + TWIM0_NS as TWIM0, + TWIM1_NS as TWIM1, + TWIM2_NS as TWIM2, + TWIM3_NS as TWIM3, + TWIS0_NS as TWIS0, + TWIS1_NS as TWIS1, + TWIS2_NS as TWIS2, + TWIS3_NS as TWIS3, + UARTE0_NS as UARTE0, + UARTE1_NS as UARTE1, + UARTE2_NS as UARTE2, + UARTE3_NS as UARTE3, + VMC_NS as VMC, + WDT_NS as WDT, + }; + } - #[cfg(feature = "nrf9160-s")] - #[doc(no_inline)] - pub use nrf9160_pac::{ - CC_HOST_RGF_S as CC_HOST_RGF, - CLOCK_S as CLOCK, - CRYPTOCELL_S as CRYPTOCELL, - CTRL_AP_PERI_S as CTRL_AP_PERI, - DPPIC_S as DPPIC, - EGU0_S as EGU0, - EGU1_S as EGU1, - EGU2_S as EGU2, - EGU3_S as EGU3, - EGU4_S as EGU4, - EGU5_S as EGU5, - FICR_S as FICR, - FPU_S as FPU, - GPIOTE0_S as GPIOTE0, - I2S_S as I2S, - IPC_S as IPC, - KMU_S as KMU, - NVMC_S as NVMC, - P0_S as P0, - PDM_S as PDM, - POWER_S as POWER, - PWM0_S as PWM0, - PWM1_S as PWM1, - PWM2_S as PWM2, - PWM3_S as PWM3, - REGULATORS_S as REGULATORS, - RTC0_S as RTC0, - RTC1_S as RTC1, - SAADC_S as SAADC, - SPIM0_S as SPIM0, - SPIM1_S as SPIM1, - SPIM2_S as SPIM2, - SPIM3_S as SPIM3, - SPIS0_S as SPIS0, - SPIS1_S as SPIS1, - SPIS2_S as SPIS2, - SPIS3_S as SPIS3, - SPU_S as SPU, - TAD_S as TAD, - TIMER0_S as TIMER0, - TIMER1_S as TIMER1, - TIMER2_S as TIMER2, - TWIM0_S as TWIM0, - TWIM1_S as TWIM1, - TWIM2_S as TWIM2, - TWIM3_S as TWIM3, - TWIS0_S as TWIS0, - TWIS1_S as TWIS1, - TWIS2_S as TWIS2, - TWIS3_S as TWIS3, - UARTE0_S as UARTE0, - UARTE1_S as UARTE1, - UARTE2_S as UARTE2, - UARTE3_S as UARTE3, - UICR_S as UICR, - VMC_S as VMC, - WDT_S as WDT, - }; + /// Secure mode (S) peripherals + pub mod s { + #[doc(no_inline)] + pub use nrf9160_pac::{ + CC_HOST_RGF_S as CC_HOST_RGF, + CLOCK_S as CLOCK, + CRYPTOCELL_S as CRYPTOCELL, + CTRL_AP_PERI_S as CTRL_AP_PERI, + DPPIC_S as DPPIC, + EGU0_S as EGU0, + EGU1_S as EGU1, + EGU2_S as EGU2, + EGU3_S as EGU3, + EGU4_S as EGU4, + EGU5_S as EGU5, + FICR_S as FICR, + FPU_S as FPU, + GPIOTE0_S as GPIOTE0, + I2S_S as I2S, + IPC_S as IPC, + KMU_S as KMU, + NVMC_S as NVMC, + P0_S as P0, + PDM_S as PDM, + POWER_S as POWER, + PWM0_S as PWM0, + PWM1_S as PWM1, + PWM2_S as PWM2, + PWM3_S as PWM3, + REGULATORS_S as REGULATORS, + RTC0_S as RTC0, + RTC1_S as RTC1, + SAADC_S as SAADC, + SPIM0_S as SPIM0, + SPIM1_S as SPIM1, + SPIM2_S as SPIM2, + SPIM3_S as SPIM3, + SPIS0_S as SPIS0, + SPIS1_S as SPIS1, + SPIS2_S as SPIS2, + SPIS3_S as SPIS3, + SPU_S as SPU, + TAD_S as TAD, + TIMER0_S as TIMER0, + TIMER1_S as TIMER1, + TIMER2_S as TIMER2, + TWIM0_S as TWIM0, + TWIM1_S as TWIM1, + TWIM2_S as TWIM2, + TWIM3_S as TWIM3, + TWIS0_S as TWIS0, + TWIS1_S as TWIS1, + TWIS2_S as TWIS2, + TWIS3_S as TWIS3, + UARTE0_S as UARTE0, + UARTE1_S as UARTE1, + UARTE2_S as UARTE2, + UARTE3_S as UARTE3, + UICR_S as UICR, + VMC_S as VMC, + WDT_S as WDT, + }; + } + + #[cfg(feature = "_ns")] + pub use ns::*; + #[cfg(feature = "_s")] + pub use s::*; } /// The maximum buffer size that the EasyDMA can send/recv in one operation. diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 02b11e19..903dc25a 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -60,7 +60,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"] [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.4", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } +embassy-time = { version = "0.1.5", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index bac45574..5b913f15 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -213,6 +213,7 @@ impl<'d> Adc<'d, Async> { ch: &mut Channel<'_>, buf: &mut [W], fcs_err: bool, + div: u16, dma: impl Peripheral

, ) -> Result<(), Error> { let r = Self::regs(); @@ -258,6 +259,7 @@ impl<'d> Adc<'d, Async> { // start conversions and wait for dma to finish. we can't report errors early // because there's no interrupt to signal them, and inspecting every element // of the fifo is too costly to do here. + r.div().write_set(|w| w.set_int(div)); r.cs().write_set(|w| w.set_start_many(true)); dma.await; mem::drop(auto_reset); @@ -275,9 +277,10 @@ impl<'d> Adc<'d, Async> { &mut self, ch: &mut Channel<'_>, buf: &mut [S], + div: u16, dma: impl Peripheral

, ) -> Result<(), Error> { - self.read_many_inner(ch, buf, false, dma).await + self.read_many_inner(ch, buf, false, div, dma).await } #[inline] @@ -285,11 +288,12 @@ impl<'d> Adc<'d, Async> { &mut self, ch: &mut Channel<'_>, buf: &mut [Sample], + div: u16, dma: impl Peripheral

, ) { // errors are reported in individual samples let _ = self - .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, dma) + .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, div, dma) .await; } } diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index c297d69a..516b8254 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -10,16 +10,39 @@ use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::{pac, peripherals, RegExt}; +/// The configuration of a PWM slice. +/// Note the period in clock cycles of a slice can be computed as: +/// `(top + 1) * (phase_correct ? 1 : 2) * divider` #[non_exhaustive] #[derive(Clone)] pub struct Config { + /// Inverts the PWM output signal on channel A. pub invert_a: bool, + /// Inverts the PWM output signal on channel B. pub invert_b: bool, + /// Enables phase-correct mode for PWM operation. + /// In phase-correct mode, the PWM signal is generated in such a way that + /// the pulse is always centered regardless of the duty cycle. + /// The output frequency is halved when phase-correct mode is enabled. pub phase_correct: bool, + /// Enables the PWM slice, allowing it to generate an output. pub enable: bool, + /// A fractional clock divider, represented as a fixed-point number with + /// 8 integer bits and 4 fractional bits. It allows precise control over + /// the PWM output frequency by gating the PWM counter increment. + /// A higher value will result in a slower output frequency. pub divider: fixed::FixedU16, + /// The output on channel A goes high when `compare_a` is higher than the + /// counter. A compare of 0 will produce an always low output, while a + /// compare of `top + 1` will produce an always high output. pub compare_a: u16, + /// The output on channel B goes high when `compare_b` is higher than the + /// counter. A compare of 0 will produce an always low output, while a + /// compare of `top + 1` will produce an always high output. pub compare_b: u16, + /// The point at which the counter wraps, representing the maximum possible + /// period. The counter will either wrap to 0 or reverse depending on the + /// setting of `phase_correct`. pub top: u16, } @@ -173,6 +196,9 @@ impl<'d, T: Channel> Pwm<'d, T> { }); } + /// Advances a slice’s output phase by one count while it is running + /// by inserting a pulse into the clock enable. The counter + /// will not count faster than once per cycle. #[inline] pub fn phase_advance(&mut self) { let p = self.inner.regs(); @@ -180,6 +206,9 @@ impl<'d, T: Channel> Pwm<'d, T> { while p.csr().read().ph_adv() {} } + /// Retards a slice’s output phase by one count while it is running + /// by deleting a pulse from the clock enable. The counter will not + /// count backward when clock enable is permenantly low. #[inline] pub fn phase_retard(&mut self) { let p = self.inner.regs(); diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 645d703d..9f638761 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -5,7 +5,7 @@ use core::task::Poll; use atomic_polyfill::{AtomicU8, Ordering}; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; use embassy_sync::waitqueue::AtomicWaker; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use super::*; use crate::clocks::clk_peri_freq; @@ -435,7 +435,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { Self::flush().await.unwrap(); while self.busy() {} regs.uartlcr_h().write_set(|w| w.set_brk(true)); - Timer::after(Duration::from_micros(wait_usecs)).await; + Timer::after_micros(wait_usecs).await; regs.uartlcr_h().write_clear(|w| w.set_brk(true)); } } diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 202b0883..461986c8 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -6,7 +6,7 @@ use atomic_polyfill::{AtomicU16, Ordering}; use embassy_futures::select::{select, Either}; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use pac::uart::regs::Uartris; use crate::clocks::clk_peri_freq; @@ -187,7 +187,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { self.blocking_flush().unwrap(); while self.busy() {} regs.uartlcr_h().write_set(|w| w.set_brk(true)); - Timer::after(Duration::from_micros(wait_usecs)).await; + Timer::after_micros(wait_usecs).await; regs.uartlcr_h().write_clear(|w| w.set_brk(true)); } } diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index b9d7776e..52ecf15d 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -13,11 +13,11 @@ features = ["stm32wb55rg"] [dependencies] embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" } embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true } defmt = { version = "0.3", optional = true } cortex-m = "0.7.6" diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs index bfc4f1ee..ffba6e5e 100644 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ b/embassy-stm32-wpan/src/mac/driver.rs @@ -3,7 +3,7 @@ use core::task::Context; -use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; @@ -60,24 +60,15 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; // caps.max_burst_size = Some(self.tx.len()); - - caps.medium = Medium::Ieee802154; caps } fn link_state(&mut self, _cx: &mut Context) -> LinkState { - // if self.phy.poll_link(&mut self.station_management, cx) { - // LinkState::Up - // } else { - // LinkState::Down - // } - LinkState::Down } fn hardware_address(&self) -> HardwareAddress { // self.mac_addr - HardwareAddress::Ieee802154([0; 8]) } } diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index dbf5a69d..99288340 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -33,11 +33,11 @@ flavors = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-time = { version = "0.1.4", path = "../embassy-time", optional = true } +embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } -embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } +embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true } @@ -58,7 +58,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e4a769aa67aa82603448377daa579d67a789983a", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 7ba3a6bd..3400529c 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt::Write as _; use std::path::PathBuf; use std::{env, fs}; @@ -352,7 +352,7 @@ fn main() { // ======== // Generate DMA IRQs. - let mut dma_irqs: HashMap<&str, Vec<(&str, &str, &str)>> = HashMap::new(); + let mut dma_irqs: BTreeMap<&str, Vec<(&str, &str, &str)>> = BTreeMap::new(); for p in METADATA.peripherals { if let Some(r) = &p.registers { @@ -371,37 +371,43 @@ fn main() { } } - for (irq, channels) in dma_irqs { - let irq = format_ident!("{}", irq); + let dma_irqs: TokenStream = dma_irqs + .iter() + .map(|(irq, channels)| { + let irq = format_ident!("{}", irq); - let xdma = format_ident!("{}", channels[0].0); - let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); + let xdma = format_ident!("{}", channels[0].0); + let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); - g.extend(quote! { - #[cfg(feature = "rt")] - #[crate::interrupt] - unsafe fn #irq () { - #( - ::on_irq(); - )* + quote! { + #[cfg(feature = "rt")] + #[crate::interrupt] + unsafe fn #irq () { + #( + ::on_irq(); + )* + } } - }); - } + }) + .collect(); + + g.extend(dma_irqs); + + // ======== + // Extract the rcc registers + let rcc_registers = METADATA + .peripherals + .iter() + .filter_map(|p| p.registers.as_ref()) + .find(|r| r.kind == "rcc") + .unwrap(); // ======== // Generate rcc fieldset and enum maps let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = { - let rcc_registers = METADATA - .peripherals - .iter() - .filter_map(|p| p.registers.as_ref()) - .find(|r| r.kind == "rcc") - .unwrap() - .ir; - - let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; - let rcc_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.fieldsets.iter().map(|f| (f.name, f)).collect(); - let rcc_enums: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect(); + let rcc_blocks = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap().items; + let rcc_fieldsets: HashMap<&str, &FieldSet> = rcc_registers.ir.fieldsets.iter().map(|f| (f.name, f)).collect(); + let rcc_enums: HashMap<&str, &Enum> = rcc_registers.ir.enums.iter().map(|e| (e.name, e)).collect(); rcc_blocks .iter() @@ -432,7 +438,7 @@ fn main() { // Generate RccPeripheral impls let refcounted_peripherals = HashSet::from(["usart", "adc"]); - let mut refcount_statics = HashSet::new(); + let mut refcount_statics = BTreeSet::new(); for p in METADATA.peripherals { if !singletons.contains(&p.name.to_string()) { @@ -465,9 +471,9 @@ fn main() { let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let pname = format_ident!("{}", p.name); - let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); - let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); - let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); + let clk = format_ident!("{}", rcc.clock); + let en_reg = format_ident!("{}", en.register); + let set_en_field = format_ident!("set_{}", en.field); let (before_enable, before_disable) = if refcounted_peripherals.contains(ptype) { let refcount_static = @@ -493,9 +499,11 @@ fn main() { (TokenStream::new(), TokenStream::new()) }; + let mux_supported = HashSet::from(["c0", "h5", "h50", "h7", "h7ab", "h7rm0433", "g4", "l4"]) + .contains(rcc_registers.version); let mux_for = |mux: Option<&'static PeripheralRccRegister>| { - // temporary hack to restrict the scope of the implementation to h5 - if !&chip_name.starts_with("stm32h5") { + // restrict mux implementation to supported versions + if !mux_supported { return None; } @@ -518,12 +526,16 @@ fn main() { .filter(|v| v.name != "DISABLE") .map(|v| { let variant_name = format_ident!("{}", v.name); + let clock_name = format_ident!("{}", v.name.to_ascii_lowercase()); - // temporary hack to restrict the scope of the implementation until clock names can be stabilized - let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase()); - - quote! { - #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }, + if v.name.starts_with("HCLK") || v.name.starts_with("PCLK") || v.name == "SYS" { + quote! { + #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name }, + } + } else { + quote! { + #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }, + } } }) .collect(); @@ -552,7 +564,7 @@ fn main() { fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { #before_enable #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_add(_cs); + unsafe { crate::rcc::REFCOUNT_STOP2 += 1 }; crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable #rst @@ -561,7 +573,7 @@ fn main() { #before_disable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(_cs); + unsafe { crate::rcc::REFCOUNT_STOP2 -= 1 }; } } @@ -1007,15 +1019,7 @@ fn main() { // ======== // Generate Div/Mul impls for RCC prescalers/dividers/multipliers. - let rcc_registers = METADATA - .peripherals - .iter() - .filter_map(|p| p.registers.as_ref()) - .find(|r| r.kind == "rcc") - .unwrap() - .ir; - - for e in rcc_registers.enums { + for e in rcc_registers.ir.enums { fn is_rcc_name(e: &str) -> bool { match e { "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true, diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index a3c7823c..3d1a820e 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -564,7 +564,7 @@ foreach_peripheral!( #[cfg(any(rcc_h7, rcc_h7rm0433))] impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { fn frequency() -> crate::time::Hertz { - critical_section::with(|_| unsafe { crate::rcc::get_freqs().apb1 }) + critical_section::with(|_| unsafe { crate::rcc::get_freqs().pclk1 }) } fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 631a9377..13e53f68 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -191,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { // TODO MTU size setting not found for v1 ethernet, check if correct // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called - let hclk = unsafe { crate::rcc::get_freqs() }.ahb1; + let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk_mhz = hclk.0 / 1_000_000; // Set the MDC clock frequency in the range 1MHz - 2.5MHz diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 12cf618a..c77155fe 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -164,7 +164,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { }); // NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called - let hclk = unsafe { crate::rcc::get_freqs() }.ahb1; + let hclk = unsafe { crate::rcc::get_freqs() }.hclk1; let hclk_mhz = hclk.0 / 1_000_000; // Set the MDC clock frequency in the range 1MHz - 2.5MHz diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 81deaa17..3e5959dd 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -465,7 +465,7 @@ pub(crate) fn assert_not_corrupted_read(end_address: u32) { feature = "stm32f439vg", feature = "stm32f439zg", ))] - if second_bank_read && unsafe { pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() } { + if second_bank_read && pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() { panic!("Read corruption for stm32f42xxG and stm32f43xxG in dual bank mode when PA12 is in use for chips below revision 3, see errata 2.2.11"); } } diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index e1702b00..011f4c07 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -763,6 +763,13 @@ pub(crate) unsafe fn init(_cs: CriticalSection) { ::enable_and_reset_with_cs(_cs); crate::_generated::init_gpio(); + + // Setting this bit is mandatory to use PG[15:2]. + #[cfg(stm32u5)] + crate::pac::PWR.svmcr().modify(|w| { + w.set_io2sv(true); + w.set_io2vmen(true); + }); } mod eh02 { diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index 8fd3a8c6..67d40c47 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -170,7 +170,7 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> { let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg); #[cfg(all(rcc_f4, not(stm32f410)))] - let pclk = unsafe { get_freqs() }.plli2s.unwrap(); + let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap(); #[cfg(stm32f410)] let pclk = T::frequency(); diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 1b1e182f..4006dee1 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -5,6 +5,7 @@ use core::task::Poll; use self::sealed::Instance; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; +use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel}; use crate::peripherals::IPCC; use crate::rcc::sealed::RccPeripheral; @@ -273,7 +274,7 @@ fn _configure_pwr() { // set LPTIM1 & LPTIM2 clock source rcc.ccipr().modify(|w| { - w.set_lptim1sel(0b00); // PCLK - w.set_lptim2sel(0b00); // PCLK + w.set_lptim1sel(Lptim1sel::PCLK1); + w.set_lptim2sel(Lptim2sel::PCLK1); }); } diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 372246f8..5c7067d2 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -226,9 +226,9 @@ pub fn init(config: Config) -> Peripherals { time_driver::init(cs); #[cfg(feature = "low-power")] - while !crate::rcc::low_power_ready() { - crate::rcc::clock_refcount_sub(cs); - } + { + crate::rcc::REFCOUNT_STOP2 = 0 + }; } p diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 861a59d7..d5846f53 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -6,7 +6,6 @@ use cortex_m::peripheral::SCB; use embassy_executor::*; use crate::interrupt; -use crate::rcc::low_power_ready; use crate::time_driver::{get_driver, RtcDriver}; const THREAD_PENDER: usize = usize::MAX; @@ -33,6 +32,15 @@ pub fn stop_with_rtc(rtc: &'static Rtc) { unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) } +pub fn stop_ready(stop_mode: StopMode) -> bool { + unsafe { EXECUTOR.as_mut().unwrap() }.stop_ready(stop_mode) +} + +#[non_exhaustive] +pub enum StopMode { + Stop2, +} + /// Thread mode executor, using WFE/SEV. /// /// This is the simplest and most common kind of executor. It runs on @@ -80,12 +88,18 @@ impl Executor { trace!("low power: stop with rtc configured"); } + fn stop_ready(&self, stop_mode: StopMode) -> bool { + match stop_mode { + StopMode::Stop2 => unsafe { crate::rcc::REFCOUNT_STOP2 == 0 }, + } + } + fn configure_pwr(&mut self) { self.scb.clear_sleepdeep(); compiler_fence(Ordering::SeqCst); - if !low_power_ready() { + if !self.stop_ready(StopMode::Stop2) { trace!("low power: not ready to stop"); } else if self.time_driver.pause_time().is_err() { trace!("low power: failed to pause time"); diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index e0fad26e..cb55cbe1 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -101,18 +101,22 @@ pub trait InvertingPin: sealed::InvertingPin {} #[cfg(opamp_f3)] macro_rules! impl_opamp_output { ($inst:ident, $adc:ident, $ch:expr) => { - impl<'d, 'p, P: NonInvertingPin> crate::adc::sealed::AdcPin - for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> - { - fn channel(&self) -> u8 { - $ch - } - } + foreach_adc!( + ($adc, $common_inst:ident, $adc_clock:ident) => { + impl<'d, 'p, P: NonInvertingPin> crate::adc::sealed::AdcPin + for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + { + fn channel(&self) -> u8 { + $ch + } + } - impl<'d, 'p, P: NonInvertingPin> crate::adc::AdcPin - for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> - { - } + impl<'d, 'p, P: NonInvertingPin> crate::adc::AdcPin + for OpAmpOutput<'d, 'p, crate::peripherals::$inst, P> + { + } + }; + ); }; } diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index a7c4b4f9..d20f5818 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -106,7 +106,7 @@ impl LsConfig { pub const fn off() -> Self { Self { - rtc: RtcClockSource::NOCLOCK, + rtc: RtcClockSource::DISABLE, lsi: false, lse: None, } @@ -133,7 +133,7 @@ impl LsConfig { Some(LSI_FREQ) } RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency), - RtcClockSource::NOCLOCK => None, + RtcClockSource::DISABLE => None, _ => todo!(), }; @@ -180,7 +180,7 @@ impl LsConfig { ok &= reg.rtcsel() == self.rtc; #[cfg(not(rcc_wba))] { - ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK); + ok &= reg.rtcen() == (self.rtc != RtcClockSource::DISABLE); } ok &= reg.lseon() == lse_en; ok &= reg.lsebyp() == lse_byp; @@ -225,7 +225,7 @@ impl LsConfig { while !bdcr().read().lserdy() {} } - if self.rtc != RtcClockSource::NOCLOCK { + if self.rtc != RtcClockSource::DISABLE { bdcr().modify(|w| { #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index eeb6418a..68f029ca 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -134,10 +134,12 @@ pub(crate) unsafe fn init(config: Config) { }; set_freqs(Clocks { + hsi: None, + lse: None, sys: sys_clk, - ahb1: ahb_freq, - apb1: apb_freq, - apb1_tim: apb_tim_freq, + hclk1: ahb_freq, + pclk1: apb_freq, + pclk1_tim: apb_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs index cc712e87..feaa2f4c 100644 --- a/embassy-stm32/src/rcc/f0.rs +++ b/embassy-stm32/src/rcc/f0.rs @@ -127,7 +127,7 @@ pub(crate) unsafe fn init(config: Config) { } if config.usb_pll { - RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLLCLK)); + RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLL1_P)); } // TODO: Option to use CRS (Clock Recovery) @@ -140,7 +140,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| { w.set_ppre(Ppre::from_bits(ppre_bits)); w.set_hpre(Hpre::from_bits(hpre_bits)); - w.set_sw(Sw::PLL) + w.set_sw(Sw::PLL1_P) }); } else { RCC.cfgr().modify(|w| { @@ -162,11 +162,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(real_sysclk), - apb1: Hertz(pclk), - apb2: Hertz(pclk), - apb1_tim: Hertz(pclk * timer_mul), - apb2_tim: Hertz(pclk * timer_mul), - ahb1: Hertz(hclk), + pclk1: Hertz(pclk), + pclk2: Hertz(pclk), + pclk1_tim: Hertz(pclk * timer_mul), + pclk2_tim: Hertz(pclk * timer_mul), + hclk1: Hertz(hclk), rtc, }); } diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 56c49cd8..169551e4 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs @@ -102,7 +102,6 @@ pub(crate) unsafe fn init(config: Config) { assert!(pclk2 <= 72_000_000); - // Only needed for stm32f103? FLASH.acr().write(|w| { w.set_latency(if real_sysclk <= 24_000_000 { Latency::WS0 @@ -111,6 +110,8 @@ pub(crate) unsafe fn init(config: Config) { } else { Latency::WS2 }); + // the prefetch buffer is enabled by default, let's keep it enabled + w.set_prftbe(true); }); // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the @@ -168,7 +169,7 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(not(rcc_f100))] w.set_usbpre(Usbpre::from_bits(usbpre as u8)); w.set_sw(if pllmul_bits.is_some() { - Sw::PLL + Sw::PLL1_P } else if config.hse.is_some() { Sw::HSE } else { @@ -180,11 +181,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: Hertz(real_sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), - ahb1: Hertz(hclk), + pclk1: Hertz(pclk1), + pclk2: Hertz(pclk2), + pclk1_tim: Hertz(pclk1 * timer_mul1), + pclk2_tim: Hertz(pclk2 * timer_mul2), + hclk1: Hertz(hclk), adc: Some(Hertz(adcclk)), rtc, }); diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index ab588233..9a66e75a 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -256,7 +256,7 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL => { RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} - (pll_clocks.main_freq, Sw::PLL) + (pll_clocks.main_freq, Sw::PLL1_P) } }; // RM0033 Figure 9. Clock tree suggests max SYSCLK/HCLK is 168 MHz, but datasheet specifies PLL @@ -307,14 +307,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: ahb_freq, - apb1: apb1_freq, - apb1_tim: apb1_tim_freq, - apb2: apb2_freq, - apb2_tim: apb2_tim_freq, - pll48: Some(pll_clocks.pll48_freq), + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk1_tim: apb1_tim_freq, + pclk2: apb2_freq, + pclk2_tim: apb2_tim_freq, + pll1_q: Some(pll_clocks.pll48_freq), rtc, }); } diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 2aa79cec..9dcd50df 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -214,7 +214,7 @@ pub(crate) unsafe fn init(config: Config) { // CFGR has been written before (PLL, PLL48, clock divider) don't overwrite these settings RCC.cfgr().modify(|w| { w.set_sw(match (pll_config, config.hse) { - (Some(_), _) => Sw::PLL, + (Some(_), _) => Sw::PLL1_P, (None, Some(_)) => Sw::HSE, (None, None) => Sw::HSI, }) @@ -271,7 +271,7 @@ pub(crate) unsafe fn init(config: Config) { pll_config.unwrap(); assert!((pclk2 == sysclk) || (pclk2 * 2u32 == sysclk)); - RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL)); + RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL1_P)); Some(sysclk * 2u32) } @@ -281,11 +281,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sysclk, - apb1: pclk1, - apb2: pclk2, - apb1_tim: pclk1 * timer_mul1, - apb2_tim: pclk2 * timer_mul2, - ahb1: hclk, + pclk1: pclk1, + pclk2: pclk2, + pclk1_tim: pclk1 * timer_mul1, + pclk2_tim: pclk2 * timer_mul2, + hclk1: hclk, #[cfg(rcc_f3)] adc: adc, #[cfg(all(rcc_f3, adc3_common))] diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs deleted file mode 100644 index 79c2d2f6..00000000 --- a/embassy-stm32/src/rcc/f4.rs +++ /dev/null @@ -1,396 +0,0 @@ -use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllq, Pllr, Ppre, Sw}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// Clocks configuration -#[non_exhaustive] -#[derive(Default)] -pub struct Config { - pub hse: Option, - pub bypass_hse: bool, - pub hclk: Option, - pub sys_ck: Option, - pub pclk1: Option, - pub pclk2: Option, - - #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] - pub plli2s: Option, - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pub pllsai: Option, - - pub pll48: bool, - pub ls: super::LsConfig, -} - -#[cfg(stm32f410)] -fn setup_i2s_pll(_vco_in: u32, _plli2s: Option) -> Option { - None -} - -// Not currently implemented, but will be in the future -#[cfg(any(stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] -fn setup_i2s_pll(_vco_in: u32, _plli2s: Option) -> Option { - None -} - -#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423)))] -fn calculate_sai_i2s_pll_values(vco_in: u32, max_div: u32, target: Option) -> Option<(u32, u32, u32)> { - let min_div = 2; - let target = match target { - Some(target) => target, - None => return None, - }; - - // We loop through the possible divider values to find the best configuration. Looping - // through all possible "N" values would result in more iterations. - let (n, outdiv, output, _error) = (min_div..=max_div) - .filter_map(|outdiv| { - let target_vco_out = match target.checked_mul(outdiv) { - Some(x) => x, - None => return None, - }; - let n = (target_vco_out + (vco_in >> 1)) / vco_in; - let vco_out = vco_in * n; - if !(100_000_000..=432_000_000).contains(&vco_out) { - return None; - } - let output = vco_out / outdiv; - let error = (output as i32 - target as i32).unsigned_abs(); - Some((n, outdiv, output, error)) - }) - .min_by_key(|(_, _, _, error)| *error)?; - - Some((n, outdiv, output)) -} - -#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] -fn setup_i2s_pll(vco_in: u32, plli2s: Option) -> Option { - let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 7, plli2s)?; - - RCC.plli2scfgr().modify(|w| { - w.set_plli2sn(n as u16); - w.set_plli2sr(outdiv as u8); - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - w.set_plli2sq(outdiv as u8); //set sai divider same as i2s - }); - - Some(output) -} - -#[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] -fn setup_sai_pll(_vco_in: u32, _pllsai: Option) -> Option { - None -} - -#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] -fn setup_sai_pll(vco_in: u32, pllsai: Option) -> Option { - let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 15, pllsai)?; - - RCC.pllsaicfgr().modify(|w| { - w.set_pllsain(n as u16); - w.set_pllsaiq(outdiv as u8); - }); - - Some(output) -} - -fn setup_pll( - pllsrcclk: u32, - use_hse: bool, - pllsysclk: Option, - plli2s: Option, - pllsai: Option, - pll48clk: bool, -) -> PllResults { - use crate::pac::rcc::vals::{Pllp, Pllsrc}; - - let sysclk = pllsysclk.unwrap_or(pllsrcclk); - if pllsysclk.is_none() && !pll48clk { - RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8))); - - return PllResults { - use_pll: false, - pllsysclk: None, - pll48clk: None, - plli2sclk: None, - pllsaiclk: None, - }; - } - // Input divisor from PLL source clock, must result to frequency in - // the range from 1 to 2 MHz - let pllm_min = (pllsrcclk + 1_999_999) / 2_000_000; - let pllm_max = pllsrcclk / 1_000_000; - - // Sysclk output divisor must be one of 2, 4, 6 or 8 - let sysclk_div = core::cmp::min(8, (432_000_000 / sysclk) & !1); - - let target_freq = if pll48clk { 48_000_000 } else { sysclk * sysclk_div }; - - // Find the lowest pllm value that minimize the difference between - // target frequency and the real vco_out frequency. - let pllm = unwrap!((pllm_min..=pllm_max).min_by_key(|pllm| { - let vco_in = pllsrcclk / pllm; - let plln = target_freq / vco_in; - target_freq - vco_in * plln - })); - - let vco_in = pllsrcclk / pllm; - assert!((1_000_000..=2_000_000).contains(&vco_in)); - - // Main scaler, must result in >= 100MHz (>= 192MHz for F401) - // and <= 432MHz, min 50, max 432 - let plln = if pll48clk { - // try the different valid pllq according to the valid - // main scaller values, and take the best - let pllq = unwrap!((4..=9).min_by_key(|pllq| { - let plln = 48_000_000 * pllq / vco_in; - let pll48_diff = 48_000_000 - vco_in * plln / pllq; - let sysclk_diff = (sysclk as i32 - (vco_in * plln / sysclk_div) as i32).abs(); - (pll48_diff, sysclk_diff) - })); - 48_000_000 * pllq / vco_in - } else { - sysclk * sysclk_div / vco_in - }; - - let pllp = (sysclk_div / 2) - 1; - - let pllq = (vco_in * plln + 47_999_999) / 48_000_000; - let real_pll48clk = vco_in * plln / pllq; - - RCC.pllcfgr().modify(|w| { - w.set_pllm(Pllm::from_bits(pllm as u8)); - w.set_plln(Plln::from_bits(plln as u16)); - w.set_pllp(Pllp::from_bits(pllp as u8)); - w.set_pllq(Pllq::from_bits(pllq as u8)); - w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); - w.set_pllr(Pllr::from_bits(0)); - }); - - let real_pllsysclk = vco_in * plln / sysclk_div; - - PllResults { - use_pll: true, - pllsysclk: Some(real_pllsysclk), - pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, - plli2sclk: setup_i2s_pll(vco_in, plli2s), - pllsaiclk: setup_sai_pll(vco_in, pllsai), - } -} - -fn flash_setup(sysclk: u32) { - use crate::pac::flash::vals::Latency; - - // Be conservative with voltage ranges - const FLASH_LATENCY_STEP: u32 = 30_000_000; - - critical_section::with(|_| { - FLASH - .acr() - .modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8))); - }); -} - -pub(crate) unsafe fn init(config: Config) { - let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0); - let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); - let sysclk_on_pll = sysclk != pllsrcclk; - - let plls = setup_pll( - pllsrcclk, - config.hse.is_some(), - if sysclk_on_pll { Some(sysclk) } else { None }, - #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] - config.plli2s.map(|i2s| i2s.0), - #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] - None, - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - config.pllsai.map(|sai| sai.0), - #[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] - None, - config.pll48, - ); - - if config.pll48 { - let freq = unwrap!(plls.pll48clk); - - assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); - } - - let sysclk = if sysclk_on_pll { unwrap!(plls.pllsysclk) } else { sysclk }; - - // AHB prescaler - let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); - let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk { - 0 => unreachable!(), - 1 => (Hpre::DIV1, 1), - 2 => (Hpre::DIV2, 2), - 3..=5 => (Hpre::DIV4, 4), - 6..=11 => (Hpre::DIV8, 8), - 12..=39 => (Hpre::DIV16, 16), - 40..=95 => (Hpre::DIV64, 64), - 96..=191 => (Hpre::DIV128, 128), - 192..=383 => (Hpre::DIV256, 256), - _ => (Hpre::DIV512, 512), - }; - - // Calculate real AHB clock - let hclk = sysclk / hpre_div; - - let pclk1 = config - .pclk1 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); - - let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; - - // Calculate real APB1 clock - let pclk1 = hclk / ppre1; - assert!(pclk1 <= max::PCLK1_MAX); - - let pclk2 = config - .pclk2 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK2_MAX, hclk)); - let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; - - // Calculate real APB2 clock - let pclk2 = hclk / ppre2; - assert!(pclk2 <= max::PCLK2_MAX); - - flash_setup(sysclk); - - if config.hse.is_some() { - RCC.cr().modify(|w| { - w.set_hsebyp(config.bypass_hse); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - - if plls.use_pll { - RCC.cr().modify(|w| w.set_pllon(true)); - - if hclk > max::HCLK_OVERDRIVE_FREQUENCY { - PWR.cr1().modify(|w| w.set_oden(true)); - while !PWR.csr1().read().odrdy() {} - - PWR.cr1().modify(|w| w.set_odswen(true)); - while !PWR.csr1().read().odswrdy() {} - } - - while !RCC.cr().read().pllrdy() {} - } - - #[cfg(not(stm32f410))] - if plls.plli2sclk.is_some() { - RCC.cr().modify(|w| w.set_plli2son(true)); - - while !RCC.cr().read().plli2srdy() {} - } - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - if plls.pllsaiclk.is_some() { - RCC.cr().modify(|w| w.set_pllsaion(true)); - while !RCC.cr().read().pllsairdy() {} - } - - RCC.cfgr().modify(|w| { - w.set_ppre2(Ppre::from_bits(ppre2_bits)); - w.set_ppre1(Ppre::from_bits(ppre1_bits)); - w.set_hpre(hpre_bits); - }); - - // Wait for the new prescalers to kick in - // "The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after write" - cortex_m::asm::delay(16); - - RCC.cfgr().modify(|w| { - w.set_sw(if sysclk_on_pll { - Sw::PLL - } else if config.hse.is_some() { - Sw::HSE - } else { - Sw::HSI - }) - }); - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: Hertz(sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), - - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), - - ahb1: Hertz(hclk), - ahb2: Hertz(hclk), - ahb3: Hertz(hclk), - - pll48: plls.pll48clk.map(Hertz), - - #[cfg(not(stm32f410))] - plli2s: plls.plli2sclk.map(Hertz), - - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pllsai: plls.pllsaiclk.map(Hertz), - - rtc, - }); -} - -struct PllResults { - use_pll: bool, - pllsysclk: Option, - pll48clk: Option, - #[allow(dead_code)] - plli2sclk: Option, - #[allow(dead_code)] - pllsaiclk: Option, -} - -mod max { - #[cfg(stm32f401)] - pub(crate) const SYSCLK_MAX: u32 = 84_000_000; - #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] - pub(crate) const SYSCLK_MAX: u32 = 168_000_000; - #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] - pub(crate) const SYSCLK_MAX: u32 = 100_000_000; - #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,))] - pub(crate) const SYSCLK_MAX: u32 = 180_000_000; - - pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 168_000_000; - - pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2; - - #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX; - #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - - pub(crate) const PLL_48_CLK: u32 = 48_000_000; - pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; -} diff --git a/embassy-stm32/src/rcc/f4f7.rs b/embassy-stm32/src/rcc/f4f7.rs new file mode 100644 index 00000000..3102600a --- /dev/null +++ b/embassy-stm32/src/rcc/f4f7.rs @@ -0,0 +1,387 @@ +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp, Pllq, Pllr, Pllsrc as PllSource, + Ppre as APBPrescaler, Sw as Sysclk, +}; +use crate::pac::{FLASH, RCC}; +use crate::rcc::{set_freqs, Clocks}; +use crate::time::Hertz; + +// TODO: on some F4s, PLLM is shared between all PLLs. Enforce that. +// TODO: on some F4s, add support for plli2s_src +// +// plli2s plli2s_m plli2s_src pllsai pllsai_m +// f401 y shared +// f410 +// f411 y individual +// f412 y individual y +// f4[12]3 y individual y +// f446 y individual y individual +// f4[67]9 y shared y shared +// f4[23][79] y shared y shared +// f4[01][57] y shared + +/// HSI speed +pub const HSI_FREQ: Hertz = Hertz(16_000_000); + +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum HseMode { + /// crystal/ceramic oscillator (HSEBYP=0) + Oscillator, + /// external analog clock (low swing) (HSEBYP=1) + Bypass, +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Hse { + /// HSE frequency. + pub freq: Hertz, + /// HSE mode. + pub mode: HseMode, +} + +#[derive(Clone, Copy)] +pub struct Pll { + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL P division factor. If None, PLL P output is disabled. + pub divp: Option, + /// PLL Q division factor. If None, PLL Q output is disabled. + pub divq: Option, + /// PLL R division factor. If None, PLL R output is disabled. + pub divr: Option, +} + +/// Configuration of the core clocks +#[non_exhaustive] +pub struct Config { + pub hsi: bool, + pub hse: Option, + pub sys: Sysclk, + + pub pll_src: PllSource, + + pub pll: Option, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + pub plli2s: Option, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + pub pllsai: Option, + + pub ahb_pre: AHBPrescaler, + pub apb1_pre: APBPrescaler, + pub apb2_pre: APBPrescaler, + + pub ls: super::LsConfig, +} + +impl Default for Config { + fn default() -> Self { + Self { + hsi: true, + hse: None, + sys: Sysclk::HSI, + pll_src: PllSource::HSI, + pll: None, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + plli2s: None, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + pllsai: None, + + ahb_pre: AHBPrescaler::DIV1, + apb1_pre: APBPrescaler::DIV1, + apb2_pre: APBPrescaler::DIV1, + + ls: Default::default(), + } + } +} + +pub(crate) unsafe fn init(config: Config) { + // always enable overdrive for now. Make it configurable in the future. + #[cfg(not(any( + stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f405, stm32f407, stm32f415, stm32f417 + )))] + { + use crate::pac::PWR; + PWR.cr1().modify(|w| w.set_oden(true)); + while !PWR.csr1().read().odrdy() {} + + PWR.cr1().modify(|w| w.set_odswen(true)); + while !PWR.csr1().read().odswrdy() {} + } + + // Configure HSI + let hsi = match config.hsi { + false => { + RCC.cr().modify(|w| w.set_hsion(false)); + None + } + true => { + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + Some(HSI_FREQ) + } + }; + + // Configure HSE + let hse = match config.hse { + None => { + RCC.cr().modify(|w| w.set_hseon(false)); + None + } + Some(hse) => { + match hse.mode { + HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), + HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), + } + + RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); + RCC.cr().modify(|w| w.set_hseon(true)); + while !RCC.cr().read().hserdy() {} + Some(hse.freq) + } + }; + + // Configure PLLs. + let pll_input = PllInput { + hse, + hsi, + source: config.pll_src, + }; + let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + #[cfg(any(all(stm32f4, not(any(stm32f410, stm32f429))), stm32f7))] + let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); + #[cfg(all(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7), not(stm32f429)))] + let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); + + // Configure sysclk + let sys = match config.sys { + Sysclk::HSI => unwrap!(hsi), + Sysclk::HSE => unwrap!(hse), + Sysclk::PLL1_P => unwrap!(pll.p), + _ => unreachable!(), + }; + + let hclk = sys / config.ahb_pre; + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); + + assert!(max::SYSCLK.contains(&sys)); + assert!(max::HCLK.contains(&hclk)); + assert!(max::PCLK1.contains(&pclk1)); + assert!(max::PCLK2.contains(&pclk2)); + + let rtc = config.ls.init(); + + flash_setup(hclk); + + RCC.cfgr().modify(|w| { + w.set_sw(config.sys); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); + }); + while RCC.cfgr().read().sws() != config.sys {} + + set_freqs(Clocks { + sys, + hclk1: hclk, + hclk2: hclk, + hclk3: hclk, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, + rtc, + pll1_q: pll.q, + #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] + plli2s1_q: _plli2s.q, + #[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))] + plli2s1_r: _plli2s.r, + + #[cfg(stm32f429)] + plli2s1_q: None, + #[cfg(stm32f429)] + plli2s1_r: None, + + #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pllsai1_q: _pllsai.q, + #[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pllsai1_r: _pllsai.r, + + #[cfg(stm32f429)] + pllsai1_q: None, + #[cfg(stm32f429)] + pllsai1_r: None, + }); +} + +struct PllInput { + source: PllSource, + hsi: Option, + hse: Option, +} + +#[derive(Default)] +#[allow(unused)] +struct PllOutput { + p: Option, + q: Option, + r: Option, +} + +#[allow(dead_code)] +#[derive(PartialEq, Eq, Clone, Copy)] +enum PllInstance { + Pll, + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + Plli2s, + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + Pllsai, +} + +fn pll_enable(instance: PllInstance, enabled: bool) { + match instance { + PllInstance::Pll => { + RCC.cr().modify(|w| w.set_pllon(enabled)); + while RCC.cr().read().pllrdy() != enabled {} + } + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + PllInstance::Plli2s => { + RCC.cr().modify(|w| w.set_plli2son(enabled)); + while RCC.cr().read().plli2srdy() != enabled {} + } + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + PllInstance::Pllsai => { + RCC.cr().modify(|w| w.set_pllsaion(enabled)); + while RCC.cr().read().pllsairdy() != enabled {} + } + } +} + +fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match input.source { + PllSource::HSE => input.hse, + PllSource::HSI => input.hsi, + }; + + let pll_src = pll_src.unwrap(); + + let in_freq = pll_src / pll.prediv; + assert!(max::PLL_IN.contains(&in_freq)); + let vco_freq = in_freq * pll.mul; + assert!(max::PLL_VCO.contains(&vco_freq)); + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(input.source); + write_fields!(w); + }), + #[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))] + PllInstance::Plli2s => RCC.plli2scfgr().write(|w| { + write_fields!(w); + }), + #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] + PllInstance::Pllsai => RCC.pllsaicfgr().write(|w| { + write_fields!(w); + }), + } + + // Enable PLL + pll_enable(instance, true); + + PllOutput { p, q, r } +} + +fn flash_setup(clk: Hertz) { + use crate::pac::flash::vals::Latency; + + // Be conservative with voltage ranges + const FLASH_LATENCY_STEP: u32 = 30_000_000; + + let latency = (clk.0 - 1) / FLASH_LATENCY_STEP; + debug!("flash: latency={}", latency); + + let latency = Latency::from_bits(latency as u8); + FLASH.acr().write(|w| { + w.set_latency(latency); + }); + while FLASH.acr().read().latency() != latency {} +} + +#[cfg(stm32f7)] +mod max { + use core::ops::RangeInclusive; + + use crate::time::Hertz; + + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(50_000_000); + + pub(crate) const SYSCLK: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000); + pub(crate) const HCLK: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000); + pub(crate) const PCLK1: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000 / 4); + pub(crate) const PCLK2: RangeInclusive = Hertz(12_500_000)..=Hertz(216_000_000 / 2); + + pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); +} + +#[cfg(stm32f4)] +mod max { + use core::ops::RangeInclusive; + + use crate::time::Hertz; + + pub(crate) const HSE_OSC: RangeInclusive = Hertz(4_000_000)..=Hertz(26_000_000); + pub(crate) const HSE_BYP: RangeInclusive = Hertz(1_000_000)..=Hertz(50_000_000); + + #[cfg(stm32f401)] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(84_000_000); + #[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(168_000_000); + #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(100_000_000); + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,))] + pub(crate) const SYSCLK: RangeInclusive = Hertz(0)..=Hertz(180_000_000); + + pub(crate) const HCLK: RangeInclusive = Hertz(0)..=Hertz(SYSCLK.end().0); + + pub(crate) const PCLK1: RangeInclusive = Hertz(0)..=Hertz(PCLK2.end().0 / 2); + + #[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))] + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(HCLK.end().0); + #[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))] + pub(crate) const PCLK2: RangeInclusive = Hertz(0)..=Hertz(HCLK.end().0 / 2); + + pub(crate) const PLL_IN: RangeInclusive = Hertz(1_000_000)..=Hertz(2_100_000); + pub(crate) const PLL_VCO: RangeInclusive = Hertz(100_000_000)..=Hertz(432_000_000); +} diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs deleted file mode 100644 index 0a0a1cf2..00000000 --- a/embassy-stm32/src/rcc/f7.rs +++ /dev/null @@ -1,305 +0,0 @@ -use crate::pac::pwr::vals::Vos; -use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// Clocks configuration -#[non_exhaustive] -#[derive(Default)] -pub struct Config { - pub hse: Option, - pub bypass_hse: bool, - pub hclk: Option, - pub sys_ck: Option, - pub pclk1: Option, - pub pclk2: Option, - - pub pll48: bool, - pub ls: super::LsConfig, -} - -fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option, pll48clk: bool) -> PllResults { - let sysclk = pllsysclk.unwrap_or(pllsrcclk); - if pllsysclk.is_none() && !pll48clk { - RCC.pllcfgr().modify(|w| w.set_pllsrc(Pllsrc::from_bits(use_hse as u8))); - - return PllResults { - use_pll: false, - pllsysclk: None, - pll48clk: None, - }; - } - // Input divisor from PLL source clock, must result to frequency in - // the range from 1 to 2 MHz - let pllm_min = (pllsrcclk + 1_999_999) / 2_000_000; - let pllm_max = pllsrcclk / 1_000_000; - - // Sysclk output divisor must be one of 2, 4, 6 or 8 - let sysclk_div = core::cmp::min(8, (432_000_000 / sysclk) & !1); - - let target_freq = if pll48clk { 48_000_000 } else { sysclk * sysclk_div }; - - // Find the lowest pllm value that minimize the difference between - // target frequency and the real vco_out frequency. - let pllm = unwrap!((pllm_min..=pllm_max).min_by_key(|pllm| { - let vco_in = pllsrcclk / pllm; - let plln = target_freq / vco_in; - target_freq - vco_in * plln - })); - - let vco_in = pllsrcclk / pllm; - assert!((1_000_000..=2_000_000).contains(&vco_in)); - - // Main scaler, must result in >= 100MHz (>= 192MHz for F401) - // and <= 432MHz, min 50, max 432 - let plln = if pll48clk { - // try the different valid pllq according to the valid - // main scaller values, and take the best - let pllq = unwrap!((4..=9).min_by_key(|pllq| { - let plln = 48_000_000 * pllq / vco_in; - let pll48_diff = 48_000_000 - vco_in * plln / pllq; - let sysclk_diff = (sysclk as i32 - (vco_in * plln / sysclk_div) as i32).abs(); - (pll48_diff, sysclk_diff) - })); - 48_000_000 * pllq / vco_in - } else { - sysclk * sysclk_div / vco_in - }; - - let pllp = (sysclk_div / 2) - 1; - - let pllq = (vco_in * plln + 47_999_999) / 48_000_000; - let real_pll48clk = vco_in * plln / pllq; - - RCC.pllcfgr().modify(|w| { - w.set_pllm(Pllm::from_bits(pllm as u8)); - w.set_plln(Plln::from_bits(plln as u16)); - w.set_pllp(Pllp::from_bits(pllp as u8)); - w.set_pllq(Pllq::from_bits(pllq as u8)); - w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); - }); - - let real_pllsysclk = vco_in * plln / sysclk_div; - - PllResults { - use_pll: true, - pllsysclk: Some(real_pllsysclk), - pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, - } -} - -fn flash_setup(sysclk: u32) { - use crate::pac::flash::vals::Latency; - - // Be conservative with voltage ranges - const FLASH_LATENCY_STEP: u32 = 30_000_000; - - critical_section::with(|_| { - FLASH - .acr() - .modify(|w| w.set_latency(Latency::from_bits(((sysclk - 1) / FLASH_LATENCY_STEP) as u8))); - }); -} - -pub(crate) unsafe fn init(config: Config) { - if let Some(hse) = config.hse { - if config.bypass_hse { - assert!((max::HSE_BYPASS_MIN..=max::HSE_BYPASS_MAX).contains(&hse.0)); - } else { - assert!((max::HSE_OSC_MIN..=max::HSE_OSC_MAX).contains(&hse.0)); - } - } - - let pllsrcclk = config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0); - let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); - let sysclk_on_pll = sysclk != pllsrcclk; - - assert!((max::SYSCLK_MIN..=max::SYSCLK_MAX).contains(&sysclk)); - - let plls = setup_pll( - pllsrcclk, - config.hse.is_some(), - if sysclk_on_pll { Some(sysclk) } else { None }, - config.pll48, - ); - - if config.pll48 { - let freq = unwrap!(plls.pll48clk); - - assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32); - } - - let sysclk = if sysclk_on_pll { unwrap!(plls.pllsysclk) } else { sysclk }; - - // AHB prescaler - let hclk = config.hclk.map(|h| h.0).unwrap_or(sysclk); - let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk { - 0 => unreachable!(), - 1 => (Hpre::DIV1, 1), - 2 => (Hpre::DIV2, 2), - 3..=5 => (Hpre::DIV4, 4), - 6..=11 => (Hpre::DIV8, 8), - 12..=39 => (Hpre::DIV16, 16), - 40..=95 => (Hpre::DIV64, 64), - 96..=191 => (Hpre::DIV128, 128), - 192..=383 => (Hpre::DIV256, 256), - _ => (Hpre::DIV512, 512), - }; - - // Calculate real AHB clock - let hclk = sysclk / hpre_div; - - assert!(hclk <= max::HCLK_MAX); - - let pclk1 = config - .pclk1 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk)); - - let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; - - // Calculate real APB1 clock - let pclk1 = hclk / ppre1; - assert!((max::PCLK1_MIN..=max::PCLK1_MAX).contains(&pclk1)); - - let pclk2 = config - .pclk2 - .map(|p| p.0) - .unwrap_or_else(|| core::cmp::min(max::PCLK2_MAX, hclk)); - let (ppre2_bits, ppre2) = match (hclk + pclk2 - 1) / pclk2 { - 0 => unreachable!(), - 1 => (0b000, 1), - 2 => (0b100, 2), - 3..=5 => (0b101, 4), - 6..=11 => (0b110, 8), - _ => (0b111, 16), - }; - let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; - - // Calculate real APB2 clock - let pclk2 = hclk / ppre2; - assert!((max::PCLK2_MIN..=max::PCLK2_MAX).contains(&pclk2)); - - flash_setup(sysclk); - - if config.hse.is_some() { - RCC.cr().modify(|w| { - w.set_hsebyp(config.bypass_hse); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - - if plls.use_pll { - RCC.cr().modify(|w| w.set_pllon(false)); - - // setup VOSScale - let vos_scale = if sysclk <= 144_000_000 { - 3 - } else if sysclk <= 168_000_000 { - 2 - } else { - 1 - }; - PWR.cr1().modify(|w| { - w.set_vos(match vos_scale { - 3 => Vos::SCALE3, - 2 => Vos::SCALE2, - 1 => Vos::SCALE1, - _ => panic!("Invalid VOS Scale."), - }) - }); - - RCC.cr().modify(|w| w.set_pllon(true)); - - if hclk > max::HCLK_OVERDRIVE_FREQUENCY { - PWR.cr1().modify(|w| w.set_oden(true)); - while !PWR.csr1().read().odrdy() {} - - PWR.cr1().modify(|w| w.set_odswen(true)); - while !PWR.csr1().read().odswrdy() {} - } - - while !RCC.cr().read().pllrdy() {} - } - - RCC.cfgr().modify(|w| { - w.set_ppre2(Ppre::from_bits(ppre2_bits)); - w.set_ppre1(Ppre::from_bits(ppre1_bits)); - w.set_hpre(hpre_bits); - }); - - // Wait for the new prescalers to kick in - // "The clocks are divided with the new prescaler factor from 1 to 16 AHB cycles after write" - cortex_m::asm::delay(16); - - RCC.cfgr().modify(|w| { - w.set_sw(if sysclk_on_pll { - Sw::PLL - } else if config.hse.is_some() { - Sw::HSE - } else { - Sw::HSI - }) - }); - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: Hertz(sysclk), - apb1: Hertz(pclk1), - apb2: Hertz(pclk2), - - apb1_tim: Hertz(pclk1 * timer_mul1), - apb2_tim: Hertz(pclk2 * timer_mul2), - - ahb1: Hertz(hclk), - ahb2: Hertz(hclk), - ahb3: Hertz(hclk), - - pll48: plls.pll48clk.map(Hertz), - - rtc, - }); -} - -struct PllResults { - use_pll: bool, - pllsysclk: Option, - pll48clk: Option, -} - -mod max { - pub(crate) const HSE_OSC_MIN: u32 = 4_000_000; - pub(crate) const HSE_OSC_MAX: u32 = 26_000_000; - pub(crate) const HSE_BYPASS_MIN: u32 = 1_000_000; - pub(crate) const HSE_BYPASS_MAX: u32 = 50_000_000; - - pub(crate) const HCLK_MAX: u32 = 216_000_000; - pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 180_000_000; - - pub(crate) const SYSCLK_MIN: u32 = 12_500_000; - pub(crate) const SYSCLK_MAX: u32 = 216_000_000; - - pub(crate) const PCLK1_MIN: u32 = SYSCLK_MIN; - pub(crate) const PCLK1_MAX: u32 = SYSCLK_MAX / 4; - - pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN; - pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2; - - // USB specification allows +-0.25% - pub(crate) const PLL_48_CLK: u32 = 48_000_000; - pub(crate) const PLL_48_TOLERANCE: u32 = 120_000; -} diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 962b1dc0..45d41a4e 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -1,7 +1,7 @@ use crate::pac::flash::vals::Latency; use crate::pac::rcc::vals::{self, Sw}; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Hsidiv as HSI16Prescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, + Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, }; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -14,7 +14,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); #[derive(Clone, Copy)] pub enum ClockSrc { HSE(Hertz), - HSI16(HSI16Prescaler), + HSI(HSIPrescaler), PLL(PllConfig), LSI, } @@ -46,9 +46,9 @@ pub struct PllConfig { impl Default for PllConfig { #[inline] fn default() -> PllConfig { - // HSI16 / 1 * 8 / 2 = 64 MHz + // HSI / 1 * 8 / 2 = 64 MHz PllConfig { - source: PllSrc::HSI16, + source: PllSrc::HSI, m: Pllm::DIV1, n: Plln::MUL8, r: Pllr::DIV2, @@ -60,7 +60,7 @@ impl Default for PllConfig { #[derive(Clone, Copy, Eq, PartialEq)] pub enum PllSrc { - HSI16, + HSI, HSE(Hertz), } @@ -77,7 +77,7 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16(HSI16Prescaler::DIV1), + mux: ClockSrc::HSI(HSIPrescaler::DIV1), ahb_pre: AHBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1, low_power_run: false, @@ -89,7 +89,7 @@ impl Default for Config { impl PllConfig { pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI16 => (vals::Pllsrc::HSI16, HSI_FREQ), + PllSrc::HSI => (vals::Pllsrc::HSI, HSI_FREQ), PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), }; @@ -121,7 +121,7 @@ impl PllConfig { // > 3. Change the desired parameter. // Enable whichever clock source we're using, and wait for it to become ready match self.source { - PllSrc::HSI16 => { + PllSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } @@ -167,8 +167,8 @@ impl PllConfig { pub(crate) unsafe fn init(config: Config) { let (sys_clk, sw) = match config.mux { - ClockSrc::HSI16(div) => { - // Enable HSI16 + ClockSrc::HSI(div) => { + // Enable HSI RCC.cr().write(|w| { w.set_hsidiv(div); w.set_hsion(true) @@ -186,7 +186,7 @@ pub(crate) unsafe fn init(config: Config) { } ClockSrc::PLL(pll) => { let freq = pll.init(); - (freq, Sw::PLLRCLK) + (freq, Sw::PLL1_R) } ClockSrc::LSI => { // Enable LSI @@ -275,9 +275,9 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - apb1: apb_freq, - apb1_tim: apb_tim_freq, + hclk1: ahb_freq, + pclk1: apb_freq, + pclk1_tim: apb_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index afdf5cc7..b14a6197 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -18,14 +18,14 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); #[derive(Clone, Copy)] pub enum ClockSrc { HSE(Hertz), - HSI16, + HSI, PLL, } /// PLL clock input source #[derive(Clone, Copy, Debug)] pub enum PllSrc { - HSI16, + HSI, HSE(Hertz), } @@ -33,7 +33,7 @@ impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -112,15 +112,15 @@ impl Default for Config { #[inline] fn default() -> Config { Config { - mux: ClockSrc::HSI16, + mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, low_power_run: false, pll: None, - clock_48mhz_src: None, - adc12_clock_source: Adcsel::NOCLK, - adc345_clock_source: Adcsel::NOCLK, + clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(None)), + adc12_clock_source: Adcsel::DISABLE, + adc345_clock_source: Adcsel::DISABLE, ls: Default::default(), } } @@ -135,7 +135,7 @@ pub struct PllFreq { pub(crate) unsafe fn init(config: Config) { let pll_freq = config.pll.map(|pll_config| { let src_freq = match pll_config.source { - PllSrc::HSI16 => { + PllSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -196,12 +196,12 @@ pub(crate) unsafe fn init(config: Config) { }); let (sys_clk, sw) = match config.mux { - ClockSrc::HSI16 => { - // Enable HSI16 + ClockSrc::HSI => { + // Enable HSI RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} - (HSI_FREQ, Sw::HSI16) + (HSI_FREQ, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE @@ -249,7 +249,7 @@ pub(crate) unsafe fn init(config: Config) { } } - (Hertz(freq), Sw::PLLRCLK) + (Hertz(freq), Sw::PLL1_R) } }; @@ -286,7 +286,7 @@ pub(crate) unsafe fn init(config: Config) { let pllq_freq = pll_freq.as_ref().and_then(|f| f.pll_q); assert!(pllq_freq.is_some() && pllq_freq.unwrap().0 == 48_000_000); - crate::pac::rcc::vals::Clk48sel::PLLQCLK + crate::pac::rcc::vals::Clk48sel::PLL1_Q } Clock48MhzSrc::Hsi48(crs_config) => { // Enable HSI48 @@ -326,16 +326,16 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source)); let adc12_ck = match config.adc12_clock_source { - AdcClockSource::NOCLK => None, - AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, - AdcClockSource::SYSCLK => Some(sys_clk), + AdcClockSource::DISABLE => None, + AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYS => Some(sys_clk), _ => unreachable!(), }; let adc345_ck = match config.adc345_clock_source { - AdcClockSource::NOCLK => None, - AdcClockSource::PLLP => pll_freq.as_ref().unwrap().pll_p, - AdcClockSource::SYSCLK => Some(sys_clk), + AdcClockSource::DISABLE => None, + AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p, + AdcClockSource::SYS => Some(sys_clk), _ => unreachable!(), }; @@ -348,14 +348,15 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - apb1: apb1_freq, - apb1_tim: apb1_tim_freq, - apb2: apb2_freq, - apb2_tim: apb2_tim_freq, + hclk1: ahb_freq, + hclk2: ahb_freq, + pclk1: apb1_freq, + pclk1_tim: apb1_tim_freq, + pclk2: apb2_freq, + pclk2_tim: apb2_tim_freq, adc: adc12_ck, adc34: adc345_ck, + pll1_p: None, rtc, }); } diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 379d3179..7e924f0a 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs @@ -6,8 +6,11 @@ use crate::pac::pwr::vals::Vos; pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource; #[cfg(stm32h7)] pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; -use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; -pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; +pub use crate::pac::rcc::vals::{ + Ckpersel as PerClockSource, Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, + Pllsrc as PllSource, Sw as Sysclk, +}; +use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre}; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -58,50 +61,9 @@ pub struct Hse { pub mode: HseMode, } -#[cfg(stm32h7)] -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum Lse { - /// 32.768 kHz crystal/ceramic oscillator (LSEBYP=0) - Oscillator, - /// external clock input up to 1MHz (LSEBYP=1) - Bypass(Hertz), -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum Hsi { - /// 64Mhz - Mhz64, - /// 32Mhz (divided by 2) - Mhz32, - /// 16Mhz (divided by 4) - Mhz16, - /// 8Mhz (divided by 8) - Mhz8, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum Sysclk { - /// HSI selected as sysclk - HSI, - /// HSE selected as sysclk - HSE, - /// CSI selected as sysclk - CSI, - /// PLL1_P selected as sysclk - Pll1P, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum PllSource { - Hsi, - Csi, - Hse, -} - #[derive(Clone, Copy)] pub struct Pll { /// Source clock selection. - #[cfg(stm32h5)] pub source: PllSource, /// PLL pre-divider (DIVM). @@ -161,19 +123,12 @@ impl From for Timpre { /// Configuration of the core clocks #[non_exhaustive] pub struct Config { - pub hsi: Option, + pub hsi: Option, pub hse: Option, - #[cfg(stm32h7)] - pub lse: Option, - #[cfg(stm32h7)] - pub lsi: bool, pub csi: bool, pub hsi48: bool, pub sys: Sysclk, - #[cfg(stm32h7)] - pub pll_src: PllSource, - pub pll1: Option, pub pll2: Option, #[cfg(any(rcc_h5, stm32h7))] @@ -197,17 +152,11 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { - hsi: Some(Hsi::Mhz64), + hsi: Some(HSIPrescaler::DIV1), hse: None, - #[cfg(stm32h7)] - lse: None, - #[cfg(stm32h7)] - lsi: false, csi: false, hsi48: false, sys: Sysclk::HSI, - #[cfg(stm32h7)] - pll_src: PllSource::Hsi, pll1: None, pll2: None, #[cfg(any(rcc_h5, stm32h7))] @@ -320,19 +269,13 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_hsion(false)); None } - Some(hsi) => { - let (freq, hsidiv) = match hsi { - Hsi::Mhz64 => (HSI_FREQ / 1u32, Hsidiv::DIV1), - Hsi::Mhz32 => (HSI_FREQ / 2u32, Hsidiv::DIV2), - Hsi::Mhz16 => (HSI_FREQ / 4u32, Hsidiv::DIV4), - Hsi::Mhz8 => (HSI_FREQ / 8u32, Hsidiv::DIV8), - }; + Some(hsidiv) => { RCC.cr().modify(|w| { w.set_hsidiv(hsidiv); w.set_hsion(true); }); while !RCC.cr().read().hsirdy() {} - Some(freq) + Some(HSI_FREQ / hsidiv) } }; @@ -377,25 +320,29 @@ pub(crate) unsafe fn init(config: Config) { } }; + // H7 has shared PLLSRC, check it's equal in all PLLs. + #[cfg(stm32h7)] + { + let plls = [&config.pll1, &config.pll2, &config.pll3]; + if !super::util::all_equal(plls.into_iter().flatten().map(|p| p.source)) { + panic!("Source must be equal across all enabled PLLs.") + }; + } + // Configure PLLs. - let pll_input = PllInput { - csi, - hse, - hsi, - #[cfg(stm32h7)] - source: config.pll_src, - }; + let pll_input = PllInput { csi, hse, hsi }; let pll1 = init_pll(0, config.pll1, &pll_input); let pll2 = init_pll(1, config.pll2, &pll_input); #[cfg(any(rcc_h5, stm32h7))] let pll3 = init_pll(2, config.pll3, &pll_input); // Configure sysclk - let (sys, sw) = match config.sys { - Sysclk::HSI => (unwrap!(hsi), Sw::HSI), - Sysclk::HSE => (unwrap!(hse), Sw::HSE), - Sysclk::CSI => (unwrap!(csi), Sw::CSI), - Sysclk::Pll1P => (unwrap!(pll1.p), Sw::PLL1), + let sys = match config.sys { + Sysclk::HSI => unwrap!(hsi), + Sysclk::HSE => unwrap!(hse), + Sysclk::CSI => unwrap!(csi), + Sysclk::PLL1_P => unwrap!(pll1.p), + _ => unreachable!(), }; // Check limits. @@ -406,7 +353,14 @@ pub(crate) unsafe fn init(config: Config) { VoltageScale::Scale2 => (Hertz(150_000_000), Hertz(150_000_000)), VoltageScale::Scale3 => (Hertz(100_000_000), Hertz(100_000_000)), }; - #[cfg(stm32h7)] + #[cfg(pwr_h7rm0455)] + let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { + VoltageScale::Scale0 => (Hertz(280_000_000), Hertz(280_000_000), Hertz(140_000_000)), + VoltageScale::Scale1 => (Hertz(225_000_000), Hertz(225_000_000), Hertz(112_500_000)), + VoltageScale::Scale2 => (Hertz(160_000_000), Hertz(160_000_000), Hertz(80_000_000)), + VoltageScale::Scale3 => (Hertz(88_000_000), Hertz(88_000_000), Hertz(44_000_000)), + }; + #[cfg(all(stm32h7, not(pwr_h7rm0455)))] let (d1cpre_clk_max, hclk_max, pclk_max) = match config.voltage_scale { VoltageScale::Scale0 => (Hertz(480_000_000), Hertz(240_000_000), Hertz(120_000_000)), VoltageScale::Scale1 => (Hertz(400_000_000), Hertz(200_000_000), Hertz(100_000_000)), @@ -453,8 +407,8 @@ pub(crate) unsafe fn init(config: Config) { }; #[cfg(stm32h5)] let adc = match config.adc_clock_source { - AdcClockSource::HCLK => Some(hclk), - AdcClockSource::SYSCLK => Some(sys), + AdcClockSource::HCLK1 => Some(hclk), + AdcClockSource::SYS => Some(sys), AdcClockSource::PLL2_R => pll2.r, AdcClockSource::HSE => hse, AdcClockSource::HSI => hsi, @@ -512,8 +466,8 @@ pub(crate) unsafe fn init(config: Config) { RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into())); - RCC.cfgr().modify(|w| w.set_sw(sw)); - while RCC.cfgr().read().sws() != sw {} + RCC.cfgr().modify(|w| w.set_sw(config.sys)); + while RCC.cfgr().read().sws() != config.sys {} // IO compensation cell - Requires CSI clock and SYSCFG #[cfg(stm32h7)] // TODO h5 @@ -532,70 +486,65 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys, - ahb1: hclk, - ahb2: hclk, - ahb3: hclk, - ahb4: hclk, - apb1, - apb2, - apb3, + hclk1: hclk, + hclk2: hclk, + hclk3: hclk, + hclk4: hclk, + pclk1: apb1, + pclk2: apb2, + pclk3: apb3, #[cfg(stm32h7)] - apb4, - apb1_tim, - apb2_tim, + pclk4: apb4, + #[cfg(stm32h5)] + pclk4: Hertz(1), + pclk1_tim: apb1_tim, + pclk2_tim: apb2_tim, adc, rtc, + #[cfg(any(stm32h5, stm32h7))] + hsi: None, #[cfg(stm32h5)] - mux_apb1: Some(apb1), + hsi48: None, #[cfg(stm32h5)] - mux_apb2: Some(apb2), - #[cfg(stm32h5)] - mux_apb3: Some(apb3), - #[cfg(stm32h5)] - mux_apb4: None, + lsi: None, + #[cfg(any(stm32h5, stm32h7))] + csi: None, + + #[cfg(any(stm32h5, stm32h7))] + lse: None, + #[cfg(any(stm32h5, stm32h7))] + hse: None, + + #[cfg(any(stm32h5, stm32h7))] + pll1_q: pll1.q, + #[cfg(any(stm32h5, stm32h7))] + pll2_p: pll2.p, + #[cfg(any(stm32h5, stm32h7))] + pll2_q: pll2.q, + #[cfg(any(stm32h5, stm32h7))] + pll2_r: pll2.r, + #[cfg(any(rcc_h5, stm32h7))] + pll3_p: pll3.p, + #[cfg(any(rcc_h5, stm32h7))] + pll3_q: pll3.q, + #[cfg(any(rcc_h5, stm32h7))] + pll3_r: pll3.r, + + #[cfg(rcc_h50)] + pll3_p: None, + #[cfg(rcc_h50)] + pll3_q: None, + #[cfg(rcc_h50)] + pll3_r: None, #[cfg(stm32h5)] - mux_rcc_hclk4: None, + audioclk: None, + #[cfg(any(stm32h5, stm32h7))] + per: None, - #[cfg(stm32h5)] - mux_pll2_q: None, - #[cfg(stm32h5)] - mux_pll3_q: None, - #[cfg(stm32h5)] - mux_hsi: None, - #[cfg(stm32h5)] - mux_csi: None, - #[cfg(stm32h5)] - mux_lse: None, - #[cfg(stm32h5)] - mux_pll1_q: pll1.q, - #[cfg(stm32h5)] - mux_pll2_p: pll2.p, - #[cfg(rcc_h5)] - mux_pll3_p: pll3.p, - #[cfg(stm32h5)] - mux_audioclk: None, - #[cfg(stm32h5)] - mux_per: None, - - #[cfg(rcc_h5)] - mux_pll3_r: pll3.r, - #[cfg(all(not(rcc_h5), stm32h5))] - mux_pll3_r: None, - #[cfg(stm32h5)] - mux_pll3_1: None, - #[cfg(stm32h5)] - mux_hsi48_ker: None, - #[cfg(stm32h5)] - mux_lsi: None, - #[cfg(stm32h5)] - mux_pll2_r: pll2.r, - #[cfg(stm32h5)] - mux_hse: hse, - - #[cfg(stm32h5)] - mux_hsi48: None, + #[cfg(stm32h7)] + rcc_pclk_d3: None, }); } @@ -603,8 +552,6 @@ struct PllInput { hsi: Option, hse: Option, csi: Option, - #[cfg(stm32h7)] - source: PllSource, } struct PllOutput { @@ -634,15 +581,11 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { }; }; - #[cfg(stm32h5)] - let source = config.source; - #[cfg(stm32h7)] - let source = input.source; - - let (in_clk, src) = match source { - PllSource::Hsi => (unwrap!(input.hsi), Pllsrc::HSI), - PllSource::Hse => (unwrap!(input.hse), Pllsrc::HSE), - PllSource::Csi => (unwrap!(input.csi), Pllsrc::CSI), + let in_clk = match config.source { + PllSource::DISABLE => panic!("must not set PllSource::Disable"), + PllSource::HSI => unwrap!(input.hsi), + PllSource::HSE => unwrap!(input.hse), + PllSource::CSI => unwrap!(input.csi), }; let ref_clk = in_clk / config.prediv as u32; @@ -682,7 +625,7 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { #[cfg(stm32h5)] RCC.pllcfgr(num).write(|w| { - w.set_pllsrc(src); + w.set_pllsrc(config.source); w.set_divm(config.prediv); w.set_pllvcosel(vco_range); w.set_pllrge(ref_range); @@ -696,7 +639,7 @@ fn init_pll(num: usize, config: Option, input: &PllInput) -> PllOutput { { RCC.pllckselr().modify(|w| { w.set_divm(num, config.prediv); - w.set_pllsrc(src); + w.set_pllsrc(config.source); }); RCC.pllcfgr().modify(|w| { w.set_pllvcosel(num, vco_range); diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index d8a1fc10..9fb2062d 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -18,20 +18,20 @@ pub enum ClockSrc { MSI(MSIRange), PLL(PLLSource, PLLMul, PLLDiv), HSE(Hertz), - HSI16, + HSI, } /// PLL clock input source #[derive(Clone, Copy)] pub enum PLLSource { - HSI16, + HSI, HSE(Hertz), } impl From for Pllsrc { fn from(val: PLLSource) -> Pllsrc { match val { - PLLSource::HSI16 => Pllsrc::HSI16, + PLLSource::HSI => Pllsrc::HSI, PLLSource::HSE(_) => Pllsrc::HSE, } } @@ -83,12 +83,12 @@ pub(crate) unsafe fn init(config: Config) { let freq = 32_768 * (1 << (range as u8 + 1)); (Hertz(freq), Sw::MSI) } - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdy() {} + ClockSrc::HSI => { + // Enable HSI + RCC.cr().write(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} - (HSI_FREQ, Sw::HSI16) + (HSI_FREQ, Sw::HSI) } ClockSrc::HSE(freq) => { // Enable HSE @@ -105,10 +105,10 @@ pub(crate) unsafe fn init(config: Config) { while !RCC.cr().read().hserdy() {} freq } - PLLSource::HSI16 => { + PLLSource::HSI => { // Enable HSI - RCC.cr().write(|w| w.set_hsi16on(true)); - while !RCC.cr().read().hsi16rdy() {} + RCC.cr().write(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} HSI_FREQ } }; @@ -131,7 +131,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} - (freq, Sw::PLL) + (freq, Sw::PLL1_P) } }; @@ -156,23 +156,9 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre2(config.apb2_pre); }); - let ahb_freq = sys_clk / config.ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; + let hclk1 = sys_clk / config.ahb_pre; + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); #[cfg(crs)] if config.enable_hsi48 { @@ -209,11 +195,11 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, + hclk1, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, rtc, }); } diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs deleted file mode 100644 index 1e5733d3..00000000 --- a/embassy-stm32/src/rcc/l4.rs +++ /dev/null @@ -1,296 +0,0 @@ -use crate::pac::rcc::regs::Cfgr; -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, - Pllr as PllRDiv, Ppre as APBPrescaler, -}; -use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; -use crate::pac::{FLASH, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), - HSE(Hertz), - HSI16, -} - -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI16, - HSE(Hertz), - MSI(MSIRange), -} - -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI16 => Pllsrc::HSI16, - PLLSource::HSE(_) => Pllsrc::HSE, - PLLSource::MSI(_) => Pllsrc::MSI, - } - } -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - pub hsi48: bool, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - pllsai1: None, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - hsi48: false, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Switch to MSI to prevent problems with PLL configuration. - if !RCC.cr().read().msion() { - // Turn on MSI and configure it to 4MHz. - RCC.cr().modify(|w| { - w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0]. - w.set_msirange(MSIRange::RANGE4M); - w.set_msipllen(false); - w.set_msion(true) - }); - - // Wait until MSI is running - while !RCC.cr().read().msirdy() {} - } - if RCC.cfgr().read().sws() != Sw::MSI { - // Set MSI as a clock source, reset prescalers. - RCC.cfgr().write_value(Cfgr::default()); - // Wait for clock switch status bits to change. - while RCC.cfgr().read().sws() != Sw::MSI {} - } - - let rtc = config.ls.init(); - - let (sys_clk, sw) = match config.mux { - ClockSrc::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msirgsel(true); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - - // Enable as clock source for USB, RNG if running at 48 MHz - if range == MSIRange::RANGE48M { - RCC.ccipr().modify(|w| { - w.set_clk48sel(0b11); - }); - } - (msirange_to_hertz(range), Sw::MSI) - } - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - (HSI_FREQ, Sw::HSI16) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - (freq, Sw::HSE) - } - ClockSrc::PLL(src, divr, prediv, mul, divq) => { - let src_freq = match src { - PLLSource::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - freq - } - PLLSource::HSI16 => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - HSI_FREQ - } - PLLSource::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msipllen(false); // should be turned on if LSE is started - w.set_msirgsel(true); - w.set_msion(true); - }); - while !RCC.cr().read().msirdy() {} - - msirange_to_hertz(range) - } - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = src_freq / prediv * mul / divr; - - #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] - assert!(freq.0 <= 120_000_000); - #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] - assert!(freq.0 <= 80_000_000); - - RCC.pllcfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - w.set_pllr(divr); - if let Some(divq) = divq { - w.set_pllq(divq); - w.set_pllqen(true); - } - w.set_pllsrc(src.into()); - }); - - // Enable as clock source for USB, RNG if PLL48 divisor is provided - if let Some(divq) = divq { - let freq = src_freq / prediv * mul / divq; - assert!(freq.0 == 48_000_000); - RCC.ccipr().modify(|w| { - w.set_clk48sel(0b10); - }); - } - - if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { - RCC.pllsai1cfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - if let Some(r_div) = r_div { - w.set_pllr(r_div); - w.set_pllren(true); - } - if let Some(q_div) = q_div { - w.set_pllq(q_div); - w.set_pllqen(true); - let freq = src_freq / prediv * mul / q_div; - if freq.0 == 48_000_000 { - RCC.ccipr().modify(|w| { - w.set_clk48sel(0b1); - }); - } - } - if let Some(p_div) = p_div { - w.set_pllp(p_div); - w.set_pllpen(true); - } - }); - - RCC.cr().modify(|w| w.set_pllsai1on(true)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - RCC.pllcfgr().modify(|w| w.set_pllren(true)); - - (freq, Sw::PLL) - } - }; - - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] - if config.hsi48 { - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - - // Enable as clock source for USB, RNG and SDMMC - RCC.ccipr().modify(|w| w.set_clk48sel(0)); - } - - // Set flash wait states - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=16_000_000 => 0, - 0..=32_000_000 => 1, - 0..=48_000_000 => 2, - 0..=64_000_000 => 3, - _ => 4, - }) - }); - - RCC.cfgr().modify(|w| { - w.set_sw(sw); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - let ahb_freq = sys_clk / config.ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - set_freqs(Clocks { - sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, - rtc, - }); -} - -fn msirange_to_hertz(range: Msirange) -> Hertz { - match range { - MSIRange::RANGE100K => Hertz(100_000), - MSIRange::RANGE200K => Hertz(200_000), - MSIRange::RANGE400K => Hertz(400_000), - MSIRange::RANGE800K => Hertz(800_000), - MSIRange::RANGE1M => Hertz(1_000_000), - MSIRange::RANGE2M => Hertz(2_000_000), - MSIRange::RANGE4M => Hertz(4_000_000), - MSIRange::RANGE8M => Hertz(8_000_000), - MSIRange::RANGE16M => Hertz(16_000_000), - MSIRange::RANGE24M => Hertz(24_000_000), - MSIRange::RANGE32M => Hertz(32_000_000), - MSIRange::RANGE48M => Hertz(48_000_000), - _ => unreachable!(), - } -} diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs new file mode 100644 index 00000000..2f89f682 --- /dev/null +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -0,0 +1,523 @@ +use crate::pac::rcc::regs::Cfgr; +#[cfg(any(stm32l4, stm32l5, stm32wb))] +pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; +#[cfg(any(stm32wb, stm32wl))] +pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; +pub use crate::pac::rcc::vals::{ + Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, + Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, +}; +use crate::pac::{FLASH, RCC}; +use crate::rcc::{set_freqs, Clocks}; +use crate::time::Hertz; + +/// HSI speed +pub const HSI_FREQ: Hertz = Hertz(16_000_000); + +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum HseMode { + /// crystal/ceramic oscillator (HSEBYP=0) + Oscillator, + /// external analog clock (low swing) (HSEBYP=1) + Bypass, +} + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Hse { + /// HSE frequency. + pub freq: Hertz, + /// HSE mode. + pub mode: HseMode, + /// HSE prescaler + #[cfg(any(stm32wb, stm32wl))] + pub prescaler: HsePrescaler, +} + +#[derive(Clone, Copy)] +pub struct Pll { + /// PLL source + pub source: PLLSource, + + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL P division factor. If None, PLL P output is disabled. + pub divp: Option, + /// PLL Q division factor. If None, PLL Q output is disabled. + pub divq: Option, + /// PLL R division factor. If None, PLL R output is disabled. + pub divr: Option, +} + +/// Clocks configutation +pub struct Config { + // base clock sources + pub msi: Option, + pub hsi: bool, + pub hse: Option, + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] + pub hsi48: bool, + + // pll + pub pll: Option, + #[cfg(any(stm32l4, stm32l5, stm32wb))] + pub pllsai1: Option, + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + pub pllsai2: Option, + + // sysclk, buses. + pub mux: ClockSrc, + pub ahb_pre: AHBPrescaler, + pub apb1_pre: APBPrescaler, + pub apb2_pre: APBPrescaler, + #[cfg(any(stm32wl5x, stm32wb))] + pub core2_ahb_pre: AHBPrescaler, + #[cfg(any(stm32wl, stm32wb))] + pub shared_ahb_pre: AHBPrescaler, + + // muxes + #[cfg(any(stm32l4, stm32l5, stm32wb))] + pub clk48_src: Clk48Src, + + // low speed LSI/LSE/RTC + pub ls: super::LsConfig, +} + +impl Default for Config { + #[inline] + fn default() -> Config { + Config { + hse: None, + hsi: false, + msi: Some(MSIRange::RANGE4M), + mux: ClockSrc::MSI, + ahb_pre: AHBPrescaler::DIV1, + apb1_pre: APBPrescaler::DIV1, + apb2_pre: APBPrescaler::DIV1, + #[cfg(any(stm32wl5x, stm32wb))] + core2_ahb_pre: AHBPrescaler::DIV1, + #[cfg(any(stm32wl, stm32wb))] + shared_ahb_pre: AHBPrescaler::DIV1, + pll: None, + #[cfg(any(stm32l4, stm32l5, stm32wb))] + pllsai1: None, + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + pllsai2: None, + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] + hsi48: true, + #[cfg(any(stm32l4, stm32l5, stm32wb))] + clk48_src: Clk48Src::HSI48, + ls: Default::default(), + } + } +} + +#[cfg(stm32wb)] +pub const WPAN_DEFAULT: Config = Config { + hse: Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Oscillator, + prescaler: HsePrescaler::DIV1, + }), + mux: ClockSrc::PLL1_R, + hsi48: true, + msi: None, + hsi: false, + clk48_src: Clk48Src::PLL1_Q, + + ls: super::LsConfig::default_lse(), + + pll: Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL12, + divp: Some(PllPDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz + divq: Some(PllQDiv::DIV4), // 32 / 2 * 12 / 4 = 48Mhz + divr: Some(PllRDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz + }), + pllsai1: None, + + ahb_pre: AHBPrescaler::DIV1, + core2_ahb_pre: AHBPrescaler::DIV2, + shared_ahb_pre: AHBPrescaler::DIV1, + apb1_pre: APBPrescaler::DIV1, + apb2_pre: APBPrescaler::DIV1, +}; + +pub(crate) unsafe fn init(config: Config) { + // Switch to MSI to prevent problems with PLL configuration. + if !RCC.cr().read().msion() { + // Turn on MSI and configure it to 4MHz. + RCC.cr().modify(|w| { + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); + w.set_msirange(MSIRange::RANGE4M); + w.set_msipllen(false); + w.set_msion(true) + }); + + // Wait until MSI is running + while !RCC.cr().read().msirdy() {} + } + if RCC.cfgr().read().sws() != ClockSrc::MSI { + // Set MSI as a clock source, reset prescalers. + RCC.cfgr().write_value(Cfgr::default()); + // Wait for clock switch status bits to change. + while RCC.cfgr().read().sws() != ClockSrc::MSI {} + } + + #[cfg(stm32l5)] + crate::pac::PWR.cr1().modify(|w| { + w.set_vos(crate::pac::pwr::vals::Vos::RANGE0); + }); + + let rtc = config.ls.init(); + + let msi = config.msi.map(|range| { + // Enable MSI + RCC.cr().modify(|w| { + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); + w.set_msirange(range); + w.set_msion(true); + + // If LSE is enabled, enable calibration of MSI + w.set_msipllen(config.ls.lse.is_some()); + }); + while !RCC.cr().read().msirdy() {} + + // Enable as clock source for USB, RNG if running at 48 MHz + if range == MSIRange::RANGE48M {} + + msirange_to_hertz(range) + }); + + let hsi = config.hsi.then(|| { + RCC.cr().modify(|w| w.set_hsion(true)); + while !RCC.cr().read().hsirdy() {} + + HSI_FREQ + }); + + let hse = config.hse.map(|hse| { + RCC.cr().modify(|w| { + #[cfg(stm32wl)] + w.set_hsebyppwr(hse.mode == HseMode::Bypass); + #[cfg(not(stm32wl))] + w.set_hsebyp(hse.mode == HseMode::Bypass); + w.set_hseon(true); + }); + while !RCC.cr().read().hserdy() {} + + hse.freq + }); + + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))] + let hsi48 = config.hsi48.then(|| { + RCC.crrcr().modify(|w| w.set_hsi48on(true)); + while !RCC.crrcr().read().hsi48rdy() {} + + Hertz(48_000_000) + }); + #[cfg(any(stm32l47x, stm32l48x))] + let hsi48 = None; + + let _plls = [ + &config.pll, + #[cfg(any(stm32l4, stm32l5, stm32wb))] + &config.pllsai1, + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + &config.pllsai2, + ]; + + // L4 has shared PLLSRC, PLLM, check it's equal in all PLLs. + #[cfg(all(stm32l4, not(rcc_l4plus)))] + match super::util::get_equal(_plls.into_iter().flatten().map(|p| (p.source, p.prediv))) { + Err(()) => panic!("Source must be equal across all enabled PLLs."), + Ok(None) => {} + Ok(Some((source, prediv))) => RCC.pllcfgr().write(|w| { + w.set_pllm(prediv); + w.set_pllsrc(source); + }), + }; + + // L4+, WL has shared PLLSRC, check it's equal in all PLLs. + #[cfg(any(rcc_l4plus, stm32wl))] + match super::util::get_equal(_plls.into_iter().flatten().map(|p| p.source)) { + Err(()) => panic!("Source must be equal across all enabled PLLs."), + Ok(None) => {} + Ok(Some(source)) => RCC.pllcfgr().write(|w| { + w.set_pllsrc(source); + }), + }; + + let pll_input = PllInput { hse, hsi, msi }; + let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + #[cfg(any(stm32l4, stm32l5, stm32wb))] + let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); + + let sys_clk = match config.mux { + ClockSrc::HSE => hse.unwrap(), + ClockSrc::HSI => hsi.unwrap(), + ClockSrc::MSI => msi.unwrap(), + ClockSrc::PLL1_R => pll.r.unwrap(), + }; + + #[cfg(stm32l4)] + RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(stm32l5)] + RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(any(stm32l4, stm32l5, stm32wb))] + let _clk48 = match config.clk48_src { + Clk48Src::HSI48 => hsi48, + Clk48Src::MSI => msi, + Clk48Src::PLLSAI1_Q => pllsai1.q, + Clk48Src::PLL1_Q => pll.q, + }; + + #[cfg(rcc_l4plus)] + assert!(sys_clk.0 <= 120_000_000); + #[cfg(all(stm32l4, not(rcc_l4plus)))] + assert!(sys_clk.0 <= 80_000_000); + + let hclk1 = sys_clk / config.ahb_pre; + let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); + let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); + #[cfg(not(any(stm32wl5x, stm32wb)))] + let hclk2 = hclk1; + #[cfg(any(stm32wl5x, stm32wb))] + let hclk2 = sys_clk / config.core2_ahb_pre; + #[cfg(not(any(stm32wl, stm32wb)))] + let hclk3 = hclk1; + #[cfg(any(stm32wl, stm32wb))] + let hclk3 = sys_clk / config.shared_ahb_pre; + + // Set flash wait states + #[cfg(stm32l4)] + let latency = match hclk1.0 { + 0..=16_000_000 => 0, + 0..=32_000_000 => 1, + 0..=48_000_000 => 2, + 0..=64_000_000 => 3, + _ => 4, + }; + #[cfg(stm32l5)] + let latency = match hclk1.0 { + // VCORE Range 0 (performance), others TODO + 0..=20_000_000 => 0, + 0..=40_000_000 => 1, + 0..=60_000_000 => 2, + 0..=80_000_000 => 3, + 0..=100_000_000 => 4, + _ => 5, + }; + #[cfg(stm32wl)] + let latency = match hclk3.0 { + // VOS RANGE1, others TODO. + ..=18_000_000 => 0, + ..=36_000_000 => 1, + _ => 2, + }; + #[cfg(stm32wb)] + let latency = match hclk3.0 { + // VOS RANGE1, others TODO. + ..=18_000_000 => 0, + ..=36_000_000 => 1, + ..=54_000_000 => 2, + ..=64_000_000 => 3, + _ => 4, + }; + + FLASH.acr().modify(|w| w.set_latency(latency)); + while FLASH.acr().read().latency() != latency {} + + RCC.cfgr().modify(|w| { + w.set_sw(config.mux); + w.set_hpre(config.ahb_pre); + w.set_ppre1(config.apb1_pre); + w.set_ppre2(config.apb2_pre); + }); + while RCC.cfgr().read().sws() != config.mux {} + + #[cfg(any(stm32wl, stm32wb))] + { + RCC.extcfgr().modify(|w| { + w.set_shdhpre(config.shared_ahb_pre); + #[cfg(any(stm32wl5x, stm32wb))] + w.set_c2hpre(config.core2_ahb_pre); + }); + while !RCC.extcfgr().read().shdhpref() {} + #[cfg(any(stm32wl5x, stm32wb))] + while !RCC.extcfgr().read().c2hpref() {} + } + + set_freqs(Clocks { + sys: sys_clk, + hclk1, + hclk2, + hclk3, + pclk1, + pclk2, + pclk1_tim, + pclk2_tim, + #[cfg(stm32wl)] + pclk3: hclk3, + #[cfg(rcc_l4)] + hsi: None, + #[cfg(rcc_l4)] + lse: None, + #[cfg(rcc_l4)] + pllsai1_p: None, + #[cfg(rcc_l4)] + pllsai2_p: None, + #[cfg(rcc_l4)] + pll1_p: None, + #[cfg(rcc_l4)] + pll1_q: None, + #[cfg(rcc_l4)] + sai1_extclk: None, + #[cfg(rcc_l4)] + sai2_extclk: None, + rtc, + }); +} + +fn msirange_to_hertz(range: MSIRange) -> Hertz { + match range { + MSIRange::RANGE100K => Hertz(100_000), + MSIRange::RANGE200K => Hertz(200_000), + MSIRange::RANGE400K => Hertz(400_000), + MSIRange::RANGE800K => Hertz(800_000), + MSIRange::RANGE1M => Hertz(1_000_000), + MSIRange::RANGE2M => Hertz(2_000_000), + MSIRange::RANGE4M => Hertz(4_000_000), + MSIRange::RANGE8M => Hertz(8_000_000), + MSIRange::RANGE16M => Hertz(16_000_000), + MSIRange::RANGE24M => Hertz(24_000_000), + MSIRange::RANGE32M => Hertz(32_000_000), + MSIRange::RANGE48M => Hertz(48_000_000), + _ => unreachable!(), + } +} + +struct PllInput { + hsi: Option, + hse: Option, + msi: Option, +} + +#[allow(unused)] +#[derive(Default)] +struct PllOutput { + p: Option, + q: Option, + r: Option, +} + +#[derive(PartialEq, Eq, Clone, Copy)] +enum PllInstance { + Pll, + #[cfg(any(stm32l4, stm32l5, stm32wb))] + Pllsai1, + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + Pllsai2, +} + +fn pll_enable(instance: PllInstance, enabled: bool) { + match instance { + PllInstance::Pll => { + RCC.cr().modify(|w| w.set_pllon(enabled)); + while RCC.cr().read().pllrdy() != enabled {} + } + #[cfg(any(stm32l4, stm32l5, stm32wb))] + PllInstance::Pllsai1 => { + RCC.cr().modify(|w| w.set_pllsai1on(enabled)); + while RCC.cr().read().pllsai1rdy() != enabled {} + } + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + PllInstance::Pllsai2 => { + RCC.cr().modify(|w| w.set_pllsai2on(enabled)); + while RCC.cr().read().pllsai2rdy() != enabled {} + } + } +} + +fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PLLSource::DISABLE => panic!("must not select PLL source as DISABLE"), + PLLSource::HSE => input.hse, + PLLSource::HSI => input.hsi, + PLLSource::MSI => input.msi, + }; + + let pll_src = pll_src.unwrap(); + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + #[cfg(stm32l5)] + if instance == PllInstance::Pllsai2 { + assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); + assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + } + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + $w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + $w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + $w.set_pllren(true); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l4, stm32l5, stm32wb))] + PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + } + + // Enable PLL + pll_enable(instance, true); + + PllOutput { p, q, r } +} diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs deleted file mode 100644 index 1f4e0034..00000000 --- a/embassy-stm32/src/rcc/l5.rs +++ /dev/null @@ -1,291 +0,0 @@ -use crate::pac::rcc::regs::Cfgr; -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, - Pllr as PllRDiv, Ppre as APBPrescaler, -}; -use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - PLL(PLLSource, PllRDiv, PllPreDiv, PllMul, Option), - HSE(Hertz), - HSI16, -} - -/// PLL clock input source -#[derive(Clone, Copy)] -pub enum PLLSource { - HSI16, - HSE(Hertz), - MSI(MSIRange), -} - -impl From for Pllsrc { - fn from(val: PLLSource) -> Pllsrc { - match val { - PLLSource::HSI16 => Pllsrc::HSI16, - PLLSource::HSE(_) => Pllsrc::HSE, - PLLSource::MSI(_) => Pllsrc::MSI, - } - } -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub pllsai1: Option<(PllMul, PllPreDiv, Option, Option, Option)>, - pub hsi48: bool, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - pllsai1: None, - hsi48: false, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Switch to MSI to prevent problems with PLL configuration. - if !RCC.cr().read().msion() { - // Turn on MSI and configure it to 4MHz. - RCC.cr().modify(|w| { - w.set_msirgsel(true); // MSI Range is provided by MSIRANGE[3:0]. - w.set_msirange(MSIRange::RANGE4M); - w.set_msipllen(false); - w.set_msion(true) - }); - - // Wait until MSI is running - while !RCC.cr().read().msirdy() {} - } - if RCC.cfgr().read().sws() != Sw::MSI { - // Set MSI as a clock source, reset prescalers. - RCC.cfgr().write_value(Cfgr::default()); - // Wait for clock switch status bits to change. - while RCC.cfgr().read().sws() != Sw::MSI {} - } - - let rtc = config.ls.init(); - - PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); - let (sys_clk, sw) = match config.mux { - ClockSrc::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msirgsel(true); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - - // Enable as clock source for USB, RNG if running at 48 MHz - if range == MSIRange::RANGE48M { - RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b11); - }); - } - (msirange_to_hertz(range), Sw::MSI) - } - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - (HSI_FREQ, Sw::HSI16) - } - ClockSrc::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - - (freq, Sw::HSE) - } - ClockSrc::PLL(src, divr, prediv, mul, divq) => { - let src_freq = match src { - PLLSource::HSE(freq) => { - // Enable HSE - RCC.cr().write(|w| w.set_hseon(true)); - while !RCC.cr().read().hserdy() {} - freq - } - PLLSource::HSI16 => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - HSI_FREQ - } - PLLSource::MSI(range) => { - // Enable MSI - RCC.cr().write(|w| { - w.set_msirange(range); - w.set_msipllen(false); // should be turned on if LSE is started - w.set_msirgsel(true); - w.set_msion(true); - }); - while !RCC.cr().read().msirdy() {} - - msirange_to_hertz(range) - } - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = src_freq / prediv * mul / divr; - - RCC.pllcfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - w.set_pllr(divr); - if let Some(divq) = divq { - w.set_pllq(divq); - w.set_pllqen(true); - } - w.set_pllsrc(src.into()); - }); - - // Enable as clock source for USB, RNG if PLL48 divisor is provided - if let Some(divq) = divq { - let freq = src_freq / prediv * mul / divq; - assert!(freq.0 == 48_000_000); - RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b10); - }); - } - - if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { - RCC.pllsai1cfgr().write(move |w| { - w.set_plln(mul); - w.set_pllm(prediv); - if let Some(r_div) = r_div { - w.set_pllr(r_div); - w.set_pllren(true); - } - if let Some(q_div) = q_div { - w.set_pllq(q_div); - w.set_pllqen(true); - let freq = src_freq / prediv * mul / q_div; - if freq.0 == 48_000_000 { - RCC.ccipr1().modify(|w| { - w.set_clk48msel(0b1); - }); - } - } - if let Some(p_div) = p_div { - w.set_pllp(p_div); - w.set_pllpen(true); - } - }); - - RCC.cr().modify(|w| w.set_pllsai1on(true)); - } - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - RCC.pllcfgr().modify(|w| w.set_pllren(true)); - - (freq, Sw::PLL) - } - }; - - if config.hsi48 { - RCC.crrcr().modify(|w| w.set_hsi48on(true)); - while !RCC.crrcr().read().hsi48rdy() {} - - // Enable as clock source for USB, RNG and SDMMC - RCC.ccipr1().modify(|w| w.set_clk48msel(0)); - } - - // Set flash wait states - // VCORE Range 0 (performance), others TODO - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=20_000_000 => 0, - 0..=40_000_000 => 1, - 0..=60_000_000 => 2, - 0..=80_000_000 => 3, - 0..=100_000_000 => 4, - _ => 5, - }) - }); - - RCC.cfgr().modify(|w| { - w.set_sw(sw); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - let ahb_freq = sys_clk / config.ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - set_freqs(Clocks { - sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, - rtc, - }); -} - -fn msirange_to_hertz(range: Msirange) -> Hertz { - match range { - MSIRange::RANGE100K => Hertz(100_000), - MSIRange::RANGE200K => Hertz(200_000), - MSIRange::RANGE400K => Hertz(400_000), - MSIRange::RANGE800K => Hertz(800_000), - MSIRange::RANGE1M => Hertz(1_000_000), - MSIRange::RANGE2M => Hertz(2_000_000), - MSIRange::RANGE4M => Hertz(4_000_000), - MSIRange::RANGE8M => Hertz(8_000_000), - MSIRange::RANGE16M => Hertz(16_000_000), - MSIRange::RANGE24M => Hertz(24_000_000), - MSIRange::RANGE32M => Hertz(32_000_000), - MSIRange::RANGE48M => Hertz(48_000_000), - _ => unreachable!(), - } -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index f7210e18..3b19e4b9 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -13,22 +13,16 @@ pub use mco::*; #[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")] #[cfg_attr(rcc_f2, path = "f2.rs")] #[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")] -#[cfg_attr(any(rcc_f4, rcc_f410), path = "f4.rs")] -#[cfg_attr(rcc_f7, path = "f7.rs")] +#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")] #[cfg_attr(rcc_c0, path = "c0.rs")] #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] #[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(rcc_l4, path = "l4.rs")] -#[cfg_attr(rcc_l5, path = "l5.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] -#[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] -#[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] mod _version; -#[cfg(feature = "low-power")] -use core::sync::atomic::{AtomicU32, Ordering}; pub use _version::*; @@ -48,23 +42,24 @@ pub struct Clocks { pub sys: Hertz, // APB - pub apb1: Hertz, - pub apb1_tim: Hertz, + pub pclk1: Hertz, + pub pclk1_tim: Hertz, #[cfg(not(any(rcc_c0, rcc_g0)))] - pub apb2: Hertz, + pub pclk2: Hertz, #[cfg(not(any(rcc_c0, rcc_g0)))] - pub apb2_tim: Hertz, + pub pclk2_tim: Hertz, #[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))] - pub apb3: Hertz, - #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab))] - pub apb4: Hertz, + pub pclk3: Hertz, + #[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))] + pub pclk4: Hertz, #[cfg(any(rcc_wba))] - pub apb7: Hertz, + pub pclk7: Hertz, // AHB - pub ahb1: Hertz, + pub hclk1: Hertz, #[cfg(any( rcc_l4, + rcc_l4plus, rcc_l5, rcc_f2, rcc_f4, @@ -82,9 +77,10 @@ pub struct Clocks { rcc_wl5, rcc_wle ))] - pub ahb2: Hertz, + pub hclk2: Hertz, #[cfg(any( rcc_l4, + rcc_l4plus, rcc_l5, rcc_f2, rcc_f4, @@ -100,18 +96,40 @@ pub struct Clocks { rcc_wl5, rcc_wle ))] - pub ahb3: Hertz, + pub hclk3: Hertz, #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))] - pub ahb4: Hertz, - - #[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))] - pub pll48: Option, + pub hclk4: Hertz, #[cfg(all(rcc_f4, not(stm32f410)))] - pub plli2s: Option, + pub plli2s1_q: Option, + #[cfg(all(rcc_f4, not(stm32f410)))] + pub plli2s1_r: Option, + #[cfg(rcc_l4)] + pub pllsai1_p: Option, #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] - pub pllsai: Option, + pub pllsai1_q: Option, + #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] + pub pllsai1_r: Option, + #[cfg(rcc_l4)] + pub pllsai2_p: Option, + + #[cfg(any(stm32g4, rcc_l4))] + pub pll1_p: Option, + #[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_l4))] + pub pll1_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_p: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll2_r: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_p: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_q: Option, + #[cfg(any(stm32h5, stm32h7))] + pub pll3_r: Option, #[cfg(any( rcc_f1, @@ -135,79 +153,35 @@ pub struct Clocks { pub rtc: Option, + #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] + pub hsi: Option, #[cfg(stm32h5)] - pub mux_apb1: Option, + pub hsi48: Option, #[cfg(stm32h5)] - pub mux_apb2: Option, - #[cfg(stm32h5)] - pub mux_apb3: Option, - #[cfg(stm32h5)] - pub mux_apb4: Option, + pub lsi: Option, + #[cfg(any(stm32h5, stm32h7))] + pub csi: Option, + + #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] + pub lse: Option, + #[cfg(any(stm32h5, stm32h7))] + pub hse: Option, #[cfg(stm32h5)] - pub mux_rcc_hclk4: Option, + pub audioclk: Option, + #[cfg(any(stm32h5, stm32h7))] + pub per: Option, - #[cfg(stm32h5)] - pub mux_pll2_q: Option, - #[cfg(stm32h5)] - pub mux_pll3_q: Option, - #[cfg(stm32h5)] - pub mux_hsi: Option, - #[cfg(stm32h5)] - pub mux_csi: Option, - #[cfg(stm32h5)] - pub mux_lse: Option, - - #[cfg(stm32h5)] - pub mux_pll1_q: Option, - #[cfg(stm32h5)] - pub mux_pll2_p: Option, - #[cfg(rcc_h5)] - pub mux_pll3_p: Option, - #[cfg(stm32h5)] - pub mux_audioclk: Option, - #[cfg(stm32h5)] - pub mux_per: Option, - - #[cfg(stm32h5)] - pub mux_pll3_r: Option, - #[cfg(stm32h5)] - pub mux_pll3_1: Option, - #[cfg(stm32h5)] - pub mux_hsi48_ker: Option, - #[cfg(stm32h5)] - pub mux_lsi: Option, - #[cfg(stm32h5)] - pub mux_pll2_r: Option, - #[cfg(stm32h5)] - pub mux_hse: Option, - - #[cfg(stm32h5)] - pub mux_hsi48: Option, + #[cfg(stm32h7)] + pub rcc_pclk_d3: Option, + #[cfg(rcc_l4)] + pub sai1_extclk: Option, + #[cfg(rcc_l4)] + pub sai2_extclk: Option, } #[cfg(feature = "low-power")] -static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0); - -#[cfg(feature = "low-power")] -pub fn low_power_ready() -> bool { - // trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst)); - CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0 -} - -#[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) { - // We don't check for overflow because constructing more than u32 peripherals is unlikely - let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); - CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed); -} - -#[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_sub(_cs: critical_section::CriticalSection) { - let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); - assert!(n != 0); - CLOCK_REFCOUNT.store(n - 1, Ordering::Relaxed); -} +pub(crate) static mut REFCOUNT_STOP2: u32 = 0; /// Frozen clock frequencies /// @@ -250,3 +224,33 @@ pub(crate) mod sealed { } pub trait RccPeripheral: sealed::RccPeripheral + 'static {} + +#[allow(unused)] +mod util { + use crate::time::Hertz; + + pub fn calc_pclk(hclk: Hertz, ppre: D) -> (Hertz, Hertz) + where + Hertz: core::ops::Div, + { + let pclk = hclk / ppre; + let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 }; + (pclk, pclk_tim) + } + + pub fn all_equal(mut iter: impl Iterator) -> bool { + let Some(x) = iter.next() else { return true }; + if !iter.all(|y| y == x) { + return false; + } + true + } + + pub fn get_equal(mut iter: impl Iterator) -> Result, ()> { + let Some(x) = iter.next() else { return Ok(None) }; + if !iter.all(|y| y == x) { + return Err(()); + } + Ok(Some(x)) + } +} diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 68a8d3a3..2bbacbbd 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -10,6 +10,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub use crate::pac::pwr::vals::Vos as VoltageScale; #[derive(Copy, Clone)] +#[allow(non_camel_case_types)] pub enum ClockSrc { /// Use an internal medium speed oscillator (MSIS) as the system clock. MSI(Msirange), @@ -19,9 +20,9 @@ pub enum ClockSrc { /// never exceed 50 MHz. HSE(Hertz), /// Use the 16 MHz internal high speed oscillator as the system clock. - HSI16, + HSI, /// Use PLL1 as the system clock. - PLL1R(PllConfig), + PLL1_R(PllConfig), } impl Default for ClockSrc { @@ -53,10 +54,10 @@ pub struct PllConfig { } impl PllConfig { - /// A configuration for HSI16 / 1 * 10 / 1 = 160 MHz - pub const fn hsi16_160mhz() -> Self { + /// A configuration for HSI / 1 * 10 / 1 = 160 MHz + pub const fn hsi_160mhz() -> Self { PllConfig { - source: PllSrc::HSI16, + source: PllSrc::HSI, m: Pllm::DIV1, n: Plln::MUL10, r: Plldiv::DIV1, @@ -84,7 +85,7 @@ pub enum PllSrc { /// never exceed 50 MHz. HSE(Hertz), /// Use the 16 MHz internal high speed oscillator as the PLL source. - HSI16, + HSI, } impl Into for PllSrc { @@ -92,7 +93,7 @@ impl Into for PllSrc { match self { PllSrc::MSIS(..) => Pllsrc::MSIS, PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -102,8 +103,8 @@ impl Into for ClockSrc { match self { ClockSrc::MSI(..) => Sw::MSIS, ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI16, - ClockSrc::PLL1R(..) => Sw::PLL1_R, + ClockSrc::HSI => Sw::HSI, + ClockSrc::PLL1_R(..) => Sw::PLL1_R, } } } @@ -125,7 +126,7 @@ pub struct Config { } impl Config { - unsafe fn init_hsi16(&self) -> Hertz { + unsafe fn init_hsi(&self) -> Hertz { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -169,7 +170,7 @@ impl Config { RCC.icscr1().modify(|w| { w.set_msisrange(range); - w.set_msirgsel(Msirgsel::RCC_ICSCR1); + w.set_msirgsel(Msirgsel::ICSCR1); }); RCC.cr().write(|w| { w.set_msipllen(false); @@ -188,7 +189,7 @@ impl Default for Config { apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1, - hsi48: false, + hsi48: true, voltage_range: VoltageScale::RANGE3, ls: Default::default(), } @@ -211,13 +212,13 @@ pub(crate) unsafe fn init(config: Config) { let sys_clk = match config.mux { ClockSrc::MSI(range) => config.init_msis(range), ClockSrc::HSE(freq) => config.init_hse(freq), - ClockSrc::HSI16 => config.init_hsi16(), - ClockSrc::PLL1R(pll) => { + ClockSrc::HSI => config.init_hsi(), + ClockSrc::PLL1_R(pll) => { // Configure the PLL source let source_clk = match pll.source { PllSrc::MSIS(range) => config.init_msis(range), PllSrc::HSE(hertz) => config.init_hse(hertz), - PllSrc::HSI16 => config.init_hsi16(), + PllSrc::HSI => config.init_hsi(), }; // Calculate the reference clock, which is the source divided by m @@ -292,7 +293,7 @@ pub(crate) unsafe fn init(config: Config) { // Set the prescaler for PWR EPOD w.set_pllmboost(mboost); - // Enable PLL1R output + // Enable PLL1_R output w.set_pllren(true); }); @@ -436,14 +437,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb3: apb3_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk3: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk3: apb3_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs deleted file mode 100644 index 181e6bb5..00000000 --- a/embassy-stm32/src/rcc/wb.rs +++ /dev/null @@ -1,248 +0,0 @@ -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, - Ppre as APBPrescaler, Sw as Sysclk, -}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::{mhz, Hertz}; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -pub struct Hse { - pub prediv: HsePrescaler, - - pub frequency: Hertz, -} - -pub struct PllMux { - /// Source clock selection. - pub source: PllSource, - - /// PLL pre-divider (DIVM). Must be between 1 and 63. - pub prediv: Pllm, -} - -pub struct Pll { - /// PLL multiplication factor. Must be between 4 and 512. - pub mul: Plln, - - /// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128. - /// On PLL1, it must be even (in particular, it cannot be 1.) - pub divp: Option, - /// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128. - pub divq: Option, - /// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128. - pub divr: Option, -} - -/// Clocks configutation -pub struct Config { - pub hse: Option, - pub sys: Sysclk, - pub mux: Option, - - pub pll: Option, - pub pllsai: Option, - - pub ahb1_pre: AHBPrescaler, - pub ahb2_pre: AHBPrescaler, - pub ahb3_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - - pub ls: super::LsConfig, -} - -pub const WPAN_DEFAULT: Config = Config { - hse: Some(Hse { - frequency: mhz(32), - prediv: HsePrescaler::DIV1, - }), - sys: Sysclk::PLL, - mux: Some(PllMux { - source: PllSource::HSE, - prediv: Pllm::DIV2, - }), - - ls: super::LsConfig::default_lse(), - - pll: Some(Pll { - mul: Plln::MUL12, - divp: Some(Pllp::DIV3), - divq: Some(Pllq::DIV4), - divr: Some(Pllr::DIV3), - }), - pllsai: None, - - ahb1_pre: AHBPrescaler::DIV1, - ahb2_pre: AHBPrescaler::DIV2, - ahb3_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, -}; - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - hse: None, - sys: Sysclk::HSI16, - mux: None, - pll: None, - pllsai: None, - - ls: Default::default(), - - ahb1_pre: AHBPrescaler::DIV1, - ahb2_pre: AHBPrescaler::DIV1, - ahb3_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - } - } -} - -#[cfg(stm32wb)] -/// RCC initialization function -pub(crate) unsafe fn init(config: Config) { - let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv); - - let mux_clk = config.mux.as_ref().map(|pll_mux| { - (match pll_mux.source { - PllSource::HSE => hse_clk.unwrap(), - PllSource::HSI16 => HSI_FREQ, - _ => unreachable!(), - } / pll_mux.prediv) - }); - - let (pll_r, _pll_q, _pll_p) = match &config.pll { - Some(pll) => { - let pll_vco = mux_clk.unwrap() * pll.mul as u32; - - ( - pll.divr.map(|divr| pll_vco / divr), - pll.divq.map(|divq| pll_vco / divq), - pll.divp.map(|divp| pll_vco / divp), - ) - } - None => (None, None, None), - }; - - let sys_clk = match config.sys { - Sysclk::HSE => hse_clk.unwrap(), - Sysclk::HSI16 => HSI_FREQ, - Sysclk::PLL => pll_r.unwrap(), - _ => unreachable!(), - }; - - let ahb1_clk = sys_clk / config.ahb1_pre; - let ahb2_clk = sys_clk / config.ahb2_pre; - let ahb3_clk = sys_clk / config.ahb3_pre; - - let (apb1_clk, apb1_tim_clk) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), - pre => { - let freq = ahb1_clk / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_clk, apb2_tim_clk) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk), - pre => { - let freq = ahb1_clk / pre; - (freq, freq * 2u32) - } - }; - - let rcc = crate::pac::RCC; - - let needs_hsi = if let Some(pll_mux) = &config.mux { - pll_mux.source == PllSource::HSI16 - } else { - false - }; - - if needs_hsi || config.sys == Sysclk::HSI16 { - rcc.cr().modify(|w| { - w.set_hsion(true); - }); - - while !rcc.cr().read().hsirdy() {} - } - - rcc.cfgr().modify(|w| w.set_stopwuck(true)); - - let rtc = config.ls.init(); - - match &config.hse { - Some(hse) => { - rcc.cr().modify(|w| { - w.set_hsepre(hse.prediv); - w.set_hseon(true); - }); - - while !rcc.cr().read().hserdy() {} - } - _ => {} - } - - match &config.mux { - Some(pll_mux) => { - rcc.pllcfgr().modify(|w| { - w.set_pllm(pll_mux.prediv); - w.set_pllsrc(pll_mux.source.into()); - }); - } - _ => {} - }; - - match &config.pll { - Some(pll) => { - rcc.pllcfgr().modify(|w| { - w.set_plln(pll.mul); - pll.divp.map(|divp| { - w.set_pllpen(true); - w.set_pllp(divp) - }); - pll.divq.map(|divq| { - w.set_pllqen(true); - w.set_pllq(divq) - }); - pll.divr.map(|divr| { - w.set_pllren(true); - w.set_pllr(divr); - }); - }); - - rcc.cr().modify(|w| w.set_pllon(true)); - - while !rcc.cr().read().pllrdy() {} - } - _ => {} - } - - rcc.cfgr().modify(|w| { - w.set_sw(config.sys.into()); - w.set_hpre(config.ahb1_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - rcc.extcfgr().modify(|w| { - w.set_c2hpre(config.ahb2_pre); - w.set_shdhpre(config.ahb3_pre); - }); - - set_freqs(Clocks { - sys: sys_clk, - ahb1: ahb1_clk, - ahb2: ahb2_clk, - ahb3: ahb3_clk, - apb1: apb1_clk, - apb2: apb2_clk, - apb1_tim: apb1_tim_clk, - apb2_tim: apb2_tim_clk, - rtc, - }) -} diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index ff5669ec..8925d960 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -13,20 +13,20 @@ pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; #[derive(Copy, Clone)] pub enum ClockSrc { HSE(Hertz), - HSI16, + HSI, } #[derive(Clone, Copy, Debug)] pub enum PllSrc { HSE(Hertz), - HSI16, + HSI, } impl Into for PllSrc { fn into(self) -> Pllsrc { match self { PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI16 => Pllsrc::HSI16, + PllSrc::HSI => Pllsrc::HSI, } } } @@ -35,7 +35,7 @@ impl Into for ClockSrc { fn into(self) -> Sw { match self { ClockSrc::HSE(..) => Sw::HSE, - ClockSrc::HSI16 => Sw::HSI16, + ClockSrc::HSI => Sw::HSI, } } } @@ -52,7 +52,7 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { - mux: ClockSrc::HSI16, + mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, @@ -70,7 +70,7 @@ pub(crate) unsafe fn init(config: Config) { freq } - ClockSrc::HSI16 => { + ClockSrc::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -142,14 +142,14 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb4: ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb7: apb7_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, + hclk1: ahb_freq, + hclk2: ahb_freq, + hclk4: ahb_freq, + pclk1: apb1_freq, + pclk2: apb2_freq, + pclk7: apb7_freq, + pclk1_tim: apb1_tim_freq, + pclk2_tim: apb2_tim_freq, rtc, }); } diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs deleted file mode 100644 index 366ca136..00000000 --- a/embassy-stm32/src/rcc/wl.rs +++ /dev/null @@ -1,184 +0,0 @@ -pub use crate::pac::pwr::vals::Vos as VoltageScale; -use crate::pac::rcc::vals::Sw; -pub use crate::pac::rcc::vals::{ - Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm, Plln, Pllp, Pllq, Pllr, - Pllsrc as PllSource, Ppre as APBPrescaler, -}; -use crate::pac::{FLASH, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// HSE speed -pub const HSE_FREQ: Hertz = Hertz(32_000_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - HSE, - HSI16, -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub shd_ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub adc_clock_source: AdcClockSource, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - shd_ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - adc_clock_source: AdcClockSource::HSI16, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - let (sys_clk, sw, vos) = match config.mux { - ClockSrc::HSI16 => (HSI_FREQ, Sw::HSI16, VoltageScale::RANGE2), - ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), - ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), - }; - - let ahb_freq = sys_clk / config.ahb_pre; - let shd_ahb_freq = sys_clk / config.shd_ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - // Adjust flash latency - let flash_clk_src_freq = shd_ahb_freq; - let ws = match vos { - VoltageScale::RANGE1 => match flash_clk_src_freq.0 { - 0..=18_000_000 => 0b000, - 18_000_001..=36_000_000 => 0b001, - _ => 0b010, - }, - VoltageScale::RANGE2 => match flash_clk_src_freq.0 { - 0..=6_000_000 => 0b000, - 6_000_001..=12_000_000 => 0b001, - _ => 0b010, - }, - _ => unreachable!(), - }; - - FLASH.acr().modify(|w| { - w.set_latency(ws); - }); - - while FLASH.acr().read().latency() != ws {} - - match config.mux { - ClockSrc::HSI16 => { - // Enable HSI16 - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - ClockSrc::HSE => { - // Enable HSE - RCC.cr().write(|w| { - w.set_hsebyppwr(true); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - ClockSrc::MSI(range) => { - let cr = RCC.cr().read(); - assert!(!cr.msion() || cr.msirdy()); - RCC.cr().write(|w| { - w.set_msirgsel(true); - w.set_msirange(range); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - } - } - - RCC.extcfgr().modify(|w| { - w.set_shdhpre(config.shd_ahb_pre); - }); - - RCC.cfgr().modify(|w| { - w.set_sw(sw.into()); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - // ADC clock MUX - RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); - - // TODO: switch voltage range - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: sys_clk, - ahb1: ahb_freq, - ahb2: ahb_freq, - ahb3: shd_ahb_freq, - apb1: apb1_freq, - apb2: apb2_freq, - apb3: shd_ahb_freq, - apb1_tim: apb1_tim_freq, - apb2_tim: apb2_tim_freq, - rtc, - }); -} - -fn msirange_to_hertz(range: MSIRange) -> Hertz { - match range { - MSIRange::RANGE100K => Hertz(100_000), - MSIRange::RANGE200K => Hertz(200_000), - MSIRange::RANGE400K => Hertz(400_000), - MSIRange::RANGE800K => Hertz(800_000), - MSIRange::RANGE1M => Hertz(1_000_000), - MSIRange::RANGE2M => Hertz(2_000_000), - MSIRange::RANGE4M => Hertz(4_000_000), - MSIRange::RANGE8M => Hertz(8_000_000), - MSIRange::RANGE16M => Hertz(16_000_000), - MSIRange::RANGE24M => Hertz(24_000_000), - MSIRange::RANGE32M => Hertz(32_000_000), - MSIRange::RANGE48M => Hertz(48_000_000), - _ => unreachable!(), - } -} - -fn msirange_to_vos(range: MSIRange) -> VoltageScale { - if range.to_bits() > MSIRange::RANGE16M.to_bits() { - VoltageScale::RANGE1 - } else { - VoltageScale::RANGE2 - } -} diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index fc003ebe..5e6922e9 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -85,7 +85,7 @@ impl<'d, T: Instance> Rng<'d, T> { reg.set_ie(false); reg.set_rngen(true); }); - T::regs().cr().write(|reg| { + T::regs().cr().modify(|reg| { reg.set_ced(false); }); // wait for CONDRST to be set diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index 3efe9be5..a1943cf3 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs @@ -4,8 +4,60 @@ use core::convert::From; #[cfg(feature = "chrono")] use chrono::{self, Datelike, NaiveDate, Timelike, Weekday}; -use super::byte_to_bcd2; -use crate::pac::rtc::Rtc; +#[cfg(any(feature = "defmt", feature = "time"))] +use crate::peripherals::RTC; +#[cfg(any(feature = "defmt", feature = "time"))] +use crate::rtc::sealed::Instance; + +/// Represents an instant in time that can be substracted to compute a duration +pub struct RtcInstant { + /// 0..59 + pub second: u8, + /// 0..256 + pub subsecond: u16, +} + +impl RtcInstant { + #[allow(dead_code)] + pub(super) fn from(second: u8, subsecond: u16) -> Result { + Ok(Self { second, subsecond }) + } +} + +#[cfg(feature = "defmt")] +impl defmt::Format for RtcInstant { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!( + fmt, + "{}:{}", + self.second, + RTC::regs().prer().read().prediv_s() - self.subsecond, + ) + } +} + +#[cfg(feature = "time")] +impl core::ops::Sub for RtcInstant { + type Output = embassy_time::Duration; + + fn sub(self, rhs: Self) -> Self::Output { + use embassy_time::{Duration, TICK_HZ}; + + let second = if self.second < rhs.second { + self.second + 60 + } else { + self.second + }; + + let psc = RTC::regs().prer().read().prediv_s() as u32; + + let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32); + let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32); + let rtc_ticks = self_ticks - other_ticks; + + Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64) + } +} /// Errors regarding the [`DateTime`] struct. #[derive(Clone, Debug, PartialEq, Eq)] @@ -32,19 +84,85 @@ pub enum Error { /// Structure containing date and time information pub struct DateTime { /// 0..4095 - pub year: u16, + year: u16, /// 1..12, 1 is January - pub month: u8, + month: u8, /// 1..28,29,30,31 depending on month - pub day: u8, + day: u8, /// - pub day_of_week: DayOfWeek, + day_of_week: DayOfWeek, /// 0..23 - pub hour: u8, + hour: u8, /// 0..59 - pub minute: u8, + minute: u8, /// 0..59 - pub second: u8, + second: u8, +} + +impl DateTime { + pub const fn year(&self) -> u16 { + self.year + } + + pub const fn month(&self) -> u8 { + self.month + } + + pub const fn day(&self) -> u8 { + self.day + } + + pub const fn day_of_week(&self) -> DayOfWeek { + self.day_of_week + } + + pub const fn hour(&self) -> u8 { + self.hour + } + + pub const fn minute(&self) -> u8 { + self.minute + } + + pub const fn second(&self) -> u8 { + self.second + } + + pub fn from( + year: u16, + month: u8, + day: u8, + day_of_week: u8, + hour: u8, + minute: u8, + second: u8, + ) -> Result { + let day_of_week = day_of_week_from_u8(day_of_week)?; + + if year > 4095 { + Err(Error::InvalidYear) + } else if month < 1 || month > 12 { + Err(Error::InvalidMonth) + } else if day < 1 || day > 31 { + Err(Error::InvalidDay) + } else if hour > 23 { + Err(Error::InvalidHour) + } else if minute > 59 { + Err(Error::InvalidMinute) + } else if second > 59 { + Err(Error::InvalidSecond) + } else { + Ok(Self { + year, + month, + day, + day_of_week, + hour, + minute, + second, + }) + } + } } #[cfg(feature = "chrono")] @@ -142,58 +260,3 @@ pub(super) fn validate_datetime(dt: &DateTime) -> Result<(), Error> { Ok(()) } } - -pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) { - let (ht, hu) = byte_to_bcd2(t.hour as u8); - let (mnt, mnu) = byte_to_bcd2(t.minute as u8); - let (st, su) = byte_to_bcd2(t.second as u8); - - let (dt, du) = byte_to_bcd2(t.day as u8); - let (mt, mu) = byte_to_bcd2(t.month as u8); - let yr = t.year as u16; - let yr_offset = (yr - 1970_u16) as u8; - let (yt, yu) = byte_to_bcd2(yr_offset); - - use crate::pac::rtc::vals::Ampm; - - rtc.tr().write(|w| { - w.set_ht(ht); - w.set_hu(hu); - w.set_mnt(mnt); - w.set_mnu(mnu); - w.set_st(st); - w.set_su(su); - w.set_pm(Ampm::AM); - }); - - rtc.dr().write(|w| { - w.set_dt(dt); - w.set_du(du); - w.set_mt(mt > 0); - w.set_mu(mu); - w.set_yt(yt); - w.set_yu(yu); - w.set_wdu(day_of_week_to_u8(t.day_of_week)); - }); -} - -pub(super) fn datetime( - year: u16, - month: u8, - day: u8, - day_of_week: u8, - hour: u8, - minute: u8, - second: u8, -) -> Result { - let day_of_week = day_of_week_from_u8(day_of_week)?; - Ok(DateTime { - year, - month, - day, - day_of_week, - hour, - minute, - second, - }) -} diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 552dcc76..c8990c30 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -9,7 +9,8 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; #[cfg(feature = "low-power")] use embassy_sync::blocking_mutex::Mutex; -pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; +pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError, RtcInstant}; +use crate::rtc::datetime::day_of_week_to_u8; use crate::time::Hertz; /// refer to AN4759 to compare features of RTC2 and RTC3 @@ -39,48 +40,6 @@ pub enum RtcError { NotRunning, } -#[cfg(feature = "low-power")] -/// Represents an instant in time that can be substracted to compute a duration -struct RtcInstant { - second: u8, - subsecond: u16, -} - -#[cfg(all(feature = "low-power", feature = "defmt"))] -impl defmt::Format for RtcInstant { - fn format(&self, fmt: defmt::Formatter) { - defmt::write!( - fmt, - "{}:{}", - self.second, - RTC::regs().prer().read().prediv_s() - self.subsecond, - ) - } -} - -#[cfg(feature = "low-power")] -impl core::ops::Sub for RtcInstant { - type Output = embassy_time::Duration; - - fn sub(self, rhs: Self) -> Self::Output { - use embassy_time::{Duration, TICK_HZ}; - - let second = if self.second < rhs.second { - self.second + 60 - } else { - self.second - }; - - let psc = RTC::regs().prer().read().prediv_s() as u32; - - let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32); - let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32); - let rtc_ticks = self_ticks - other_ticks; - - Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64) - } -} - pub struct RtcTimeProvider { _private: (), } @@ -113,7 +72,7 @@ impl RtcTimeProvider { let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; - return self::datetime::datetime(year, month, day, weekday, hour, minute, second) + return DateTime::from(year, month, day, weekday, hour, minute, second) .map_err(RtcError::InvalidDateTime); } } @@ -134,7 +93,7 @@ impl RtcTimeProvider { let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; - self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) + DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) } } } @@ -184,7 +143,13 @@ impl Default for RtcCalibrationCyclePeriod { impl Rtc { pub fn new(_rtc: impl Peripheral

, rtc_config: RtcConfig) -> Self { #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] - ::enable_and_reset(); + critical_section::with(|cs| { + ::enable_and_reset_with_cs(cs); + #[cfg(feature = "low-power")] + unsafe { + crate::rcc::REFCOUNT_STOP2 -= 1 + }; + }); let mut this = Self { #[cfg(feature = "low-power")] @@ -219,14 +184,46 @@ impl Rtc { /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?; - self.write(true, |rtc| self::datetime::write_date_time(rtc, t)); + self.write(true, |rtc| { + let (ht, hu) = byte_to_bcd2(t.hour() as u8); + let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); + let (st, su) = byte_to_bcd2(t.second() as u8); + + let (dt, du) = byte_to_bcd2(t.day() as u8); + let (mt, mu) = byte_to_bcd2(t.month() as u8); + let yr = t.year() as u16; + let yr_offset = (yr - 1970_u16) as u8; + let (yt, yu) = byte_to_bcd2(yr_offset); + + use crate::pac::rtc::vals::Ampm; + + rtc.tr().write(|w| { + w.set_ht(ht); + w.set_hu(hu); + w.set_mnt(mnt); + w.set_mnu(mnu); + w.set_st(st); + w.set_su(su); + w.set_pm(Ampm::AM); + }); + + rtc.dr().write(|w| { + w.set_dt(dt); + w.set_du(du); + w.set_mt(mt > 0); + w.set_mu(mu); + w.set_yt(yt); + w.set_yu(yu); + w.set_wdu(day_of_week_to_u8(t.day_of_week())); + }); + }); Ok(()) } - #[cfg(feature = "low-power")] + #[cfg(not(rtc_v2f2))] /// Return the current instant. - fn instant(&self) -> RtcInstant { + pub fn instant(&self) -> Result { let r = RTC::regs(); let tr = r.tr().read(); let subsecond = r.ssr().read().ss(); @@ -235,7 +232,7 @@ impl Rtc { // Unlock the registers r.dr().read(); - RtcInstant { second, subsecond } + RtcInstant::from(second, subsecond.try_into().unwrap()) } /// Return the current datetime. diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index eeb23e1f..b6ab9b20 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -95,15 +95,16 @@ impl super::Rtc { regs.cr().modify(|w| w.set_wutie(true)); }); + let instant = self.instant().unwrap(); trace!( "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), prescaler as u32, rtc_ticks, - self.instant(), + instant, ); - assert!(self.stop_time.borrow(cs).replace(Some(self.instant())).is_none()) + assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none()) } #[cfg(feature = "low-power")] @@ -112,8 +113,9 @@ impl super::Rtc { pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { use crate::interrupt::typelevel::Interrupt; + let instant = self.instant().unwrap(); if RTC::regs().cr().read().wute() { - trace!("rtc: stop wakeup alarm at {}", self.instant()); + trace!("rtc: stop wakeup alarm at {}", instant); self.write(false, |regs| { regs.cr().modify(|w| w.set_wutie(false)); @@ -128,10 +130,7 @@ impl super::Rtc { }); } - self.stop_time - .borrow(cs) - .take() - .map(|stop_time| self.instant() - stop_time) + self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) } #[cfg(feature = "low-power")] diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index bc29fe54..a99a5707 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -1457,7 +1457,7 @@ cfg_if::cfg_if! { macro_rules! kernel_clk { ($inst:ident) => { critical_section::with(|_| unsafe { - crate::rcc::get_freqs().pll48 + crate::rcc::get_freqs().pll1_q }).expect("PLL48 is required for SDIO") } } @@ -1466,20 +1466,20 @@ cfg_if::cfg_if! { (SDMMC1) => { critical_section::with(|_| unsafe { let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc1sel(); - if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { + if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS { crate::rcc::get_freqs().sys } else { - crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") + crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") } }) }; (SDMMC2) => { critical_section::with(|_| unsafe { let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc2sel(); - if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYSCLK { + if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS { crate::rcc::get_freqs().sys } else { - crate::rcc::get_freqs().pll48.expect("PLL48 is required for SDMMC") + crate::rcc::get_freqs().pll1_q.expect("PLL48 is required for SDMMC") } }) }; diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index e1baf6b2..6654366c 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -57,18 +57,20 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { _ch4: Option>, _ch4n: Option>, freq: Hertz, + counting_mode: CountingMode, ) -> Self { - Self::new_inner(tim, freq) + Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { + fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { into_ref!(tim); T::enable_and_reset(); let mut this = Self { inner: tim }; - this.inner.set_frequency(freq); + this.inner.set_counting_mode(counting_mode); + this.set_freq(freq); this.inner.start(); this.inner.enable_outputs(); @@ -95,7 +97,12 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { } pub fn set_freq(&mut self, freq: Hertz) { - self.inner.set_frequency(freq); + let multiplier = if self.inner.get_counting_mode().is_center_aligned() { + 2u8 + } else { + 1u8 + }; + self.inner.set_frequency(freq * multiplier); } pub fn get_max_duty(&self) -> u16 { diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 4b88834c..913bfed2 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -29,10 +29,17 @@ pub(crate) mod sealed { Self::regs().cr1().modify(|r| r.set_cen(false)); } + /// Reset the counter value to 0 fn reset(&mut self) { Self::regs().cnt().write(|r| r.set_cnt(0)); } + /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. + /// + /// This means that in the default edge-aligned mode, + /// the timer counter will wrap around at the same frequency as is being set. + /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved + /// because it needs to count up and down. fn set_frequency(&mut self, frequency: Hertz) { let f = frequency.0; let timer_f = Self::frequency().0; @@ -85,8 +92,21 @@ pub(crate) mod sealed { pub trait GeneralPurpose16bitInstance: Basic16bitInstance { fn regs_gp16() -> crate::pac::timer::TimGp16; - fn set_count_direction(&mut self, direction: vals::Dir) { - Self::regs_gp16().cr1().modify(|r| r.set_dir(direction)); + fn set_counting_mode(&mut self, mode: CountingMode) { + let (cms, dir) = mode.into(); + + let timer_enabled = Self::regs().cr1().read().cen(); + // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. + // Changing direction is discouraged while the timer is running. + assert!(!timer_enabled); + + Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); + Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) + } + + fn get_counting_mode(&self) -> CountingMode { + let cr1 = Self::regs_gp16().cr1().read(); + (cr1.cms(), cr1.dir()).into() } fn set_clock_division(&mut self, ckd: vals::Ckd) { @@ -293,6 +313,73 @@ impl From for stm32_metapac::timer::vals::CcmrInputCcs { } } +#[repr(u8)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum CountingMode { + #[default] + /// The timer counts up to the reload value and then resets back to 0. + EdgeAlignedUp, + /// The timer counts down to 0 and then resets back to the reload value. + EdgeAlignedDown, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting down. + CenterAlignedDownInterrupts, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting up. + CenterAlignedUpInterrupts, + /// The timer counts up to the reload value and then counts back to 0. + /// + /// The output compare interrupt flags of channels configured in output are + /// set when the counter is counting both up or down. + CenterAlignedBothInterrupts, +} + +impl CountingMode { + pub fn is_edge_aligned(&self) -> bool { + match self { + CountingMode::EdgeAlignedUp | CountingMode::EdgeAlignedDown => true, + _ => false, + } + } + + pub fn is_center_aligned(&self) -> bool { + match self { + CountingMode::CenterAlignedDownInterrupts + | CountingMode::CenterAlignedUpInterrupts + | CountingMode::CenterAlignedBothInterrupts => true, + _ => false, + } + } +} + +impl From for (vals::Cms, vals::Dir) { + fn from(value: CountingMode) -> Self { + match value { + CountingMode::EdgeAlignedUp => (vals::Cms::EDGEALIGNED, vals::Dir::UP), + CountingMode::EdgeAlignedDown => (vals::Cms::EDGEALIGNED, vals::Dir::DOWN), + CountingMode::CenterAlignedDownInterrupts => (vals::Cms::CENTERALIGNED1, vals::Dir::UP), + CountingMode::CenterAlignedUpInterrupts => (vals::Cms::CENTERALIGNED2, vals::Dir::UP), + CountingMode::CenterAlignedBothInterrupts => (vals::Cms::CENTERALIGNED3, vals::Dir::UP), + } + } +} + +impl From<(vals::Cms, vals::Dir)> for CountingMode { + fn from(value: (vals::Cms, vals::Dir)) -> Self { + match value { + (vals::Cms::EDGEALIGNED, vals::Dir::UP) => CountingMode::EdgeAlignedUp, + (vals::Cms::EDGEALIGNED, vals::Dir::DOWN) => CountingMode::EdgeAlignedDown, + (vals::Cms::CENTERALIGNED1, _) => CountingMode::CenterAlignedDownInterrupts, + (vals::Cms::CENTERALIGNED2, _) => CountingMode::CenterAlignedUpInterrupts, + (vals::Cms::CENTERALIGNED3, _) => CountingMode::CenterAlignedBothInterrupts, + } + } +} + #[derive(Clone, Copy)] pub enum OutputCompareMode { Frozen, @@ -471,9 +558,5 @@ foreach_interrupt! { crate::pac::$inst } } - - - - }; } diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 01773ff3..1cf0ad72 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -56,18 +56,20 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { _ch3: Option>, _ch4: Option>, freq: Hertz, + counting_mode: CountingMode, ) -> Self { - Self::new_inner(tim, freq) + Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { + fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { into_ref!(tim); T::enable_and_reset(); let mut this = Self { inner: tim }; - this.inner.set_frequency(freq); + this.inner.set_counting_mode(counting_mode); + this.set_freq(freq); this.inner.start(); this.inner.enable_outputs(); @@ -92,7 +94,12 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { } pub fn set_freq(&mut self, freq: Hertz) { - self.inner.set_frequency(freq); + let multiplier = if self.inner.get_counting_mode().is_center_aligned() { + 2u8 + } else { + 1u8 + }; + self.inner.set_frequency(freq * multiplier); } pub fn get_max_duty(&self) -> u16 { diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index cbc13a34..4daddfe9 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -116,28 +116,28 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } @@ -233,9 +233,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { configure(r, &config, T::frequency(), T::KIND, true, true)?; r.cr1().modify(|w| { - #[cfg(lpuart_v2)] - w.set_fifoen(true); - w.set_rxneie(true); w.set_idleie(true); }); @@ -254,7 +251,14 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -334,7 +338,14 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } @@ -408,7 +419,14 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) + reconfigure::(config)?; + + T::regs().cr1().modify(|w| { + w.set_rxneie(true); + w.set_idleie(true); + }); + + Ok(()) } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 880ca416..ea127e7f 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -108,6 +108,7 @@ pub enum StopBits { pub enum ConfigError { BaudrateTooLow, BaudrateTooHigh, + RxOrTxNotEnabled, } #[non_exhaustive] @@ -181,11 +182,11 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.tx.set_config(config).map_err(|_| ())?; - self.rx.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.tx.set_config(config)?; + self.rx.set_config(config) } } @@ -196,10 +197,10 @@ pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } @@ -213,10 +214,10 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } @@ -866,7 +867,7 @@ fn configure( enable_tx: bool, ) -> Result<(), ConfigError> { if !enable_rx && !enable_tx { - panic!("USART: At least one of RX or TX should be enabled"); + return Err(ConfigError::RxOrTxNotEnabled); } #[cfg(not(usart_v4))] @@ -909,6 +910,11 @@ fn configure( brr + rounding } + // UART must be disabled during configuration. + r.cr1().modify(|w| { + w.set_ue(false); + }); + #[cfg(not(usart_v1))] let mut over8 = false; let mut found_brr = None; @@ -968,6 +974,12 @@ fn configure( #[cfg(any(usart_v3, usart_v4))] w.set_swap(config.swap_rx_tx); }); + + #[cfg(not(usart_v1))] + r.cr3().modify(|w| { + w.set_onebit(config.assume_noise_free); + }); + r.cr1().write(|w| { // enable uart w.set_ue(true); @@ -976,6 +988,7 @@ fn configure( // enable receiver w.set_re(enable_rx); // configure word size + // if using odd or even parity it must be configured to 9bits w.set_m0(if config.parity != Parity::ParityNone { vals::M0::BIT9 } else { @@ -994,11 +1007,6 @@ fn configure( w.set_fifoen(true); }); - #[cfg(not(usart_v1))] - r.cr3().modify(|w| { - w.set_onebit(config.assume_noise_free); - }); - Ok(()) } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 55489f2e..eceabbe9 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -18,10 +18,10 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma> { impl<'d, T: BasicInstance, RxDma: super::RxDma> SetConfig for RingBufferedUartRx<'d, T, RxDma> { type Config = Config; - type ConfigError = (); + type ConfigError = ConfigError; - fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { - self.set_config(config).map_err(|_| ()) + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { + self.set_config(config) } } diff --git a/embassy-time/CHANGELOG.md b/embassy-time/CHANGELOG.md index 0dd938c2..1421d76a 100644 --- a/embassy-time/CHANGELOG.md +++ b/embassy-time/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.6 - ??? + +- Added tick rates in multiples of 10 kHz + +## 0.1.5 - 2023-10-16 + +- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary. + Needed because different copies might get different tick rates, causing + wrong delays if the time driver is using one copy and user code is using another. + This is especially common when mixing crates from crates.io and git. + ## 0.1.4 - 2023-10-12 - Added more tick rates diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index e4b88d78..62404863 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embassy-time" -version = "0.1.4" +version = "0.1.5" edition = "2021" description = "Instant and Duration for embedded no-std systems, with async timer support" repository = "https://github.com/embassy-rs/embassy" @@ -13,6 +13,12 @@ categories = [ "asynchronous", ] +# Prevent multiple copies of this crate in the same binary. +# Needed because different copies might get different tick rates, causing +# wrong delays if the time driver is using one copy and user code is using another. +# This is especially common when mixing crates from crates.io and git. +links = "embassy-time" + [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-time-v$VERSION/embassy-time/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-time/src/" @@ -120,6 +126,25 @@ tick-hz-65_536_000 = [] tick-hz-131_072_000 = [] tick-hz-262_144_000 = [] tick-hz-524_288_000 = [] +tick-hz-20_000 = [] +tick-hz-40_000 = [] +tick-hz-80_000 = [] +tick-hz-160_000 = [] +tick-hz-320_000 = [] +tick-hz-640_000 = [] +tick-hz-1_280_000 = [] +tick-hz-2_560_000 = [] +tick-hz-5_120_000 = [] +tick-hz-10_240_000 = [] +tick-hz-20_480_000 = [] +tick-hz-40_960_000 = [] +tick-hz-81_920_000 = [] +tick-hz-163_840_000 = [] +tick-hz-327_680_000 = [] +tick-hz-655_360_000 = [] +tick-hz-1_310_720_000 = [] +tick-hz-2_621_440_000 = [] +tick-hz-5_242_880_000 = [] tick-hz-2_000_000 = [] tick-hz-3_000_000 = [] tick-hz-4_000_000 = [] diff --git a/embassy-time/build.rs b/embassy-time/build.rs new file mode 100644 index 00000000..5b009566 --- /dev/null +++ b/embassy-time/build.rs @@ -0,0 +1,3 @@ +// empty, needed to be able to use `links` in Cargo.toml. + +fn main() {} diff --git a/embassy-time/gen_tick.py b/embassy-time/gen_tick.py index 67a4c79c..d4a17591 100644 --- a/embassy-time/gen_tick.py +++ b/embassy-time/gen_tick.py @@ -13,6 +13,8 @@ for i in range(1, 25): ticks.append(2**i) for i in range(1, 20): ticks.append(2**i * 1000) +for i in range(1, 20): + ticks.append(2**i * 10000) for i in range(1, 10): ticks.append(2**i * 1000000) ticks.append(2**i * 9 // 8 * 1000000) diff --git a/embassy-time/src/delay.rs b/embassy-time/src/delay.rs index cf191872..be962747 100644 --- a/embassy-time/src/delay.rs +++ b/embassy-time/src/delay.rs @@ -36,11 +36,11 @@ mod eha { impl embedded_hal_async::delay::DelayUs for Delay { async fn delay_us(&mut self, micros: u32) { - Timer::after(Duration::from_micros(micros as _)).await + Timer::after_micros(micros as _).await } async fn delay_ms(&mut self, millis: u32) { - Timer::after(Duration::from_millis(millis as _)).await + Timer::after_millis(millis as _).await } } } diff --git a/embassy-time/src/tick.rs b/embassy-time/src/tick.rs index be544181..834e7c09 100644 --- a/embassy-time/src/tick.rs +++ b/embassy-time/src/tick.rs @@ -106,6 +106,44 @@ pub const TICK_HZ: u64 = 131_072_000; pub const TICK_HZ: u64 = 262_144_000; #[cfg(feature = "tick-hz-524_288_000")] pub const TICK_HZ: u64 = 524_288_000; +#[cfg(feature = "tick-hz-20_000")] +pub const TICK_HZ: u64 = 20_000; +#[cfg(feature = "tick-hz-40_000")] +pub const TICK_HZ: u64 = 40_000; +#[cfg(feature = "tick-hz-80_000")] +pub const TICK_HZ: u64 = 80_000; +#[cfg(feature = "tick-hz-160_000")] +pub const TICK_HZ: u64 = 160_000; +#[cfg(feature = "tick-hz-320_000")] +pub const TICK_HZ: u64 = 320_000; +#[cfg(feature = "tick-hz-640_000")] +pub const TICK_HZ: u64 = 640_000; +#[cfg(feature = "tick-hz-1_280_000")] +pub const TICK_HZ: u64 = 1_280_000; +#[cfg(feature = "tick-hz-2_560_000")] +pub const TICK_HZ: u64 = 2_560_000; +#[cfg(feature = "tick-hz-5_120_000")] +pub const TICK_HZ: u64 = 5_120_000; +#[cfg(feature = "tick-hz-10_240_000")] +pub const TICK_HZ: u64 = 10_240_000; +#[cfg(feature = "tick-hz-20_480_000")] +pub const TICK_HZ: u64 = 20_480_000; +#[cfg(feature = "tick-hz-40_960_000")] +pub const TICK_HZ: u64 = 40_960_000; +#[cfg(feature = "tick-hz-81_920_000")] +pub const TICK_HZ: u64 = 81_920_000; +#[cfg(feature = "tick-hz-163_840_000")] +pub const TICK_HZ: u64 = 163_840_000; +#[cfg(feature = "tick-hz-327_680_000")] +pub const TICK_HZ: u64 = 327_680_000; +#[cfg(feature = "tick-hz-655_360_000")] +pub const TICK_HZ: u64 = 655_360_000; +#[cfg(feature = "tick-hz-1_310_720_000")] +pub const TICK_HZ: u64 = 1_310_720_000; +#[cfg(feature = "tick-hz-2_621_440_000")] +pub const TICK_HZ: u64 = 2_621_440_000; +#[cfg(feature = "tick-hz-5_242_880_000")] +pub const TICK_HZ: u64 = 5_242_880_000; #[cfg(feature = "tick-hz-2_000_000")] pub const TICK_HZ: u64 = 2_000_000; #[cfg(feature = "tick-hz-3_000_000")] @@ -334,6 +372,25 @@ pub const TICK_HZ: u64 = 980_000_000; feature = "tick-hz-131_072_000", feature = "tick-hz-262_144_000", feature = "tick-hz-524_288_000", + feature = "tick-hz-20_000", + feature = "tick-hz-40_000", + feature = "tick-hz-80_000", + feature = "tick-hz-160_000", + feature = "tick-hz-320_000", + feature = "tick-hz-640_000", + feature = "tick-hz-1_280_000", + feature = "tick-hz-2_560_000", + feature = "tick-hz-5_120_000", + feature = "tick-hz-10_240_000", + feature = "tick-hz-20_480_000", + feature = "tick-hz-40_960_000", + feature = "tick-hz-81_920_000", + feature = "tick-hz-163_840_000", + feature = "tick-hz-327_680_000", + feature = "tick-hz-655_360_000", + feature = "tick-hz-1_310_720_000", + feature = "tick-hz-2_621_440_000", + feature = "tick-hz-5_242_880_000", feature = "tick-hz-2_000_000", feature = "tick-hz-3_000_000", feature = "tick-hz-4_000_000", diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs index 07ddf473..ee2423da 100644 --- a/embassy-time/src/timer.rs +++ b/embassy-time/src/timer.rs @@ -64,6 +64,42 @@ impl Timer { yielded_once: false, } } + + /// Expire after the specified number of ticks. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_ticks())`. + /// For more details, refer to [`Timer::after()`] and [`Duration::from_ticks()`]. + #[inline] + pub fn after_ticks(ticks: u64) -> Self { + Self::after(Duration::from_ticks(ticks)) + } + + /// Expire after the specified number of microseconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_micros())`. + /// For more details, refer to [`Timer::after()`] and [`Duration::from_micros()`]. + #[inline] + pub fn after_micros(micros: u64) -> Self { + Self::after(Duration::from_micros(micros)) + } + + /// Expire after the specified number of milliseconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_millis())`. + /// For more details, refer to [`Timer::after`] and [`Duration::from_millis()`]. + #[inline] + pub fn after_millis(millis: u64) -> Self { + Self::after(Duration::from_millis(millis)) + } + + /// Expire after the specified number of seconds. + /// + /// This method is a convenience wrapper for calling `Timer::after(Duration::from_secs())`. + /// For more details, refer to [`Timer::after`] and [`Duration::from_secs()`]. + #[inline] + pub fn after_secs(secs: u64) -> Self { + Self::after(Duration::from_secs(secs)) + } } impl Unpin for Timer {} diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 0e7e0e70..9ae14499 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -42,7 +42,7 @@ max-handler-count-8 = [] embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } embassy-sync = { version = "0.3.0", path = "../embassy-sync" } -embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" } +embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-usb/build.rs b/embassy-usb/build.rs index 33d32f7d..5e3bec48 100644 --- a/embassy-usb/build.rs +++ b/embassy-usb/build.rs @@ -70,9 +70,11 @@ fn main() { // envvars take priority. if !cfg.seen_env { - if cfg.seen_feature { - panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value); - } + assert!( + !cfg.seen_feature, + "multiple values set for feature {}: {} and {}", + name, cfg.value, value + ); cfg.value = value; cfg.seen_feature = true; diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index 6b68bcd7..b4ddccd7 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs @@ -1,17 +1,17 @@ use heapless::Vec; -use crate::config::*; +use crate::config::MAX_HANDLER_COUNT; use crate::descriptor::{BosWriter, DescriptorWriter}; use crate::driver::{Driver, Endpoint, EndpointType}; #[cfg(feature = "msos-descriptor")] use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START}; #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] -/// Configuration used when creating [UsbDevice]. +/// Configuration used when creating [`UsbDevice`]. pub struct Config<'a> { pub(crate) vendor_id: u16, pub(crate) product_id: u16, @@ -99,7 +99,7 @@ pub struct Config<'a> { impl<'a> Config<'a> { /// Create default configuration with the provided vid and pid values. - pub fn new(vid: u16, pid: u16) -> Self { + pub const fn new(vid: u16, pid: u16) -> Self { Self { device_class: 0x00, device_sub_class: 0x00, @@ -159,9 +159,10 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { panic!("if composite_with_iads is set, you must set device_class = 0xEF, device_sub_class = 0x02, device_protocol = 0x01"); } - if config.max_power > 500 { - panic!("The maximum allowed value for `max_power` is 500mA"); - } + assert!( + config.max_power <= 500, + "The maximum allowed value for `max_power` is 500mA" + ); match config.max_packet_size_0 { 8 | 16 | 32 | 64 => {} @@ -260,12 +261,11 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { /// The Handler is called on some USB bus events, and to handle all control requests not already /// handled by the USB stack. pub fn handler(&mut self, handler: &'d mut dyn Handler) { - if self.handlers.push(handler).is_err() { - panic!( - "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}", - MAX_HANDLER_COUNT - ) - } + assert!( + self.handlers.push(handler).is_ok(), + "embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}", + MAX_HANDLER_COUNT + ); } /// Allocates a new string index. @@ -332,12 +332,10 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> { num_alt_settings: 0, }; - if self.builder.interfaces.push(iface).is_err() { - panic!( - "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}", - MAX_INTERFACE_COUNT - ) - } + assert!(self.builder.interfaces.push(iface).is_ok(), + "embassy-usb: interface list full. Increase the `max_interface_count` compile-time setting. Current value: {}", + MAX_INTERFACE_COUNT + ); InterfaceBuilder { builder: self.builder, @@ -371,7 +369,7 @@ pub struct InterfaceBuilder<'a, 'd, D: Driver<'d>> { impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> { /// Get the interface number. - pub fn interface_number(&self) -> InterfaceNumber { + pub const fn interface_number(&self) -> InterfaceNumber { self.interface_number } @@ -422,12 +420,12 @@ pub struct InterfaceAltBuilder<'a, 'd, D: Driver<'d>> { impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { /// Get the interface number. - pub fn interface_number(&self) -> InterfaceNumber { + pub const fn interface_number(&self) -> InterfaceNumber { self.interface_number } /// Get the alternate setting number. - pub fn alt_setting_number(&self) -> u8 { + pub const fn alt_setting_number(&self) -> u8 { self.alt_setting_number } @@ -436,7 +434,7 @@ impl<'a, 'd, D: Driver<'d>> InterfaceAltBuilder<'a, 'd, D> { /// Descriptors are written in the order builder functions are called. Note that some /// classes care about the order. pub fn descriptor(&mut self, descriptor_type: u8, descriptor: &[u8]) { - self.builder.config_descriptor.write(descriptor_type, descriptor) + self.builder.config_descriptor.write(descriptor_type, descriptor); } fn endpoint_in(&mut self, ep_type: EndpointType, max_packet_size: u16, interval_ms: u8) -> D::EndpointIn { diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 0c708464..f1066d2f 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -11,7 +11,7 @@ use embassy_sync::waitqueue::WakerRegistration; use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType}; use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use crate::types::*; +use crate::types::InterfaceNumber; use crate::{Builder, Handler}; /// This should be used as `device_class` when building the `UsbDevice`. @@ -39,12 +39,18 @@ pub struct State<'a> { shared: ControlShared, } +impl<'a> Default for State<'a> { + fn default() -> Self { + Self::new() + } +} + impl<'a> State<'a> { /// Create a new `State`. pub fn new() -> Self { Self { control: MaybeUninit::uninit(), - shared: Default::default(), + shared: ControlShared::default(), } } } @@ -55,9 +61,9 @@ impl<'a> State<'a> { /// writing USB packets with no intermediate buffers, but it will not act like a stream-like serial /// port. The following constraints must be followed if you use this class directly: /// -/// - `read_packet` must be called with a buffer large enough to hold max_packet_size bytes. -/// - `write_packet` must not be called with a buffer larger than max_packet_size bytes. -/// - If you write a packet that is exactly max_packet_size bytes long, it won't be processed by the +/// - `read_packet` must be called with a buffer large enough to hold `max_packet_size` bytes. +/// - `write_packet` must not be called with a buffer larger than `max_packet_size` bytes. +/// - If you write a packet that is exactly `max_packet_size` bytes long, it won't be processed by the /// host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP) /// can be sent if there is no other data to send. This is because USB bulk transactions must be /// terminated with a short packet, even if the bulk endpoint is used for stream-like data. @@ -103,17 +109,16 @@ impl Default for ControlShared { impl ControlShared { async fn changed(&self) { - poll_fn(|cx| match self.changed.load(Ordering::Relaxed) { - true => { + poll_fn(|cx| { + if self.changed.load(Ordering::Relaxed) { self.changed.store(false, Ordering::Relaxed); Poll::Ready(()) - } - false => { + } else { self.waker.borrow_mut().register(cx.waker()); Poll::Pending } }) - .await + .await; } } @@ -192,7 +197,7 @@ impl<'d> Handler for Control<'d> { // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below. REQ_GET_LINE_CODING if req.length == 7 => { debug!("Sending line coding"); - let coding = self.shared().line_coding.lock(|x| x.get()); + let coding = self.shared().line_coding.lock(Cell::get); assert!(buf.len() >= 7); buf[0..4].copy_from_slice(&coding.data_rate.to_le_bytes()); buf[4] = coding.stop_bits as u8; @@ -206,8 +211,8 @@ impl<'d> Handler for Control<'d> { } impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { - /// Creates a new CdcAcmClass with the provided UsbBus and max_packet_size in bytes. For - /// full-speed devices, max_packet_size has to be one of 8, 16, 32 or 64. + /// Creates a new CdcAcmClass with the provided UsbBus and `max_packet_size` in bytes. For + /// full-speed devices, `max_packet_size` has to be one of 8, 16, 32 or 64. pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State<'d>, max_packet_size: u16) -> Self { assert!(builder.control_buf_len() >= 7); @@ -242,7 +247,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { &[ CDC_TYPE_UNION, // bDescriptorSubtype comm_if.into(), // bControlInterface - data_if.into(), // bSubordinateInterface + data_if, // bSubordinateInterface ], ); @@ -283,7 +288,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -308,7 +313,7 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } /// Split the class into a sender and receiver. @@ -356,7 +361,7 @@ pub struct ControlChanged<'d> { impl<'d> ControlChanged<'d> { /// Return a future for when the control settings change pub async fn control_changed(&self) { - self.control.changed().await + self.control.changed().await; } } @@ -378,7 +383,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -398,7 +403,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.write_ep.wait_enabled().await + self.write_ep.wait_enabled().await; } } @@ -420,7 +425,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { /// Gets the current line coding. The line coding contains information that's mainly relevant /// for USB to UART serial port emulators, and can be ignored if not relevant. pub fn line_coding(&self) -> LineCoding { - self.control.line_coding.lock(|x| x.get()) + self.control.line_coding.lock(Cell::get) } /// Gets the DTR (data terminal ready) state @@ -440,7 +445,7 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { /// Waits for the USB host to enable this interface pub async fn wait_connection(&mut self) { - self.read_ep.wait_enabled().await + self.read_ep.wait_enabled().await; } } @@ -514,17 +519,17 @@ impl LineCoding { } /// Gets the number of data bits for UART communication. - pub fn data_bits(&self) -> u8 { + pub const fn data_bits(&self) -> u8 { self.data_bits } /// Gets the parity type for UART communication. - pub fn parity_type(&self) -> ParityType { + pub const fn parity_type(&self) -> ParityType { self.parity_type } /// Gets the data rate in bits per second for UART communication. - pub fn data_rate(&self) -> u32 { + pub const fn data_rate(&self) -> u32 { self.data_rate } } diff --git a/embassy-usb/src/class/cdc_ncm/mod.rs b/embassy-usb/src/class/cdc_ncm/mod.rs index 830e9b76..bea9dac2 100644 --- a/embassy-usb/src/class/cdc_ncm/mod.rs +++ b/embassy-usb/src/class/cdc_ncm/mod.rs @@ -16,10 +16,11 @@ use core::intrinsics::copy_nonoverlapping; use core::mem::{size_of, MaybeUninit}; +use core::ptr::addr_of; use crate::control::{self, InResponse, OutResponse, Recipient, Request, RequestType}; use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::{Builder, Handler}; pub mod embassy_net; @@ -62,9 +63,9 @@ const REQ_SET_NTB_INPUT_SIZE: u8 = 0x86; //const NOTIF_POLL_INTERVAL: u8 = 20; const NTB_MAX_SIZE: usize = 2048; -const SIG_NTH: u32 = 0x484d434e; -const SIG_NDP_NO_FCS: u32 = 0x304d434e; -const SIG_NDP_WITH_FCS: u32 = 0x314d434e; +const SIG_NTH: u32 = 0x484d_434e; +const SIG_NDP_NO_FCS: u32 = 0x304d_434e; +const SIG_NDP_WITH_FCS: u32 = 0x314d_434e; const ALTERNATE_SETTING_DISABLED: u8 = 0x00; const ALTERNATE_SETTING_ENABLED: u8 = 0x01; @@ -111,7 +112,7 @@ struct NtbParametersDir { fn byteify(buf: &mut [u8], data: T) -> &[u8] { let len = size_of::(); - unsafe { copy_nonoverlapping(&data as *const _ as *const u8, buf.as_mut_ptr(), len) } + unsafe { copy_nonoverlapping(addr_of!(data).cast(), buf.as_mut_ptr(), len) } &buf[..len] } @@ -121,27 +122,28 @@ pub struct State<'a> { shared: ControlShared, } +impl<'a> Default for State<'a> { + fn default() -> Self { + Self::new() + } +} + impl<'a> State<'a> { /// Create a new `State`. pub fn new() -> Self { Self { control: MaybeUninit::uninit(), - shared: Default::default(), + shared: ControlShared::default(), } } } -/// Shared data between Control and CdcAcmClass +/// Shared data between Control and `CdcAcmClass` +#[derive(Default)] struct ControlShared { mac_addr: [u8; 6], } -impl Default for ControlShared { - fn default() -> Self { - ControlShared { mac_addr: [0; 6] } - } -} - struct Control<'a> { mac_addr_string: StringIndex, shared: &'a ControlShared, @@ -377,12 +379,12 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { /// /// This waits until the packet is successfully stored in the CDC-NCM endpoint buffers. pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { - let seq = self.seq; - self.seq = self.seq.wrapping_add(1); - const OUT_HEADER_LEN: usize = 28; const ABS_MAX_PACKET_SIZE: usize = 512; + let seq = self.seq; + self.seq = self.seq.wrapping_add(1); + let header = NtbOutHeader { nth_sig: SIG_NTH, nth_len: 0x0c, @@ -416,7 +418,7 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { self.write_ep.write(&buf[..self.max_packet_size]).await?; for chunk in d2.chunks(self.max_packet_size) { - self.write_ep.write(&chunk).await?; + self.write_ep.write(chunk).await?; } // Send ZLP if needed. @@ -459,12 +461,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { let ntb = &ntb[..pos]; // Process NTB header (NTH) - let nth = match ntb.get(..12) { - Some(x) => x, - None => { - warn!("Received too short NTB"); - continue; - } + let Some(nth) = ntb.get(..12) else { + warn!("Received too short NTB"); + continue; }; let sig = u32::from_le_bytes(nth[0..4].try_into().unwrap()); if sig != SIG_NTH { @@ -474,12 +473,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { let ndp_idx = u16::from_le_bytes(nth[10..12].try_into().unwrap()) as usize; // Process NTB Datagram Pointer (NDP) - let ndp = match ntb.get(ndp_idx..ndp_idx + 12) { - Some(x) => x, - None => { - warn!("NTH has an NDP pointer out of range."); - continue; - } + let Some(ndp) = ntb.get(ndp_idx..ndp_idx + 12) else { + warn!("NTH has an NDP pointer out of range."); + continue; }; let sig = u32::from_le_bytes(ndp[0..4].try_into().unwrap()); if sig != SIG_NDP_NO_FCS && sig != SIG_NDP_WITH_FCS { @@ -495,12 +491,9 @@ impl<'d, D: Driver<'d>> Receiver<'d, D> { } // Process actual datagram, finally. - let datagram = match ntb.get(datagram_index..datagram_index + datagram_len) { - Some(x) => x, - None => { - warn!("NDP has a datagram pointer out of range."); - continue; - } + let Some(datagram) = ntb.get(datagram_index..datagram_index + datagram_len) else { + warn!("NDP has a datagram pointer out of range."); + continue; }; buf[..datagram_len].copy_from_slice(datagram); diff --git a/embassy-usb/src/class/hid.rs b/embassy-usb/src/class/hid.rs index 889d66ec..0000b5b2 100644 --- a/embassy-usb/src/class/hid.rs +++ b/embassy-usb/src/class/hid.rs @@ -63,7 +63,7 @@ pub enum ReportId { } impl ReportId { - fn try_from(value: u16) -> Result { + const fn try_from(value: u16) -> Result { match value >> 8 { 1 => Ok(ReportId::In(value as u8)), 2 => Ok(ReportId::Out(value as u8)), @@ -79,9 +79,15 @@ pub struct State<'d> { out_report_offset: AtomicUsize, } +impl<'d> Default for State<'d> { + fn default() -> Self { + Self::new() + } +} + impl<'d> State<'d> { /// Create a new `State`. - pub fn new() -> Self { + pub const fn new() -> Self { State { control: MaybeUninit::uninit(), out_report_offset: AtomicUsize::new(0), @@ -148,7 +154,7 @@ fn build<'d, D: Driver<'d>>( } impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWriter<'d, D, READ_N, WRITE_N> { - /// Creates a new HidReaderWriter. + /// Creates a new `HidReaderWriter`. /// /// This will allocate one IN and one OUT endpoints. If you only need writing (sending) /// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only. @@ -171,7 +177,7 @@ impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWrit } /// Waits for both IN and OUT endpoints to be enabled. - pub async fn ready(&mut self) -> () { + pub async fn ready(&mut self) { self.reader.ready().await; self.writer.ready().await; } @@ -224,7 +230,7 @@ pub enum ReadError { impl From for ReadError { fn from(val: EndpointError) -> Self { - use EndpointError::*; + use EndpointError::{BufferOverflow, Disabled}; match val { BufferOverflow => ReadError::BufferOverflow, Disabled => ReadError::Disabled, @@ -251,17 +257,16 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { } /// Waits for the interrupt in endpoint to be enabled. - pub async fn ready(&mut self) -> () { - self.ep_in.wait_enabled().await + pub async fn ready(&mut self) { + self.ep_in.wait_enabled().await; } /// Writes an input report by serializing the given report structure. #[cfg(feature = "usbd-hid")] pub async fn write_serialize(&mut self, r: &IR) -> Result<(), EndpointError> { let mut buf: [u8; N] = [0; N]; - let size = match serialize(&mut buf, r) { - Ok(size) => size, - Err(_) => return Err(EndpointError::BufferOverflow), + let Ok(size) = serialize(&mut buf, r) else { + return Err(EndpointError::BufferOverflow); }; self.write(&buf[0..size]).await } @@ -286,8 +291,8 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { /// Waits for the interrupt out endpoint to be enabled. - pub async fn ready(&mut self) -> () { - self.ep_out.wait_enabled().await + pub async fn ready(&mut self) { + self.ep_out.wait_enabled().await; } /// Delivers output reports from the Interrupt Out pipe to `handler`. @@ -344,9 +349,8 @@ impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { if size < max_packet_size || total == N { self.offset.store(0, Ordering::Release); break; - } else { - self.offset.store(total, Ordering::Release); } + self.offset.store(total, Ordering::Release); } Err(err) => { self.offset.store(0, Ordering::Release); @@ -466,7 +470,7 @@ impl<'d> Handler for Control<'d> { HID_REQ_SET_IDLE => { if let Some(handler) = self.request_handler { let id = req.value as u8; - let id = (id != 0).then(|| ReportId::In(id)); + let id = (id != 0).then_some(ReportId::In(id)); let dur = u32::from(req.value >> 8); let dur = if dur == 0 { u32::MAX } else { 4 * dur }; handler.set_idle_ms(id, dur); @@ -522,7 +526,7 @@ impl<'d> Handler for Control<'d> { HID_REQ_GET_IDLE => { if let Some(handler) = self.request_handler { let id = req.value as u8; - let id = (id != 0).then(|| ReportId::In(id)); + let id = (id != 0).then_some(ReportId::In(id)); if let Some(dur) = handler.get_idle_ms(id) { let dur = u8::try_from(dur / 4).unwrap_or(0); buf[0] = dur; diff --git a/embassy-usb/src/class/midi.rs b/embassy-usb/src/class/midi.rs new file mode 100644 index 00000000..52a96f27 --- /dev/null +++ b/embassy-usb/src/class/midi.rs @@ -0,0 +1,227 @@ +//! MIDI class implementation. + +use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut}; +use crate::Builder; + +/// This should be used as `device_class` when building the `UsbDevice`. +pub const USB_AUDIO_CLASS: u8 = 0x01; + +const USB_AUDIOCONTROL_SUBCLASS: u8 = 0x01; +const USB_MIDISTREAMING_SUBCLASS: u8 = 0x03; +const MIDI_IN_JACK_SUBTYPE: u8 = 0x02; +const MIDI_OUT_JACK_SUBTYPE: u8 = 0x03; +const EMBEDDED: u8 = 0x01; +const EXTERNAL: u8 = 0x02; +const CS_INTERFACE: u8 = 0x24; +const CS_ENDPOINT: u8 = 0x25; +const HEADER_SUBTYPE: u8 = 0x01; +const MS_HEADER_SUBTYPE: u8 = 0x01; +const MS_GENERAL: u8 = 0x01; +const PROTOCOL_NONE: u8 = 0x00; +const MIDI_IN_SIZE: u8 = 0x06; +const MIDI_OUT_SIZE: u8 = 0x09; + +/// Packet level implementation of a USB MIDI device. +/// +/// This class can be used directly and it has the least overhead due to directly reading and +/// writing USB packets with no intermediate buffers, but it will not act like a stream-like port. +/// The following constraints must be followed if you use this class directly: +/// +/// - `read_packet` must be called with a buffer large enough to hold `max_packet_size` bytes. +/// - `write_packet` must not be called with a buffer larger than `max_packet_size` bytes. +/// - If you write a packet that is exactly `max_packet_size` bytes long, it won't be processed by the +/// host operating system until a subsequent shorter packet is sent. A zero-length packet (ZLP) +/// can be sent if there is no other data to send. This is because USB bulk transactions must be +/// terminated with a short packet, even if the bulk endpoint is used for stream-like data. +pub struct MidiClass<'d, D: Driver<'d>> { + read_ep: D::EndpointOut, + write_ep: D::EndpointIn, +} + +impl<'d, D: Driver<'d>> MidiClass<'d, D> { + /// Creates a new `MidiClass` with the provided UsbBus, number of input and output jacks and `max_packet_size` in bytes. + /// For full-speed devices, `max_packet_size` has to be one of 8, 16, 32 or 64. + pub fn new(builder: &mut Builder<'d, D>, n_in_jacks: u8, n_out_jacks: u8, max_packet_size: u16) -> Self { + let mut func = builder.function(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE); + + // Audio control interface + let mut iface = func.interface(); + let audio_if = iface.interface_number(); + let midi_if = u8::from(audio_if) + 1; + let mut alt = iface.alt_setting(USB_AUDIO_CLASS, USB_AUDIOCONTROL_SUBCLASS, PROTOCOL_NONE, None); + alt.descriptor(CS_INTERFACE, &[HEADER_SUBTYPE, 0x00, 0x01, 0x09, 0x00, 0x01, midi_if]); + + // MIDIStreaming interface + let mut iface = func.interface(); + let _midi_if = iface.interface_number(); + let mut alt = iface.alt_setting(USB_AUDIO_CLASS, USB_MIDISTREAMING_SUBCLASS, PROTOCOL_NONE, None); + + let midi_streaming_total_length = 7 + + (n_in_jacks + n_out_jacks) as usize * (MIDI_IN_SIZE + MIDI_OUT_SIZE) as usize + + 7 + + (4 + n_out_jacks as usize) + + 7 + + (4 + n_in_jacks as usize); + + alt.descriptor( + CS_INTERFACE, + &[ + MS_HEADER_SUBTYPE, + 0x00, + 0x01, + (midi_streaming_total_length & 0xFF) as u8, + ((midi_streaming_total_length >> 8) & 0xFF) as u8, + ], + ); + + // Calculates the index'th external midi in jack id + let in_jack_id_ext = |index| 2 * index + 1; + // Calculates the index'th embedded midi out jack id + let out_jack_id_emb = |index| 2 * index + 2; + // Calculates the index'th external midi out jack id + let out_jack_id_ext = |index| 2 * n_in_jacks + 2 * index + 1; + // Calculates the index'th embedded midi in jack id + let in_jack_id_emb = |index| 2 * n_in_jacks + 2 * index + 2; + + for i in 0..n_in_jacks { + alt.descriptor(CS_INTERFACE, &[MIDI_IN_JACK_SUBTYPE, EXTERNAL, in_jack_id_ext(i), 0x00]); + } + + for i in 0..n_out_jacks { + alt.descriptor(CS_INTERFACE, &[MIDI_IN_JACK_SUBTYPE, EMBEDDED, in_jack_id_emb(i), 0x00]); + } + + for i in 0..n_out_jacks { + alt.descriptor( + CS_INTERFACE, + &[ + MIDI_OUT_JACK_SUBTYPE, + EXTERNAL, + out_jack_id_ext(i), + 0x01, + in_jack_id_emb(i), + 0x01, + 0x00, + ], + ); + } + + for i in 0..n_in_jacks { + alt.descriptor( + CS_INTERFACE, + &[ + MIDI_OUT_JACK_SUBTYPE, + EMBEDDED, + out_jack_id_emb(i), + 0x01, + in_jack_id_ext(i), + 0x01, + 0x00, + ], + ); + } + + let mut endpoint_data = [ + MS_GENERAL, 0, // Number of jacks + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Jack mappings + ]; + endpoint_data[1] = n_out_jacks; + for i in 0..n_out_jacks { + endpoint_data[2 + i as usize] = in_jack_id_emb(i); + } + let read_ep = alt.endpoint_bulk_out(max_packet_size); + alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_out_jacks as usize]); + + endpoint_data[1] = n_in_jacks; + for i in 0..n_in_jacks { + endpoint_data[2 + i as usize] = out_jack_id_emb(i); + } + let write_ep = alt.endpoint_bulk_in(max_packet_size); + alt.descriptor(CS_ENDPOINT, &endpoint_data[0..2 + n_in_jacks as usize]); + + MidiClass { read_ep, write_ep } + } + + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.read_ep.info().max_packet_size + } + + /// Writes a single packet into the IN endpoint. + pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { + self.write_ep.write(data).await + } + + /// Reads a single packet from the OUT endpoint. + pub async fn read_packet(&mut self, data: &mut [u8]) -> Result { + self.read_ep.read(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.read_ep.wait_enabled().await; + } + + /// Split the class into a sender and receiver. + /// + /// This allows concurrently sending and receiving packets from separate tasks. + pub fn split(self) -> (Sender<'d, D>, Receiver<'d, D>) { + ( + Sender { + write_ep: self.write_ep, + }, + Receiver { read_ep: self.read_ep }, + ) + } +} + +/// Midi class packet sender. +/// +/// You can obtain a `Sender` with [`MidiClass::split`] +pub struct Sender<'d, D: Driver<'d>> { + write_ep: D::EndpointIn, +} + +impl<'d, D: Driver<'d>> Sender<'d, D> { + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.write_ep.info().max_packet_size + } + + /// Writes a single packet. + pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> { + self.write_ep.write(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.write_ep.wait_enabled().await; + } +} + +/// Midi class packet receiver. +/// +/// You can obtain a `Receiver` with [`MidiClass::split`] +pub struct Receiver<'d, D: Driver<'d>> { + read_ep: D::EndpointOut, +} + +impl<'d, D: Driver<'d>> Receiver<'d, D> { + /// Gets the maximum packet size in bytes. + pub fn max_packet_size(&self) -> u16 { + // The size is the same for both endpoints. + self.read_ep.info().max_packet_size + } + + /// Reads a single packet. + pub async fn read_packet(&mut self, data: &mut [u8]) -> Result { + self.read_ep.read(data).await + } + + /// Waits for the USB host to enable this interface + pub async fn wait_connection(&mut self) { + self.read_ep.wait_enabled().await; + } +} diff --git a/embassy-usb/src/class/mod.rs b/embassy-usb/src/class/mod.rs index b23e03d4..452eedf1 100644 --- a/embassy-usb/src/class/mod.rs +++ b/embassy-usb/src/class/mod.rs @@ -2,3 +2,4 @@ pub mod cdc_acm; pub mod cdc_ncm; pub mod hid; +pub mod midi; diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index ceccfd85..79f73630 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -120,7 +120,7 @@ impl Request { } /// Gets the descriptor type and index from the value field of a GET_DESCRIPTOR request. - pub fn descriptor_type_index(&self) -> (u8, u8) { + pub const fn descriptor_type_index(&self) -> (u8, u8) { ((self.value >> 8) as u8, self.value as u8) } } diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index ae38e26c..fa83ef58 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -2,7 +2,7 @@ use crate::builder::Config; use crate::driver::EndpointInfo; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; use crate::CONFIGURATION_VALUE; /// Standard descriptor types @@ -59,7 +59,7 @@ impl<'a> DescriptorWriter<'a> { } /// Gets the current position in the buffer, i.e. the number of bytes written so far. - pub fn position(&self) -> usize { + pub const fn position(&self) -> usize { self.position } @@ -67,9 +67,10 @@ impl<'a> DescriptorWriter<'a> { pub fn write(&mut self, descriptor_type: u8, descriptor: &[u8]) { let length = descriptor.len(); - if (self.position + 2 + length) > self.buf.len() || (length + 2) > 255 { - panic!("Descriptor buffer full"); - } + assert!( + (self.position + 2 + length) <= self.buf.len() && (length + 2) <= 255, + "Descriptor buffer full" + ); self.buf[self.position] = (length + 2) as u8; self.buf[self.position + 1] = descriptor_type; @@ -102,7 +103,7 @@ impl<'a> DescriptorWriter<'a> { config.serial_number.map_or(0, |_| 3), // iSerialNumber 1, // bNumConfigurations ], - ) + ); } pub(crate) fn configuration(&mut self, config: &Config) { @@ -120,7 +121,7 @@ impl<'a> DescriptorWriter<'a> { | if config.supports_remote_wakeup { 0x20 } else { 0x00 }, // bmAttributes (config.max_power / 2) as u8, // bMaxPower ], - ) + ); } #[allow(unused)] @@ -248,9 +249,7 @@ impl<'a> DescriptorWriter<'a> { pub(crate) fn string(&mut self, string: &str) { let mut pos = self.position; - if pos + 2 > self.buf.len() { - panic!("Descriptor buffer full"); - } + assert!(pos + 2 <= self.buf.len(), "Descriptor buffer full"); self.buf[pos] = 0; // length placeholder self.buf[pos + 1] = descriptor_type::STRING; @@ -258,9 +257,7 @@ impl<'a> DescriptorWriter<'a> { pos += 2; for c in string.encode_utf16() { - if pos >= self.buf.len() { - panic!("Descriptor buffer full"); - } + assert!(pos < self.buf.len(), "Descriptor buffer full"); self.buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); pos += 2; @@ -279,9 +276,9 @@ pub struct BosWriter<'a> { } impl<'a> BosWriter<'a> { - pub(crate) fn new(writer: DescriptorWriter<'a>) -> Self { + pub(crate) const fn new(writer: DescriptorWriter<'a>) -> Self { Self { - writer: writer, + writer, num_caps_mark: None, } } @@ -314,9 +311,10 @@ impl<'a> BosWriter<'a> { let mut start = self.writer.position; let blen = data.len(); - if (start + blen + 3) > self.writer.buf.len() || (blen + 3) > 255 { - panic!("Descriptor buffer full"); - } + assert!( + (start + blen + 3) <= self.writer.buf.len() && (blen + 3) <= 255, + "Descriptor buffer full" + ); self.writer.buf[start] = (blen + 3) as u8; self.writer.buf[start + 1] = descriptor_type::CAPABILITY; diff --git a/embassy-usb/src/descriptor_reader.rs b/embassy-usb/src/descriptor_reader.rs index 05adcce6..abb4b379 100644 --- a/embassy-usb/src/descriptor_reader.rs +++ b/embassy-usb/src/descriptor_reader.rs @@ -11,11 +11,11 @@ pub struct Reader<'a> { } impl<'a> Reader<'a> { - pub fn new(data: &'a [u8]) -> Self { + pub const fn new(data: &'a [u8]) -> Self { Self { data } } - pub fn eof(&self) -> bool { + pub const fn eof(&self) -> bool { self.data.is_empty() } @@ -102,7 +102,7 @@ pub fn foreach_endpoint(data: &[u8], mut f: impl FnMut(EndpointInfo)) -> Result< } descriptor_type::ENDPOINT => { ep.ep_address = EndpointAddress::from(r.read_u8()?); - f(ep) + f(ep); } _ => {} } diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 1180b9b6..88d88cad 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -24,12 +24,12 @@ use embassy_futures::select::{select, Either}; use heapless::Vec; pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder}; -use crate::config::*; -use crate::control::*; -use crate::descriptor::*; +use crate::config::{MAX_HANDLER_COUNT, MAX_INTERFACE_COUNT}; +use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType}; +use crate::descriptor::{descriptor_type, lang_id}; use crate::descriptor_reader::foreach_endpoint; use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event}; -use crate::types::*; +use crate::types::{InterfaceNumber, StringIndex}; /// The global state of the USB device. /// @@ -294,7 +294,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { /// After dropping the future, [`UsbDevice::disable()`] should be called /// before calling any other `UsbDevice` methods to fully reset the /// peripheral. - pub async fn run_until_suspend(&mut self) -> () { + pub async fn run_until_suspend(&mut self) { while !self.inner.suspended { let control_fut = self.control.setup(); let bus_fut = self.inner.bus.poll(); @@ -364,6 +364,8 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { } async fn handle_control_in(&mut self, req: Request) { + const DEVICE_DESCRIPTOR_LEN: usize = 18; + let mut resp_length = req.length as usize; let max_packet_size = self.control.max_packet_size(); @@ -371,19 +373,15 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { // The host doesn't know our EP0 max packet size yet, and might assume // a full-length packet is a short packet, thinking we're done sending data. // See https://github.com/hathach/tinyusb/issues/184 - const DEVICE_DESCRIPTOR_LEN: usize = 18; - if self.inner.address == 0 - && max_packet_size < DEVICE_DESCRIPTOR_LEN - && (max_packet_size as usize) < resp_length - { + if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length { trace!("received control req while not addressed: capping response to 1 packet."); resp_length = max_packet_size; } - match self.inner.handle_control_in(req, &mut self.control_buf) { + match self.inner.handle_control_in(req, self.control_buf) { InResponse::Accepted(data) => { let len = data.len().min(resp_length); - let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0; + let need_zlp = len != resp_length && (len % max_packet_size) == 0; let chunks = data[0..len] .chunks(max_packet_size) @@ -435,7 +433,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { self.control.accept_set_address(self.inner.address).await; self.inner.set_address_pending = false; } else { - self.control.accept().await + self.control.accept().await; } } OutResponse::Rejected => self.control.reject().await, @@ -548,9 +546,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { OutResponse::Accepted } - (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state { - UsbDeviceState::Default => OutResponse::Accepted, - _ => { + (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => { + if self.device_state != UsbDeviceState::Default { debug!("SET_CONFIGURATION: unconfigured"); self.device_state = UsbDeviceState::Addressed; @@ -564,17 +561,15 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { for h in &mut self.handlers { h.configured(false); } - - OutResponse::Accepted } - }, + OutResponse::Accepted + } _ => OutResponse::Rejected, }, (RequestType::Standard, Recipient::Interface) => { let iface_num = InterfaceNumber::new(req.index as _); - let iface = match self.interfaces.get_mut(iface_num.0 as usize) { - Some(iface) => iface, - None => return OutResponse::Rejected, + let Some(iface) = self.interfaces.get_mut(iface_num.0 as usize) else { + return OutResponse::Rejected; }; match req.request { @@ -650,9 +645,8 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { _ => InResponse::Rejected, }, (RequestType::Standard, Recipient::Interface) => { - let iface = match self.interfaces.get_mut(req.index as usize) { - Some(iface) => iface, - None => return InResponse::Rejected, + let Some(iface) = self.interfaces.get_mut(req.index as usize) else { + return InResponse::Rejected; }; match req.request { @@ -706,7 +700,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { } fn handle_control_in_delegated<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> { - unsafe fn extend_lifetime<'x, 'y>(r: InResponse<'x>) -> InResponse<'y> { + unsafe fn extend_lifetime<'y>(r: InResponse<'_>) -> InResponse<'y> { core::mem::transmute(r) } @@ -756,16 +750,12 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { }; if let Some(s) = s { - if buf.len() < 2 { - panic!("control buffer too small"); - } + assert!(buf.len() >= 2, "control buffer too small"); buf[1] = descriptor_type::STRING; let mut pos = 2; for c in s.encode_utf16() { - if pos + 2 >= buf.len() { - panic!("control buffer too small"); - } + assert!(pos + 2 < buf.len(), "control buffer too small"); buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes()); pos += 2; diff --git a/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 847338e5..13d5d7c4 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs @@ -6,7 +6,7 @@ use core::mem::size_of; -use super::{capability_type, BosWriter}; +use crate::descriptor::{capability_type, BosWriter}; use crate::types::InterfaceNumber; /// A serialized Microsoft OS 2.0 Descriptor set. diff --git a/embassy-usb/src/types.rs b/embassy-usb/src/types.rs index c7a47f7e..cb9fe257 100644 --- a/embassy-usb/src/types.rs +++ b/embassy-usb/src/types.rs @@ -7,7 +7,7 @@ pub struct InterfaceNumber(pub u8); impl InterfaceNumber { - pub(crate) fn new(index: u8) -> InterfaceNumber { + pub(crate) const fn new(index: u8) -> InterfaceNumber { InterfaceNumber(index) } } @@ -25,7 +25,7 @@ impl From for u8 { pub struct StringIndex(pub u8); impl StringIndex { - pub(crate) fn new(index: u8) -> StringIndex { + pub(crate) const fn new(index: u8) -> StringIndex { StringIndex(index) } } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 4c570cf2..275367ff 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly"] } embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot", features = ["nightly"] } embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf", features = ["nightly"] } diff --git a/examples/boot/application/nrf/src/bin/b.rs b/examples/boot/application/nrf/src/bin/b.rs index 15ebce5f..a88c3c56 100644 --- a/examples/boot/application/nrf/src/bin/b.rs +++ b/examples/boot/application/nrf/src/bin/b.rs @@ -5,7 +5,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -19,8 +19,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 330eac41..da89f15d 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly"] } embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] } embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs index a4602a7e..6fd5d7f6 100644 --- a/examples/boot/application/rp/src/bin/a.rs +++ b/examples/boot/application/rp/src/bin/a.rs @@ -41,7 +41,7 @@ async fn main(_s: Spawner) { let mut aligned = AlignedBuffer([0; 1]); let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; watchdog.feed(); led.set_high(); let mut offset = 0; @@ -61,7 +61,7 @@ async fn main(_s: Spawner) { watchdog.feed(); defmt::info!("firmware written, marking update"); updater.mark_updated().unwrap(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; led.set_low(); defmt::info!("update marked, resetting"); cortex_m::peripheral::SCB::sys_reset(); diff --git a/examples/boot/application/rp/src/bin/b.rs b/examples/boot/application/rp/src/bin/b.rs index 47dec329..1eca5b4a 100644 --- a/examples/boot/application/rp/src/bin/b.rs +++ b/examples/boot/application/rp/src/bin/b.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Level, Output}; use {defmt_rtt as _, panic_reset as _}; @@ -15,9 +15,9 @@ async fn main(_s: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; led.set_low(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index 0ee7241a..147a5bcf 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32f3/src/bin/b.rs b/examples/boot/application/stm32f3/src/bin/b.rs index a5862b1b..8411f384 100644 --- a/examples/boot/application/stm32f3/src/bin/b.rs +++ b/examples/boot/application/stm32f3/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index fdc02c28..3fa136ae 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32f7/src/bin/b.rs b/examples/boot/application/stm32f7/src/bin/b.rs index 16c94d84..4c2ad06a 100644 --- a/examples/boot/application/stm32f7/src/bin/b.rs +++ b/examples/boot/application/stm32f7/src/bin/b.rs @@ -6,21 +6,21 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut led = Output::new(p.PB7, Level::High, Speed::Low); led.set_high(); loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index de309ae0..7ca767bd 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32h7/src/bin/b.rs b/examples/boot/application/stm32h7/src/bin/b.rs index 34799279..5c03e2d0 100644 --- a/examples/boot/application/stm32h7/src/bin/b.rs +++ b/examples/boot/application/stm32h7/src/bin/b.rs @@ -6,21 +6,21 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut led = Output::new(p.PB14, Level::High, Speed::Low); led.set_high(); loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 5bee7458..3e3cbbd8 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index b4cdcd44..42e1a71e 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -11,7 +11,7 @@ use embassy_stm32::exti::ExtiInput; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[cfg(feature = "skip-include")] @@ -46,6 +46,6 @@ async fn main(_spawner: Spawner) { updater.mark_updated().await.unwrap(); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/boot/application/stm32l0/src/bin/b.rs b/examples/boot/application/stm32l0/src/bin/b.rs index ee40274f..52d42395 100644 --- a/examples/boot/application/stm32l0/src/bin/b.rs +++ b/examples/boot/application/stm32l0/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index cc0b4509..5e77b7d5 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index b4cdcd44..42e1a71e 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -11,7 +11,7 @@ use embassy_stm32::exti::ExtiInput; use embassy_stm32::flash::{Flash, WRITE_SIZE}; use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[cfg(feature = "skip-include")] @@ -46,6 +46,6 @@ async fn main(_spawner: Spawner) { updater.mark_updated().await.unwrap(); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/boot/application/stm32l1/src/bin/b.rs b/examples/boot/application/stm32l1/src/bin/b.rs index ee40274f..52d42395 100644 --- a/examples/boot/application/stm32l1/src/bin/b.rs +++ b/examples/boot/application/stm32l1/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index 85fff4bf..aa5c5cf9 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32l4/src/bin/b.rs b/examples/boot/application/stm32l4/src/bin/b.rs index a5862b1b..8411f384 100644 --- a/examples/boot/application/stm32l4/src/bin/b.rs +++ b/examples/boot/application/stm32l4/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index 78d92468..87b8a116 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } diff --git a/examples/boot/application/stm32wl/src/bin/b.rs b/examples/boot/application/stm32wl/src/bin/b.rs index f9f0ffc6..1ca3c6ea 100644 --- a/examples/boot/application/stm32wl/src/bin/b.rs +++ b/examples/boot/application/stm32wl/src/bin/b.rs @@ -6,7 +6,7 @@ use defmt_rtt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use panic_reset as _; #[embassy_executor::main] @@ -16,9 +16,9 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index 01983005..e5820f26 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -18,7 +18,7 @@ log = [ [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time" } +embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } diff --git a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs index cf8b2f80..88837569 100644 --- a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs +++ b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs @@ -6,7 +6,7 @@ use core::future::poll_fn; use core::task::Poll; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; #[cfg(feature = "log")] use log::*; use panic_probe as _; @@ -34,7 +34,7 @@ async fn run1() { info!("DING DONG"); #[cfg(not(feature = "log"))] rtos_trace::trace::marker(13); - Timer::after(Duration::from_ticks(16000)).await; + Timer::after_ticks(16000).await; } } diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index 7428f85f..a81d43a2 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -9,7 +9,7 @@ rtic = { version = "2", features = ["thumbv7-backend"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nightly", "unstable-traits", "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } defmt = "0.3" diff --git a/examples/nrf52840-rtic/memory.x b/examples/nrf52840-rtic/memory.x index 9b04edec..15b492bc 100644 --- a/examples/nrf52840-rtic/memory.x +++ b/examples/nrf52840-rtic/memory.x @@ -1,7 +1,12 @@ MEMORY { /* NOTE 1 K = 1 KiBi = 1024 bytes */ - /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */ FLASH : ORIGIN = 0x00000000, LENGTH = 1024K RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* These values correspond to the NRF52840 with Softdevices S140 7.3.0 */ + /* + FLASH : ORIGIN = 0x00027000, LENGTH = 868K + RAM : ORIGIN = 0x20020000, LENGTH = 128K + */ } diff --git a/examples/nrf52840-rtic/src/bin/blinky.rs b/examples/nrf52840-rtic/src/bin/blinky.rs index a682c193..060bb9eb 100644 --- a/examples/nrf52840-rtic/src/bin/blinky.rs +++ b/examples/nrf52840-rtic/src/bin/blinky.rs @@ -9,7 +9,7 @@ mod app { use defmt::info; use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::peripherals; - use embassy_time::{Duration, Timer}; + use embassy_time::Timer; #[shared] struct Shared {} @@ -34,10 +34,10 @@ mod app { loop { info!("off!"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("on!"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 7a3ef54f..75373350 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -31,9 +31,9 @@ nightly = [ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt", "msos-descriptor",], optional = true } embedded-io = { version = "0.6.0", features = ["defmt-03"] } embedded-io-async = { version = "0.6.0", optional = true, features = ["defmt-03"] } diff --git a/examples/nrf52840/memory.x b/examples/nrf52840/memory.x index 9b04edec..15b492bc 100644 --- a/examples/nrf52840/memory.x +++ b/examples/nrf52840/memory.x @@ -1,7 +1,12 @@ MEMORY { /* NOTE 1 K = 1 KiBi = 1024 bytes */ - /* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */ FLASH : ORIGIN = 0x00000000, LENGTH = 1024K RAM : ORIGIN = 0x20000000, LENGTH = 256K + + /* These values correspond to the NRF52840 with Softdevices S140 7.3.0 */ + /* + FLASH : ORIGIN = 0x00027000, LENGTH = 868K + RAM : ORIGIN = 0x20020000, LENGTH = 128K + */ } diff --git a/examples/nrf52840/src/bin/blinky.rs b/examples/nrf52840/src/bin/blinky.rs index 513f6cd8..d3d1a712 100644 --- a/examples/nrf52840/src/bin/blinky.rs +++ b/examples/nrf52840/src/bin/blinky.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/nrf52840/src/bin/channel.rs b/examples/nrf52840/src/bin/channel.rs index bd9c909d..d3c7b47d 100644 --- a/examples/nrf52840/src/bin/channel.rs +++ b/examples/nrf52840/src/bin/channel.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; enum LedState { @@ -21,9 +21,9 @@ static CHANNEL: Channel = Channel::new(); async fn my_task() { loop { CHANNEL.send(LedState::On).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; CHANNEL.send(LedState::Off).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs index ec4f1d80..79d2c404 100644 --- a/examples/nrf52840/src/bin/channel_sender_receiver.rs +++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::channel::{Channel, Receiver, Sender}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -22,9 +22,9 @@ static CHANNEL: StaticCell> = StaticCell::new async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) { loop { sender.send(LedState::On).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; sender.send(LedState::Off).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/executor_fairness_test.rs b/examples/nrf52840/src/bin/executor_fairness_test.rs index 2a28f276..f111b272 100644 --- a/examples/nrf52840/src/bin/executor_fairness_test.rs +++ b/examples/nrf52840/src/bin/executor_fairness_test.rs @@ -7,14 +7,14 @@ use core::task::Poll; use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] async fn run1() { loop { info!("DING DONG"); - Timer::after(Duration::from_ticks(16000)).await; + Timer::after_ticks(16000).await; } } diff --git a/examples/nrf52840/src/bin/lora_cad.rs b/examples/nrf52840/src/bin/lora_cad.rs index 3a98133c..38e6d619 100644 --- a/examples/nrf52840/src/bin/lora_cad.rs +++ b/examples/nrf52840/src/bin/lora_cad.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mdltn_params = { @@ -89,7 +89,7 @@ async fn main(_spawner: Spawner) { info!("cad successful without activity detected") } debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } Err(err) => info!("cad unsuccessful = {}", err), diff --git a/examples/nrf52840/src/bin/lora_p2p_receive.rs b/examples/nrf52840/src/bin/lora_p2p_receive.rs index 1d293c6b..4f41e124 100644 --- a/examples/nrf52840/src/bin/lora_p2p_receive.rs +++ b/examples/nrf52840/src/bin/lora_p2p_receive.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs b/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs index eee4d20e..3d34f6ae 100644 --- a/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs +++ b/examples/nrf52840/src/bin/lora_p2p_receive_duty_cycle.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull}; use embassy_nrf::{bind_interrupts, peripherals, spim}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -116,7 +116,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet") diff --git a/examples/nrf52840/src/bin/manually_create_executor.rs b/examples/nrf52840/src/bin/manually_create_executor.rs index 12ce660f..80364d34 100644 --- a/examples/nrf52840/src/bin/manually_create_executor.rs +++ b/examples/nrf52840/src/bin/manually_create_executor.rs @@ -8,7 +8,7 @@ use cortex_m_rt::entry; use defmt::{info, unwrap}; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -16,7 +16,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } @@ -24,7 +24,7 @@ async fn run1() { async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/multiprio.rs b/examples/nrf52840/src/bin/multiprio.rs index aab81911..352f62bf 100644 --- a/examples/nrf52840/src/bin/multiprio.rs +++ b/examples/nrf52840/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::{info, unwrap}; use embassy_executor::{Executor, InterruptExecutor}; use embassy_nrf::interrupt; use embassy_nrf::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/nrf52840/src/bin/mutex.rs b/examples/nrf52840/src/bin/mutex.rs index c402c6ba..11b47d99 100644 --- a/examples/nrf52840/src/bin/mutex.rs +++ b/examples/nrf52840/src/bin/mutex.rs @@ -6,7 +6,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::mutex::Mutex; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static MUTEX: Mutex = Mutex::new(0); @@ -20,11 +20,11 @@ async fn my_task() { *m += 1000; // Hold the mutex for a long time. - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("end long operation: count = {}", *m); } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } @@ -34,7 +34,7 @@ async fn main(spawner: Spawner) { unwrap!(spawner.spawn(my_task())); loop { - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut m = MUTEX.lock().await; *m += 1; info!("short operation: count = {}", *m); diff --git a/examples/nrf52840/src/bin/nvmc.rs b/examples/nrf52840/src/bin/nvmc.rs index 31c6fe4b..62482986 100644 --- a/examples/nrf52840/src/bin/nvmc.rs +++ b/examples/nrf52840/src/bin/nvmc.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_nrf::nvmc::Nvmc; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; use {defmt_rtt as _, panic_probe as _}; @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { info!("Hello NVMC!"); // probe-rs run breaks without this, I'm not sure why. - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; let mut f = Nvmc::new(p.NVMC); const ADDR: u32 = 0x80000; diff --git a/examples/nrf52840/src/bin/pdm.rs b/examples/nrf52840/src/bin/pdm.rs index 444b9137..bff32397 100644 --- a/examples/nrf52840/src/bin/pdm.rs +++ b/examples/nrf52840/src/bin/pdm.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::pdm::{self, Config, Pdm}; use embassy_nrf::{bind_interrupts, peripherals}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use fixed::types::I7F1; use num_integer::Roots; use {defmt_rtt as _, panic_probe as _}; @@ -28,7 +28,7 @@ async fn main(_p: Spawner) { pdm.start().await; // wait some time till the microphon settled - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; const SAMPLES: usize = 2048; let mut buf = [0i16; SAMPLES]; @@ -51,7 +51,7 @@ async fn main(_p: Spawner) { info!("samples: {:?}", &buf); pdm.stop().await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } } diff --git a/examples/nrf52840/src/bin/pubsub.rs b/examples/nrf52840/src/bin/pubsub.rs index cca60ebc..17d90222 100644 --- a/examples/nrf52840/src/bin/pubsub.rs +++ b/examples/nrf52840/src/bin/pubsub.rs @@ -6,7 +6,7 @@ use defmt::unwrap; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::pubsub::{DynSubscriber, PubSubChannel, Subscriber}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Create the message bus. It has a queue of 4, supports 3 subscribers and 1 publisher @@ -39,7 +39,7 @@ async fn main(spawner: Spawner) { let mut index = 0; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; let message = match index % 3 { 0 => Message::A, @@ -81,7 +81,7 @@ async fn fast_logger(mut messages: Subscriber<'static, ThreadModeRawMutex, Messa async fn slow_logger(mut messages: DynSubscriber<'static, Message>) { loop { // Do some work - Timer::after(Duration::from_millis(2000)).await; + Timer::after_millis(2000).await; // If the publisher has used the `publish_immediate` function, then we may receive a lag message here let message = messages.next_message().await; @@ -98,7 +98,7 @@ async fn slow_logger(mut messages: DynSubscriber<'static, Message>) { async fn slow_logger_pure(mut messages: DynSubscriber<'static, Message>) { loop { // Do some work - Timer::after(Duration::from_millis(2000)).await; + Timer::after_millis(2000).await; // Instead of receiving lags here, we just ignore that and read the next message let message = messages.next_message_pure().await; diff --git a/examples/nrf52840/src/bin/pwm.rs b/examples/nrf52840/src/bin/pwm.rs index 1698c0bc..9750935c 100644 --- a/examples/nrf52840/src/bin/pwm.rs +++ b/examples/nrf52840/src/bin/pwm.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Prescaler, SimplePwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='') @@ -84,6 +84,6 @@ async fn main(_spawner: Spawner) { pwm.set_duty(1, DUTY[(i + 256) % 1024]); pwm.set_duty(2, DUTY[(i + 512) % 1024]); pwm.set_duty(3, DUTY[(i + 768) % 1024]); - Timer::after(Duration::from_millis(3)).await; + Timer::after_millis(3).await; } } diff --git a/examples/nrf52840/src/bin/pwm_double_sequence.rs b/examples/nrf52840/src/bin/pwm_double_sequence.rs index 16e50e90..1bfe6e15 100644 --- a/examples/nrf52840/src/bin/pwm_double_sequence.rs +++ b/examples/nrf52840/src/bin/pwm_double_sequence.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::pwm::{ Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequencer, StartSequence, }; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped // when it goes out of scope - Timer::after(Duration::from_millis(40000)).await; + Timer::after_millis(40000).await; info!("pwm stopped early!"); } diff --git a/examples/nrf52840/src/bin/pwm_sequence.rs b/examples/nrf52840/src/bin/pwm_sequence.rs index b9aca9aa..f282cf91 100644 --- a/examples/nrf52840/src/bin/pwm_sequence.rs +++ b/examples/nrf52840/src/bin/pwm_sequence.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped // when it goes out of scope - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; info!("pwm stopped early!"); } diff --git a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs index 711c8a17..8596e654 100644 --- a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs +++ b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_nrf::pwm::{ Config, Prescaler, SequenceConfig, SequenceLoad, SequencePwm, SingleSequenceMode, SingleSequencer, }; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // WS2812B LED light demonstration. Drives just one light. @@ -52,7 +52,7 @@ async fn main(_spawner: Spawner) { let sequences = SingleSequencer::new(&mut pwm, &seq_words, seq_config.clone()); unwrap!(sequences.start(SingleSequenceMode::Times(1))); - Timer::after(Duration::from_millis(50)).await; + Timer::after_millis(50).await; if bit_value == T0H { if color_bit == 20 { diff --git a/examples/nrf52840/src/bin/pwm_servo.rs b/examples/nrf52840/src/bin/pwm_servo.rs index 19228f43..92ded1f8 100644 --- a/examples/nrf52840/src/bin/pwm_servo.rs +++ b/examples/nrf52840/src/bin/pwm_servo.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::pwm::{Prescaler, SimplePwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -19,29 +19,29 @@ async fn main(_spawner: Spawner) { pwm.set_max_duty(2500); info!("pwm initialized!"); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; // 1ms 0deg (1/.008=125), 1.5ms 90deg (1.5/.008=187.5), 2ms 180deg (2/.008=250), loop { info!("45 deg"); // poor mans inverting, subtract our value from max_duty pwm.set_duty(0, 2500 - 156); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("90 deg"); pwm.set_duty(0, 2500 - 187); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("135 deg"); pwm.set_duty(0, 2500 - 218); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("180 deg"); pwm.set_duty(0, 2500 - 250); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; info!("0 deg"); pwm.set_duty(0, 2500 - 125); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; } } diff --git a/examples/nrf52840/src/bin/qspi_lowpower.rs b/examples/nrf52840/src/bin/qspi_lowpower.rs index 22a5c0c6..42b5454e 100644 --- a/examples/nrf52840/src/bin/qspi_lowpower.rs +++ b/examples/nrf52840/src/bin/qspi_lowpower.rs @@ -8,7 +8,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_nrf::qspi::Frequency; use embassy_nrf::{bind_interrupts, peripherals, qspi}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // Workaround for alignment requirements. @@ -79,6 +79,6 @@ async fn main(_p: Spawner) { // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do. // During this sleep, the nRF chip should only use ~3uA - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/raw_spawn.rs b/examples/nrf52840/src/bin/raw_spawn.rs index 1b067f5e..717b0faa 100644 --- a/examples/nrf52840/src/bin/raw_spawn.rs +++ b/examples/nrf52840/src/bin/raw_spawn.rs @@ -7,21 +7,21 @@ use cortex_m_rt::entry; use defmt::{info, unwrap}; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs index ffd9a7f4..d651834f 100644 --- a/examples/nrf52840/src/bin/saadc.rs +++ b/examples/nrf52840/src/bin/saadc.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; use embassy_nrf::{bind_interrupts, saadc}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -24,6 +24,6 @@ async fn main(_p: Spawner) { let mut buf = [0; 1]; saadc.sample(&mut buf).await; info!("sample: {=i16}", &buf[0]); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs index a25e1746..a5f8a4dd 100644 --- a/examples/nrf52840/src/bin/saadc_continuous.rs +++ b/examples/nrf52840/src/bin/saadc_continuous.rs @@ -7,7 +7,6 @@ use embassy_executor::Spawner; use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc}; use embassy_nrf::timer::Frequency; use embassy_nrf::{bind_interrupts, saadc}; -use embassy_time::Duration; use {defmt_rtt as _, panic_probe as _}; // Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer @@ -32,7 +31,7 @@ async fn main(_p: Spawner) { // This delay demonstrates that starting the timer prior to running // the task sampler is benign given the calibration that follows. - embassy_time::Timer::after(Duration::from_millis(500)).await; + embassy_time::Timer::after_millis(500).await; saadc.calibrate().await; let mut bufs = [[[0; 3]; 500]; 2]; diff --git a/examples/nrf52840/src/bin/self_spawn.rs b/examples/nrf52840/src/bin/self_spawn.rs index 31ea6c81..8a58396a 100644 --- a/examples/nrf52840/src/bin/self_spawn.rs +++ b/examples/nrf52840/src/bin/self_spawn.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; mod config { @@ -13,7 +13,7 @@ mod config { #[embassy_executor::task(pool_size = config::MY_TASK_POOL_SIZE)] async fn my_task(spawner: Spawner, n: u32) { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Spawning self! {}", n); unwrap!(spawner.spawn(my_task(spawner, n + 1))); } diff --git a/examples/nrf52840/src/bin/self_spawn_current_executor.rs b/examples/nrf52840/src/bin/self_spawn_current_executor.rs index 8a179886..65d50f8c 100644 --- a/examples/nrf52840/src/bin/self_spawn_current_executor.rs +++ b/examples/nrf52840/src/bin/self_spawn_current_executor.rs @@ -4,12 +4,12 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task(pool_size = 2)] async fn my_task(n: u32) { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Spawning self! {}", n); unwrap!(Spawner::for_current_executor().await.spawn(my_task(n + 1))); } diff --git a/examples/nrf52840/src/bin/temp.rs b/examples/nrf52840/src/bin/temp.rs index 70957548..d94dea38 100644 --- a/examples/nrf52840/src/bin/temp.rs +++ b/examples/nrf52840/src/bin/temp.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_nrf::temp::Temp; use embassy_nrf::{bind_interrupts, temp}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -21,6 +21,6 @@ async fn main(_spawner: Spawner) { loop { let value = temp.read().await; info!("temperature: {}℃", value.to_num::()); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/timer.rs b/examples/nrf52840/src/bin/timer.rs index c22b5acd..9b9bb3eb 100644 --- a/examples/nrf52840/src/bin/timer.rs +++ b/examples/nrf52840/src/bin/timer.rs @@ -4,14 +4,14 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } @@ -19,7 +19,7 @@ async fn run1() { async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index 0970d3c3..bf9f966e 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs @@ -14,7 +14,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_nrf::twim::{self, Twim}; use embassy_nrf::{bind_interrupts, peripherals}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDRESS: u8 = 0x50; @@ -48,6 +48,6 @@ async fn main(_p: Spawner) { // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do. // During this sleep, the nRF chip should only use ~3uA - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index edf634a5..96fcf8a6 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs @@ -10,7 +10,7 @@ use embassy_futures::join::join; use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; use embassy_nrf::usb::Driver; use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config}; @@ -83,7 +83,7 @@ async fn main(_spawner: Spawner) { let hid_fut = async { let mut y: i8 = 5; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; y = -y; let report = MouseReport { diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 5824d57b..24972a4f 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -14,7 +14,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature "defmt", "integrated-timers", ] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = [ +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", ] } @@ -27,7 +27,7 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "gpiote", "unstable-pac", ] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = [ +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = [ "nightly", "defmt", "tcp", diff --git a/examples/nrf5340/src/bin/blinky.rs b/examples/nrf5340/src/bin/blinky.rs index 3422cedf..b784564a 100644 --- a/examples/nrf5340/src/bin/blinky.rs +++ b/examples/nrf5340/src/bin/blinky.rs @@ -4,7 +4,7 @@ use embassy_executor::Spawner; use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,8 +14,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 6eeb1ceb..7386eeea 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -9,10 +9,10 @@ license = "MIT OR Apache-2.0" embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "critical-section-impl"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs index 02bc493b..a579be13 100644 --- a/examples/rp/src/bin/adc.rs +++ b/examples/rp/src/bin/adc.rs @@ -10,7 +10,7 @@ use embassy_executor::Spawner; use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) { info!("Pin 28 ADC: {}", level); let temp = adc.read(&mut ts).await.unwrap(); info!("Temp: {} degrees", convert_to_celsius(temp)); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/blinky.rs b/examples/rp/src/bin/blinky.rs index 295b000f..66c8773f 100644 --- a/examples/rp/src/bin/blinky.rs +++ b/examples/rp/src/bin/blinky.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("led on!"); led.set_high(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("led off!"); led.set_low(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index e593acae..b19362fc 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -111,7 +111,7 @@ async fn main(spawner: Spawner) { break; } info!("txd: {}", core::str::from_utf8(msg).unwrap()); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs index 911a657e..129a8497 100644 --- a/examples/rp/src/bin/flash.rs +++ b/examples/rp/src/bin/flash.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; use embassy_rp::peripherals::FLASH; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDR_OFFSET: u32 = 0x100000; @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { // defmt RTT header. Reading that header might touch flash memory, which // interferes with flash write operations. // https://github.com/knurling-rs/defmt/pull/683 - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; let mut flash = embassy_rp::flash::Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); diff --git a/examples/rp/src/bin/gpio_async.rs b/examples/rp/src/bin/gpio_async.rs index bf58044d..98209fe4 100644 --- a/examples/rp/src/bin/gpio_async.rs +++ b/examples/rp/src/bin/gpio_async.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use gpio::{Input, Level, Output, Pull}; use {defmt_rtt as _, panic_probe as _}; @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { info!("done wait_for_high. Turn off LED"); led.set_low(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; } } diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs index 0a3b5fa9..896cc15e 100644 --- a/examples/rp/src/bin/gpout.rs +++ b/examples/rp/src/bin/gpout.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::clocks; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -26,13 +26,13 @@ async fn main(_spawner: Spawner) { "Pin 25 is now outputing CLK_SYS/1000, should be toggling at {}", gpout3.get_freq() ); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; gpout3.set_src(clocks::GpoutSrc::Ref); info!( "Pin 25 is now outputing CLK_REF/1000, should be toggling at {}", gpout3.get_freq() ); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; } } diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs index 93224bc4..7b53aae7 100644 --- a/examples/rp/src/bin/i2c_async.rs +++ b/examples/rp/src/bin/i2c_async.rs @@ -12,7 +12,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::i2c::{self, Config, InterruptHandler}; use embassy_rp::peripherals::I2C1; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_async::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -106,6 +106,6 @@ async fn main(_spawner: Spawner) { } } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs index 1c8c2039..9ddb48d6 100644 --- a/examples/rp/src/bin/i2c_blocking.rs +++ b/examples/rp/src/bin/i2c_blocking.rs @@ -10,7 +10,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::i2c::{self, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_1::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -70,6 +70,6 @@ async fn main(_spawner: Spawner) { info!("portb = {:02x}", portb[0]); val = !val; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs index 7de300fb..151b083a 100644 --- a/examples/rp/src/bin/i2c_slave.rs +++ b/examples/rp/src/bin/i2c_slave.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::peripherals::{I2C0, I2C1}; use embassy_rp::{bind_interrupts, i2c, i2c_slave}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_hal_async::i2c::I2c; use {defmt_rtt as _, panic_probe as _}; @@ -81,7 +81,7 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { Err(e) => error!("Error writing {}", e), } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } match con.read(DEV_ADDR, &mut resp_buff).await { Ok(_) => info!("read response: {}", resp_buff), @@ -91,7 +91,7 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { Ok(_) => info!("write_read response: {}", resp_buff), Err(e) => error!("Error writing {}", e), } - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/lora_p2p_receive.rs b/examples/rp/src/bin/lora_p2p_receive.rs index 5891826f..d5843fdc 100644 --- a/examples/rp/src/bin/lora_p2p_receive.rs +++ b/examples/rp/src/bin/lora_p2p_receive.rs @@ -11,7 +11,7 @@ use embassy_executor::Spawner; use embassy_lora::iv::GenericSx126xInterfaceVariant; use embassy_rp::gpio::{Input, Level, Output, Pin, Pull}; use embassy_rp::spi::{Config, Spi}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -96,7 +96,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/rp/src/bin/lora_p2p_send_multicore.rs b/examples/rp/src/bin/lora_p2p_send_multicore.rs index e31aa62a..ccf44987 100644 --- a/examples/rp/src/bin/lora_p2p_send_multicore.rs +++ b/examples/rp/src/bin/lora_p2p_send_multicore.rs @@ -15,7 +15,7 @@ use embassy_rp::peripherals::SPI1; use embassy_rp::spi::{Async, Config, Spi}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -59,7 +59,7 @@ async fn core0_task() { info!("Hello from core 0"); loop { CHANNEL.send([0x01u8, 0x02u8, 0x03u8]).await; - Timer::after(Duration::from_millis(60 * 1000)).await; + Timer::after_millis(60 * 1000).await; } } diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs index bf017f6a..43eaf8b0 100644 --- a/examples/rp/src/bin/multicore.rs +++ b/examples/rp/src/bin/multicore.rs @@ -13,7 +13,7 @@ use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_rp::peripherals::PIN_25; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -46,9 +46,9 @@ async fn core0_task() { info!("Hello from core 0"); loop { CHANNEL.send(LedState::On).await; - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; CHANNEL.send(LedState::Off).await; - Timer::after(Duration::from_millis(400)).await; + Timer::after_millis(400).await; } } diff --git a/examples/rp/src/bin/multiprio.rs b/examples/rp/src/bin/multiprio.rs index 9ace4cd6..28f62143 100644 --- a/examples/rp/src/bin/multiprio.rs +++ b/examples/rp/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::{info, unwrap}; use embassy_executor::{Executor, InterruptExecutor}; use embassy_rp::interrupt; use embassy_rp::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer, TICK_HZ}; +use embassy_time::{Instant, Timer, TICK_HZ}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(673740)).await; + Timer::after_ticks(673740).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() * 1000 / TICK_HZ; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(53421)).await; + Timer::after_ticks(53421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() * 1000 / TICK_HZ; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(82983)).await; + Timer::after_ticks(82983).await; } } diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index d80c5c24..5e5a6f9a 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -15,7 +15,7 @@ use embassy_rp::pio::{ }; use embassy_rp::pwm::{self, Pwm}; use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(pub struct Irqs { @@ -66,7 +66,7 @@ async fn main(_spawner: Spawner) { let mut buf = Buf([0; 16], 0); write!(buf, "up {}s", Instant::now().as_micros() as f32 / 1e6).unwrap(); hd.add_line(&buf.0[0..buf.1]).await; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs index 5c0c6024..7b325953 100644 --- a/examples/rp/src/bin/pio_ws2812.rs +++ b/examples/rp/src/bin/pio_ws2812.rs @@ -13,7 +13,7 @@ use embassy_rp::pio::{ Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, }; use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use fixed::types::U24F8; use fixed_macro::fixed; use smart_leds::RGB8; @@ -153,7 +153,7 @@ async fn main(_spawner: Spawner) { } ws2812.write(&data).await; - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } } } diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs index 9d919287..a99e8800 100644 --- a/examples/rp/src/bin/pwm.rs +++ b/examples/rp/src/bin/pwm.rs @@ -9,7 +9,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::pwm::{Config, Pwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { loop { info!("current LED duty cycle: {}/32768", c.compare_b); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; c.compare_b = c.compare_b.rotate_left(4); pwm.set_config(&c); } diff --git a/examples/rp/src/bin/rosc.rs b/examples/rp/src/bin/rosc.rs new file mode 100644 index 00000000..f841043b --- /dev/null +++ b/examples/rp/src/bin/rosc.rs @@ -0,0 +1,32 @@ +//! This example test the RP Pico on board LED. +//! +//! It does not work with the RP Pico W board. See wifi_blinky.rs. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::{clocks, gpio}; +use embassy_time::Timer; +use gpio::{Level, Output}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = embassy_rp::config::Config::default(); + config.clocks = clocks::ClockConfig::rosc(); + let p = embassy_rp::init(config); + let mut led = Output::new(p.PIN_25, Level::Low); + + loop { + info!("led on!"); + led.set_high(); + Timer::after_secs(1).await; + + info!("led off!"); + led.set_low(); + Timer::after_secs(1).await; + } +} diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs index 15aa8243..667876db 100644 --- a/examples/rp/src/bin/rtc.rs +++ b/examples/rp/src/bin/rtc.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now).unwrap(); } - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; if let Ok(dt) = rtc.now() { info!( @@ -41,6 +41,6 @@ async fn main(_spawner: Spawner) { } info!("Reboot."); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/rp/src/bin/spi_async.rs b/examples/rp/src/bin/spi_async.rs index 328074e8..f5a2d334 100644 --- a/examples/rp/src/bin/spi_async.rs +++ b/examples/rp/src/bin/spi_async.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::spi::{Config, Spi}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -27,6 +27,6 @@ async fn main(_spawner: Spawner) { let mut rx_buf = [0_u8; 6]; spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); info!("{:?}", rx_buf); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/uart_buffered_split.rs b/examples/rp/src/bin/uart_buffered_split.rs index d3e67c8e..14e8810a 100644 --- a/examples/rp/src/bin/uart_buffered_split.rs +++ b/examples/rp/src/bin/uart_buffered_split.rs @@ -13,7 +13,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::{Read, Write}; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) { ]; info!("TX {:?}", data); tx.write_all(&data).await.unwrap(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/uart_unidir.rs b/examples/rp/src/bin/uart_unidir.rs index c1515a91..42c8b432 100644 --- a/examples/rp/src/bin/uart_unidir.rs +++ b/examples/rp/src/bin/uart_unidir.rs @@ -14,7 +14,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::UART1; use embassy_rp::uart::{Async, Config, InterruptHandler, UartRx, UartTx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,7 +35,7 @@ async fn main(spawner: Spawner) { let data = [1u8, 2, 3, 4, 5, 6, 7, 8]; info!("TX {:?}", data); uart_tx.write(&data).await.unwrap(); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/usb_logger.rs b/examples/rp/src/bin/usb_logger.rs index 9c5e6897..791f15e5 100644 --- a/examples/rp/src/bin/usb_logger.rs +++ b/examples/rp/src/bin/usb_logger.rs @@ -10,7 +10,7 @@ use embassy_executor::Spawner; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -32,6 +32,6 @@ async fn main(spawner: Spawner) { loop { counter += 1; log::info!("Tick {}", counter); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs new file mode 100644 index 00000000..f0b03c81 --- /dev/null +++ b/examples/rp/src/bin/usb_midi.rs @@ -0,0 +1,110 @@ +//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! +//! This creates a USB MIDI device that echoes MIDI messages back to the host. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::{info, panic}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, Instance, InterruptHandler}; +use embassy_usb::class::midi::MidiClass; +use embassy_usb::driver::EndpointError; +use embassy_usb::{Builder, Config}; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("Hello world!"); + + let p = embassy_rp::init(Default::default()); + + // Create the driver, from the HAL. + let driver = Driver::new(p.USB, Irqs); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-MIDI example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut device_descriptor = [0; 256]; + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut control_buf, + ); + + // Create classes on the builder. + let mut class = MidiClass::new(&mut builder, 1, 1, 64); + + // The `MidiClass` can be split into `Sender` and `Receiver`, to be used in separate tasks. + // let (sender, receiver) = class.split(); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Use the Midi class! + let midi_fut = async { + loop { + class.wait_connection().await; + info!("Connected"); + let _ = midi_echo(&mut class).await; + info!("Disconnected"); + } + }; + + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, midi_fut).await; +} + +struct Disconnected {} + +impl From for Disconnected { + fn from(val: EndpointError) -> Self { + match val { + EndpointError::BufferOverflow => panic!("Buffer overflow"), + EndpointError::Disabled => Disconnected {}, + } + } +} + +async fn midi_echo<'d, T: Instance + 'd>(class: &mut MidiClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { + let mut buf = [0; 64]; + loop { + let n = class.read_packet(&mut buf).await?; + let data = &buf[..n]; + info!("data: {:x}", data); + class.write_packet(data).await?; + } +} diff --git a/examples/rp/src/bin/watchdog.rs b/examples/rp/src/bin/watchdog.rs index fe5eaf92..b6af518a 100644 --- a/examples/rp/src/bin/watchdog.rs +++ b/examples/rp/src/bin/watchdog.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { // Set the LED high for 2 seconds so we know when we're about to start the watchdog led.set_high(); - Timer::after(Duration::from_secs(2)).await; + Timer::after_secs(2).await; // Set to watchdog to reset if it's not fed within 1.05 seconds, and start it watchdog.start(Duration::from_millis(1_050)); @@ -33,9 +33,9 @@ async fn main(_spawner: Spawner) { // Blink once a second for 5 seconds, feed the watchdog timer once a second to avoid a reset for _ in 1..=5 { led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("Feeding watchdog"); watchdog.feed(); } @@ -45,8 +45,8 @@ async fn main(_spawner: Spawner) { // The processor should reset in 1.05 seconds. loop { led.set_low(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; led.set_high(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 64cf9517..c00fff21 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -105,7 +105,7 @@ async fn main(spawner: Spawner) { // Wait for DHCP, not necessary when using static IP info!("waiting for DHCP..."); while !stack.is_config_up() { - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } info!("DHCP is now up!"); diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 444dd500..a5f4c871 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["log", "std", "nightly"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "std", "nightly"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]} embedded-io-async = { version = "0.6.0" } diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 199e4c9e..79fa375c 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -100,7 +100,7 @@ async fn main_task(spawner: Spawner) { return; } - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } info!("Closing the connection"); socket.abort(); diff --git a/examples/std/src/bin/tick.rs b/examples/std/src/bin/tick.rs index b9de9d87..a3f99067 100644 --- a/examples/std/src/bin/tick.rs +++ b/examples/std/src/bin/tick.rs @@ -1,14 +1,14 @@ #![feature(type_alias_impl_trait)] use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use log::*; #[embassy_executor::task] async fn run() { loop { info!("tick"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 8d65a399..b80ccd30 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32c0/src/bin/blinky.rs b/examples/stm32c0/src/bin/blinky.rs index 8a65b069..cbeb0dee 100644 --- a/examples/stm32c0/src/bin/blinky.rs +++ b/examples/stm32c0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 750d5304..47a95ec1 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -16,7 +16,7 @@ defmt-rtt = "0.4" panic-probe = "0.3" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } static_cell = { version = "1.1", features = ["nightly"]} [profile.release] diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs index 1564ecfc..96f23440 100644 --- a/examples/stm32f0/src/bin/adc.rs +++ b/examples/stm32f0/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::peripherals::ADC; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin).await; info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f0/src/bin/blinky.rs b/examples/stm32f0/src/bin/blinky.rs index 9f923399..89939454 100644 --- a/examples/stm32f0/src/bin/blinky.rs +++ b/examples/stm32f0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // main is itself an async function. @@ -19,10 +19,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index f362c53f..306df175 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -10,7 +10,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::exti::ExtiInput; use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static BLINK_MS: AtomicU32 = AtomicU32::new(0); @@ -24,7 +24,7 @@ async fn led_task(led: AnyPin) { loop { let del = BLINK_MS.load(Ordering::Relaxed); info!("Value of del is {}", del); - Timer::after(Duration::from_millis(del.into())).await; + Timer::after_millis(del.into()).await; info!("LED toggling"); led.toggle(); } diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs index db78233e..0f98d986 100644 --- a/examples/stm32f0/src/bin/hello.rs +++ b/examples/stm32f0/src/bin/hello.rs @@ -4,14 +4,14 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { let _p = embassy_stm32::init(Default::default()); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; info!("Hello"); } } diff --git a/examples/stm32f0/src/bin/multiprio.rs b/examples/stm32f0/src/bin/multiprio.rs index 988ffeef..870c7c45 100644 --- a/examples/stm32f0/src/bin/multiprio.rs +++ b/examples/stm32f0/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { // info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f0/src/bin/wdg.rs b/examples/stm32f0/src/bin/wdg.rs index a44b1752..b51dee8e 100644 --- a/examples/stm32f0/src/bin/wdg.rs +++ b/examples/stm32f0/src/bin/wdg.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { wdg.unleash(); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; wdg.pet(); } } diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 664be1f9..34319fbd 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any", "unstable-traits" ] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs index 30947c3c..1edac3d8 100644 --- a/examples/stm32f1/src/bin/adc.rs +++ b/examples/stm32f1/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::peripherals::ADC1; use embassy_stm32::{adc, bind_interrupts}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,6 +35,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin).await; info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f1/src/bin/blinky.rs b/examples/stm32f1/src/bin/blinky.rs index b9b0ac23..3425b053 100644 --- a/examples/stm32f1/src/bin/blinky.rs +++ b/examples/stm32f1/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs index 180b6aab..e63bcaae 100644 --- a/examples/stm32f1/src/bin/hello.rs +++ b/examples/stm32f1/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,6 +17,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index 663099ff..60eb5d0e 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; @@ -35,7 +35,7 @@ async fn main(_spawner: Spawner) { // This forced reset is needed only for development, without it host // will not reset your device when you upload new firmware. let _dp = Output::new(&mut p.PA12, Level::Low, Speed::Low); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } // Create the driver, from the HAL. diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 7330eef3..fbf50836 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32f2/src/bin/blinky.rs b/examples/stm32f2/src/bin/blinky.rs index d8c89a51..f6d7a000 100644 --- a/examples/stm32f2/src/bin/blinky.rs +++ b/examples/stm32f2/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index 62aaa980..56591b52 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -11,7 +11,7 @@ use embassy_stm32::rcc::{ }; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) { let _p = embassy_stm32::init(config); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("1s elapsed"); } } diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 6ff425fa..b3b2b123 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32f3/src/bin/blinky.rs b/examples/stm32f3/src/bin/blinky.rs index 185785ce..e71031b3 100644 --- a/examples/stm32f3/src/bin/blinky.rs +++ b/examples/stm32f3/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 8e97e85e..9df6d680 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs @@ -65,11 +65,11 @@ impl<'a> Leds<'a> { for led in &mut self.leds { led.set_high(); } - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; for led in &mut self.leds { led.set_low(); } - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; } } diff --git a/examples/stm32f3/src/bin/hello.rs b/examples/stm32f3/src/bin/hello.rs index 65773210..b3285f3c 100644 --- a/examples/stm32f3/src/bin/hello.rs +++ b/examples/stm32f3/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,6 +18,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs index 80bf59de..74f3bb1c 100644 --- a/examples/stm32f3/src/bin/multiprio.rs +++ b/examples/stm32f3/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index f15f333b..a9537c77 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::time::mhz; use embassy_stm32::usb::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::Builder; @@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) { // Needed for nucleo-stm32f303ze let mut dp_pullup = Output::new(p.PG6, Level::Low, Speed::Medium); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; dp_pullup.set_high(); // Create the driver, from the HAL. diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index a9286c44..f259135d 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs @@ -9,7 +9,7 @@ use embassy_stm32::peripherals::ADC1; use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -51,6 +51,6 @@ async fn main(_spawner: Spawner) -> ! { let pin_mv = (pin as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; info!("computed pin mv: {}", pin_mv); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32f334/src/bin/button.rs b/examples/stm32f334/src/bin/button.rs index 599c0f27..501fb080 100644 --- a/examples/stm32f334/src/bin/button.rs +++ b/examples/stm32f334/src/bin/button.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,10 +17,10 @@ async fn main(_spawner: Spawner) { let mut out1 = Output::new(p.PA8, Level::Low, Speed::High); out1.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; out1.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("end program"); cortex_m::asm::bkpt(); diff --git a/examples/stm32f334/src/bin/hello.rs b/examples/stm32f334/src/bin/hello.rs index 65773210..b3285f3c 100644 --- a/examples/stm32f334/src/bin/hello.rs +++ b/examples/stm32f334/src/bin/hello.rs @@ -6,7 +6,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,6 +18,6 @@ async fn main(_spawner: Spawner) -> ! { loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index fb5a85bc..128001bf 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -10,7 +10,7 @@ use embassy_stm32::peripherals::ADC2; use embassy_stm32::rcc::{AdcClockSource, Adcpres}; use embassy_stm32::time::mhz; use embassy_stm32::{adc, bind_interrupts, Config}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -54,6 +54,6 @@ async fn main(_spawner: Spawner) -> ! { let pin_mv = (buffer as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; info!("computed pin mv: {}", pin_mv); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs index aebc421b..8040c3f1 100644 --- a/examples/stm32f334/src/bin/pwm.rs +++ b/examples/stm32f334/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::hrtim::*; use embassy_stm32::rcc::HrtimClockSource; use embassy_stm32::time::{khz, mhz}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) { // .setr(0) // .modify(|w| w.set_sst(Activeeffect::SETACTIVE)); // - // Timer::after(Duration::from_millis(500)).await; + // Timer::after_millis(500).await; // // embassy_stm32::pac::HRTIM1 // .tim(0) @@ -65,7 +65,7 @@ async fn main(_spawner: Spawner) { buck_converter.start(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("end program"); diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index b76238ee..9b10e975 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -9,9 +9,9 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs index dd10385c..f1932872 100644 --- a/examples/stm32f4/src/bin/adc.rs +++ b/examples/stm32f4/src/bin/adc.rs @@ -6,7 +6,7 @@ use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, Temperature, VrefInt}; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -63,6 +63,6 @@ async fn main(_spawner: Spawner) { let v = adc.read(&mut vrefint); info!("VrefInt: {}", v); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32f4/src/bin/blinky.rs +++ b/examples/stm32f4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 6a1d4b08..1747bbf4 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -10,9 +10,9 @@ use embassy_stm32::eth::generic_smi::GenericSMI; use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; @@ -32,7 +32,25 @@ async fn net_task(stack: &'static Stack) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL180, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); @@ -99,7 +117,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -110,7 +128,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs index 6c9689d9..f0a65a72 100644 --- a/examples/stm32f4/src/bin/flash_async.rs +++ b/examples/stm32f4/src/bin/flash_async.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::flash::{Flash, InterruptHandler}; use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -35,11 +35,11 @@ async fn blinky(p: AnyPin) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs index c409703f..a2a28711 100644 --- a/examples/stm32f4/src/bin/hello.rs +++ b/examples/stm32f4/src/bin/hello.rs @@ -4,19 +4,17 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { - let mut config = Config::default(); - config.rcc.sys_ck = Some(Hertz(84_000_000)); + let config = Config::default(); let _p = embassy_stm32::init(config); loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs index 5144a78c..3315e765 100644 --- a/examples/stm32f4/src/bin/mco.rs +++ b/examples/stm32f4/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoPrescaler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs index 80bf59de..74f3bb1c 100644 --- a/examples/stm32f4/src/bin/multiprio.rs +++ b/examples/stm32f4/src/bin/multiprio.rs @@ -62,7 +62,7 @@ use defmt::*; use embassy_executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::{InterruptExt, Priority}; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -70,7 +70,7 @@ use {defmt_rtt as _, panic_probe as _}; async fn run_high() { loop { info!(" [high] tick!"); - Timer::after(Duration::from_ticks(27374)).await; + Timer::after_ticks(27374).await; } } @@ -87,7 +87,7 @@ async fn run_med() { let ms = end.duration_since(start).as_ticks() / 33; info!(" [med] done in {} ms", ms); - Timer::after(Duration::from_ticks(23421)).await; + Timer::after_ticks(23421).await; } } @@ -104,7 +104,7 @@ async fn run_low() { let ms = end.duration_since(start).as_ticks() / 33; info!("[low] done in {} ms", ms); - Timer::after(Duration::from_ticks(32983)).await; + Timer::after_ticks(32983).await; } } diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index 1013a844..8e41d0e7 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::gpio::OutputType; use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); @@ -26,12 +26,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs index 83a3c753..d925f26d 100644 --- a/examples/stm32f4/src/bin/pwm_complementary.rs +++ b/examples/stm32f4/src/bin/pwm_complementary.rs @@ -9,7 +9,7 @@ use embassy_stm32::time::khz; use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; use embassy_stm32::timer::simple_pwm::PwmPin; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -30,6 +30,7 @@ async fn main(_spawner: Spawner) { None, None, khz(10), + Default::default(), ); let max = pwm.get_max_duty(); @@ -42,12 +43,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index e95ad577..44b4303c 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { info!("{}", now.timestamp()); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs index 6ec7d0fe..37e42384 100644 --- a/examples/stm32f4/src/bin/sdmmc.rs +++ b/examples/stm32f4/src/bin/sdmmc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; -use embassy_stm32::time::mhz; +use embassy_stm32::time::{mhz, Hertz}; use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -20,8 +20,25 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(48)); - config.rcc.pll48 = true; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index 763e3a9e..7c0644ae 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_net::tcp::TcpSocket; use embassy_net::{Stack, StackResources}; use embassy_stm32::rng::{self, Rng}; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; @@ -46,9 +46,25 @@ async fn main(spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(48)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 4ff6452e..004ff038 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; @@ -22,9 +22,25 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(48)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL168, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. + divq: Some(Pllq::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs index e5d122af..0443b61c 100644 --- a/examples/stm32f4/src/bin/wdt.rs +++ b/examples/stm32f4/src/bin/wdt.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -24,11 +24,11 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; // Pet watchdog for 5 iterations and then stop. // MCU should restart in 1 second after the last pet. diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 01549f11..5cbaca46 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -9,8 +9,8 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs index bc4ed289..48c59eaf 100644 --- a/examples/stm32f7/src/bin/adc.rs +++ b/examples/stm32f7/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -29,6 +29,6 @@ async fn main(_spawner: Spawner) { loop { let v = adc.read(&mut pin); info!("--> {} - {} mV", v, convert_to_millivolts(v)); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } } diff --git a/examples/stm32f7/src/bin/blinky.rs b/examples/stm32f7/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32f7/src/bin/blinky.rs +++ b/examples/stm32f7/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs index e9650f23..78b21cea 100644 --- a/examples/stm32f7/src/bin/can.rs +++ b/examples/stm32f7/src/bin/can.rs @@ -26,7 +26,7 @@ pub async fn send_can_message(tx: &'static mut CanTx<'static, 'static, CAN3>) { loop { let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), [0]); tx.write(&frame).await; - embassy_time::Timer::after(embassy_time::Duration::from_secs(1)).await; + embassy_time::Timer::after_secs(1).await; } } diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 7c9ee159..7c6c419a 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -10,9 +10,9 @@ use embassy_stm32::eth::generic_smi::GenericSMI; use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -33,7 +33,25 @@ async fn net_task(stack: &'static Stack) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); @@ -100,7 +118,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -111,7 +129,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32f7/src/bin/flash.rs b/examples/stm32f7/src/bin/flash.rs index 35d3059b..06a94f1c 100644 --- a/examples/stm32f7/src/bin/flash.rs +++ b/examples/stm32f7/src/bin/flash.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_stm32::flash::Flash; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x8_0000; // This is the offset into the third region, the absolute address is 4x32K + 128K + 0x8_0000. // wait a bit before accessing the flash - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region3; diff --git a/examples/stm32f7/src/bin/hello.rs b/examples/stm32f7/src/bin/hello.rs index c409703f..a2a28711 100644 --- a/examples/stm32f7/src/bin/hello.rs +++ b/examples/stm32f7/src/bin/hello.rs @@ -4,19 +4,17 @@ use defmt::info; use embassy_executor::Spawner; -use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { - let mut config = Config::default(); - config.rcc.sys_ck = Some(Hertz(84_000_000)); + let config = Config::default(); let _p = embassy_stm32::init(config); loop { info!("Hello World!"); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs index 9d43892a..430aa781 100644 --- a/examples/stm32f7/src/bin/sdmmc.rs +++ b/examples/stm32f7/src/bin/sdmmc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::sdmmc::Sdmmc; -use embassy_stm32::time::mhz; +use embassy_stm32::time::{mhz, Hertz}; use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,8 +16,25 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.sys_ck = Some(mhz(200)); - config.rcc.pll48 = true; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index a2c76178..2f832c23 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::time::mhz; +use embassy_stm32::time::Hertz; use embassy_stm32::usb_otg::{Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; @@ -22,10 +22,25 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.hse = Some(mhz(8)); - config.rcc.pll48 = true; - config.rcc.sys_ck = Some(mhz(200)); - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz + divq: Some(Pllq::DIV9), // 8mhz / 4 * 216 / 9 = 48Mhz + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; + } let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index dd26ce4e..d0b7d85f 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -9,7 +9,8 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } + defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32g0/src/bin/blinky.rs b/examples/stm32g0/src/bin/blinky.rs index b27bee4c..4bfc5a50 100644 --- a/examples/stm32g0/src/bin/blinky.rs +++ b/examples/stm32g0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs index ee7aaf33..214462d0 100644 --- a/examples/stm32g0/src/bin/spi_neopixel.rs +++ b/examples/stm32g0/src/bin/spi_neopixel.rs @@ -8,7 +8,7 @@ use embassy_stm32::dma::word::U5; use embassy_stm32::dma::NoDma; use embassy_stm32::spi::{Config, Spi}; use embassy_stm32::time::Hertz; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const NR_PIXELS: usize = 15; @@ -96,8 +96,8 @@ async fn main(_spawner: Spawner) { cnt += 1; // start sending the neopixel bit patters over spi to the neopixel string spi.write(&neopixels.bitbuffer).await.ok(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 4b0b1084..908c6d19 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.6.0" diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index 30a112b7..f0573384 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -7,7 +7,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI16, + source: PllSrc::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { div_r: Some(PllR::DIV2), }); - config.rcc.adc12_clock_source = AdcClockSource::SYSCLK; + config.rcc.adc12_clock_source = AdcClockSource::SYS; config.rcc.mux = ClockSrc::PLL; let mut p = embassy_stm32::init(config); @@ -36,6 +36,6 @@ async fn main(_spawner: Spawner) { loop { let measured = adc.read(&mut p.PA7); info!("measured: {}", measured); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32g4/src/bin/blinky.rs b/examples/stm32g4/src/bin/blinky.rs index 8a65b069..cbeb0dee 100644 --- a/examples/stm32g4/src/bin/blinky.rs +++ b/examples/stm32g4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index f8159cb5..90c3f8dc 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI16, + source: PllSrc::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, @@ -29,7 +29,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("1s elapsed"); } } diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 01e9cb47..a8439400 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs @@ -8,7 +8,7 @@ use embassy_stm32::gpio::OutputType; use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PC0, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); @@ -26,12 +26,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index bc6d5898..f5980d87 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -9,8 +9,8 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } -embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h5/src/bin/blinky.rs b/examples/stm32h5/src/bin/blinky.rs index f9bf90d2..1394f03f 100644 --- a/examples/stm32h5/src/bin/blinky.rs +++ b/examples/stm32h5/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 2535c6a6..5bec9d44 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -15,7 +15,7 @@ use embassy_stm32::rcc::{ use embassy_stm32::rng::Rng; use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -43,7 +43,7 @@ async fn main(spawner: Spawner) -> ! { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), @@ -54,7 +54,7 @@ async fn main(spawner: Spawner) -> ! { config.rcc.apb1_pre = APBPrescaler::DIV1; config.rcc.apb2_pre = APBPrescaler::DIV1; config.rcc.apb3_pre = APBPrescaler::DIV1; - config.rcc.sys = Sysclk::Pll1P; + config.rcc.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; let p = embassy_stm32::init(config); info!("Hello World!"); @@ -121,7 +121,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(3)).await; + Timer::after_secs(3).await; continue; } info!("connected!"); @@ -131,7 +131,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 3b3c38e1..735826a6 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), // 250mhz @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { config.rcc.apb1_pre = APBPrescaler::DIV4; config.rcc.apb2_pre = APBPrescaler::DIV2; config.rcc.apb3_pre = APBPrescaler::DIV4; - config.rcc.sys = Sysclk::Pll1P; + config.rcc.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; let p = embassy_stm32::init(config); diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index adc99024..0855bdfc 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -9,8 +9,8 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "unstable-traits", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } -embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embedded-io-async = { version = "0.6.0" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index 7859b86d..e367827e 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,10 +14,10 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -25,13 +25,14 @@ async fn main(_spawner: Spawner) { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -55,6 +56,6 @@ async fn main(_spawner: Spawner) { info!("vrefint: {}", vrefint); let measured = adc.read(&mut p.PC0); info!("measured: {}", measured); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs index 12f08c0f..a9cab1ff 100644 --- a/examples/stm32h7/src/bin/blinky.rs +++ b/examples/stm32h7/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 40ef16cf..23ece1c3 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs @@ -9,7 +9,7 @@ use embassy_stm32::i2c::I2c; use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; use embassy_stm32::time::khz; use embassy_stm32::{bind_interrupts, i2c, peripherals, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use ov7725::*; use {defmt_rtt as _, panic_probe as _}; @@ -28,17 +28,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -86,11 +86,11 @@ async fn main(_spawner: Spawner) { loop { defmt::info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; defmt::info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } @@ -99,7 +99,7 @@ mod ov7725 { use defmt::Format; use embassy_stm32::rcc::{Mco, McoInstance}; - use embassy_time::{Duration, Timer}; + use embassy_time::Timer; use embedded_hal_async::i2c::I2c; #[repr(u8)] @@ -210,9 +210,9 @@ mod ov7725 { } pub async fn init(&mut self) -> Result<(), Error> { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; self.reset_regs().await?; - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; self.set_pixformat().await?; self.set_resolution().await?; Ok(()) diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index 82122189..35fd6550 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -16,10 +16,10 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -27,13 +27,14 @@ fn main() -> ! { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 334986a0..e141fc48 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -24,10 +24,10 @@ async fn main(spawner: Spawner) { let mut config = embassy_stm32::Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -35,13 +35,14 @@ async fn main(spawner: Spawner) { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 6fbf4344..e37d8797 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -11,7 +11,7 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use rand_core::RngCore; use static_cell::make_static; @@ -34,18 +34,18 @@ async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -118,7 +118,7 @@ async fn main(spawner: Spawner) -> ! { let r = socket.connect(remote_endpoint).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } info!("connected!"); @@ -128,7 +128,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 09d27cdb..88df53f0 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -11,7 +11,7 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::Write; use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; use rand_core::RngCore; @@ -35,18 +35,18 @@ async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -115,7 +115,7 @@ async fn main(spawner: Spawner) -> ! { let r = client.connect(addr).await; if let Err(e) = r { info!("connect error: {:?}", e); - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; continue; } let mut connection = r.unwrap(); @@ -126,7 +126,7 @@ async fn main(spawner: Spawner) -> ! { info!("write error: {:?}", e); break; } - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } } diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs index f66df770..89c0c8a6 100644 --- a/examples/stm32h7/src/bin/flash.rs +++ b/examples/stm32h7/src/bin/flash.rs @@ -5,7 +5,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_stm32::flash::Flash; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0; // This is the offset into bank 2, the absolute address is 0x8_0000 // wait a bit before accessing the flash - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank2_region; diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs index 7ae87b02..54e2c362 100644 --- a/examples/stm32h7/src/bin/fmc.rs +++ b/examples/stm32h7/src/bin/fmc.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::fmc::Fmc; use embassy_stm32::Config; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,17 +14,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -212,6 +212,6 @@ async fn main(_spawner: Spawner) { info!("Assertions succeeded."); loop { - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 5841efb2..e4bac8a5 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -9,7 +9,7 @@ use embassy_stm32::gpio::Speed; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::*; use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,18 +17,18 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // 100mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -49,13 +49,13 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs index de89aee2..c023f458 100644 --- a/examples/stm32h7/src/bin/mco.rs +++ b/examples/stm32h7/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index 37e4c92c..c55d780a 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs @@ -9,7 +9,7 @@ use embassy_stm32::time::khz; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,17 +17,17 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let ch1 = PwmPin::new_ch1(p.PA6, OutputType::PushPull); - let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); + let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10), Default::default()); let max = pwm.get_max_duty(); pwm.enable(Channel::Ch1); @@ -48,12 +48,12 @@ async fn main(_spawner: Spawner) { loop { pwm.set_duty(Channel::Ch1, 0); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 4); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max / 2); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; pwm.set_duty(Channel::Ch1, max - 1); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs index f2a19af8..78cea9c8 100644 --- a/examples/stm32h7/src/bin/rtc.rs +++ b/examples/stm32h7/src/bin/rtc.rs @@ -8,7 +8,7 @@ use embassy_executor::Spawner; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs index ecb8d654..be968ff7 100644 --- a/examples/stm32h7/src/bin/sdmmc.rs +++ b/examples/stm32h7/src/bin/sdmmc.rs @@ -18,17 +18,17 @@ async fn main(_spawner: Spawner) -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV4), // default clock chosen by SDMMCSEL. 200 Mhz divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs index 6d7c168d..b5f58328 100644 --- a/examples/stm32h7/src/bin/signal.rs +++ b/examples/stm32h7/src/bin/signal.rs @@ -6,7 +6,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::signal::Signal; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static SIGNAL: Signal = Signal::new(); @@ -16,7 +16,7 @@ async fn my_sending_task() { let mut counter: u32 = 0; loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; SIGNAL.signal(counter); diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index f128d4a5..a8db0ff7 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -40,17 +40,17 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index d4c0bcdb..561052e4 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -36,17 +36,17 @@ fn main() -> ! { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index c1e5144b..19d77183 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs @@ -23,18 +23,18 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for USB - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs index 9181dfd6..76fd9dfc 100644 --- a/examples/stm32h7/src/bin/wdg.rs +++ b/examples/stm32h7/src/bin/wdg.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::wdg::IndependentWatchdog; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) { wdg.unleash(); loop { - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; wdg.pet(); } } diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index f70ecc06..03b6d600 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -14,7 +14,7 @@ nightly = ["embassy-stm32/nightly", "embassy-time/nightly", "embassy-time/unstab embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"], optional = true } lora-phy = { version = "2", optional = true } lorawan-device = { version = "0.11.0", default-features = false, features = ["async", "external-lora-phy"], optional = true } diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs index 07fad07c..ea40bfc4 100644 --- a/examples/stm32l0/src/bin/blinky.rs +++ b/examples/stm32l0/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l0/src/bin/lora_cad.rs b/examples/stm32l0/src/bin/lora_cad.rs index 900848fd..5c2b331c 100644 --- a/examples/stm32l0/src/bin/lora_cad.rs +++ b/examples/stm32l0/src/bin/lora_cad.rs @@ -12,7 +12,7 @@ use embassy_stm32::exti::{Channel, ExtiInput}; use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; use embassy_stm32::spi; use embassy_stm32::time::khz; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1276_7_8_9::SX1276_7_8_9; use lora_phy::LoRa; @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB6, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mdltn_params = { @@ -89,7 +89,7 @@ async fn main(_spawner: Spawner) { info!("cad successful without activity detected") } debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } Err(err) => info!("cad unsuccessful = {}", err), diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index 7a93737e..d44d03d3 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs @@ -33,7 +33,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l0/src/bin/lora_p2p_receive.rs b/examples/stm32l0/src/bin/lora_p2p_receive.rs index edd14bb8..0478ce1e 100644 --- a/examples/stm32l0/src/bin/lora_p2p_receive.rs +++ b/examples/stm32l0/src/bin/lora_p2p_receive.rs @@ -12,7 +12,7 @@ use embassy_stm32::exti::{Channel, ExtiInput}; use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; use embassy_stm32::spi; use embassy_stm32::time::khz; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1276_7_8_9::SX1276_7_8_9; use lora_phy::LoRa; @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); @@ -55,7 +55,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB6, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/stm32l0/src/bin/lora_p2p_send.rs b/examples/stm32l0/src/bin/lora_p2p_send.rs index 23cc1c6f..88a836d3 100644 --- a/examples/stm32l0/src/bin/lora_p2p_send.rs +++ b/examples/stm32l0/src/bin/lora_p2p_send.rs @@ -23,7 +23,7 @@ const LORA_FREQUENCY_IN_HZ: u32 = 903_900_000; // warning: set this appropriatel #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI; config.rcc.enable_hsi48 = true; let p = embassy_stm32::init(config); diff --git a/examples/stm32l0/src/bin/raw_spawn.rs b/examples/stm32l0/src/bin/raw_spawn.rs index edc17304..29c7e0dc 100644 --- a/examples/stm32l0/src/bin/raw_spawn.rs +++ b/examples/stm32l0/src/bin/raw_spawn.rs @@ -7,21 +7,21 @@ use cortex_m_rt::entry; use defmt::*; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { loop { info!("BIG INFREQUENT TICK"); - Timer::after(Duration::from_ticks(64000)).await; + Timer::after_ticks(64000).await; } } async fn run2() { loop { info!("tick"); - Timer::after(Duration::from_ticks(13000)).await; + Timer::after_ticks(13000).await; } } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 472e1b7a..70058d49 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } defmt = "0.3" diff --git a/examples/stm32l1/src/bin/blinky.rs b/examples/stm32l1/src/bin/blinky.rs index 8a345d23..06f732eb 100644 --- a/examples/stm32l1/src/bin/blinky.rs +++ b/examples/stm32l1/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(1000)).await; + Timer::after_millis(1000).await; } } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 5456efe8..b420ad56 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -9,11 +9,11 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "unstable-traits", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "udp", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "udp", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embedded-io-async = { version = "0.6.0", features = ["defmt-03"] } embedded-io = { version = "0.6.0", features = ["defmt-03"] } diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index 1771e520..a0ec5c33 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs @@ -13,7 +13,7 @@ fn main() -> ! { info!("Hello World!"); pac::RCC.ccipr().modify(|w| { - w.set_adcsel(0b11); + w.set_adcsel(pac::rcc::vals::Adcsel::SYS); }); pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs index 033292ff..6202fe2f 100644 --- a/examples/stm32l4/src/bin/blinky.rs +++ b/examples/stm32l4/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,8 +17,8 @@ async fn main(_spawner: Spawner) { loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs index 8d35af78..50487988 100644 --- a/examples/stm32l4/src/bin/mco.rs +++ b/examples/stm32l4/src/bin/mco.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,14 +14,14 @@ async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI16, McoPrescaler::DIV1); + let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI, McoPrescaler::DIV1); let mut led = Output::new(p.PB14, Level::High, Speed::Low); loop { led.set_high(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; led.set_low(); - Timer::after(Duration::from_millis(300)).await; + Timer::after_millis(300).await; } } diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index d0208d8a..553d11c0 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,14 +16,16 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - // 72Mhz clock (16 / 1 * 18 / 4) - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSI16, - PllRDiv::DIV4, - PllPreDiv::DIV1, - PllMul::MUL18, - Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) - ); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL18, + divp: None, + divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) + divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4) + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 33efc76b..69527c9a 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -5,27 +5,34 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = { - let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSE(Hertz::mhz(8)), - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL20, - None, - ); + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hse = Some(Hse { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); config.rcc.ls = LsConfig::default_lse(); - embassy_stm32::init(config) - }; + } + let p = embassy_stm32::init(config); + info!("Hello World!"); let now = NaiveDate::from_ymd_opt(2020, 5, 15) @@ -39,7 +46,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 7193d1f1..f76b504a 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -48,7 +48,6 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; use embedded_hal_bus::spi::ExclusiveDevice; use hal::gpio::Pull; use hal::i2c::Config as I2C_Config; -use hal::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; use hal::spi::{Config as SPI_Config, Spi}; use hal::time::Hertz; @@ -74,17 +73,25 @@ async fn main(spawner: Spawner) { defmt::println!("Start main()"); let mut config = embassy_stm32::Config::default(); - - // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) - // 80MHz highest frequency for flash 0 wait. - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSE(Hertz(8_000_000)), - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL20, - None, - ); - config.rcc.hsi48 = true; // needed for rng + { + use embassy_stm32::rcc::*; + // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) + // 80MHz highest frequency for flash 0 wait. + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hse = Some(Hse { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + config.rcc.hsi48 = true; // needed for rng + } let dp = embassy_stm32::init(config); @@ -306,7 +313,7 @@ async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static, periphera loop { led.set_low(); - match select(temp_sens.read_temp(), Timer::after(Duration::from_millis(500))).await { + match select(temp_sens.read_temp(), Timer::after_millis(500)).await { Either::First(i2c_ret) => match i2c_ret { Ok(value) => { led.set_high(); @@ -424,7 +431,7 @@ where // Start: One shot let cfg = 0b01 << 5; self.write_cfg(cfg).await?; - Timer::after(Duration::from_millis(250)).await; + Timer::after_millis(250).await; self.bus .write_read(self.addr, &[Registers::Temp_MSB as u8], &mut buffer) .await diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index dc0d98ad..15c6f198 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -23,8 +23,17 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); config.rcc.hsi48 = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) + }); let p = embassy_stm32::init(config); diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index cf8601da..ecf88d7e 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -9,9 +9,9 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.6.0" diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index cc3c99b5..b9d4cd25 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLSource, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -16,13 +16,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL( - PLLSource::HSI16, - PllRDiv::DIV2, - PllPreDiv::DIV1, - PllMul::MUL8, - Some(PllQDiv::DIV2), - ); + config.rcc.hsi = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + // 64Mhz clock (16 / 1 * 8 / 2) + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL8, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 498147f9..f5b3ca34 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -45,8 +45,17 @@ async fn net_task(stack: &'static Stack>) -> ! { #[embassy_executor::main] async fn main(spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); // Create the driver, from the HAL. diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index db6a9c76..bec3d5e4 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -8,7 +8,7 @@ use embassy_futures::join::join; use embassy_stm32::rcc::*; use embassy_stm32::usb::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; use embassy_usb::control::OutResponse; use embassy_usb::Builder; @@ -22,8 +22,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); // Create the driver, from the HAL. @@ -76,7 +85,7 @@ async fn main(_spawner: Spawner) { let hid_fut = async { let mut y: i8 = 5; loop { - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; y = -y; let report = MouseReport { diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index e19ecbf0..ff1154f9 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -20,8 +20,17 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL(PLLSource::HSI16, PllRDiv::DIV2, PllPreDiv::DIV1, PllMul::MUL10, None); - config.rcc.hsi48 = true; + config.rcc.hsi = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + // 80Mhz clock (16 / 1 * 10 / 2) + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL10, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 9c139c2e..de60b3b1 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } defmt = "0.3" diff --git a/examples/stm32u5/src/bin/blinky.rs b/examples/stm32u5/src/bin/blinky.rs index 976fb0b9..4b44cb12 100644 --- a/examples/stm32u5/src/bin/blinky.rs +++ b/examples/stm32u5/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) -> ! { loop { defmt::info!("on!"); led.set_low(); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; defmt::info!("off!"); led.set_high(); - Timer::after(Duration::from_millis(200)).await; + Timer::after_millis(200).await; } } diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 9b2adb0a..f59f623b 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -23,8 +23,8 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL1R(PllConfig { - source: PllSrc::HSI16, + config.rcc.mux = ClockSrc::PLL1_R(PllConfig { + source: PllSrc::HSI, m: Pllm::DIV2, n: Plln::MUL10, r: Plldiv::DIV1, diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index e0711ad0..fa2cc63f 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -10,8 +10,8 @@ embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [" embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs index f9bf90d2..1394f03f 100644 --- a/examples/stm32wb/src/bin/blinky.rs +++ b/examples/stm32wb/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 2f53f5df..9d0e0070 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs @@ -8,7 +8,7 @@ use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::rcc::WPAN_DEFAULT; use embassy_stm32_wpan::TlMbox; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ @@ -71,7 +71,7 @@ async fn main(_spawner: Spawner) { } } - Timer::after(Duration::from_millis(50)).await; + Timer::after_millis(50).await; } info!("Test OK"); diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 7effc09a..68ab5a46 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", "nightly"], optional=true } defmt = "0.3" defmt-rtt = "0.4" diff --git a/examples/stm32wba/src/bin/blinky.rs b/examples/stm32wba/src/bin/blinky.rs index 53074629..6b9635e6 100644 --- a/examples/stm32wba/src/bin/blinky.rs +++ b/examples/stm32wba/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index c106d62b..6a338af4 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] } lora-phy = { version = "2" } diff --git a/examples/stm32wl/src/bin/blinky.rs b/examples/stm32wl/src/bin/blinky.rs index 6af5099c..5bd5745f 100644 --- a/examples/stm32wl/src/bin/blinky.rs +++ b/examples/stm32wl/src/bin/blinky.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Speed}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { loop { info!("high"); led.set_high(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; info!("low"); led.set_low(); - Timer::after(Duration::from_millis(500)).await; + Timer::after_millis(500).await; } } diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 8c789afb..35a6a842 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -12,7 +12,8 @@ use embassy_lora::LoraTimer; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::rng::{self, Rng}; use embassy_stm32::spi::Spi; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -33,11 +34,25 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); - let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index 19b0d853..1c485d73 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -11,7 +11,8 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_stm32::bind_interrupts; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::spi::Spi; -use embassy_time::{Delay, Duration, Timer}; +use embassy_stm32::time::Hertz; +use embassy_time::{Delay, Timer}; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; use lora_phy::LoRa; @@ -26,7 +27,23 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); @@ -51,7 +68,7 @@ async fn main(_spawner: Spawner) { let mut start_indicator = Output::new(p.PB15, Level::Low, Speed::Low); start_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; start_indicator.set_low(); let mut receiving_buffer = [00u8; 100]; @@ -103,7 +120,7 @@ async fn main(_spawner: Spawner) { { info!("rx successful"); debug_indicator.set_high(); - Timer::after(Duration::from_secs(5)).await; + Timer::after_secs(5).await; debug_indicator.set_low(); } else { info!("rx unknown packet"); diff --git a/examples/stm32wl/src/bin/lora_p2p_send.rs b/examples/stm32wl/src/bin/lora_p2p_send.rs index 85f6a84b..3afa78ac 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -11,6 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_stm32::bind_interrupts; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::spi::Spi; +use embassy_stm32::time::Hertz; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -26,7 +27,23 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 7c7e8a4e..1a8822b4 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -5,7 +5,8 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rng::{self, Rng}; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ @@ -15,12 +16,24 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; - + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| { - w.set_rngsel(0b01); - }); info!("Hello World!"); diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index a6bb2801..b3b7f9c5 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -5,20 +5,34 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, LsConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig}; +use embassy_stm32::time::Hertz; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = { - let mut config = Config::default(); - config.rcc.mux = ClockSrc::HSE; + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; config.rcc.ls = LsConfig::default_lse(); - embassy_stm32::init(config) - }; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } + let p = embassy_stm32::init(config); info!("Hello World!"); let now = NaiveDate::from_ymd_opt(2020, 5, 15) @@ -32,7 +46,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); // In reality the delay would be much longer - Timer::after(Duration::from_millis(20000)).await; + Timer::after_millis(20000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); info!("Got RTC! {:?}", then.timestamp()); diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 9136c81c..29339295 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } wasm-logger = "0.2.0" wasm-bindgen = "0.2" diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs index edfe8baf..1141096f 100644 --- a/examples/wasm/src/lib.rs +++ b/examples/wasm/src/lib.rs @@ -1,7 +1,7 @@ #![feature(type_alias_impl_trait)] use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; #[embassy_executor::task] async fn ticker() { @@ -19,7 +19,7 @@ async fn ticker() { log::info!("tick {}", counter); counter += 1; - Timer::after(Duration::from_secs(1)).await; + Timer::after_secs(1).await; } } diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 32f296a1..96a5871e 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -10,10 +10,10 @@ teleprobe-meta = "1" embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } embedded-io-async = { version = "0.6.0" } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } embedded-hal-async = { version = "1.0.0-rc.1" } diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 8abeae6d..65b9d76d 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs @@ -13,7 +13,7 @@ use embassy_nrf::gpio::{Level, Output, OutputDrive}; use embassy_nrf::ppi::{Event, Ppi, Task}; use embassy_nrf::uarte::Uarte; use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -50,7 +50,7 @@ async fn main(_spawner: Spawner) { info!("uarte initialized!"); // uarte needs some quiet time to start rxing properly. - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; // Tx spam in a loop. const NSPAM: usize = 17; diff --git a/tests/nrf/src/bin/timer.rs b/tests/nrf/src/bin/timer.rs index c00f35fd..5723acb0 100644 --- a/tests/nrf/src/bin/timer.rs +++ b/tests/nrf/src/bin/timer.rs @@ -5,7 +5,7 @@ teleprobe_meta::target!(b"nrf52840-dk"); use defmt::{assert, info}; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let start = Instant::now(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let end = Instant::now(); let ms = (end - start).as_millis(); info!("slept for {} ms", ms); diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index daa8edfb..bab5ac49 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3.0" diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs index d709c7bd..54762379 100644 --- a/tests/perf-client/src/lib.rs +++ b/tests/perf-client/src/lib.rs @@ -16,7 +16,7 @@ pub struct Expected { pub async fn run(stack: &Stack, expected: Expected) { info!("Waiting for DHCP up..."); while stack.config_v4().is_none() { - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; } info!("IP addressing up!"); diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index ddd83ec2..3bb46d37 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" critical-section = { version = "1.1.1", features = ["restore-state-bool"] } embassy-sync = { version = "0.3.0", path = "../../embassy-sync" } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time" } +embassy-time = { version = "0.1.5", path = "../../embassy-time" } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } riscv-rt = "0.11" diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index a1e4c085..1fb73857 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -9,10 +9,10 @@ teleprobe-meta = "1.1" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 0250fd5f..0c04a55f 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -93,6 +93,7 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_pin(&mut p.PIN_29, Pull::Down), &mut low, + 1, &mut p.DMA_CH0, ) .await @@ -100,12 +101,18 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_pin(&mut p.PIN_29, Pull::None), &mut none, + 1, &mut p.DMA_CH0, ) .await .unwrap(); - adc.read_many_raw(&mut Channel::new_pin(&mut p.PIN_29, Pull::Up), &mut up, &mut p.DMA_CH0) - .await; + adc.read_many_raw( + &mut Channel::new_pin(&mut p.PIN_29, Pull::Up), + &mut up, + 1, + &mut p.DMA_CH0, + ) + .await; defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); defmt::assert!(up.iter().all(|s| s.good())); defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value())); @@ -115,6 +122,7 @@ async fn main(_spawner: Spawner) { adc.read_many( &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), &mut temp, + 1, &mut p.DMA_CH0, ) .await diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs index df1ed8d2..4678775e 100644 --- a/tests/rp/src/bin/bootsel.rs +++ b/tests/rp/src/bin/bootsel.rs @@ -5,7 +5,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { // defmt RTT header. Reading that header might touch flash memory, which // interferes with flash write operations. // https://github.com/knurling-rs/defmt/pull/683 - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; assert_eq!(p.BOOTSEL.is_pressed(), false); diff --git a/tests/rp/src/bin/flash.rs b/tests/rp/src/bin/flash.rs index 75be2bf0..2d85135d 100644 --- a/tests/rp/src/bin/flash.rs +++ b/tests/rp/src/bin/flash.rs @@ -6,7 +6,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; use embassy_rp::flash::{Async, ERASE_SIZE, FLASH_BASE}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; const ADDR_OFFSET: u32 = 0x8000; @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { // defmt RTT header. Reading that header might touch flash memory, which // interferes with flash write operations. // https://github.com/knurling-rs/defmt/pull/683 - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; let mut flash = embassy_rp::flash::Flash::<_, Async, { 2 * 1024 * 1024 }>::new(p.FLASH, p.DMA_CH0); diff --git a/tests/rp/src/bin/float.rs b/tests/rp/src/bin/float.rs index 2874aa91..1e89c10f 100644 --- a/tests/rp/src/bin/float.rs +++ b/tests/rp/src/bin/float.rs @@ -6,7 +6,7 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; use embassy_rp::pac; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) { rad_d + PI_D, rad_d % PI_D ); - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; } let rom_accesses = pac::BUSCTRL.perfctr(0).read().perfctr(); diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs index 60c65b7a..26582f74 100644 --- a/tests/rp/src/bin/gpio_async.rs +++ b/tests/rp/src/bin/gpio_async.rs @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { let set_high_future = async { // Allow time for wait_for_high_future to await wait_for_high(). - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_high_future = async { @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_low_future = async { @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_low(), "input was expected to be low"); let set_high_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_rising_edge_future = async { @@ -87,7 +87,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_falling_edge_future = async { @@ -107,7 +107,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_high(), "input was expected to be high"); let set_low_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_low(); }; let wait_for_any_edge_future = async { @@ -127,7 +127,7 @@ async fn main(_spawner: Spawner) { assert!(input.is_low(), "input was expected to be low"); let set_high_future = async { - Timer::after(Duration::from_millis(10)).await; + Timer::after_millis(10).await; output.set_high(); }; let wait_for_any_edge_future = async { diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index 8c02b844..8c9db115 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs @@ -7,7 +7,7 @@ use defmt::{assert, assert_eq, assert_ne, *}; use embassy_executor::Spawner; use embassy_rp::gpio::{Input, Level, Output, Pull}; use embassy_rp::pwm::{Config, InputMode, Pwm}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -48,13 +48,13 @@ async fn main(_spawner: Spawner) { { let pin1 = Input::new(&mut p9, Pull::None); let _pwm = Pwm::new_output_a(&mut p.PWM_CH3, &mut p6, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); } @@ -62,13 +62,13 @@ async fn main(_spawner: Spawner) { { let pin2 = Input::new(&mut p11, Pull::None); let _pwm = Pwm::new_output_b(&mut p.PWM_CH3, &mut p7, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_ne!(pin2.is_high(), invert_a); } @@ -77,16 +77,16 @@ async fn main(_spawner: Spawner) { let pin1 = Input::new(&mut p9, Pull::None); let pin2 = Input::new(&mut p11, Pull::None); let _pwm = Pwm::new_output_ab(&mut p.PWM_CH3, &mut p6, &mut p7, cfg.clone()); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); assert_ne!(pin2.is_high(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_low(), invert_a); assert_ne!(pin2.is_low(), invert_a); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pin1.is_high(), invert_a); assert_ne!(pin2.is_high(), invert_a); } @@ -97,14 +97,14 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::Low); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::Level, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_low(); let ctr = pwm.counter(); assert!(ctr >= 1000); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), ctr); } @@ -113,13 +113,13 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::Low); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::RisingEdge, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_low(); assert_eq!(pwm.counter(), 1); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), 1); } @@ -128,13 +128,13 @@ async fn main(_spawner: Spawner) { let mut pin2 = Output::new(&mut p11, Level::High); let pwm = Pwm::new_input(&mut p.PWM_CH3, &mut p7, InputMode::FallingEdge, cfg.clone()); assert_eq!(pwm.counter(), 0); - Timer::after(Duration::from_millis(5)).await; + Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); pin2.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; pin2.set_high(); assert_eq!(pwm.counter(), 1); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(pwm.counter(), 1); } diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index 00f3e194..8d351a3a 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs @@ -7,7 +7,7 @@ use defmt::{assert_eq, *}; use embassy_executor::Spawner; use embassy_rp::gpio::{Level, Output}; use embassy_rp::uart::{Blocking, Config, Error, Instance, Parity, Uart, UartRx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; fn read(uart: &mut Uart<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> { @@ -24,14 +24,14 @@ fn read1(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Resu async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -39,10 +39,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index 6ab7de29..6a9c910f 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs @@ -9,7 +9,7 @@ use embassy_rp::bind_interrupts; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Instance, Parity}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use embedded_io_async::{Read, ReadExactError, Write}; use {defmt_rtt as _, panic_probe as _}; @@ -39,14 +39,14 @@ async fn read1(uart: &mut BufferedUartRx<'_, impl Instance>) -> async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -54,10 +54,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index cd4af1ef..e79fcde6 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs @@ -9,7 +9,7 @@ use embassy_rp::bind_interrupts; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::UART0; use embassy_rp::uart::{Async, Config, Error, Instance, InterruptHandler, Parity, Uart, UartRx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -30,14 +30,14 @@ async fn read1(uart: &mut UartRx<'_, impl Instance, Async>) -> R async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option) { pin.set_low(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; for i in 0..8 { if v & (1 << i) == 0 { pin.set_low(); } else { pin.set_high(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } if let Some(b) = parity { if b { @@ -45,10 +45,10 @@ async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: O } else { pin.set_low(); } - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } pin.set_high(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; } #[embassy_executor::main] @@ -105,7 +105,7 @@ async fn main(_spawner: Spawner) { // new data is accepted, latest overrunning byte first assert_eq!(read(&mut uart).await, Ok([3])); uart.blocking_write(&[8, 9]).unwrap(); - Timer::after(Duration::from_millis(1)).await; + Timer::after_millis(1).await; assert_eq!(read(&mut uart).await, Ok([8, 9])); } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index fd18cd77..c6a50e2c 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -6,26 +6,32 @@ license = "MIT OR Apache-2.0" autobins = false [features] -stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill -stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" -stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo -stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo -stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma"] # Nucleo -stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo -stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" ] # Nucleo -stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth"] # Nucleo -stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono"] # IoT board -stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo -stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] # Nucleo -stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma"] # Nucleo -stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma"] # Nucleo -stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo -stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth"] # Nucleo -stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth"] # Nucleo -stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] # Nucleo -stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo +stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] +stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"] +stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] +stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] +stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma", "rng"] +stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] +stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] +stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] +stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] +stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] +stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] +stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] +stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng"] +stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma", "rng"] +stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] +stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng"] +stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] +stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng"] +stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] +stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] +stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] +stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] +stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] eth = [] +rng = [] sdmmc = [] stop = ["embassy-stm32/low-power"] chrono = ["embassy-stm32/chrono", "dep:chrono"] @@ -41,11 +47,11 @@ teleprobe-meta = "1" embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.4", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } +embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } perf-client = { path = "../perf-client" } defmt = "0.3.0" @@ -86,6 +92,11 @@ name = "gpio" path = "src/bin/gpio.rs" required-features = [] +[[bin]] +name = "rng" +path = "src/bin/rng.rs" +required-features = [ "rng",] + [[bin]] name = "rtc" path = "src/bin/rtc.rs" diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index 9aabf854..c5d0e40d 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs @@ -8,12 +8,14 @@ fn main() -> Result<(), Box> { println!("cargo:rustc-link-search={}", out.display()); println!("cargo:rustc-link-arg-bins=--nmagic"); - // too little RAM to run from RAM. if cfg!(any( + // too little RAM to run from RAM. feature = "stm32f103c8", feature = "stm32c031c6", feature = "stm32wb55rg", feature = "stm32l073rz", + // wrong ram size in stm32-data + feature = "stm32wl55jc", )) { println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rerun-if-changed=link.x"); diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index fb7a84b1..10e3c3e8 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -12,7 +12,7 @@ use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::dac::{DacCh1, DacChannel, Value}; use embassy_stm32::dma::NoDma; -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { unwrap!(dac.set(Value::Bit8(0))); // Now wait a little to obtain a stable value - Timer::after(Duration::from_millis(30)).await; + Timer::after_millis(30).await; let offset = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); for v in 0..=255 { @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { unwrap!(dac.set(Value::Bit8(dac_output_val))); // Now wait a little to obtain a stable value - Timer::after(Duration::from_millis(30)).await; + Timer::after_millis(30).await; // Need to steal the peripherals here because PA4 is obviously in use already let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4); diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 6d5e05cd..75435494 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -60,6 +60,8 @@ async fn main(spawner: Spawner) { let n = 4; #[cfg(feature = "stm32f207zg")] let n = 5; + #[cfg(feature = "stm32h753zi")] + let n = 6; let mac_addr = [0x00, n, 0xDE, 0xAD, 0xBE, 0xEF]; diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index 49d9a60f..83c96ce9 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs @@ -217,8 +217,7 @@ async fn main(_spawner: Spawner) { } fn delay() { - #[cfg(feature = "stm32h755zi")] - cortex_m::asm::delay(10000); - #[cfg(not(feature = "stm32h755zi"))] + #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h7a3zi"))] + cortex_m::asm::delay(9000); cortex_m::asm::delay(1000); } diff --git a/tests/stm32/src/bin/rng.rs b/tests/stm32/src/bin/rng.rs new file mode 100644 index 00000000..b7f36137 --- /dev/null +++ b/tests/stm32/src/bin/rng.rs @@ -0,0 +1,56 @@ +// required-features: rng +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../common.rs"] +mod common; +use common::*; +use embassy_executor::Spawner; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng}; +use {defmt_rtt as _, panic_probe as _}; + +#[cfg(any( + feature = "stm32l4a6zg", + feature = "stm32h755zi", + feature = "stm32h753zi", + feature = "stm32f429zi" +))] +bind_interrupts!(struct Irqs { + HASH_RNG => rng::InterruptHandler; +}); +#[cfg(any(feature = "stm32l073rz"))] +bind_interrupts!(struct Irqs { + RNG_LPUART1 => rng::InterruptHandler; +}); +#[cfg(not(any( + feature = "stm32l4a6zg", + feature = "stm32l073rz", + feature = "stm32h755zi", + feature = "stm32h753zi", + feature = "stm32f429zi" +)))] +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); + + let mut rng = Rng::new(p.RNG, Irqs); + + let mut buf1 = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf1).await); + info!("random bytes: {:02x}", buf1); + + let mut buf2 = [0u8; 16]; + unwrap!(rng.async_fill_bytes(&mut buf2).await); + info!("random bytes: {:02x}", buf2); + + defmt::assert!(buf1 != buf2); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 46fdbfae..64f1122a 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs @@ -12,7 +12,7 @@ use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) { rtc.set_datetime(now.into()).expect("datetime not set"); info!("Waiting 5 seconds"); - Timer::after(Duration::from_millis(5000)).await; + Timer::after_millis(5000).await; let then: NaiveDateTime = rtc.now().unwrap().into(); let seconds = (then - now).num_seconds(); diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 929869bc..b9810673 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs @@ -10,11 +10,11 @@ use chrono::NaiveDate; use common::*; use cortex_m_rt::entry; use embassy_executor::Spawner; -use embassy_stm32::low_power::{stop_with_rtc, Executor}; +use embassy_stm32::low_power::{stop_ready, stop_with_rtc, Executor, StopMode}; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::Config; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use static_cell::make_static; #[entry] @@ -28,7 +28,8 @@ fn main() -> ! { async fn task_1() { for _ in 0..9 { info!("task 1: waiting for 500ms..."); - Timer::after(Duration::from_millis(500)).await; + defmt::assert!(stop_ready(StopMode::Stop2)); + Timer::after_millis(500).await; } } @@ -36,7 +37,8 @@ async fn task_1() { async fn task_2() { for _ in 0..5 { info!("task 2: waiting for 1000ms..."); - Timer::after(Duration::from_millis(1000)).await; + defmt::assert!(stop_ready(StopMode::Stop2)); + Timer::after_millis(1000).await; } info!("Test OK"); diff --git a/tests/stm32/src/bin/timer.rs b/tests/stm32/src/bin/timer.rs index f8b453cd..4efeb0a4 100644 --- a/tests/stm32/src/bin/timer.rs +++ b/tests/stm32/src/bin/timer.rs @@ -7,7 +7,7 @@ mod common; use common::*; use defmt::assert; use embassy_executor::Spawner; -use embassy_time::{Duration, Instant, Timer}; +use embassy_time::{Instant, Timer}; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); let start = Instant::now(); - Timer::after(Duration::from_millis(100)).await; + Timer::after_millis(100).await; let end = Instant::now(); let ms = (end - start).as_millis(); info!("slept for {} ms", ms); diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index 1ee7e596..7e15f64b 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs @@ -10,7 +10,7 @@ use common::*; use defmt::{assert_eq, panic}; use embassy_executor::Spawner; use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; -use embassy_time::{Duration, Timer}; +use embassy_time::Timer; use rand_chacha::ChaCha8Rng; use rand_core::{RngCore, SeedableRng}; @@ -54,7 +54,7 @@ async fn main(spawner: Spawner) { #[embassy_executor::task] async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) { // workaround https://github.com/embassy-rs/embassy/issues/1426 - Timer::after(Duration::from_millis(100) as _).await; + Timer::after_millis(100).await; let mut rng = ChaCha8Rng::seed_from_u64(1337); @@ -70,7 +70,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) } tx.write(&buf[..len]).await.unwrap(); - Timer::after(Duration::from_micros((rng.next_u32() % 1000) as _)).await; + Timer::after_micros((rng.next_u32() % 1000) as _).await; } } @@ -98,7 +98,7 @@ async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UA } if received < max_len { - Timer::after(Duration::from_micros((rng.next_u32() % 1000) as _)).await; + Timer::after_micros((rng.next_u32() % 1000) as _).await; } i += received; diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 2bf50079..ff808281 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -18,8 +18,14 @@ teleprobe_meta::target!(b"nucleo-stm32f429zi"); teleprobe_meta::target!(b"nucleo-stm32wb55rg"); #[cfg(feature = "stm32h755zi")] teleprobe_meta::target!(b"nucleo-stm32h755zi"); +#[cfg(feature = "stm32h753zi")] +teleprobe_meta::target!(b"nucleo-stm32h753zi"); +#[cfg(feature = "stm32h7a3zi")] +teleprobe_meta::target!(b"nucleo-stm32h7a3zi"); #[cfg(feature = "stm32u585ai")] teleprobe_meta::target!(b"iot-stm32u585ai"); +#[cfg(feature = "stm32u5a5zj")] +teleprobe_meta::target!(b"nucleo-stm32u5a5zj"); #[cfg(feature = "stm32h563zi")] teleprobe_meta::target!(b"nucleo-stm32h563zi"); #[cfg(feature = "stm32c031c6")] @@ -42,6 +48,10 @@ teleprobe_meta::target!(b"nucleo-stm32f207zg"); teleprobe_meta::target!(b"nucleo-stm32f303ze"); #[cfg(feature = "stm32l496zg")] teleprobe_meta::target!(b"nucleo-stm32l496zg"); +#[cfg(feature = "stm32wl55jc")] +teleprobe_meta::target!(b"nucleo-stm32wl55jc"); +#[cfg(feature = "stm32wba52cg")] +teleprobe_meta::target!(b"nucleo-stm32wba52cg"); macro_rules! define_peris { ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { @@ -103,18 +113,30 @@ define_peris!( SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, ); -#[cfg(feature = "stm32h755zi")] +#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] define_peris!( UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32h7a3zi")] +define_peris!( + UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, +); #[cfg(feature = "stm32u585ai")] define_peris!( UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, SPI = SPI1, SPI_SCK = PE13, SPI_MOSI = PE15, SPI_MISO = PE14, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32u5a5zj")] +define_peris!( + UART = LPUART1, UART_TX = PG7, UART_RX = PG8, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, +); #[cfg(feature = "stm32h563zi")] define_peris!( UART = LPUART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, @@ -181,11 +203,35 @@ define_peris!( SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, ); +#[cfg(feature = "stm32wl55jc")] +define_peris!( + UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, + SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, + @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler;}, +); +#[cfg(feature = "stm32wba52cg")] +define_peris!( + UART = LPUART1, UART_TX = PB5, UART_RX = PA10, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, + SPI = SPI1, SPI_SCK = PB4, SPI_MOSI = PA15, SPI_MISO = PB3, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, + @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler;}, +); pub fn config() -> Config { + // Setting this bit is mandatory to use PG[15:2]. + #[cfg(feature = "stm32u5a5zj")] + embassy_stm32::pac::PWR.svmcr().modify(|w| { + w.set_io2sv(true); + w.set_io2vmen(true); + }); + #[allow(unused_mut)] let mut config = Config::default(); + #[cfg(feature = "stm32wb55rg")] + { + config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; + } + #[cfg(feature = "stm32f207zg")] { use embassy_stm32::rcc::*; @@ -216,16 +262,44 @@ pub fn config() -> Config { #[cfg(feature = "stm32f429zi")] { - // TODO: stm32f429zi can do up to 180mhz, but that makes tests fail. - // perhaps we have some bug w.r.t overdrive. - config.rcc.sys_ck = Some(Hertz(168_000_000)); - config.rcc.pclk1 = Some(Hertz(42_000_000)); - config.rcc.pclk2 = Some(Hertz(84_000_000)); + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL180, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; } #[cfg(feature = "stm32f767zi")] { - config.rcc.sys_ck = Some(Hertz(200_000_000)); + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(8_000_000), + mode: HseMode::Bypass, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL216, + divp: Some(Pllp::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz. + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV4; + config.rcc.apb2_pre = APBPrescaler::DIV2; + config.rcc.sys = Sysclk::PLL1_P; } #[cfg(feature = "stm32h563zi")] @@ -238,7 +312,7 @@ pub fn config() -> Config { mode: HseMode::BypassDigital, }); config.rcc.pll1 = Some(Pll { - source: PllSource::Hse, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL125, divp: Some(PllDiv::DIV2), @@ -249,18 +323,18 @@ pub fn config() -> Config { config.rcc.apb1_pre = APBPrescaler::DIV1; config.rcc.apb2_pre = APBPrescaler::DIV1; config.rcc.apb3_pre = APBPrescaler::DIV1; - config.rcc.sys = Sysclk::Pll1P; + config.rcc.sys = Sysclk::PLL1_P; config.rcc.voltage_scale = VoltageScale::Scale0; } - #[cfg(feature = "stm32h755zi")] + #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] { use embassy_stm32::rcc::*; - config.rcc.hsi = Some(Hsi::Mhz64); + config.rcc.hsi = Some(HSIPrescaler::DIV1); config.rcc.csi = true; config.rcc.hsi48 = true; // needed for RNG - config.rcc.pll_src = PllSource::Hsi; config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV2), @@ -268,13 +342,14 @@ pub fn config() -> Config { divr: None, }); config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL50, divp: Some(PllDiv::DIV8), // 100mhz divq: None, divr: None, }); - config.rcc.sys = Sysclk::Pll1P; // 400 Mhz + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz @@ -284,44 +359,110 @@ pub fn config() -> Config { config.rcc.adc_clock_source = AdcClockSource::PLL2_P; } - #[cfg(any(feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] + #[cfg(any(feature = "stm32h7a3zi"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( - // 72Mhz clock (16 / 1 * 18 / 4) - PLLSource::HSI16, - PllRDiv::DIV4, - PllPreDiv::DIV1, - PllMul::MUL18, - Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) - ); + config.rcc.hsi = Some(HSIPrescaler::DIV1); + config.rcc.csi = true; + config.rcc.hsi48 = true; // needed for RNG + config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL35, + divp: Some(PllDiv::DIV2), // 280 Mhz + divq: Some(PllDiv::DIV8), // SPI1 cksel defaults to pll1_q + divr: None, + }); + config.rcc.pll2 = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL35, + divp: Some(PllDiv::DIV8), // 70 Mhz + divq: None, + divr: None, + }); + config.rcc.sys = Sysclk::PLL1_P; // 280 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV1; // 280 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz + config.rcc.voltage_scale = VoltageScale::Scale0; + config.rcc.adc_clock_source = AdcClockSource::PLL2_P; + } + + #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hsi = true; + config.rcc.pll = Some(Pll { + source: PLLSource::HSI, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL18, + divp: None, + divq: Some(PllQDiv::DIV6), // 48Mhz (16 / 1 * 18 / 6) + divr: Some(PllRDiv::DIV4), // sysclk 72Mhz clock (16 / 1 * 18 / 4) + }); + } + + #[cfg(feature = "stm32wl55jc")] + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + prescaler: HsePrescaler::DIV1, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); } #[cfg(any(feature = "stm32l552ze"))] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::PLL( + config.rcc.hsi = true; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) - PLLSource::HSI16, - PllRDiv::DIV2, - PllPreDiv::DIV4, - PllMul::MUL55, - None, - ); + source: PLLSource::HSI, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL55, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), + }); } - #[cfg(feature = "stm32u585ai")] + #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); } + #[cfg(feature = "stm32wba52cg")] + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::HSI; + + embassy_stm32::pac::RCC.ccipr2().write(|w| { + w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI); + }); + } + #[cfg(feature = "stm32l073rz")] { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI16, + PLLSource::HSI, PLLMul::MUL4, PLLDiv::DIV2, ); @@ -332,7 +473,7 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.mux = ClockSrc::PLL( // 32Mhz clock (16 * 4 / 2) - PLLSource::HSI16, + PLLSource::HSI, PLLMul::MUL4, PLLDiv::DIV2, );