From 54ef354d21f7a90b0ccddbe6d1a037b35baa6006 Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Fri, 18 Apr 2025 23:06:20 +0200 Subject: pwm: enable pull-down resistors for pins in Drop implementation --- embassy-rp/src/pwm.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 6dfb90fef..1e1ccc4c6 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -464,6 +464,10 @@ impl<'d> Drop for Pwm<'d> { pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false)); if let Some(pin) = &self.pin_a { pin.gpio().ctrl().write(|w| w.set_funcsel(31)); + // Enable pin PULL-DOWN + pin.pad_ctrl().modify(|w| { + w.set_pde(true); + }); } if let Some(pin) = &self.pin_b { pin.gpio().ctrl().write(|w| w.set_funcsel(31)); @@ -472,6 +476,10 @@ impl<'d> Drop for Pwm<'d> { pin.pad_ctrl().modify(|w| { w.set_ie(false); }); + // Enable pin PULL-DOWN + pin.pad_ctrl().modify(|w| { + w.set_pde(true); + }); } } } -- cgit From 8cf8fb324ce9063890d8912cccd02bc79fbffd1d Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 07:15:11 +0200 Subject: Add function to allow re-init rcc config for stm32 --- embassy-stm32/src/lib.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 226293a9d..0cc6886d9 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -616,3 +616,31 @@ fn init_hw(config: Config) -> Peripherals { p }) } + + +/// Re-initialize the `embassy-stm32` clock configuration with the provided configuration. +/// +/// This is useful when you need to alter the CPU clock after configuring peripherals. +/// For instance, configure an external clock via spi or i2c. +/// +/// Please not this only re-configures the rcc and the time driver (not GPIO, EXTI, etc). +/// +/// This should only be called after `init`. +#[cfg(not(feature = "_dual-core"))] +pub fn reinitialize_rcc(config: Config) { + critical_section::with(|cs| { + unsafe { + rcc::init(config.rcc); + + // must be after rcc init + #[cfg(feature = "_time-driver")] + time_driver::init(cs); + + #[cfg(feature = "low-power")] + { + crate::rcc::REFCOUNT_STOP2 = 0; + crate::rcc::REFCOUNT_STOP1 = 0; + } + } + }) +} -- cgit From f67f11534f9617279b9ff83a693aad5f7ceb4d4f Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 07:25:21 +0200 Subject: Fixed formatting --- embassy-stm32/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 0cc6886d9..cccffd4fe 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -617,7 +617,6 @@ fn init_hw(config: Config) -> Peripherals { }) } - /// Re-initialize the `embassy-stm32` clock configuration with the provided configuration. /// /// This is useful when you need to alter the CPU clock after configuring peripherals. -- cgit From 6842ced7cb858f7735bc9376db9d39386dadec58 Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 10:17:04 +0200 Subject: Fixed for cs not always used --- embassy-stm32/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index cccffd4fe..1ad30d522 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -627,13 +627,13 @@ fn init_hw(config: Config) -> Peripherals { /// This should only be called after `init`. #[cfg(not(feature = "_dual-core"))] pub fn reinitialize_rcc(config: Config) { - critical_section::with(|cs| { + critical_section::with(|_cs| { unsafe { rcc::init(config.rcc); // must be after rcc init #[cfg(feature = "_time-driver")] - time_driver::init(cs); + time_driver::init(_cs); #[cfg(feature = "low-power")] { -- cgit From b2c32a947ea724facb75f81978dfb5d3ca331ddb Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 10:54:35 +0200 Subject: Updated based on feedback --- embassy-stm32/src/lib.rs | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 1ad30d522..af7ef9fe0 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -222,6 +222,7 @@ pub(crate) use stm32_metapac as pac; use crate::interrupt::Priority; #[cfg(feature = "rt")] pub use crate::pac::NVIC_PRIO_BITS; +use critical_section::CriticalSection; /// `embassy-stm32` global configuration. #[non_exhaustive] @@ -600,17 +601,7 @@ fn init_hw(config: Config) -> Peripherals { #[cfg(feature = "exti")] exti::init(cs); - rcc::init(config.rcc); - - // must be after rcc init - #[cfg(feature = "_time-driver")] - time_driver::init(cs); - - #[cfg(feature = "low-power")] - { - crate::rcc::REFCOUNT_STOP2 = 0; - crate::rcc::REFCOUNT_STOP1 = 0; - } + init_rcc(cs, config.rcc); } p @@ -626,20 +617,23 @@ fn init_hw(config: Config) -> Peripherals { /// /// This should only be called after `init`. #[cfg(not(feature = "_dual-core"))] -pub fn reinitialize_rcc(config: Config) { - critical_section::with(|_cs| { - unsafe { - rcc::init(config.rcc); +pub fn reinit(config: rcc::Config) { + critical_section::with(|cs| init_rcc(cs, config)) +} - // must be after rcc init - #[cfg(feature = "_time-driver")] - time_driver::init(_cs); +#[cfg(not(feature = "_dual-core"))] +fn init_rcc(_cs: CriticalSection, config: rcc::Config) { + unsafe { + rcc::init(config); - #[cfg(feature = "low-power")] - { - crate::rcc::REFCOUNT_STOP2 = 0; - crate::rcc::REFCOUNT_STOP1 = 0; - } + // must be after rcc init + #[cfg(feature = "_time-driver")] + time_driver::init(_cs); + + #[cfg(feature = "low-power")] + { + crate::rcc::REFCOUNT_STOP2 = 0; + crate::rcc::REFCOUNT_STOP1 = 0; } - }) + } } -- cgit From 8661b019e609f50bd78067cc49c65a4babfead00 Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 10:57:02 +0200 Subject: Fixed formatting --- embassy-stm32/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index af7ef9fe0..b0bc7ffbb 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -213,6 +213,7 @@ macro_rules! bind_interrupts { // Reexports pub use _generated::{peripherals, Peripherals}; +use critical_section::CriticalSection; pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] pub use stm32_metapac as pac; @@ -222,7 +223,6 @@ pub(crate) use stm32_metapac as pac; use crate::interrupt::Priority; #[cfg(feature = "rt")] pub use crate::pac::NVIC_PRIO_BITS; -use critical_section::CriticalSection; /// `embassy-stm32` global configuration. #[non_exhaustive] -- cgit From b0519d11fb0842267e0cdd36da9b84cdb0ebb23a Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 11:01:46 +0200 Subject: Possible fix for unused CS and feature selections --- embassy-stm32/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index b0bc7ffbb..466634edf 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -213,6 +213,7 @@ macro_rules! bind_interrupts { // Reexports pub use _generated::{peripherals, Peripherals}; +#[cfg(not(feature = "_dual-core"))] use critical_section::CriticalSection; pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] -- cgit From 584066e209141ce92d882ceb6e7525c980833689 Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Thu, 24 Apr 2025 11:07:15 +0200 Subject: updated cs gates for dual core --- embassy-stm32/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 466634edf..444d14f28 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -213,7 +213,6 @@ macro_rules! bind_interrupts { // Reexports pub use _generated::{peripherals, Peripherals}; -#[cfg(not(feature = "_dual-core"))] use critical_section::CriticalSection; pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] @@ -622,7 +621,6 @@ pub fn reinit(config: rcc::Config) { critical_section::with(|cs| init_rcc(cs, config)) } -#[cfg(not(feature = "_dual-core"))] fn init_rcc(_cs: CriticalSection, config: rcc::Config) { unsafe { rcc::init(config); -- cgit From 74cb84eb4e4be75859deb6fa4896efae5345eacb Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Mon, 28 Apr 2025 09:14:56 +0200 Subject: Moved functions to rcc module (this is a bit awkward as we now have two init functions in rcc: `rcc::init`and `rcc::init_rcc`) --- embassy-stm32/src/lib.rs | 32 +------------------------------- embassy-stm32/src/rcc/mod.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 444d14f28..3e84d3386 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -213,7 +213,6 @@ macro_rules! bind_interrupts { // Reexports pub use _generated::{peripherals, Peripherals}; -use critical_section::CriticalSection; pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] pub use stm32_metapac as pac; @@ -601,38 +600,9 @@ fn init_hw(config: Config) -> Peripherals { #[cfg(feature = "exti")] exti::init(cs); - init_rcc(cs, config.rcc); + rcc::init_rcc(cs, config.rcc); } p }) } - -/// Re-initialize the `embassy-stm32` clock configuration with the provided configuration. -/// -/// This is useful when you need to alter the CPU clock after configuring peripherals. -/// For instance, configure an external clock via spi or i2c. -/// -/// Please not this only re-configures the rcc and the time driver (not GPIO, EXTI, etc). -/// -/// This should only be called after `init`. -#[cfg(not(feature = "_dual-core"))] -pub fn reinit(config: rcc::Config) { - critical_section::with(|cs| init_rcc(cs, config)) -} - -fn init_rcc(_cs: CriticalSection, config: rcc::Config) { - unsafe { - rcc::init(config); - - // must be after rcc init - #[cfg(feature = "_time-driver")] - time_driver::init(_cs); - - #[cfg(feature = "low-power")] - { - crate::rcc::REFCOUNT_STOP2 = 0; - crate::rcc::REFCOUNT_STOP1 = 0; - } - } -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 4f43d3748..cf88cfad6 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -34,6 +34,7 @@ pub use _version::*; use stm32_metapac::RCC; pub use crate::_generated::{mux, Clocks}; +use crate::rcc; use crate::time::Hertz; #[cfg(feature = "low-power")] @@ -369,3 +370,32 @@ pub fn enable_and_reset() { pub fn disable() { T::RCC_INFO.disable(); } + +/// Re-initialize the `embassy-stm32` clock configuration with the provided configuration. +/// +/// This is useful when you need to alter the CPU clock after configuring peripherals. +/// For instance, configure an external clock via spi or i2c. +/// +/// Please not this only re-configures the rcc and the time driver (not GPIO, EXTI, etc). +/// +/// This should only be called after `init`. +#[cfg(not(feature = "_dual-core"))] +pub fn reinit(config: Config) { + critical_section::with(|cs| init_rcc(cs, config)) +} + +fn init_rcc(_cs: CriticalSection, config: Config) { + unsafe { + init(config); + + // must be after rcc init + #[cfg(feature = "_time-driver")] + crate::time_driver::init(_cs); + + #[cfg(feature = "low-power")] + { + REFCOUNT_STOP2 = 0; + REFCOUNT_STOP1 = 0; + } + } +} -- cgit From 1d578f5a7e1fe2b676f36b1960a93af899418c91 Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Mon, 28 Apr 2025 09:21:21 +0200 Subject: function needs to be pub(crate) --- embassy-stm32/src/rcc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index cf88cfad6..22bec6d1a 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -384,7 +384,7 @@ pub fn reinit(config: Config) { critical_section::with(|cs| init_rcc(cs, config)) } -fn init_rcc(_cs: CriticalSection, config: Config) { +pub(crate) fn init_rcc(_cs: CriticalSection, config: Config) { unsafe { init(config); -- cgit From a94cc79b9b5e01f7b207947a1dfa30432e508a9c Mon Sep 17 00:00:00 2001 From: Michael Medin Date: Mon, 28 Apr 2025 18:52:03 +0200 Subject: removed unused import --- embassy-stm32/src/rcc/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 22bec6d1a..3c00d5dfb 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -34,7 +34,6 @@ pub use _version::*; use stm32_metapac::RCC; pub use crate::_generated::{mux, Clocks}; -use crate::rcc; use crate::time::Hertz; #[cfg(feature = "low-power")] -- cgit From f8f9c38b2e2527c6e3b8396e06fbb18fc1ce2a1c Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 29 Apr 2025 08:49:19 -0400 Subject: add a task registry to tracing infrastructure --- embassy-executor/src/raw/mod.rs | 2 +- embassy-executor/src/raw/trace.rs | 139 +++++++++++++++++++++++++++++++++++++- embassy-executor/src/spawner.rs | 27 ++++++++ 3 files changed, 166 insertions(+), 2 deletions(-) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 88d839e07..35c82557c 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -18,7 +18,7 @@ mod state; pub mod timer_queue; #[cfg(feature = "trace")] -mod trace; +pub mod trace; pub(crate) mod util; #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] mod waker; diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index aba519c8f..bdd3e4706 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -83,6 +83,129 @@ use crate::raw::{SyncExecutor, TaskRef}; +use core::cell::UnsafeCell; +use core::sync::atomic::{AtomicUsize, Ordering}; +use rtos_trace::TaskInfo; + +const MAX_TASKS: usize = 1000; + +/// Represents a task being tracked in the task registry. +/// +/// Contains the task's unique identifier and optional name. +#[derive(Clone)] +pub struct TrackedTask { + task_id: u32, + name: Option<&'static str>, +} + +/// A thread-safe registry for tracking tasks in the system. +/// +/// This registry maintains a list of active tasks with their IDs and optional names. +/// It supports registering, unregistering, and querying information about tasks. +/// The registry has a fixed capacity of `MAX_TASKS`. +pub struct TaskRegistry { + tasks: [UnsafeCell>; MAX_TASKS], + count: AtomicUsize, +} + +impl TaskRegistry { + /// Creates a new empty task registry. + /// + /// This initializes a registry that can track up to `MAX_TASKS` tasks. + pub const fn new() -> Self { + const EMPTY: UnsafeCell> = UnsafeCell::new(None); + Self { + tasks: [EMPTY; MAX_TASKS], + count: AtomicUsize::new(0), + } + } + + /// Registers a new task in the registry. + /// + /// # Arguments + /// * `task_id` - Unique identifier for the task + /// * `name` - Optional name for the task + /// + /// # Note + /// If the registry is full, the task will not be registered. + pub fn register(&self, task_id: u32, name: Option<&'static str>) { + let count = self.count.load(Ordering::Relaxed); + if count < MAX_TASKS { + for i in 0..MAX_TASKS { + unsafe { + let slot = &self.tasks[i]; + let slot_ref = &mut *slot.get(); + if slot_ref.is_none() { + *slot_ref = Some(TrackedTask { task_id, name }); + self.count.fetch_add(1, Ordering::Relaxed); + break; + } + } + } + } + } + + /// Removes a task from the registry. + /// + /// # Arguments + /// * `task_id` - Unique identifier of the task to remove + pub fn unregister(&self, task_id: u32) { + for i in 0..MAX_TASKS { + unsafe { + let slot = &self.tasks[i]; + let slot_ref = &mut *slot.get(); + if let Some(task) = slot_ref { + if task.task_id == task_id { + *slot_ref = None; + self.count.fetch_sub(1, Ordering::Relaxed); + break; + } + } + } + } + } + + /// Returns an iterator over all registered tasks. + /// + /// This allows accessing information about all tasks currently in the registry. + pub fn get_all_tasks(&self) -> impl Iterator + '_ { + (0..MAX_TASKS).filter_map(move |i| unsafe { + let slot = &self.tasks[i]; + (*slot.get()).clone() + }) + } + + /// Retrieves the name of a task with the given ID. + /// + /// # Arguments + /// * `task_id` - Unique identifier of the task + /// + /// # Returns + /// The name of the task if found and named, or `None` otherwise + pub fn get_task_name(&self, task_id: u32) -> Option<&'static str> { + for i in 0..MAX_TASKS { + unsafe { + let slot = &self.tasks[i]; + let slot_ref = &*slot.get(); + if let Some(task) = slot_ref { + if task.task_id == task_id { + return task.name; + } + } + } + } + None + } +} + +unsafe impl Sync for TaskRegistry {} +unsafe impl Send for TaskRegistry {} + +/// Global task registry instance used for tracking all tasks in the system. +/// +/// This provides a centralized registry accessible from anywhere in the application. +pub static TASK_REGISTRY: TaskRegistry = TaskRegistry::new(); + #[cfg(not(feature = "rtos-trace"))] extern "Rust" { /// This callback is called when the executor begins polling. This will always @@ -153,6 +276,8 @@ pub(crate) fn poll_start(executor: &SyncExecutor) { #[inline] pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { + let task_id = task.as_ptr() as u32; + #[cfg(not(feature = "rtos-trace"))] unsafe { _embassy_trace_task_new(executor as *const _ as u32, task.as_ptr() as u32) @@ -164,10 +289,14 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { #[inline] pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) { + let task_id = task.as_ptr() as u32; + #[cfg(not(feature = "rtos-trace"))] unsafe { _embassy_trace_task_end(executor as u32, task.as_ptr() as u32) } + + TASK_REGISTRY.unregister(task_id); } #[inline] @@ -213,7 +342,15 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) { #[cfg(feature = "rtos-trace")] impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { fn task_list() { - // We don't know what tasks exist, so we can't send them. + for task in TASK_REGISTRY.get_all_tasks() { + let info = rtos_trace::TaskInfo { + name: TASK_REGISTRY.get_task_name(task.task_id).unwrap(), + priority: 0, + stack_base: 0, + stack_size: 0, + }; + rtos_trace::trace::task_send_info(task.task_id, info); + } } fn time() -> u64 { const fn gcd(a: u64, b: u64) -> u64 { diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index ff243081c..ea754341b 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -5,6 +5,8 @@ use core::sync::atomic::Ordering; use core::task::Poll; use super::raw; +#[cfg(feature = "rtos-trace")] +use super::raw::trace::TASK_REGISTRY; /// Token to spawn a newly-created task in an executor. /// @@ -154,6 +156,31 @@ impl Spawner { } } + /// Spawns a new task with a specified name. + /// + /// # Arguments + /// * `name` - Static string name to associate with the task + /// * `token` - Token representing the task to spawn + /// + /// # Returns + /// Result indicating whether the spawn was successful + #[cfg(feature = "rtos-trace")] + pub fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + let task = token.raw_task; + mem::forget(token); + + match task { + Some(task) => { + let task_id = task.as_ptr() as u32; + TASK_REGISTRY.register(task_id, Some(name)); + + unsafe { self.executor.spawn(task) }; + Ok(()) + } + None => Err(SpawnError::Busy), + } + } + // Used by the `embassy_executor_macros::main!` macro to throw an error when spawn // fails. This is here to allow conditional use of `defmt::unwrap!` // without introducing a `defmt` feature in the `embassy_executor_macros` package, -- cgit From 032898adf5848da237e4bf55b8c06c2ff73cae7c Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Mon, 5 May 2025 12:14:14 -0400 Subject: add a stub implementation for spawn_named When rtos-trace is not enabled, spawn_named will use spawn instead --- embassy-executor/src/spawner.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index ea754341b..f87700be6 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -181,6 +181,13 @@ impl Spawner { } } + /// When rtos-trace is disabled, spawn_named falls back to regular spawn. +/// This maintains API compatibility while optimizing out the name parameter. + #[cfg(not(feature = "rtos-trace"))] + pub fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + self.spawn(token) + } + // Used by the `embassy_executor_macros::main!` macro to throw an error when spawn // fails. This is here to allow conditional use of `defmt::unwrap!` // without introducing a `defmt` feature in the `embassy_executor_macros` package, -- cgit From bbffd2b3f9f27dd9c3ae3f66ac88bcd1ee1dcb93 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Mon, 5 May 2025 12:17:03 -0400 Subject: whitespace in the documentation --- embassy-executor/src/spawner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index f87700be6..4fc4312b9 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -182,7 +182,7 @@ impl Spawner { } /// When rtos-trace is disabled, spawn_named falls back to regular spawn. -/// This maintains API compatibility while optimizing out the name parameter. + /// This maintains API compatibility while optimizing out the name parameter. #[cfg(not(feature = "rtos-trace"))] pub fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { self.spawn(token) -- cgit From 05d52decb2a98ad5111962b71e667c692e68c23e Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 09:04:21 -0400 Subject: add name to TaskHeader --- embassy-executor/src/raw/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 35c82557c..2928848b8 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -89,6 +89,8 @@ pub(crate) struct TaskHeader { /// Integrated timer queue storage. This field should not be accessed outside of the timer queue. pub(crate) timer_queue_item: timer_queue::TimerQueueItem, + #[cfg(feature = "trace")] + pub(crate) name: Option<&'static str>, } /// This is essentially a `&'static TaskStorage` where the type of the future has been erased. @@ -190,6 +192,8 @@ impl TaskStorage { poll_fn: SyncUnsafeCell::new(None), timer_queue_item: timer_queue::TimerQueueItem::new(), + #[cfg(feature = "trace")] + name: None, }, future: UninitCell::uninit(), } -- cgit From 61f0f889a0dc89410218be725a43dcd967e53003 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 09:23:39 -0400 Subject: add get/set for task name --- embassy-executor/src/raw/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 2928848b8..3f4e06350 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -151,6 +151,21 @@ impl TaskRef { pub fn as_id(self) -> u32 { self.ptr.as_ptr() as u32 } + + /// Get the name for a task + #[cfg(feature = "trace")] + pub fn name(&self) -> Option<&'static str> { + self.header().name + } + + /// Set the name for a task + #[cfg(feature = "trace")] + pub fn set_name(&self, name: Option<&'static str>) { + unsafe { + let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; + (*header_ptr).name = name; + } + } } /// Raw storage in which a task can be spawned. -- cgit From 54b3fb6e7a12598e0f6299c18a333060d6a3f9c7 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 09:27:19 -0400 Subject: remove name from TaskRegistry and retrieve from task header instead --- embassy-executor/src/raw/trace.rs | 33 ++++++--------------------------- embassy-executor/src/spawner.rs | 3 ++- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index bdd3e4706..28be79cee 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -81,7 +81,7 @@ #![allow(unused)] -use crate::raw::{SyncExecutor, TaskRef}; +use crate::raw::{SyncExecutor, TaskHeader, TaskRef}; use core::cell::UnsafeCell; use core::sync::atomic::{AtomicUsize, Ordering}; @@ -95,7 +95,6 @@ const MAX_TASKS: usize = 1000; #[derive(Clone)] pub struct TrackedTask { task_id: u32, - name: Option<&'static str>, } /// A thread-safe registry for tracking tasks in the system. @@ -128,7 +127,7 @@ impl TaskRegistry { /// /// # Note /// If the registry is full, the task will not be registered. - pub fn register(&self, task_id: u32, name: Option<&'static str>) { + pub fn register(&self, task_id: u32) { let count = self.count.load(Ordering::Relaxed); if count < MAX_TASKS { for i in 0..MAX_TASKS { @@ -136,7 +135,7 @@ impl TaskRegistry { let slot = &self.tasks[i]; let slot_ref = &mut *slot.get(); if slot_ref.is_none() { - *slot_ref = Some(TrackedTask { task_id, name }); + *slot_ref = Some(TrackedTask { task_id }); self.count.fetch_add(1, Ordering::Relaxed); break; } @@ -174,28 +173,6 @@ impl TaskRegistry { (*slot.get()).clone() }) } - - /// Retrieves the name of a task with the given ID. - /// - /// # Arguments - /// * `task_id` - Unique identifier of the task - /// - /// # Returns - /// The name of the task if found and named, or `None` otherwise - pub fn get_task_name(&self, task_id: u32) -> Option<&'static str> { - for i in 0..MAX_TASKS { - unsafe { - let slot = &self.tasks[i]; - let slot_ref = &*slot.get(); - if let Some(task) = slot_ref { - if task.task_id == task_id { - return task.name; - } - } - } - } - None - } } unsafe impl Sync for TaskRegistry {} @@ -343,8 +320,10 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) { impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { fn task_list() { for task in TASK_REGISTRY.get_all_tasks() { + let task_ref = unsafe { TaskRef::from_ptr(task.task_id as *const TaskHeader) }; + let name = task_ref.name().unwrap_or("unnamed\0"); let info = rtos_trace::TaskInfo { - name: TASK_REGISTRY.get_task_name(task.task_id).unwrap(), + name, priority: 0, stack_base: 0, stack_size: 0, diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 4fc4312b9..40202299f 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -171,8 +171,9 @@ impl Spawner { match task { Some(task) => { + task.set_name(Some(name)); let task_id = task.as_ptr() as u32; - TASK_REGISTRY.register(task_id, Some(name)); + TASK_REGISTRY.register(task_id); unsafe { self.executor.spawn(task) }; Ok(()) -- cgit From f4e0cbb7cc476b171acd0b21448e9bbc848a616d Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 09:59:27 -0400 Subject: add ID field to TaskHeader --- embassy-executor/src/raw/mod.rs | 19 +++++++++++++++++++ embassy-executor/src/spawner.rs | 1 + 2 files changed, 20 insertions(+) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 3f4e06350..075d8a254 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -91,6 +91,8 @@ pub(crate) struct TaskHeader { pub(crate) timer_queue_item: timer_queue::TimerQueueItem, #[cfg(feature = "trace")] pub(crate) name: Option<&'static str>, + #[cfg(feature = "trace")] + pub(crate) id: u32, } /// This is essentially a `&'static TaskStorage` where the type of the future has been erased. @@ -166,6 +168,21 @@ impl TaskRef { (*header_ptr).name = name; } } + + /// Get the ID for a task + #[cfg(feature = "trace")] + pub fn id(&self) -> u32 { + self.header().id + } + + /// Set the ID for a task + #[cfg(feature = "trace")] + pub fn set_id(&self, id: u32) { + unsafe { + let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; + (*header_ptr).id = id; + } + } } /// Raw storage in which a task can be spawned. @@ -209,6 +226,8 @@ impl TaskStorage { timer_queue_item: timer_queue::TimerQueueItem::new(), #[cfg(feature = "trace")] name: None, + #[cfg(feature = "trace")] + id: 0, }, future: UninitCell::uninit(), } diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 40202299f..7f907346d 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -174,6 +174,7 @@ impl Spawner { task.set_name(Some(name)); let task_id = task.as_ptr() as u32; TASK_REGISTRY.register(task_id); + task.set_id(task_id); unsafe { self.executor.spawn(task) }; Ok(()) -- cgit From 6085916714b79a888e117a2d7223e78c9a5de9d3 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 11:47:04 -0400 Subject: use an intrusive linked list in TaskHeader to track tasks --- embassy-executor/src/raw/mod.rs | 76 ++++++++++++++- embassy-executor/src/raw/trace.rs | 190 ++++++++++++++++++-------------------- embassy-executor/src/spawner.rs | 3 - 3 files changed, 163 insertions(+), 106 deletions(-) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 075d8a254..b4adfe01b 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -93,6 +93,78 @@ pub(crate) struct TaskHeader { pub(crate) name: Option<&'static str>, #[cfg(feature = "trace")] pub(crate) id: u32, + #[cfg(feature = "trace")] + all_tasks_next: AtomicPtr, +} + +/// A thread-safe tracker for all tasks in the system +/// +/// This struct uses an intrusive linked list approach to track all tasks +/// without additional memory allocations. It maintains a global list of +/// tasks that can be traversed to find all currently existing tasks. +#[cfg(feature = "trace")] +pub struct TaskTracker { + head: AtomicPtr, +} + +#[cfg(feature = "trace")] +impl TaskTracker { + /// Creates a new empty task tracker + /// + /// Initializes a tracker with no tasks in its list. + pub const fn new() -> Self { + Self { + head: AtomicPtr::new(core::ptr::null_mut()), + } + } + + /// Adds a task to the tracker + /// + /// This method inserts a task at the head of the intrusive linked list. + /// The operation is thread-safe and lock-free, using atomic operations + /// to ensure consistency even when called from different contexts. + /// + /// # Arguments + /// * `task` - The task reference to add to the tracker + pub fn add(&self, task: TaskRef) { + let task_ptr = task.as_ptr() as *mut TaskHeader; + + loop { + let current_head = self.head.load(Ordering::Acquire); + unsafe { + (*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed); + } + + if self + .head + .compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed) + .is_ok() + { + break; + } + } + } + + /// Performs an operation on each task in the tracker + /// + /// This method traverses the entire list of tasks and calls the provided + /// function for each task. This allows inspecting or processing all tasks + /// in the system without modifying the tracker's structure. + /// + /// # Arguments + /// * `f` - A function to call for each task in the tracker + pub fn for_each(&self, mut f: F) + where + F: FnMut(TaskRef), + { + let mut current = self.head.load(Ordering::Acquire); + while !current.is_null() { + let task = unsafe { TaskRef::from_ptr(current) }; + f(task); + + current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) }; + } + } } /// This is essentially a `&'static TaskStorage` where the type of the future has been erased. @@ -173,7 +245,7 @@ impl TaskRef { #[cfg(feature = "trace")] pub fn id(&self) -> u32 { self.header().id - } + } /// Set the ID for a task #[cfg(feature = "trace")] @@ -228,6 +300,8 @@ impl TaskStorage { name: None, #[cfg(feature = "trace")] id: 0, + #[cfg(feature = "trace")] + all_tasks_next: AtomicPtr::new(core::ptr::null_mut()), }, future: UninitCell::uninit(), } diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 28be79cee..81c8a0024 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -81,107 +81,19 @@ #![allow(unused)] -use crate::raw::{SyncExecutor, TaskHeader, TaskRef}; +use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker}; use core::cell::UnsafeCell; use core::sync::atomic::{AtomicUsize, Ordering}; use rtos_trace::TaskInfo; -const MAX_TASKS: usize = 1000; - -/// Represents a task being tracked in the task registry. -/// -/// Contains the task's unique identifier and optional name. -#[derive(Clone)] -pub struct TrackedTask { - task_id: u32, -} - -/// A thread-safe registry for tracking tasks in the system. -/// -/// This registry maintains a list of active tasks with their IDs and optional names. -/// It supports registering, unregistering, and querying information about tasks. -/// The registry has a fixed capacity of `MAX_TASKS`. -pub struct TaskRegistry { - tasks: [UnsafeCell>; MAX_TASKS], - count: AtomicUsize, -} - -impl TaskRegistry { - /// Creates a new empty task registry. - /// - /// This initializes a registry that can track up to `MAX_TASKS` tasks. - pub const fn new() -> Self { - const EMPTY: UnsafeCell> = UnsafeCell::new(None); - Self { - tasks: [EMPTY; MAX_TASKS], - count: AtomicUsize::new(0), - } - } - - /// Registers a new task in the registry. - /// - /// # Arguments - /// * `task_id` - Unique identifier for the task - /// * `name` - Optional name for the task - /// - /// # Note - /// If the registry is full, the task will not be registered. - pub fn register(&self, task_id: u32) { - let count = self.count.load(Ordering::Relaxed); - if count < MAX_TASKS { - for i in 0..MAX_TASKS { - unsafe { - let slot = &self.tasks[i]; - let slot_ref = &mut *slot.get(); - if slot_ref.is_none() { - *slot_ref = Some(TrackedTask { task_id }); - self.count.fetch_add(1, Ordering::Relaxed); - break; - } - } - } - } - } - - /// Removes a task from the registry. - /// - /// # Arguments - /// * `task_id` - Unique identifier of the task to remove - pub fn unregister(&self, task_id: u32) { - for i in 0..MAX_TASKS { - unsafe { - let slot = &self.tasks[i]; - let slot_ref = &mut *slot.get(); - if let Some(task) = slot_ref { - if task.task_id == task_id { - *slot_ref = None; - self.count.fetch_sub(1, Ordering::Relaxed); - break; - } - } - } - } - } - - /// Returns an iterator over all registered tasks. - /// - /// This allows accessing information about all tasks currently in the registry. - pub fn get_all_tasks(&self) -> impl Iterator + '_ { - (0..MAX_TASKS).filter_map(move |i| unsafe { - let slot = &self.tasks[i]; - (*slot.get()).clone() - }) - } -} - -unsafe impl Sync for TaskRegistry {} -unsafe impl Send for TaskRegistry {} - -/// Global task registry instance used for tracking all tasks in the system. +/// Global task tracker instance /// -/// This provides a centralized registry accessible from anywhere in the application. -pub static TASK_REGISTRY: TaskRegistry = TaskRegistry::new(); +/// This static provides access to the global task tracker which maintains +/// a list of all tasks in the system. It's automatically updated by the +/// task lifecycle hooks in the trace module. +#[cfg(feature = "trace")] +pub static TASK_TRACKER: TaskTracker = TaskTracker::new(); #[cfg(not(feature = "rtos-trace"))] extern "Rust" { @@ -262,6 +174,9 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { #[cfg(feature = "rtos-trace")] rtos_trace::trace::task_new(task.as_ptr() as u32); + + #[cfg(feature = "rtos-trace")] + TASK_TRACKER.add(*task); } #[inline] @@ -272,8 +187,6 @@ pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) { unsafe { _embassy_trace_task_end(executor as u32, task.as_ptr() as u32) } - - TASK_REGISTRY.unregister(task_id); } #[inline] @@ -316,20 +229,93 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) { rtos_trace::trace::system_idle(); } +/// Returns an iterator over all active tasks in the system +/// +/// This function provides a convenient way to iterate over all tasks +/// that are currently tracked in the system. The returned iterator +/// yields each task in the global task tracker. +/// +/// # Returns +/// An iterator that yields `TaskRef` items for each task +#[cfg(feature = "trace")] +pub fn get_all_active_tasks() -> impl Iterator + 'static { + struct TaskIterator<'a> { + tracker: &'a TaskTracker, + current: *mut TaskHeader, + } + + impl<'a> Iterator for TaskIterator<'a> { + type Item = TaskRef; + + fn next(&mut self) -> Option { + if self.current.is_null() { + return None; + } + + let task = unsafe { TaskRef::from_ptr(self.current) }; + self.current = unsafe { (*self.current).all_tasks_next.load(Ordering::Acquire) }; + + Some(task) + } + } + + TaskIterator { + tracker: &TASK_TRACKER, + current: TASK_TRACKER.head.load(Ordering::Acquire), + } +} + +/// Get all active tasks, filtered by a predicate function +#[cfg(feature = "trace")] +pub fn filter_active_tasks(predicate: F) -> impl Iterator + 'static +where + F: Fn(&TaskRef) -> bool + 'static, +{ + get_all_active_tasks().filter(move |task| predicate(task)) +} + +/// Count the number of active tasks +#[cfg(feature = "trace")] +pub fn count_active_tasks() -> usize { + let mut count = 0; + TASK_TRACKER.for_each(|_| count += 1); + count +} + +/// Perform an action on each active task +#[cfg(feature = "trace")] +pub fn with_all_active_tasks(f: F) +where + F: FnMut(TaskRef), +{ + TASK_TRACKER.for_each(f); +} + +/// Get tasks by name +#[cfg(feature = "trace")] +pub fn get_tasks_by_name(name: &'static str) -> impl Iterator + 'static { + filter_active_tasks(move |task| task.name() == Some(name)) +} + +/// Get tasks by ID +#[cfg(feature = "trace")] +pub fn get_task_by_id(id: u32) -> Option { + filter_active_tasks(move |task| task.id() == id).next() +} + #[cfg(feature = "rtos-trace")] impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { fn task_list() { - for task in TASK_REGISTRY.get_all_tasks() { - let task_ref = unsafe { TaskRef::from_ptr(task.task_id as *const TaskHeader) }; - let name = task_ref.name().unwrap_or("unnamed\0"); + with_all_active_tasks(|task| { + let name = task.name().unwrap_or("unnamed task\0"); let info = rtos_trace::TaskInfo { name, priority: 0, stack_base: 0, stack_size: 0, }; - rtos_trace::trace::task_send_info(task.task_id, info); - } + rtos_trace::trace::task_send_info(task.as_id(), info); + }); } fn time() -> u64 { const fn gcd(a: u64, b: u64) -> u64 { diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 7f907346d..5e42f01bf 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -5,8 +5,6 @@ use core::sync::atomic::Ordering; use core::task::Poll; use super::raw; -#[cfg(feature = "rtos-trace")] -use super::raw::trace::TASK_REGISTRY; /// Token to spawn a newly-created task in an executor. /// @@ -173,7 +171,6 @@ impl Spawner { Some(task) => { task.set_name(Some(name)); let task_id = task.as_ptr() as u32; - TASK_REGISTRY.register(task_id); task.set_id(task_id); unsafe { self.executor.spawn(task) }; -- cgit From f2429c212e77969bacfe726cd293bf0ab5903664 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Tue, 6 May 2025 11:54:45 -0400 Subject: fix whitespace in the imports in trace.rs --- embassy-executor/src/raw/trace.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 81c8a0024..c0599d2c7 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -81,12 +81,13 @@ #![allow(unused)] -use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker}; - use core::cell::UnsafeCell; use core::sync::atomic::{AtomicUsize, Ordering}; + use rtos_trace::TaskInfo; +use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker}; + /// Global task tracker instance /// /// This static provides access to the global task tracker which maintains -- cgit From b3e13cc6de744a241521cff20725706a1e40ef25 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 10:58:07 -0400 Subject: make tracing API functions internal --- embassy-executor/src/raw/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index c0599d2c7..503d806bd 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -239,7 +239,7 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) { /// # Returns /// An iterator that yields `TaskRef` items for each task #[cfg(feature = "trace")] -pub fn get_all_active_tasks() -> impl Iterator + 'static { +fn get_all_active_tasks() -> impl Iterator + 'static { struct TaskIterator<'a> { tracker: &'a TaskTracker, current: *mut TaskHeader, @@ -285,7 +285,7 @@ pub fn count_active_tasks() -> usize { /// Perform an action on each active task #[cfg(feature = "trace")] -pub fn with_all_active_tasks(f: F) +fn with_all_active_tasks(f: F) where F: FnMut(TaskRef), { -- cgit From 8f18810ec61ce235a4c895413936e0216ed22c4f Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 10:58:27 -0400 Subject: remove unused tracing API --- embassy-executor/src/raw/trace.rs | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 503d806bd..fec3a4834 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -266,23 +266,6 @@ fn get_all_active_tasks() -> impl Iterator + 'static { } } -/// Get all active tasks, filtered by a predicate function -#[cfg(feature = "trace")] -pub fn filter_active_tasks(predicate: F) -> impl Iterator + 'static -where - F: Fn(&TaskRef) -> bool + 'static, -{ - get_all_active_tasks().filter(move |task| predicate(task)) -} - -/// Count the number of active tasks -#[cfg(feature = "trace")] -pub fn count_active_tasks() -> usize { - let mut count = 0; - TASK_TRACKER.for_each(|_| count += 1); - count -} - /// Perform an action on each active task #[cfg(feature = "trace")] fn with_all_active_tasks(f: F) @@ -292,18 +275,6 @@ where TASK_TRACKER.for_each(f); } -/// Get tasks by name -#[cfg(feature = "trace")] -pub fn get_tasks_by_name(name: &'static str) -> impl Iterator + 'static { - filter_active_tasks(move |task| task.name() == Some(name)) -} - -/// Get tasks by ID -#[cfg(feature = "trace")] -pub fn get_task_by_id(id: u32) -> Option { - filter_active_tasks(move |task| task.id() == id).next() -} - #[cfg(feature = "rtos-trace")] impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { fn task_list() { -- cgit From 56b5e35c60743d65aacee753d1db391c3cbeae16 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 10:58:59 -0400 Subject: change rtos-trace feature flag on tracing API to trace feature flag --- embassy-executor/src/spawner.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 5e42f01bf..a0d246616 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -162,7 +162,7 @@ impl Spawner { /// /// # Returns /// Result indicating whether the spawn was successful - #[cfg(feature = "rtos-trace")] + #[cfg(feature = "trace")] pub fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { let task = token.raw_task; mem::forget(token); @@ -182,7 +182,7 @@ impl Spawner { /// When rtos-trace is disabled, spawn_named falls back to regular spawn. /// This maintains API compatibility while optimizing out the name parameter. - #[cfg(not(feature = "rtos-trace"))] + #[cfg(not(feature = "trace"))] pub fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { self.spawn(token) } -- cgit From 8a8deb704fdd58cecf463f033cd3c3d1cc3534c7 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 11:20:22 -0400 Subject: move spawn_named into trace.rs through TraceExt trait --- embassy-executor/src/raw/trace.rs | 43 +++++++++++++++++++++++++++++++++++++++ embassy-executor/src/spawner.rs | 37 ++------------------------------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index fec3a4834..eb960f721 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -87,6 +87,49 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use rtos_trace::TaskInfo; use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker}; +use crate::spawner::{SpawnError, SpawnToken, Spawner}; + +/// Extension trait adding tracing capabilities to the Spawner +pub trait TraceExt { + /// Spawns a new task with a specified name. + /// + /// # Arguments + /// * `name` - Static string name to associate with the task + /// * `token` - Token representing the task to spawn + /// + /// # Returns + /// Result indicating whether the spawn was successful + fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError>; +} + +#[cfg(feature = "trace")] +impl TraceExt for Spawner { + fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + let task = token.raw_task; + core::mem::forget(token); + + match task { + Some(task) => { + task.set_name(Some(name)); + let task_id = task.as_ptr() as u32; + task.set_id(task_id); + + unsafe { self.executor.spawn(task) }; + Ok(()) + } + None => Err(SpawnError::Busy), + } + } +} + +/// When trace is disabled, spawn_named falls back to regular spawn. +/// This maintains API compatibility while optimizing out the name parameter. +#[cfg(not(feature = "trace"))] +impl TraceExt for Spawner { + fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + self.spawn(token) + } +} /// Global task tracker instance /// diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index a0d246616..6b8db4f8f 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -22,7 +22,7 @@ use super::raw; /// Once you've invoked a task function and obtained a SpawnToken, you *must* spawn it. #[must_use = "Calling a task function does nothing on its own. You must spawn the returned SpawnToken, typically with Spawner::spawn()"] pub struct SpawnToken { - raw_task: Option, + pub(crate) raw_task: Option, phantom: PhantomData<*mut S>, } @@ -103,7 +103,7 @@ impl core::error::Error for SpawnError {} /// If you want to spawn tasks from another thread, use [SendSpawner]. #[derive(Copy, Clone)] pub struct Spawner { - executor: &'static raw::Executor, + pub(crate) executor: &'static raw::Executor, not_send: PhantomData<*mut ()>, } @@ -154,39 +154,6 @@ impl Spawner { } } - /// Spawns a new task with a specified name. - /// - /// # Arguments - /// * `name` - Static string name to associate with the task - /// * `token` - Token representing the task to spawn - /// - /// # Returns - /// Result indicating whether the spawn was successful - #[cfg(feature = "trace")] - pub fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { - let task = token.raw_task; - mem::forget(token); - - match task { - Some(task) => { - task.set_name(Some(name)); - let task_id = task.as_ptr() as u32; - task.set_id(task_id); - - unsafe { self.executor.spawn(task) }; - Ok(()) - } - None => Err(SpawnError::Busy), - } - } - - /// When rtos-trace is disabled, spawn_named falls back to regular spawn. - /// This maintains API compatibility while optimizing out the name parameter. - #[cfg(not(feature = "trace"))] - pub fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { - self.spawn(token) - } - // Used by the `embassy_executor_macros::main!` macro to throw an error when spawn // fails. This is here to allow conditional use of `defmt::unwrap!` // without introducing a `defmt` feature in the `embassy_executor_macros` package, -- cgit From 462d04c6d5a0fc6072cf9bdb0faa60da74ff46d2 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 13:34:32 -0400 Subject: move TaskTracker to trace --- embassy-executor/src/raw/mod.rs | 70 ------------------------------------ embassy-executor/src/raw/trace.rs | 74 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index b4adfe01b..882e4605b 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -97,76 +97,6 @@ pub(crate) struct TaskHeader { all_tasks_next: AtomicPtr, } -/// A thread-safe tracker for all tasks in the system -/// -/// This struct uses an intrusive linked list approach to track all tasks -/// without additional memory allocations. It maintains a global list of -/// tasks that can be traversed to find all currently existing tasks. -#[cfg(feature = "trace")] -pub struct TaskTracker { - head: AtomicPtr, -} - -#[cfg(feature = "trace")] -impl TaskTracker { - /// Creates a new empty task tracker - /// - /// Initializes a tracker with no tasks in its list. - pub const fn new() -> Self { - Self { - head: AtomicPtr::new(core::ptr::null_mut()), - } - } - - /// Adds a task to the tracker - /// - /// This method inserts a task at the head of the intrusive linked list. - /// The operation is thread-safe and lock-free, using atomic operations - /// to ensure consistency even when called from different contexts. - /// - /// # Arguments - /// * `task` - The task reference to add to the tracker - pub fn add(&self, task: TaskRef) { - let task_ptr = task.as_ptr() as *mut TaskHeader; - - loop { - let current_head = self.head.load(Ordering::Acquire); - unsafe { - (*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed); - } - - if self - .head - .compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed) - .is_ok() - { - break; - } - } - } - - /// Performs an operation on each task in the tracker - /// - /// This method traverses the entire list of tasks and calls the provided - /// function for each task. This allows inspecting or processing all tasks - /// in the system without modifying the tracker's structure. - /// - /// # Arguments - /// * `f` - A function to call for each task in the tracker - pub fn for_each(&self, mut f: F) - where - F: FnMut(TaskRef), - { - let mut current = self.head.load(Ordering::Acquire); - while !current.is_null() { - let task = unsafe { TaskRef::from_ptr(current) }; - f(task); - - current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) }; - } - } -} - /// This is essentially a `&'static TaskStorage` where the type of the future has been erased. #[derive(Clone, Copy, PartialEq)] pub struct TaskRef { diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index eb960f721..b59da0526 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -82,11 +82,11 @@ #![allow(unused)] use core::cell::UnsafeCell; -use core::sync::atomic::{AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use rtos_trace::TaskInfo; -use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker}; +use crate::raw::{SyncExecutor, TaskHeader, TaskRef}; use crate::spawner::{SpawnError, SpawnToken, Spawner}; /// Extension trait adding tracing capabilities to the Spawner @@ -139,6 +139,76 @@ impl TraceExt for Spawner { #[cfg(feature = "trace")] pub static TASK_TRACKER: TaskTracker = TaskTracker::new(); +/// A thread-safe tracker for all tasks in the system +/// +/// This struct uses an intrusive linked list approach to track all tasks +/// without additional memory allocations. It maintains a global list of +/// tasks that can be traversed to find all currently existing tasks. +#[cfg(feature = "trace")] +pub struct TaskTracker { + head: AtomicPtr, +} + +#[cfg(feature = "trace")] +impl TaskTracker { + /// Creates a new empty task tracker + /// + /// Initializes a tracker with no tasks in its list. + pub const fn new() -> Self { + Self { + head: AtomicPtr::new(core::ptr::null_mut()), + } + } + + /// Adds a task to the tracker + /// + /// This method inserts a task at the head of the intrusive linked list. + /// The operation is thread-safe and lock-free, using atomic operations + /// to ensure consistency even when called from different contexts. + /// + /// # Arguments + /// * `task` - The task reference to add to the tracker + pub fn add(&self, task: TaskRef) { + let task_ptr = task.as_ptr() as *mut TaskHeader; + + loop { + let current_head = self.head.load(Ordering::Acquire); + unsafe { + (*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed); + } + + if self + .head + .compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed) + .is_ok() + { + break; + } + } + } + + /// Performs an operation on each task in the tracker + /// + /// This method traverses the entire list of tasks and calls the provided + /// function for each task. This allows inspecting or processing all tasks + /// in the system without modifying the tracker's structure. + /// + /// # Arguments + /// * `f` - A function to call for each task in the tracker + pub fn for_each(&self, mut f: F) + where + F: FnMut(TaskRef), + { + let mut current = self.head.load(Ordering::Acquire); + while !current.is_null() { + let task = unsafe { TaskRef::from_ptr(current) }; + f(task); + + current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) }; + } + } +} + #[cfg(not(feature = "rtos-trace"))] extern "Rust" { /// This callback is called when the executor begins polling. This will always -- cgit From 3b873bb6bb51b9bdac9272b5ec629a6ac54a89f7 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 13:40:32 -0400 Subject: implement TaskRefTrace for tracing-only fields in TaskRef --- embassy-executor/src/raw/mod.rs | 36 --------------------------- embassy-executor/src/raw/trace.rs | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 36 deletions(-) diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 882e4605b..e7a27035a 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -149,42 +149,6 @@ impl TaskRef { pub(crate) fn as_ptr(self) -> *const TaskHeader { self.ptr.as_ptr() } - - /// Get the ID for a task - #[cfg(feature = "trace")] - pub fn as_id(self) -> u32 { - self.ptr.as_ptr() as u32 - } - - /// Get the name for a task - #[cfg(feature = "trace")] - pub fn name(&self) -> Option<&'static str> { - self.header().name - } - - /// Set the name for a task - #[cfg(feature = "trace")] - pub fn set_name(&self, name: Option<&'static str>) { - unsafe { - let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; - (*header_ptr).name = name; - } - } - - /// Get the ID for a task - #[cfg(feature = "trace")] - pub fn id(&self) -> u32 { - self.header().id - } - - /// Set the ID for a task - #[cfg(feature = "trace")] - pub fn set_id(&self, id: u32) { - unsafe { - let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; - (*header_ptr).id = id; - } - } } /// Raw storage in which a task can be spawned. diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index b59da0526..b30f23468 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -209,6 +209,58 @@ impl TaskTracker { } } +/// Extension trait for `TaskRef` that provides tracing functionality. +/// +/// This trait is only available when the `trace` feature is enabled. +/// It extends `TaskRef` with methods for accessing and modifying task identifiers +/// and names, which are useful for debugging, logging, and performance analysis. +#[cfg(feature = "trace")] +pub trait TaskRefTrace { + /// Get the ID for a task + fn as_id(self) -> u32; + + /// Get the name for a task + fn name(&self) -> Option<&'static str>; + + /// Set the name for a task + fn set_name(&self, name: Option<&'static str>); + + /// Get the ID for a task + fn id(&self) -> u32; + + /// Set the ID for a task + fn set_id(&self, id: u32); +} + +#[cfg(feature = "trace")] +impl TaskRefTrace for TaskRef { + fn as_id(self) -> u32 { + self.ptr.as_ptr() as u32 + } + + fn name(&self) -> Option<&'static str> { + self.header().name + } + + fn set_name(&self, name: Option<&'static str>) { + unsafe { + let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; + (*header_ptr).name = name; + } + } + + fn id(&self) -> u32 { + self.header().id + } + + fn set_id(&self, id: u32) { + unsafe { + let header_ptr = self.ptr.as_ptr() as *mut TaskHeader; + (*header_ptr).id = id; + } + } +} + #[cfg(not(feature = "rtos-trace"))] extern "Rust" { /// This callback is called when the executor begins polling. This will always -- cgit From 194a3044acb5cd9691ced78596b9fd81e6884667 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 13:41:23 -0400 Subject: remove unused task_id --- embassy-executor/src/raw/trace.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index b30f23468..04e9d234f 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -216,9 +216,6 @@ impl TaskTracker { /// and names, which are useful for debugging, logging, and performance analysis. #[cfg(feature = "trace")] pub trait TaskRefTrace { - /// Get the ID for a task - fn as_id(self) -> u32; - /// Get the name for a task fn name(&self) -> Option<&'static str>; @@ -234,10 +231,6 @@ pub trait TaskRefTrace { #[cfg(feature = "trace")] impl TaskRefTrace for TaskRef { - fn as_id(self) -> u32 { - self.ptr.as_ptr() as u32 - } - fn name(&self) -> Option<&'static str> { self.header().name } @@ -331,8 +324,6 @@ pub(crate) fn poll_start(executor: &SyncExecutor) { #[inline] pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { - let task_id = task.as_ptr() as u32; - #[cfg(not(feature = "rtos-trace"))] unsafe { _embassy_trace_task_new(executor as *const _ as u32, task.as_ptr() as u32) @@ -347,8 +338,6 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { #[inline] pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) { - let task_id = task.as_ptr() as u32; - #[cfg(not(feature = "rtos-trace"))] unsafe { _embassy_trace_task_end(executor as u32, task.as_ptr() as u32) @@ -451,7 +440,7 @@ impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { stack_base: 0, stack_size: 0, }; - rtos_trace::trace::task_send_info(task.as_id(), info); + rtos_trace::trace::task_send_info(task.id(), info); }); } fn time() -> u64 { -- cgit From e968c4763694d676cca6f1bd30949619dd12e962 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 14:03:03 -0400 Subject: update TraceExt trait name for Spawner --- embassy-executor/src/raw/trace.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 04e9d234f..f55033530 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -90,7 +90,7 @@ use crate::raw::{SyncExecutor, TaskHeader, TaskRef}; use crate::spawner::{SpawnError, SpawnToken, Spawner}; /// Extension trait adding tracing capabilities to the Spawner -pub trait TraceExt { +pub trait SpawnerTraceExt { /// Spawns a new task with a specified name. /// /// # Arguments @@ -103,7 +103,7 @@ pub trait TraceExt { } #[cfg(feature = "trace")] -impl TraceExt for Spawner { +impl SpawnerTraceExt for Spawner { fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { let task = token.raw_task; core::mem::forget(token); @@ -125,7 +125,7 @@ impl TraceExt for Spawner { /// When trace is disabled, spawn_named falls back to regular spawn. /// This maintains API compatibility while optimizing out the name parameter. #[cfg(not(feature = "trace"))] -impl TraceExt for Spawner { +impl SpawnerTraceExt for Spawner { fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { self.spawn(token) } -- cgit From dfaab013ebaaa4a19c06f2eb00821712ff13cf7a Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 14:35:43 -0400 Subject: move SpawnerTraceExt back into Spawner --- embassy-executor/src/raw/trace.rs | 42 -------------------------------- embassy-executor/src/spawner.rs | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index f55033530..593f7b0ba 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -89,48 +89,6 @@ use rtos_trace::TaskInfo; use crate::raw::{SyncExecutor, TaskHeader, TaskRef}; use crate::spawner::{SpawnError, SpawnToken, Spawner}; -/// Extension trait adding tracing capabilities to the Spawner -pub trait SpawnerTraceExt { - /// Spawns a new task with a specified name. - /// - /// # Arguments - /// * `name` - Static string name to associate with the task - /// * `token` - Token representing the task to spawn - /// - /// # Returns - /// Result indicating whether the spawn was successful - fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError>; -} - -#[cfg(feature = "trace")] -impl SpawnerTraceExt for Spawner { - fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { - let task = token.raw_task; - core::mem::forget(token); - - match task { - Some(task) => { - task.set_name(Some(name)); - let task_id = task.as_ptr() as u32; - task.set_id(task_id); - - unsafe { self.executor.spawn(task) }; - Ok(()) - } - None => Err(SpawnError::Busy), - } - } -} - -/// When trace is disabled, spawn_named falls back to regular spawn. -/// This maintains API compatibility while optimizing out the name parameter. -#[cfg(not(feature = "trace"))] -impl SpawnerTraceExt for Spawner { - fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { - self.spawn(token) - } -} - /// Global task tracker instance /// /// This static provides access to the global task tracker which maintains diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index 6b8db4f8f..bfb32ebcc 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -6,6 +6,9 @@ use core::task::Poll; use super::raw; +#[cfg(feature = "trace")] +use crate::raw::trace::TaskRefTrace; + /// Token to spawn a newly-created task in an executor. /// /// When calling a task function (like `#[embassy_executor::task] async fn my_task() { ... }`), the returned @@ -180,6 +183,53 @@ impl Spawner { } } +/// Extension trait adding tracing capabilities to the Spawner +/// +/// This trait provides an additional method to spawn tasks with an associated name, +/// which can be useful for debugging and tracing purposes. +pub trait SpawnerTraceExt { + /// Spawns a new task with a specified name. + /// + /// # Arguments + /// * `name` - Static string name to associate with the task + /// * `token` - Token representing the task to spawn + /// + /// # Returns + /// Result indicating whether the spawn was successful + fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError>; +} + +/// Implementation of the SpawnerTraceExt trait for Spawner when trace is enabled +#[cfg(feature = "trace")] +impl SpawnerTraceExt for Spawner { + fn spawn_named(&self, name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + let task = token.raw_task; + core::mem::forget(token); + + match task { + Some(task) => { + // Set the name and ID when trace is enabled + task.set_name(Some(name)); + let task_id = task.as_ptr() as u32; + task.set_id(task_id); + + unsafe { self.executor.spawn(task) }; + Ok(()) + } + None => Err(SpawnError::Busy), + } + } +} + +/// Implementation of the SpawnerTraceExt trait for Spawner when trace is disabled +#[cfg(not(feature = "trace"))] +impl SpawnerTraceExt for Spawner { + fn spawn_named(&self, _name: &'static str, token: SpawnToken) -> Result<(), SpawnError> { + // When trace is disabled, just forward to regular spawn and ignore the name + self.spawn(token) + } +} + /// Handle to spawn tasks into an executor from any thread. /// /// This Spawner can be used from any thread (it is Send), but it can -- cgit From 3ffa2e4f3f9ecbca8637ae1603194a63d55b4396 Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 16:30:06 -0400 Subject: remove unnecessary trace flags --- embassy-executor/src/raw/trace.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 593f7b0ba..6c9cfda25 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs @@ -94,7 +94,6 @@ use crate::spawner::{SpawnError, SpawnToken, Spawner}; /// This static provides access to the global task tracker which maintains /// a list of all tasks in the system. It's automatically updated by the /// task lifecycle hooks in the trace module. -#[cfg(feature = "trace")] pub static TASK_TRACKER: TaskTracker = TaskTracker::new(); /// A thread-safe tracker for all tasks in the system @@ -102,12 +101,10 @@ pub static TASK_TRACKER: TaskTracker = TaskTracker::new(); /// This struct uses an intrusive linked list approach to track all tasks /// without additional memory allocations. It maintains a global list of /// tasks that can be traversed to find all currently existing tasks. -#[cfg(feature = "trace")] pub struct TaskTracker { head: AtomicPtr, } -#[cfg(feature = "trace")] impl TaskTracker { /// Creates a new empty task tracker /// @@ -172,7 +169,6 @@ impl TaskTracker { /// This trait is only available when the `trace` feature is enabled. /// It extends `TaskRef` with methods for accessing and modifying task identifiers /// and names, which are useful for debugging, logging, and performance analysis. -#[cfg(feature = "trace")] pub trait TaskRefTrace { /// Get the name for a task fn name(&self) -> Option<&'static str>; @@ -187,7 +183,6 @@ pub trait TaskRefTrace { fn set_id(&self, id: u32); } -#[cfg(feature = "trace")] impl TaskRefTrace for TaskRef { fn name(&self) -> Option<&'static str> { self.header().name @@ -350,7 +345,6 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) { /// /// # Returns /// An iterator that yields `TaskRef` items for each task -#[cfg(feature = "trace")] fn get_all_active_tasks() -> impl Iterator + 'static { struct TaskIterator<'a> { tracker: &'a TaskTracker, @@ -379,7 +373,6 @@ fn get_all_active_tasks() -> impl Iterator + 'static { } /// Perform an action on each active task -#[cfg(feature = "trace")] fn with_all_active_tasks(f: F) where F: FnMut(TaskRef), -- cgit From ebb6132f5f9c55ad4ced2602134f8e2c69135c1e Mon Sep 17 00:00:00 2001 From: Kat Perez Date: Thu, 8 May 2025 16:31:47 -0400 Subject: rustfmt --- embassy-executor/src/spawner.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs index bfb32ebcc..522d97db3 100644 --- a/embassy-executor/src/spawner.rs +++ b/embassy-executor/src/spawner.rs @@ -5,7 +5,6 @@ use core::sync::atomic::Ordering; use core::task::Poll; use super::raw; - #[cfg(feature = "trace")] use crate::raw::trace::TaskRefTrace; -- cgit From d4c378e059443dbaaaece02a0f5148db62bd4484 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Apr 2025 14:28:59 -0700 Subject: Add embassy-imxrt CRC driver --- docs/pages/imxrt.adoc | 2 +- embassy-imxrt/src/crc.rs | 190 ++++++++++++++++++++++++++++++++++++++++ embassy-imxrt/src/lib.rs | 1 + examples/mimxrt6/src/bin/crc.rs | 175 ++++++++++++++++++++++++++++++++++++ 4 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 embassy-imxrt/src/crc.rs create mode 100644 examples/mimxrt6/src/bin/crc.rs diff --git a/docs/pages/imxrt.adoc b/docs/pages/imxrt.adoc index adf5218e8..a84fbae03 100644 --- a/docs/pages/imxrt.adoc +++ b/docs/pages/imxrt.adoc @@ -9,5 +9,5 @@ The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Emb The following peripherals have a HAL implementation at present +* CRC * GPIO - diff --git a/embassy-imxrt/src/crc.rs b/embassy-imxrt/src/crc.rs new file mode 100644 index 000000000..24d6ba5bd --- /dev/null +++ b/embassy-imxrt/src/crc.rs @@ -0,0 +1,190 @@ +//! Cyclic Redundancy Check (CRC) + +use core::marker::PhantomData; + +use crate::clocks::{enable_and_reset, SysconPeripheral}; +pub use crate::pac::crc_engine::mode::CrcPolynomial as Polynomial; +use crate::{peripherals, Peri, PeripheralType}; + +/// CRC driver. +pub struct Crc<'d> { + info: Info, + _config: Config, + _lifetime: PhantomData<&'d ()>, +} + +/// CRC configuration +pub struct Config { + /// Polynomial to be used + pub polynomial: Polynomial, + + /// Reverse bit order of input? + pub reverse_in: bool, + + /// 1's complement input? + pub complement_in: bool, + + /// Reverse CRC bit order? + pub reverse_out: bool, + + /// 1's complement CRC? + pub complement_out: bool, + + /// CRC Seed + pub seed: u32, +} + +impl Config { + /// Create a new CRC config. + #[must_use] + pub fn new( + polynomial: Polynomial, + reverse_in: bool, + complement_in: bool, + reverse_out: bool, + complement_out: bool, + seed: u32, + ) -> Self { + Config { + polynomial, + reverse_in, + complement_in, + reverse_out, + complement_out, + seed, + } + } +} + +impl Default for Config { + fn default() -> Self { + Self { + polynomial: Polynomial::CrcCcitt, + reverse_in: false, + complement_in: false, + reverse_out: false, + complement_out: false, + seed: 0xffff, + } + } +} + +impl<'d> Crc<'d> { + /// Instantiates new CRC peripheral and initializes to default values. + pub fn new(_peripheral: Peri<'d, T>, config: Config) -> Self { + // enable CRC clock + enable_and_reset::(); + + let mut instance = Self { + info: T::info(), + _config: config, + _lifetime: PhantomData, + }; + + instance.reconfigure(); + instance + } + + /// Reconfigured the CRC peripheral. + fn reconfigure(&mut self) { + self.info.regs.mode().write(|w| { + w.crc_poly() + .variant(self._config.polynomial) + .bit_rvs_wr() + .variant(self._config.reverse_in) + .cmpl_wr() + .variant(self._config.complement_in) + .bit_rvs_sum() + .variant(self._config.reverse_out) + .cmpl_sum() + .variant(self._config.complement_out) + }); + + // Init CRC value + self.info + .regs + .seed() + .write(|w| unsafe { w.crc_seed().bits(self._config.seed) }); + } + + /// Feeds a byte into the CRC peripheral. Returns the computed checksum. + pub fn feed_byte(&mut self, byte: u8) -> u32 { + self.info.regs.wr_data8().write(|w| unsafe { w.bits(byte) }); + + self.info.regs.sum().read().bits() + } + + /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum. + pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 { + let (prefix, data, suffix) = unsafe { bytes.align_to::() }; + + for b in prefix { + self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) }); + } + + for d in data { + self.info.regs.wr_data32().write(|w| unsafe { w.bits(*d) }); + } + + for b in suffix { + self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) }); + } + + self.info.regs.sum().read().bits() + } + + /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. + pub fn feed_halfword(&mut self, halfword: u16) -> u32 { + self.info.regs.wr_data16().write(|w| unsafe { w.bits(halfword) }); + + self.info.regs.sum().read().bits() + } + + /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. + pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 { + for halfword in halfwords { + self.info.regs.wr_data16().write(|w| unsafe { w.bits(*halfword) }); + } + + self.info.regs.sum().read().bits() + } + + /// Feeds a words into the CRC peripheral. Returns the computed checksum. + pub fn feed_word(&mut self, word: u32) -> u32 { + self.info.regs.wr_data32().write(|w| unsafe { w.bits(word) }); + + self.info.regs.sum().read().bits() + } + + /// Feeds an slice of words into the CRC peripheral. Returns the computed checksum. + pub fn feed_words(&mut self, words: &[u32]) -> u32 { + for word in words { + self.info.regs.wr_data32().write(|w| unsafe { w.bits(*word) }); + } + + self.info.regs.sum().read().bits() + } +} + +struct Info { + regs: crate::pac::CrcEngine, +} + +trait SealedInstance { + fn info() -> Info; +} + +/// CRC instance trait. +#[allow(private_bounds)] +pub trait Instance: SealedInstance + PeripheralType + SysconPeripheral + 'static + Send {} + +impl Instance for peripherals::CRC {} + +impl SealedInstance for peripherals::CRC { + fn info() -> Info { + // SAFETY: safe from single executor + Info { + regs: unsafe { crate::pac::CrcEngine::steal() }, + } + } +} diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index ad9f81e88..d8ce97f76 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs @@ -18,6 +18,7 @@ compile_error!( pub(crate) mod fmt; pub mod clocks; +pub mod crc; pub mod gpio; pub mod iopctl; diff --git a/examples/mimxrt6/src/bin/crc.rs b/examples/mimxrt6/src/bin/crc.rs new file mode 100644 index 000000000..005a250e5 --- /dev/null +++ b/examples/mimxrt6/src/bin/crc.rs @@ -0,0 +1,175 @@ +#![no_std] +#![no_main] + +extern crate embassy_imxrt_examples; + +use defmt::*; +use embassy_executor::Spawner; +use embassy_imxrt::crc::{Config, Crc, Polynomial}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut p = embassy_imxrt::init(Default::default()); + let data = b"123456789"; + + info!("Initializing CRC"); + + // CRC-CCITT + let mut crc = Crc::new(p.CRC.reborrow(), Default::default()); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x29b1); + + // CRC16-ARC + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc16, + reverse_in: true, + reverse_out: true, + complement_out: false, + seed: 0, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0xbb3d); + + // CRC16-CMS + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc16, + reverse_in: false, + reverse_out: false, + complement_out: false, + seed: 0xffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0xaee7); + + // CRC16-DDS-110 + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc16, + reverse_in: false, + reverse_out: false, + complement_out: false, + seed: 0x800d, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x9ecf); + + // CRC16-MAXIM-DOW + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc16, + reverse_in: true, + reverse_out: true, + complement_out: true, + seed: 0, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x44c2); + + // CRC16-MODBUS + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc16, + reverse_in: true, + reverse_out: true, + complement_out: false, + seed: 0xffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x4b37); + + // CRC32-BZIP2 + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc32, + reverse_in: false, + reverse_out: false, + complement_out: true, + seed: 0xffff_ffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0xfc89_1918); + + // CRC32-CKSUM + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc32, + reverse_in: false, + reverse_out: false, + complement_out: true, + seed: 0, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x765e_7680); + + // CRC32-ISO-HDLC + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc32, + reverse_in: true, + reverse_out: true, + complement_out: true, + seed: 0xffff_ffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0xcbf4_3926); + + // CRC32-JAMCRC + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc32, + reverse_in: true, + reverse_out: true, + complement_out: false, + seed: 0xffff_ffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x340b_c6d9); + + // CRC32-MPEG-2 + let mut crc = Crc::new( + p.CRC.reborrow(), + Config { + polynomial: Polynomial::Crc32, + reverse_in: false, + reverse_out: false, + complement_out: false, + seed: 0xffff_ffff, + ..Default::default() + }, + ); + let output = crc.feed_bytes(data); + defmt::assert_eq!(output, 0x0376_e6e7); + + info!("end program"); + cortex_m::asm::bkpt(); +} -- cgit From 8e7e4332b40707e8d36338ad8ec486320bb3538f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Apr 2025 15:03:53 -0700 Subject: Add embassy-imxrt RNG driver --- docs/pages/imxrt.adoc | 2 +- embassy-imxrt/src/lib.rs | 1 + embassy-imxrt/src/rng.rs | 257 ++++++++++++++++++++++++++++++++++++++++ examples/mimxrt6/src/bin/rng.rs | 40 +++++++ 4 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 embassy-imxrt/src/rng.rs create mode 100644 examples/mimxrt6/src/bin/rng.rs diff --git a/docs/pages/imxrt.adoc b/docs/pages/imxrt.adoc index adf5218e8..9fcb6725c 100644 --- a/docs/pages/imxrt.adoc +++ b/docs/pages/imxrt.adoc @@ -10,4 +10,4 @@ The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Emb The following peripherals have a HAL implementation at present * GPIO - +* RNG diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index ad9f81e88..f728ba060 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs @@ -20,6 +20,7 @@ pub(crate) mod fmt; pub mod clocks; pub mod gpio; pub mod iopctl; +pub mod rng; #[cfg(feature = "_time-driver")] pub mod time_driver; diff --git a/embassy-imxrt/src/rng.rs b/embassy-imxrt/src/rng.rs new file mode 100644 index 000000000..67e7ab65d --- /dev/null +++ b/embassy-imxrt/src/rng.rs @@ -0,0 +1,257 @@ +//! True Random Number Generator (TRNG) + +use core::future::poll_fn; +use core::marker::PhantomData; +use core::task::Poll; + +use embassy_futures::block_on; +use embassy_sync::waitqueue::AtomicWaker; +use rand_core::{CryptoRng, RngCore}; + +use crate::clocks::{enable_and_reset, SysconPeripheral}; +use crate::interrupt::typelevel::Interrupt; +use crate::{interrupt, peripherals, Peri, PeripheralType}; + +static RNG_WAKER: AtomicWaker = AtomicWaker::new(); + +/// RNG ;error +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Error { + /// Seed error. + SeedError, + + /// HW Error. + HwError, + + /// Frequency Count Fail + FreqCountFail, +} + +/// RNG interrupt handler. +pub struct InterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::typelevel::Handler for InterruptHandler { + unsafe fn on_interrupt() { + let regs = T::info().regs; + let int_status = regs.int_status().read(); + + if int_status.ent_val().bit_is_set() + || int_status.hw_err().bit_is_set() + || int_status.frq_ct_fail().bit_is_set() + { + regs.int_ctrl().modify(|_, w| { + w.ent_val() + .ent_val_0() + .hw_err() + .hw_err_0() + .frq_ct_fail() + .frq_ct_fail_0() + }); + RNG_WAKER.wake(); + } + } +} + +/// RNG driver. +pub struct Rng<'d> { + info: Info, + _lifetime: PhantomData<&'d ()>, +} + +impl<'d> Rng<'d> { + /// Create a new RNG driver. + pub fn new( + _inner: Peri<'d, T>, + _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { + enable_and_reset::(); + + let mut random = Self { + info: T::info(), + _lifetime: PhantomData, + }; + random.init(); + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + random + } + + /// Reset the RNG. + pub fn reset(&mut self) { + self.info.regs.mctl().write(|w| w.rst_def().set_bit().prgm().set_bit()); + } + + /// Fill the given slice with random values. + pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + // We have a total of 16 words (512 bits) of entropy at our + // disposal. The idea here is to read all bits and copy the + // necessary bytes to the slice. + for chunk in dest.chunks_mut(64) { + self.async_fill_chunk(chunk).await?; + } + + Ok(()) + } + + async fn async_fill_chunk(&mut self, chunk: &mut [u8]) -> Result<(), Error> { + // wait for interrupt + let res = poll_fn(|cx| { + // Check if already ready. + // TODO: Is this necessary? Could we just check once after + // the waker has been registered? + if self.info.regs.int_status().read().ent_val().bit_is_set() { + return Poll::Ready(Ok(())); + } + + RNG_WAKER.register(cx.waker()); + + self.unmask_interrupts(); + + let mctl = self.info.regs.mctl().read(); + + // Check again if interrupt fired + if mctl.ent_val().bit_is_set() { + Poll::Ready(Ok(())) + } else if mctl.err().bit_is_set() { + Poll::Ready(Err(Error::HwError)) + } else if mctl.fct_fail().bit_is_set() { + Poll::Ready(Err(Error::FreqCountFail)) + } else { + Poll::Pending + } + }) + .await; + + let bits = self.info.regs.mctl().read(); + + if bits.ent_val().bit_is_set() { + let mut entropy = [0; 16]; + + for (i, item) in entropy.iter_mut().enumerate() { + *item = self.info.regs.ent(i).read().bits(); + } + + // Read MCTL after reading ENT15 + let _ = self.info.regs.mctl().read(); + + if entropy.iter().any(|e| *e == 0) { + return Err(Error::SeedError); + } + + // SAFETY: entropy is the same for input and output types in + // native endianness. + let entropy: [u8; 64] = unsafe { core::mem::transmute(entropy) }; + + // write bytes to chunk + chunk.copy_from_slice(&entropy[..chunk.len()]); + } + + res + } + + fn mask_interrupts(&mut self) { + self.info.regs.int_mask().write(|w| { + w.ent_val() + .ent_val_0() + .hw_err() + .hw_err_0() + .frq_ct_fail() + .frq_ct_fail_0() + }); + } + + fn unmask_interrupts(&mut self) { + self.info.regs.int_mask().modify(|_, w| { + w.ent_val() + .ent_val_1() + .hw_err() + .hw_err_1() + .frq_ct_fail() + .frq_ct_fail_1() + }); + } + + fn enable_interrupts(&mut self) { + self.info.regs.int_ctrl().write(|w| { + w.ent_val() + .ent_val_1() + .hw_err() + .hw_err_1() + .frq_ct_fail() + .frq_ct_fail_1() + }); + } + + fn init(&mut self) { + self.mask_interrupts(); + + // Switch TRNG to programming mode + self.info.regs.mctl().modify(|_, w| w.prgm().set_bit()); + + self.enable_interrupts(); + + // Switch TRNG to Run Mode + self.info + .regs + .mctl() + .modify(|_, w| w.trng_acc().set_bit().prgm().clear_bit()); + } +} + +impl RngCore for Rng<'_> { + fn next_u32(&mut self) -> u32 { + let mut bytes = [0u8; 4]; + block_on(self.async_fill_bytes(&mut bytes)).unwrap(); + u32::from_ne_bytes(bytes) + } + + fn next_u64(&mut self) -> u64 { + let mut bytes = [0u8; 8]; + block_on(self.async_fill_bytes(&mut bytes)).unwrap(); + u64::from_ne_bytes(bytes) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + block_on(self.async_fill_bytes(dest)).unwrap(); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + self.fill_bytes(dest); + Ok(()) + } +} + +impl CryptoRng for Rng<'_> {} + +struct Info { + regs: crate::pac::Trng, +} + +trait SealedInstance { + fn info() -> Info; +} + +/// RNG instance trait. +#[allow(private_bounds)] +pub trait Instance: SealedInstance + PeripheralType + SysconPeripheral + 'static + Send { + /// Interrupt for this RNG instance. + type Interrupt: interrupt::typelevel::Interrupt; +} + +impl Instance for peripherals::RNG { + type Interrupt = crate::interrupt::typelevel::RNG; +} + +impl SealedInstance for peripherals::RNG { + fn info() -> Info { + // SAFETY: safe from single executor + Info { + regs: unsafe { crate::pac::Trng::steal() }, + } + } +} diff --git a/examples/mimxrt6/src/bin/rng.rs b/examples/mimxrt6/src/bin/rng.rs new file mode 100644 index 000000000..5f64cb96a --- /dev/null +++ b/examples/mimxrt6/src/bin/rng.rs @@ -0,0 +1,40 @@ +#![no_std] +#![no_main] + +extern crate embassy_imxrt_examples; + +use defmt::*; +use embassy_executor::Spawner; +use embassy_imxrt::rng::Rng; +use embassy_imxrt::{bind_interrupts, peripherals, rng}; +use rand::RngCore; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("Initializing RNG"); + let mut rng = Rng::new(p.RNG, Irqs); + let mut buf = [0u8; 65]; + + // Async interface + unwrap!(rng.async_fill_bytes(&mut buf).await); + info!("random bytes: {:02x}", buf); + + // RngCore interface + let mut random_bytes = [0; 16]; + + let random_u32 = rng.next_u32(); + let random_u64 = rng.next_u64(); + + rng.fill_bytes(&mut random_bytes); + + info!("random_u32 {}", random_u32); + info!("random_u64 {}", random_u64); + info!("random_bytes {}", random_bytes); +} -- cgit From ee71dda6317ef8de66b09612a020416466aeb2d3 Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Sat, 10 May 2025 19:58:03 +1000 Subject: Clarify embassy-rp rt feature purpose --- embassy-rp/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index b440591cf..8fb8a50fd 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -26,7 +26,10 @@ features = ["defmt", "unstable-pac", "time-driver", "rp2040"] [features] default = [ "rt" ] -## Enable the rt feature of [`rp-pac`](https://docs.rs/rp-pac). This brings in the [`cortex-m-rt`](https://docs.rs/cortex-m-rt) crate, which adds startup code and minimal runtime initialization. + +## Enable the `rt` feature of [`rp-pac`](https://docs.rs/rp-pac). +## With `rt` enabled the PAC provides interrupt vectors instead of letting [`cortex-m-rt`](https://docs.rs/cortex-m-rt) do that. +## See for more info. rt = [ "rp-pac/rt" ] ## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers. -- cgit From 967a98fd4448a8e00c8cbfb509c1cc32e2bdcd29 Mon Sep 17 00:00:00 2001 From: Alessandro Gasbarroni Date: Tue, 17 Dec 2024 13:25:58 +0100 Subject: nrf: Add IPC peripheral for nRF5340 --- embassy-nrf/src/chips/nrf5340_app.rs | 5 + embassy-nrf/src/chips/nrf5340_net.rs | 5 + embassy-nrf/src/ipc.rs | 360 +++++++++++++++++++++++++++++++++++ embassy-nrf/src/lib.rs | 2 + 4 files changed, 372 insertions(+) create mode 100644 embassy-nrf/src/ipc.rs diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 0103fa7ae..99cf29487 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -262,6 +262,9 @@ embassy_hal_internal::peripherals! { PPI_GROUP4, PPI_GROUP5, + // IPC + IPC, + // GPIO port 0 #[cfg(feature = "lfxo-pins-as-gpio")] P0_00, @@ -327,6 +330,8 @@ embassy_hal_internal::peripherals! { EGU5, } +impl_ipc!(IPC, IPC, IPC); + impl_usb!(USBD, USBD, USBD); impl_uarte!(SERIAL0, UARTE0, SERIAL0); diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index 22d33d080..c2932be31 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs @@ -141,6 +141,9 @@ embassy_hal_internal::peripherals! { PPI_GROUP4, PPI_GROUP5, + // IPC + IPC, + // GPIO port 0 P0_00, P0_01, @@ -200,6 +203,8 @@ embassy_hal_internal::peripherals! { EGU0, } +impl_ipc!(IPC, IPC, IPC); + impl_uarte!(SERIAL0, UARTE0, SERIAL0); impl_spim!(SERIAL0, SPIM0, SERIAL0); impl_spis!(SERIAL0, SPIS0, SERIAL0); diff --git a/embassy-nrf/src/ipc.rs b/embassy-nrf/src/ipc.rs new file mode 100644 index 000000000..410783ef4 --- /dev/null +++ b/embassy-nrf/src/ipc.rs @@ -0,0 +1,360 @@ +//! InterProcessor Communication (IPC) + +#![macro_use] + +use core::future::poll_fn; +use core::sync::atomic::{compiler_fence, Ordering}; +use core::task::Poll; + +use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_sync::waitqueue::AtomicWaker; + +use crate::peripherals::IPC; +use crate::{interrupt, pac}; + +/// IPC Event +#[derive(Debug, Clone, Copy)] +pub enum IpcEvent { + /// IPC Event 0 + Event0 = 0, + /// IPC Event 1 + Event1 = 1, + /// IPC Event 2 + Event2 = 2, + /// IPC Event 3 + Event3 = 3, + /// IPC Event 4 + Event4 = 4, + /// IPC Event 5 + Event5 = 5, + /// IPC Event 6 + Event6 = 6, + /// IPC Event 7 + Event7 = 7, + /// IPC Event 8 + Event8 = 8, + /// IPC Event 9 + Event9 = 9, + /// IPC Event 10 + Event10 = 10, + /// IPC Event 11 + Event11 = 11, + /// IPC Event 12 + Event12 = 12, + /// IPC Event 13 + Event13 = 13, + /// IPC Event 14 + Event14 = 14, + /// IPC Event 15 + Event15 = 15, +} + +const EVENTS: [IpcEvent; 16] = [ + IpcEvent::Event0, + IpcEvent::Event1, + IpcEvent::Event2, + IpcEvent::Event3, + IpcEvent::Event4, + IpcEvent::Event5, + IpcEvent::Event6, + IpcEvent::Event7, + IpcEvent::Event8, + IpcEvent::Event9, + IpcEvent::Event10, + IpcEvent::Event11, + IpcEvent::Event12, + IpcEvent::Event13, + IpcEvent::Event14, + IpcEvent::Event15, +]; + +/// IPC Channel +#[derive(Debug, Clone, Copy)] +pub enum IpcChannel { + /// IPC Channel 0 + Channel0, + /// IPC Channel 1 + Channel1, + /// IPC Channel 2 + Channel2, + /// IPC Channel 3 + Channel3, + /// IPC Channel 4 + Channel4, + /// IPC Channel 5 + Channel5, + /// IPC Channel 6 + Channel6, + /// IPC Channel 7 + Channel7, + /// IPC Channel 8 + Channel8, + /// IPC Channel 9 + Channel9, + /// IPC Channel 10 + Channel10, + /// IPC Channel 11 + Channel11, + /// IPC Channel 12 + Channel12, + /// IPC Channel 13 + Channel13, + /// IPC Channel 14 + Channel14, + /// IPC Channel 15 + Channel15, +} + +/// Interrupt Handler +pub struct InterruptHandler {} + +impl interrupt::typelevel::Handler for InterruptHandler { + unsafe fn on_interrupt() { + let regs = IPC::regs(); + + // Check if an event was generated, and if it was, trigger the corresponding waker + for event in EVENTS { + if regs.events_receive(event as usize).read() & 0x01 == 0x01 { + // Event is set. Reset and wake waker + regs.events_receive(event as usize).write_value(0); + IPC::state().waker_for(event); + } + + // Ensure the state is actually cleared + // Ref: nRF5340 PS v1.5 7.1.9.1 p.153 + compiler_fence(Ordering::SeqCst); + while regs.events_receive(event as usize).read() & 0x01 != 0x00 {} + } + } +} + +/// IPC driver +pub struct Ipc<'d, T: Instance> { + _peri: PeripheralRef<'d, T>, +} + +impl<'d, T: Instance> From> for Ipc<'d, T> { + fn from(value: PeripheralRef<'d, T>) -> Self { + Self { _peri: value } + } +} + +impl<'d, T: Instance> Ipc<'d, T> { + /// Create IPC driver + pub fn new(ipc: impl Peripheral

+ 'd) -> Self { + into_ref!(ipc); + + Self { _peri: ipc } + } + + /// Duplicates the peripheral singleton + /// + /// # Safety + /// + /// Ensure manually that only one peripheral is in use at one time + pub unsafe fn clone_unchecked(&self) -> Self { + Self { + _peri: self._peri.clone_unchecked(), + } + } + + /// Configures the sending of events + /// + /// Events can be configured to broadcast on one or multiple IPC channels. + pub fn configure_send_event>(&self, ev: IpcEvent, channels: I) { + let regs = T::regs(); + + regs.send_cnf(ev as usize).write(|w| { + for channel in channels { + match channel { + IpcChannel::Channel0 => w.set_chen0(true), + IpcChannel::Channel1 => w.set_chen1(true), + IpcChannel::Channel2 => w.set_chen2(true), + IpcChannel::Channel3 => w.set_chen3(true), + IpcChannel::Channel4 => w.set_chen4(true), + IpcChannel::Channel5 => w.set_chen5(true), + IpcChannel::Channel6 => w.set_chen6(true), + IpcChannel::Channel7 => w.set_chen7(true), + IpcChannel::Channel8 => w.set_chen8(true), + IpcChannel::Channel9 => w.set_chen9(true), + IpcChannel::Channel10 => w.set_chen10(true), + IpcChannel::Channel11 => w.set_chen11(true), + IpcChannel::Channel12 => w.set_chen12(true), + IpcChannel::Channel13 => w.set_chen13(true), + IpcChannel::Channel14 => w.set_chen14(true), + IpcChannel::Channel15 => w.set_chen15(true), + } + } + }) + } + + /// Configures the receiving of events + /// + /// Events can be configured to be received by one or multiple IPC channels. + pub fn configure_receive_event>(&self, ev: IpcEvent, channels: I) { + let regs = T::regs(); + + regs.receive_cnf(ev as usize).write(|w| { + for channel in channels { + match channel { + IpcChannel::Channel0 => w.set_chen0(true), + IpcChannel::Channel1 => w.set_chen1(true), + IpcChannel::Channel2 => w.set_chen2(true), + IpcChannel::Channel3 => w.set_chen3(true), + IpcChannel::Channel4 => w.set_chen4(true), + IpcChannel::Channel5 => w.set_chen5(true), + IpcChannel::Channel6 => w.set_chen6(true), + IpcChannel::Channel7 => w.set_chen7(true), + IpcChannel::Channel8 => w.set_chen8(true), + IpcChannel::Channel9 => w.set_chen9(true), + IpcChannel::Channel10 => w.set_chen10(true), + IpcChannel::Channel11 => w.set_chen11(true), + IpcChannel::Channel12 => w.set_chen12(true), + IpcChannel::Channel13 => w.set_chen13(true), + IpcChannel::Channel14 => w.set_chen14(true), + IpcChannel::Channel15 => w.set_chen15(true), + } + } + }); + } + + /// Triggers an event + pub fn trigger_event(&self, ev: IpcEvent) { + let regs = T::regs(); + + regs.tasks_send(ev as usize).write_value(0x01); + } + + /// Wait for event to be triggered + pub async fn wait_for_event(&self, ev: IpcEvent) { + let regs = T::regs(); + + // Enable interrupt + match ev { + IpcEvent::Event0 => { + regs.inten().modify(|m| m.set_receive0(true)); + } + IpcEvent::Event1 => { + regs.inten().modify(|m| m.set_receive1(true)); + } + IpcEvent::Event2 => { + regs.inten().modify(|m| m.set_receive2(true)); + } + IpcEvent::Event3 => { + regs.inten().modify(|m| m.set_receive3(true)); + } + IpcEvent::Event4 => { + regs.inten().modify(|m| m.set_receive4(true)); + } + IpcEvent::Event5 => { + regs.inten().modify(|m| m.set_receive5(true)); + } + IpcEvent::Event6 => { + regs.inten().modify(|m| m.set_receive6(true)); + } + IpcEvent::Event7 => { + regs.inten().modify(|m| m.set_receive7(true)); + } + IpcEvent::Event8 => { + regs.inten().modify(|m| m.set_receive8(true)); + } + IpcEvent::Event9 => { + regs.inten().modify(|m| m.set_receive9(true)); + } + IpcEvent::Event10 => { + regs.inten().modify(|m| m.set_receive10(true)); + } + IpcEvent::Event11 => { + regs.inten().modify(|m| m.set_receive11(true)); + } + IpcEvent::Event12 => { + regs.inten().modify(|m| m.set_receive12(true)); + } + IpcEvent::Event13 => { + regs.inten().modify(|m| m.set_receive13(true)); + } + IpcEvent::Event14 => { + regs.inten().modify(|m| m.set_receive14(true)); + } + IpcEvent::Event15 => { + regs.inten().modify(|m| m.set_receive15(true)); + } + }; + + poll_fn(|cx| { + IPC::state().waker_for(ev).register(cx.waker()); + + if regs.events_receive(ev as usize).read() & 0x01 == 0x01 { + regs.events_receive(ev as usize).write_value(0x00); + + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await; + } +} + +pub(crate) struct State { + wakers: [AtomicWaker; 16], +} + +impl State { + pub(crate) const fn new() -> Self { + const WAKER: AtomicWaker = AtomicWaker::new(); + + Self { wakers: [WAKER; 16] } + } + + const fn waker_for(&self, ev: IpcEvent) -> &AtomicWaker { + match ev { + IpcEvent::Event0 => &self.wakers[0], + IpcEvent::Event1 => &self.wakers[1], + IpcEvent::Event2 => &self.wakers[2], + IpcEvent::Event3 => &self.wakers[3], + IpcEvent::Event4 => &self.wakers[4], + IpcEvent::Event5 => &self.wakers[5], + IpcEvent::Event6 => &self.wakers[6], + IpcEvent::Event7 => &self.wakers[7], + IpcEvent::Event8 => &self.wakers[8], + IpcEvent::Event9 => &self.wakers[9], + IpcEvent::Event10 => &self.wakers[10], + IpcEvent::Event11 => &self.wakers[11], + IpcEvent::Event12 => &self.wakers[12], + IpcEvent::Event13 => &self.wakers[13], + IpcEvent::Event14 => &self.wakers[14], + IpcEvent::Event15 => &self.wakers[15], + } + } +} + +pub(crate) trait SealedInstance { + fn regs() -> pac::ipc::Ipc; + fn state() -> &'static State; +} + +/// IPC peripheral instance. +#[allow(private_bounds)] +pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { + /// Interrupt for this peripheral. + type Interrupt: interrupt::typelevel::Interrupt; +} + +macro_rules! impl_ipc { + ($type:ident, $pac_type:ident, $irq:ident) => { + impl crate::ipc::SealedInstance for peripherals::$type { + fn regs() -> pac::ipc::Ipc { + pac::$pac_type + } + + fn state() -> &'static crate::ipc::State { + static STATE: crate::ipc::State = crate::ipc::State::new(); + &STATE + } + } + impl crate::ipc::Instance for peripherals::$type { + type Interrupt = crate::interrupt::typelevel::$irq; + } + }; +} diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 07ba2f6d4..5bce65a98 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -88,6 +88,8 @@ pub mod gpiote; #[cfg(not(feature = "_nrf54l"))] // TODO #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] pub mod i2s; +#[cfg(feature = "_nrf5340")] +pub mod ipc; #[cfg(not(feature = "_nrf54l"))] // TODO #[cfg(any( feature = "nrf52832", -- cgit From 4567beda7b7773c8cb11f19f0f4f146c1243508d Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Sun, 11 May 2025 17:26:36 +0200 Subject: rp235x overclocking --- embassy-rp/src/clocks.rs | 329 ++++++++++++++++++++++++++++---- examples/rp/src/bin/overclock.rs | 8 +- examples/rp/src/bin/overclock_manual.rs | 10 +- examples/rp235x/src/bin/overclock.rs | 74 +++++++ tests/rp/src/bin/overclock.rs | 49 +++-- 5 files changed, 405 insertions(+), 65 deletions(-) create mode 100644 examples/rp235x/src/bin/overclock.rs diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 6694aab66..ea5e9362b 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -38,7 +38,7 @@ //! //! ## Examples //! -//! ### Standard 125MHz configuration +//! ### Standard 125MHz (rp2040) or 150Mhz (rp235x) configuration //! ```rust,ignore //! let config = ClockConfig::crystal(12_000_000); //! ``` @@ -136,43 +136,152 @@ pub enum PeriClkSrc { // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ , } -/// Core voltage regulator settings for RP2040. +/// Core voltage regulator settings. /// -/// The RP2040 voltage regulator can be configured for different output voltages. +/// The voltage regulator can be configured for different output voltages. /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. -#[cfg(feature = "rp2040")] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u8)] pub enum CoreVoltage { - /// 0.80V - Suitable for lower frequencies + // RP2040 voltage levels + #[cfg(feature = "rp2040")] + /// RP2040: 0.80V V0_80 = 0b0000, - /// 0.85V + #[cfg(feature = "rp2040")] + /// RP2040: 0.85V V0_85 = 0b0110, - /// 0.90V + #[cfg(feature = "rp2040")] + /// RP2040: 0.90V V0_90 = 0b0111, - /// 0.95V + #[cfg(feature = "rp2040")] + /// RP2040: 0.95V V0_95 = 0b1000, - /// 1.00V + #[cfg(feature = "rp2040")] + /// RP2040: 1.00V V1_00 = 0b1001, - /// 1.05V + #[cfg(feature = "rp2040")] + /// RP2040: 1.05V V1_05 = 0b1010, - /// 1.10V - Default voltage level + #[cfg(feature = "rp2040")] + /// RP2040: 1.10V - Default voltage level V1_10 = 0b1011, - /// 1.15V - Required for overclocking to 133-200MHz + #[cfg(feature = "rp2040")] + /// RP2040: 1.15V - Required for overclocking to 133-200MHz V1_15 = 0b1100, - /// 1.20V + #[cfg(feature = "rp2040")] + /// RP2040: 1.20V V1_20 = 0b1101, - /// 1.25V + #[cfg(feature = "rp2040")] + /// RP2040: 1.25V V1_25 = 0b1110, - /// 1.30V + #[cfg(feature = "rp2040")] + /// RP2040: 1.30V V1_30 = 0b1111, + + // RP235x voltage levels + #[cfg(feature = "_rp235x")] + /// RP235x: 0.55V + V0_55 = 0b00000, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.60V + V0_60 = 0b00001, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.65V + V0_65 = 0b00010, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.70V + V0_70 = 0b00011, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.75V + V0_75 = 0b00100, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.80V + V0_80 = 0b00101, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.85V + V0_85 = 0b00110, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.90V + V0_90 = 0b00111, + #[cfg(feature = "_rp235x")] + /// RP235x: 0.95V + V0_95 = 0b01000, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.00V + V1_00 = 0b01001, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.05V + V1_05 = 0b01010, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.10V - Default voltage level + V1_10 = 0b01011, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.15V + V1_15 = 0b01100, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.20V + V1_20 = 0b01101, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.25V + V1_25 = 0b01110, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.30V + V1_30 = 0b01111, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.35V + V1_35 = 0b10000, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.40V + V1_40 = 0b10001, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.50V + V1_50 = 0b10010, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.60V + V1_60 = 0b10011, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.65V + V1_65 = 0b10100, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.70V + V1_70 = 0b10101, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.80V + V1_80 = 0b10110, + #[cfg(feature = "_rp235x")] + /// RP235x: 1.90V + V1_90 = 0b10111, + #[cfg(feature = "_rp235x")] + /// RP235x: 2.00V + V2_00 = 0b11000, + #[cfg(feature = "_rp235x")] + /// RP235x: 2.35V + V2_35 = 0b11001, + #[cfg(feature = "_rp235x")] + /// RP235x: 2.50V + V2_50 = 0b11010, + #[cfg(feature = "_rp235x")] + /// RP235x: 2.65V + V2_65 = 0b11011, + #[cfg(feature = "_rp235x")] + /// RP235x: 2.80V + V2_80 = 0b11100, + #[cfg(feature = "_rp235x")] + /// RP235x: 3.00V + V3_00 = 0b11101, + #[cfg(feature = "_rp235x")] + /// RP235x: 3.15V + V3_15 = 0b11110, + #[cfg(feature = "_rp235x")] + /// RP235x: 3.30V + V3_30 = 0b11111, } -#[cfg(feature = "rp2040")] impl CoreVoltage { /// Get the recommended Brown-Out Detection (BOD) setting for this voltage. /// Sets the BOD threshold to approximately 80% of the core voltage. fn recommended_bod(self) -> u8 { + #[cfg(feature = "rp2040")] match self { CoreVoltage::V0_80 => 0b0100, // 0.645V (~81% of 0.80V) CoreVoltage::V0_85 => 0b0101, // 0.688V (~81% of 0.85V) @@ -180,12 +289,38 @@ impl CoreVoltage { CoreVoltage::V0_95 => 0b0111, // 0.774V (~81% of 0.95V) CoreVoltage::V1_00 => 0b1000, // 0.817V (~82% of 1.00V) CoreVoltage::V1_05 => 0b1000, // 0.817V (~78% of 1.05V) - CoreVoltage::V1_10 => 0b1001, // 0.860V (~78% of 1.10V) + CoreVoltage::V1_10 => 0b1001, // 0.860V (~78% of 1.10V), the default CoreVoltage::V1_15 => 0b1010, // 0.903V (~79% of 1.15V) CoreVoltage::V1_20 => 0b1011, // 0.946V (~79% of 1.20V) CoreVoltage::V1_25 => 0b1100, // 0.989V (~79% of 1.25V) CoreVoltage::V1_30 => 0b1101, // 1.032V (~79% of 1.30V) } + #[cfg(feature = "_rp235x")] + match self { + CoreVoltage::V0_55 => 0b00001, // 0.516V (~94% of 0.55V) + CoreVoltage::V0_60 => 0b00010, // 0.559V (~93% of 0.60V) + CoreVoltage::V0_65 => 0b00011, // 0.602V (~93% of 0.65V) + CoreVoltage::V0_70 => 0b00011, // 0.602V (~86% of 0.70V) + CoreVoltage::V0_75 => 0b00100, // 0.645V (~86% of 0.75V) + CoreVoltage::V0_80 => 0b00101, // 0.688V (~86% of 0.80V) + CoreVoltage::V0_85 => 0b00110, // 0.731V (~86% of 0.85V) + CoreVoltage::V0_90 => 0b00110, // 0.731V (~81% of 0.90V) + CoreVoltage::V0_95 => 0b00111, // 0.774V (~81% of 0.95V) + CoreVoltage::V1_00 => 0b01000, // 0.817V (~82% of 1.00V) + CoreVoltage::V1_05 => 0b01000, // 0.817V (~78% of 1.05V) + CoreVoltage::V1_10 => 0b01001, // 0.860V (~78% of 1.10V), the default + CoreVoltage::V1_15 => 0b01001, // 0.860V (~75% of 1.15V) + CoreVoltage::V1_20 => 0b01010, // 0.903V (~75% of 1.20V) + CoreVoltage::V1_25 => 0b01010, // 0.903V (~72% of 1.25V) + CoreVoltage::V1_30 => 0b01011, // 0.946V (~73% of 1.30V) + CoreVoltage::V1_35 => 0b01011, // 0.946V (~70% of 1.35V) + CoreVoltage::V1_40 => 0b01100, // 0.989V (~71% of 1.40V) + CoreVoltage::V1_50 => 0b01101, // 1.032V (~69% of 1.50V) + CoreVoltage::V1_60 => 0b01110, // 1.075V (~67% of 1.60V) + CoreVoltage::V1_65 => 0b01110, // 1.075V (~65% of 1.65V) + CoreVoltage::V1_70 => 0b01111, // 1.118V (~66% of 1.70V) + _ => 0b10000, // the rp2350 datasheet repeats this value for all other core voltages + } } } @@ -209,12 +344,10 @@ pub struct ClockConfig { /// RTC clock configuration. #[cfg(feature = "rp2040")] pub rtc_clk: Option, - /// Core voltage scaling (RP2040 only). Defaults to 1.10V. - #[cfg(feature = "rp2040")] + /// Core voltage scaling. Defaults to 1.10V. pub core_voltage: CoreVoltage, /// Voltage stabilization delay in microseconds. /// If not set, defaults will be used based on voltage level. - #[cfg(feature = "rp2040")] pub voltage_stabilization_delay_us: Option, // See above re gpin handling being commented out // gpin0: Option<(u32, Gpin<'static, AnyPin>)>, @@ -250,9 +383,7 @@ impl Default for ClockConfig { adc_clk: None, #[cfg(feature = "rp2040")] rtc_clk: None, - #[cfg(feature = "rp2040")] core_voltage: CoreVoltage::V1_10, - #[cfg(feature = "rp2040")] voltage_stabilization_delay_us: None, // See above re gpin handling being commented out // gpin0: None, @@ -323,9 +454,7 @@ impl ClockConfig { div_frac: 0, phase: 0, }), - #[cfg(feature = "rp2040")] core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) - #[cfg(feature = "rp2040")] voltage_stabilization_delay_us: None, // See above re gpin handling being commented out // gpin0: None, @@ -368,9 +497,7 @@ impl ClockConfig { div_frac: 171, phase: 0, }), - #[cfg(feature = "rp2040")] core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) - #[cfg(feature = "rp2040")] voltage_stabilization_delay_us: None, // See above re gpin handling being commented out // gpin0: None, @@ -394,12 +521,17 @@ impl ClockConfig { /// the usual 12Mhz crystal, or panic if no valid parameters can be found. /// /// # Note on core voltage: + /// + /// **For RP2040**: /// To date the only officially documented core voltages (see Datasheet section 2.15.3.1. Instances) are: /// - Up to 133MHz: V1_10 (default) /// - Above 133MHz: V1_15, but in the context of the datasheet covering reaching up to 200Mhz /// That way all other frequencies below 133MHz or above 200MHz are not explicitly documented and not covered here. /// In case You want to go below 133MHz or above 200MHz and want a different voltage, You will have to set that manually and with caution. - #[cfg(feature = "rp2040")] + /// + /// **For RP235x**: + /// At this point in time there is no official manufacturer endorsement for running the chip on other core voltages and/or other clock speeds than the defaults. + /// Using this function is experimental and may not work as expected or even damage the chip. pub fn system_freq(hz: u32) -> Self { // Start with the standard configuration from crystal() const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000; @@ -407,9 +539,14 @@ impl ClockConfig { // No need to modify anything if target frequency is already 125MHz // (which is what crystal() configures by default) + #[cfg(feature = "rp2040")] if hz == 125_000_000 { return config; } + #[cfg(feature = "_rp235x")] + if hz == 150_000_000 { + return config; + } // Find optimal PLL parameters for the requested frequency let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, hz) @@ -429,6 +566,14 @@ impl ClockConfig { _ => CoreVoltage::V1_10, // Use default voltage (V1_10) }; } + #[cfg(feature = "_rp235x")] + { + config.core_voltage = match hz { + // There is no official support for running the chip on other core voltages and/or other clock speeds than the defaults. + // So for now we have not way of knowing what the voltage should be. Change this if the manufacturer provides more information. + _ => CoreVoltage::V1_10, // Use default voltage (V1_10) + }; + } config } @@ -791,7 +936,6 @@ pub struct RtcClkConfig { /// // Find parameters for 133MHz system clock from 12MHz crystal /// let pll_params = find_pll_params(12_000_000, 133_000_000).unwrap(); /// ``` -#[cfg(feature = "rp2040")] fn find_pll_params(input_hz: u32, target_hz: u32) -> Option { // Fixed reference divider for system PLL const PLL_SYS_REFDIV: u8 = 1; @@ -925,18 +1069,59 @@ pub(crate) unsafe fn init(config: ClockConfig) { }; CLOCKS.rosc.store(rosc_freq, Ordering::Relaxed); - // Set Core Voltage (RP2040 only), if we have config for it and we're not using the default - #[cfg(feature = "rp2040")] + // Set Core Voltage, if we have config for it and we're not using the default { let voltage = config.core_voltage; + + #[cfg(feature = "rp2040")] let vreg = pac::VREG_AND_CHIP_RESET; + #[cfg(feature = "_rp235x")] + let vreg = pac::POWMAN; + let current_vsel = vreg.vreg().read().vsel(); let target_vsel = voltage as u8; // If the target voltage is different from the current one, we need to change it if target_vsel != current_vsel { - // Use modify() to preserve the HIZ and EN bits - otherwise we will disable the regulator when changing voltage - vreg.vreg().modify(|w| w.set_vsel(target_vsel)); + #[cfg(feature = "rp2040")] + { + // Use modify() to preserve the HIZ and EN bits - otherwise we will disable the regulator when changing voltage + vreg.vreg().modify(|w| w.set_vsel(target_vsel)); + } + #[cfg(feature = "_rp235x")] + { + // The rp235x has a different way of controlling the voltage regulator + // Changes to the voltage regulator are protected by a password, see datasheet section 6.4 + // The password is "5AFE" (0x5AFE), it must be set in the top 16 bits of the register + + // The rp235x by default locks the voltage regulator control, so we need to unlock it first + // See datasheet section 6.3.2. Software Control + vreg.vreg_ctrl().modify(|w| { + // Add password to top 16 bits, preserving the rest, repeat below for other registers + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); + w.set_unlock(true); + *w + }); + + // Set the voltage + vreg.vreg().modify(|w| { + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); + w.set_vsel(target_vsel); + *w + }); + + // The rp235x has two more registers to set the voltage for low power mode + vreg.vreg_lp_entry().modify(|w| { + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); + w.set_vsel(target_vsel); + *w + }); + vreg.vreg_lp_exit().modify(|w| { + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); + w.set_vsel(target_vsel); + *w + }); + } // Wait for the voltage to stabilize. Use the provided delay or default based on voltage let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| { @@ -959,6 +1144,19 @@ pub(crate) unsafe fn init(config: ClockConfig) { w.set_vsel(voltage.recommended_bod()); w.set_en(true); // Enable brownout detection }); + + #[cfg(feature = "_rp235x")] + { + // The rp235x has a separate register for the BOD level in low power mode + vreg.bod_lp_entry().write(|w| { + w.set_vsel(voltage.recommended_bod()); + w.set_en(true); // Enable brownout detection + }); + vreg.bod_lp_exit().write(|w| { + w.set_vsel(voltage.recommended_bod()); + w.set_en(true); // Enable brownout detection + }); + } } } @@ -1283,6 +1481,73 @@ pub fn clk_rtc_freq() -> u16 { CLOCKS.rtc.load(Ordering::Relaxed) } +/// The core voltage of the chip. +/// +/// Returns the current core voltage or an error if the voltage register +/// contains an unknown value. +pub fn core_voltage() -> Result { + #[cfg(feature = "rp2040")] + { + let vreg = pac::VREG_AND_CHIP_RESET; + let vsel = vreg.vreg().read().vsel(); + match vsel { + 0b0000 => Ok(CoreVoltage::V0_80), + 0b0110 => Ok(CoreVoltage::V0_85), + 0b0111 => Ok(CoreVoltage::V0_90), + 0b1000 => Ok(CoreVoltage::V0_95), + 0b1001 => Ok(CoreVoltage::V1_00), + 0b1010 => Ok(CoreVoltage::V1_05), + 0b1011 => Ok(CoreVoltage::V1_10), + 0b1100 => Ok(CoreVoltage::V1_15), + 0b1101 => Ok(CoreVoltage::V1_20), + 0b1110 => Ok(CoreVoltage::V1_25), + 0b1111 => Ok(CoreVoltage::V1_30), + _ => Err("Unexpected value in register"), + } + } + + #[cfg(feature = "_rp235x")] + { + let vreg = pac::POWMAN; + let vsel = vreg.vreg().read().vsel(); + match vsel { + 0b00000 => Ok(CoreVoltage::V0_55), + 0b00001 => Ok(CoreVoltage::V0_60), + 0b00010 => Ok(CoreVoltage::V0_65), + 0b00011 => Ok(CoreVoltage::V0_70), + 0b00100 => Ok(CoreVoltage::V0_75), + 0b00101 => Ok(CoreVoltage::V0_80), + 0b00110 => Ok(CoreVoltage::V0_85), + 0b00111 => Ok(CoreVoltage::V0_90), + 0b01000 => Ok(CoreVoltage::V0_95), + 0b01001 => Ok(CoreVoltage::V1_00), + 0b01010 => Ok(CoreVoltage::V1_05), + 0b01011 => Ok(CoreVoltage::V1_10), + 0b01100 => Ok(CoreVoltage::V1_15), + 0b01101 => Ok(CoreVoltage::V1_20), + 0b01110 => Ok(CoreVoltage::V1_25), + 0b01111 => Ok(CoreVoltage::V1_30), + 0b10000 => Ok(CoreVoltage::V1_35), + 0b10001 => Ok(CoreVoltage::V1_40), + 0b10010 => Ok(CoreVoltage::V1_50), + 0b10011 => Ok(CoreVoltage::V1_60), + 0b10100 => Ok(CoreVoltage::V1_65), + 0b10101 => Ok(CoreVoltage::V1_70), + 0b10110 => Ok(CoreVoltage::V1_80), + 0b10111 => Ok(CoreVoltage::V1_90), + 0b11000 => Ok(CoreVoltage::V2_00), + 0b11001 => Ok(CoreVoltage::V2_35), + 0b11010 => Ok(CoreVoltage::V2_50), + 0b11011 => Ok(CoreVoltage::V2_65), + 0b11100 => Ok(CoreVoltage::V2_80), + 0b11101 => Ok(CoreVoltage::V3_00), + 0b11110 => Ok(CoreVoltage::V3_15), + 0b11111 => Ok(CoreVoltage::V3_30), + _ => Err("Unexpected value in register"), + } + } +} + fn start_xosc(crystal_hz: u32, delay_multiplier: u32) { let startup_delay = (((crystal_hz / 1000) * delay_multiplier) + 128) / 256; pac::XOSC.startup().write(|w| w.set_delay(startup_delay as u16)); diff --git a/examples/rp/src/bin/overclock.rs b/examples/rp/src/bin/overclock.rs index 9c78e0c9d..89147ba42 100644 --- a/examples/rp/src/bin/overclock.rs +++ b/examples/rp/src/bin/overclock.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_rp::clocks::{clk_sys_freq, ClockConfig}; +use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig}; use embassy_rp::config::Config; use embassy_rp::gpio::{Level, Output}; use embassy_time::{Duration, Instant, Timer}; @@ -20,15 +20,15 @@ async fn main(_spawner: Spawner) -> ! { // Set up for clock frequency of 200 MHz, setting all necessary defaults. let config = Config::new(ClockConfig::system_freq(200_000_000)); - // Show the voltage scale for verification - info!("System core voltage: {}", Debug2Format(&config.clocks.core_voltage)); - // Initialize the peripherals let p = embassy_rp::init(config); // Show CPU frequency for verification let sys_freq = clk_sys_freq(); info!("System clock frequency: {} MHz", sys_freq / 1_000_000); + // Show core voltage for verification + let core_voltage = core_voltage().unwrap(); + info!("Core voltage: {}", Debug2Format(&core_voltage)); // LED to indicate the system is running let mut led = Output::new(p.PIN_25, Level::Low); diff --git a/examples/rp/src/bin/overclock_manual.rs b/examples/rp/src/bin/overclock_manual.rs index 35160b250..88ef26a7a 100644 --- a/examples/rp/src/bin/overclock_manual.rs +++ b/examples/rp/src/bin/overclock_manual.rs @@ -7,8 +7,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_rp::clocks; -use embassy_rp::clocks::{ClockConfig, CoreVoltage, PllConfig}; +use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage, PllConfig}; use embassy_rp::config::Config; use embassy_rp::gpio::{Level, Output}; use embassy_time::{Duration, Instant, Timer}; @@ -41,9 +40,12 @@ async fn main(_spawner: Spawner) -> ! { // Initialize with our manual overclock configuration let p = embassy_rp::init(configure_manual_overclock()); - // Verify the actual system clock frequency - let sys_freq = clocks::clk_sys_freq(); + // Show CPU frequency for verification + let sys_freq = clk_sys_freq(); info!("System clock frequency: {} MHz", sys_freq / 1_000_000); + // Show core voltage for verification + let core_voltage = core_voltage().unwrap(); + info!("Core voltage: {}", Debug2Format(&core_voltage)); // LED to indicate the system is running let mut led = Output::new(p.PIN_25, Level::Low); diff --git a/examples/rp235x/src/bin/overclock.rs b/examples/rp235x/src/bin/overclock.rs new file mode 100644 index 000000000..8713df688 --- /dev/null +++ b/examples/rp235x/src/bin/overclock.rs @@ -0,0 +1,74 @@ +//! # Overclocking the RP2350 to 200 MHz +//! +//! This example demonstrates how to configure the RP2350 to run at 200 MHz instead of the default 150 MHz. +//! +//! ## Note +//! +//! As of yet there is no official support for running the RP235x at higher clock frequencies and/or other core voltages than the default. +//! Doing so may cause unexpected behavior and/or damage the chip. + +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage}; +use embassy_rp::config::Config; +use embassy_rp::gpio::{Level, Output}; +use embassy_time::{Duration, Instant, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +const COUNT_TO: i64 = 10_000_000; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + // Set up for clock frequency of 200 MHz, setting all necessary defaults. + let mut config = Config::new(ClockConfig::system_freq(200_000_000)); + + // since for the rp235x there is no official support for higher clock frequencies, `system_freq()` will not set a voltage for us. + // We need to guess the core voltage, that is needed for the higher clock frequency. Going with a small increase from the default 1.1V here, based on + // what we know about the RP2040. This is not guaranteed to be correct. + config.clocks.core_voltage = CoreVoltage::V1_15; + + // Initialize the peripherals + let p = embassy_rp::init(config); + + // Show CPU frequency for verification + let sys_freq = clk_sys_freq(); + info!("System clock frequency: {} MHz", sys_freq / 1_000_000); + // Show core voltage for verification + let core_voltage = core_voltage().unwrap(); + info!("Core voltage: {}", Debug2Format(&core_voltage)); + + // LED to indicate the system is running + let mut led = Output::new(p.PIN_25, Level::Low); + + loop { + // Reset the counter at the start of measurement period + let mut counter = 0; + + // Turn LED on while counting + led.set_high(); + + let start = Instant::now(); + + // This is a busy loop that will take some time to complete + while counter < COUNT_TO { + counter += 1; + } + + let elapsed = Instant::now() - start; + + // Report the elapsed time + led.set_low(); + info!( + "At {}Mhz: Elapsed time to count to {}: {}ms", + sys_freq / 1_000_000, + counter, + elapsed.as_millis() + ); + + // Wait 2 seconds before starting the next measurement + Timer::after(Duration::from_secs(2)).await; + } +} diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs index be8e85a3f..a568d7fed 100644 --- a/tests/rp/src/bin/overclock.rs +++ b/tests/rp/src/bin/overclock.rs @@ -7,14 +7,8 @@ teleprobe_meta::target!(b"rpi-pico"); teleprobe_meta::target!(b"pimoroni-pico-plus-2"); use defmt::info; -#[cfg(feature = "rp2040")] -use defmt::{assert, assert_eq}; use embassy_executor::Spawner; -use embassy_rp::clocks; -#[cfg(feature = "rp2040")] -use embassy_rp::clocks::ClockConfig; -#[cfg(feature = "rp2040")] -use embassy_rp::clocks::CoreVoltage; +use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage}; use embassy_rp::config::Config; use embassy_time::Instant; use {defmt_rtt as _, panic_probe as _}; @@ -23,23 +17,26 @@ const COUNT_TO: i64 = 10_000_000; #[embassy_executor::main] async fn main(_spawner: Spawner) { - #[cfg(feature = "rp2040")] let mut config = Config::default(); - #[cfg(not(feature = "rp2040"))] - let config = Config::default(); - // Initialize with 200MHz clock configuration for RP2040, other chips will use default clock - #[cfg(feature = "rp2040")] + // Initialize with 200MHz clock configuration + config.clocks = ClockConfig::system_freq(200_000_000); + + // if we are rp235x, we need to manually set the core voltage. rp2040 should do this automatically + #[cfg(feature = "rp235xb")] { - config.clocks = ClockConfig::system_freq(200_000_000); - let voltage = config.clocks.core_voltage; - assert!(matches!(voltage, CoreVoltage::V1_15), "Expected voltage scale V1_15"); + config.clocks.core_voltage = CoreVoltage::V1_15; } let _p = embassy_rp::init(config); + // We should be at core voltage of 1.15V + assert_eq!(core_voltage().unwrap(), CoreVoltage::V1_15, "Core voltage is not 1.15V"); + // We should be at 200MHz + assert_eq!(clk_sys_freq(), 200_000_000, "System clock frequency is not 200MHz"); + // Test the system speed - let (time_elapsed, clk_sys_freq) = { + let time_elapsed = { let mut counter = 0; let start = Instant::now(); while counter < COUNT_TO { @@ -47,24 +44,26 @@ async fn main(_spawner: Spawner) { } let elapsed = Instant::now() - start; - (elapsed.as_millis(), clocks::clk_sys_freq()) + elapsed.as_millis() }; - // Report the elapsed time, so that the compiler doesn't optimize it away for chips other than RP2040 + // Tests will fail if unused variables are detected: + // Report the elapsed time, so that the compiler doesn't optimize it away for the chip not on test info!( "At {}Mhz: Elapsed time to count to {}: {}ms", - clk_sys_freq / 1_000_000, + clk_sys_freq() / 1_000_000, COUNT_TO, time_elapsed ); + // Check if the elapsed time is within expected limits + // for rp2040 we expect about 600ms #[cfg(feature = "rp2040")] - { - // we should be at 200MHz - assert_eq!(clk_sys_freq, 200_000_000, "System clock frequency is not 200MHz"); - // At 200MHz, the time to count to 10_000_000 should be at 600ms, testing with 1% margin - assert!(time_elapsed <= 606, "Elapsed time is too long"); - } + // allow 1% error + assert!(time_elapsed < 606, "Elapsed time is too long"); + // for rp235x we expect about 450ms + #[cfg(feature = "rp235xb")] + assert!(time_elapsed < 455, "Elapsed time is too long"); cortex_m::asm::bkpt(); } -- cgit From a0a339d01ade57aa6e66835a27b1e6ea54333b54 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Thu, 8 May 2025 23:26:10 -0500 Subject: nrf: Rework IPC module --- embassy-nrf/src/ipc.rs | 391 +++++++++++++++++++++++++------------------------ 1 file changed, 197 insertions(+), 194 deletions(-) diff --git a/embassy-nrf/src/ipc.rs b/embassy-nrf/src/ipc.rs index 410783ef4..a8a08c911 100644 --- a/embassy-nrf/src/ipc.rs +++ b/embassy-nrf/src/ipc.rs @@ -3,18 +3,20 @@ #![macro_use] use core::future::poll_fn; -use core::sync::atomic::{compiler_fence, Ordering}; +use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; -use crate::peripherals::IPC; -use crate::{interrupt, pac}; +use crate::interrupt::typelevel::Interrupt; +use crate::{interrupt, pac, ppi}; + +const EVENT_COUNT: usize = 16; /// IPC Event -#[derive(Debug, Clone, Copy)] -pub enum IpcEvent { +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum EventNumber { /// IPC Event 0 Event0 = 0, /// IPC Event 1 @@ -49,27 +51,27 @@ pub enum IpcEvent { Event15 = 15, } -const EVENTS: [IpcEvent; 16] = [ - IpcEvent::Event0, - IpcEvent::Event1, - IpcEvent::Event2, - IpcEvent::Event3, - IpcEvent::Event4, - IpcEvent::Event5, - IpcEvent::Event6, - IpcEvent::Event7, - IpcEvent::Event8, - IpcEvent::Event9, - IpcEvent::Event10, - IpcEvent::Event11, - IpcEvent::Event12, - IpcEvent::Event13, - IpcEvent::Event14, - IpcEvent::Event15, +const EVENTS: [EventNumber; EVENT_COUNT] = [ + EventNumber::Event0, + EventNumber::Event1, + EventNumber::Event2, + EventNumber::Event3, + EventNumber::Event4, + EventNumber::Event5, + EventNumber::Event6, + EventNumber::Event7, + EventNumber::Event8, + EventNumber::Event9, + EventNumber::Event10, + EventNumber::Event11, + EventNumber::Event12, + EventNumber::Event13, + EventNumber::Event14, + EventNumber::Event15, ]; /// IPC Channel -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum IpcChannel { /// IPC Channel 0 Channel0, @@ -105,226 +107,227 @@ pub enum IpcChannel { Channel15, } +impl IpcChannel { + fn mask(self) -> u32 { + 1 << (self as u32) + } +} + /// Interrupt Handler -pub struct InterruptHandler {} +pub struct InterruptHandler { + _phantom: PhantomData, +} -impl interrupt::typelevel::Handler for InterruptHandler { +impl interrupt::typelevel::Handler for InterruptHandler { unsafe fn on_interrupt() { - let regs = IPC::regs(); + let regs = T::regs(); // Check if an event was generated, and if it was, trigger the corresponding waker for event in EVENTS { if regs.events_receive(event as usize).read() & 0x01 == 0x01 { - // Event is set. Reset and wake waker - regs.events_receive(event as usize).write_value(0); - IPC::state().waker_for(event); + regs.intenclr().write(|w| w.0 = 0x01 << event as u32); + T::state().wakers[event as usize].wake(); } - - // Ensure the state is actually cleared - // Ref: nRF5340 PS v1.5 7.1.9.1 p.153 - compiler_fence(Ordering::SeqCst); - while regs.events_receive(event as usize).read() & 0x01 != 0x00 {} } } } /// IPC driver +#[non_exhaustive] pub struct Ipc<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + /// Event 0 + pub event0: Event<'d, T>, + /// Event 1 + pub event1: Event<'d, T>, + /// Event 2 + pub event2: Event<'d, T>, + /// Event 3 + pub event3: Event<'d, T>, + /// Event 4 + pub event4: Event<'d, T>, + /// Event 5 + pub event5: Event<'d, T>, + /// Event 6 + pub event6: Event<'d, T>, + /// Event 7 + pub event7: Event<'d, T>, + /// Event 8 + pub event8: Event<'d, T>, + /// Event 9 + pub event9: Event<'d, T>, + /// Event 10 + pub event10: Event<'d, T>, + /// Event 11 + pub event11: Event<'d, T>, + /// Event 12 + pub event12: Event<'d, T>, + /// Event 13 + pub event13: Event<'d, T>, + /// Event 14 + pub event14: Event<'d, T>, + /// Event 15 + pub event15: Event<'d, T>, } -impl<'d, T: Instance> From> for Ipc<'d, T> { - fn from(value: PeripheralRef<'d, T>) -> Self { - Self { _peri: value } +impl<'d, T: Instance> Ipc<'d, T> { + /// Create a new IPC driver. + pub fn new( + _p: Peri<'d, T>, + _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + let _phantom = PhantomData; + #[rustfmt::skip] + let r = Self { // attributes on expressions are experimental + event0: Event { number: EventNumber::Event0, _phantom }, + event1: Event { number: EventNumber::Event1, _phantom }, + event2: Event { number: EventNumber::Event2, _phantom }, + event3: Event { number: EventNumber::Event3, _phantom }, + event4: Event { number: EventNumber::Event4, _phantom }, + event5: Event { number: EventNumber::Event5, _phantom }, + event6: Event { number: EventNumber::Event6, _phantom }, + event7: Event { number: EventNumber::Event7, _phantom }, + event8: Event { number: EventNumber::Event8, _phantom }, + event9: Event { number: EventNumber::Event9, _phantom }, + event10: Event { number: EventNumber::Event10, _phantom }, + event11: Event { number: EventNumber::Event11, _phantom }, + event12: Event { number: EventNumber::Event12, _phantom }, + event13: Event { number: EventNumber::Event13, _phantom }, + event14: Event { number: EventNumber::Event14, _phantom }, + event15: Event { number: EventNumber::Event15, _phantom }, + }; + r } } -impl<'d, T: Instance> Ipc<'d, T> { - /// Create IPC driver - pub fn new(ipc: impl Peripheral

+ 'd) -> Self { - into_ref!(ipc); +/// IPC event +pub struct Event<'d, T: Instance> { + number: EventNumber, + _phantom: PhantomData<&'d T>, +} - Self { _peri: ipc } +impl<'d, T: Instance> Event<'d, T> { + /// Trigger the event. + pub fn trigger(&self) { + let nr = self.number; + T::regs().tasks_send(nr as usize).write_value(1); } - /// Duplicates the peripheral singleton - /// - /// # Safety - /// - /// Ensure manually that only one peripheral is in use at one time - pub unsafe fn clone_unchecked(&self) -> Self { - Self { - _peri: self._peri.clone_unchecked(), - } + /// Wait for the event to be triggered. + pub async fn wait(&mut self) { + let regs = T::regs(); + let nr = self.number as usize; + regs.intenset().write(|w| w.0 = 1 << nr); + poll_fn(|cx| { + T::state().wakers[nr].register(cx.waker()); + + if regs.events_receive(nr).read() == 1 { + regs.events_receive(nr).write_value(0x00); + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await; } - /// Configures the sending of events - /// - /// Events can be configured to broadcast on one or multiple IPC channels. - pub fn configure_send_event>(&self, ev: IpcEvent, channels: I) { - let regs = T::regs(); + /// Returns the [`EventNumber`] of the event. + pub fn number(&self) -> EventNumber { + self.number + } - regs.send_cnf(ev as usize).write(|w| { + /// Create a handle that can trigger the event. + pub fn trigger_handle(&self) -> EventTrigger<'d, T> { + EventTrigger { + number: self.number, + _phantom: PhantomData, + } + } + + /// Configure the channels the event will broadcast to + pub fn configure_trigger>(&mut self, channels: I) { + T::regs().send_cnf(self.number as usize).write(|w| { for channel in channels { - match channel { - IpcChannel::Channel0 => w.set_chen0(true), - IpcChannel::Channel1 => w.set_chen1(true), - IpcChannel::Channel2 => w.set_chen2(true), - IpcChannel::Channel3 => w.set_chen3(true), - IpcChannel::Channel4 => w.set_chen4(true), - IpcChannel::Channel5 => w.set_chen5(true), - IpcChannel::Channel6 => w.set_chen6(true), - IpcChannel::Channel7 => w.set_chen7(true), - IpcChannel::Channel8 => w.set_chen8(true), - IpcChannel::Channel9 => w.set_chen9(true), - IpcChannel::Channel10 => w.set_chen10(true), - IpcChannel::Channel11 => w.set_chen11(true), - IpcChannel::Channel12 => w.set_chen12(true), - IpcChannel::Channel13 => w.set_chen13(true), - IpcChannel::Channel14 => w.set_chen14(true), - IpcChannel::Channel15 => w.set_chen15(true), - } + w.0 |= channel.mask(); } }) } - /// Configures the receiving of events - /// - /// Events can be configured to be received by one or multiple IPC channels. - pub fn configure_receive_event>(&self, ev: IpcEvent, channels: I) { - let regs = T::regs(); - - regs.receive_cnf(ev as usize).write(|w| { + /// Configure the channels the event will listen on + pub fn configure_wait>(&mut self, channels: I) { + T::regs().receive_cnf(self.number as usize).write(|w| { for channel in channels { - match channel { - IpcChannel::Channel0 => w.set_chen0(true), - IpcChannel::Channel1 => w.set_chen1(true), - IpcChannel::Channel2 => w.set_chen2(true), - IpcChannel::Channel3 => w.set_chen3(true), - IpcChannel::Channel4 => w.set_chen4(true), - IpcChannel::Channel5 => w.set_chen5(true), - IpcChannel::Channel6 => w.set_chen6(true), - IpcChannel::Channel7 => w.set_chen7(true), - IpcChannel::Channel8 => w.set_chen8(true), - IpcChannel::Channel9 => w.set_chen9(true), - IpcChannel::Channel10 => w.set_chen10(true), - IpcChannel::Channel11 => w.set_chen11(true), - IpcChannel::Channel12 => w.set_chen12(true), - IpcChannel::Channel13 => w.set_chen13(true), - IpcChannel::Channel14 => w.set_chen14(true), - IpcChannel::Channel15 => w.set_chen15(true), - } + w.0 |= channel.mask(); } }); } - /// Triggers an event - pub fn trigger_event(&self, ev: IpcEvent) { + /// Get the task for the IPC event to use with PPI. + pub fn task(&self) -> ppi::Task<'d> { + let nr = self.number as usize; let regs = T::regs(); - - regs.tasks_send(ev as usize).write_value(0x01); + ppi::Task::from_reg(regs.tasks_send(nr)) } - /// Wait for event to be triggered - pub async fn wait_for_event(&self, ev: IpcEvent) { + /// Get the event for the IPC event to use with PPI. + pub fn event(&self) -> ppi::Event<'d> { + let nr = self.number as usize; let regs = T::regs(); + ppi::Event::from_reg(regs.events_receive(nr)) + } - // Enable interrupt - match ev { - IpcEvent::Event0 => { - regs.inten().modify(|m| m.set_receive0(true)); - } - IpcEvent::Event1 => { - regs.inten().modify(|m| m.set_receive1(true)); - } - IpcEvent::Event2 => { - regs.inten().modify(|m| m.set_receive2(true)); - } - IpcEvent::Event3 => { - regs.inten().modify(|m| m.set_receive3(true)); - } - IpcEvent::Event4 => { - regs.inten().modify(|m| m.set_receive4(true)); - } - IpcEvent::Event5 => { - regs.inten().modify(|m| m.set_receive5(true)); - } - IpcEvent::Event6 => { - regs.inten().modify(|m| m.set_receive6(true)); - } - IpcEvent::Event7 => { - regs.inten().modify(|m| m.set_receive7(true)); - } - IpcEvent::Event8 => { - regs.inten().modify(|m| m.set_receive8(true)); - } - IpcEvent::Event9 => { - regs.inten().modify(|m| m.set_receive9(true)); - } - IpcEvent::Event10 => { - regs.inten().modify(|m| m.set_receive10(true)); - } - IpcEvent::Event11 => { - regs.inten().modify(|m| m.set_receive11(true)); - } - IpcEvent::Event12 => { - regs.inten().modify(|m| m.set_receive12(true)); - } - IpcEvent::Event13 => { - regs.inten().modify(|m| m.set_receive13(true)); - } - IpcEvent::Event14 => { - regs.inten().modify(|m| m.set_receive14(true)); - } - IpcEvent::Event15 => { - regs.inten().modify(|m| m.set_receive15(true)); - } - }; + /// Reborrow into a "child" Event. + /// + /// `self` will stay borrowed until the child Event is dropped. + pub fn reborrow(&mut self) -> Event<'_, T> { + Self { ..*self } + } - poll_fn(|cx| { - IPC::state().waker_for(ev).register(cx.waker()); + /// Steal an IPC event by number. + /// + /// # Safety + /// + /// The event number must not be in use by another [`Event`]. + pub unsafe fn steal(number: EventNumber) -> Self { + Self { + number, + _phantom: PhantomData, + } + } +} - if regs.events_receive(ev as usize).read() & 0x01 == 0x01 { - regs.events_receive(ev as usize).write_value(0x00); +/// A handle that can trigger an IPC event. +/// +/// This `struct` is returned by [`Event::trigger_handle`]. +#[derive(Debug, Copy, Clone)] +pub struct EventTrigger<'d, T: Instance> { + number: EventNumber, + _phantom: PhantomData<&'d T>, +} - Poll::Ready(()) - } else { - Poll::Pending - } - }) - .await; +impl EventTrigger<'_, T> { + /// Trigger the event. + pub fn trigger(&self) { + let nr = self.number; + T::regs().tasks_send(nr as usize).write_value(1); + } + + /// Returns the [`EventNumber`] of the event. + pub fn number(&self) -> EventNumber { + self.number } } pub(crate) struct State { - wakers: [AtomicWaker; 16], + wakers: [AtomicWaker; EVENT_COUNT], } impl State { pub(crate) const fn new() -> Self { - const WAKER: AtomicWaker = AtomicWaker::new(); - - Self { wakers: [WAKER; 16] } - } - - const fn waker_for(&self, ev: IpcEvent) -> &AtomicWaker { - match ev { - IpcEvent::Event0 => &self.wakers[0], - IpcEvent::Event1 => &self.wakers[1], - IpcEvent::Event2 => &self.wakers[2], - IpcEvent::Event3 => &self.wakers[3], - IpcEvent::Event4 => &self.wakers[4], - IpcEvent::Event5 => &self.wakers[5], - IpcEvent::Event6 => &self.wakers[6], - IpcEvent::Event7 => &self.wakers[7], - IpcEvent::Event8 => &self.wakers[8], - IpcEvent::Event9 => &self.wakers[9], - IpcEvent::Event10 => &self.wakers[10], - IpcEvent::Event11 => &self.wakers[11], - IpcEvent::Event12 => &self.wakers[12], - IpcEvent::Event13 => &self.wakers[13], - IpcEvent::Event14 => &self.wakers[14], - IpcEvent::Event15 => &self.wakers[15], + Self { + wakers: [const { AtomicWaker::new() }; EVENT_COUNT], } } } @@ -336,7 +339,7 @@ pub(crate) trait SealedInstance { /// IPC peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: PeripheralType + SealedInstance + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } -- cgit From 133500167ca53cfbc5e9268356753bc0e3f8c209 Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Mon, 12 May 2025 09:45:05 +0200 Subject: limit CoreVoltage eum to values up to 1.30V, because we do not support unlocking higher voltages --- embassy-rp/src/clocks.rs | 141 +++++++---------------------------------------- 1 file changed, 21 insertions(+), 120 deletions(-) diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index ea5e9362b..bcd08c204 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -140,6 +140,10 @@ pub enum PeriClkSrc { /// /// The voltage regulator can be configured for different output voltages. /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. +/// +/// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit +/// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this +/// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u8)] pub enum CoreVoltage { @@ -227,54 +231,6 @@ pub enum CoreVoltage { #[cfg(feature = "_rp235x")] /// RP235x: 1.30V V1_30 = 0b01111, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.35V - V1_35 = 0b10000, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.40V - V1_40 = 0b10001, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.50V - V1_50 = 0b10010, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.60V - V1_60 = 0b10011, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.65V - V1_65 = 0b10100, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.70V - V1_70 = 0b10101, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.80V - V1_80 = 0b10110, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.90V - V1_90 = 0b10111, - #[cfg(feature = "_rp235x")] - /// RP235x: 2.00V - V2_00 = 0b11000, - #[cfg(feature = "_rp235x")] - /// RP235x: 2.35V - V2_35 = 0b11001, - #[cfg(feature = "_rp235x")] - /// RP235x: 2.50V - V2_50 = 0b11010, - #[cfg(feature = "_rp235x")] - /// RP235x: 2.65V - V2_65 = 0b11011, - #[cfg(feature = "_rp235x")] - /// RP235x: 2.80V - V2_80 = 0b11100, - #[cfg(feature = "_rp235x")] - /// RP235x: 3.00V - V3_00 = 0b11101, - #[cfg(feature = "_rp235x")] - /// RP235x: 3.15V - V3_15 = 0b11110, - #[cfg(feature = "_rp235x")] - /// RP235x: 3.30V - V3_30 = 0b11111, } impl CoreVoltage { @@ -313,13 +269,7 @@ impl CoreVoltage { CoreVoltage::V1_20 => 0b01010, // 0.903V (~75% of 1.20V) CoreVoltage::V1_25 => 0b01010, // 0.903V (~72% of 1.25V) CoreVoltage::V1_30 => 0b01011, // 0.946V (~73% of 1.30V) - CoreVoltage::V1_35 => 0b01011, // 0.946V (~70% of 1.35V) - CoreVoltage::V1_40 => 0b01100, // 0.989V (~71% of 1.40V) - CoreVoltage::V1_50 => 0b01101, // 1.032V (~69% of 1.50V) - CoreVoltage::V1_60 => 0b01110, // 1.075V (~67% of 1.60V) - CoreVoltage::V1_65 => 0b01110, // 1.075V (~65% of 1.65V) - CoreVoltage::V1_70 => 0b01111, // 1.118V (~66% of 1.70V) - _ => 0b10000, // the rp2350 datasheet repeats this value for all other core voltages + // all others: 0.946V (see CoreVoltage: we do not support setting Voltages higher than 1.30V at this point) } } } @@ -1083,45 +1033,17 @@ pub(crate) unsafe fn init(config: ClockConfig) { // If the target voltage is different from the current one, we need to change it if target_vsel != current_vsel { + // Set the voltage regulator to the target voltage #[cfg(feature = "rp2040")] - { - // Use modify() to preserve the HIZ and EN bits - otherwise we will disable the regulator when changing voltage - vreg.vreg().modify(|w| w.set_vsel(target_vsel)); - } + vreg.vreg().modify(|w| w.set_vsel(target_vsel)); #[cfg(feature = "_rp235x")] - { - // The rp235x has a different way of controlling the voltage regulator - // Changes to the voltage regulator are protected by a password, see datasheet section 6.4 - // The password is "5AFE" (0x5AFE), it must be set in the top 16 bits of the register - - // The rp235x by default locks the voltage regulator control, so we need to unlock it first - // See datasheet section 6.3.2. Software Control - vreg.vreg_ctrl().modify(|w| { - // Add password to top 16 bits, preserving the rest, repeat below for other registers - w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); - w.set_unlock(true); - *w - }); - - // Set the voltage - vreg.vreg().modify(|w| { - w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); - w.set_vsel(target_vsel); - *w - }); - - // The rp235x has two more registers to set the voltage for low power mode - vreg.vreg_lp_entry().modify(|w| { - w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); - w.set_vsel(target_vsel); - *w - }); - vreg.vreg_lp_exit().modify(|w| { - w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); - w.set_vsel(target_vsel); - *w - }); - } + // For rp235x changes to the voltage regulator are protected by a password, see datasheet section 6.4 Power Management (POWMAN) Registers + // The password is "5AFE" (0x5AFE), it must be set in the top 16 bits of the register + vreg.vreg().modify(|w| { + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); // Set the password + w.set_vsel(target_vsel); + *w + }); // Wait for the voltage to stabilize. Use the provided delay or default based on voltage let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| { @@ -1140,23 +1062,17 @@ pub(crate) unsafe fn init(config: ClockConfig) { } // Only now set the BOD level. At this point the voltage is considered stable. + #[cfg(feature = "rp2040")] vreg.bod().write(|w| { w.set_vsel(voltage.recommended_bod()); w.set_en(true); // Enable brownout detection }); - #[cfg(feature = "_rp235x")] - { - // The rp235x has a separate register for the BOD level in low power mode - vreg.bod_lp_entry().write(|w| { - w.set_vsel(voltage.recommended_bod()); - w.set_en(true); // Enable brownout detection - }); - vreg.bod_lp_exit().write(|w| { - w.set_vsel(voltage.recommended_bod()); - w.set_en(true); // Enable brownout detection - }); - } + vreg.bod().write(|w| { + w.0 = (w.0 & 0x0000FFFF) | (0x5AFE << 16); // Set the password + w.set_vsel(voltage.recommended_bod()); + w.set_en(true); // Enable brownout detection + }); } } @@ -1527,23 +1443,8 @@ pub fn core_voltage() -> Result { 0b01101 => Ok(CoreVoltage::V1_20), 0b01110 => Ok(CoreVoltage::V1_25), 0b01111 => Ok(CoreVoltage::V1_30), - 0b10000 => Ok(CoreVoltage::V1_35), - 0b10001 => Ok(CoreVoltage::V1_40), - 0b10010 => Ok(CoreVoltage::V1_50), - 0b10011 => Ok(CoreVoltage::V1_60), - 0b10100 => Ok(CoreVoltage::V1_65), - 0b10101 => Ok(CoreVoltage::V1_70), - 0b10110 => Ok(CoreVoltage::V1_80), - 0b10111 => Ok(CoreVoltage::V1_90), - 0b11000 => Ok(CoreVoltage::V2_00), - 0b11001 => Ok(CoreVoltage::V2_35), - 0b11010 => Ok(CoreVoltage::V2_50), - 0b11011 => Ok(CoreVoltage::V2_65), - 0b11100 => Ok(CoreVoltage::V2_80), - 0b11101 => Ok(CoreVoltage::V3_00), - 0b11110 => Ok(CoreVoltage::V3_15), - 0b11111 => Ok(CoreVoltage::V3_30), _ => Err("Unexpected value in register"), + // see CoreVoltage: we do not support setting Voltages higher than 1.30V at this point } } } -- cgit From 3c73b497909ce5bacd16d23e54928a7f66544e09 Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Mon, 12 May 2025 15:51:19 +0200 Subject: [embassy-usb-dfu] support function level WinUSB GUIDs This commit makes it possible to provide function level msos GUIDs to usb_dfu. This helps to ensure that composite DFU devices automatically get assigned the WinUSB driver on Windows. --- embassy-usb-dfu/src/application.rs | 16 +++++++++++++- embassy-usb-dfu/src/dfu.rs | 16 +++++++++++++- examples/boot/application/stm32wb-dfu/src/main.rs | 26 +++++++++++++++++++++-- examples/boot/bootloader/stm32wb-dfu/src/main.rs | 15 +++++++++---- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs index 6ad07a78c..52a7ca951 100644 --- a/embassy-usb-dfu/src/application.rs +++ b/embassy-usb-dfu/src/application.rs @@ -2,7 +2,7 @@ use embassy_boot::BlockingFirmwareState; use embassy_time::{Duration, Instant}; use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; use embassy_usb::driver::Driver; -use embassy_usb::{Builder, Handler}; +use embassy_usb::{msos, Builder, Handler}; use embedded_storage::nor_flash::NorFlash; use crate::consts::{ @@ -130,8 +130,22 @@ pub fn usb_dfu<'d, D: Driver<'d>, MARK: DfuMarker, RST: Reset>( builder: &mut Builder<'d, D>, handler: &'d mut Control, timeout: Duration, + winusb_guids: Option<&'d [&str]>, ) { let mut func = builder.function(0x00, 0x00, 0x00); + if let Some(winusb_guids) = winusb_guids { + // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. + // Otherwise users need to do this manually using a tool like Zadig. + // + // Adding them here on the function level appears to only work for compositive devices though. + // For non-composite devices they should be placed on the device level instead. + func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(winusb_guids), + )); + } + let mut iface = func.interface(); let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); let timeout = timeout.as_millis() as u16; diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs index a98d6ab40..83feacaf8 100644 --- a/embassy-usb-dfu/src/dfu.rs +++ b/embassy-usb-dfu/src/dfu.rs @@ -1,7 +1,7 @@ use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError}; use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; use embassy_usb::driver::Driver; -use embassy_usb::{Builder, Handler}; +use embassy_usb::{msos, Builder, Handler}; use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind}; use crate::consts::{ @@ -186,8 +186,22 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>( builder: &mut Builder<'d, D>, handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>, + winusb_guids: Option<&'d [&str]>, ) { let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU); + if let Some(winusb_guids) = winusb_guids { + // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. + // Otherwise users need to do this manually using a tool like Zadig. + // + // Adding them here on the function level appears to only work for compositive devices though. + // For non-composite devices they should be placed on the device level instead. + func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(winusb_guids), + )); + } + let mut iface = func.interface(); let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); alt.descriptor( diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index dda2b795b..68e9bc3f6 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs @@ -13,7 +13,7 @@ use embassy_stm32::usb::{self, Driver}; use embassy_stm32::{bind_interrupts, peripherals}; use embassy_sync::blocking_mutex::Mutex; use embassy_time::Duration; -use embassy_usb::Builder; +use embassy_usb::{msos, Builder}; use embassy_usb_dfu::consts::DfuAttributes; use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate}; use panic_reset as _; @@ -22,6 +22,9 @@ bind_interrupts!(struct Irqs { USB_LP => usb::InterruptHandler; }); +// This is a randomly generated GUID to allow clients on Windows to find our device +const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"]; + #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); @@ -54,7 +57,26 @@ async fn main(_spawner: Spawner) { &mut control_buf, ); - usb_dfu(&mut builder, &mut state, Duration::from_millis(2500)); + // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. + // Otherwise users need to do this manually using a tool like Zadig. + builder.msos_descriptor(msos::windows_version::WIN8_1, 2); + + // In the case of non-composite devices, it seems that feature headers need to be on the device level. + // (As is implemented here) + // + // For composite devices however, they should be on the function level instead. + // (This is achieved by passing a GUID to the "usb_dfu" function) + builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + + // For non-composite devices: + usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), None); + + // Or for composite devices: + // usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), Some(DEVICE_INTERFACE_GUIDS)); let mut dev = builder.build(); dev.run().await diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index 28216806e..2cd7f859d 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs @@ -67,17 +67,24 @@ fn main() -> ! { // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. // Otherwise users need to do this manually using a tool like Zadig. - // - // It seems it is important for the DFU class that these headers be on the Device level. - // builder.msos_descriptor(msos::windows_version::WIN8_1, 2); + + // In the case of non-composite devices, it seems that feature headers need to be on the device level. + // (As is implemented here) + // + // For composite devices however, they should be on the function level instead. + // (This is achieved by passing a GUID to the "usb_dfu" function) builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( "DeviceInterfaceGUIDs", msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), )); - usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state); + // For non-composite devices: + usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, None); + + // Or for composite devices: + // usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, Some(DEVICE_INTERFACE_GUIDS)); let mut dev = builder.build(); embassy_futures::block_on(dev.run()); -- cgit From 79e452922a6b467f2e8547a6b28698ed5f409705 Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Mon, 12 May 2025 21:33:47 +0200 Subject: Add ClockError enum and update system_freq to return Result for error handling --- embassy-rp/src/clocks.rs | 66 +++++++++++++++++++++++++----------- examples/rp/src/bin/overclock.rs | 2 +- examples/rp235x/src/bin/overclock.rs | 2 +- tests/rp/src/bin/overclock.rs | 2 +- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index bcd08c204..5872ef789 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -82,6 +82,18 @@ use crate::{pac, reset, Peri}; // be very useful until we have runtime clock reconfiguration. once this // happens we can resurrect the commented-out gpin bits. +/// Clock error types. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClockError { + /// PLL failed to lock within the timeout period. + PllLockTimedOut, + /// Could not find valid PLL parameters for system clock. + InvalidPllParameters, + /// Reading the core voltage failed due to an unexpected value in the register. + UnexpectedCoreVoltageRead, +} + struct Clocks { xosc: AtomicU32, sys: AtomicU32, @@ -144,8 +156,9 @@ pub enum PeriClkSrc { /// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit /// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this /// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u8)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum CoreVoltage { // RP2040 voltage levels #[cfg(feature = "rp2040")] @@ -468,7 +481,7 @@ impl ClockConfig { /// # Returns /// /// A ClockConfig configured to achieve the requested system frequency using the - /// the usual 12Mhz crystal, or panic if no valid parameters can be found. + /// the usual 12Mhz crystal, or an error if no valid parameters can be found. /// /// # Note on core voltage: /// @@ -482,7 +495,11 @@ impl ClockConfig { /// **For RP235x**: /// At this point in time there is no official manufacturer endorsement for running the chip on other core voltages and/or other clock speeds than the defaults. /// Using this function is experimental and may not work as expected or even damage the chip. - pub fn system_freq(hz: u32) -> Self { + /// + /// # Returns + /// + /// A Result containing either the configured ClockConfig or a ClockError. + pub fn system_freq(hz: u32) -> Result { // Start with the standard configuration from crystal() const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000; let mut config = Self::crystal(DEFAULT_CRYSTAL_HZ); @@ -491,16 +508,15 @@ impl ClockConfig { // (which is what crystal() configures by default) #[cfg(feature = "rp2040")] if hz == 125_000_000 { - return config; + return Ok(config); } #[cfg(feature = "_rp235x")] if hz == 150_000_000 { - return config; + return Ok(config); } // Find optimal PLL parameters for the requested frequency - let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, hz) - .unwrap_or_else(|| panic!("Could not find valid PLL parameters for system clock")); + let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, hz).ok_or(ClockError::InvalidPllParameters)?; // Replace the sys_pll configuration with our custom parameters if let Some(xosc) = &mut config.xosc { @@ -525,7 +541,7 @@ impl ClockConfig { }; } - config + Ok(config) } /// Configure with manual PLL settings for full control over system clock @@ -620,6 +636,7 @@ impl ClockConfig { #[repr(u16)] #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum RoscRange { /// Low range. Low = pac::rosc::vals::FreqRange::LOW.0, @@ -726,6 +743,7 @@ pub struct RefClkConfig { /// Reference clock source. #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum RefClkSrc { /// XOSC. Xosc, @@ -741,6 +759,7 @@ pub enum RefClkSrc { /// SYS clock source. #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SysClkSrc { /// REF. Ref, @@ -779,6 +798,7 @@ pub struct SysClkConfig { #[repr(u8)] #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum UsbClkSrc { /// PLL USB. PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB as _, @@ -807,6 +827,7 @@ pub struct UsbClkConfig { #[repr(u8)] #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum AdcClkSrc { /// PLL USB. PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB as _, @@ -835,6 +856,7 @@ pub struct AdcClkConfig { #[repr(u8)] #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg(feature = "rp2040")] pub enum RtcClkSrc { /// PLL USB. @@ -1084,14 +1106,20 @@ pub(crate) unsafe fn init(config: ClockConfig) { let pll_sys_freq = match config.sys_pll { Some(sys_pll_config) => match configure_pll(pac::PLL_SYS, config.hz, sys_pll_config) { Ok(freq) => freq, + #[cfg(feature = "defmt")] Err(e) => panic!("Failed to configure PLL_SYS: {}", e), + #[cfg(not(feature = "defmt"))] + Err(_e) => panic!("Failed to configure PLL_SYS"), }, None => 0, }; let pll_usb_freq = match config.usb_pll { Some(usb_pll_config) => match configure_pll(pac::PLL_USB, config.hz, usb_pll_config) { Ok(freq) => freq, + #[cfg(feature = "defmt")] Err(e) => panic!("Failed to configure PLL_USB: {}", e), + #[cfg(not(feature = "defmt"))] + Err(_e) => panic!("Failed to configure PLL_USB"), }, None => 0, }; @@ -1401,7 +1429,7 @@ pub fn clk_rtc_freq() -> u16 { /// /// Returns the current core voltage or an error if the voltage register /// contains an unknown value. -pub fn core_voltage() -> Result { +pub fn core_voltage() -> Result { #[cfg(feature = "rp2040")] { let vreg = pac::VREG_AND_CHIP_RESET; @@ -1418,7 +1446,7 @@ pub fn core_voltage() -> Result { 0b1101 => Ok(CoreVoltage::V1_20), 0b1110 => Ok(CoreVoltage::V1_25), 0b1111 => Ok(CoreVoltage::V1_30), - _ => Err("Unexpected value in register"), + _ => Err(ClockError::UnexpectedCoreVoltageRead), } } @@ -1443,7 +1471,7 @@ pub fn core_voltage() -> Result { 0b01101 => Ok(CoreVoltage::V1_20), 0b01110 => Ok(CoreVoltage::V1_25), 0b01111 => Ok(CoreVoltage::V1_30), - _ => Err("Unexpected value in register"), + _ => Err(ClockError::UnexpectedCoreVoltageRead), // see CoreVoltage: we do not support setting Voltages higher than 1.30V at this point } } @@ -1461,7 +1489,7 @@ fn start_xosc(crystal_hz: u32, delay_multiplier: u32) { /// PLL (Phase-Locked Loop) configuration #[inline(always)] -fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result { +fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result { // Calculate reference frequency let ref_freq = input_freq / config.refdiv as u32; @@ -1532,7 +1560,7 @@ fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result timeout -= 1; if timeout == 0 { // PLL failed to lock, return 0 to indicate failure - return Err("PLL failed to lock"); + return Err(ClockError::PllLockTimedOut); } } @@ -2103,21 +2131,21 @@ mod tests { { // Test automatic voltage scaling based on frequency // Under 133 MHz should use default voltage (V1_10) - let config = ClockConfig::system_freq(125_000_000); + let config = ClockConfig::system_freq(125_000_000).unwrap(); assert_eq!(config.core_voltage, CoreVoltage::V1_10); // 133-200 MHz should use V1_15 - let config = ClockConfig::system_freq(150_000_000); + let config = ClockConfig::system_freq(150_000_000).unwrap(); assert_eq!(config.core_voltage, CoreVoltage::V1_15); - let config = ClockConfig::system_freq(200_000_000); + let config = ClockConfig::system_freq(200_000_000).unwrap(); assert_eq!(config.core_voltage, CoreVoltage::V1_15); - // Above 200 MHz should use V1_25 - let config = ClockConfig::system_freq(250_000_000); + // Above 200 MHz should use V1_15 + let config = ClockConfig::system_freq(250_000_000).unwrap(); assert_eq!(config.core_voltage, CoreVoltage::V1_15); // Below 125 MHz should use V1_10 - let config = ClockConfig::system_freq(100_000_000); + let config = ClockConfig::system_freq(100_000_000).unwrap(); assert_eq!(config.core_voltage, CoreVoltage::V1_10); } } diff --git a/examples/rp/src/bin/overclock.rs b/examples/rp/src/bin/overclock.rs index 89147ba42..2706399af 100644 --- a/examples/rp/src/bin/overclock.rs +++ b/examples/rp/src/bin/overclock.rs @@ -18,7 +18,7 @@ const COUNT_TO: i64 = 10_000_000; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { // Set up for clock frequency of 200 MHz, setting all necessary defaults. - let config = Config::new(ClockConfig::system_freq(200_000_000)); + let config = Config::new(ClockConfig::system_freq(200_000_000).unwrap()); // Initialize the peripherals let p = embassy_rp::init(config); diff --git a/examples/rp235x/src/bin/overclock.rs b/examples/rp235x/src/bin/overclock.rs index 8713df688..178fd62ca 100644 --- a/examples/rp235x/src/bin/overclock.rs +++ b/examples/rp235x/src/bin/overclock.rs @@ -23,7 +23,7 @@ const COUNT_TO: i64 = 10_000_000; #[embassy_executor::main] async fn main(_spawner: Spawner) -> ! { // Set up for clock frequency of 200 MHz, setting all necessary defaults. - let mut config = Config::new(ClockConfig::system_freq(200_000_000)); + let mut config = Config::new(ClockConfig::system_freq(200_000_000).unwrap()); // since for the rp235x there is no official support for higher clock frequencies, `system_freq()` will not set a voltage for us. // We need to guess the core voltage, that is needed for the higher clock frequency. Going with a small increase from the default 1.1V here, based on diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs index a568d7fed..167a26eb2 100644 --- a/tests/rp/src/bin/overclock.rs +++ b/tests/rp/src/bin/overclock.rs @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); // Initialize with 200MHz clock configuration - config.clocks = ClockConfig::system_freq(200_000_000); + config.clocks = ClockConfig::system_freq(200_000_000).unwrap(); // if we are rp235x, we need to manually set the core voltage. rp2040 should do this automatically #[cfg(feature = "rp235xb")] -- cgit From be1b679d48b5d781f888fb97c1fed7479235019b Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Mon, 12 May 2025 21:42:03 +0200 Subject: Refactor CoreVoltage enum, separate for rp2040 and rp235x --- embassy-rp/src/clocks.rs | 98 +++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 56 deletions(-) diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 5872ef789..3975e7e79 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -156,93 +156,79 @@ pub enum PeriClkSrc { /// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit /// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this /// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. +#[cfg(feature = "rp2040")] #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum CoreVoltage { - // RP2040 voltage levels - #[cfg(feature = "rp2040")] - /// RP2040: 0.80V + /// 0.80V V0_80 = 0b0000, - #[cfg(feature = "rp2040")] - /// RP2040: 0.85V + /// 0.85V V0_85 = 0b0110, - #[cfg(feature = "rp2040")] - /// RP2040: 0.90V + /// 0.90V V0_90 = 0b0111, - #[cfg(feature = "rp2040")] - /// RP2040: 0.95V + /// 0.95V V0_95 = 0b1000, - #[cfg(feature = "rp2040")] - /// RP2040: 1.00V + /// 1.00V V1_00 = 0b1001, - #[cfg(feature = "rp2040")] - /// RP2040: 1.05V + /// 1.05V V1_05 = 0b1010, - #[cfg(feature = "rp2040")] - /// RP2040: 1.10V - Default voltage level + /// 1.10V - Default voltage level V1_10 = 0b1011, - #[cfg(feature = "rp2040")] - /// RP2040: 1.15V - Required for overclocking to 133-200MHz + /// 1.15V - Required for overclocking to 133-200MHz V1_15 = 0b1100, - #[cfg(feature = "rp2040")] - /// RP2040: 1.20V + /// 1.20V V1_20 = 0b1101, - #[cfg(feature = "rp2040")] - /// RP2040: 1.25V + /// 1.25V V1_25 = 0b1110, - #[cfg(feature = "rp2040")] - /// RP2040: 1.30V + /// 1.30V V1_30 = 0b1111, +} - // RP235x voltage levels - #[cfg(feature = "_rp235x")] - /// RP235x: 0.55V +/// Core voltage regulator settings. +/// +/// The voltage regulator can be configured for different output voltages. +/// Higher voltages allow for higher clock frequencies but increase power consumption and heat. +/// +/// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit +/// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this +/// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. +#[cfg(feature = "_rp235x")] +#[repr(u8)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum CoreVoltage { + /// 0.55V V0_55 = 0b00000, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.60V + /// 0.60V V0_60 = 0b00001, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.65V + /// 0.65V V0_65 = 0b00010, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.70V + /// 0.70V V0_70 = 0b00011, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.75V + /// 0.75V V0_75 = 0b00100, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.80V + /// 0.80V V0_80 = 0b00101, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.85V + /// 0.85V V0_85 = 0b00110, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.90V + /// 0.90V V0_90 = 0b00111, - #[cfg(feature = "_rp235x")] - /// RP235x: 0.95V + /// 0.95V V0_95 = 0b01000, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.00V + /// 1.00V V1_00 = 0b01001, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.05V + /// 1.05V V1_05 = 0b01010, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.10V - Default voltage level + /// 1.10V - Default voltage level V1_10 = 0b01011, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.15V + /// 1.15V V1_15 = 0b01100, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.20V + /// 1.20V V1_20 = 0b01101, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.25V + /// 1.25V V1_25 = 0b01110, - #[cfg(feature = "_rp235x")] - /// RP235x: 1.30V + /// 1.30V V1_30 = 0b01111, } -- cgit From abafbed0d5fba70ab5d0096b9d381577d2f880c8 Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Mon, 12 May 2025 21:43:17 +0200 Subject: remove Debug2Fmt from examples --- examples/rp/src/bin/overclock.rs | 2 +- examples/rp/src/bin/overclock_manual.rs | 2 +- examples/rp235x/src/bin/overclock.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/rp/src/bin/overclock.rs b/examples/rp/src/bin/overclock.rs index 2706399af..83b17308b 100644 --- a/examples/rp/src/bin/overclock.rs +++ b/examples/rp/src/bin/overclock.rs @@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) -> ! { info!("System clock frequency: {} MHz", sys_freq / 1_000_000); // Show core voltage for verification let core_voltage = core_voltage().unwrap(); - info!("Core voltage: {}", Debug2Format(&core_voltage)); + info!("Core voltage: {}", core_voltage); // LED to indicate the system is running let mut led = Output::new(p.PIN_25, Level::Low); diff --git a/examples/rp/src/bin/overclock_manual.rs b/examples/rp/src/bin/overclock_manual.rs index 88ef26a7a..dea5cfb3c 100644 --- a/examples/rp/src/bin/overclock_manual.rs +++ b/examples/rp/src/bin/overclock_manual.rs @@ -45,7 +45,7 @@ async fn main(_spawner: Spawner) -> ! { info!("System clock frequency: {} MHz", sys_freq / 1_000_000); // Show core voltage for verification let core_voltage = core_voltage().unwrap(); - info!("Core voltage: {}", Debug2Format(&core_voltage)); + info!("Core voltage: {}", core_voltage); // LED to indicate the system is running let mut led = Output::new(p.PIN_25, Level::Low); diff --git a/examples/rp235x/src/bin/overclock.rs b/examples/rp235x/src/bin/overclock.rs index 178fd62ca..5fd97ef97 100644 --- a/examples/rp235x/src/bin/overclock.rs +++ b/examples/rp235x/src/bin/overclock.rs @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) -> ! { info!("System clock frequency: {} MHz", sys_freq / 1_000_000); // Show core voltage for verification let core_voltage = core_voltage().unwrap(); - info!("Core voltage: {}", Debug2Format(&core_voltage)); + info!("Core voltage: {}", core_voltage); // LED to indicate the system is running let mut led = Output::new(p.PIN_25, Level::Low); -- cgit From 1314808b3a39d856d33655504db00d799914c440 Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Tue, 13 May 2025 10:49:23 +0200 Subject: Changes after review: copypasted doc comment fixed and no cfg gates to panic on failing pll config in init() --- embassy-rp/src/clocks.rs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 3975e7e79..47e71c448 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -152,11 +152,6 @@ pub enum PeriClkSrc { /// /// The voltage regulator can be configured for different output voltages. /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. -/// -/// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit -/// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this -/// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. -#[cfg(feature = "rp2040")] #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -190,7 +185,7 @@ pub enum CoreVoltage { /// The voltage regulator can be configured for different output voltages. /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. /// -/// **Note**: For RP235x the maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit +/// **Note**: The maximum voltage is 1.30V, unless unlocked by setting unless the voltage limit /// is disabled using the disable_voltage_limit field in the vreg_ctrl register. For lack of practical use at this /// point in time, this is not implemented here. So the maximum voltage in this enum is 1.30V for now. #[cfg(feature = "_rp235x")] @@ -1092,20 +1087,14 @@ pub(crate) unsafe fn init(config: ClockConfig) { let pll_sys_freq = match config.sys_pll { Some(sys_pll_config) => match configure_pll(pac::PLL_SYS, config.hz, sys_pll_config) { Ok(freq) => freq, - #[cfg(feature = "defmt")] - Err(e) => panic!("Failed to configure PLL_SYS: {}", e), - #[cfg(not(feature = "defmt"))] - Err(_e) => panic!("Failed to configure PLL_SYS"), + Err(e) => panic!("Failed to configure PLL_SYS: {:?}", e), }, None => 0, }; let pll_usb_freq = match config.usb_pll { Some(usb_pll_config) => match configure_pll(pac::PLL_USB, config.hz, usb_pll_config) { Ok(freq) => freq, - #[cfg(feature = "defmt")] - Err(e) => panic!("Failed to configure PLL_USB: {}", e), - #[cfg(not(feature = "defmt"))] - Err(_e) => panic!("Failed to configure PLL_USB"), + Err(e) => panic!("Failed to configure PLL_USB: {:?}", e), }, None => 0, }; -- cgit From 981ef20f83ec88601818d8c55f69a1037d57b0cb Mon Sep 17 00:00:00 2001 From: 1-rafael-1 Date: Tue, 13 May 2025 10:59:11 +0200 Subject: removed one line too many --- embassy-rp/src/clocks.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 47e71c448..857877680 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -152,6 +152,7 @@ pub enum PeriClkSrc { /// /// The voltage regulator can be configured for different output voltages. /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. +#[cfg(feature = "rp2040")] #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -- cgit From 46e25cbc5ff62e24f86574d7ae5d872aa0c2595d Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Tue, 13 May 2025 15:09:53 +0200 Subject: [embassy-usb-dfu] correct comment about composite devices --- embassy-usb-dfu/src/application.rs | 5 +++-- embassy-usb-dfu/src/dfu.rs | 5 +++-- examples/boot/application/stm32wb-dfu/src/main.rs | 10 ++++------ examples/boot/bootloader/stm32wb-dfu/src/main.rs | 10 ++++------ 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs index 52a7ca951..2646d100d 100644 --- a/embassy-usb-dfu/src/application.rs +++ b/embassy-usb-dfu/src/application.rs @@ -137,8 +137,9 @@ pub fn usb_dfu<'d, D: Driver<'d>, MARK: DfuMarker, RST: Reset>( // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. // Otherwise users need to do this manually using a tool like Zadig. // - // Adding them here on the function level appears to only work for compositive devices though. - // For non-composite devices they should be placed on the device level instead. + // Adding them here on the function level appears to only be needed for compositive devices. + // In addition to being on the function level, they should also be added to the device level. + // func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( "DeviceInterfaceGUIDs", diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs index 83feacaf8..43a35637d 100644 --- a/embassy-usb-dfu/src/dfu.rs +++ b/embassy-usb-dfu/src/dfu.rs @@ -193,8 +193,9 @@ pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, co // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. // Otherwise users need to do this manually using a tool like Zadig. // - // Adding them here on the function level appears to only work for compositive devices though. - // For non-composite devices they should be placed on the device level instead. + // Adding them here on the function level appears to only be needed for compositive devices. + // In addition to being on the function level, they should also be added to the device level. + // func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( "DeviceInterfaceGUIDs", diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index 68e9bc3f6..6236dfe52 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs @@ -59,13 +59,11 @@ async fn main(_spawner: Spawner) { // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. // Otherwise users need to do this manually using a tool like Zadig. - builder.msos_descriptor(msos::windows_version::WIN8_1, 2); - - // In the case of non-composite devices, it seems that feature headers need to be on the device level. - // (As is implemented here) // - // For composite devices however, they should be on the function level instead. - // (This is achieved by passing a GUID to the "usb_dfu" function) + // It seems these always need to be at added at the device level for this to work and for + // composite devices they also need to be added on the function level (as shown later). + // + builder.msos_descriptor(msos::windows_version::WIN8_1, 2); builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( "DeviceInterfaceGUIDs", diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index 2cd7f859d..8cfd4daa7 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs @@ -67,13 +67,11 @@ fn main() -> ! { // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. // Otherwise users need to do this manually using a tool like Zadig. - builder.msos_descriptor(msos::windows_version::WIN8_1, 2); - - // In the case of non-composite devices, it seems that feature headers need to be on the device level. - // (As is implemented here) // - // For composite devices however, they should be on the function level instead. - // (This is achieved by passing a GUID to the "usb_dfu" function) + // It seems these always need to be at added at the device level for this to work and for + // composite devices they also need to be added on the function level (as shown later). + // + builder.msos_descriptor(msos::windows_version::WIN8_1, 2); builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( "DeviceInterfaceGUIDs", -- cgit From edcbfeb15257e93557a73b9aac3a8ee92a273e32 Mon Sep 17 00:00:00 2001 From: Marvin Gudel Date: Tue, 13 May 2025 22:36:28 +0200 Subject: Make bit-depth of I2S PIO program configurable Also the channel argument is removed, since only 2 channels are supported. --- embassy-rp/src/pio_programs/i2s.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs index b967f0160..7ceed3fa6 100644 --- a/embassy-rp/src/pio_programs/i2s.rs +++ b/embassy-rp/src/pio_programs/i2s.rs @@ -9,6 +9,10 @@ use crate::pio::{ use crate::Peri; /// This struct represents an i2s output driver program +/// +/// The sample bit-depth is set through scratch register `Y`. +/// `Y` has to be set to sample bit-depth - 2. +/// (14 = 16bit, 22 = 24bit, 30 = 32bit) pub struct PioI2sOutProgram<'d, PIO: Instance> { prg: LoadedProgram<'d, PIO>, } @@ -17,13 +21,13 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> { /// Load the program into the given pio pub fn new(common: &mut Common<'d, PIO>) -> Self { let prg = pio::pio_asm!( - ".side_set 2", - " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock + ".side_set 2", // side 0bWB - W = Word Clock, B = Bit Clock + " mov x, y side 0b01", // y stores sample depth - 2 (14 = 16bit, 22 = 24bit, 30 = 32bit) "left_data:", " out pins, 1 side 0b00", " jmp x-- left_data side 0b01", " out pins 1 side 0b10", - " set x, 14 side 0b11", + " mov x, y side 0b11", "right_data:", " out pins 1 side 0b10", " jmp x-- right_data side 0b11", @@ -53,7 +57,6 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { lr_clock_pin: Peri<'d, impl PioPin>, sample_rate: u32, bit_depth: u32, - channels: u32, program: &PioI2sOutProgram<'d, P>, ) -> Self { let data_pin = common.make_pio_pin(data_pin); @@ -64,7 +67,7 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { let mut cfg = Config::default(); cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]); cfg.set_out_pins(&[&data_pin]); - let clock_frequency = sample_rate * bit_depth * channels; + let clock_frequency = sample_rate * bit_depth * 2; cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed(); cfg.shift_out = ShiftConfig { threshold: 32, @@ -78,6 +81,11 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { sm.set_config(&cfg); sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]); + // Set the `y` register up to configure the sample depth + // The SM counts down to 0 and uses one clock cycle to set up the counter, + // which results in bit_depth - 2 as register value. + unsafe { sm.set_y(bit_depth - 2) }; + sm.set_enable(true); Self { dma: dma.into(), sm } -- cgit From fd9ed3924c5a7c4ef4f9bc4b8a4f934ad2bcc486 Mon Sep 17 00:00:00 2001 From: Marvin Gudel Date: Tue, 13 May 2025 22:49:35 +0200 Subject: Fix example --- examples/rp/src/bin/pio_i2s.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs index 192c8f854..695a74cc3 100644 --- a/examples/rp/src/bin/pio_i2s.rs +++ b/examples/rp/src/bin/pio_i2s.rs @@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs { const SAMPLE_RATE: u32 = 48_000; const BIT_DEPTH: u32 = 16; -const CHANNELS: u32 = 2; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) { left_right_clock_pin, SAMPLE_RATE, BIT_DEPTH, - CHANNELS, &program, ); -- cgit From 58383465d52b45016f88aa6af081f60d67d2b123 Mon Sep 17 00:00:00 2001 From: Marvin Gudel Date: Tue, 13 May 2025 23:30:55 +0200 Subject: Fix example for rp235x --- examples/rp235x/src/bin/pio_i2s.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/rp235x/src/bin/pio_i2s.rs b/examples/rp235x/src/bin/pio_i2s.rs index 5a4bcfcac..cfcb0221d 100644 --- a/examples/rp235x/src/bin/pio_i2s.rs +++ b/examples/rp235x/src/bin/pio_i2s.rs @@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs { const SAMPLE_RATE: u32 = 48_000; const BIT_DEPTH: u32 = 16; -const CHANNELS: u32 = 2; #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) { left_right_clock_pin, SAMPLE_RATE, BIT_DEPTH, - CHANNELS, &program, ); -- cgit From f41e8c45f68ca31819ea1b1eae5fbd019bf8f318 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 13 May 2025 21:55:50 -0500 Subject: mspm0: generate feature per chip + package --- ci.sh | 10 +-- embassy-mspm0/Cargo.toml | 140 +++++++++++++++++++++++++++++++++-- embassy-mspm0/README.md | 28 +++++++ embassy-mspm0/build.rs | 87 ++++++++++++++++++++-- embassy-mspm0/src/gpio.rs | 4 +- embassy-mspm0/src/int_group/g150x.rs | 51 +++++++++++++ embassy-mspm0/src/lib.rs | 17 +++-- examples/mspm0c1104/Cargo.toml | 2 +- examples/mspm0c1104/README.md | 4 +- examples/mspm0g3507/Cargo.toml | 2 +- examples/mspm0g3507/README.md | 4 +- examples/mspm0g3519/Cargo.toml | 2 +- examples/mspm0g3519/README.md | 4 +- examples/mspm0l1306/Cargo.toml | 2 +- examples/mspm0l1306/README.md | 4 +- examples/mspm0l2228/Cargo.toml | 2 +- examples/mspm0l2228/README.md | 4 +- tests/mspm0/Cargo.toml | 2 +- 18 files changed, 326 insertions(+), 43 deletions(-) create mode 100644 embassy-mspm0/README.md create mode 100644 embassy-mspm0/src/int_group/g150x.rs diff --git a/ci.sh b/ci.sh index 6e320e4d1..4e48778da 100755 --- a/ci.sh +++ b/ci.sh @@ -174,11 +174,11 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \ - --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c110x,defmt,time-driver-any \ - --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g350x,defmt,time-driver-any \ - --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g351x,defmt,time-driver-any \ - --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l130x,defmt,time-driver-any \ - --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l222x,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c1104dgs20,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3507pm,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1306rhb,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l2228pn,defmt,time-driver-any \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index df996ff4b..79feee0c2 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -46,14 +46,14 @@ cortex-m = "0.7.6" critical-section = "1.2.0" # mspm0-metapac = { version = "" } -mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a" } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b" } [build-dependencies] proc-macro2 = "1.0.94" quote = "1.0.40" # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } -mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a", default-features = false, features = ["metadata"] } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b", default-features = false, features = ["metadata"] } [features] default = ["rt"] @@ -120,14 +120,138 @@ time-driver-tima0 = ["_time-driver"] time-driver-tima1 = ["_time-driver"] #! ## Chip-selection features -#! Select your chip by specifying the model as a feature, e.g. `mspm0g350x`. +#! Select your chip by specifying the model as a feature, e.g. `mspm0g3507pm`. #! Check the `Cargo.toml` for the latest list of supported chips. #! #! **Important:** Do not forget to adapt the target chip in your toolchain, #! e.g. in `.cargo/config.toml`. -mspm0c110x = [ "mspm0-metapac/mspm0c110x" ] -mspm0g350x = [ "mspm0-metapac/mspm0g350x" ] -mspm0g351x = [ "mspm0-metapac/mspm0g351x" ] -mspm0l130x = [ "mspm0-metapac/mspm0l130x" ] -mspm0l222x = [ "mspm0-metapac/mspm0l222x" ] +mspm0c1103dgs20 = ["mspm0-metapac/mspm0c1103dgs20"] +mspm0c1103dsg = ["mspm0-metapac/mspm0c1103dsg"] +mspm0c1103dyy = ["mspm0-metapac/mspm0c1103dyy"] +mspm0c1103ruk = ["mspm0-metapac/mspm0c1103ruk"] +mspm0c1104dgs20 = ["mspm0-metapac/mspm0c1104dgs20"] +mspm0c1104dsg = ["mspm0-metapac/mspm0c1104dsg"] +mspm0c1104dyy = ["mspm0-metapac/mspm0c1104dyy"] +mspm0c1104ruk = ["mspm0-metapac/mspm0c1104ruk"] +mspm0c1104ycj = ["mspm0-metapac/mspm0c1104ycj"] +mspm0g1105dgs28 = ["mspm0-metapac/mspm0g1105dgs28"] +mspm0g1105pm = ["mspm0-metapac/mspm0g1105pm"] +mspm0g1105pt = ["mspm0-metapac/mspm0g1105pt"] +mspm0g1105rge = ["mspm0-metapac/mspm0g1105rge"] +mspm0g1105rgz = ["mspm0-metapac/mspm0g1105rgz"] +mspm0g1105rhb = ["mspm0-metapac/mspm0g1105rhb"] +mspm0g1106dgs28 = ["mspm0-metapac/mspm0g1106dgs28"] +mspm0g1106pm = ["mspm0-metapac/mspm0g1106pm"] +mspm0g1106pt = ["mspm0-metapac/mspm0g1106pt"] +mspm0g1106rge = ["mspm0-metapac/mspm0g1106rge"] +mspm0g1106rgz = ["mspm0-metapac/mspm0g1106rgz"] +mspm0g1106rhb = ["mspm0-metapac/mspm0g1106rhb"] +mspm0g1107dgs28 = ["mspm0-metapac/mspm0g1107dgs28"] +mspm0g1107pm = ["mspm0-metapac/mspm0g1107pm"] +mspm0g1107pt = ["mspm0-metapac/mspm0g1107pt"] +mspm0g1107rge = ["mspm0-metapac/mspm0g1107rge"] +mspm0g1107rgz = ["mspm0-metapac/mspm0g1107rgz"] +mspm0g1107rhb = ["mspm0-metapac/mspm0g1107rhb"] +mspm0g1107ycj = ["mspm0-metapac/mspm0g1107ycj"] +mspm0g1505pm = ["mspm0-metapac/mspm0g1505pm"] +mspm0g1505pt = ["mspm0-metapac/mspm0g1505pt"] +mspm0g1505rge = ["mspm0-metapac/mspm0g1505rge"] +mspm0g1505rgz = ["mspm0-metapac/mspm0g1505rgz"] +mspm0g1505rhb = ["mspm0-metapac/mspm0g1505rhb"] +mspm0g1506pm = ["mspm0-metapac/mspm0g1506pm"] +mspm0g1506pt = ["mspm0-metapac/mspm0g1506pt"] +mspm0g1506rge = ["mspm0-metapac/mspm0g1506rge"] +mspm0g1506rgz = ["mspm0-metapac/mspm0g1506rgz"] +mspm0g1506rhb = ["mspm0-metapac/mspm0g1506rhb"] +mspm0g1507pm = ["mspm0-metapac/mspm0g1507pm"] +mspm0g1507pt = ["mspm0-metapac/mspm0g1507pt"] +mspm0g1507rge = ["mspm0-metapac/mspm0g1507rge"] +mspm0g1507rgz = ["mspm0-metapac/mspm0g1507rgz"] +mspm0g1507rhb = ["mspm0-metapac/mspm0g1507rhb"] +mspm0g1507ycj = ["mspm0-metapac/mspm0g1507ycj"] +mspm0g1519rgz = ["mspm0-metapac/mspm0g1519rgz"] +mspm0g1519rhb = ["mspm0-metapac/mspm0g1519rhb"] +mspm0g3105dgs20 = ["mspm0-metapac/mspm0g3105dgs20"] +mspm0g3105dgs28 = ["mspm0-metapac/mspm0g3105dgs28"] +mspm0g3105rhb = ["mspm0-metapac/mspm0g3105rhb"] +mspm0g3106dgs20 = ["mspm0-metapac/mspm0g3106dgs20"] +mspm0g3106dgs28 = ["mspm0-metapac/mspm0g3106dgs28"] +mspm0g3106rhb = ["mspm0-metapac/mspm0g3106rhb"] +mspm0g3107dgs20 = ["mspm0-metapac/mspm0g3107dgs20"] +mspm0g3107dgs28 = ["mspm0-metapac/mspm0g3107dgs28"] +mspm0g3107rhb = ["mspm0-metapac/mspm0g3107rhb"] +mspm0g3505dgs28 = ["mspm0-metapac/mspm0g3505dgs28"] +mspm0g3505pm = ["mspm0-metapac/mspm0g3505pm"] +mspm0g3505pt = ["mspm0-metapac/mspm0g3505pt"] +mspm0g3505rgz = ["mspm0-metapac/mspm0g3505rgz"] +mspm0g3505rhb = ["mspm0-metapac/mspm0g3505rhb"] +mspm0g3506dgs28 = ["mspm0-metapac/mspm0g3506dgs28"] +mspm0g3506pm = ["mspm0-metapac/mspm0g3506pm"] +mspm0g3506pt = ["mspm0-metapac/mspm0g3506pt"] +mspm0g3506rgz = ["mspm0-metapac/mspm0g3506rgz"] +mspm0g3506rhb = ["mspm0-metapac/mspm0g3506rhb"] +mspm0g3507dgs28 = ["mspm0-metapac/mspm0g3507dgs28"] +mspm0g3507pm = ["mspm0-metapac/mspm0g3507pm"] +mspm0g3507pt = ["mspm0-metapac/mspm0g3507pt"] +mspm0g3507rgz = ["mspm0-metapac/mspm0g3507rgz"] +mspm0g3507rhb = ["mspm0-metapac/mspm0g3507rhb"] +mspm0g3519pm = ["mspm0-metapac/mspm0g3519pm"] +mspm0g3519pn = ["mspm0-metapac/mspm0g3519pn"] +mspm0g3519pz = ["mspm0-metapac/mspm0g3519pz"] +mspm0g3519rgz = ["mspm0-metapac/mspm0g3519rgz"] +mspm0g3519rhb = ["mspm0-metapac/mspm0g3519rhb"] +mspm0l1105dgs20 = ["mspm0-metapac/mspm0l1105dgs20"] +mspm0l1105dgs28 = ["mspm0-metapac/mspm0l1105dgs28"] +mspm0l1105dyy = ["mspm0-metapac/mspm0l1105dyy"] +mspm0l1105rge = ["mspm0-metapac/mspm0l1105rge"] +mspm0l1105rtr = ["mspm0-metapac/mspm0l1105rtr"] +mspm0l1106dgs20 = ["mspm0-metapac/mspm0l1106dgs20"] +mspm0l1106dgs28 = ["mspm0-metapac/mspm0l1106dgs28"] +mspm0l1106dyy = ["mspm0-metapac/mspm0l1106dyy"] +mspm0l1106rge = ["mspm0-metapac/mspm0l1106rge"] +mspm0l1106rhb = ["mspm0-metapac/mspm0l1106rhb"] +mspm0l1106rtr = ["mspm0-metapac/mspm0l1106rtr"] +mspm0l1227pm = ["mspm0-metapac/mspm0l1227pm"] +mspm0l1227pn = ["mspm0-metapac/mspm0l1227pn"] +mspm0l1227pt = ["mspm0-metapac/mspm0l1227pt"] +mspm0l1227rge = ["mspm0-metapac/mspm0l1227rge"] +mspm0l1227rgz = ["mspm0-metapac/mspm0l1227rgz"] +mspm0l1227rhb = ["mspm0-metapac/mspm0l1227rhb"] +mspm0l1228pm = ["mspm0-metapac/mspm0l1228pm"] +mspm0l1228pn = ["mspm0-metapac/mspm0l1228pn"] +mspm0l1228pt = ["mspm0-metapac/mspm0l1228pt"] +mspm0l1228rge = ["mspm0-metapac/mspm0l1228rge"] +mspm0l1228rgz = ["mspm0-metapac/mspm0l1228rgz"] +mspm0l1228rhb = ["mspm0-metapac/mspm0l1228rhb"] +mspm0l1303rge = ["mspm0-metapac/mspm0l1303rge"] +mspm0l1304dgs20 = ["mspm0-metapac/mspm0l1304dgs20"] +mspm0l1304dgs28 = ["mspm0-metapac/mspm0l1304dgs28"] +mspm0l1304dyy = ["mspm0-metapac/mspm0l1304dyy"] +mspm0l1304rge = ["mspm0-metapac/mspm0l1304rge"] +mspm0l1304rhb = ["mspm0-metapac/mspm0l1304rhb"] +mspm0l1304rtr = ["mspm0-metapac/mspm0l1304rtr"] +mspm0l1305dgs20 = ["mspm0-metapac/mspm0l1305dgs20"] +mspm0l1305dgs28 = ["mspm0-metapac/mspm0l1305dgs28"] +mspm0l1305dyy = ["mspm0-metapac/mspm0l1305dyy"] +mspm0l1305rge = ["mspm0-metapac/mspm0l1305rge"] +mspm0l1305rtr = ["mspm0-metapac/mspm0l1305rtr"] +mspm0l1306dgs20 = ["mspm0-metapac/mspm0l1306dgs20"] +mspm0l1306dgs28 = ["mspm0-metapac/mspm0l1306dgs28"] +mspm0l1306dyy = ["mspm0-metapac/mspm0l1306dyy"] +mspm0l1306rge = ["mspm0-metapac/mspm0l1306rge"] +mspm0l1306rhb = ["mspm0-metapac/mspm0l1306rhb"] +mspm0l1343dgs20 = ["mspm0-metapac/mspm0l1343dgs20"] +mspm0l1344dgs20 = ["mspm0-metapac/mspm0l1344dgs20"] +mspm0l1345dgs28 = ["mspm0-metapac/mspm0l1345dgs28"] +mspm0l1346dgs28 = ["mspm0-metapac/mspm0l1346dgs28"] +mspm0l2227pm = ["mspm0-metapac/mspm0l2227pm"] +mspm0l2227pn = ["mspm0-metapac/mspm0l2227pn"] +mspm0l2227pt = ["mspm0-metapac/mspm0l2227pt"] +mspm0l2227rgz = ["mspm0-metapac/mspm0l2227rgz"] +mspm0l2228pm = ["mspm0-metapac/mspm0l2228pm"] +mspm0l2228pn = ["mspm0-metapac/mspm0l2228pn"] +mspm0l2228pt = ["mspm0-metapac/mspm0l2228pt"] +mspm0l2228rgz = ["mspm0-metapac/mspm0l2228rgz"] +msps003f3pw20 = ["mspm0-metapac/msps003f3pw20"] +msps003f4pw20 = ["mspm0-metapac/msps003f4pw20"] diff --git a/embassy-mspm0/README.md b/embassy-mspm0/README.md new file mode 100644 index 000000000..b2b8934aa --- /dev/null +++ b/embassy-mspm0/README.md @@ -0,0 +1,28 @@ +# Embassy MSPM0 HAL + +The embassy-mspm0 HAL aims to provide a safe, idiomatic hardware abstraction layer for all MSPM0 and MSPS003 chips. + +* [Documentation](https://docs.embassy.dev/embassy-mspm0/) (**Important:** use docs.embassy.dev rather than docs.rs to see the specific docs for the chip you’re using!) +* [Source](https://github.com/embassy-rs/embassy/tree/main/embassy-mspm0) +* [Examples](https://github.com/embassy-rs/embassy/tree/main/examples) + +## Embedded-hal + +The `embassy-mspm0` HAL implements the traits from [embedded-hal](https://crates.io/crates/embedded-hal) (1.0) and [embedded-hal-async](https://crates.io/crates/embedded-hal-async), as well as [embedded-io](https://crates.io/crates/embedded-io) and [embedded-io-async](https://crates.io/crates/embedded-io-async). + +## A note on feature flag names + +Feature flag names for chips do not include temperature rating or distribution format. + +Usually chapter 10 of your device's datasheet will explain the device nomenclature and how to decode it. Feature names in embassy-mspm0 only use the following from device nomenclature: +- MCU platform +- Product family +- Device subfamily +- Flash memory +- Package type + +This means for a part such as `MSPM0G3507SPMR`, the feature name is `mspm0g3507pm`. This also means that `MSPM0G3507QPMRQ1` uses the feature `mspm0g3507pm`, since the Q1 parts are just qualified variants of the base G3507 with a PM (QFP-64) package. + +## Interoperability + +This crate can run on any executor. diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 08209df2a..409ce0621 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -7,7 +7,7 @@ use std::sync::LazyLock; use std::{env, fs}; use common::CfgSet; -use mspm0_metapac::metadata::METADATA; +use mspm0_metapac::metadata::{ALL_CHIPS, METADATA}; use proc_macro2::{Ident, Literal, Span, TokenStream}; use quote::{format_ident, quote}; @@ -24,6 +24,27 @@ fn generate_code() { cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); + let chip_name = match env::vars() + .map(|(a, _)| a) + .filter(|x| x.starts_with("CARGO_FEATURE_MSPM0") || x.starts_with("CARGO_FEATURE_MSPS")) + .get_one() + { + Ok(x) => x, + Err(GetOneError::None) => panic!("No mspm0xx/mspsxx Cargo feature enabled"), + Err(GetOneError::Multiple) => panic!("Multiple mspm0xx/mspsxx Cargo features enabled"), + } + .strip_prefix("CARGO_FEATURE_") + .unwrap() + .to_ascii_lowercase() + .replace('_', "-"); + + eprintln!("chip: {chip_name}"); + + cfgs.enable_all(&get_chip_cfgs(&chip_name)); + for chip in ALL_CHIPS { + cfgs.declare_all(&get_chip_cfgs(&chip)); + } + let mut singletons = get_singletons(&mut cfgs); time_driver(&mut singletons, &mut cfgs); @@ -44,6 +65,60 @@ fn generate_code() { rustfmt(&out_file); } +fn get_chip_cfgs(chip_name: &str) -> Vec { + let mut cfgs = Vec::new(); + + // GPIO on C110x is special as it does not belong to an interrupt group. + if chip_name.starts_with("mspm0c110") || chip_name.starts_with("msps003f") { + cfgs.push("mspm0c110x".to_string()); + } + + // Family ranges (temporary until int groups are generated) + // + // TODO: Remove this once int group stuff is generated. + if chip_name.starts_with("mspm0g110") { + cfgs.push("mspm0g110x".to_string()); + } + + if chip_name.starts_with("mspm0g150") { + cfgs.push("mspm0g150x".to_string()); + } + + if chip_name.starts_with("mspm0g310") { + cfgs.push("mspm0g310x".to_string()); + } + + if chip_name.starts_with("mspm0g350") { + cfgs.push("mspm0g350x".to_string()); + } + + if chip_name.starts_with("mspm0g351") { + cfgs.push("mspm0g351x".to_string()); + } + + if chip_name.starts_with("mspm0l110") { + cfgs.push("mspm0l110x".to_string()); + } + + if chip_name.starts_with("mspm0l122") { + cfgs.push("mspm0l122x".to_string()); + } + + if chip_name.starts_with("mspm0l130") { + cfgs.push("mspm0l130x".to_string()); + } + + if chip_name.starts_with("mspm0l134") { + cfgs.push("mspm0l134x".to_string()); + } + + if chip_name.starts_with("mspm0l222") { + cfgs.push("mspm0l222x".to_string()); + } + + cfgs +} + #[derive(Debug, Clone)] struct Singleton { name: String, @@ -146,7 +221,7 @@ fn make_valid_identifier(s: &str) -> Singleton { } fn generate_pincm_mapping() -> TokenStream { - let pincms = METADATA.pincm_mappings.iter().map(|mapping| { + let pincms = METADATA.pins.iter().map(|mapping| { let port_letter = mapping.pin.strip_prefix("P").unwrap(); let port_base = (port_letter.chars().next().unwrap() as u8 - b'A') * 32; // This assumes all ports are single letter length. @@ -174,11 +249,11 @@ fn generate_pincm_mapping() -> TokenStream { } fn generate_pin() -> TokenStream { - let pin_impls = METADATA.pincm_mappings.iter().map(|pincm_mapping| { - let name = Ident::new(&pincm_mapping.pin, Span::call_site()); - let port_letter = pincm_mapping.pin.strip_prefix("P").unwrap(); + let pin_impls = METADATA.pins.iter().map(|pin| { + let name = Ident::new(&pin.pin, Span::call_site()); + let port_letter = pin.pin.strip_prefix("P").unwrap(); let port_letter = port_letter.chars().next().unwrap(); - let pin_number = Literal::u8_unsuffixed(pincm_mapping.pin[2..].parse::().unwrap()); + let pin_number = Literal::u8_unsuffixed(pin.pin[2..].parse::().unwrap()); let port = Ident::new(&format!("Port{}", port_letter), Span::call_site()); diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index 3f895d962..3c824b0e6 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs @@ -10,7 +10,7 @@ use embassy_sync::waitqueue::AtomicWaker; use crate::pac::gpio::vals::*; use crate::pac::gpio::{self}; -#[cfg(all(feature = "rt", feature = "mspm0c110x"))] +#[cfg(all(feature = "rt", mspm0c110x))] use crate::pac::interrupt; use crate::pac::{self}; @@ -1120,7 +1120,7 @@ impl Iterator for BitIter { } // C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt. -#[cfg(all(feature = "rt", feature = "mspm0c110x"))] +#[cfg(all(feature = "rt", mspm0c110x))] #[interrupt] fn GPIOA() { gpioa_interrupt(); diff --git a/embassy-mspm0/src/int_group/g150x.rs b/embassy-mspm0/src/int_group/g150x.rs new file mode 100644 index 000000000..706ba2078 --- /dev/null +++ b/embassy-mspm0/src/int_group/g150x.rs @@ -0,0 +1,51 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::WWDT1 => todo!("implement WWDT1"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::GPIOB => crate::gpio::gpiob_interrupt(), + Group1::COMP0 => todo!("implement COMP0"), + Group1::COMP1 => todo!("implement COMP1"), + Group1::COMP2 => todo!("implement COMP2"), + Group1::TRNG => todo!("implement TRNG"), + } +} diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index e8f5971d5..df2d83cc0 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -1,6 +1,11 @@ #![no_std] // Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc #![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))] +#![cfg_attr( + docsrs, + doc = "

You might want to browse the `embassy-mspm0` documentation on the Embassy website instead.

The documentation here on `docs.rs` is built for a single chip only, while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.

\n\n" +)] +#![doc = include_str!("../README.md")] // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; @@ -35,11 +40,11 @@ pub mod mode { mod time_driver; // Interrupt group handlers. -#[cfg_attr(feature = "mspm0c110x", path = "int_group/c110x.rs")] -#[cfg_attr(feature = "mspm0g350x", path = "int_group/g350x.rs")] -#[cfg_attr(feature = "mspm0g351x", path = "int_group/g351x.rs")] -#[cfg_attr(feature = "mspm0l130x", path = "int_group/l130x.rs")] -#[cfg_attr(feature = "mspm0l222x", path = "int_group/l222x.rs")] +#[cfg_attr(mspm0c110x, path = "int_group/c110x.rs")] +#[cfg_attr(mspm0g350x, path = "int_group/g350x.rs")] +#[cfg_attr(mspm0g351x, path = "int_group/g351x.rs")] +#[cfg_attr(mspm0l130x, path = "int_group/l130x.rs")] +#[cfg_attr(mspm0l222x, path = "int_group/l222x.rs")] mod int_group; pub(crate) mod _generated { @@ -109,7 +114,7 @@ pub fn init(_config: Config) -> Peripherals { _generated::enable_group_interrupts(cs); - #[cfg(feature = "mspm0c110x")] + #[cfg(mspm0c110x)] unsafe { use crate::_generated::interrupt::typelevel::Interrupt; crate::interrupt::typelevel::GPIOA::enable(); diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml index ba64a578d..67b0372ab 100644 --- a/examples/mspm0c1104/Cargo.toml +++ b/examples/mspm0c1104/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c110x", "defmt", "rt", "time-driver-any"] } +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c1104dgs20", "defmt", "rt", "time-driver-any"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } diff --git a/examples/mspm0c1104/README.md b/examples/mspm0c1104/README.md index e5c9f961d..86b6c3918 100644 --- a/examples/mspm0c1104/README.md +++ b/examples/mspm0c1104/README.md @@ -1,4 +1,4 @@ -# Examples for MSPM0C110x family +# Examples for MSPM0C1104 Run individual examples with ``` @@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0C1104](https://www.t You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for C1104 it should be `probe-rs run --chip MSPM0C1104`. (use `probe-rs chip list` to find your chip) -* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for C1104 it should be `mspm0c1104`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. +* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0C1104 it should be `mspm0c1104dgs20`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml index f6fed091d..49baeabdf 100644 --- a/examples/mspm0g3507/Cargo.toml +++ b/examples/mspm0g3507/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g350x", "defmt", "rt", "time-driver-any"] } +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g3507pm", "defmt", "rt", "time-driver-any"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } diff --git a/examples/mspm0g3507/README.md b/examples/mspm0g3507/README.md index 5e8a83212..be91dc5a0 100644 --- a/examples/mspm0g3507/README.md +++ b/examples/mspm0g3507/README.md @@ -1,4 +1,4 @@ -# Examples for MSPM0C350x family +# Examples for MSPM0M3507 Run individual examples with ``` @@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0G3507](https://www.t You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3507 it should be `probe-rs run --chip MSPM0G3507`. (use `probe-rs chip list` to find your chip) -* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3507 it should be `mspm0g3507`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. +* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0G3507 it should be `mspm0g3507pm`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml index 1662e1f8d..dfe365daf 100644 --- a/examples/mspm0g3519/Cargo.toml +++ b/examples/mspm0g3519/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g351x", "defmt", "rt", "time-driver-any"] } +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g3519pz", "defmt", "rt", "time-driver-any"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } diff --git a/examples/mspm0g3519/README.md b/examples/mspm0g3519/README.md index 5034b1913..c392c9e25 100644 --- a/examples/mspm0g3519/README.md +++ b/examples/mspm0g3519/README.md @@ -1,4 +1,4 @@ -# Examples for MSPM0G351x family +# Examples for MSPM0G3519 Run individual examples with ``` @@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0G3519](https://www.t You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3519 it should be `probe-rs run --chip MSPM0G3519`. (use `probe-rs chip list` to find your chip) -* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3519 it should be `mspm0g3519`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. +* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0G3519 it should be `mspm0g3519pz`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml index 609b3f205..b0c370bb5 100644 --- a/examples/mspm0l1306/Cargo.toml +++ b/examples/mspm0l1306/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l130x", "defmt", "rt", "time-driver-any"] } +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l1306rhb", "defmt", "rt", "time-driver-any"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } diff --git a/examples/mspm0l1306/README.md b/examples/mspm0l1306/README.md index 5a55d721e..4d698e0fa 100644 --- a/examples/mspm0l1306/README.md +++ b/examples/mspm0l1306/README.md @@ -1,4 +1,4 @@ -# Examples for MSPM0L130x family +# Examples for MSPM0L1306 Run individual examples with ``` @@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0L1306](https://www.t You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L1306 it should be `probe-rs run --chip MSPM0L1306`. (use `probe-rs chip list` to find your chip) -* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L1306 it should be `mspm0l1306`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. +* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0L1306 it should be `mspm0l1306rhb`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml index bbca011a1..d55b9e6a8 100644 --- a/examples/mspm0l2228/Cargo.toml +++ b/examples/mspm0l2228/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l222x", "defmt", "rt", "time-driver-any"] } +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l2228pn", "defmt", "rt", "time-driver-any"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } diff --git a/examples/mspm0l2228/README.md b/examples/mspm0l2228/README.md index c73fa13b6..191022258 100644 --- a/examples/mspm0l2228/README.md +++ b/examples/mspm0l2228/README.md @@ -1,4 +1,4 @@ -# Examples for MSPM0L222x family +# Examples for MSPM0L2228 Run individual examples with ``` @@ -15,7 +15,7 @@ A large number of the examples are written for the [LP-MSPM0L2228](https://www.t You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L2228 it should be `probe-rs run --chip MSPM0L2228`. (use `probe-rs chip list` to find your chip) -* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L2228 it should be `mspm0l2228`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. +* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for LP-MSPM0L2228 it should be `mspm0l2228pn`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml index 0566807d7..d76aaff73 100644 --- a/tests/mspm0/Cargo.toml +++ b/tests/mspm0/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [features] -mspm0g3507 = [ "embassy-mspm0/mspm0g350x" ] +mspm0g3507 = [ "embassy-mspm0/mspm0g3507pm" ] [dependencies] teleprobe-meta = "1.1" -- cgit From 8bb25a551abbf3677a440d6f73401b88cf4de57f Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 13 May 2025 22:53:16 -0500 Subject: ci: build std examples on aarch64-unknown-linux-gnu --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 6e320e4d1..f2d461c1a 100755 --- a/ci.sh +++ b/ci.sh @@ -19,7 +19,7 @@ fi TARGET=$(rustc -vV | sed -n 's|host: ||p') BUILD_EXTRA="" -if [ $TARGET = "x86_64-unknown-linux-gnu" ]; then +if [ $TARGET = "x86_64-unknown-linux-gnu" ] || [ $TARGET = "aarch64-unknown-linux-gnu" ]; then BUILD_EXTRA="--- build --release --manifest-path examples/std/Cargo.toml --target $TARGET --artifact-dir out/examples/std" fi -- cgit From d4d10bad0bc2f2bbfbad116fb07e27eea4ac5af2 Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Wed, 14 May 2025 09:52:46 +0200 Subject: [embassy-usb-dfu] accept closure to customise DFU function This provides a more generic interface for users to customise the DFU function instead of restricting customisation to DFU headers. --- embassy-usb-dfu/src/application.rs | 21 ++++++--------------- embassy-usb-dfu/src/dfu.rs | 21 ++++++--------------- examples/boot/application/stm32wb-dfu/src/main.rs | 14 +++++++++----- examples/boot/bootloader/stm32wb-dfu/src/main.rs | 14 +++++++++----- 4 files changed, 30 insertions(+), 40 deletions(-) diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs index 2646d100d..4b7b72073 100644 --- a/embassy-usb-dfu/src/application.rs +++ b/embassy-usb-dfu/src/application.rs @@ -2,7 +2,7 @@ use embassy_boot::BlockingFirmwareState; use embassy_time::{Duration, Instant}; use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; use embassy_usb::driver::Driver; -use embassy_usb::{msos, Builder, Handler}; +use embassy_usb::{Builder, FunctionBuilder, Handler}; use embedded_storage::nor_flash::NorFlash; use crate::consts::{ @@ -130,22 +130,13 @@ pub fn usb_dfu<'d, D: Driver<'d>, MARK: DfuMarker, RST: Reset>( builder: &mut Builder<'d, D>, handler: &'d mut Control, timeout: Duration, - winusb_guids: Option<&'d [&str]>, + func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>), ) { let mut func = builder.function(0x00, 0x00, 0x00); - if let Some(winusb_guids) = winusb_guids { - // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. - // Otherwise users need to do this manually using a tool like Zadig. - // - // Adding them here on the function level appears to only be needed for compositive devices. - // In addition to being on the function level, they should also be added to the device level. - // - func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); - func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( - "DeviceInterfaceGUIDs", - msos::PropertyData::RegMultiSz(winusb_guids), - )); - } + + // Here we give users the opportunity to add their own function level MSOS headers for instance. + // This is useful when DFU functionality is part of a composite USB device. + func_modifier(&mut func); let mut iface = func.interface(); let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs index 43a35637d..0f39d906b 100644 --- a/embassy-usb-dfu/src/dfu.rs +++ b/embassy-usb-dfu/src/dfu.rs @@ -1,7 +1,7 @@ use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterError}; use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; use embassy_usb::driver::Driver; -use embassy_usb::{msos, Builder, Handler}; +use embassy_usb::{Builder, FunctionBuilder, Handler}; use embedded_storage::nor_flash::{NorFlash, NorFlashErrorKind}; use crate::consts::{ @@ -186,22 +186,13 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize>( builder: &mut Builder<'d, D>, handler: &'d mut Control<'d, DFU, STATE, RST, BLOCK_SIZE>, - winusb_guids: Option<&'d [&str]>, + func_modifier: impl Fn(&mut FunctionBuilder<'_, 'd, D>), ) { let mut func = builder.function(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU); - if let Some(winusb_guids) = winusb_guids { - // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows. - // Otherwise users need to do this manually using a tool like Zadig. - // - // Adding them here on the function level appears to only be needed for compositive devices. - // In addition to being on the function level, they should also be added to the device level. - // - func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); - func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( - "DeviceInterfaceGUIDs", - msos::PropertyData::RegMultiSz(winusb_guids), - )); - } + + // Here we give users the opportunity to add their own function level MSOS headers for instance. + // This is useful when DFU functionality is part of a composite USB device. + func_modifier(&mut func); let mut iface = func.interface(); let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_DFU, None); diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index 6236dfe52..4d6556597 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs @@ -70,11 +70,15 @@ async fn main(_spawner: Spawner) { msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), )); - // For non-composite devices: - usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), None); - - // Or for composite devices: - // usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), Some(DEVICE_INTERFACE_GUIDS)); + usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), |func| { + // You likely don't have to add these function level headers if your USB device is not composite + // (i.e. if your device does not expose another interface in addition to DFU) + func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + }); let mut dev = builder.build(); dev.run().await diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index 8cfd4daa7..fea6f4a0d 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs @@ -78,11 +78,15 @@ fn main() -> ! { msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), )); - // For non-composite devices: - usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, None); - - // Or for composite devices: - // usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, Some(DEVICE_INTERFACE_GUIDS)); + usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, |func| { + // You likely don't have to add these function level headers if your USB device is not composite + // (i.e. if your device does not expose another interface in addition to DFU) + func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + }); let mut dev = builder.build(); embassy_futures::block_on(dev.run()); -- cgit From 2bbc2045a4a6cb1e489295d258ac0cdb6338f90a Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Wed, 14 May 2025 09:56:28 +0200 Subject: [usb-dfu examples] Alert users to customise their WinUSB GUIDs --- examples/boot/application/stm32wb-dfu/src/main.rs | 4 +++- examples/boot/bootloader/stm32wb-dfu/src/main.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index 4d6556597..5e7b71f5a 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs @@ -22,7 +22,9 @@ bind_interrupts!(struct Irqs { USB_LP => usb::InterruptHandler; }); -// This is a randomly generated GUID to allow clients on Windows to find our device +// This is a randomly generated GUID to allow clients on Windows to find your device. +// +// N.B. update to a custom GUID for your own device! const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"]; #[embassy_executor::main] diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index fea6f4a0d..0b643079f 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs @@ -20,7 +20,9 @@ bind_interrupts!(struct Irqs { USB_LP => usb::InterruptHandler; }); -// This is a randomly generated GUID to allow clients on Windows to find our device +// This is a randomly generated GUID to allow clients on Windows to find your device. +// +// N.B. update to a custom GUID for your own device! const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"]; #[entry] -- cgit From be20c708fa7b099507c2027a8c5666b54f1e5723 Mon Sep 17 00:00:00 2001 From: jake-taf <149392739+jake-taf@users.noreply.github.com> Date: Wed, 14 May 2025 09:45:20 -0400 Subject: Interrupt Doc Comments Support adding doc comments to interrupts --- embassy-stm32/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 3e84d3386..f8d09413d 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -173,8 +173,9 @@ pub use crate::_generated::interrupt; // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. #[macro_export] macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { + ($(#[$outer:meta])* $vis:vis struct $name:ident { $( + $(#[$inner:meta])* $(#[cfg($cond_irq:meta)])? $irq:ident => $( $(#[cfg($cond_handler:meta)])? @@ -183,12 +184,14 @@ macro_rules! bind_interrupts { )* }) => { #[derive(Copy, Clone)] + $(#[$outer])* $vis struct $name; $( #[allow(non_snake_case)] #[no_mangle] $(#[cfg($cond_irq)])? + $(#[$inner])* unsafe extern "C" fn $irq() { $( $(#[cfg($cond_handler)])? -- cgit From a71642ca01190d1a8f8bd652bd41d8a9539fe2ee Mon Sep 17 00:00:00 2001 From: Jakob Date: Wed, 14 May 2025 18:57:00 +0200 Subject: Fix compile error in adc_read doc comment code --- embassy-stm32/src/adc/g4.rs | 4 ++-- embassy-stm32/src/adc/v3.rs | 4 ++-- embassy-stm32/src/adc/v4.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 8ed102c1b..1fce3085a 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs @@ -371,8 +371,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// let mut adc_pin1 = p.PA1.into(); /// let mut measurements = [0u16; 2]; /// - /// adc.read_async( - /// p.DMA1_CH2, + /// adc.read( + /// p.DMA1_CH2.reborrow(), /// [ /// (&mut *adc_pin0, SampleTime::CYCLES160_5), /// (&mut *adc_pin1, SampleTime::CYCLES160_5), diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 1c5ad16e9..313244e19 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -272,8 +272,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// let mut adc_pin1 = p.PA1.degrade_adc(); /// let mut measurements = [0u16; 2]; /// - /// adc.read_async( - /// p.DMA1_CH2, + /// adc.read( + /// p.DMA1_CH2.reborrow(), /// [ /// (&mut *adc_pin0, SampleTime::CYCLES160_5), /// (&mut *adc_pin1, SampleTime::CYCLES160_5), diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index e455b275c..39e0d51b9 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -347,8 +347,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// let mut adc_pin2 = p.PA2.into(); /// let mut measurements = [0u16; 2]; /// - /// adc.read_async( - /// p.DMA2_CH0, + /// adc.read( + /// p.DMA2_CH0.reborrow(), /// [ /// (&mut *adc_pin0, SampleTime::CYCLES112), /// (&mut *adc_pin2, SampleTime::CYCLES112), -- cgit From ad091324a7da4d6b4326f6d1f8dc29e7a9844be0 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Wed, 14 May 2025 22:26:55 -0500 Subject: nrf: _3v3 -> _3V3 --- embassy-nrf/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 5bce65a98..7d86e1218 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -339,7 +339,7 @@ pub mod config { /// 3.0 V _3V0 = 4, /// 3.3 V - _3v3 = 5, + _3V3 = 5, //ERASED = 7, means 1.8V } @@ -371,7 +371,7 @@ pub mod config { /// 3.0 V _3V0 = 4, /// 3.3 V - _3v3 = 5, + _3V3 = 5, //ERASED = 7, means 1.8V } -- cgit From d64ae225b30bc3a0f7a9b1277188b6e60fc97484 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 10 Apr 2025 10:39:54 -0700 Subject: Add UART and DMA drivers Both blocking and async versions are supported. Add separate examples for each mode. --- docs/pages/imxrt.adoc | 2 + embassy-imxrt/src/dma.rs | 418 +++++++++++ embassy-imxrt/src/flexcomm/mod.rs | 252 +++++++ embassy-imxrt/src/flexcomm/uart.rs | 1230 ++++++++++++++++++++++++++++++++ embassy-imxrt/src/gpio.rs | 20 +- embassy-imxrt/src/lib.rs | 26 +- examples/mimxrt6/src/bin/uart-async.rs | 87 +++ examples/mimxrt6/src/bin/uart.rs | 55 ++ 8 files changed, 2069 insertions(+), 21 deletions(-) create mode 100644 embassy-imxrt/src/dma.rs create mode 100644 embassy-imxrt/src/flexcomm/mod.rs create mode 100644 embassy-imxrt/src/flexcomm/uart.rs create mode 100644 examples/mimxrt6/src/bin/uart-async.rs create mode 100644 examples/mimxrt6/src/bin/uart.rs diff --git a/docs/pages/imxrt.adoc b/docs/pages/imxrt.adoc index bbd65e494..87867e1e0 100644 --- a/docs/pages/imxrt.adoc +++ b/docs/pages/imxrt.adoc @@ -10,5 +10,7 @@ The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Emb The following peripherals have a HAL implementation at present * CRC +* DMA * GPIO * RNG +* UART diff --git a/embassy-imxrt/src/dma.rs b/embassy-imxrt/src/dma.rs new file mode 100644 index 000000000..e141447f3 --- /dev/null +++ b/embassy-imxrt/src/dma.rs @@ -0,0 +1,418 @@ +//! DMA driver. + +use core::future::Future; +use core::pin::Pin; +use core::sync::atomic::{compiler_fence, Ordering}; +use core::task::{Context, Poll}; + +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; +use embassy_sync::waitqueue::AtomicWaker; +use pac::dma0::channel::cfg::Periphreqen; +use pac::dma0::channel::xfercfg::{Dstinc, Srcinc, Width}; + +use crate::clocks::enable_and_reset; +use crate::interrupt::InterruptExt; +use crate::peripherals::DMA0; +use crate::sealed::Sealed; +use crate::{interrupt, pac, peripherals, BitIter}; + +#[cfg(feature = "rt")] +#[interrupt] +fn DMA0() { + let reg = unsafe { crate::pac::Dma0::steal() }; + + if reg.intstat().read().activeerrint().bit() { + let err = reg.errint0().read().bits(); + + for channel in BitIter(err) { + error!("DMA error interrupt on channel {}!", channel); + reg.errint0().write(|w| unsafe { w.err().bits(1 << channel) }); + CHANNEL_WAKERS[channel as usize].wake(); + } + } + + if reg.intstat().read().activeint().bit() { + let ia = reg.inta0().read().bits(); + + for channel in BitIter(ia) { + reg.inta0().write(|w| unsafe { w.ia().bits(1 << channel) }); + CHANNEL_WAKERS[channel as usize].wake(); + } + } +} + +/// Initialize DMA controllers (DMA0 only, for now) +pub(crate) unsafe fn init() { + let sysctl0 = crate::pac::Sysctl0::steal(); + let dmactl0 = crate::pac::Dma0::steal(); + + enable_and_reset::(); + + interrupt::DMA0.disable(); + interrupt::DMA0.set_priority(interrupt::Priority::P3); + + dmactl0.ctrl().modify(|_, w| w.enable().set_bit()); + + // Set channel descriptor SRAM base address + // Descriptor base must be 1K aligned + let descriptor_base = core::ptr::addr_of!(DESCRIPTORS.descs) as u32; + dmactl0.srambase().write(|w| w.bits(descriptor_base)); + + // Ensure AHB priority it highest (M4 == DMAC0) + sysctl0.ahbmatrixprior().modify(|_, w| w.m4().bits(0)); + + interrupt::DMA0.unpend(); + interrupt::DMA0.enable(); +} + +/// DMA read. +/// +/// SAFETY: Slice must point to a valid location reachable by DMA. +pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: *mut [W]) -> Transfer<'a, C> { + let count = ((to.len() / W::size() as usize) - 1) as isize; + + copy_inner( + ch, + from as *const u32, + (to as *mut u32).byte_offset(count * W::size()), + W::width(), + count, + false, + true, + true, + ) +} + +/// DMA write. +/// +/// SAFETY: Slice must point to a valid location reachable by DMA. +pub unsafe fn write<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const [W], to: *mut W) -> Transfer<'a, C> { + let count = ((from.len() / W::size() as usize) - 1) as isize; + + copy_inner( + ch, + (from as *const u32).byte_offset(count * W::size()), + to as *mut u32, + W::width(), + count, + true, + false, + true, + ) +} + +/// DMA copy between slices. +/// +/// SAFETY: Slices must point to locations reachable by DMA. +pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> { + let from_len = from.len(); + let to_len = to.len(); + assert_eq!(from_len, to_len); + + let count = ((from_len / W::size() as usize) - 1) as isize; + + copy_inner( + ch, + from.as_ptr().byte_offset(count * W::size()) as *const u32, + to.as_mut_ptr().byte_offset(count * W::size()) as *mut u32, + W::width(), + count, + true, + true, + false, + ) +} + +fn copy_inner<'a, C: Channel>( + ch: Peri<'a, C>, + from: *const u32, + to: *mut u32, + width: Width, + count: isize, + incr_read: bool, + incr_write: bool, + periph: bool, +) -> Transfer<'a, C> { + let p = ch.regs(); + + unsafe { + DESCRIPTORS.descs[ch.number() as usize].src = from as u32; + DESCRIPTORS.descs[ch.number() as usize].dest = to as u32; + } + + compiler_fence(Ordering::SeqCst); + + p.errint0().write(|w| unsafe { w.err().bits(1 << ch.number()) }); + p.inta0().write(|w| unsafe { w.ia().bits(1 << ch.number()) }); + + p.channel(ch.number().into()).cfg().write(|w| { + unsafe { w.chpriority().bits(0) } + .periphreqen() + .variant(match periph { + false => Periphreqen::Disabled, + true => Periphreqen::Enabled, + }) + .hwtrigen() + .clear_bit() + }); + + p.intenset0().write(|w| unsafe { w.inten().bits(1 << ch.number()) }); + + p.channel(ch.number().into()).xfercfg().write(|w| { + unsafe { w.xfercount().bits(count as u16) } + .cfgvalid() + .set_bit() + .clrtrig() + .set_bit() + .reload() + .clear_bit() + .setinta() + .set_bit() + .width() + .variant(width) + .srcinc() + .variant(match incr_read { + false => Srcinc::NoIncrement, + true => Srcinc::WidthX1, + // REVISIT: what about WidthX2 and WidthX4? + }) + .dstinc() + .variant(match incr_write { + false => Dstinc::NoIncrement, + true => Dstinc::WidthX1, + // REVISIT: what about WidthX2 and WidthX4? + }) + }); + + p.enableset0().write(|w| unsafe { w.ena().bits(1 << ch.number()) }); + + p.channel(ch.number().into()) + .xfercfg() + .modify(|_, w| w.swtrig().set_bit()); + + compiler_fence(Ordering::SeqCst); + + Transfer::new(ch) +} + +/// DMA transfer driver. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Transfer<'a, C: Channel> { + channel: Peri<'a, C>, +} + +impl<'a, C: Channel> Transfer<'a, C> { + pub(crate) fn new(channel: Peri<'a, C>) -> Self { + Self { channel } + } + + pub(crate) fn abort(&mut self) -> usize { + let p = self.channel.regs(); + + p.abort0().write(|w| w.channel(self.channel.number()).set_bit()); + while p.busy0().read().bsy().bits() & (1 << self.channel.number()) != 0 {} + + p.enableclr0() + .write(|w| unsafe { w.clr().bits(1 << self.channel.number()) }); + + let width: u8 = p + .channel(self.channel.number().into()) + .xfercfg() + .read() + .width() + .variant() + .unwrap() + .into(); + + let count = p + .channel(self.channel.number().into()) + .xfercfg() + .read() + .xfercount() + .bits() + + 1; + + usize::from(count) * usize::from(width) + } +} + +impl<'a, C: Channel> Drop for Transfer<'a, C> { + fn drop(&mut self) { + self.abort(); + } +} + +impl<'a, C: Channel> Unpin for Transfer<'a, C> {} +impl<'a, C: Channel> Future for Transfer<'a, C> { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // Re-register the waker on each call to poll() because any calls to + // wake will deregister the waker. + CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker()); + + if self.channel.regs().active0().read().act().bits() & (1 << self.channel.number()) == 0 { + Poll::Ready(()) + } else { + Poll::Pending + } + } +} + +/// DMA channel descriptor +#[derive(Copy, Clone)] +#[repr(C)] +struct Descriptor { + reserved: u32, + src: u32, + dest: u32, + link: u32, +} + +impl Descriptor { + const fn new() -> Self { + Self { + reserved: 0, + src: 0, + dest: 0, + link: 0, + } + } +} + +#[repr(align(1024))] +struct Descriptors { + descs: [Descriptor; CHANNEL_COUNT], +} + +impl Descriptors { + const fn new() -> Self { + Self { + descs: [const { Descriptor::new() }; CHANNEL_COUNT], + } + } +} + +static mut DESCRIPTORS: Descriptors = Descriptors::new(); +static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT]; +pub(crate) const CHANNEL_COUNT: usize = 33; + +/// DMA channel interface. +#[allow(private_bounds)] +pub trait Channel: PeripheralType + Sealed + Into + Sized + 'static { + /// Channel number. + fn number(&self) -> u8; + + /// Channel registry block. + fn regs(&self) -> &'static pac::dma0::RegisterBlock { + unsafe { &*crate::pac::Dma0::ptr() } + } +} + +/// DMA word. +#[allow(private_bounds)] +pub trait Word: Sealed { + /// Transfer width. + fn width() -> Width; + + /// Size in bytes for the width. + fn size() -> isize; +} + +impl Sealed for u8 {} +impl Word for u8 { + fn width() -> Width { + Width::Bit8 + } + + fn size() -> isize { + 1 + } +} + +impl Sealed for u16 {} +impl Word for u16 { + fn width() -> Width { + Width::Bit16 + } + + fn size() -> isize { + 2 + } +} + +impl Sealed for u32 {} +impl Word for u32 { + fn width() -> Width { + Width::Bit32 + } + + fn size() -> isize { + 4 + } +} + +/// Type erased DMA channel. +pub struct AnyChannel { + number: u8, +} + +impl_peripheral!(AnyChannel); + +impl Sealed for AnyChannel {} +impl Channel for AnyChannel { + fn number(&self) -> u8 { + self.number + } +} + +macro_rules! channel { + ($name:ident, $num:expr) => { + impl Sealed for peripherals::$name {} + impl Channel for peripherals::$name { + fn number(&self) -> u8 { + $num + } + } + + impl From for crate::dma::AnyChannel { + fn from(val: peripherals::$name) -> Self { + Self { number: val.number() } + } + } + }; +} + +channel!(DMA0_CH0, 0); +channel!(DMA0_CH1, 1); +channel!(DMA0_CH2, 2); +channel!(DMA0_CH3, 3); +channel!(DMA0_CH4, 4); +channel!(DMA0_CH5, 5); +channel!(DMA0_CH6, 6); +channel!(DMA0_CH7, 7); +channel!(DMA0_CH8, 8); +channel!(DMA0_CH9, 9); +channel!(DMA0_CH10, 10); +channel!(DMA0_CH11, 11); +channel!(DMA0_CH12, 12); +channel!(DMA0_CH13, 13); +channel!(DMA0_CH14, 14); +channel!(DMA0_CH15, 15); +channel!(DMA0_CH16, 16); +channel!(DMA0_CH17, 17); +channel!(DMA0_CH18, 18); +channel!(DMA0_CH19, 19); +channel!(DMA0_CH20, 20); +channel!(DMA0_CH21, 21); +channel!(DMA0_CH22, 22); +channel!(DMA0_CH23, 23); +channel!(DMA0_CH24, 24); +channel!(DMA0_CH25, 25); +channel!(DMA0_CH26, 26); +channel!(DMA0_CH27, 27); +channel!(DMA0_CH28, 28); +channel!(DMA0_CH29, 29); +channel!(DMA0_CH30, 30); +channel!(DMA0_CH31, 31); +channel!(DMA0_CH32, 32); diff --git a/embassy-imxrt/src/flexcomm/mod.rs b/embassy-imxrt/src/flexcomm/mod.rs new file mode 100644 index 000000000..4473c9a77 --- /dev/null +++ b/embassy-imxrt/src/flexcomm/mod.rs @@ -0,0 +1,252 @@ +//! Implements Flexcomm interface wrapper for easier usage across modules + +pub mod uart; + +use paste::paste; + +use crate::clocks::{enable_and_reset, SysconPeripheral}; +use crate::peripherals::{ + FLEXCOMM0, FLEXCOMM1, FLEXCOMM14, FLEXCOMM15, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, +}; +use crate::{pac, PeripheralType}; + +/// clock selection option +#[derive(Copy, Clone, Debug)] +pub enum Clock { + /// SFRO + Sfro, + + /// FFRO + Ffro, + + /// `AUDIO_PLL` + AudioPll, + + /// MASTER + Master, + + /// FCn_FRG with Main clock source + FcnFrgMain, + + /// FCn_FRG with Pll clock source + FcnFrgPll, + + /// FCn_FRG with Sfro clock source + FcnFrgSfro, + + /// FCn_FRG with Ffro clock source + FcnFrgFfro, + + /// disabled + None, +} + +/// do not allow implementation of trait outside this mod +mod sealed { + /// trait does not get re-exported outside flexcomm mod, allowing us to safely expose only desired APIs + pub trait Sealed {} +} + +/// primary low-level flexcomm interface +pub(crate) trait FlexcommLowLevel: sealed::Sealed + PeripheralType + SysconPeripheral + 'static + Send { + // fetch the flexcomm register block for direct manipulation + fn reg() -> &'static pac::flexcomm0::RegisterBlock; + + // set the clock select for this flexcomm instance and remove from reset + fn enable(clk: Clock); +} + +macro_rules! impl_flexcomm { + ($($idx:expr),*) => { + $( + paste!{ + impl sealed::Sealed for crate::peripherals::[] {} + + impl FlexcommLowLevel for crate::peripherals::[] { + fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock { + // SAFETY: safe from single executor, enforce + // via peripheral reference lifetime tracking + unsafe { + &*crate::pac::[]::ptr() + } + } + + fn enable(clk: Clock) { + // SAFETY: safe from single executor + let clkctl1 = unsafe { crate::pac::Clkctl1::steal() }; + + clkctl1.flexcomm($idx).fcfclksel().write(|w| match clk { + Clock::Sfro => w.sel().sfro_clk(), + Clock::Ffro => w.sel().ffro_clk(), + Clock::AudioPll => w.sel().audio_pll_clk(), + Clock::Master => w.sel().master_clk(), + Clock::FcnFrgMain => w.sel().fcn_frg_clk(), + Clock::FcnFrgPll => w.sel().fcn_frg_clk(), + Clock::FcnFrgSfro => w.sel().fcn_frg_clk(), + Clock::FcnFrgFfro => w.sel().fcn_frg_clk(), + Clock::None => w.sel().none(), // no clock? throw an error? + }); + + clkctl1.flexcomm($idx).frgclksel().write(|w| match clk { + Clock::FcnFrgMain => w.sel().main_clk(), + Clock::FcnFrgPll => w.sel().frg_pll_clk(), + Clock::FcnFrgSfro => w.sel().sfro_clk(), + Clock::FcnFrgFfro => w.sel().ffro_clk(), + _ => w.sel().none(), // not using frg ... + }); + + // todo: add support for frg div/mult + clkctl1 + .flexcomm($idx) + .frgctl() + .write(|w| + // SAFETY: unsafe only used for .bits() call + unsafe { w.mult().bits(0) }); + + enable_and_reset::<[]>(); + } + } + } + )* + } +} + +impl_flexcomm!(0, 1, 2, 3, 4, 5, 6, 7); + +// TODO: FLEXCOMM 14 is untested. Enable SPI support on FLEXCOMM14 +// Add special case FLEXCOMM14 +impl sealed::Sealed for crate::peripherals::FLEXCOMM14 {} + +impl FlexcommLowLevel for crate::peripherals::FLEXCOMM14 { + fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock { + // SAFETY: safe from single executor, enforce + // via peripheral reference lifetime tracking + unsafe { &*crate::pac::Flexcomm14::ptr() } + } + + fn enable(clk: Clock) { + // SAFETY: safe from single executor + let clkctl1 = unsafe { crate::pac::Clkctl1::steal() }; + + clkctl1.fc14fclksel().write(|w| match clk { + Clock::Sfro => w.sel().sfro_clk(), + Clock::Ffro => w.sel().ffro_clk(), + Clock::AudioPll => w.sel().audio_pll_clk(), + Clock::Master => w.sel().master_clk(), + Clock::FcnFrgMain => w.sel().fcn_frg_clk(), + Clock::FcnFrgPll => w.sel().fcn_frg_clk(), + Clock::FcnFrgSfro => w.sel().fcn_frg_clk(), + Clock::FcnFrgFfro => w.sel().fcn_frg_clk(), + Clock::None => w.sel().none(), // no clock? throw an error? + }); + + clkctl1.frg14clksel().write(|w| match clk { + Clock::FcnFrgMain => w.sel().main_clk(), + Clock::FcnFrgPll => w.sel().frg_pll_clk(), + Clock::FcnFrgSfro => w.sel().sfro_clk(), + Clock::FcnFrgFfro => w.sel().ffro_clk(), + _ => w.sel().none(), // not using frg ... + }); + + // todo: add support for frg div/mult + clkctl1.frg14ctl().write(|w| + // SAFETY: unsafe only used for .bits() call + unsafe { w.mult().bits(0) }); + + enable_and_reset::(); + } +} + +// Add special case FLEXCOMM15 +impl sealed::Sealed for crate::peripherals::FLEXCOMM15 {} + +impl FlexcommLowLevel for crate::peripherals::FLEXCOMM15 { + fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock { + // SAFETY: safe from single executor, enforce + // via peripheral reference lifetime tracking + unsafe { &*crate::pac::Flexcomm15::ptr() } + } + + fn enable(clk: Clock) { + // SAFETY: safe from single executor + let clkctl1 = unsafe { crate::pac::Clkctl1::steal() }; + + clkctl1.fc15fclksel().write(|w| match clk { + Clock::Sfro => w.sel().sfro_clk(), + Clock::Ffro => w.sel().ffro_clk(), + Clock::AudioPll => w.sel().audio_pll_clk(), + Clock::Master => w.sel().master_clk(), + Clock::FcnFrgMain => w.sel().fcn_frg_clk(), + Clock::FcnFrgPll => w.sel().fcn_frg_clk(), + Clock::FcnFrgSfro => w.sel().fcn_frg_clk(), + Clock::FcnFrgFfro => w.sel().fcn_frg_clk(), + Clock::None => w.sel().none(), // no clock? throw an error? + }); + clkctl1.frg15clksel().write(|w| match clk { + Clock::FcnFrgMain => w.sel().main_clk(), + Clock::FcnFrgPll => w.sel().frg_pll_clk(), + Clock::FcnFrgSfro => w.sel().sfro_clk(), + Clock::FcnFrgFfro => w.sel().ffro_clk(), + _ => w.sel().none(), // not using frg ... + }); + // todo: add support for frg div/mult + clkctl1.frg15ctl().write(|w| + // SAFETY: unsafe only used for .bits() call + unsafe { w.mult().bits(0) }); + + enable_and_reset::(); + } +} + +macro_rules! into_mode { + ($mode:ident, $($fc:ident),*) => { + paste! { + /// Sealed Mode trait + trait []: FlexcommLowLevel {} + + /// Select mode of operation + #[allow(private_bounds)] + pub trait []: [] { + /// Set mode of operation + fn []() { + Self::reg().pselid().write(|w| w.persel().[<$mode>]()); + } + } + } + + $( + paste!{ + impl [] for crate::peripherals::$fc {} + impl [] for crate::peripherals::$fc {} + } + )* + } +} + +into_mode!(usart, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7); +into_mode!(spi, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM14); +into_mode!(i2c, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM15); + +into_mode!( + i2s_transmit, + FLEXCOMM0, + FLEXCOMM1, + FLEXCOMM2, + FLEXCOMM3, + FLEXCOMM4, + FLEXCOMM5, + FLEXCOMM6, + FLEXCOMM7 +); + +into_mode!( + i2s_receive, + FLEXCOMM0, + FLEXCOMM1, + FLEXCOMM2, + FLEXCOMM3, + FLEXCOMM4, + FLEXCOMM5, + FLEXCOMM6, + FLEXCOMM7 +); diff --git a/embassy-imxrt/src/flexcomm/uart.rs b/embassy-imxrt/src/flexcomm/uart.rs new file mode 100644 index 000000000..230b30d43 --- /dev/null +++ b/embassy-imxrt/src/flexcomm/uart.rs @@ -0,0 +1,1230 @@ +//! Universal Asynchronous Receiver Transmitter (UART) driver. + +use core::future::poll_fn; +use core::marker::PhantomData; +use core::sync::atomic::{compiler_fence, AtomicU8, Ordering}; +use core::task::Poll; + +use embassy_futures::select::{select, Either}; +use embassy_hal_internal::drop::OnDrop; +use embassy_hal_internal::{Peri, PeripheralType}; +use embassy_sync::waitqueue::AtomicWaker; +use paste::paste; + +use crate::dma::AnyChannel; +use crate::flexcomm::Clock; +use crate::gpio::{AnyPin, GpioPin as Pin}; +use crate::interrupt::typelevel::Interrupt; +use crate::iopctl::{DriveMode, DriveStrength, Inverter, IopctlPin, Pull, SlewRate}; +use crate::pac::usart0::cfg::{Clkpol, Datalen, Loop, Paritysel as Parity, Stoplen, Syncen, Syncmst}; +use crate::pac::usart0::ctl::Cc; +use crate::sealed::Sealed; +use crate::{dma, interrupt}; + +/// Driver move trait. +#[allow(private_bounds)] +pub trait Mode: Sealed {} + +/// Blocking mode. +pub struct Blocking; +impl Sealed for Blocking {} +impl Mode for Blocking {} + +/// Async mode. +pub struct Async; +impl Sealed for Async {} +impl Mode for Async {} + +/// Uart driver. +pub struct Uart<'a, M: Mode> { + tx: UartTx<'a, M>, + rx: UartRx<'a, M>, +} + +/// Uart TX driver. +pub struct UartTx<'a, M: Mode> { + info: Info, + tx_dma: Option>, + _phantom: PhantomData<(&'a (), M)>, +} + +/// Uart RX driver. +pub struct UartRx<'a, M: Mode> { + info: Info, + rx_dma: Option>, + _phantom: PhantomData<(&'a (), M)>, +} + +/// UART config +#[derive(Clone, Copy)] +pub struct Config { + /// Baudrate of the Uart + pub baudrate: u32, + /// data length + pub data_bits: Datalen, + /// Parity + pub parity: Parity, + /// Stop bits + pub stop_bits: Stoplen, + /// Polarity of the clock + pub clock_polarity: Clkpol, + /// Sync/ Async operation selection + pub operation: Syncen, + /// Sync master/slave mode selection (only applicable in sync mode) + pub sync_mode_master_select: Syncmst, + /// USART continuous Clock generation enable in synchronous master mode. + pub continuous_clock: Cc, + /// Normal/ loopback mode + pub loopback_mode: Loop, + /// Clock type + pub clock: Clock, +} + +impl Default for Config { + /// Default configuration for single channel sampling. + fn default() -> Self { + Self { + baudrate: 115_200, + data_bits: Datalen::Bit8, + parity: Parity::NoParity, + stop_bits: Stoplen::Bit1, + clock_polarity: Clkpol::FallingEdge, + operation: Syncen::AsynchronousMode, + sync_mode_master_select: Syncmst::Slave, + continuous_clock: Cc::ClockOnCharacter, + loopback_mode: Loop::Normal, + clock: crate::flexcomm::Clock::Sfro, + } + } +} + +/// Uart Errors +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Error { + /// Read error + Read, + + /// Buffer overflow + Overrun, + + /// Noise error + Noise, + + /// Framing error + Framing, + + /// Parity error + Parity, + + /// Failure + Fail, + + /// Invalid argument + InvalidArgument, + + /// Uart baud rate cannot be supported with the given clock + UnsupportedBaudrate, + + /// RX FIFO Empty + RxFifoEmpty, + + /// TX FIFO Full + TxFifoFull, + + /// TX Busy + TxBusy, +} +/// shorthand for -> `Result` +pub type Result = core::result::Result; + +impl<'a, M: Mode> UartTx<'a, M> { + fn new_inner(tx_dma: Option>) -> Self { + let uarttx = Self { + info: T::info(), + tx_dma, + _phantom: PhantomData, + }; + uarttx.info.refcnt.fetch_add(1, Ordering::Relaxed); + uarttx + } +} + +impl<'a, M: Mode> Drop for UartTx<'a, M> { + fn drop(&mut self) { + if self.info.refcnt.fetch_sub(1, Ordering::Relaxed) == 1 { + while self.info.regs.stat().read().txidle().bit_is_clear() {} + + self.info.regs.fifointenclr().modify(|_, w| { + w.txerr() + .set_bit() + .rxerr() + .set_bit() + .txlvl() + .set_bit() + .rxlvl() + .set_bit() + }); + + self.info + .regs + .fifocfg() + .modify(|_, w| w.dmatx().clear_bit().dmarx().clear_bit()); + + self.info.regs.cfg().modify(|_, w| w.enable().disabled()); + } + } +} + +impl<'a> UartTx<'a, Blocking> { + /// Create a new UART which can only send data + /// Unidirectional Uart - Tx only + pub fn new_blocking(_inner: Peri<'a, T>, tx: Peri<'a, impl TxPin>, config: Config) -> Result { + tx.as_tx(); + + let _tx = tx.into(); + Uart::::init::(Some(_tx), None, None, None, config)?; + + Ok(Self::new_inner::(None)) + } + + fn write_byte_internal(&mut self, byte: u8) -> Result<()> { + // SAFETY: unsafe only used for .bits() + self.info + .regs + .fifowr() + .write(|w| unsafe { w.txdata().bits(u16::from(byte)) }); + + Ok(()) + } + + fn blocking_write_byte(&mut self, byte: u8) -> Result<()> { + while self.info.regs.fifostat().read().txnotfull().bit_is_clear() {} + + // Prevent the compiler from reordering write_byte_internal() + // before the loop above. + compiler_fence(Ordering::Release); + + self.write_byte_internal(byte) + } + + fn write_byte(&mut self, byte: u8) -> Result<()> { + if self.info.regs.fifostat().read().txnotfull().bit_is_clear() { + Err(Error::TxFifoFull) + } else { + self.write_byte_internal(byte) + } + } + + /// Transmit the provided buffer blocking execution until done. + pub fn blocking_write(&mut self, buf: &[u8]) -> Result<()> { + for x in buf { + self.blocking_write_byte(*x)?; + } + + Ok(()) + } + + /// Transmit the provided buffer. Non-blocking version, bails out + /// if it would block. + pub fn write(&mut self, buf: &[u8]) -> Result<()> { + for x in buf { + self.write_byte(*x)?; + } + + Ok(()) + } + + /// Flush UART TX blocking execution until done. + pub fn blocking_flush(&mut self) -> Result<()> { + while self.info.regs.stat().read().txidle().bit_is_clear() {} + Ok(()) + } + + /// Flush UART TX. + pub fn flush(&mut self) -> Result<()> { + if self.info.regs.stat().read().txidle().bit_is_clear() { + Err(Error::TxBusy) + } else { + Ok(()) + } + } +} + +impl<'a, M: Mode> UartRx<'a, M> { + fn new_inner(rx_dma: Option>) -> Self { + let uartrx = Self { + info: T::info(), + rx_dma, + _phantom: PhantomData, + }; + uartrx.info.refcnt.fetch_add(1, Ordering::Relaxed); + uartrx + } +} + +impl<'a, M: Mode> Drop for UartRx<'a, M> { + fn drop(&mut self) { + if self.info.refcnt.fetch_sub(1, Ordering::Relaxed) == 1 { + while self.info.regs.stat().read().rxidle().bit_is_clear() {} + + self.info.regs.fifointenclr().modify(|_, w| { + w.txerr() + .set_bit() + .rxerr() + .set_bit() + .txlvl() + .set_bit() + .rxlvl() + .set_bit() + }); + + self.info + .regs + .fifocfg() + .modify(|_, w| w.dmatx().clear_bit().dmarx().clear_bit()); + + self.info.regs.cfg().modify(|_, w| w.enable().disabled()); + } + } +} + +impl<'a> UartRx<'a, Blocking> { + /// Create a new blocking UART which can only receive data + pub fn new_blocking(_inner: Peri<'a, T>, rx: Peri<'a, impl RxPin>, config: Config) -> Result { + rx.as_rx(); + + let _rx = rx.into(); + Uart::::init::(None, Some(_rx), None, None, config)?; + + Ok(Self::new_inner::(None)) + } +} + +impl UartRx<'_, Blocking> { + fn read_byte_internal(&mut self) -> Result { + if self.info.regs.fifostat().read().rxerr().bit_is_set() { + self.info.regs.fifocfg().modify(|_, w| w.emptyrx().set_bit()); + self.info.regs.fifostat().modify(|_, w| w.rxerr().set_bit()); + Err(Error::Read) + } else if self.info.regs.stat().read().parityerrint().bit_is_set() { + self.info.regs.stat().modify(|_, w| w.parityerrint().clear_bit_by_one()); + Err(Error::Parity) + } else if self.info.regs.stat().read().framerrint().bit_is_set() { + self.info.regs.stat().modify(|_, w| w.framerrint().clear_bit_by_one()); + Err(Error::Framing) + } else if self.info.regs.stat().read().rxnoiseint().bit_is_set() { + self.info.regs.stat().modify(|_, w| w.rxnoiseint().clear_bit_by_one()); + Err(Error::Noise) + } else { + let byte = self.info.regs.fiford().read().rxdata().bits() as u8; + Ok(byte) + } + } + + fn read_byte(&mut self) -> Result { + if self.info.regs.fifostat().read().rxnotempty().bit_is_clear() { + Err(Error::RxFifoEmpty) + } else { + self.read_byte_internal() + } + } + + fn blocking_read_byte(&mut self) -> Result { + while self.info.regs.fifostat().read().rxnotempty().bit_is_clear() {} + + // Prevent the compiler from reordering read_byte_internal() + // before the loop above. + compiler_fence(Ordering::Acquire); + + self.read_byte_internal() + } + + /// Read from UART RX. Non-blocking version, bails out if it would + /// block. + pub fn read(&mut self, buf: &mut [u8]) -> Result<()> { + for b in buf.iter_mut() { + *b = self.read_byte()?; + } + + Ok(()) + } + + /// Read from UART RX blocking execution until done. + pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<()> { + for b in buf.iter_mut() { + *b = self.blocking_read_byte()?; + } + + Ok(()) + } +} + +impl<'a, M: Mode> Uart<'a, M> { + fn init( + tx: Option>, + rx: Option>, + rts: Option>, + cts: Option>, + config: Config, + ) -> Result<()> { + T::enable(config.clock); + T::into_usart(); + + let regs = T::info().regs; + + if tx.is_some() { + regs.fifocfg().modify(|_, w| w.emptytx().set_bit().enabletx().enabled()); + + // clear FIFO error + regs.fifostat().write(|w| w.txerr().set_bit()); + } + + if rx.is_some() { + regs.fifocfg().modify(|_, w| w.emptyrx().set_bit().enablerx().enabled()); + + // clear FIFO error + regs.fifostat().write(|w| w.rxerr().set_bit()); + } + + if rts.is_some() && cts.is_some() { + regs.cfg().modify(|_, w| w.ctsen().enabled()); + } + + Self::set_baudrate_inner::(config.baudrate, config.clock)?; + Self::set_uart_config::(config); + + Ok(()) + } + + fn get_fc_freq(clock: Clock) -> Result { + match clock { + Clock::Sfro => Ok(16_000_000), + Clock::Ffro => Ok(48_000_000), + // We only support Sfro and Ffro now. + _ => Err(Error::InvalidArgument), + } + } + + fn set_baudrate_inner(baudrate: u32, clock: Clock) -> Result<()> { + // Get source clock frequency according to clock type. + let source_clock_hz = Self::get_fc_freq(clock)?; + + if baudrate == 0 { + return Err(Error::InvalidArgument); + } + + let regs = T::info().regs; + + // If synchronous master mode is enabled, only configure the BRG value. + if regs.cfg().read().syncen().is_synchronous_mode() { + // Master + if regs.cfg().read().syncmst().is_master() { + // Calculate the BRG value + let brgval = (source_clock_hz / baudrate) - 1; + + // SAFETY: unsafe only used for .bits() + regs.brg().write(|w| unsafe { w.brgval().bits(brgval as u16) }); + } + } else { + // Smaller values of OSR can make the sampling position within a + // data bit less accurate and may potentially cause more noise + // errors or incorrect data. + let (_, osr, brg) = (8..16).rev().fold( + (u32::MAX, u32::MAX, u32::MAX), + |(best_diff, best_osr, best_brg), osrval| { + // Compare source_clock_hz agaist with ((osrval + 1) * baudrate) to make sure + // (source_clock_hz / ((osrval + 1) * baudrate)) is not less than 0. + if source_clock_hz < ((osrval + 1) * baudrate) { + (best_diff, best_osr, best_brg) + } else { + let brgval = (source_clock_hz / ((osrval + 1) * baudrate)) - 1; + // We know brgval will not be less than 0 now, it should have already been a valid u32 value, + // then compare it agaist with 65535. + if brgval > 65535 { + (best_diff, best_osr, best_brg) + } else { + // Calculate the baud rate based on the BRG value + let candidate = source_clock_hz / ((osrval + 1) * (brgval + 1)); + + // Calculate the difference between the + // current baud rate and the desired baud rate + let diff = (candidate as i32 - baudrate as i32).unsigned_abs(); + + // Check if the current calculated difference is the best so far + if diff < best_diff { + (diff, osrval, brgval) + } else { + (best_diff, best_osr, best_brg) + } + } + } + }, + ); + + // Value over range + if brg > 65535 { + return Err(Error::UnsupportedBaudrate); + } + + // SAFETY: unsafe only used for .bits() + regs.osr().write(|w| unsafe { w.osrval().bits(osr as u8) }); + + // SAFETY: unsafe only used for .bits() + regs.brg().write(|w| unsafe { w.brgval().bits(brg as u16) }); + } + + Ok(()) + } + + fn set_uart_config(config: Config) { + let regs = T::info().regs; + + regs.cfg().modify(|_, w| w.enable().disabled()); + + regs.cfg().modify(|_, w| { + w.datalen() + .variant(config.data_bits) + .stoplen() + .variant(config.stop_bits) + .paritysel() + .variant(config.parity) + .loop_() + .variant(config.loopback_mode) + .syncen() + .variant(config.operation) + .clkpol() + .variant(config.clock_polarity) + }); + + regs.cfg().modify(|_, w| w.enable().enabled()); + } + + /// Split the Uart into a transmitter and receiver, which is particularly + /// useful when having two tasks correlating to transmitting and receiving. + pub fn split(self) -> (UartTx<'a, M>, UartRx<'a, M>) { + (self.tx, self.rx) + } + + /// Split the Uart into a transmitter and receiver by mutable reference, + /// which is particularly useful when having two tasks correlating to + /// transmitting and receiving. + pub fn split_ref(&mut self) -> (&mut UartTx<'a, M>, &mut UartRx<'a, M>) { + (&mut self.tx, &mut self.rx) + } +} + +impl<'a> Uart<'a, Blocking> { + /// Create a new blocking UART + pub fn new_blocking( + _inner: Peri<'a, T>, + tx: Peri<'a, impl TxPin>, + rx: Peri<'a, impl RxPin>, + config: Config, + ) -> Result { + tx.as_tx(); + rx.as_rx(); + + let tx = tx.into(); + let rx = rx.into(); + + Self::init::(Some(tx), Some(rx), None, None, config)?; + + Ok(Self { + tx: UartTx::new_inner::(None), + rx: UartRx::new_inner::(None), + }) + } + + /// Read from UART RX blocking execution until done. + pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<()> { + self.rx.blocking_read(buf) + } + + /// Read from UART RX. Non-blocking version, bails out if it would + /// block. + pub fn read(&mut self, buf: &mut [u8]) -> Result<()> { + self.rx.read(buf) + } + + /// Transmit the provided buffer blocking execution until done. + pub fn blocking_write(&mut self, buf: &[u8]) -> Result<()> { + self.tx.blocking_write(buf) + } + + /// Transmit the provided buffer. Non-blocking version, bails out + /// if it would block. + pub fn write(&mut self, buf: &[u8]) -> Result<()> { + self.tx.write(buf) + } + + /// Flush UART TX blocking execution until done. + pub fn blocking_flush(&mut self) -> Result<()> { + self.tx.blocking_flush() + } + + /// Flush UART TX. + pub fn flush(&mut self) -> Result<()> { + self.tx.flush() + } +} + +impl<'a> UartTx<'a, Async> { + /// Create a new DMA enabled UART which can only send data + pub fn new_async( + _inner: Peri<'a, T>, + tx: Peri<'a, impl TxPin>, + _irq: impl interrupt::typelevel::Binding> + 'a, + tx_dma: Peri<'a, impl TxDma>, + config: Config, + ) -> Result { + tx.as_tx(); + + let _tx = tx.into(); + Uart::::init::(Some(_tx), None, None, None, config)?; + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + Ok(Self::new_inner::(Some(tx_dma.into()))) + } + + /// Transmit the provided buffer asynchronously. + pub async fn write(&mut self, buf: &[u8]) -> Result<()> { + let regs = self.info.regs; + + // Disable DMA on completion/cancellation + let _dma_guard = OnDrop::new(|| { + regs.fifocfg().modify(|_, w| w.dmatx().disabled()); + }); + + for chunk in buf.chunks(1024) { + regs.fifocfg().modify(|_, w| w.dmatx().enabled()); + + let ch = self.tx_dma.as_mut().unwrap().reborrow(); + let transfer = unsafe { dma::write(ch, chunk, regs.fifowr().as_ptr() as *mut u8) }; + + let res = select( + transfer, + poll_fn(|cx| { + UART_WAKERS[self.info.index].register(cx.waker()); + + self.info.regs.intenset().write(|w| { + w.framerren() + .set_bit() + .parityerren() + .set_bit() + .rxnoiseen() + .set_bit() + .aberren() + .set_bit() + }); + + let stat = self.info.regs.stat().read(); + + self.info.regs.stat().write(|w| { + w.framerrint() + .clear_bit_by_one() + .parityerrint() + .clear_bit_by_one() + .rxnoiseint() + .clear_bit_by_one() + .aberr() + .clear_bit_by_one() + }); + + if stat.framerrint().bit_is_set() { + Poll::Ready(Err(Error::Framing)) + } else if stat.parityerrint().bit_is_set() { + Poll::Ready(Err(Error::Parity)) + } else if stat.rxnoiseint().bit_is_set() { + Poll::Ready(Err(Error::Noise)) + } else if stat.aberr().bit_is_set() { + Poll::Ready(Err(Error::Fail)) + } else { + Poll::Pending + } + }), + ) + .await; + + match res { + Either::First(()) | Either::Second(Ok(())) => (), + Either::Second(e) => return e, + } + } + + Ok(()) + } + + /// Flush UART TX asynchronously. + pub async fn flush(&mut self) -> Result<()> { + self.wait_on( + |me| { + if me.info.regs.stat().read().txidle().bit_is_set() { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + }, + |me| { + me.info.regs.intenset().write(|w| w.txidleen().set_bit()); + }, + ) + .await + } + + /// Calls `f` to check if we are ready or not. + /// If not, `g` is called once the waker is set (to eg enable the required interrupts). + async fn wait_on(&mut self, mut f: F, mut g: G) -> U + where + F: FnMut(&mut Self) -> Poll, + G: FnMut(&mut Self), + { + poll_fn(|cx| { + // Register waker before checking condition, to ensure that wakes/interrupts + // aren't lost between f() and g() + UART_WAKERS[self.info.index].register(cx.waker()); + let r = f(self); + + if r.is_pending() { + g(self); + } + + r + }) + .await + } +} + +impl<'a> UartRx<'a, Async> { + /// Create a new DMA enabled UART which can only receive data + pub fn new_async( + _inner: Peri<'a, T>, + rx: Peri<'a, impl RxPin>, + _irq: impl interrupt::typelevel::Binding> + 'a, + rx_dma: Peri<'a, impl RxDma>, + config: Config, + ) -> Result { + rx.as_rx(); + + let _rx = rx.into(); + Uart::::init::(None, Some(_rx), None, None, config)?; + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + Ok(Self::new_inner::(Some(rx_dma.into()))) + } + + /// Read from UART RX asynchronously. + pub async fn read(&mut self, buf: &mut [u8]) -> Result<()> { + let regs = self.info.regs; + + // Disable DMA on completion/cancellation + let _dma_guard = OnDrop::new(|| { + regs.fifocfg().modify(|_, w| w.dmarx().disabled()); + }); + + for chunk in buf.chunks_mut(1024) { + regs.fifocfg().modify(|_, w| w.dmarx().enabled()); + + let ch = self.rx_dma.as_mut().unwrap().reborrow(); + let transfer = unsafe { dma::read(ch, regs.fiford().as_ptr() as *const u8, chunk) }; + + let res = select( + transfer, + poll_fn(|cx| { + UART_WAKERS[self.info.index].register(cx.waker()); + + self.info.regs.intenset().write(|w| { + w.framerren() + .set_bit() + .parityerren() + .set_bit() + .rxnoiseen() + .set_bit() + .aberren() + .set_bit() + }); + + let stat = self.info.regs.stat().read(); + + self.info.regs.stat().write(|w| { + w.framerrint() + .clear_bit_by_one() + .parityerrint() + .clear_bit_by_one() + .rxnoiseint() + .clear_bit_by_one() + .aberr() + .clear_bit_by_one() + }); + + if stat.framerrint().bit_is_set() { + Poll::Ready(Err(Error::Framing)) + } else if stat.parityerrint().bit_is_set() { + Poll::Ready(Err(Error::Parity)) + } else if stat.rxnoiseint().bit_is_set() { + Poll::Ready(Err(Error::Noise)) + } else if stat.aberr().bit_is_set() { + Poll::Ready(Err(Error::Fail)) + } else { + Poll::Pending + } + }), + ) + .await; + + match res { + Either::First(()) | Either::Second(Ok(())) => (), + Either::Second(e) => return e, + } + } + + Ok(()) + } +} + +impl<'a> Uart<'a, Async> { + /// Create a new DMA enabled UART + pub fn new_async( + _inner: Peri<'a, T>, + tx: Peri<'a, impl TxPin>, + rx: Peri<'a, impl RxPin>, + _irq: impl interrupt::typelevel::Binding> + 'a, + tx_dma: Peri<'a, impl TxDma>, + rx_dma: Peri<'a, impl RxDma>, + config: Config, + ) -> Result { + tx.as_tx(); + rx.as_rx(); + + let tx = tx.into(); + let rx = rx.into(); + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + Self::init::(Some(tx), Some(rx), None, None, config)?; + + Ok(Self { + tx: UartTx::new_inner::(Some(tx_dma.into())), + rx: UartRx::new_inner::(Some(rx_dma.into())), + }) + } + + /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) + pub fn new_with_rtscts( + _inner: Peri<'a, T>, + tx: Peri<'a, impl TxPin>, + rx: Peri<'a, impl RxPin>, + rts: Peri<'a, impl RtsPin>, + cts: Peri<'a, impl CtsPin>, + _irq: impl interrupt::typelevel::Binding> + 'a, + tx_dma: Peri<'a, impl TxDma>, + rx_dma: Peri<'a, impl RxDma>, + config: Config, + ) -> Result { + tx.as_tx(); + rx.as_rx(); + rts.as_rts(); + cts.as_cts(); + + let tx = tx.into(); + let rx = rx.into(); + let rts = rts.into(); + let cts = cts.into(); + + Self::init::(Some(tx), Some(rx), Some(rts), Some(cts), config)?; + + Ok(Self { + tx: UartTx::new_inner::(Some(tx_dma.into())), + rx: UartRx::new_inner::(Some(rx_dma.into())), + }) + } + + /// Read from UART RX. + pub async fn read(&mut self, buf: &mut [u8]) -> Result<()> { + self.rx.read(buf).await + } + + /// Transmit the provided buffer. + pub async fn write(&mut self, buf: &[u8]) -> Result<()> { + self.tx.write(buf).await + } + + /// Flush UART TX. + pub async fn flush(&mut self) -> Result<()> { + self.tx.flush().await + } +} + +impl embedded_hal_02::serial::Read for UartRx<'_, Blocking> { + type Error = Error; + + fn read(&mut self) -> core::result::Result> { + let mut buf = [0; 1]; + + match self.read(&mut buf) { + Ok(_) => Ok(buf[0]), + Err(Error::RxFifoEmpty) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } +} + +impl embedded_hal_02::serial::Write for UartTx<'_, Blocking> { + type Error = Error; + + fn write(&mut self, word: u8) -> core::result::Result<(), nb::Error> { + match self.write(&[word]) { + Ok(_) => Ok(()), + Err(Error::TxFifoFull) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } + + fn flush(&mut self) -> core::result::Result<(), nb::Error> { + match self.flush() { + Ok(_) => Ok(()), + Err(Error::TxBusy) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } +} + +impl embedded_hal_02::blocking::serial::Write for UartTx<'_, Blocking> { + type Error = Error; + + fn bwrite_all(&mut self, buffer: &[u8]) -> core::result::Result<(), Self::Error> { + self.blocking_write(buffer) + } + + fn bflush(&mut self) -> core::result::Result<(), Self::Error> { + self.blocking_flush() + } +} + +impl embedded_hal_02::serial::Read for Uart<'_, Blocking> { + type Error = Error; + + fn read(&mut self) -> core::result::Result> { + embedded_hal_02::serial::Read::read(&mut self.rx) + } +} + +impl embedded_hal_02::serial::Write for Uart<'_, Blocking> { + type Error = Error; + + fn write(&mut self, word: u8) -> core::result::Result<(), nb::Error> { + embedded_hal_02::serial::Write::write(&mut self.tx, word) + } + + fn flush(&mut self) -> core::result::Result<(), nb::Error> { + embedded_hal_02::serial::Write::flush(&mut self.tx) + } +} + +impl embedded_hal_02::blocking::serial::Write for Uart<'_, Blocking> { + type Error = Error; + + fn bwrite_all(&mut self, buffer: &[u8]) -> core::result::Result<(), Self::Error> { + self.blocking_write(buffer) + } + + fn bflush(&mut self) -> core::result::Result<(), Self::Error> { + self.blocking_flush() + } +} + +impl embedded_hal_nb::serial::Error for Error { + fn kind(&self) -> embedded_hal_nb::serial::ErrorKind { + match *self { + Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat, + Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun, + Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity, + Self::Noise => embedded_hal_nb::serial::ErrorKind::Noise, + _ => embedded_hal_nb::serial::ErrorKind::Other, + } + } +} + +impl embedded_hal_nb::serial::ErrorType for UartRx<'_, Blocking> { + type Error = Error; +} + +impl embedded_hal_nb::serial::ErrorType for UartTx<'_, Blocking> { + type Error = Error; +} + +impl embedded_hal_nb::serial::ErrorType for Uart<'_, Blocking> { + type Error = Error; +} + +impl embedded_hal_nb::serial::Read for UartRx<'_, Blocking> { + fn read(&mut self) -> nb::Result { + let mut buf = [0; 1]; + + match self.read(&mut buf) { + Ok(_) => Ok(buf[0]), + Err(Error::RxFifoEmpty) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } +} + +impl embedded_hal_nb::serial::Write for UartTx<'_, Blocking> { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + match self.write(&[word]) { + Ok(_) => Ok(()), + Err(Error::TxFifoFull) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + match self.flush() { + Ok(_) => Ok(()), + Err(Error::TxBusy) => Err(nb::Error::WouldBlock), + Err(e) => Err(nb::Error::Other(e)), + } + } +} + +impl embedded_hal_nb::serial::Read for Uart<'_, Blocking> { + fn read(&mut self) -> core::result::Result> { + embedded_hal_02::serial::Read::read(&mut self.rx) + } +} + +impl embedded_hal_nb::serial::Write for Uart<'_, Blocking> { + fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { + self.blocking_write(&[char]).map_err(nb::Error::Other) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.blocking_flush().map_err(nb::Error::Other) + } +} + +struct Info { + regs: &'static crate::pac::usart0::RegisterBlock, + index: usize, + refcnt: AtomicU8, +} + +trait SealedInstance { + fn info() -> Info; + fn index() -> usize; +} + +/// UART interrupt handler. +pub struct InterruptHandler { + _phantom: PhantomData, +} + +const UART_COUNT: usize = 8; +static UART_WAKERS: [AtomicWaker; UART_COUNT] = [const { AtomicWaker::new() }; UART_COUNT]; + +impl interrupt::typelevel::Handler for InterruptHandler { + unsafe fn on_interrupt() { + let waker = &UART_WAKERS[T::index()]; + let regs = T::info().regs; + let stat = regs.intstat().read(); + + if stat.txidle().bit_is_set() + || stat.framerrint().bit_is_set() + || stat.parityerrint().bit_is_set() + || stat.rxnoiseint().bit_is_set() + || stat.aberrint().bit_is_set() + { + regs.intenclr().write(|w| { + w.txidleclr() + .set_bit() + .framerrclr() + .set_bit() + .parityerrclr() + .set_bit() + .rxnoiseclr() + .set_bit() + .aberrclr() + .set_bit() + }); + } + + waker.wake(); + } +} + +/// UART instance trait. +#[allow(private_bounds)] +pub trait Instance: crate::flexcomm::IntoUsart + SealedInstance + PeripheralType + 'static + Send { + /// Interrupt for this UART instance. + type Interrupt: interrupt::typelevel::Interrupt; +} + +macro_rules! impl_instance { + ($($n:expr),*) => { + $( + paste!{ + impl SealedInstance for crate::peripherals::[] { + fn info() -> Info { + Info { + regs: unsafe { &*crate::pac::[]::ptr() }, + index: $n, + refcnt: AtomicU8::new(0), + } + } + + #[inline] + fn index() -> usize { + $n + } + } + + impl Instance for crate::peripherals::[] { + type Interrupt = crate::interrupt::typelevel::[]; + } + } + )* + }; +} + +impl_instance!(0, 1, 2, 3, 4, 5, 6, 7); + +impl Sealed for T {} + +/// io configuration trait for Uart Tx configuration +pub trait TxPin: Pin + Sealed + PeripheralType { + /// convert the pin to appropriate function for Uart Tx usage + fn as_tx(&self); +} + +/// io configuration trait for Uart Rx configuration +pub trait RxPin: Pin + Sealed + PeripheralType { + /// convert the pin to appropriate function for Uart Rx usage + fn as_rx(&self); +} + +/// io configuration trait for Uart Cts +pub trait CtsPin: Pin + Sealed + PeripheralType { + /// convert the pin to appropriate function for Uart Cts usage + fn as_cts(&self); +} + +/// io configuration trait for Uart Rts +pub trait RtsPin: Pin + Sealed + PeripheralType { + /// convert the pin to appropriate function for Uart Rts usage + fn as_rts(&self); +} + +macro_rules! impl_pin_trait { + ($fcn:ident, $mode:ident, $($pin:ident, $fn:ident),*) => { + paste! { + $( + impl [<$mode:camel Pin>] for crate::peripherals::$pin { + fn [](&self) { + // UM11147 table 507 pg 495 + self.set_function(crate::iopctl::Function::$fn) + .set_pull(Pull::None) + .enable_input_buffer() + .set_slew_rate(SlewRate::Standard) + .set_drive_strength(DriveStrength::Normal) + .disable_analog_multiplex() + .set_drive_mode(DriveMode::PushPull) + .set_input_inverter(Inverter::Disabled); + } + } + )* + } + }; +} + +// FLEXCOMM0 +impl_pin_trait!(FLEXCOMM0, tx, PIO0_1, F1, PIO3_1, F5); +impl_pin_trait!(FLEXCOMM0, rx, PIO0_2, F1, PIO3_2, F5); +impl_pin_trait!(FLEXCOMM0, cts, PIO0_3, F1, PIO3_3, F5); +impl_pin_trait!(FLEXCOMM0, rts, PIO0_4, F1, PIO3_4, F5); + +// FLEXCOMM1 +impl_pin_trait!(FLEXCOMM1, tx, PIO0_8, F1, PIO7_26, F1); +impl_pin_trait!(FLEXCOMM1, rx, PIO0_9, F1, PIO7_27, F1); +impl_pin_trait!(FLEXCOMM1, cts, PIO0_10, F1, PIO7_28, F1); +impl_pin_trait!(FLEXCOMM1, rts, PIO0_11, F1, PIO7_29, F1); + +// FLEXCOMM2 +impl_pin_trait!(FLEXCOMM2, tx, PIO0_15, F1, PIO7_30, F5); +impl_pin_trait!(FLEXCOMM2, rx, PIO0_16, F1, PIO7_31, F5); +impl_pin_trait!(FLEXCOMM2, cts, PIO0_17, F1, PIO4_8, F5); +impl_pin_trait!(FLEXCOMM2, rts, PIO0_18, F1); + +// FLEXCOMM3 +impl_pin_trait!(FLEXCOMM3, tx, PIO0_22, F1); +impl_pin_trait!(FLEXCOMM3, rx, PIO0_23, F1); +impl_pin_trait!(FLEXCOMM3, cts, PIO0_24, F1); +impl_pin_trait!(FLEXCOMM3, rts, PIO0_25, F1); + +// FLEXCOMM4 +impl_pin_trait!(FLEXCOMM4, tx, PIO0_29, F1); +impl_pin_trait!(FLEXCOMM4, rx, PIO0_30, F1); +impl_pin_trait!(FLEXCOMM4, cts, PIO0_31, F1); +impl_pin_trait!(FLEXCOMM4, rts, PIO1_0, F1); + +// FLEXCOMM5 +impl_pin_trait!(FLEXCOMM5, tx, PIO1_4, F1, PIO3_16, F5); +impl_pin_trait!(FLEXCOMM5, rx, PIO1_5, F1, PIO3_17, F5); +impl_pin_trait!(FLEXCOMM5, cts, PIO1_6, F1, PIO3_18, F5); +impl_pin_trait!(FLEXCOMM5, rts, PIO1_7, F1, PIO3_23, F5); + +// FLEXCOMM6 +impl_pin_trait!(FLEXCOMM6, tx, PIO3_26, F1); +impl_pin_trait!(FLEXCOMM6, rx, PIO3_27, F1); +impl_pin_trait!(FLEXCOMM6, cts, PIO3_28, F1); +impl_pin_trait!(FLEXCOMM6, rts, PIO3_29, F1); + +// FLEXCOMM7 +impl_pin_trait!(FLEXCOMM7, tx, PIO4_1, F1); +impl_pin_trait!(FLEXCOMM7, rx, PIO4_2, F1); +impl_pin_trait!(FLEXCOMM7, cts, PIO4_3, F1); +impl_pin_trait!(FLEXCOMM7, rts, PIO4_4, F1); + +/// UART Tx DMA trait. +#[allow(private_bounds)] +pub trait TxDma: crate::dma::Channel {} + +/// UART Rx DMA trait. +#[allow(private_bounds)] +pub trait RxDma: crate::dma::Channel {} + +macro_rules! impl_dma { + ($fcn:ident, $mode:ident, $dma:ident) => { + paste! { + impl [<$mode Dma>] for crate::peripherals::$dma {} + } + }; +} + +impl_dma!(FLEXCOMM0, Rx, DMA0_CH0); +impl_dma!(FLEXCOMM0, Tx, DMA0_CH1); + +impl_dma!(FLEXCOMM1, Rx, DMA0_CH2); +impl_dma!(FLEXCOMM1, Tx, DMA0_CH3); + +impl_dma!(FLEXCOMM2, Rx, DMA0_CH4); +impl_dma!(FLEXCOMM2, Tx, DMA0_CH5); + +impl_dma!(FLEXCOMM3, Rx, DMA0_CH6); +impl_dma!(FLEXCOMM3, Tx, DMA0_CH7); + +impl_dma!(FLEXCOMM4, Rx, DMA0_CH8); +impl_dma!(FLEXCOMM4, Tx, DMA0_CH9); + +impl_dma!(FLEXCOMM5, Rx, DMA0_CH10); +impl_dma!(FLEXCOMM5, Tx, DMA0_CH11); + +impl_dma!(FLEXCOMM6, Rx, DMA0_CH12); +impl_dma!(FLEXCOMM6, Tx, DMA0_CH13); + +impl_dma!(FLEXCOMM7, Rx, DMA0_CH14); +impl_dma!(FLEXCOMM7, Tx, DMA0_CH15); diff --git a/embassy-imxrt/src/gpio.rs b/embassy-imxrt/src/gpio.rs index 6883c4ee0..e62fde8b1 100644 --- a/embassy-imxrt/src/gpio.rs +++ b/embassy-imxrt/src/gpio.rs @@ -13,7 +13,7 @@ use crate::clocks::enable_and_reset; use crate::iopctl::IopctlPin; pub use crate::iopctl::{AnyPin, DriveMode, DriveStrength, Function, Inverter, Pull, SlewRate}; use crate::sealed::Sealed; -use crate::{interrupt, peripherals, Peri, PeripheralType}; +use crate::{interrupt, peripherals, BitIter, Peri, PeripheralType}; // This should be unique per IMXRT package const PORT_COUNT: usize = 8; @@ -63,24 +63,6 @@ fn GPIO_INTA() { irq_handler(&GPIO_WAKERS); } -#[cfg(feature = "rt")] -struct BitIter(u32); - -#[cfg(feature = "rt")] -impl Iterator for BitIter { - type Item = u32; - - fn next(&mut self) -> Option { - match self.0.trailing_zeros() { - 32 => None, - b => { - self.0 &= !(1 << b); - Some(b) - } - } - } -} - #[cfg(feature = "rt")] fn irq_handler(port_wakers: &[Option<&PortWaker>]) { let reg = unsafe { crate::pac::Gpio::steal() }; diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index b1183d8fc..ad0d9e21c 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs @@ -19,6 +19,8 @@ pub(crate) mod fmt; pub mod clocks; pub mod crc; +pub mod dma; +pub mod flexcomm; pub mod gpio; pub mod iopctl; pub mod rng; @@ -129,14 +131,16 @@ pub fn init(config: config::Config) -> Peripherals { // before doing anything important. let peripherals = Peripherals::take(); + #[cfg(feature = "_time-driver")] + time_driver::init(config.time_interrupt_priority); + unsafe { if let Err(e) = clocks::init(config.clocks) { error!("unable to initialize Clocks for reason: {:?}", e); // Panic here? } + dma::init(); } - #[cfg(feature = "_time-driver")] - time_driver::init(config.time_interrupt_priority); gpio::init(); peripherals @@ -145,3 +149,21 @@ pub fn init(config: config::Config) -> Peripherals { pub(crate) mod sealed { pub trait Sealed {} } + +#[cfg(feature = "rt")] +struct BitIter(u32); + +#[cfg(feature = "rt")] +impl Iterator for BitIter { + type Item = u32; + + fn next(&mut self) -> Option { + match self.0.trailing_zeros() { + 32 => None, + b => { + self.0 &= !(1 << b); + Some(b) + } + } + } +} diff --git a/examples/mimxrt6/src/bin/uart-async.rs b/examples/mimxrt6/src/bin/uart-async.rs new file mode 100644 index 000000000..58e31f379 --- /dev/null +++ b/examples/mimxrt6/src/bin/uart-async.rs @@ -0,0 +1,87 @@ +#![no_std] +#![no_main] + +extern crate embassy_imxrt_examples; + +use defmt::info; +use embassy_executor::Spawner; +use embassy_imxrt::flexcomm::uart::{self, Async, Uart}; +use embassy_imxrt::{bind_interrupts, peripherals}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FLEXCOMM2 => uart::InterruptHandler; + FLEXCOMM4 => uart::InterruptHandler; +}); + +const BUFLEN: usize = 16; + +#[embassy_executor::task] +async fn usart4_task(mut uart: Uart<'static, Async>) { + info!("RX Task"); + + loop { + let mut rx_buf = [0; BUFLEN]; + uart.read(&mut rx_buf).await.unwrap(); + info!("usart4: rx_buf {:02x}", rx_buf); + + Timer::after_millis(10).await; + + let tx_buf = [0xaa; BUFLEN]; + uart.write(&tx_buf).await.unwrap(); + info!("usart4: tx_buf {:02x}", tx_buf); + } +} + +#[embassy_executor::task] +async fn usart2_task(mut uart: Uart<'static, Async>) { + info!("TX Task"); + + loop { + let tx_buf = [0x55; BUFLEN]; + uart.write(&tx_buf).await.unwrap(); + info!("usart2: tx_buf {:02x}", tx_buf); + + Timer::after_millis(10).await; + + let mut rx_buf = [0x00; BUFLEN]; + uart.read(&mut rx_buf).await.unwrap(); + info!("usart2: rx_buf {:02x}", rx_buf); + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("UART test start"); + + let usart4 = Uart::new_with_rtscts( + p.FLEXCOMM4, + p.PIO0_29, + p.PIO0_30, + p.PIO1_0, + p.PIO0_31, + Irqs, + p.DMA0_CH9, + p.DMA0_CH8, + Default::default(), + ) + .unwrap(); + spawner.must_spawn(usart4_task(usart4)); + + let usart2 = Uart::new_with_rtscts( + p.FLEXCOMM2, + p.PIO0_15, + p.PIO0_16, + p.PIO0_18, + p.PIO0_17, + Irqs, + p.DMA0_CH5, + p.DMA0_CH4, + Default::default(), + ) + .unwrap(); + spawner.must_spawn(usart2_task(usart2)); +} diff --git a/examples/mimxrt6/src/bin/uart.rs b/examples/mimxrt6/src/bin/uart.rs new file mode 100644 index 000000000..d6a75f85d --- /dev/null +++ b/examples/mimxrt6/src/bin/uart.rs @@ -0,0 +1,55 @@ +#![no_std] +#![no_main] + +extern crate embassy_imxrt_examples; + +use defmt::info; +use embassy_executor::Spawner; +use embassy_imxrt::flexcomm::uart::{Blocking, Uart, UartRx, UartTx}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn usart4_task(mut uart: UartRx<'static, Blocking>) { + info!("RX Task"); + + loop { + let mut buf = [0; 8]; + + Timer::after_millis(10).await; + + uart.blocking_read(&mut buf).unwrap(); + + let s = core::str::from_utf8(&buf).unwrap(); + + info!("Received '{}'", s); + } +} + +#[embassy_executor::task] +async fn usart2_task(mut uart: UartTx<'static, Blocking>) { + info!("TX Task"); + + loop { + let buf = "Testing\0".as_bytes(); + + uart.blocking_write(buf).unwrap(); + + Timer::after_millis(10).await; + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("UART test start"); + + let usart4 = Uart::new_blocking(p.FLEXCOMM4, p.PIO0_29, p.PIO0_30, Default::default()).unwrap(); + + let (_, usart4) = usart4.split(); + spawner.must_spawn(usart4_task(usart4)); + + let usart2 = UartTx::new_blocking(p.FLEXCOMM2, p.PIO0_15, Default::default()).unwrap(); + spawner.must_spawn(usart2_task(usart2)); +} -- cgit From 117eb45fa0829239da9152b9cf54c3cf706dc76d Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Thu, 15 May 2025 17:53:31 +0200 Subject: add the possibility to document `bind_interrupts` `struct`s the `bind_interrupts` macro creates a `struct` for the interrupts. it was so far not possible to document those (except for STM32) and there was no generic documentation being generated/added either, thus the `missing_docs` lint was triggered for consumers which enabled it. with this change it is now possible to manually add a comment on the `struct` being defined in the macro invocation. to show that this works one RP example has been modified accordingly. --- embassy-imxrt/src/lib.rs | 12 ++++++++---- embassy-nrf/src/lib.rs | 12 ++++++++---- embassy-rp/src/lib.rs | 12 ++++++++---- embassy-stm32/src/lib.rs | 13 ++++++++----- examples/rp/src/bin/adc.rs | 9 ++++++--- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index b1183d8fc..5b7341fbd 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs @@ -54,16 +54,20 @@ pub use crate::pac::NVIC_PRIO_BITS; /// ```rust,ignore /// use embassy_imxrt::{bind_interrupts, flexspi, peripherals}; /// -/// bind_interrupts!(struct Irqs { -/// FLEXSPI_IRQ => flexspi::InterruptHandler; -/// }); +/// bind_interrupts!( +/// /// Binds the FLEXSPI interrupt. +/// struct Irqs { +/// FLEXSPI_IRQ => flexspi::InterruptHandler; +/// } +/// ); /// ``` /// // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. #[macro_export] macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { + ($(#[$attr:meta])* $vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { #[derive(Copy, Clone)] + $(#[$attr])* $vis struct $name; $( diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 7d86e1218..0c5dd059d 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -200,9 +200,12 @@ mod chip; /// ```rust,ignore /// use embassy_nrf::{bind_interrupts, spim, peripherals}; /// -/// bind_interrupts!(struct Irqs { -/// SPIM3 => spim::InterruptHandler; -/// }); +/// bind_interrupts!( +/// /// Binds the SPIM3 interrupt. +/// struct Irqs { +/// SPIM3 => spim::InterruptHandler; +/// } +/// ); /// ``` /// /// Example of how to bind multiple interrupts in a single macro invocation: @@ -219,7 +222,7 @@ mod chip; // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. #[macro_export] macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { + ($(#[$attr:meta])* $vis:vis struct $name:ident { $( $(#[cfg($cond_irq:meta)])? $irq:ident => $( @@ -229,6 +232,7 @@ macro_rules! bind_interrupts { )* }) => { #[derive(Copy, Clone)] + $(#[$attr])* $vis struct $name; $( diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index f549446bc..f3c5a35bb 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -160,15 +160,18 @@ embassy_hal_internal::interrupt_mod!( /// ```rust,ignore /// use embassy_rp::{bind_interrupts, usb, peripherals}; /// -/// bind_interrupts!(struct Irqs { -/// USBCTRL_IRQ => usb::InterruptHandler; -/// }); +/// bind_interrupts!( +/// /// Binds the USB Interrupts. +/// struct Irqs { +/// USBCTRL_IRQ => usb::InterruptHandler; +/// } +/// ); /// ``` /// // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. #[macro_export] macro_rules! bind_interrupts { - ($vis:vis struct $name:ident { + ($(#[$attr:meta])* $vis:vis struct $name:ident { $( $(#[cfg($cond_irq:meta)])? $irq:ident => $( @@ -178,6 +181,7 @@ macro_rules! bind_interrupts { )* }) => { #[derive(Copy, Clone)] + $(#[$attr])* $vis struct $name; $( diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index f8d09413d..973acc9bb 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -163,11 +163,14 @@ pub use crate::_generated::interrupt; /// ```rust,ignore /// use embassy_stm32::{bind_interrupts, i2c, peripherals}; /// -/// bind_interrupts!(struct Irqs { -/// I2C1 => i2c::EventInterruptHandler, i2c::ErrorInterruptHandler; -/// I2C2_3 => i2c::EventInterruptHandler, i2c::ErrorInterruptHandler, -/// i2c::EventInterruptHandler, i2c::ErrorInterruptHandler; -/// }); +/// bind_interrupts!( +/// /// Binds the I2C interrupts. +/// struct Irqs { +/// I2C1 => i2c::EventInterruptHandler, i2c::ErrorInterruptHandler; +/// I2C2_3 => i2c::EventInterruptHandler, i2c::ErrorInterruptHandler, +/// i2c::EventInterruptHandler, i2c::ErrorInterruptHandler; +/// } +/// ); /// ``` // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs index 1bb7c2249..015915586 100644 --- a/examples/rp/src/bin/adc.rs +++ b/examples/rp/src/bin/adc.rs @@ -12,9 +12,12 @@ use embassy_rp::gpio::Pull; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; -bind_interrupts!(struct Irqs { - ADC_IRQ_FIFO => InterruptHandler; -}); +bind_interrupts!( + /// Binds the ADC interrupts. + struct Irqs { + ADC_IRQ_FIFO => InterruptHandler; + } +); #[embassy_executor::main] async fn main(_spawner: Spawner) { -- cgit From 05bfbacee55207f8065b6e9bbbc0d5454e77668f Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Thu, 15 May 2025 18:36:51 +0200 Subject: `embassy-nxp`: make `defmt` optional also enable it on all dependencies (where available). this is needed because in a next commit we'll add code to `embassy-hal-internal` which uses the feature in a macro, as it expects `defmt` to be optional in all embassy HALs. this was the only HAL where that wasn't the case. note that this is a breaking change for consumers! if you wish to use `defmt` in `embassy-nxp` you now need to enable the feature. --- embassy-nxp/Cargo.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index cf36a67ec..031cd4aba 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml @@ -10,8 +10,11 @@ critical-section = "1.1.2" embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } lpc55-pac = "0.5.0" -defmt = "0.3.8" +defmt = { version = "0.3.8", optional = true } [features] default = ["rt"] -rt = ["lpc55-pac/rt"] \ No newline at end of file +rt = ["lpc55-pac/rt"] + +## Enable [defmt support](https://docs.rs/defmt) and enables `defmt` debug-log messages and formatting in embassy drivers. +defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt"] -- cgit From 4a089fe2455f22f956455548816fcd96735e38d8 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Thu, 15 May 2025 17:29:23 +0200 Subject: rp: add missing `Debug` and `defmt::Format` `derive`s for ADC this doesn't cover every `struct` & co. in `embassy-rp`, but at least it adds those needed for `Adc` and `adc::Channel`. --- embassy-hal-internal/src/macros.rs | 2 ++ embassy-hal-internal/src/peripheral.rs | 2 ++ embassy-rp/src/adc.rs | 2 ++ embassy-rp/src/gpio.rs | 2 ++ 4 files changed, 8 insertions(+) diff --git a/embassy-hal-internal/src/macros.rs b/embassy-hal-internal/src/macros.rs index cd2bc3cab..ce72ded5c 100644 --- a/embassy-hal-internal/src/macros.rs +++ b/embassy-hal-internal/src/macros.rs @@ -8,6 +8,8 @@ macro_rules! peripherals_definition { $(#[$cfg])? #[allow(non_camel_case_types)] #[doc = concat!(stringify!($name), " peripheral")] + #[derive(Debug)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct $name { _private: () } $(#[$cfg])? diff --git a/embassy-hal-internal/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs index 803259bb8..b1868caf6 100644 --- a/embassy-hal-internal/src/peripheral.rs +++ b/embassy-hal-internal/src/peripheral.rs @@ -14,6 +14,8 @@ use core::ops::Deref; /// the driver code would be monomorphized two times. With Peri, the driver is generic /// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes /// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization. +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Peri<'a, T: PeripheralType> { inner: T, _lifetime: PhantomData<&'a mut T>, diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index ec0c8c46c..2db8e63d7 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -21,6 +21,8 @@ static WAKER: AtomicWaker = AtomicWaker::new(); #[derive(Default)] pub struct Config {} +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] enum Source<'p> { Pin(Peri<'p, AnyPin>), TempSensor(Peri<'p, ADC_TEMP_SENSOR>), diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index af0837f6a..2fb2d65c2 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -932,6 +932,8 @@ pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { } /// Type-erased GPIO pin +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct AnyPin { pin_bank: u8, } -- cgit From 466e1ee9eff2a40f562b0f970e3afcdeac017cfb Mon Sep 17 00:00:00 2001 From: Tobias Naumann Date: Fri, 16 May 2025 13:05:35 +0200 Subject: Impl Drop for stm32 Rng --- embassy-stm32/src/rng.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 250a08a39..8fa1b3a9d 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -186,6 +186,15 @@ impl<'d, T: Instance> Rng<'d, T> { } } +impl<'d, T: Instance> Drop for Rng<'d, T> { + fn drop(&mut self) { + T::regs().cr().modify(|reg| { + reg.set_rngen(false); + }); + rcc::disable::(); + } +} + impl<'d, T: Instance> RngCore for Rng<'d, T> { fn next_u32(&mut self) -> u32 { loop { -- cgit From 1eb76eb59170f3953c390385fc572cf36536f652 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 16 May 2025 09:45:02 +0200 Subject: fix: add bank configuration doc build features --- embassy-stm32/Cargo.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 972307bec..873c9b6ae 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -19,16 +19,22 @@ flavors = [ { regex_feature = "stm32f1.*", target = "thumbv7m-none-eabi" }, { regex_feature = "stm32f2.*", target = "thumbv7m-none-eabi" }, { regex_feature = "stm32f3.*", target = "thumbv7em-none-eabi" }, - { regex_feature = "stm32f4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, + { regex_feature = "stm32f4[2367]..[ig]", target = "thumbv7em-none-eabi", features = ["low-power", "dual-bank"] }, + { regex_feature = "stm32f4.*", target = "thumbv7em-none-eabi", features = ["low-power", "single-bank"] }, + { regex_feature = "stm32f7[67]..[ig]", target = "thumbv7em-none-eabi", features = ["dual-bank"] }, { regex_feature = "stm32f7.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32c0.*", target = "thumbv6m-none-eabi" }, + { regex_feature = "stm32g0...c", target = "thumbv6m-none-eabi", features = ["dual-bank"] }, { regex_feature = "stm32g0.*", target = "thumbv6m-none-eabi" }, + { regex_feature = "stm32g4[78].*", target = "thumbv7em-none-eabi", features = ["low-power", "dual-bank"] }, { regex_feature = "stm32g4.*", target = "thumbv7em-none-eabi", features = ["low-power"] }, { regex_feature = "stm32h5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, { regex_feature = "stm32h7.*", target = "thumbv7em-none-eabi" }, { regex_feature = "stm32l0.*", target = "thumbv6m-none-eabi", features = ["low-power"] }, { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, + { regex_feature = "stm32l4[pqrs].*", target = "thumbv7em-none-eabi", features = ["dual-bank"] }, { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, + { regex_feature = "stm32l5...e", target = "thumbv8m.main-none-eabihf", features = ["low-power", "dual-bank"] }, { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, { regex_feature = "stm32u0.*", target = "thumbv6m-none-eabi" }, { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, @@ -38,7 +44,7 @@ flavors = [ ] [package.metadata.docs.rs] -features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time", "stm32h755zi-cm7"] +features = ["defmt", "unstable-pac", "exti", "time-driver-any", "time", "stm32h755zi-cm7", "single-bank"] rustdoc-args = ["--cfg", "docsrs"] [dependencies] -- cgit From e2d053e5a85bc0206b6d088f2b794211d0a46e96 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 May 2025 14:48:18 +0200 Subject: Fix a minor formatting issue in `README.md` --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 669fa469b..68d8460d3 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Rust's [async/await](https://rust-lang.github.io/async-book/) allows for unprece ## Batteries included -- **Hardware Abstraction Layers - ** - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy. +- **Hardware Abstraction Layers** + - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy. - [embassy-stm32](https://docs.embassy.dev/embassy-stm32/), for all STM32 microcontroller families. - [embassy-nrf](https://docs.embassy.dev/embassy-nrf/), for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series. - [embassy-rp](https://docs.embassy.dev/embassy-rp/), for the Raspberry Pi RP2040 and RP23xx microcontrollers. -- cgit From e4fc48764491f8981e4a145a72e9b6e72df8c546 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 18 May 2025 20:32:48 +0200 Subject: Add rand-core v0.9 support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Aurélien Jacobs --- embassy-imxrt/Cargo.toml | 4 +- embassy-imxrt/src/rng.rs | 48 +++++++++++++--- embassy-nrf/Cargo.toml | 4 +- embassy-nrf/src/rng.rs | 47 +++++++++++----- embassy-rp/Cargo.toml | 4 +- embassy-rp/src/clocks.rs | 49 ++++++++++++++--- embassy-rp/src/trng.rs | 25 +++++++-- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rng.rs | 64 ++++++++++++++++------ examples/mimxrt6/Cargo.toml | 1 - examples/mimxrt6/src/bin/rng.rs | 7 +-- examples/nrf-rtos-trace/Cargo.toml | 1 - examples/nrf52840/Cargo.toml | 2 +- examples/nrf52840/src/bin/rng.rs | 2 +- examples/nrf5340/Cargo.toml | 1 - examples/rp/Cargo.toml | 3 +- examples/rp/src/bin/ethernet_w5500_icmp.rs | 1 - examples/rp/src/bin/ethernet_w5500_icmp_ping.rs | 1 - examples/rp/src/bin/ethernet_w5500_multisocket.rs | 1 - examples/rp/src/bin/ethernet_w5500_tcp_client.rs | 1 - examples/rp/src/bin/ethernet_w5500_tcp_server.rs | 1 - examples/rp/src/bin/ethernet_w5500_udp.rs | 1 - examples/rp/src/bin/orchestrate_tasks.rs | 1 - examples/rp/src/bin/sharing.rs | 1 - examples/rp/src/bin/spi_gc9a01.rs | 1 - examples/rp/src/bin/usb_ethernet.rs | 1 - examples/rp/src/bin/usb_hid_mouse.rs | 4 +- examples/rp/src/bin/wifi_ap_tcp_server.rs | 1 - examples/rp/src/bin/wifi_tcp_server.rs | 1 - examples/rp/src/bin/wifi_webrequest.rs | 1 - examples/rp235x/Cargo.toml | 1 - examples/rp235x/src/bin/sharing.rs | 1 - examples/rp235x/src/bin/trng.rs | 5 +- examples/std/Cargo.toml | 2 +- examples/std/src/bin/net.rs | 4 +- examples/std/src/bin/net_dns.rs | 4 +- examples/std/src/bin/net_ppp.rs | 4 +- examples/std/src/bin/net_udp.rs | 4 +- examples/std/src/bin/tcp_accept.rs | 4 +- examples/stm32f7/Cargo.toml | 1 - examples/stm32f7/src/bin/eth.rs | 1 - examples/stm32h5/Cargo.toml | 1 - examples/stm32h5/src/bin/eth.rs | 1 - examples/stm32h7/Cargo.toml | 1 - examples/stm32h7/src/bin/eth.rs | 1 - examples/stm32h7/src/bin/eth_client.rs | 1 - examples/stm32h7/src/bin/eth_client_mii.rs | 1 - examples/stm32h723/Cargo.toml | 1 - examples/stm32h742/Cargo.toml | 1 - examples/stm32h755cm4/Cargo.toml | 1 - examples/stm32h755cm7/Cargo.toml | 1 - examples/stm32h7b0/Cargo.toml | 1 - examples/stm32h7rs/Cargo.toml | 1 - examples/stm32h7rs/src/bin/eth.rs | 1 - examples/stm32l4/Cargo.toml | 1 - .../stm32l4/src/bin/spe_adin1110_http_server.rs | 1 - examples/stm32l5/Cargo.toml | 1 - examples/stm32l5/src/bin/usb_ethernet.rs | 1 - tests/rp/Cargo.toml | 1 - tests/rp/src/bin/ethernet_w5100s_perf.rs | 1 - tests/stm32/Cargo.toml | 4 +- tests/stm32/src/bin/eth.rs | 1 - tests/utils/Cargo.toml | 2 +- 63 files changed, 218 insertions(+), 122 deletions(-) mode change 100644 => 100755 examples/nrf52840/src/bin/rng.rs mode change 100644 => 100755 examples/rp/src/bin/usb_hid_mouse.rs diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml index f16002a8d..d8cf3aaba 100644 --- a/embassy-imxrt/Cargo.toml +++ b/embassy-imxrt/Cargo.toml @@ -80,9 +80,11 @@ cortex-m = "0.7.6" critical-section = "1.1" embedded-io = { version = "0.6.1" } embedded-io-async = { version = "0.6.1" } -rand_core = "0.6.4" fixed = "1.23.1" +rand-core-06 = { package = "rand_core", version = "0.6" } +rand-core-09 = { package = "rand_core", version = "0.9" } + embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [ "unproven", ] } diff --git a/embassy-imxrt/src/rng.rs b/embassy-imxrt/src/rng.rs index 67e7ab65d..75f243df9 100644 --- a/embassy-imxrt/src/rng.rs +++ b/embassy-imxrt/src/rng.rs @@ -6,7 +6,6 @@ use core::task::Poll; use embassy_futures::block_on; use embassy_sync::waitqueue::AtomicWaker; -use rand_core::{CryptoRng, RngCore}; use crate::clocks::{enable_and_reset, SysconPeripheral}; use crate::interrupt::typelevel::Interrupt; @@ -201,32 +200,63 @@ impl<'d> Rng<'d> { .mctl() .modify(|_, w| w.trng_acc().set_bit().prgm().clear_bit()); } -} -impl RngCore for Rng<'_> { - fn next_u32(&mut self) -> u32 { + /// Generate a random u32 + pub fn blocking_next_u32(&mut self) -> u32 { let mut bytes = [0u8; 4]; block_on(self.async_fill_bytes(&mut bytes)).unwrap(); u32::from_ne_bytes(bytes) } - fn next_u64(&mut self) -> u64 { + /// Generate a random u64 + pub fn blocking_next_u64(&mut self) -> u64 { let mut bytes = [0u8; 8]; block_on(self.async_fill_bytes(&mut bytes)).unwrap(); u64::from_ne_bytes(bytes) } - fn fill_bytes(&mut self, dest: &mut [u8]) { + /// Fill a slice with random bytes. + pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) { block_on(self.async_fill_bytes(dest)).unwrap(); } +} - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.fill_bytes(dest); +impl<'d> rand_core_06::RngCore for Rng<'d> { + fn next_u32(&mut self) -> u32 { + self.blocking_next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.blocking_next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.blocking_fill_bytes(dest); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { + self.blocking_fill_bytes(dest); Ok(()) } } -impl CryptoRng for Rng<'_> {} +impl<'d> rand_core_06::CryptoRng for Rng<'d> {} + +impl<'d> rand_core_09::RngCore for Rng<'d> { + fn next_u32(&mut self) -> u32 { + self.blocking_next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.blocking_next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.blocking_fill_bytes(dest); + } +} + +impl<'d> rand_core_09::CryptoRng for Rng<'d> {} struct Info { regs: crate::pac::Trng, diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 6ca099599..e4e143c65 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -154,6 +154,9 @@ embedded-hal-async = { version = "1.0" } embedded-io = { version = "0.6.0" } embedded-io-async = { version = "0.6.1" } +rand-core-06 = { package = "rand_core", version = "0.6" } +rand-core-09 = { package = "rand_core", version = "0.9" } + nrf-pac = "0.1.0" defmt = { version = "0.3", optional = true } @@ -162,7 +165,6 @@ log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" critical-section = "1.1" -rand_core = "0.6.3" fixed = "1.10.0" embedded-storage = "0.3.1" embedded-storage-async = "0.4.1" diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index e75ffda00..7e42dc938 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs @@ -167,6 +167,21 @@ impl<'d, T: Instance> Rng<'d, T> { self.stop(); } + + /// Generate a random u32 + pub fn blocking_next_u32(&mut self) -> u32 { + let mut bytes = [0; 4]; + self.blocking_fill_bytes(&mut bytes); + // We don't care about the endianness, so just use the native one. + u32::from_ne_bytes(bytes) + } + + /// Generate a random u64 + pub fn blocking_next_u64(&mut self) -> u64 { + let mut bytes = [0; 8]; + self.blocking_fill_bytes(&mut bytes); + u64::from_ne_bytes(bytes) + } } impl<'d, T: Instance> Drop for Rng<'d, T> { @@ -180,31 +195,37 @@ impl<'d, T: Instance> Drop for Rng<'d, T> { } } -impl<'d, T: Instance> rand_core::RngCore for Rng<'d, T> { +impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> { fn fill_bytes(&mut self, dest: &mut [u8]) { self.blocking_fill_bytes(dest); } - fn next_u32(&mut self) -> u32 { - let mut bytes = [0; 4]; - self.blocking_fill_bytes(&mut bytes); - // We don't care about the endianness, so just use the native one. - u32::from_ne_bytes(bytes) + self.blocking_next_u32() } - fn next_u64(&mut self) -> u64 { - let mut bytes = [0; 8]; - self.blocking_fill_bytes(&mut bytes); - u64::from_ne_bytes(bytes) + self.blocking_next_u64() } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { self.blocking_fill_bytes(dest); Ok(()) } } -impl<'d, T: Instance> rand_core::CryptoRng for Rng<'d, T> {} +impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {} + +impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> { + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.blocking_fill_bytes(dest); + } + fn next_u32(&mut self) -> u32 { + self.blocking_next_u32() + } + fn next_u64(&mut self) -> u64 { + self.blocking_next_u64() + } +} + +impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {} /// Peripheral static state pub(crate) struct State { diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 8fb8a50fd..849cb549a 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -157,7 +157,6 @@ embedded-io = { version = "0.6.1" } embedded-io-async = { version = "0.6.1" } embedded-storage = { version = "0.3" } embedded-storage-async = { version = "0.4.1" } -rand_core = "0.6.4" fixed = "1.28.0" rp-pac = { version = "7.0.0" } @@ -167,6 +166,9 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-nb = { version = "1.0" } +rand-core-06 = { package = "rand_core", version = "0.6" } +rand-core-09 = { package = "rand_core", version = "0.9" } + pio = { version = "0.3" } rp2040-boot2 = "0.3" document-features = "0.2.10" diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 857877680..d79bffab3 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -1776,7 +1776,8 @@ impl<'d, T: GpoutPin> Drop for Gpout<'d, T> { pub struct RoscRng; impl RoscRng { - fn next_u8() -> u8 { + /// Get a random u8 + pub fn next_u8() -> u8 { let random_reg = pac::ROSC.randombit(); let mut acc = 0; for _ in 0..u8::BITS { @@ -1785,26 +1786,60 @@ impl RoscRng { } acc } + + /// Get a random u32 + pub fn next_u32(&mut self) -> u32 { + rand_core_09::impls::next_u32_via_fill(self) + } + + /// Get a random u64 + pub fn next_u64(&mut self) -> u64 { + rand_core_09::impls::next_u64_via_fill(self) + } + + /// Fill a slice with random bytes + pub fn fill_bytes(&mut self, dest: &mut [u8]) { + dest.fill_with(Self::next_u8) + } } -impl rand_core::RngCore for RoscRng { - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - Ok(self.fill_bytes(dest)) +impl rand_core_06::RngCore for RoscRng { + fn next_u32(&mut self) -> u32 { + self.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.fill_bytes(dest); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { + self.fill_bytes(dest); + Ok(()) } +} + +impl rand_core_06::CryptoRng for RoscRng {} +impl rand_core_09::RngCore for RoscRng { fn next_u32(&mut self) -> u32 { - rand_core::impls::next_u32_via_fill(self) + self.next_u32() } fn next_u64(&mut self) -> u64 { - rand_core::impls::next_u64_via_fill(self) + self.next_u64() } fn fill_bytes(&mut self, dest: &mut [u8]) { - dest.fill_with(Self::next_u8) + self.fill_bytes(dest); } } +impl rand_core_09::CryptoRng for RoscRng {} + /// Enter the `DORMANT` sleep state. This will stop *all* internal clocks /// and can only be exited through resets, dormant-wake GPIO interrupts, /// and RTC interrupts. If RTC is clocked from an internal clock source diff --git a/embassy-rp/src/trng.rs b/embassy-rp/src/trng.rs index a8a0172be..a3f23c1f2 100644 --- a/embassy-rp/src/trng.rs +++ b/embassy-rp/src/trng.rs @@ -7,7 +7,6 @@ use core::task::Poll; use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; -use rand_core::Error; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::peripherals::TRNG; @@ -369,7 +368,7 @@ impl<'d, T: Instance> Trng<'d, T> { } } -impl<'d, T: Instance> rand_core::RngCore for Trng<'d, T> { +impl<'d, T: Instance> rand_core_06::RngCore for Trng<'d, T> { fn next_u32(&mut self) -> u32 { self.blocking_next_u32() } @@ -379,16 +378,32 @@ impl<'d, T: Instance> rand_core::RngCore for Trng<'d, T> { } fn fill_bytes(&mut self, dest: &mut [u8]) { - self.blocking_fill_bytes(dest) + self.blocking_fill_bytes(dest); } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { self.blocking_fill_bytes(dest); Ok(()) } } -impl<'d, T: Instance> rand_core::CryptoRng for Trng<'d, T> {} +impl<'d, T: Instance> rand_core_06::CryptoRng for Trng<'d, T> {} + +impl<'d, T: Instance> rand_core_09::RngCore for Trng<'d, T> { + fn next_u32(&mut self) -> u32 { + self.blocking_next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.blocking_next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.blocking_fill_bytes(dest); + } +} + +impl<'d, T: Instance> rand_core_09::CryptoRng for Trng<'d, T> {} /// TRNG interrupt handler. pub struct InterruptHandler { diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 972307bec..35c1291fd 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -63,13 +63,15 @@ embedded-can = "0.4" embedded-storage = "0.3.1" embedded-storage-async = { version = "0.4.1" } +rand-core-06 = { package = "rand_core", version = "0.6" } +rand-core-09 = { package = "rand_core", version = "0.9" } + defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" futures-util = { version = "0.3.30", default-features = false } -rand_core = "0.6.3" sdio-host = "0.9.0" critical-section = "1.1" #stm32-metapac = { version = "16" } diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 8fa1b3a9d..312f343b9 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -7,7 +7,6 @@ use core::task::Poll; use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; -use rand_core::{CryptoRng, RngCore}; use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, pac, peripherals, rcc, Peri}; @@ -184,19 +183,9 @@ impl<'d, T: Instance> Rng<'d, T> { Ok(()) } -} - -impl<'d, T: Instance> Drop for Rng<'d, T> { - fn drop(&mut self) { - T::regs().cr().modify(|reg| { - reg.set_rngen(false); - }); - rcc::disable::(); - } -} -impl<'d, T: Instance> RngCore for Rng<'d, T> { - fn next_u32(&mut self) -> u32 { + /// Get a random u32 + pub fn next_u32(&mut self) -> u32 { loop { let sr = T::regs().sr().read(); if sr.seis() | sr.ceis() { @@ -207,13 +196,15 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> { } } - fn next_u64(&mut self) -> u64 { + /// Get a random u64 + pub fn next_u64(&mut self) -> u64 { let mut rand = self.next_u32() as u64; rand |= (self.next_u32() as u64) << 32; rand } - fn fill_bytes(&mut self, dest: &mut [u8]) { + /// Fill a slice with random bytes + pub fn fill_bytes(&mut self, dest: &mut [u8]) { for chunk in dest.chunks_mut(4) { let rand = self.next_u32(); for (slot, num) in chunk.iter_mut().zip(rand.to_ne_bytes().iter()) { @@ -221,14 +212,53 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> { } } } +} + +impl<'d, T: Instance> Drop for Rng<'d, T> { + fn drop(&mut self) { + T::regs().cr().modify(|reg| { + reg.set_rngen(false); + }); + rcc::disable::(); + } +} - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { +impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> { + fn next_u32(&mut self) -> u32 { + self.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.fill_bytes(dest); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { self.fill_bytes(dest); Ok(()) } } -impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} +impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {} + +impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> { + fn next_u32(&mut self) -> u32 { + self.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.fill_bytes(dest); + } +} + +impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {} trait SealedInstance { fn regs() -> pac::rng::Rng; diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml index b0c56f003..27c3a27dc 100644 --- a/examples/mimxrt6/Cargo.toml +++ b/examples/mimxrt6/Cargo.toml @@ -20,7 +20,6 @@ embedded-hal-async = "1.0.0" mimxrt600-fcb = "0.2.2" panic-probe = { version = "0.3", features = ["print-defmt"] } -rand = { version = "0.8.5", default-features = false } # cargo build/run [profile.dev] diff --git a/examples/mimxrt6/src/bin/rng.rs b/examples/mimxrt6/src/bin/rng.rs index 5f64cb96a..9468dd109 100644 --- a/examples/mimxrt6/src/bin/rng.rs +++ b/examples/mimxrt6/src/bin/rng.rs @@ -7,7 +7,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_imxrt::rng::Rng; use embassy_imxrt::{bind_interrupts, peripherals, rng}; -use rand::RngCore; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -29,10 +28,10 @@ async fn main(_spawner: Spawner) { // RngCore interface let mut random_bytes = [0; 16]; - let random_u32 = rng.next_u32(); - let random_u64 = rng.next_u64(); + let random_u32 = rng.blocking_next_u32(); + let random_u64 = rng.blocking_next_u64(); - rng.fill_bytes(&mut random_bytes); + rng.blocking_fill_bytes(&mut random_bytes); info!("random_u32 {}", random_u32); info!("random_u64 {}", random_u64); diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index af12212cd..ba609d889 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -23,7 +23,6 @@ embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["nrf5 cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3" } -rand = { version = "0.8.4", default-features = false } serde = { version = "1.0.136", default-features = false } rtos-trace = "0.1.3" systemview-target = { version = "0.1.2", features = ["callbacks-app", "callbacks-os", "log", "cortex-m"] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 902193f3a..ff40a34af 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -25,7 +25,7 @@ static_cell = { version = "2" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -rand = { version = "0.8.4", default-features = false } +rand = { version = "0.9.0", default-features = false } embedded-storage = "0.3.1" usbd-hid = "0.8.1" serde = { version = "1.0.136", default-features = false } diff --git a/examples/nrf52840/src/bin/rng.rs b/examples/nrf52840/src/bin/rng.rs old mode 100644 new mode 100755 index 326054c9a..f32d17cd9 --- a/examples/nrf52840/src/bin/rng.rs +++ b/examples/nrf52840/src/bin/rng.rs @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { defmt::info!("Some random bytes: {:?}", bytes); // Sync API with `rand` - defmt::info!("A random number from 1 to 10: {:?}", rng.gen_range(1..=10)); + defmt::info!("A random number from 1 to 10: {:?}", rng.random_range(1..=10)); let mut bytes = [0; 1024]; rng.fill_bytes(&mut bytes).await; diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 459c43221..5c226695f 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -21,7 +21,6 @@ static_cell = "2" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } -rand = { version = "0.8.4", default-features = false } embedded-storage = "0.3.1" usbd-hid = "0.8.1" serde = { version = "1.0.136", default-features = false } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 45ca30e4c..aacf9846a 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -45,7 +45,6 @@ byte-slice-cast = { version = "1.2.0", default-features = false } smart-leds = "0.4.0" heapless = "0.8" usbd-hid = "0.8.1" -rand_core = "0.6.4" embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = "1.0" @@ -55,7 +54,7 @@ embedded-storage = { version = "0.3" } static_cell = "2.1" portable-atomic = { version = "1.5", features = ["critical-section"] } log = "0.4" -rand = { version = "0.8.5", default-features = false } +rand = { version = "0.9.0", default-features = false } embedded-sdmmc = "0.7.0" [profile.release] diff --git a/examples/rp/src/bin/ethernet_w5500_icmp.rs b/examples/rp/src/bin/ethernet_w5500_icmp.rs index 5c42b2dde..e434b3bbc 100644 --- a/examples/rp/src/bin/ethernet_w5500_icmp.rs +++ b/examples/rp/src/bin/ethernet_w5500_icmp.rs @@ -21,7 +21,6 @@ use embassy_rp::peripherals::SPI0; use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::{Delay, Instant, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs b/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs index 0724311f9..0ec594fd5 100644 --- a/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs +++ b/examples/rp/src/bin/ethernet_w5500_icmp_ping.rs @@ -23,7 +23,6 @@ use embassy_rp::peripherals::SPI0; use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::{Delay, Duration}; use embedded_hal_bus::spi::ExclusiveDevice; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index 2bea9fc9d..27e2f3c30 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs @@ -18,7 +18,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::{Delay, Duration}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index 78d1b0b83..ba82f2a60 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -20,7 +20,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::{Delay, Duration, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index 25a38c714..5c56dcafa 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs @@ -19,7 +19,6 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::{Delay, Duration}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 683e29222..c5fc8de1d 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs @@ -18,7 +18,6 @@ use embassy_rp::peripherals::SPI0; use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::Delay; use embedded_hal_bus::spi::ExclusiveDevice; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/orchestrate_tasks.rs b/examples/rp/src/bin/orchestrate_tasks.rs index 5e2775793..c35679251 100644 --- a/examples/rp/src/bin/orchestrate_tasks.rs +++ b/examples/rp/src/bin/orchestrate_tasks.rs @@ -29,7 +29,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::Mutex; use embassy_sync::{channel, signal}; use embassy_time::{Duration, Timer}; -use rand::RngCore; use {defmt_rtt as _, panic_probe as _}; // Hardware resource assignment. See other examples for different ways of doing this. diff --git a/examples/rp/src/bin/sharing.rs b/examples/rp/src/bin/sharing.rs index 497c4f845..856be6ace 100644 --- a/examples/rp/src/bin/sharing.rs +++ b/examples/rp/src/bin/sharing.rs @@ -27,7 +27,6 @@ use embassy_rp::{bind_interrupts, interrupt}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::{blocking_mutex, mutex}; use embassy_time::{Duration, Ticker}; -use rand::RngCore; use static_cell::{ConstStaticCell, StaticCell}; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/spi_gc9a01.rs b/examples/rp/src/bin/spi_gc9a01.rs index 30afc253d..fdef09d4b 100644 --- a/examples/rp/src/bin/spi_gc9a01.rs +++ b/examples/rp/src/bin/spi_gc9a01.rs @@ -26,7 +26,6 @@ use embedded_graphics::primitives::{PrimitiveStyleBuilder, Rectangle}; use mipidsi::models::GC9A01; use mipidsi::options::{ColorInversion, ColorOrder}; use mipidsi::Builder; -use rand_core::RngCore; use {defmt_rtt as _, panic_probe as _}; const DISPLAY_FREQ: u32 = 64_000_000; diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index 2add20bc6..171f21a75 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -17,7 +17,6 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; use embassy_usb::{Builder, Config, UsbDevice}; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs old mode 100644 new mode 100755 index 5ee650910..4454c593c --- a/examples/rp/src/bin/usb_hid_mouse.rs +++ b/examples/rp/src/bin/usb_hid_mouse.rs @@ -85,8 +85,8 @@ async fn main(_spawner: Spawner) { _ = Timer::after_secs(1).await; let report = MouseReport { buttons: 0, - x: rng.gen_range(-100..100), // random small x movement - y: rng.gen_range(-100..100), // random small y movement + x: rng.random_range(-100..100), // random small x movement + y: rng.random_range(-100..100), // random small y movement wheel: 0, pan: 0, }; diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index e97ddb4c1..856838a8c 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs @@ -19,7 +19,6 @@ use embassy_rp::peripherals::{DMA_CH0, PIO0}; use embassy_rp::pio::{InterruptHandler, Pio}; use embassy_time::Duration; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 7e3c663fe..fbc957e0e 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs @@ -20,7 +20,6 @@ use embassy_rp::peripherals::{DMA_CH0, PIO0}; use embassy_rp::pio::{InterruptHandler, Pio}; use embassy_time::{Duration, Timer}; use embedded_io_async::Write; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs index f1b398b65..1efd1cd28 100644 --- a/examples/rp/src/bin/wifi_webrequest.rs +++ b/examples/rp/src/bin/wifi_webrequest.rs @@ -20,7 +20,6 @@ use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::{DMA_CH0, PIO0}; use embassy_rp::pio::{InterruptHandler, Pio}; use embassy_time::{Duration, Timer}; -use rand::RngCore; use reqwless::client::{HttpClient, TlsConfig, TlsVerify}; use reqwless::request::Method; use serde::Deserialize; diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml index 345a915af..a247bc619 100644 --- a/examples/rp235x/Cargo.toml +++ b/examples/rp235x/Cargo.toml @@ -55,7 +55,6 @@ embedded-storage = { version = "0.3" } static_cell = "2.1" portable-atomic = { version = "1.5", features = ["critical-section"] } log = "0.4" -rand = { version = "0.8.5", default-features = false } embedded-sdmmc = "0.7.0" [profile.release] diff --git a/examples/rp235x/src/bin/sharing.rs b/examples/rp235x/src/bin/sharing.rs index 497c4f845..856be6ace 100644 --- a/examples/rp235x/src/bin/sharing.rs +++ b/examples/rp235x/src/bin/sharing.rs @@ -27,7 +27,6 @@ use embassy_rp::{bind_interrupts, interrupt}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::{blocking_mutex, mutex}; use embassy_time::{Duration, Ticker}; -use rand::RngCore; use static_cell::{ConstStaticCell, StaticCell}; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp235x/src/bin/trng.rs b/examples/rp235x/src/bin/trng.rs index ad19aef3e..100d6b104 100644 --- a/examples/rp235x/src/bin/trng.rs +++ b/examples/rp235x/src/bin/trng.rs @@ -10,7 +10,6 @@ use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::TRNG; use embassy_rp::trng::Trng; use embassy_time::Timer; -use rand::RngCore; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { @@ -33,8 +32,8 @@ async fn main(_spawner: Spawner) { info!("Random bytes async {}", &randomness); trng.blocking_fill_bytes(&mut randomness); info!("Random bytes blocking {}", &randomness); - let random_u32 = trng.next_u32(); - let random_u64 = trng.next_u64(); + let random_u32 = trng.blocking_next_u32(); + let random_u64 = trng.blocking_next_u64(); info!("Random u32 {} u64 {}", random_u32, random_u64); // Random number of blinks between 0 and 31 let blinks = random_u32 % 32; diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index f00953167..ff4b2fbbd 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -21,7 +21,7 @@ futures = { version = "0.3.17" } log = "0.4.14" nix = "0.26.2" clap = { version = "3.0.0-beta.5", features = ["derive"] } -rand_core = { version = "0.6.3", features = ["std"] } +rand_core = { version = "0.9.1", features = ["std", "os_rng"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 6e50b1a01..232cf494b 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -9,7 +9,7 @@ use embassy_time::Duration; use embedded_io_async::Write; use heapless::Vec; use log::*; -use rand_core::{OsRng, RngCore}; +use rand_core::{OsRng, TryRngCore}; use static_cell::StaticCell; #[derive(Parser)] @@ -48,7 +48,7 @@ async fn main_task(spawner: Spawner) { // Generate random seed let mut seed = [0; 8]; - OsRng.fill_bytes(&mut seed); + OsRng.try_fill_bytes(&mut seed).unwrap(); let seed = u64::from_le_bytes(seed); // Init network stack diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index a42c5dbb7..cf90731dd 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -5,7 +5,7 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources}; use embassy_net_tuntap::TunTapDevice; use heapless::Vec; use log::*; -use rand_core::{OsRng, RngCore}; +use rand_core::{OsRng, TryRngCore}; use static_cell::StaticCell; #[derive(Parser)] @@ -45,7 +45,7 @@ async fn main_task(spawner: Spawner) { // Generate random seed let mut seed = [0; 8]; - OsRng.fill_bytes(&mut seed); + OsRng.try_fill_bytes(&mut seed).unwrap(); let seed = u64::from_le_bytes(seed); // Init network stack diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs index f667e8d4c..ac3aea6ff 100644 --- a/examples/std/src/bin/net_ppp.rs +++ b/examples/std/src/bin/net_ppp.rs @@ -23,7 +23,7 @@ use futures::io::BufReader; use heapless::Vec; use log::*; use nix::sys::termios; -use rand_core::{OsRng, RngCore}; +use rand_core::{OsRng, TryRngCore}; use static_cell::StaticCell; use crate::serial_port::SerialPort; @@ -89,7 +89,7 @@ async fn main_task(spawner: Spawner) { // Generate random seed let mut seed = [0; 8]; - OsRng.fill_bytes(&mut seed); + OsRng.try_fill_bytes(&mut seed).unwrap(); let seed = u64::from_le_bytes(seed); // Init network stack diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 02d4d3efb..53632a5b4 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -5,7 +5,7 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources}; use embassy_net_tuntap::TunTapDevice; use heapless::Vec; use log::*; -use rand_core::{OsRng, RngCore}; +use rand_core::{OsRng, TryRngCore}; use static_cell::StaticCell; #[derive(Parser)] @@ -44,7 +44,7 @@ async fn main_task(spawner: Spawner) { // Generate random seed let mut seed = [0; 8]; - OsRng.fill_bytes(&mut seed); + OsRng.try_fill_bytes(&mut seed).unwrap(); let seed = u64::from_le_bytes(seed); // Init network stack diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 18646a083..961c20e2d 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -7,7 +7,7 @@ use embassy_time::{Duration, Timer}; use embedded_io_async::Write as _; use heapless::Vec; use log::*; -use rand_core::{OsRng, RngCore}; +use rand_core::{OsRng, TryRngCore}; use static_cell::StaticCell; #[derive(Parser)] @@ -46,7 +46,7 @@ async fn main_task(spawner: Spawner) { // Generate random seed let mut seed = [0; 8]; - OsRng.fill_bytes(&mut seed); + OsRng.try_fill_bytes(&mut seed).unwrap(); let seed = u64::from_le_bytes(seed); // Init network stack diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 1a46931d9..94e0a80eb 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -24,7 +24,6 @@ embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" -rand_core = "0.6.3" critical-section = "1.1" embedded-storage = "0.3.1" static_cell = "2" diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 17ab7fc00..67a2b34bb 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -12,7 +12,6 @@ use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 5631ff746..6fb14f422 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -26,7 +26,6 @@ embedded-io-async = { version = "0.6.1" } embedded-nal-async = "0.8.0" panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 4034b552c..1d85cc1e7 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -15,7 +15,6 @@ use embassy_stm32::time::Hertz; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 2f98542bb..5035dacae 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -27,7 +27,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index da7aa4af5..fc14c1a70 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -11,7 +11,6 @@ use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 10485109a..46301a478 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -14,7 +14,6 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; use embedded_nal_async::TcpConnect; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs index 849173615..99cd1a158 100644 --- a/examples/stm32h7/src/bin/eth_client_mii.rs +++ b/examples/stm32h7/src/bin/eth_client_mii.rs @@ -14,7 +14,6 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use embedded_io_async::Write; use embedded_nal_async::TcpConnect; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml index 749fd78ae..f07d360b3 100644 --- a/examples/stm32h723/Cargo.toml +++ b/examples/stm32h723/Cargo.toml @@ -24,7 +24,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" static_cell = "2" chrono = { version = "^0.4", default-features = false } diff --git a/examples/stm32h742/Cargo.toml b/examples/stm32h742/Cargo.toml index e2e0094b8..3f936193c 100644 --- a/examples/stm32h742/Cargo.toml +++ b/examples/stm32h742/Cargo.toml @@ -51,7 +51,6 @@ embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" -rand_core = "0.6.3" critical-section = "1.1" embedded-storage = "0.3.1" static_cell = "2" diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml index 7c17bc766..c186ef19f 100644 --- a/examples/stm32h755cm4/Cargo.toml +++ b/examples/stm32h755cm4/Cargo.toml @@ -27,7 +27,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml index 3186929a8..d37978e44 100644 --- a/examples/stm32h755cm7/Cargo.toml +++ b/examples/stm32h755cm7/Cargo.toml @@ -27,7 +27,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml index e5f2dfe86..dc8ecc684 100644 --- a/examples/stm32h7b0/Cargo.toml +++ b/examples/stm32h7b0/Cargo.toml @@ -26,7 +26,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml index 22d59be04..aee2703a1 100644 --- a/examples/stm32h7rs/Cargo.toml +++ b/examples/stm32h7rs/Cargo.toml @@ -26,7 +26,6 @@ embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } -rand_core = "0.6.3" critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.3.0" diff --git a/examples/stm32h7rs/src/bin/eth.rs b/examples/stm32h7rs/src/bin/eth.rs index f2bd9575e..6d246bb09 100644 --- a/examples/stm32h7rs/src/bin/eth.rs +++ b/examples/stm32h7rs/src/bin/eth.rs @@ -11,7 +11,6 @@ use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::Timer; use heapless::Vec; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 239bfcd79..cceec86dd 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -30,7 +30,6 @@ embedded-hal-bus = { version = "0.1", features = ["async"] } panic-probe = { version = "0.3", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } -rand = { version = "0.8.5", default-features = false } static_cell = "2" micromath = "2.0.0" diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 4a7c01f9f..354ac90b2 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -38,7 +38,6 @@ use embedded_io::Write as bWrite; use embedded_io_async::Write; use heapless::Vec; use panic_probe as _; -use rand::RngCore; use static_cell::StaticCell; bind_interrupts!(struct Irqs { diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 4c372a554..6962db7ea 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -23,7 +23,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" heapless = { version = "0.8", default-features = false } -rand_core = { version = "0.6.3", default-features = false } embedded-io-async = { version = "0.6.1" } static_cell = "2" diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 809ec6ab1..6c72132c6 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -12,7 +12,6 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; use embassy_usb::{Builder, UsbDevice}; use embedded_io_async::Write; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 1335aa84b..46dc820ab 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -38,7 +38,6 @@ embedded-io-async = { version = "0.6.1" } embedded-storage = { version = "0.3" } static_cell = "2" portable-atomic = { version = "1.5", features = ["critical-section"] } -rand = { version = "0.8.5", default-features = false } # bootsel not currently supported on 2350 [[bin]] diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs index ae2adfa55..89e0ad32e 100644 --- a/tests/rp/src/bin/ethernet_w5100s_perf.rs +++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs @@ -14,7 +14,6 @@ use embassy_rp::peripherals::SPI0; use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; use embassy_time::Delay; use embedded_hal_bus::spi::ExclusiveDevice; -use rand::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 3a347e279..b230e619e 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -81,8 +81,8 @@ embedded-hal-async = { version = "1.0" } embedded-can = { version = "0.4" } micromath = "2.0.0" panic-probe = { version = "0.3.0", features = ["print-defmt"] } -rand_core = { version = "0.6", default-features = false } -rand_chacha = { version = "0.3", default-features = false } +rand_core = { version = "0.9.1", default-features = false } +rand_chacha = { version = "0.9.0", default-features = false } static_cell = "2" portable-atomic = { version = "1.5", features = [] } diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index a7e76fd8e..bcb362b42 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -11,7 +11,6 @@ use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; -use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml index 7b54a4f52..bda55ad32 100644 --- a/tests/utils/Cargo.toml +++ b/tests/utils/Cargo.toml @@ -4,5 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] -rand = "0.8" +rand = "0.9" serial = "0.4" -- cgit From ef0f29f0ede245671ffd82fcf384a9105f174c24 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sun, 18 May 2025 20:51:15 +0200 Subject: Update defmt dependencies --- cyw43-pio/Cargo.toml | 2 +- cyw43/Cargo.toml | 2 +- docs/examples/basic/Cargo.toml | 6 +++--- docs/examples/layer-by-layer/blinky-async/Cargo.toml | 6 +++--- docs/examples/layer-by-layer/blinky-hal/Cargo.toml | 6 +++--- docs/examples/layer-by-layer/blinky-irq/Cargo.toml | 6 +++--- docs/examples/layer-by-layer/blinky-pac/Cargo.toml | 6 +++--- embassy-boot-nrf/Cargo.toml | 2 +- embassy-boot-rp/Cargo.toml | 2 +- embassy-boot-stm32/Cargo.toml | 2 +- embassy-boot/Cargo.toml | 2 +- embassy-embedded-hal/Cargo.toml | 2 +- embassy-executor/Cargo.toml | 2 +- embassy-futures/Cargo.toml | 2 +- embassy-hal-internal/Cargo.toml | 2 +- embassy-imxrt/Cargo.toml | 2 +- embassy-mspm0/Cargo.toml | 2 +- embassy-net-adin1110/Cargo.toml | 4 ++-- embassy-net-driver-channel/Cargo.toml | 2 +- embassy-net-driver/Cargo.toml | 2 +- embassy-net-enc28j60/Cargo.toml | 2 +- embassy-net-esp-hosted/Cargo.toml | 6 +++--- embassy-net-nrf91/Cargo.toml | 12 ++++++------ embassy-net-ppp/Cargo.toml | 2 +- embassy-net-wiznet/Cargo.toml | 2 +- embassy-net/Cargo.toml | 2 +- embassy-nrf/Cargo.toml | 2 +- embassy-nxp/Cargo.toml | 2 +- embassy-rp/Cargo.toml | 2 +- embassy-stm32-wpan/Cargo.toml | 2 +- embassy-stm32/Cargo.toml | 2 +- embassy-sync/Cargo.toml | 2 +- embassy-time/Cargo.toml | 2 +- embassy-usb-dfu/Cargo.toml | 2 +- embassy-usb-driver/Cargo.toml | 2 +- embassy-usb-synopsys-otg/Cargo.toml | 2 +- embassy-usb/Cargo.toml | 4 ++-- examples/boot/application/nrf/Cargo.toml | 4 ++-- examples/boot/application/rp/Cargo.toml | 6 +++--- examples/boot/application/stm32f3/Cargo.toml | 4 ++-- examples/boot/application/stm32f7/Cargo.toml | 4 ++-- examples/boot/application/stm32h7/Cargo.toml | 4 ++-- examples/boot/application/stm32l0/Cargo.toml | 4 ++-- examples/boot/application/stm32l1/Cargo.toml | 4 ++-- examples/boot/application/stm32l4/Cargo.toml | 4 ++-- examples/boot/application/stm32wb-dfu/Cargo.toml | 4 ++-- examples/boot/application/stm32wl/Cargo.toml | 4 ++-- examples/boot/bootloader/nrf/Cargo.toml | 4 ++-- examples/boot/bootloader/rp/Cargo.toml | 4 ++-- examples/boot/bootloader/stm32-dual-bank/Cargo.toml | 4 ++-- examples/boot/bootloader/stm32/Cargo.toml | 4 ++-- examples/boot/bootloader/stm32wb-dfu/Cargo.toml | 4 ++-- examples/lpc55s69/Cargo.toml | 8 ++++---- examples/mimxrt6/Cargo.toml | 6 +++--- examples/mspm0c1104/Cargo.toml | 8 ++++---- examples/mspm0g3507/Cargo.toml | 8 ++++---- examples/mspm0g3519/Cargo.toml | 8 ++++---- examples/mspm0l1306/Cargo.toml | 8 ++++---- examples/mspm0l2228/Cargo.toml | 8 ++++---- examples/nrf-rtos-trace/Cargo.toml | 2 +- examples/nrf51/Cargo.toml | 6 +++--- examples/nrf52810/Cargo.toml | 6 +++--- examples/nrf52840-rtic/Cargo.toml | 6 +++--- examples/nrf52840/Cargo.toml | 6 +++--- examples/nrf5340/Cargo.toml | 6 +++--- examples/nrf54l15/Cargo.toml | 6 +++--- examples/nrf9151/ns/Cargo.toml | 6 +++--- examples/nrf9151/s/Cargo.toml | 6 +++--- examples/nrf9160/Cargo.toml | 6 +++--- examples/rp/Cargo.toml | 6 +++--- examples/rp235x/Cargo.toml | 6 +++--- examples/stm32c0/Cargo.toml | 6 +++--- examples/stm32f0/Cargo.toml | 6 +++--- examples/stm32f1/Cargo.toml | 6 +++--- examples/stm32f2/Cargo.toml | 6 +++--- examples/stm32f3/Cargo.toml | 6 +++--- examples/stm32f334/Cargo.toml | 6 +++--- examples/stm32f4/Cargo.toml | 6 +++--- examples/stm32f469/Cargo.toml | 6 +++--- examples/stm32f7/Cargo.toml | 6 +++--- examples/stm32g0/Cargo.toml | 6 +++--- examples/stm32g4/Cargo.toml | 6 +++--- examples/stm32h5/Cargo.toml | 6 +++--- examples/stm32h7/Cargo.toml | 6 +++--- examples/stm32h723/Cargo.toml | 6 +++--- examples/stm32h735/Cargo.toml | 6 +++--- examples/stm32h742/Cargo.toml | 6 +++--- examples/stm32h755cm4/Cargo.toml | 6 +++--- examples/stm32h755cm7/Cargo.toml | 6 +++--- examples/stm32h7b0/Cargo.toml | 6 +++--- examples/stm32h7rs/Cargo.toml | 6 +++--- examples/stm32l0/Cargo.toml | 6 +++--- examples/stm32l1/Cargo.toml | 6 +++--- examples/stm32l4/Cargo.toml | 6 +++--- examples/stm32l432/Cargo.toml | 6 +++--- examples/stm32l5/Cargo.toml | 6 +++--- examples/stm32u0/Cargo.toml | 6 +++--- examples/stm32u5/Cargo.toml | 6 +++--- examples/stm32wb/Cargo.toml | 10 +++++----- examples/stm32wba/Cargo.toml | 10 +++++----- examples/stm32wl/Cargo.toml | 6 +++--- rustfmt.toml | 2 +- tests/mspm0/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 6 +++--- tests/perf-client/Cargo.toml | 2 +- tests/rp/Cargo.toml | 6 +++--- tests/stm32/Cargo.toml | 6 +++--- 107 files changed, 254 insertions(+), 254 deletions(-) diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml index 600caf5ed..93a2e7089 100644 --- a/cyw43-pio/Cargo.toml +++ b/cyw43-pio/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.embassy.dev/cyw43-pio" cyw43 = { version = "0.3.0", path = "../cyw43" } embassy-rp = { version = "0.4.0", path = "../embassy-rp" } fixed = "1.23.1" -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/cyw43-pio-v$VERSION/cyw43-pio/src/" diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index 88d1fe506..4b58ee9c9 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml @@ -23,7 +23,7 @@ embassy-sync = { version = "0.6.2", path = "../embassy-sync"} embassy-futures = { version = "0.1.0", path = "../embassy-futures"} embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel"} -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.17", optional = true } cortex-m = "0.7.6" diff --git a/docs/examples/basic/Cargo.toml b/docs/examples/basic/Cargo.toml index 705c334a7..f5cf2b231 100644 --- a/docs/examples/basic/Cargo.toml +++ b/docs/examples/basic/Cargo.toml @@ -10,9 +10,9 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt"] } embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } -defmt = "0.3" -defmt-rtt = "0.3" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } diff --git a/docs/examples/layer-by-layer/blinky-async/Cargo.toml b/docs/examples/layer-by-layer/blinky-async/Cargo.toml index 541eb6edf..2a6741b33 100644 --- a/docs/examples/layer-by-layer/blinky-async/Cargo.toml +++ b/docs/examples/layer-by-layer/blinky-async/Cargo.toml @@ -10,6 +10,6 @@ cortex-m-rt = "0.7" embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "exti"] } embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } diff --git a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml index dd574c3e7..9a261f804 100644 --- a/docs/examples/layer-by-layer/blinky-hal/Cargo.toml +++ b/docs/examples/layer-by-layer/blinky-hal/Cargo.toml @@ -9,6 +9,6 @@ cortex-m-rt = "0.7" cortex-m = { version = "0.7", features = ["critical-section-single-core"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x"] } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } diff --git a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml index 8733ee894..c3ec9ad1a 100644 --- a/docs/examples/layer-by-layer/blinky-irq/Cargo.toml +++ b/docs/examples/layer-by-layer/blinky-irq/Cargo.toml @@ -11,6 +11,6 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m-rt = { version = "0.7" } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "memory-x", "unstable-pac"] } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } diff --git a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml index 155c41ec6..4e7e2f2ff 100644 --- a/docs/examples/layer-by-layer/blinky-pac/Cargo.toml +++ b/docs/examples/layer-by-layer/blinky-pac/Cargo.toml @@ -9,6 +9,6 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m-rt = "0.7" stm32-metapac = { version = "16", features = ["stm32l475vg"] } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } diff --git a/embassy-boot-nrf/Cargo.toml b/embassy-boot-nrf/Cargo.toml index c3e0cb5ec..7d3e04419 100644 --- a/embassy-boot-nrf/Cargo.toml +++ b/embassy-boot-nrf/Cargo.toml @@ -21,7 +21,7 @@ target = "thumbv7em-none-eabi" [lib] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.17", optional = true } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } diff --git a/embassy-boot-rp/Cargo.toml b/embassy-boot-rp/Cargo.toml index 284ac654c..10eec774f 100644 --- a/embassy-boot-rp/Cargo.toml +++ b/embassy-boot-rp/Cargo.toml @@ -21,7 +21,7 @@ features = ["embassy-rp/rp2040"] [lib] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4", optional = true } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } diff --git a/embassy-boot-stm32/Cargo.toml b/embassy-boot-stm32/Cargo.toml index 7dbe7e22b..2b741cc95 100644 --- a/embassy-boot-stm32/Cargo.toml +++ b/embassy-boot-stm32/Cargo.toml @@ -21,7 +21,7 @@ target = "thumbv7em-none-eabi" [lib] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4", optional = true } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } diff --git a/embassy-boot/Cargo.toml b/embassy-boot/Cargo.toml index 4906da0ea..8889f1a20 100644 --- a/embassy-boot/Cargo.toml +++ b/embassy-boot/Cargo.toml @@ -24,7 +24,7 @@ features = ["defmt"] [lib] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } digest = "0.10" log = { version = "0.4", optional = true } ed25519-dalek = { version = "2", default-features = false, features = ["digest"], optional = true } diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml index f385963f1..f7a973a8d 100644 --- a/embassy-embedded-hal/Cargo.toml +++ b/embassy-embedded-hal/Cargo.toml @@ -35,7 +35,7 @@ embedded-storage = "0.3.1" embedded-storage-async = { version = "0.4.1" } nb = "1.0.0" -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } [dev-dependencies] critical-section = { version = "1.1.1", features = ["std"] } diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 0f69d3c8a..9f9eaa600 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -29,7 +29,7 @@ targets = ["thumbv7em-none-eabi"] features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } rtos-trace = { version = "0.1.3", optional = true } diff --git a/embassy-futures/Cargo.toml b/embassy-futures/Cargo.toml index 47cefa56f..0deab0165 100644 --- a/embassy-futures/Cargo.toml +++ b/embassy-futures/Cargo.toml @@ -24,5 +24,5 @@ target = "thumbv7em-none-eabi" features = ["defmt"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-hal-internal/Cargo.toml b/embassy-hal-internal/Cargo.toml index d5ca95ac2..cc360682e 100644 --- a/embassy-hal-internal/Cargo.toml +++ b/embassy-hal-internal/Cargo.toml @@ -28,7 +28,7 @@ prio-bits-8 = [] cortex-m = ["dep:cortex-m", "dep:critical-section"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } num-traits = { version = "0.2.14", default-features = false } diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml index d8cf3aaba..231a80251 100644 --- a/embassy-imxrt/Cargo.toml +++ b/embassy-imxrt/Cargo.toml @@ -71,7 +71,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", fe embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false } embassy-futures = { version = "0.1.1", path = "../embassy-futures" } -defmt = { version = "1.0", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } nb = "1.0.0" cfg-if = "1.0.0" diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index df996ff4b..877d1ae18 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -38,7 +38,7 @@ embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional = embedded-hal = { version = "1.0" } embedded-hal-async = { version = "1.0" } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } fixed = "1.29" log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" diff --git a/embassy-net-adin1110/Cargo.toml b/embassy-net-adin1110/Cargo.toml index 22d494b84..a620928cb 100644 --- a/embassy-net-adin1110/Cargo.toml +++ b/embassy-net-adin1110/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://docs.embassy.dev/embassy-net-adin1110" [dependencies] heapless = "0.8" -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4", default-features = false, optional = true } embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } @@ -29,7 +29,7 @@ critical-section = { version = "1.1.2", features = ["std"] } futures-test = "0.3.28" [features] -defmt = [ "dep:defmt", "embedded-hal-1/defmt-03" ] +defmt = ["dep:defmt", "embedded-hal-1/defmt-03"] log = ["dep:log"] [package.metadata.embassy_docs] diff --git a/embassy-net-driver-channel/Cargo.toml b/embassy-net-driver-channel/Cargo.toml index 5165621b7..beadbf3c9 100644 --- a/embassy-net-driver-channel/Cargo.toml +++ b/embassy-net-driver-channel/Cargo.toml @@ -22,7 +22,7 @@ target = "thumbv7em-none-eabi" features = ["defmt"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml index 97e8a0db3..34bc6c91a 100644 --- a/embassy-net-driver/Cargo.toml +++ b/embassy-net-driver/Cargo.toml @@ -22,4 +22,4 @@ target = "thumbv7em-none-eabi" features = ["defmt"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } diff --git a/embassy-net-enc28j60/Cargo.toml b/embassy-net-enc28j60/Cargo.toml index 74f94816a..b26be1420 100644 --- a/embassy-net-enc28j60/Cargo.toml +++ b/embassy-net-enc28j60/Cargo.toml @@ -16,7 +16,7 @@ embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-time = { version = "0.4.0", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } [package.metadata.embassy_docs] diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index bab0e6d7c..0cb99e67e 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml @@ -10,11 +10,11 @@ repository = "https://github.com/embassy-rs/embassy" documentation = "https://docs.embassy.dev/embassy-net-esp-hosted" [features] -defmt = [ "dep:defmt", "heapless/defmt-03" ] -log = [ "dep:log" ] +defmt = ["dep:defmt", "heapless/defmt-03"] +log = ["dep:log"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } embassy-time = { version = "0.4.0", path = "../embassy-time" } diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index 99ec5a318..de12ac36f 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml @@ -10,20 +10,20 @@ repository = "https://github.com/embassy-rs/embassy" documentation = "https://docs.embassy.dev/embassy-net-nrf91" [features] -defmt = [ "dep:defmt", "heapless/defmt-03" ] -log = [ "dep:log" ] +defmt = ["dep:defmt", "heapless/defmt-03"] +log = ["dep:log"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } nrf-pac = "0.1.0" cortex-m = "0.7.7" embassy-time = { version = "0.4.0", path = "../embassy-time" } -embassy-sync = { version = "0.6.2", path = "../embassy-sync"} -embassy-futures = { version = "0.1.0", path = "../embassy-futures"} -embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel"} +embassy-sync = { version = "0.6.2", path = "../embassy-sync" } +embassy-futures = { version = "0.1.0", path = "../embassy-futures" } +embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" } heapless = "0.8" embedded-io = "0.6.1" diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index 2d82e2ad0..ab713fed8 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml @@ -14,7 +14,7 @@ defmt = ["dep:defmt", "ppproto/defmt"] log = ["dep:log", "ppproto/log"] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } embedded-io-async = { version = "0.6.1" } diff --git a/embassy-net-wiznet/Cargo.toml b/embassy-net-wiznet/Cargo.toml index 2ad5a6f48..a06a09302 100644 --- a/embassy-net-wiznet/Cargo.toml +++ b/embassy-net-wiznet/Cargo.toml @@ -15,7 +15,7 @@ embedded-hal-async = { version = "1.0" } embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" } embassy-time = { version = "0.4.0", path = "../embassy-time" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-wiznet-v$VERSION/embassy-net-wiznet/src/" diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index c3bf1acbc..d96481f98 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -68,7 +68,7 @@ alloc = ["smoltcp/alloc"] [dependencies] -defmt = { version = "0.3.8", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } smoltcp = { version = "0.12.0", default-features = false, features = [ diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index e4e143c65..e4f40630e 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -159,7 +159,7 @@ rand-core-09 = { package = "rand_core", version = "0.9" } nrf-pac = "0.1.0" -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } bitflags = "2.4.2" log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index 031cd4aba..86a989aa7 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml @@ -10,7 +10,7 @@ critical-section = "1.1.2" embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } lpc55-pac = "0.5.0" -defmt = { version = "0.3.8", optional = true } +defmt = { version = "1", optional = true } [features] default = ["rt"] diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 849cb549a..3c18a8f77 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -145,7 +145,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", fe embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } atomic-polyfill = "1.0.1" -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } nb = "1.1.0" cfg-if = "1.0.0" diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 3bcfd11a9..81af6aedd 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -27,7 +27,7 @@ embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal" } embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver", optional=true } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.17", optional = true } cortex-m = "0.7.6" diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 35c1291fd..d898f7ff3 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -67,7 +67,7 @@ rand-core-06 = { package = "rand_core", version = "0.6" } rand-core-09 = { package = "rand_core", version = "0.9" } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } cortex-m-rt = ">=0.6.15,<0.8" cortex-m = "0.7.6" diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 92ee38ed9..65cade317 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml @@ -24,7 +24,7 @@ std = [] turbowakers = [] [dependencies] -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } futures-sink = { version = "0.3", default-features = false, features = [] } diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index dc144ec3c..76983d880 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -420,7 +420,7 @@ tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"] embassy-time-driver = { version = "0.2", path = "../embassy-time-driver" } embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true} -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } diff --git a/embassy-usb-dfu/Cargo.toml b/embassy-usb-dfu/Cargo.toml index eba902c74..ccf8a16eb 100644 --- a/embassy-usb-dfu/Cargo.toml +++ b/embassy-usb-dfu/Cargo.toml @@ -26,7 +26,7 @@ flavors = [ features = ["defmt", "cortex-m", "dfu"] [dependencies] -defmt = { version = "0.3.5", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.17", optional = true } bitflags = "2.4.1" diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml index edb6551b0..e40421649 100644 --- a/embassy-usb-driver/Cargo.toml +++ b/embassy-usb-driver/Cargo.toml @@ -19,5 +19,5 @@ target = "thumbv7em-none-eabi" features = ["defmt"] [dependencies] -defmt = { version = "0.3", optional = true } embedded-io-async = "0.6.1" +defmt = { version = "1", optional = true } diff --git a/embassy-usb-synopsys-otg/Cargo.toml b/embassy-usb-synopsys-otg/Cargo.toml index f9703a54a..98fc044ce 100644 --- a/embassy-usb-synopsys-otg/Cargo.toml +++ b/embassy-usb-synopsys-otg/Cargo.toml @@ -21,5 +21,5 @@ critical-section = "1.1" embassy-sync = { version = "0.6.2", path = "../embassy-sync" } embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } -defmt = { version = "0.3", optional = true } +defmt = { version = "1.0.1", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 4950fbe2a..e52f4602d 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml @@ -51,10 +51,10 @@ embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" } embassy-sync = { version = "0.6.2", path = "../embassy-sync" } embassy-net-driver-channel = { version = "0.3.0", path = "../embassy-net-driver-channel" } -defmt = { version = "0.3", optional = true } -embedded-io-async = "0.6.1" +defmt = { version = "1", optional = true } log = { version = "0.4.14", optional = true } heapless = "0.8" +embedded-io-async = "0.6.1" # for HID usbd-hid = { version = "0.8.1", optional = true } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 4ae0e6a77..244ce9591 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -13,8 +13,8 @@ embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features embassy-boot-nrf = { version = "0.4.0", path = "../../../../embassy-boot-nrf", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 3c0d207d1..24f4218f1 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -12,9 +12,9 @@ embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = [" embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3", features = ["print-defmt"], optional = true } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true } panic-reset = { version = "0.1.1", optional = true } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index f32727ea8..1e209eb9c 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index d62c67742..877e239fa 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } embedded-storage = "0.3.1" diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index dd3a32e45..f28723835 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } embedded-storage = "0.3.1" diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 0b9e9b96a..f1cb55223 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 490541a2e..7c53e011d 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index c3aa31161..9f5060802 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml index a89e2bb6e..d1cea8520 100644 --- a/examples/boot/application/stm32wb-dfu/Cargo.toml +++ b/examples/boot/application/stm32wb-dfu/Cargo.toml @@ -14,8 +14,8 @@ embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb" } embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index f4d7ae712..54331dd69 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -12,8 +12,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", feature embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" } -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } panic-reset = { version = "0.1.1" } embedded-hal = { version = "0.2.6" } diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml index 34a0553e3..4c2712718 100644 --- a/examples/boot/bootloader/nrf/Cargo.toml +++ b/examples/boot/bootloader/nrf/Cargo.toml @@ -6,8 +6,8 @@ description = "Bootloader for nRF chips" license = "MIT OR Apache-2.0" [dependencies] -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } embassy-nrf = { path = "../../../../embassy-nrf", features = [] } embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml index 7c9c3c779..c57b90793 100644 --- a/examples/boot/bootloader/rp/Cargo.toml +++ b/examples/boot/bootloader/rp/Cargo.toml @@ -6,8 +6,8 @@ description = "Example bootloader for RP2040 chips" license = "MIT OR Apache-2.0" [dependencies] -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } embassy-rp = { path = "../../../../embassy-rp", features = ["rp2040"] } embassy-boot-rp = { path = "../../../../embassy-boot-rp" } diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml index 4beb9c61c..a3ca96aec 100644 --- a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml +++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml @@ -6,8 +6,8 @@ description = "Example bootloader for dual-bank flash STM32 chips" license = "MIT OR Apache-2.0" [dependencies] -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml index 9abad8636..bdefa2cb5 100644 --- a/examples/boot/bootloader/stm32/Cargo.toml +++ b/examples/boot/bootloader/stm32/Cargo.toml @@ -6,8 +6,8 @@ description = "Example bootloader for STM32 chips" license = "MIT OR Apache-2.0" [dependencies] -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml index 01343b86b..389f43641 100644 --- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml +++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml @@ -6,8 +6,8 @@ description = "Example USB DFUbootloader for the STM32WB series of chips" license = "MIT OR Apache-2.0" [dependencies] -defmt = { version = "0.3", optional = true } -defmt-rtt = { version = "0.4", optional = true } +defmt = { version = "1.0.1", optional = true } +defmt-rtt = { version = "1.0.0", optional = true } embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } diff --git a/examples/lpc55s69/Cargo.toml b/examples/lpc55s69/Cargo.toml index f5a6e6995..30ce0b799 100644 --- a/examples/lpc55s69/Cargo.toml +++ b/examples/lpc55s69/Cargo.toml @@ -10,12 +10,12 @@ embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"] embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" [profile.release] diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml index 27c3a27dc..40cc0fb44 100644 --- a/examples/mimxrt6/Cargo.toml +++ b/examples/mimxrt6/Cargo.toml @@ -7,8 +7,8 @@ license = "MIT or Apache-2.0" [dependencies] cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.3" -defmt = "1.0" -defmt-rtt = "1.0" +defmt = "1.0.1" +defmt-rtt = "1.0.0" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } @@ -19,7 +19,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = "1.0.0" mimxrt600-fcb = "0.2.2" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } # cargo build/run [profile.dev] diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml index ba64a578d..1498b599d 100644 --- a/examples/mspm0c1104/Cargo.toml +++ b/examples/mspm0c1104/Cargo.toml @@ -9,12 +9,12 @@ embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" # The chip only has 1KB of ram, so we must optimize binaries regardless diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml index f6fed091d..78c4b3f5a 100644 --- a/examples/mspm0g3507/Cargo.toml +++ b/examples/mspm0g3507/Cargo.toml @@ -9,12 +9,12 @@ embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" [profile.release] diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml index 1662e1f8d..1d191b2da 100644 --- a/examples/mspm0g3519/Cargo.toml +++ b/examples/mspm0g3519/Cargo.toml @@ -9,12 +9,12 @@ embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" [profile.release] diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml index 609b3f205..e427971fe 100644 --- a/examples/mspm0l1306/Cargo.toml +++ b/examples/mspm0l1306/Cargo.toml @@ -9,12 +9,12 @@ embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" [profile.release] diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml index bbca011a1..39e0e1a0c 100644 --- a/examples/mspm0l2228/Cargo.toml +++ b/examples/mspm0l2228/Cargo.toml @@ -9,12 +9,12 @@ embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } -panic-halt = "0.2.0" +panic-halt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = { version = "0.7.0"} -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3.2", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } panic-semihosting = "0.6.0" [profile.release] diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index ba609d889..dcbaf87f8 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml @@ -22,7 +22,7 @@ embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["nrf5 cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3" } +panic-probe = "1.0.0" serde = { version = "1.0.136", default-features = false } rtos-trace = "0.1.3" systemview-target = { version = "0.1.2", features = ["callbacks-app", "callbacks-os", "log", "cortex-m"] } diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml index 97b5b924a..91f78737f 100644 --- a/examples/nrf51/Cargo.toml +++ b/examples/nrf51/Cargo.toml @@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml index cd59b86c3..5373278c1 100644 --- a/examples/nrf52810/Cargo.toml +++ b/examples/nrf52810/Cargo.toml @@ -11,14 +11,14 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" fixed = "1.10.0" static_cell = { version = "2" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index ac3d2006c..2eef012b7 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml @@ -13,12 +13,12 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "d embassy-time-queue-utils = { version = "0.1", path = "../../embassy-time-queue-utils", features = ["generic-queue-8"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index ff40a34af..92127a8b0 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -17,14 +17,14 @@ embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } embassy-net-esp-hosted = { version = "0.2.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } embassy-net-enc28j60 = { version = "0.2.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" fixed = "1.10.0" static_cell = { version = "2" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } rand = { version = "0.9.0", default-features = false } embedded-storage = "0.3.1" usbd-hid = "0.8.1" diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 5c226695f..42d7766b7 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -14,13 +14,13 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embedded-io-async = { version = "0.6.1" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" static_cell = "2" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } embedded-storage = "0.3.1" usbd-hid = "0.8.1" serde = { version = "1.0.136", default-features = false } diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index 8848065d8..4b229d06d 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml @@ -9,9 +9,9 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" diff --git a/examples/nrf9151/ns/Cargo.toml b/examples/nrf9151/ns/Cargo.toml index 03f38fd63..a083aa5e7 100644 --- a/examples/nrf9151/ns/Cargo.toml +++ b/examples/nrf9151/ns/Cargo.toml @@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/nrf9151/s/Cargo.toml b/examples/nrf9151/s/Cargo.toml index ba88f6da3..ae98631ef 100644 --- a/examples/nrf9151/s/Cargo.toml +++ b/examples/nrf9151/s/Cargo.toml @@ -9,12 +9,12 @@ embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", feat embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml index a720f2d61..25aedf624 100644 --- a/examples/nrf9160/Cargo.toml +++ b/examples/nrf9160/Cargo.toml @@ -11,13 +11,13 @@ embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defm embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" heapless = "0.8" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } static_cell = { version = "2" } embedded-io = "0.6.1" embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index aacf9846a..d19dd9dc7 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -19,8 +19,8 @@ embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" } cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" fixed = "1.23.1" fixed-macro = "1.2" @@ -36,7 +36,7 @@ assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev cortex-m = { version = "0.7.6", features = ["inline-asm"] } cortex-m-rt = "0.7.0" critical-section = "1.1" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } display-interface-spi = "0.5.0" embedded-graphics = "0.8.1" mipidsi = "0.8.0" diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml index a247bc619..ae64489ae 100644 --- a/examples/rp235x/Cargo.toml +++ b/examples/rp235x/Cargo.toml @@ -19,8 +19,8 @@ embassy-usb-logger = { version = "0.4.0", path = "../../embassy-usb-logger" } cyw43 = { version = "0.3.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { version = "0.4.0", path = "../../cyw43-pio", features = ["defmt"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" fixed = "1.23.1" fixed-macro = "1.2" @@ -37,7 +37,7 @@ tb6612fng = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm"] } cortex-m-rt = "0.7.0" critical-section = "1.1" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } display-interface-spi = "0.5.0" embedded-graphics = "0.8.1" mipidsi = "0.8.0" diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 767b742f7..71f1cfda1 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml @@ -11,13 +11,13 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } [profile.release] diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 932a97dc8..534e8c33d 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml @@ -9,9 +9,9 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-tim2", "exti", "unstable-pac"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index fe800bc80..f856d2620 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" static_cell = "2.0.0" diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 26be3f485..f26cbfadc 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml @@ -11,13 +11,13 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 31bf040b0..4c1dd881f 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.1" diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 5fb6d60c5..c28855b3a 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml @@ -12,13 +12,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" embedded-storage = "0.3.1" diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 7aa4354ca..7374f8813 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-net-wiznet = { version = "0.2.0", path = "../../embassy-net-wiznet", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -24,7 +24,7 @@ embedded-hal = "0.2.6" embedded-hal-bus = { version = "0.2", features = ["async"] } embedded-io = { version = "0.6.0" } embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } futures-util = { version = "0.3.30", default-features = false } heapless = { version = "0.8", default-features = false } critical-section = "1.1" diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml index 4d403bae8..87a3b8f75 100644 --- a/examples/stm32f469/Cargo.toml +++ b/examples/stm32f469/Cargo.toml @@ -10,13 +10,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [" embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "1.0.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 94e0a80eb..bce521f30 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -15,13 +15,13 @@ embedded-io-async = { version = "0.6.1" } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" critical-section = "1.1" diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 319d84179..5e09b237e 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml @@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index aa01d84e2..582553a29 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -14,14 +14,14 @@ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defm embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.8.1" -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-can = { version = "0.4" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } static_cell = "2.0.0" diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 6fb14f422..3e022e4e5 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -24,7 +24,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-io-async = { version = "0.6.1" } embedded-nal-async = "0.8.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 5035dacae..520d0c8e6 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -25,7 +25,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml index f07d360b3..1eb706b4d 100644 --- a/examples/stm32h723/Cargo.toml +++ b/examples/stm32h723/Cargo.toml @@ -12,8 +12,8 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -22,7 +22,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" static_cell = "2" diff --git a/examples/stm32h735/Cargo.toml b/examples/stm32h735/Cargo.toml index 4d31dedf1..2ce989e6f 100644 --- a/examples/stm32h735/Cargo.toml +++ b/examples/stm32h735/Cargo.toml @@ -12,12 +12,12 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } embedded-graphics = { version = "0.8.1" } tinybmp = { version = "0.5" } diff --git a/examples/stm32h742/Cargo.toml b/examples/stm32h742/Cargo.toml index 3f936193c..c3bf39e13 100644 --- a/examples/stm32h742/Cargo.toml +++ b/examples/stm32h742/Cargo.toml @@ -39,8 +39,8 @@ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = [ ] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = [ "inline-asm", @@ -48,7 +48,7 @@ cortex-m = { version = "0.7.6", features = [ ] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } nb = "1.0.0" critical-section = "1.1" diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml index c186ef19f..c97ac447e 100644 --- a/examples/stm32h755cm4/Cargo.toml +++ b/examples/stm32h755cm4/Cargo.toml @@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -25,7 +25,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml index d37978e44..3843d5d43 100644 --- a/examples/stm32h755cm7/Cargo.toml +++ b/examples/stm32h755cm7/Cargo.toml @@ -15,8 +15,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -25,7 +25,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml index dc8ecc684..e4f1080ac 100644 --- a/examples/stm32h7b0/Cargo.toml +++ b/examples/stm32h7b0/Cargo.toml @@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -24,7 +24,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml index aee2703a1..58f8b1274 100644 --- a/examples/stm32h7rs/Cargo.toml +++ b/examples/stm32h7rs/Cargo.toml @@ -14,8 +14,8 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -24,7 +24,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-nal-async = "0.8.0" embedded-io-async = { version = "0.6.1" } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } critical-section = "1.1" micromath = "2.0.0" diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 189b0e8d4..ce54ad9fb 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -11,8 +11,8 @@ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["de embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" embedded-storage = "0.3.1" embedded-io = { version = "0.6.0" } @@ -20,7 +20,7 @@ embedded-io-async = { version = "0.6.1" } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } embedded-hal = "0.2.6" static_cell = { version = "2" } diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 6066b6dc7..a780f9290 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml @@ -12,13 +12,13 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } embedded-storage = "0.3.1" diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index cceec86dd..5c4dce482 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -18,8 +18,8 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } embedded-io = { version = "0.6.0", features = ["defmt-03"] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -27,7 +27,7 @@ embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } static_cell = "2" diff --git a/examples/stm32l432/Cargo.toml b/examples/stm32l432/Cargo.toml index e155b3e66..ac7e507de 100644 --- a/examples/stm32l432/Cargo.toml +++ b/examples/stm32l432/Cargo.toml @@ -10,8 +10,8 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -19,7 +19,7 @@ embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } [profile.release] debug = 2 diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 6962db7ea..138276b7f 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -15,9 +15,9 @@ embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defm embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } usbd-hid = "0.8.1" -defmt = "0.3" -defmt-rtt = "0.4" -panic-probe = { version = "0.3", features = ["print-defmt"] } +defmt = "1.0.1" +defmt-rtt = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" diff --git a/examples/stm32u0/Cargo.toml b/examples/stm32u0/Cargo.toml index efcb9bf4d..86cff2321 100644 --- a/examples/stm32u0/Cargo.toml +++ b/examples/stm32u0/Cargo.toml @@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de embassy-usb = { version = "0.4.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } micromath = "2.0.0" diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 886c5cb2e..94f77ce2f 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -13,13 +13,13 @@ embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["de embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } embedded-graphics = { version = "0.8.1" } tinybmp = { version = "0.6.0" } diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 96f66f3af..a83871d4d 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -11,15 +11,15 @@ embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", fea embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } +embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +embedded-hal = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 60b09adb4..b87ca88bf 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -9,15 +9,15 @@ embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } +embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" -embedded-hal = "0.2.6" -panic-probe = { version = "0.3", features = ["print-defmt"] } +embedded-hal = "1.0.0" +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } static_cell = "2" diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 6b677914e..1b6a23bed 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -12,14 +12,14 @@ embassy-executor = { version = "0.7.0", path = "../../embassy-executor", feature embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-storage = "0.3.1" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } heapless = { version = "0.8", default-features = false } chrono = { version = "^0.4", default-features = false } diff --git a/rustfmt.toml b/rustfmt.toml index 592ad27ff..2561562fd 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,4 @@ group_imports = "StdExternalCrate" imports_granularity = "Module" edition = "2021" -max_width=120 +max_width = 120 diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml index 0566807d7..b77747e5d 100644 --- a/tests/mspm0/Cargo.toml +++ b/tests/mspm0/Cargo.toml @@ -23,7 +23,7 @@ cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-sin cortex-m-rt = "0.7.0" embedded-hal = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } static_cell = "2" portable-atomic = { version = "1.5", features = ["critical-section"] } diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 410d62bdd..32087940e 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -21,12 +21,12 @@ embedded-hal-bus = { version = "0.1", features = ["async"] } static_cell = "2" perf-client = { path = "../perf-client" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" -panic-probe = { version = "0.3", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } portable-atomic = { version = "1.6.0" } [features] diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 9620972c3..e31d6361b 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -defmt = "0.3" +defmt = "1.0.1" diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 46dc820ab..2c2ed73cc 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -24,8 +24,8 @@ cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } perf-client = { path = "../perf-client" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6" } cortex-m-rt = "0.7.0" @@ -33,7 +33,7 @@ embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } embedded-io-async = { version = "0.6.1" } embedded-storage = { version = "0.3" } static_cell = "2" diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index b230e619e..6036a5a97 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -70,8 +70,8 @@ embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", opt embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } perf-client = { path = "../perf-client" } -defmt = "0.3" -defmt-rtt = "0.4" +defmt = "1.0.1" +defmt-rtt = "1.0.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" @@ -80,7 +80,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } embedded-hal-async = { version = "1.0" } embedded-can = { version = "0.4" } micromath = "2.0.0" -panic-probe = { version = "0.3.0", features = ["print-defmt"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } rand_core = { version = "0.9.1", default-features = false } rand_chacha = { version = "0.9.0", default-features = false } static_cell = "2" -- cgit From ef32187ed7349f3883d997b6f1590e11dbc8db81 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 19 May 2025 18:15:05 +0200 Subject: mspm0: fix build for int groups. --- ci.sh | 7 +++++ embassy-mspm0/build.rs | 4 +++ embassy-mspm0/src/int_group/g110x.rs | 47 ++++++++++++++++++++++++++++++++ embassy-mspm0/src/int_group/g151x.rs | 52 ++++++++++++++++++++++++++++++++++++ embassy-mspm0/src/int_group/g310x.rs | 48 +++++++++++++++++++++++++++++++++ embassy-mspm0/src/int_group/l11xx.rs | 25 +++++++++++++++++ embassy-mspm0/src/int_group/l12xx.rs | 49 +++++++++++++++++++++++++++++++++ embassy-mspm0/src/int_group/l130x.rs | 46 ------------------------------- embassy-mspm0/src/int_group/l13xx.rs | 46 +++++++++++++++++++++++++++++++ embassy-mspm0/src/lib.rs | 8 +++++- 10 files changed, 285 insertions(+), 47 deletions(-) create mode 100644 embassy-mspm0/src/int_group/g110x.rs create mode 100644 embassy-mspm0/src/int_group/g151x.rs create mode 100644 embassy-mspm0/src/int_group/g310x.rs create mode 100644 embassy-mspm0/src/int_group/l11xx.rs create mode 100644 embassy-mspm0/src/int_group/l12xx.rs delete mode 100644 embassy-mspm0/src/int_group/l130x.rs create mode 100644 embassy-mspm0/src/int_group/l13xx.rs diff --git a/ci.sh b/ci.sh index 2f4164998..2be84ef6b 100755 --- a/ci.sh +++ b/ci.sh @@ -179,6 +179,13 @@ cargo batch \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1306rhb,defmt,time-driver-any \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l2228pn,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1345dgs28,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1106dgs28,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l1228pm,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1107ycj,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3105rhb,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1505pt,defmt,time-driver-any \ + --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g1519rhb,defmt,time-driver-any \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 409ce0621..094769992 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -84,6 +84,10 @@ fn get_chip_cfgs(chip_name: &str) -> Vec { cfgs.push("mspm0g150x".to_string()); } + if chip_name.starts_with("mspm0g151") { + cfgs.push("mspm0g151x".to_string()); + } + if chip_name.starts_with("mspm0g310") { cfgs.push("mspm0g310x".to_string()); } diff --git a/embassy-mspm0/src/int_group/g110x.rs b/embassy-mspm0/src/int_group/g110x.rs new file mode 100644 index 000000000..9f8ac4d7b --- /dev/null +++ b/embassy-mspm0/src/int_group/g110x.rs @@ -0,0 +1,47 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::WWDT1 => todo!("implement WWDT1"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::GPIOB => crate::gpio::gpiob_interrupt(), + } +} diff --git a/embassy-mspm0/src/int_group/g151x.rs b/embassy-mspm0/src/int_group/g151x.rs new file mode 100644 index 000000000..e785018a7 --- /dev/null +++ b/embassy-mspm0/src/int_group/g151x.rs @@ -0,0 +1,52 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::WWDT1 => todo!("implement WWDT1"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::GPIOB => crate::gpio::gpiob_interrupt(), + Group1::COMP0 => todo!("implement COMP0"), + Group1::COMP1 => todo!("implement COMP1"), + Group1::COMP2 => todo!("implement COMP2"), + Group1::TRNG => todo!("implement TRNG"), + Group1::GPIOC => crate::gpio::gpioc_interrupt(), + } +} diff --git a/embassy-mspm0/src/int_group/g310x.rs b/embassy-mspm0/src/int_group/g310x.rs new file mode 100644 index 000000000..ad508d3a2 --- /dev/null +++ b/embassy-mspm0/src/int_group/g310x.rs @@ -0,0 +1,48 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::WWDT1 => todo!("implement WWDT1"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::GPIOB => crate::gpio::gpiob_interrupt(), + Group1::TRNG => todo!("implement TRNG"), + } +} diff --git a/embassy-mspm0/src/int_group/l11xx.rs b/embassy-mspm0/src/int_group/l11xx.rs new file mode 100644 index 000000000..426a80c13 --- /dev/null +++ b/embassy-mspm0/src/int_group/l11xx.rs @@ -0,0 +1,25 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} diff --git a/embassy-mspm0/src/int_group/l12xx.rs b/embassy-mspm0/src/int_group/l12xx.rs new file mode 100644 index 000000000..833771eea --- /dev/null +++ b/embassy-mspm0/src/int_group/l12xx.rs @@ -0,0 +1,49 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::GPIOB => todo!("implement GPIOB"), + Group1::COMP0 => todo!("implement COMP0"), + Group1::TRNG => todo!("implement TRNG"), + Group1::GPIOC => todo!("implement GPIOC"), + } +} diff --git a/embassy-mspm0/src/int_group/l130x.rs b/embassy-mspm0/src/int_group/l130x.rs deleted file mode 100644 index 8be5adcad..000000000 --- a/embassy-mspm0/src/int_group/l130x.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::pac; -use crate::pac::interrupt; - -#[cfg(feature = "rt")] -#[interrupt] -fn GROUP0() { - use mspm0_metapac::Group0; - - let group = pac::CPUSS.int_group(0); - - // Must subtract by 1 since NO_INTR is value 0 - let iidx = group.iidx().read().stat().to_bits() - 1; - - let Ok(group) = pac::Group0::try_from(iidx as u8) else { - debug!("Invalid IIDX for group 0: {}", iidx); - return; - }; - - match group { - Group0::WWDT0 => todo!("implement WWDT0"), - Group0::DEBUGSS => todo!("implement DEBUGSS"), - Group0::FLASHCTL => todo!("implement FLASHCTL"), - Group0::SYSCTL => todo!("implement SYSCTL"), - } -} - -#[cfg(feature = "rt")] -#[interrupt] -fn GROUP1() { - use mspm0_metapac::Group1; - - let group = pac::CPUSS.int_group(1); - - // Must subtract by 1 since NO_INTR is value 0 - let iidx = group.iidx().read().stat().to_bits() - 1; - - let Ok(group) = pac::Group1::try_from(iidx as u8) else { - debug!("Invalid IIDX for group 1: {}", iidx); - return; - }; - - match group { - Group1::GPIOA => crate::gpio::gpioa_interrupt(), - Group1::COMP0 => todo!("implement COMP0"), - } -} diff --git a/embassy-mspm0/src/int_group/l13xx.rs b/embassy-mspm0/src/int_group/l13xx.rs new file mode 100644 index 000000000..8be5adcad --- /dev/null +++ b/embassy-mspm0/src/int_group/l13xx.rs @@ -0,0 +1,46 @@ +use crate::pac; +use crate::pac::interrupt; + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP0() { + use mspm0_metapac::Group0; + + let group = pac::CPUSS.int_group(0); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group0::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 0: {}", iidx); + return; + }; + + match group { + Group0::WWDT0 => todo!("implement WWDT0"), + Group0::DEBUGSS => todo!("implement DEBUGSS"), + Group0::FLASHCTL => todo!("implement FLASHCTL"), + Group0::SYSCTL => todo!("implement SYSCTL"), + } +} + +#[cfg(feature = "rt")] +#[interrupt] +fn GROUP1() { + use mspm0_metapac::Group1; + + let group = pac::CPUSS.int_group(1); + + // Must subtract by 1 since NO_INTR is value 0 + let iidx = group.iidx().read().stat().to_bits() - 1; + + let Ok(group) = pac::Group1::try_from(iidx as u8) else { + debug!("Invalid IIDX for group 1: {}", iidx); + return; + }; + + match group { + Group1::GPIOA => crate::gpio::gpioa_interrupt(), + Group1::COMP0 => todo!("implement COMP0"), + } +} diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index df2d83cc0..f129e221b 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -41,9 +41,15 @@ mod time_driver; // Interrupt group handlers. #[cfg_attr(mspm0c110x, path = "int_group/c110x.rs")] +#[cfg_attr(mspm0g110x, path = "int_group/g110x.rs")] +#[cfg_attr(mspm0g150x, path = "int_group/g150x.rs")] #[cfg_attr(mspm0g350x, path = "int_group/g350x.rs")] +#[cfg_attr(mspm0g151x, path = "int_group/g151x.rs")] #[cfg_attr(mspm0g351x, path = "int_group/g351x.rs")] -#[cfg_attr(mspm0l130x, path = "int_group/l130x.rs")] +#[cfg_attr(mspm0g310x, path = "int_group/g310x.rs")] +#[cfg_attr(mspm0l110x, path = "int_group/l11xx.rs")] +#[cfg_attr(mspm0l122x, path = "int_group/l12xx.rs")] +#[cfg_attr(any(mspm0l130x, mspm0l134x), path = "int_group/l13xx.rs")] #[cfg_attr(mspm0l222x, path = "int_group/l222x.rs")] mod int_group; -- cgit From 44dce8206124359459facbb373887ca51c33c60b Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 20 May 2025 12:27:28 -0500 Subject: mspm0: add gpio handlers to l122x --- embassy-mspm0/src/int_group/l12xx.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-mspm0/src/int_group/l12xx.rs b/embassy-mspm0/src/int_group/l12xx.rs index 833771eea..eeb2ce70d 100644 --- a/embassy-mspm0/src/int_group/l12xx.rs +++ b/embassy-mspm0/src/int_group/l12xx.rs @@ -41,9 +41,9 @@ fn GROUP1() { match group { Group1::GPIOA => crate::gpio::gpioa_interrupt(), - Group1::GPIOB => todo!("implement GPIOB"), + Group1::GPIOB => crate::gpio::gpiob_interrupt(), Group1::COMP0 => todo!("implement COMP0"), Group1::TRNG => todo!("implement TRNG"), - Group1::GPIOC => todo!("implement GPIOC"), + Group1::GPIOC => crate::gpio::gpioc_interrupt(), } } -- cgit From 156bf00009495bbdffefd67f920919b4cd35c418 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 20 May 2025 12:35:17 -0500 Subject: mspm0: L110x has no group1 --- embassy-mspm0/src/gpio.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index 3c824b0e6..19a6230b6 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs @@ -10,7 +10,7 @@ use embassy_sync::waitqueue::AtomicWaker; use crate::pac::gpio::vals::*; use crate::pac::gpio::{self}; -#[cfg(all(feature = "rt", mspm0c110x))] +#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))] use crate::pac::interrupt; use crate::pac::{self}; @@ -1120,7 +1120,7 @@ impl Iterator for BitIter { } // C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt. -#[cfg(all(feature = "rt", mspm0c110x))] +#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))] #[interrupt] fn GPIOA() { gpioa_interrupt(); -- cgit