From 03f73ce339c31b2cd222a7e96e66ee78f37e2ce3 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 27 Feb 2025 06:50:01 -0500 Subject: [PATCH 01/44] stm32/i2c: disable peripheral when changing timings --- embassy-stm32/src/i2c/v2.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 71769bbc1..1f53a995d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -855,7 +855,12 @@ impl<'d, M: Mode> SetConfig for I2c<'d, M> { type Config = Hertz; type ConfigError = (); fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.info.regs.cr1().modify(|reg| { + reg.set_pe(false); + }); + let timings = Timings::new(self.kernel_clock, *config); + self.info.regs.timingr().write(|reg| { reg.set_presc(timings.prescale); reg.set_scll(timings.scll); @@ -864,6 +869,10 @@ impl<'d, M: Mode> SetConfig for I2c<'d, M> { reg.set_scldel(timings.scldel); }); + self.info.regs.cr1().modify(|reg| { + reg.set_pe(true); + }); + Ok(()) } } From e0cdc356ccd7f9e20c2b5355cc52b7eb7610147b Mon Sep 17 00:00:00 2001 From: i509VCB Date: Thu, 13 Mar 2025 22:10:45 -0500 Subject: [PATCH 02/44] Embassy for MSPM0 This adds an embassy hal for the Texas Instruments MSPM0 microcontroller series. So far the GPIO and time drivers have been implemented. I have tested these drivers on the following parts: - C1104 - L1306 - L2228 - G3507 - G3519 The PAC is generated at https://github.com/mspm0-rs --- .vscode/settings.json | 5 + embassy-mspm0/Cargo.toml | 125 ++ embassy-mspm0/build.rs | 616 ++++++++++ embassy-mspm0/build_common.rs | 94 ++ embassy-mspm0/src/fmt.rs | 270 +++++ embassy-mspm0/src/gpio.rs | 1070 +++++++++++++++++ embassy-mspm0/src/int_group/c110x.rs | 25 + embassy-mspm0/src/int_group/g350x.rs | 51 + embassy-mspm0/src/int_group/g351x.rs | 52 + embassy-mspm0/src/int_group/l130x.rs | 46 + embassy-mspm0/src/int_group/l222x.rs | 49 + embassy-mspm0/src/lib.rs | 112 ++ embassy-mspm0/src/time_driver.rs | 437 +++++++ embassy-mspm0/src/timer.rs | 48 + examples/mspm0c1104/.cargo/config.toml | 11 + examples/mspm0c1104/Cargo.toml | 32 + examples/mspm0c1104/README.md | 27 + examples/mspm0c1104/build.rs | 35 + examples/mspm0c1104/memory.x | 5 + examples/mspm0c1104/src/bin/blinky.rs | 27 + examples/mspm0c1104/src/bin/button.rs | 35 + examples/mspm0g3507/.cargo/config.toml | 9 + examples/mspm0g3507/Cargo.toml | 21 + examples/mspm0g3507/README.md | 27 + examples/mspm0g3507/build.rs | 35 + examples/mspm0g3507/memory.x | 6 + examples/mspm0g3507/src/bin/blinky.rs | 27 + examples/mspm0g3507/src/bin/button.rs | 35 + examples/mspm0g3519/.cargo/config.toml | 10 + examples/mspm0g3519/Cargo.toml | 21 + examples/mspm0g3519/MSPM0GX51X_Series.yaml | 424 +++++++ examples/mspm0g3519/README.md | 27 + examples/mspm0g3519/build.rs | 35 + examples/mspm0g3519/memory.x | 6 + examples/mspm0g3519/src/bin/blinky.rs | 27 + examples/mspm0g3519/src/bin/button.rs | 35 + examples/mspm0l1306/.cargo/config.toml | 9 + examples/mspm0l1306/Cargo.toml | 21 + examples/mspm0l1306/README.md | 27 + examples/mspm0l1306/build.rs | 35 + examples/mspm0l1306/memory.x | 5 + examples/mspm0l1306/src/bin/blinky.rs | 27 + examples/mspm0l1306/src/bin/button.rs | 35 + examples/mspm0l2228/.cargo/config.toml | 10 + examples/mspm0l2228/Cargo.toml | 21 + .../mspm0l2228/MSPM0L122X_L222X_Series.yaml | 239 ++++ examples/mspm0l2228/README.md | 27 + examples/mspm0l2228/build.rs | 35 + examples/mspm0l2228/memory.x | 6 + examples/mspm0l2228/src/bin/blinky.rs | 27 + examples/mspm0l2228/src/bin/button.rs | 35 + 51 files changed, 4476 insertions(+) create mode 100644 embassy-mspm0/Cargo.toml create mode 100644 embassy-mspm0/build.rs create mode 100644 embassy-mspm0/build_common.rs create mode 100644 embassy-mspm0/src/fmt.rs create mode 100644 embassy-mspm0/src/gpio.rs create mode 100644 embassy-mspm0/src/int_group/c110x.rs create mode 100644 embassy-mspm0/src/int_group/g350x.rs create mode 100644 embassy-mspm0/src/int_group/g351x.rs create mode 100644 embassy-mspm0/src/int_group/l130x.rs create mode 100644 embassy-mspm0/src/int_group/l222x.rs create mode 100644 embassy-mspm0/src/lib.rs create mode 100644 embassy-mspm0/src/time_driver.rs create mode 100644 embassy-mspm0/src/timer.rs create mode 100644 examples/mspm0c1104/.cargo/config.toml create mode 100644 examples/mspm0c1104/Cargo.toml create mode 100644 examples/mspm0c1104/README.md create mode 100644 examples/mspm0c1104/build.rs create mode 100644 examples/mspm0c1104/memory.x create mode 100644 examples/mspm0c1104/src/bin/blinky.rs create mode 100644 examples/mspm0c1104/src/bin/button.rs create mode 100644 examples/mspm0g3507/.cargo/config.toml create mode 100644 examples/mspm0g3507/Cargo.toml create mode 100644 examples/mspm0g3507/README.md create mode 100644 examples/mspm0g3507/build.rs create mode 100644 examples/mspm0g3507/memory.x create mode 100644 examples/mspm0g3507/src/bin/blinky.rs create mode 100644 examples/mspm0g3507/src/bin/button.rs create mode 100644 examples/mspm0g3519/.cargo/config.toml create mode 100644 examples/mspm0g3519/Cargo.toml create mode 100644 examples/mspm0g3519/MSPM0GX51X_Series.yaml create mode 100644 examples/mspm0g3519/README.md create mode 100644 examples/mspm0g3519/build.rs create mode 100644 examples/mspm0g3519/memory.x create mode 100644 examples/mspm0g3519/src/bin/blinky.rs create mode 100644 examples/mspm0g3519/src/bin/button.rs create mode 100644 examples/mspm0l1306/.cargo/config.toml create mode 100644 examples/mspm0l1306/Cargo.toml create mode 100644 examples/mspm0l1306/README.md create mode 100644 examples/mspm0l1306/build.rs create mode 100644 examples/mspm0l1306/memory.x create mode 100644 examples/mspm0l1306/src/bin/blinky.rs create mode 100644 examples/mspm0l1306/src/bin/button.rs create mode 100644 examples/mspm0l2228/.cargo/config.toml create mode 100644 examples/mspm0l2228/Cargo.toml create mode 100644 examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml create mode 100644 examples/mspm0l2228/README.md create mode 100644 examples/mspm0l2228/build.rs create mode 100644 examples/mspm0l2228/memory.x create mode 100644 examples/mspm0l2228/src/bin/blinky.rs create mode 100644 examples/mspm0l2228/src/bin/button.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 48d0957e6..e4814ff27 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,6 +28,11 @@ // To work on the examples, comment the line above and all of the cargo.features lines, // then uncomment ONE line below to select the chip you want to work on. // This makes rust-analyzer work on the example crate and all its dependencies. + // "examples/mspm0c1104/Cargo.toml", + // "examples/mspm0g3507/Cargo.toml", + // "examples/mspm0g3519/Cargo.toml", + // "examples/mspm0l1306/Cargo.toml", + // "examples/mspm0l2228/Cargo.toml", // "examples/nrf52840-rtic/Cargo.toml", // "examples/nrf5340/Cargo.toml", // "examples/nrf-rtos-trace/Cargo.toml", diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml new file mode 100644 index 000000000..0f4092d8a --- /dev/null +++ b/embassy-mspm0/Cargo.toml @@ -0,0 +1,125 @@ +[package] +name = "embassy-mspm0" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Embassy Hardware Abstraction Layer (HAL) for Texas Instruments MSPM0 series microcontrollers" +keywords = ["embedded", "async", "mspm0", "hal", "embedded-hal"] +categories = ["embedded", "hardware-support", "no-std", "asynchronous"] +repository = "https://github.com/embassy-rs/embassy" +documentation = "https://docs.embassy.dev/embassy-mspm0" + +[package.metadata.docs.rs] +features = ["defmt", "unstable-pac", "time-driver-any", "time", "mspm0g3507"] +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] +embassy-sync = { version = "0.6.2", path = "../embassy-sync" } +embassy-time = { version = "0.4.0", path = "../embassy-time", optional = true } +# TODO: Support other tick rates +embassy-time-driver = { version = "0.2", path = "../embassy-time-driver", optional = true, features = ["tick-hz-32_768"] } +embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true } +embassy-futures = { version = "0.1.0", path = "../embassy-futures" } +embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] } +embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false } +embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional = true } + +embedded-hal = { version = "1.0" } +embedded-hal-async = { version = "1.0" } + +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" +critical-section = "1.2.0" + +# mspm0-metapac = { version = "" } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-9faa5239a8eab04946086158f2a7fdff5a6a179d" } + +[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-9faa5239a8eab04946086158f2a7fdff5a6a179d", default-features = false, features = ["metadata"] } + +[features] +default = ["rt"] + +## Enable `mspm0-metapac`'s `rt` feature +rt = ["mspm0-metapac/rt"] + +## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging +defmt = [ + "dep:defmt", + "embassy-sync/defmt", + "embassy-embedded-hal/defmt", + "embassy-hal-internal/defmt", + "embassy-time?/defmt", +] + +## Re-export mspm0-metapac at `mspm0::pac`. +## This is unstable because semver-minor (non-breaking) releases of embassy-mspm0 may major-bump (breaking) the mspm0-metapac version. +## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC. +## There are no plans to make this stable. +unstable-pac = [] + +#! ## Time + +# Features starting with `_` are for internal use only. They're not intended +# to be enabled by other crates, and are not covered by semver guarantees. +_time-driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils"] + +# Use any time driver +time-driver-any = ["_time-driver"] +## Use TIMG0 as time driver +time-driver-timg0 = ["_time-driver"] +## Use TIMG1 as time driver +time-driver-timg1 = ["_time-driver"] +## Use TIMG2 as time driver +time-driver-timg2 = ["_time-driver"] +## Use TIMG3 as time driver +time-driver-timg3 = ["_time-driver"] +## Use TIMG4 as time driver +time-driver-timg4 = ["_time-driver"] +## Use TIMG5 as time driver +time-driver-timg5 = ["_time-driver"] +## Use TIMG6 as time driver +time-driver-timg6 = ["_time-driver"] +## Use TIMG7 as time driver +time-driver-timg7 = ["_time-driver"] +## Use TIMG8 as time driver +time-driver-timg8 = ["_time-driver"] +## Use TIMG9 as time driver +time-driver-timg9 = ["_time-driver"] +## Use TIMG10 as time driver +time-driver-timg10 = ["_time-driver"] +## Use TIMG11 as time driver +time-driver-timg11 = ["_time-driver"] +# TODO: Support TIMG12 and TIMG13 +## Use TIMG14 as time driver +time-driver-timg14 = ["_time-driver"] +## Use TIMA0 as time driver +time-driver-tima0 = ["_time-driver"] +## Use TIMA1 as time driver +time-driver-tima1 = ["_time-driver"] + +#! ## Chip-selection features +#! Select your chip by specifying the model as a feature, e.g. `mspm0g3507`. +#! 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" ] +mspm0g110x = [ "mspm0-metapac/mspm0g110x" ] +mspm0g150x = [ "mspm0-metapac/mspm0g150x" ] +mspm0g151x = [ "mspm0-metapac/mspm0g151x" ] +mspm0g310x = [ "mspm0-metapac/mspm0g310x" ] +mspm0g350x = [ "mspm0-metapac/mspm0g350x" ] +mspm0g351x = [ "mspm0-metapac/mspm0g351x" ] +mspm0l110x = [ "mspm0-metapac/mspm0l110x" ] +mspm0l122x = [ "mspm0-metapac/mspm0l122x" ] +mspm0l130x = [ "mspm0-metapac/mspm0l130x" ] +mspm0l134x = [ "mspm0-metapac/mspm0l134x" ] +mspm0l222x = [ "mspm0-metapac/mspm0l222x" ] diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs new file mode 100644 index 000000000..ffbe15c56 --- /dev/null +++ b/embassy-mspm0/build.rs @@ -0,0 +1,616 @@ +use std::collections::HashMap; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::sync::LazyLock; +use std::{env, fs}; + +use common::CfgSet; +use mspm0_metapac::metadata::METADATA; +use proc_macro2::{Ident, Literal, Span, TokenStream}; +use quote::{format_ident, quote}; + +#[path = "./build_common.rs"] +mod common; + +fn main() { + generate_code(); +} + +fn generate_code() { + let mut cfgs = common::CfgSet::new(); + common::set_target_cfgs(&mut cfgs); + + cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); + + let mut singletons = Vec::new(); + + // Generate singletons for GPIO pins. To only consider pins available on a family, use the name of + // the pins from the pincm mappings. + for pincm_mapping in METADATA.pincm_mappings.iter() { + singletons.push(pincm_mapping.pin.to_string()); + } + + for peri in METADATA.peripherals { + match peri.kind { + // Specially generated. + "gpio" => match peri.name { + "GPIOB" => cfgs.enable("gpio_pb"), + "GPIOC" => cfgs.enable("gpio_pc"), + _ => (), + }, + + // These peripherals are managed internally by the hal. + "iomux" | "cpuss" => {} + + _ => singletons.push(peri.name.to_string()), + } + } + + time_driver(&singletons, &mut cfgs); + + // ======== + // Write singletons + let mut g = TokenStream::new(); + + let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect(); + + g.extend(quote! { + embassy_hal_internal::peripherals_definition!(#(#singleton_tokens),*); + }); + + g.extend(quote! { + embassy_hal_internal::peripherals_struct!(#(#singleton_tokens),*); + }); + + // ======== + // Generate GPIO pincm lookup tables. + let pincms = METADATA.pincm_mappings.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. + // This is fine unless TI releases a part with 833+ GPIO pins. + let pin_number = mapping.pin[2..].parse::().unwrap(); + + let num = port_base + pin_number; + + // But subtract 1 since pincm indices start from 0, not 1. + let pincm = Literal::u8_unsuffixed(mapping.pincm - 1); + quote! { + #num => #pincm + } + }); + + g.extend(quote! { + #[doc = "Get the mapping from GPIO pin port to IOMUX PINCM index. This is required since the mapping from IO to PINCM index is not consistent across parts."] + pub(crate) fn gpio_pincm(pin_port: u8) -> u8 { + match pin_port { + #(#pincms),*, + _ => unreachable!(), + } + } + }); + + for pincm_mapping in METADATA.pincm_mappings.iter() { + let name = Ident::new(&pincm_mapping.pin, Span::call_site()); + let port_letter = pincm_mapping.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 port = Ident::new(&format!("Port{}", port_letter), Span::call_site()); + + // TODO: Feature gate pins that can be used as NRST + + g.extend(quote! { + impl_pin!(#name, crate::gpio::Port::#port, #pin_number); + }); + } + + // Generate timers + for peripheral in METADATA + .peripherals + .iter() + .filter(|p| p.name.starts_with("TIM")) + { + let name = Ident::new(&peripheral.name, Span::call_site()); + let timers = &*TIMERS; + + let timer = timers.get(peripheral.name).expect("Timer does not exist"); + assert!(timer.bits == 16 || timer.bits == 32); + let bits = if timer.bits == 16 { + quote! { Bits16 } + } else { + quote! { Bits32 } + }; + + g.extend(quote! { + impl_timer!(#name, #bits); + }); + } + + // Generate interrupt module + let interrupts: Vec = METADATA + .interrupts + .iter() + .map(|interrupt| Ident::new(interrupt.name, Span::call_site())) + .collect(); + + g.extend(quote! { + embassy_hal_internal::interrupt_mod! { + #(#interrupts),* + } + }); + + let group_interrupt_enables = METADATA + .interrupts + .iter() + .filter(|interrupt| interrupt.name.contains("GROUP")) + .map(|interrupt| { + let name = Ident::new(interrupt.name, Span::call_site()); + + quote! { + crate::interrupt::typelevel::#name::enable(); + } + }); + + // Generate interrupt enables for groups + g.extend(quote! { + pub fn enable_group_interrupts(_cs: critical_section::CriticalSection) { + use crate::interrupt::typelevel::Interrupt; + + unsafe { + #(#group_interrupt_enables)* + } + } + }); + + let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); + fs::write(&out_file, g.to_string()).unwrap(); + rustfmt(&out_file); +} + +fn time_driver(singletons: &[String], cfgs: &mut CfgSet) { + // Timer features + for (timer, desc) in TIMERS.iter() { + if desc.bits != 16 { + continue; + } + + let name = timer.to_lowercase(); + cfgs.declare(&format!("time_driver_{}", name)); + } + + let time_driver = match env::vars() + .map(|(a, _)| a) + .filter(|x| x.starts_with("CARGO_FEATURE_TIME_DRIVER_")) + .get_one() + { + Ok(x) => Some( + x.strip_prefix("CARGO_FEATURE_TIME_DRIVER_") + .unwrap() + .to_ascii_lowercase(), + ), + Err(GetOneError::None) => None, + Err(GetOneError::Multiple) => panic!("Multiple time-driver-xxx Cargo features enabled"), + }; + + // Verify the selected timer is available + let singleton = match time_driver.as_ref().map(|x| x.as_ref()) { + None => "", + Some("timg0") => "TIMG0", + Some("timg1") => "TIMG1", + Some("timg2") => "TIMG2", + Some("timg3") => "TIMG3", + Some("timg4") => "TIMG4", + Some("timg5") => "TIMG5", + Some("timg6") => "TIMG6", + Some("timg7") => "TIMG7", + Some("timg8") => "TIMG8", + Some("timg9") => "TIMG9", + Some("timg10") => "TIMG10", + Some("timg11") => "TIMG11", + Some("timg14") => "TIMG14", + Some("tima0") => "TIMA0", + Some("tima1") => "TIMA1", + Some("any") => { + // Order of timer candidates: + // 1. 16-bit, 2 channel + // 2. 16-bit, 2 channel with shadow registers + // 3. 16-bit, 4 channel + // 4. 16-bit with QEI + // 5. Advanced timers + // + // TODO: Select RTC first if available + // TODO: 32-bit timers are not considered yet + [ + // 16-bit, 2 channel + "TIMG0", "TIMG1", "TIMG2", "TIMG3", + // 16-bit, 2 channel with shadow registers + "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel + "TIMG14", // 16-bit with QEI + "TIMG8", "TIMG9", "TIMG10", "TIMG11", // Advanced timers + "TIMA0", "TIMA1", + ] + .iter() + .find(|tim| singletons.contains(&tim.to_string())) + .expect("Could not find any timer") + } + _ => panic!("unknown time_driver {:?}", time_driver), + }; + + if !singleton.is_empty() { + cfgs.enable(format!("time_driver_{}", singleton.to_lowercase())); + } +} + +/// rustfmt a given path. +/// Failures are logged to stderr and ignored. +fn rustfmt(path: impl AsRef) { + let path = path.as_ref(); + match Command::new("rustfmt").args([path]).output() { + Err(e) => { + eprintln!("failed to exec rustfmt {:?}: {:?}", path, e); + } + Ok(out) => { + if !out.status.success() { + eprintln!("rustfmt {:?} failed:", path); + eprintln!("=== STDOUT:"); + std::io::stderr().write_all(&out.stdout).unwrap(); + eprintln!("=== STDERR:"); + std::io::stderr().write_all(&out.stderr).unwrap(); + } + } + } +} + +#[allow(dead_code)] +struct TimerDesc { + bits: u8, + /// Is there an 8-bit prescaler + prescaler: bool, + /// Is there a repeat counter + repeat_counter: bool, + ccp_channels_internal: u8, + ccp_channels_external: u8, + external_pwm_channels: u8, + phase_load: bool, + shadow_load: bool, + shadow_ccs: bool, + deadband: bool, + fault_handler: bool, + qei_hall: bool, +} + +/// Description of all timer instances. +const TIMERS: LazyLock> = LazyLock::new(|| { + let mut map = HashMap::new(); + map.insert( + "TIMG0".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG1".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG2".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG3".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG4".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: true, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG5".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: true, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG6".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: true, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG7".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: true, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG8".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: true, + }, + ); + + map.insert( + "TIMG9".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: true, + }, + ); + + map.insert( + "TIMG10".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: true, + }, + ); + + map.insert( + "TIMG11".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: true, + }, + ); + + map.insert( + "TIMG12".into(), + TimerDesc { + bits: 32, + prescaler: false, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG13".into(), + TimerDesc { + bits: 32, + prescaler: false, + repeat_counter: false, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 2, + phase_load: false, + shadow_load: false, + shadow_ccs: true, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMG14".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: false, + ccp_channels_internal: 4, + ccp_channels_external: 4, + external_pwm_channels: 4, + phase_load: false, + shadow_load: false, + shadow_ccs: false, + deadband: false, + fault_handler: false, + qei_hall: false, + }, + ); + + map.insert( + "TIMA0".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: true, + ccp_channels_internal: 4, + ccp_channels_external: 2, + external_pwm_channels: 8, + phase_load: true, + shadow_load: true, + shadow_ccs: true, + deadband: true, + fault_handler: true, + qei_hall: false, + }, + ); + + map.insert( + "TIMA1".into(), + TimerDesc { + bits: 16, + prescaler: true, + repeat_counter: true, + ccp_channels_internal: 2, + ccp_channels_external: 2, + external_pwm_channels: 4, + phase_load: true, + shadow_load: true, + shadow_ccs: true, + deadband: true, + fault_handler: true, + qei_hall: false, + }, + ); + + map +}); + +enum GetOneError { + None, + Multiple, +} + +trait IteratorExt: Iterator { + fn get_one(self) -> Result; +} + +impl IteratorExt for T { + fn get_one(mut self) -> Result { + match self.next() { + None => Err(GetOneError::None), + Some(res) => match self.next() { + Some(_) => Err(GetOneError::Multiple), + None => Ok(res), + }, + } + } +} diff --git a/embassy-mspm0/build_common.rs b/embassy-mspm0/build_common.rs new file mode 100644 index 000000000..4f24e6d37 --- /dev/null +++ b/embassy-mspm0/build_common.rs @@ -0,0 +1,94 @@ +// NOTE: this file is copy-pasted between several Embassy crates, because there is no +// straightforward way to share this code: +// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path = +// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate +// reside in the crate's directory, +// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because +// symlinks don't work on Windows. + +use std::collections::HashSet; +use std::env; + +/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring +/// them (`cargo:rust-check-cfg=cfg(X)`). +#[derive(Debug)] +pub struct CfgSet { + enabled: HashSet, + declared: HashSet, +} + +impl CfgSet { + pub fn new() -> Self { + Self { + enabled: HashSet::new(), + declared: HashSet::new(), + } + } + + /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation. + /// + /// All configs that can potentially be enabled should be unconditionally declared using + /// [`Self::declare()`]. + pub fn enable(&mut self, cfg: impl AsRef) { + if self.enabled.insert(cfg.as_ref().to_owned()) { + println!("cargo:rustc-cfg={}", cfg.as_ref()); + } + } + + pub fn enable_all(&mut self, cfgs: &[impl AsRef]) { + for cfg in cfgs.iter() { + self.enable(cfg.as_ref()); + } + } + + /// Declare a valid config for conditional compilation, without enabling it. + /// + /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid. + pub fn declare(&mut self, cfg: impl AsRef) { + if self.declared.insert(cfg.as_ref().to_owned()) { + println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref()); + } + } + + pub fn declare_all(&mut self, cfgs: &[impl AsRef]) { + for cfg in cfgs.iter() { + self.declare(cfg.as_ref()); + } + } + + pub fn set(&mut self, cfg: impl Into, enable: bool) { + let cfg = cfg.into(); + if enable { + self.enable(cfg.clone()); + } + self.declare(cfg); + } +} + +/// Sets configs that describe the target platform. +pub fn set_target_cfgs(cfgs: &mut CfgSet) { + let target = env::var("TARGET").unwrap(); + + if target.starts_with("thumbv6m-") { + cfgs.enable_all(&["cortex_m", "armv6m"]); + } else if target.starts_with("thumbv7m-") { + cfgs.enable_all(&["cortex_m", "armv7m"]); + } else if target.starts_with("thumbv7em-") { + cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]); + } else if target.starts_with("thumbv8m.base") { + cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]); + } else if target.starts_with("thumbv8m.main") { + cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]); + } + cfgs.declare_all(&[ + "cortex_m", + "armv6m", + "armv7m", + "armv7em", + "armv8m", + "armv8m_base", + "armv8m_main", + ]); + + cfgs.set("has_fpu", target.ends_with("-eabihf")); +} diff --git a/embassy-mspm0/src/fmt.rs b/embassy-mspm0/src/fmt.rs new file mode 100644 index 000000000..8ca61bc39 --- /dev/null +++ b/embassy-mspm0/src/fmt.rs @@ -0,0 +1,270 @@ +#![macro_use] +#![allow(unused)] + +use core::fmt::{Debug, Display, LowerHex}; + +#[cfg(all(feature = "defmt", feature = "log"))] +compile_error!("You may not enable both `defmt` and `log` features."); + +#[collapse_debuginfo(yes)] +macro_rules! assert { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! assert_eq { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert_eq!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert_eq!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! assert_ne { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::assert_ne!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::assert_ne!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! debug_assert { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! debug_assert_eq { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert_eq!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert_eq!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! debug_assert_ne { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::debug_assert_ne!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::debug_assert_ne!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! todo { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::todo!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::todo!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! unreachable { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::unreachable!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::unreachable!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! panic { + ($($x:tt)*) => { + { + #[cfg(not(feature = "defmt"))] + ::core::panic!($($x)*); + #[cfg(feature = "defmt")] + ::defmt::panic!($($x)*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! trace { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::trace!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::trace!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! debug { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::debug!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::debug!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! info { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::info!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::info!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! warn { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::warn!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::warn!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[collapse_debuginfo(yes)] +macro_rules! error { + ($s:literal $(, $x:expr)* $(,)?) => { + { + #[cfg(feature = "log")] + ::log::error!($s $(, $x)*); + #[cfg(feature = "defmt")] + ::defmt::error!($s $(, $x)*); + #[cfg(not(any(feature = "log", feature="defmt")))] + let _ = ($( & $x ),*); + } + }; +} + +#[cfg(feature = "defmt")] +#[collapse_debuginfo(yes)] +macro_rules! unwrap { + ($($x:tt)*) => { + ::defmt::unwrap!($($x)*) + }; +} + +#[cfg(not(feature = "defmt"))] +#[collapse_debuginfo(yes)] +macro_rules! unwrap { + ($arg:expr) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); + } + } + }; + ($arg:expr, $($msg:expr),+ $(,)? ) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); + } + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct NoneError; + +pub trait Try { + type Ok; + type Error; + fn into_result(self) -> Result; +} + +impl Try for Option { + type Ok = T; + type Error = NoneError; + + #[inline] + fn into_result(self) -> Result { + self.ok_or(NoneError) + } +} + +impl Try for Result { + type Ok = T; + type Error = E; + + #[inline] + fn into_result(self) -> Self { + self + } +} + +pub(crate) struct Bytes<'a>(pub &'a [u8]); + +impl<'a> Debug for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +impl<'a> Display for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +impl<'a> LowerHex for Bytes<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:#02x?}", self.0) + } +} + +#[cfg(feature = "defmt")] +impl<'a> defmt::Format for Bytes<'a> { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!(fmt, "{:02x}", self.0) + } +} diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs new file mode 100644 index 000000000..fd4dc55ab --- /dev/null +++ b/embassy-mspm0/src/gpio.rs @@ -0,0 +1,1070 @@ +#![macro_use] + +use core::convert::Infallible; +use core::future::Future; +use core::pin::Pin as FuturePin; +use core::task::{Context, Poll}; + +use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; +use embassy_sync::waitqueue::AtomicWaker; +#[cfg(all(feature = "rt", feature = "mspm0c110x"))] +use crate::pac::interrupt; + +use crate::pac::{ + self, + gpio::{self, vals::*}, +}; + +/// Represents a digital input or output level. +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Level { + /// Logical low. + Low, + /// Logical high. + High, +} + +impl From for Level { + fn from(val: bool) -> Self { + match val { + true => Self::High, + false => Self::Low, + } + } +} + +impl From for bool { + fn from(level: Level) -> bool { + match level { + Level::Low => false, + Level::High => true, + } + } +} + +/// Represents a pull setting for an input. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum Pull { + /// No pull. + None, + /// Internal pull-up resistor. + Up, + /// Internal pull-down resistor. + Down, +} + +/// A GPIO bank with up to 32 pins. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum Port { + /// Port A. + PortA = 0, + + /// Port B. + #[cfg(gpio_pb)] + PortB = 1, + + /// Port C. + #[cfg(gpio_pc)] + PortC = 2, +} + +/// GPIO flexible pin. +/// +/// This pin can either be a disconnected, input, or output pin, or both. The level register bit will remain +/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output +/// mode. +pub struct Flex<'d> { + pin: PeripheralRef<'d, AnyPin>, +} + +impl<'d> Flex<'d> { + /// Wrap the pin in a `Flex`. + /// + /// The pin remains disconnected. The initial output level is unspecified, but can be changed + /// before the pin is put into output mode. + #[inline] + pub fn new(pin: impl Peripheral

+ 'd) -> Self { + into_ref!(pin); + + // Pin will be in disconnected state. + Self { + pin: pin.map_into(), + } + } + + /// Set the pin's pull. + #[inline] + pub fn set_pull(&mut self, pull: Pull) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pipd(matches!(pull, Pull::Down)); + w.set_pipu(matches!(pull, Pull::Up)); + }); + } + + /// Put the pin into input mode. + /// + /// The pull setting is left unchanged. + #[inline] + pub fn set_as_input(&mut self) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pf(GPIO_PF); + w.set_hiz1(false); + w.set_pc(true); + w.set_inena(true); + }); + + self.pin.block().doeclr31_0().write(|w| { + w.set_dio(self.pin.bit_index(), true); + }); + } + + /// Put the pin into output mode. + /// + /// The pin level will be whatever was set before (or low by default). If you want it to begin + /// at a specific level, call `set_high`/`set_low` on the pin first. + #[inline] + pub fn set_as_output(&mut self) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pf(GPIO_PF); + w.set_hiz1(false); + w.set_pc(true); + w.set_inena(false); + }); + + self.pin.block().doeset31_0().write(|w| { + w.set_dio(self.pin.bit_index(), true); + }); + } + + /// Put the pin into input + open-drain output mode. + /// + /// The hardware will drive the line low if you set it to low, and will leave it floating if you set + /// it to high, in which case you can read the input to figure out whether another device + /// is driving the line low. + /// + /// The pin level will be whatever was set before (or low by default). If you want it to begin + /// at a specific level, call `set_high`/`set_low` on the pin first. + /// + /// The internal weak pull-up and pull-down resistors will be disabled. + #[inline] + pub fn set_as_input_output(&mut self) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pf(GPIO_PF); + w.set_hiz1(true); + w.set_pc(true); + w.set_inena(false); + }); + + self.set_pull(Pull::None); + } + + /// Set the pin as "disconnected", ie doing nothing and consuming the lowest + /// amount of power possible. + /// + /// This is currently the same as [`Self::set_as_analog()`] but is semantically different + /// really. Drivers should `set_as_disconnected()` pins when dropped. + /// + /// Note that this also disables the internal weak pull-up and pull-down resistors. + #[inline] + pub fn set_as_disconnected(&mut self) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pf(DISCONNECT_PF); + w.set_hiz1(false); + w.set_pc(false); + w.set_inena(false); + }); + + self.set_pull(Pull::None); + self.set_inversion(false); + } + + /// Configure the logic inversion of this pin. + /// + /// Logic inversion applies to both the input and output path of this pin. + #[inline] + pub fn set_inversion(&mut self, invert: bool) { + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_inv(invert); + }); + } + + // TODO: drive strength, hysteresis, wakeup enable, wakeup compare + + /// Put the pin into the PF mode, unchecked. + /// + /// This puts the pin into the PF mode, with the request number. This is completely unchecked, + /// it can attach the pin to literally any peripheral, so use with care. In addition the pin + /// peripheral is connected in the iomux. + /// + /// The peripheral attached to the pin depends on the part in use. Consult the datasheet + /// or technical reference manual for additional details. + #[inline] + pub fn set_pf_unchecked(&mut self, pf: u8) { + // Per SLAU893, PF is only 5 bits + assert!((pf & 0x3F) != 0, "PF is out of range"); + + let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize); + + pincm.modify(|w| { + w.set_pf(pf); + // If the PF is manually set, connect the pin + w.set_pc(true); + }); + } + + /// Get whether the pin input level is high. + #[inline] + pub fn is_high(&self) -> bool { + !self.is_low() + } + + /// Get whether the pin input level is low. + #[inline] + pub fn is_low(&self) -> bool { + self.pin.block().din31_0().read().dio(self.pin.bit_index()) + } + + /// Returns current pin level + #[inline] + pub fn get_level(&self) -> Level { + self.is_high().into() + } + + /// Set the output as high. + #[inline] + pub fn set_high(&mut self) { + self.pin.block().doutset31_0().write(|w| { + w.set_dio(self.pin.bit_index() as usize, true); + }); + } + + /// Set the output as low. + #[inline] + pub fn set_low(&mut self) { + self.pin.block().doutclr31_0().write(|w| { + w.set_dio(self.pin.bit_index(), true); + }); + } + + /// Toggle pin output + #[inline] + pub fn toggle(&mut self) { + self.pin.block().douttgl31_0().write(|w| { + w.set_dio(self.pin.bit_index(), true); + }) + } + + /// Set the output level. + #[inline] + pub fn set_level(&mut self, level: Level) { + match level { + Level::Low => self.set_low(), + Level::High => self.set_high(), + } + } + + /// Get the current pin input level. + #[inline] + pub fn get_output_level(&self) -> Level { + self.is_high().into() + } + + /// Is the output level high? + #[inline] + pub fn is_set_high(&self) -> bool { + !self.is_set_low() + } + + /// Is the output level low? + #[inline] + pub fn is_set_low(&self) -> bool { + (self.pin.block().dout31_0().read().0 & self.pin.bit_index() as u32) == 0 + } + + /// Wait until the pin is high. If it is already high, return immediately. + #[inline] + pub async fn wait_for_high(&mut self) { + if self.is_high() { + return; + } + + self.wait_for_rising_edge().await + } + + /// Wait until the pin is low. If it is already low, return immediately. + #[inline] + pub async fn wait_for_low(&mut self) { + if self.is_low() { + return; + } + + self.wait_for_falling_edge().await + } + + /// Wait for the pin to undergo a transition from low to high. + #[inline] + pub async fn wait_for_rising_edge(&mut self) { + InputFuture::new(self.pin.reborrow(), Polarity::RISE).await + } + + /// Wait for the pin to undergo a transition from high to low. + #[inline] + pub async fn wait_for_falling_edge(&mut self) { + InputFuture::new(self.pin.reborrow(), Polarity::FALL).await + } + + /// Wait for the pin to undergo any transition, i.e low to high OR high to low. + #[inline] + pub async fn wait_for_any_edge(&mut self) { + InputFuture::new(self.pin.reborrow(), Polarity::RISE_FALL).await + } +} + +impl<'d> Drop for Flex<'d> { + #[inline] + fn drop(&mut self) { + self.set_as_disconnected(); + } +} + +/// GPIO input driver. +pub struct Input<'d> { + pin: Flex<'d>, +} + +impl<'d> Input<'d> { + /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. + #[inline] + pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + let mut pin = Flex::new(pin); + pin.set_as_input(); + pin.set_pull(pull); + Self { pin } + } + + /// Get whether the pin input level is high. + #[inline] + pub fn is_high(&self) -> bool { + self.pin.is_high() + } + + /// Get whether the pin input level is low. + #[inline] + pub fn is_low(&self) -> bool { + self.pin.is_low() + } + + /// Get the current pin input level. + #[inline] + pub fn get_level(&self) -> Level { + self.pin.get_level() + } + + /// Configure the logic inversion of this pin. + /// + /// Logic inversion applies to the input path of this pin. + #[inline] + pub fn set_inversion(&mut self, invert: bool) { + self.pin.set_inversion(invert) + } + + /// Wait until the pin is high. If it is already high, return immediately. + #[inline] + pub async fn wait_for_high(&mut self) { + self.pin.wait_for_high().await + } + + /// Wait until the pin is low. If it is already low, return immediately. + #[inline] + pub async fn wait_for_low(&mut self) { + self.pin.wait_for_low().await + } + + /// Wait for the pin to undergo a transition from low to high. + #[inline] + pub async fn wait_for_rising_edge(&mut self) { + self.pin.wait_for_rising_edge().await + } + + /// Wait for the pin to undergo a transition from high to low. + #[inline] + pub async fn wait_for_falling_edge(&mut self) { + self.pin.wait_for_falling_edge().await + } + + /// Wait for the pin to undergo any transition, i.e low to high OR high to low. + #[inline] + pub async fn wait_for_any_edge(&mut self) { + self.pin.wait_for_any_edge().await + } +} + +/// GPIO output driver. +/// +/// Note that pins will **return to their floating state** when `Output` is dropped. +/// If pins should retain their state indefinitely, either keep ownership of the +/// `Output`, or pass it to [`core::mem::forget`]. +pub struct Output<'d> { + pin: Flex<'d>, +} + +impl<'d> Output<'d> { + /// Create GPIO output driver for a [Pin] with the provided [Level] configuration. + #[inline] + pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + let mut pin = Flex::new(pin); + pin.set_as_output(); + pin.set_level(initial_output); + Self { pin } + } + + /// Set the output as high. + #[inline] + pub fn set_high(&mut self) { + self.pin.set_high(); + } + + /// Set the output as low. + #[inline] + pub fn set_low(&mut self) { + self.pin.set_low(); + } + + /// Set the output level. + #[inline] + pub fn set_level(&mut self, level: Level) { + self.pin.set_level(level) + } + + /// Is the output pin set as high? + #[inline] + pub fn is_set_high(&self) -> bool { + self.pin.is_set_high() + } + + /// Is the output pin set as low? + #[inline] + pub fn is_set_low(&self) -> bool { + self.pin.is_set_low() + } + + /// What level output is set to + #[inline] + pub fn get_output_level(&self) -> Level { + self.pin.get_output_level() + } + + /// Toggle pin output + #[inline] + pub fn toggle(&mut self) { + self.pin.toggle(); + } + + /// Configure the logic inversion of this pin. + /// + /// Logic inversion applies to the input path of this pin. + #[inline] + pub fn set_inversion(&mut self, invert: bool) { + self.pin.set_inversion(invert) + } +} + +/// GPIO output open-drain driver. +/// +/// Note that pins will **return to their floating state** when `OutputOpenDrain` is dropped. +/// If pins should retain their state indefinitely, either keep ownership of the +/// `OutputOpenDrain`, or pass it to [`core::mem::forget`]. +pub struct OutputOpenDrain<'d> { + pin: Flex<'d>, +} + +impl<'d> OutputOpenDrain<'d> { + /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level]. + #[inline] + pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + let mut pin = Flex::new(pin); + pin.set_level(initial_output); + pin.set_as_input_output(); + Self { pin } + } + + /// Get whether the pin input level is high. + #[inline] + pub fn is_high(&self) -> bool { + !self.pin.is_low() + } + + /// Get whether the pin input level is low. + #[inline] + pub fn is_low(&self) -> bool { + self.pin.is_low() + } + + /// Get the current pin input level. + #[inline] + pub fn get_level(&self) -> Level { + self.pin.get_level() + } + + /// Set the output as high. + #[inline] + pub fn set_high(&mut self) { + self.pin.set_high(); + } + + /// Set the output as low. + #[inline] + pub fn set_low(&mut self) { + self.pin.set_low(); + } + + /// Set the output level. + #[inline] + pub fn set_level(&mut self, level: Level) { + self.pin.set_level(level); + } + + /// Get whether the output level is set to high. + #[inline] + pub fn is_set_high(&self) -> bool { + self.pin.is_set_high() + } + + /// Get whether the output level is set to low. + #[inline] + pub fn is_set_low(&self) -> bool { + self.pin.is_set_low() + } + + /// Get the current output level. + #[inline] + pub fn get_output_level(&self) -> Level { + self.pin.get_output_level() + } + + /// Toggle pin output + #[inline] + pub fn toggle(&mut self) { + self.pin.toggle() + } + + /// Configure the logic inversion of this pin. + /// + /// Logic inversion applies to the input path of this pin. + #[inline] + pub fn set_inversion(&mut self, invert: bool) { + self.pin.set_inversion(invert) + } + + /// Wait until the pin is high. If it is already high, return immediately. + #[inline] + pub async fn wait_for_high(&mut self) { + self.pin.wait_for_high().await + } + + /// Wait until the pin is low. If it is already low, return immediately. + #[inline] + pub async fn wait_for_low(&mut self) { + self.pin.wait_for_low().await + } + + /// Wait for the pin to undergo a transition from low to high. + #[inline] + pub async fn wait_for_rising_edge(&mut self) { + self.pin.wait_for_rising_edge().await + } + + /// Wait for the pin to undergo a transition from high to low. + #[inline] + pub async fn wait_for_falling_edge(&mut self) { + self.pin.wait_for_falling_edge().await + } + + /// Wait for the pin to undergo any transition, i.e low to high OR high to low. + #[inline] + pub async fn wait_for_any_edge(&mut self) { + self.pin.wait_for_any_edge().await + } +} + +/// Type-erased GPIO pin +pub struct AnyPin { + pin_port: u8, +} + +impl AnyPin { + /// Create an [AnyPin] for a specific pin. + /// + /// # Safety + /// - `pin_port` should not in use by another driver. + #[inline] + pub unsafe fn steal(pin_port: u8) -> Self { + Self { pin_port } + } +} + +impl_peripheral!(AnyPin); + +impl Pin for AnyPin {} +impl SealedPin for AnyPin { + #[inline] + fn pin_port(&self) -> u8 { + self.pin_port + } +} + +/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. +#[allow(private_bounds)] +pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { + fn degrade(self) -> AnyPin { + AnyPin { + pin_port: self.pin_port(), + } + } + + /// The index of this pin in PINCM (pin control management) registers. + #[inline] + fn pin_cm(&self) -> u8 { + self._pin_cm() + } +} + +impl<'d> embedded_hal::digital::ErrorType for Flex<'d> { + type Error = Infallible; +} + +impl<'d> embedded_hal::digital::InputPin for Flex<'d> { + #[inline] + fn is_high(&mut self) -> Result { + Ok((*self).is_high()) + } + + #[inline] + fn is_low(&mut self) -> Result { + Ok((*self).is_low()) + } +} + +impl<'d> embedded_hal::digital::OutputPin for Flex<'d> { + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + Ok(self.set_low()) + } + + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + Ok(self.set_high()) + } +} + +impl<'d> embedded_hal::digital::StatefulOutputPin for Flex<'d> { + #[inline] + fn is_set_high(&mut self) -> Result { + Ok((*self).is_set_high()) + } + + #[inline] + fn is_set_low(&mut self) -> Result { + Ok((*self).is_set_low()) + } +} + +impl<'d> embedded_hal_async::digital::Wait for Flex<'d> { + async fn wait_for_high(&mut self) -> Result<(), Self::Error> { + self.wait_for_high().await; + Ok(()) + } + + async fn wait_for_low(&mut self) -> Result<(), Self::Error> { + self.wait_for_low().await; + Ok(()) + } + + async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_rising_edge().await; + Ok(()) + } + + async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_falling_edge().await; + Ok(()) + } + + async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_any_edge().await; + Ok(()) + } +} + +impl<'d> embedded_hal::digital::ErrorType for Input<'d> { + type Error = Infallible; +} + +impl<'d> embedded_hal::digital::InputPin for Input<'d> { + #[inline] + fn is_high(&mut self) -> Result { + Ok((*self).is_high()) + } + + #[inline] + fn is_low(&mut self) -> Result { + Ok((*self).is_low()) + } +} + +impl<'d> embedded_hal_async::digital::Wait for Input<'d> { + async fn wait_for_high(&mut self) -> Result<(), Self::Error> { + self.wait_for_high().await; + Ok(()) + } + + async fn wait_for_low(&mut self) -> Result<(), Self::Error> { + self.wait_for_low().await; + Ok(()) + } + + async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_rising_edge().await; + Ok(()) + } + + async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_falling_edge().await; + Ok(()) + } + + async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_any_edge().await; + Ok(()) + } +} + +impl<'d> embedded_hal::digital::ErrorType for Output<'d> { + type Error = Infallible; +} + +impl<'d> embedded_hal::digital::OutputPin for Output<'d> { + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + Ok(self.set_low()) + } + + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + Ok(self.set_high()) + } +} + +impl<'d> embedded_hal::digital::StatefulOutputPin for Output<'d> { + #[inline] + fn is_set_high(&mut self) -> Result { + Ok((*self).is_set_high()) + } + + #[inline] + fn is_set_low(&mut self) -> Result { + Ok((*self).is_set_low()) + } +} + +impl<'d> embedded_hal::digital::ErrorType for OutputOpenDrain<'d> { + type Error = Infallible; +} + +impl<'d> embedded_hal::digital::InputPin for OutputOpenDrain<'d> { + #[inline] + fn is_high(&mut self) -> Result { + Ok((*self).is_high()) + } + + #[inline] + fn is_low(&mut self) -> Result { + Ok((*self).is_low()) + } +} + +impl<'d> embedded_hal::digital::OutputPin for OutputOpenDrain<'d> { + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + Ok(self.set_low()) + } + + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + Ok(self.set_high()) + } +} + +impl<'d> embedded_hal::digital::StatefulOutputPin for OutputOpenDrain<'d> { + #[inline] + fn is_set_high(&mut self) -> Result { + Ok((*self).is_set_high()) + } + + #[inline] + fn is_set_low(&mut self) -> Result { + Ok((*self).is_set_low()) + } +} + +impl<'d> embedded_hal_async::digital::Wait for OutputOpenDrain<'d> { + async fn wait_for_high(&mut self) -> Result<(), Self::Error> { + self.wait_for_high().await; + Ok(()) + } + + async fn wait_for_low(&mut self) -> Result<(), Self::Error> { + self.wait_for_low().await; + Ok(()) + } + + async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_rising_edge().await; + Ok(()) + } + + async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_falling_edge().await; + Ok(()) + } + + async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { + self.wait_for_any_edge().await; + Ok(()) + } +} + +/// The pin function to disconnect peripherals from the pin. +/// +/// This is also the pin function used to connect to analog peripherals, such as an ADC. +const DISCONNECT_PF: u8 = 0; + +/// The pin function for the GPIO peripheral. +/// +/// This is fixed to `1` for every part. +const GPIO_PF: u8 = 1; + +macro_rules! impl_pin { + ($name: ident, $port: expr, $pin_num: expr) => { + impl crate::gpio::Pin for crate::peripherals::$name {} + impl crate::gpio::SealedPin for crate::peripherals::$name { + #[inline] + fn pin_port(&self) -> u8 { + ($port as u8) * 32 + $pin_num + } + } + + impl From for crate::gpio::AnyPin { + fn from(val: crate::peripherals::$name) -> Self { + crate::gpio::Pin::degrade(val) + } + } + }; +} + +// TODO: Possible micro-op for C110X, not every pin is instantiated even on the 20 pin parts. +// This would mean cfg guarding to just cfg guarding every pin instance. +static PORTA_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; +#[cfg(gpio_pb)] +static PORTB_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; +#[cfg(gpio_pc)] +static PORTC_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; + +pub(crate) trait SealedPin { + fn pin_port(&self) -> u8; + + fn port(&self) -> Port { + match self.pin_port() / 32 { + 0 => Port::PortA, + #[cfg(gpio_pb)] + 1 => Port::PortB, + #[cfg(gpio_pc)] + 2 => Port::PortC, + _ => unreachable!(), + } + } + + fn waker(&self) -> &AtomicWaker { + match self.port() { + Port::PortA => &PORTA_WAKERS[self.bit_index()], + #[cfg(gpio_pb)] + Port::PortB => &PORTB_WAKERS[self.bit_index()], + #[cfg(gpio_pc)] + Port::PortC => &PORTC_WAKERS[self.bit_index()], + } + } + + fn _pin_cm(&self) -> u8 { + // Some parts like the MSPM0L222x have pincm mappings all over the place. + crate::gpio_pincm(self.pin_port()) + } + + fn bit_index(&self) -> usize { + (self.pin_port() % 32) as usize + } + + #[inline] + fn block(&self) -> gpio::Gpio { + match self.pin_port() / 32 { + 0 => pac::GPIOA, + #[cfg(gpio_pb)] + 1 => pac::GPIOB, + #[cfg(gpio_pc)] + 2 => pac::GPIOC, + _ => unreachable!(), + } + } +} + +#[must_use = "futures do nothing unless you `.await` or poll them"] +struct InputFuture<'d> { + pin: PeripheralRef<'d, AnyPin>, +} + +impl<'d> InputFuture<'d> { + fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { + let block = pin.block(); + + // First clear the bit for this event. Otherwise previous edge events may be recorded. + block.cpu_int().iclr().write(|w| { + w.set_dio(pin.bit_index(), true); + }); + + // Selecting which polarity events happens is a RMW operation. + // + // Guard with a critical section in case two different threads try to select events at the + // same time. + critical_section::with(|_cs| { + // Tell the hardware which pin event we want to receive. + if pin.bit_index() >= 16 { + block.polarity31_16().modify(|w| { + w.set_dio(pin.bit_index() - 16, polarity); + }); + } else { + block.polarity15_0().modify(|w| { + w.set_dio(pin.bit_index(), polarity); + }); + }; + }); + + Self { pin } + } +} + +impl<'d> Future for InputFuture<'d> { + type Output = (); + + fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // We need to register/re-register the waker for each poll because any + // calls to wake will deregister the waker. + let waker = self.pin.waker(); + waker.register(cx.waker()); + + // The interrupt handler will mask the interrupt if the event has occurred. + if self + .pin + .block() + .cpu_int() + .ris() + .read() + .dio(self.pin.bit_index()) + { + return Poll::Ready(()); + } + + // Unmasking the interrupt is a RMW operation. + // + // Guard with a critical section in case two different threads try to unmask at the same time. + critical_section::with(|_cs| { + self.pin.block().cpu_int().imask().modify(|w| { + w.set_dio(self.pin.bit_index(), true); + }); + }); + + Poll::Pending + } +} + +pub(crate) fn init(gpio: gpio::Gpio) { + gpio.gprcm().rstctl().write(|w| { + w.set_resetstkyclr(true); + w.set_resetassert(true); + w.set_key(ResetKey::KEY); + }); + + gpio.gprcm().pwren().write(|w| { + w.set_enable(true); + w.set_key(PwrenKey::KEY); + }); + + gpio.evt_mode().modify(|w| { + // The CPU will clear it's own interrupts + w.set_cpu_cfg(EvtCfg::SOFTWARE); + }); +} + +#[cfg(feature = "rt")] +fn irq_handler(gpio: gpio::Gpio, wakers: &[AtomicWaker; 32]) { + // Only consider pins which have interrupts unmasked. + let bits = gpio.cpu_int().mis().read().0; + + for i in BitIter(bits) { + wakers[i as usize].wake(); + + // Notify the future that an edge event has occurred by masking the interrupt for this pin. + gpio.cpu_int().imask().modify(|w| { + w.set_dio(i as usize, false); + }); + } +} + +struct BitIter(u32); + +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) + } + } + } +} + +// C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt. +#[cfg(all(feature = "rt", feature = "mspm0c110x"))] +#[interrupt] +fn GPIOA() { + gpioa_interrupt(); +} + +#[cfg(feature = "rt")] +pub(crate) fn gpioa_interrupt() { + irq_handler(pac::GPIOA, &PORTA_WAKERS); +} + +#[cfg(all(feature = "rt", gpio_pb))] +pub(crate) fn gpiob_interrupt() { + irq_handler(pac::GPIOB, &PORTB_WAKERS); +} + +#[cfg(all(feature = "rt", gpio_pc))] +pub(crate) fn gpioc_interrupt() { + irq_handler(pac::GPIOC, &PORTC_WAKERS); +} diff --git a/embassy-mspm0/src/int_group/c110x.rs b/embassy-mspm0/src/int_group/c110x.rs new file mode 100644 index 000000000..c503af631 --- /dev/null +++ b/embassy-mspm0/src/int_group/c110x.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(1); + + // TODO: Decompose to direct u8 + let iidx = group.iidx().read().stat().to_bits(); + + 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/g350x.rs b/embassy-mspm0/src/int_group/g350x.rs new file mode 100644 index 000000000..818dd6e1e --- /dev/null +++ b/embassy-mspm0/src/int_group/g350x.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(1); + + // 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/int_group/g351x.rs b/embassy-mspm0/src/int_group/g351x.rs new file mode 100644 index 000000000..b43e0a9db --- /dev/null +++ b/embassy-mspm0/src/int_group/g351x.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(1); + + // 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/l130x.rs b/embassy-mspm0/src/int_group/l130x.rs new file mode 100644 index 000000000..6d033cc56 --- /dev/null +++ b/embassy-mspm0/src/int_group/l130x.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(1); + + // 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/l222x.rs b/embassy-mspm0/src/int_group/l222x.rs new file mode 100644 index 000000000..703e16e78 --- /dev/null +++ b/embassy-mspm0/src/int_group/l222x.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(1); + + // 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 => crate::gpio::gpiob_interrupt(), + Group1::COMP0 => todo!("implement COMP0"), + Group1::TRNG => todo!("implement TRNG"), + Group1::GPIOC => crate::gpio::gpioc_interrupt(), + } +} diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs new file mode 100644 index 000000000..ee629f063 --- /dev/null +++ b/embassy-mspm0/src/lib.rs @@ -0,0 +1,112 @@ +#![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)) +)] + +// This mod MUST go first, so that the others see its macros. +pub(crate) mod fmt; + +pub mod gpio; +pub mod timer; + +#[cfg(feature = "_time-driver")] +mod time_driver; + +// Interrupt group handlers. +#[cfg_attr(feature = "mspm0c110x", path = "int_group/c110x.rs")] +#[cfg_attr(feature = "mspm0g110x", path = "int_group/g110x.rs")] +#[cfg_attr(feature = "mspm0g150x", path = "int_group/g150x.rs")] +#[cfg_attr(feature = "mspm0g151x", path = "int_group/g151x.rs")] +#[cfg_attr(feature = "mspm0g310x", path = "int_group/g310x.rs")] +#[cfg_attr(feature = "mspm0g350x", path = "int_group/g350x.rs")] +#[cfg_attr(feature = "mspm0g351x", path = "int_group/g351x.rs")] +#[cfg_attr(feature = "mspm0l110x", path = "int_group/l110x.rs")] +#[cfg_attr(feature = "mspm0l122x", path = "int_group/l122x.rs")] +#[cfg_attr(feature = "mspm0l130x", path = "int_group/l130x.rs")] +#[cfg_attr(feature = "mspm0l134x", path = "int_group/l134x.rs")] +#[cfg_attr(feature = "mspm0l222x", path = "int_group/l222x.rs")] +mod int_group; + +pub(crate) mod _generated { + #![allow(dead_code)] + #![allow(unused_imports)] + #![allow(non_snake_case)] + #![allow(missing_docs)] + + include!(concat!(env!("OUT_DIR"), "/_generated.rs")); +} + +// Reexports +pub use _generated::{peripherals, Peripherals}; +pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +#[cfg(feature = "unstable-pac")] +pub use mspm0_metapac as pac; +#[cfg(not(feature = "unstable-pac"))] +pub(crate) use mspm0_metapac as pac; + +pub use crate::_generated::interrupt; +pub(crate) use _generated::gpio_pincm; + + +/// `embassy-mspm0` global configuration. +#[non_exhaustive] +#[derive(Clone, Copy)] +pub struct Config { + // TODO +} + +impl Default for Config { + fn default() -> Self { + Self { + // TODO + } + } +} + +pub fn init(_config: Config) -> Peripherals { + critical_section::with(|cs| { + let peripherals = Peripherals::take_with_cs(cs); + + // TODO: Further clock configuration + + pac::SYSCTL.mclkcfg().modify(|w| { + // Enable MFCLK + w.set_usemftick(true); + // MDIV must be disabled if MFCLK is enabled. + w.set_mdiv(0); + }); + + // Enable MFCLK for peripheral use + // + // TODO: Optional? + pac::SYSCTL.genclken().modify(|w| { + w.set_mfpclken(true); + }); + + pac::SYSCTL.borthreshold().modify(|w| { + w.set_level(0); + }); + + gpio::init(pac::GPIOA); + #[cfg(gpio_pb)] + gpio::init(pac::GPIOB); + #[cfg(gpio_pc)] + gpio::init(pac::GPIOC); + + _generated::enable_group_interrupts(cs); + + #[cfg(feature = "mspm0c110x")] + unsafe { + use crate::_generated::interrupt::typelevel::Interrupt; + crate::interrupt::typelevel::GPIOA::enable(); + } + + #[cfg(feature = "_time-driver")] + time_driver::init(cs); + + peripherals + }) +} diff --git a/embassy-mspm0/src/time_driver.rs b/embassy-mspm0/src/time_driver.rs new file mode 100644 index 000000000..3af7a5edb --- /dev/null +++ b/embassy-mspm0/src/time_driver.rs @@ -0,0 +1,437 @@ +use core::{ + cell::{Cell, RefCell}, + sync::atomic::{compiler_fence, AtomicU32, Ordering}, + task::Waker, +}; + +use critical_section::{CriticalSection, Mutex}; +use embassy_time_driver::Driver; +use embassy_time_queue_utils::Queue; +use mspm0_metapac::{ + interrupt, + tim::{ + vals::{Cm, Cvae, CxC, EvtCfg, PwrenKey, Ratio, Repeat, ResetKey}, + Counterregs16, Tim, + }, +}; + +use crate::peripherals; +use crate::timer::SealedTimer; + +// Currently TIMG12 and TIMG13 are excluded because those are 32-bit timers. +#[cfg(time_driver_timg0)] +type T = peripherals::TIMG0; +#[cfg(time_driver_timg1)] +type T = peripherals::TIMG1; +#[cfg(time_driver_timg2)] +type T = peripherals::TIMG2; +#[cfg(time_driver_timg3)] +type T = peripherals::TIMG3; +#[cfg(time_driver_timg4)] +type T = peripherals::TIMG4; +#[cfg(time_driver_timg5)] +type T = peripherals::TIMG5; +#[cfg(time_driver_timg6)] +type T = peripherals::TIMG6; +#[cfg(time_driver_timg7)] +type T = peripherals::TIMG7; +#[cfg(time_driver_timg8)] +type T = peripherals::TIMG8; +#[cfg(time_driver_timg9)] +type T = peripherals::TIMG9; +#[cfg(time_driver_timg10)] +type T = peripherals::TIMG10; +#[cfg(time_driver_timg11)] +type T = peripherals::TIMG11; +#[cfg(time_driver_timg14)] +type T = peripherals::TIMG14; +#[cfg(time_driver_tima0)] +type T = peripherals::TIMA0; +#[cfg(time_driver_tima1)] +type T = peripherals::TIMA1; + +// TODO: RTC + +fn regs() -> Tim { + unsafe { Tim::from_ptr(T::regs()) } +} + +fn regs_counter(tim: Tim) -> Counterregs16 { + unsafe { Counterregs16::from_ptr(tim.counterregs(0).as_ptr()) } +} + +/// Clock timekeeping works with something we call "periods", which are time intervals +/// of 2^15 ticks. The Clock counter value is 16 bits, so one "overflow cycle" is 2 periods. +fn calc_now(period: u32, counter: u16) -> u64 { + ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64) +} + +/// The TIMx driver uses one of the `TIMG` or `TIMA` timer instances to implement a timer with a 32.768 kHz +/// tick rate. (TODO: Allow setting the tick rate) +/// +/// This driver defines a period to be 2^15 ticks. 16-bit timers of course count to 2^16 ticks. +/// +/// To generate a period every 2^15 ticks, the CC0 value is set to 2^15 and the load value set to 2^16. +/// Incrementing the period on a CCU0 and load results in the a period of 2^15 ticks. +/// +/// For a specific timestamp, load the lower 16 bits into the CC1 value. When the period where the timestamp +/// should be enabled is reached, then the CCU1 (CC1 up) interrupt runs to actually wake the timer. +/// +/// TODO: Compensate for per part variance. This can supposedly be done with the FCC system. +/// TODO: Allow using 32-bit timers (TIMG12 and TIMG13). +struct TimxDriver { + /// Number of 2^15 periods elapsed since boot. + period: AtomicU32, + /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. + alarm: Mutex>, + queue: Mutex>, +} + +impl TimxDriver { + #[inline(never)] + fn init(&'static self, _cs: CriticalSection) { + // Clock config + // TODO: Configurable tick rate up to 4 MHz (32 kHz for now) + let regs = regs(); + + // Reset timer + regs.gprcm(0).rstctl().write(|w| { + w.set_resetassert(true); + w.set_key(ResetKey::KEY); + w.set_resetstkyclr(true); + }); + + // Power up timer + regs.gprcm(0).pwren().write(|w| { + w.set_enable(true); + w.set_key(PwrenKey::KEY); + }); + + // Following the instructions according to SLAU847D 23.2.1: TIMCLK Configuration + + // 1. Select TIMCLK source + regs.clksel().modify(|w| { + // Use LFCLK for a 32.768kHz tick rate + w.set_lfclk_sel(true); + // TODO: Allow MFCLK for configurable tick rate up to 4 MHz + // w.set_mfclk_sel(ClkSel::ENABLE); + }); + + // 2. Divide by TIMCLK, we don't need to divide further for the 32kHz tick rate + regs.clkdiv().modify(|w| { + w.set_ratio(Ratio::DIV_BY_1); + }); + + // 3. To be generic across timer instances, we do not use the prescaler. + // TODO: mspm0-sdk always sets this, regardless of timer width? + regs.commonregs(0).cps().modify(|w| { + w.set_pcnt(0); + }); + + regs.pdbgctl().modify(|w| { + w.set_free(true); + }); + + // 4. Enable the TIMCLK. + regs.commonregs(0).cclkctl().modify(|w| { + w.set_clken(true); + }); + + regs.counterregs(0).ctrctl().modify(|w| { + // allow counting during debug + w.set_repeat(Repeat::REPEAT_3); + w.set_cvae(Cvae::ZEROVAL); + w.set_cm(Cm::UP); + + // Must explicitly set CZC, CAC and CLC to 0 in order for all the timers to count. + // + // The reset value of these registers is 0x07, which is a reserved value. + // + // Looking at a bit representation of the reset value, this appears to be an AND + // of 2-input QEI mode and CCCTL_3 ACOND. Given that TIMG14 and TIMA0 have no QEI + // and 4 capture and compare channels, this works by accident for those timer units. + w.set_czc(CxC::CCTL0); + w.set_cac(CxC::CCTL0); + w.set_clc(CxC::CCTL0); + }); + + // Setup the period + let ctr = regs_counter(regs); + + // Middle + ctr.cc(0).modify(|w| { + w.set_ccval(0x7FFF); + }); + + ctr.load().modify(|w| { + w.set_ld(u16::MAX); + }); + + // Enable the period interrupts + // + // This does not appear to ever be set for CPU_INT in the TI SDK and is not technically needed. + regs.evt_mode().modify(|w| { + w.set_evt_cfg(0, EvtCfg::SOFTWARE); + }); + + regs.int_event(0).imask().modify(|w| { + w.set_l(true); + w.set_ccu0(true); + }); + + unsafe { T::enable_interrupt() }; + + // Allow the counter to start counting. + regs.counterregs(0).ctrctl().modify(|w| { + w.set_en(true); + }); + } + + #[inline(never)] + fn next_period(&self) { + let r = regs(); + + // We only modify the period from the timer interrupt, so we know this can't race. + let period = self.period.load(Ordering::Relaxed) + 1; + self.period.store(period, Ordering::Relaxed); + let t = (period as u64) << 15; + + critical_section::with(move |cs| { + r.int_event(0).imask().modify(move |w| { + let alarm = self.alarm.borrow(cs); + let at = alarm.get(); + + if at < t + 0xC000 { + // just enable it. `set_alarm` has already set the correct CC1 val. + w.set_ccu1(true); + } + }) + }); + } + + #[inline(never)] + fn on_interrupt(&self) { + let r = regs(); + + critical_section::with(|cs| { + let mis = r.int_event(0).mis().read(); + + // Advance to next period if overflowed + if mis.l() { + self.next_period(); + + r.int_event(0).iclr().write(|w| { + w.set_l(true); + }); + } + + if mis.ccu0() { + self.next_period(); + + r.int_event(0).iclr().write(|w| { + w.set_ccu0(true); + }); + } + + if mis.ccu1() { + r.int_event(0).iclr().write(|w| { + w.set_ccu1(true); + }); + + self.trigger_alarm(cs); + } + }); + } + + fn trigger_alarm(&self, cs: CriticalSection) { + let mut next = self + .queue + .borrow(cs) + .borrow_mut() + .next_expiration(self.now()); + + while !self.set_alarm(cs, next) { + next = self + .queue + .borrow(cs) + .borrow_mut() + .next_expiration(self.now()); + } + } + + fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { + let r = regs(); + let ctr = regs_counter(r); + + self.alarm.borrow(cs).set(timestamp); + + let t = self.now(); + + if timestamp <= t { + // If alarm timestamp has passed the alarm will not fire. + // Disarm the alarm and return `false` to indicate that. + r.int_event(0).imask().modify(|w| w.set_ccu1(false)); + + self.alarm.borrow(cs).set(u64::MAX); + + return false; + } + + // Write the CC1 value regardless of whether we're going to enable it now or not. + // This way, when we enable it later, the right value is already set. + ctr.cc(1).write(|w| { + w.set_ccval(timestamp as u16); + }); + + // Enable it if it'll happen soon. Otherwise, `next_period` will enable it. + let diff = timestamp - t; + r.int_event(0).imask().modify(|w| w.set_ccu1(diff < 0xC000)); + + // Reevaluate if the alarm timestamp is still in the future + let t = self.now(); + if timestamp <= t { + // If alarm timestamp has passed since we set it, we have a race condition and + // the alarm may or may not have fired. + // Disarm the alarm and return `false` to indicate that. + // It is the caller's responsibility to handle this ambiguity. + r.int_event(0).imask().modify(|w| w.set_ccu1(false)); + + self.alarm.borrow(cs).set(u64::MAX); + + return false; + } + + // We're confident the alarm will ring in the future. + true + } +} + +impl Driver for TimxDriver { + fn now(&self) -> u64 { + let regs = regs(); + + let period = self.period.load(Ordering::Relaxed); + // Ensure the compiler does not read the counter before the period. + compiler_fence(Ordering::Acquire); + + let counter = regs_counter(regs).ctr().read().cctr() as u16; + + calc_now(period, counter) + } + + fn schedule_wake(&self, at: u64, waker: &Waker) { + critical_section::with(|cs| { + let mut queue = self.queue.borrow(cs).borrow_mut(); + + if queue.schedule_wake(at, waker) { + let mut next = queue.next_expiration(self.now()); + + while !self.set_alarm(cs, next) { + next = queue.next_expiration(self.now()); + } + } + }); + } +} + +embassy_time_driver::time_driver_impl!(static DRIVER: TimxDriver = TimxDriver { + period: AtomicU32::new(0), + alarm: Mutex::new(Cell::new(u64::MAX)), + queue: Mutex::new(RefCell::new(Queue::new())) +}); + +pub(crate) fn init(cs: CriticalSection) { + DRIVER.init(cs); +} + +#[cfg(time_driver_timg0)] +#[interrupt] +fn TIMG0() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg1)] +#[interrupt] +fn TIMG1() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg2)] +#[interrupt] +fn TIMG2() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg3)] +#[interrupt] +fn TIMG3() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg4)] +#[interrupt] +fn TIMG4() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg5)] +#[interrupt] +fn TIMG5() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg6)] +#[interrupt] +fn TIMG6() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg7)] +#[interrupt] +fn TIMG7() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg8)] +#[interrupt] +fn TIMG8() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg9)] +#[interrupt] +fn TIMG9() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg10)] +#[interrupt] +fn TIMG10() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_timg11)] +#[interrupt] +fn TIMG11() { + DRIVER.on_interrupt(); +} + +// TODO: TIMG12 and TIMG13 + +#[cfg(time_driver_timg14)] +#[interrupt] +fn TIMG14() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_tima0)] +#[interrupt] +fn TIMA0() { + DRIVER.on_interrupt(); +} + +#[cfg(time_driver_tima1)] +#[interrupt] +fn TIMA1() { + DRIVER.on_interrupt(); +} diff --git a/embassy-mspm0/src/timer.rs b/embassy-mspm0/src/timer.rs new file mode 100644 index 000000000..4441e5640 --- /dev/null +++ b/embassy-mspm0/src/timer.rs @@ -0,0 +1,48 @@ +#![macro_use] + +/// Amount of bits of a timer. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TimerBits { + /// 16 bits. + Bits16, + /// 32 bits. + Bits32, +} + +#[allow(private_bounds)] +pub trait Timer: SealedTimer + 'static { + /// Amount of bits this timer has. + const BITS: TimerBits; +} + +pub(crate) trait SealedTimer { + /// Registers for this timer. + /// + /// This is a raw pointer to the register block. The actual register block layout varies depending on the + /// timer type. + fn regs() -> *mut (); + + /// Enable the interrupt corresponding to this timer. + unsafe fn enable_interrupt(); +} + +macro_rules! impl_timer { + ($name: ident, $bits: ident) => { + impl crate::timer::SealedTimer for crate::peripherals::$name { + fn regs() -> *mut () { + crate::pac::$name.as_ptr() + } + + unsafe fn enable_interrupt() { + use embassy_hal_internal::interrupt::InterruptExt; + crate::interrupt::$name.unpend(); + crate::interrupt::$name.enable(); + } + } + + impl crate::timer::Timer for crate::peripherals::$name { + const BITS: crate::timer::TimerBits = crate::timer::TimerBits::$bits; + } + }; +} diff --git a/examples/mspm0c1104/.cargo/config.toml b/examples/mspm0c1104/.cargo/config.toml new file mode 100644 index 000000000..204a56b1c --- /dev/null +++ b/examples/mspm0c1104/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace MSPM0C1104 with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip MSPM0C1104 --protocol=swd" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "debug" +# defmt's buffer needs to be shrunk since the MSPM0C1104 only has 1KB of ram. +DEFMT_RTT_BUFFER_SIZE = "72" diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml new file mode 100644 index 000000000..35c9b1358 --- /dev/null +++ b/examples/mspm0c1104/Cargo.toml @@ -0,0 +1,32 @@ +[package] +edition = "2021" +name = "embassy-mspm0-c1104-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c110x", "rt", "time-driver-any"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-128", "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" +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"] } +panic-semihosting = "0.6.0" + +# The chip only has 1KB of ram, so we must optimize binaries regardless +[profile.dev] +debug = 2 +opt-level = "z" +lto = true +codegen-units = 1 +# strip = true + +[profile.release] +debug = 2 +opt-level = "z" +lto = true +codegen-units = 1 diff --git a/examples/mspm0c1104/README.md b/examples/mspm0c1104/README.md new file mode 100644 index 000000000..e5c9f961d --- /dev/null +++ b/examples/mspm0c1104/README.md @@ -0,0 +1,27 @@ +# Examples for MSPM0C110x family + +Run individual examples with +``` +cargo run --bin +``` +for example +``` +cargo run --bin blinky +``` + +## Checklist before running examples +A large number of the examples are written for the [LP-MSPM0C1104](https://www.ti.com/tool/LP-MSPM0C1104) board. + +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. +* [ ] 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 + +If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: + +* Which example you are trying to run +* Which chip and board you are using + +Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org diff --git a/examples/mspm0c1104/build.rs b/examples/mspm0c1104/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/mspm0c1104/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/mspm0c1104/memory.x b/examples/mspm0c1104/memory.x new file mode 100644 index 000000000..a9108835a --- /dev/null +++ b/examples/mspm0c1104/memory.x @@ -0,0 +1,5 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 16K + RAM : ORIGIN = 0x20000000, LENGTH = 1K +} diff --git a/examples/mspm0c1104/src/bin/blinky.rs b/examples/mspm0c1104/src/bin/blinky.rs new file mode 100644 index 000000000..264ea3eb5 --- /dev/null +++ b/examples/mspm0c1104/src/bin/blinky.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Level, Output}, + Config, +}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + let p = embassy_mspm0::init(Config::default()); + + let mut led1 = Output::new(p.PA22, Level::Low); + led1.set_inversion(true); + + loop { + Timer::after_millis(400).await; + + info!("Toggle"); + led1.toggle(); + } +} diff --git a/examples/mspm0c1104/src/bin/button.rs b/examples/mspm0c1104/src/bin/button.rs new file mode 100644 index 000000000..988170ef9 --- /dev/null +++ b/examples/mspm0c1104/src/bin/button.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Input, Level, Output, Pull}, + Config, +}; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + + let p = embassy_mspm0::init(Config::default()); + + let led1 = p.PA22; + let s2 = p.PA16; + + let mut led1 = Output::new(led1, Level::Low); + + let mut s2 = Input::new(s2, Pull::Up); + + // led1 is active low + led1.set_high(); + + loop { + s2.wait_for_falling_edge().await; + + info!("Switch 2 was pressed"); + + led1.toggle(); + } +} diff --git a/examples/mspm0g3507/.cargo/config.toml b/examples/mspm0g3507/.cargo/config.toml new file mode 100644 index 000000000..34c720cdd --- /dev/null +++ b/examples/mspm0g3507/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace MSPM0G3507 with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip MSPM0G3507 --protocol=swd" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "debug" diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml new file mode 100644 index 000000000..c1f304174 --- /dev/null +++ b/examples/mspm0g3507/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2021" +name = "embassy-mspm0-g3507-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g350x", "rt", "time-driver-any"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "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" +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"] } +panic-semihosting = "0.6.0" + +[profile.release] +debug = 2 diff --git a/examples/mspm0g3507/README.md b/examples/mspm0g3507/README.md new file mode 100644 index 000000000..5e8a83212 --- /dev/null +++ b/examples/mspm0g3507/README.md @@ -0,0 +1,27 @@ +# Examples for MSPM0C350x family + +Run individual examples with +``` +cargo run --bin +``` +for example +``` +cargo run --bin blinky +``` + +## Checklist before running examples +A large number of the examples are written for the [LP-MSPM0G3507](https://www.ti.com/tool/LP-MSPM0G3507) board. + +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. +* [ ] 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 + +If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: + +* Which example you are trying to run +* Which chip and board you are using + +Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org diff --git a/examples/mspm0g3507/build.rs b/examples/mspm0g3507/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/mspm0g3507/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/mspm0g3507/memory.x b/examples/mspm0g3507/memory.x new file mode 100644 index 000000000..37e381fbd --- /dev/null +++ b/examples/mspm0g3507/memory.x @@ -0,0 +1,6 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 128K + /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ + RAM : ORIGIN = 0x20200000, LENGTH = 32K +} diff --git a/examples/mspm0g3507/src/bin/blinky.rs b/examples/mspm0g3507/src/bin/blinky.rs new file mode 100644 index 000000000..11eee2d80 --- /dev/null +++ b/examples/mspm0g3507/src/bin/blinky.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Level, Output}, + Config, +}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + let p = embassy_mspm0::init(Config::default()); + + let mut led1 = Output::new(p.PA0, Level::Low); + led1.set_inversion(true); + + loop { + Timer::after_millis(400).await; + + info!("Toggle"); + led1.toggle(); + } +} diff --git a/examples/mspm0g3507/src/bin/button.rs b/examples/mspm0g3507/src/bin/button.rs new file mode 100644 index 000000000..1d9a37c5c --- /dev/null +++ b/examples/mspm0g3507/src/bin/button.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Input, Level, Output, Pull}, + Config, +}; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + + let p = embassy_mspm0::init(Config::default()); + + let led1 = p.PA0; + let s2 = p.PB21; + + let mut led1 = Output::new(led1, Level::Low); + + let mut s2 = Input::new(s2, Pull::Up); + + // led1 is active low + led1.set_high(); + + loop { + s2.wait_for_falling_edge().await; + + info!("Switch 2 was pressed"); + + led1.toggle(); + } +} diff --git a/examples/mspm0g3519/.cargo/config.toml b/examples/mspm0g3519/.cargo/config.toml new file mode 100644 index 000000000..1a4768682 --- /dev/null +++ b/examples/mspm0g3519/.cargo/config.toml @@ -0,0 +1,10 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace MSPM0G3519 with your chip as listed in `probe-rs chip list` +# TODO: Remove description path after new chiptool release +runner = "probe-rs run --restore-unwritten --verify --chip MSPM0G3519 --protocol=swd --chip-description-path ./MSPM0GX51X_Series.yaml" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml new file mode 100644 index 000000000..fc6f0e31b --- /dev/null +++ b/examples/mspm0g3519/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2021" +name = "embassy-mspm0-g3519-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g351x", "rt", "time-driver-any"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-16384", "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" +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"] } +panic-semihosting = "0.6.0" + +[profile.release] +debug = 2 diff --git a/examples/mspm0g3519/MSPM0GX51X_Series.yaml b/examples/mspm0g3519/MSPM0GX51X_Series.yaml new file mode 100644 index 000000000..375623b94 --- /dev/null +++ b/examples/mspm0g3519/MSPM0GX51X_Series.yaml @@ -0,0 +1,424 @@ +name: MSPM0GX51X Series +manufacturer: + id: 0x17 + cc: 0x0 +generated_from_pack: true +pack_file_release: 1.0.0 +variants: +- name: MSPM0G1518 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x40000 + cores: + - main + access: + write: false + boot: true + - !Generic + name: IROM2 + range: + start: 0x400000 + end: 0x440000 + cores: + - main + access: + write: false + - !Generic + name: IRAM1 + range: + start: 0x20000000 + end: 0x20010000 + cores: + - main + - !Generic + name: IRAM_Parity + range: + start: 0x20100000 + end: 0x20110000 + cores: + - main + - !Ram + name: IRAM_No_Parity + range: + start: 0x20200000 + end: 0x20220000 + cores: + - main + - !Generic + name: IRAM_Parity_Code + range: + start: 0x20300000 + end: 0x20310000 + cores: + - main + - !Generic + name: NonMain_ECC + range: + start: 0x41c00000 + end: 0x41c00800 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory_ECC + range: + start: 0x41c40000 + end: 0x41c40200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Data + range: + start: 0x41d00000 + end: 0x41d04000 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0gx51x_main_512kb + - mspm0gx51x_nonmain + - mspm0gx51x_data_16kb +- name: MSPM0G1519 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x80000 + cores: + - main + access: + write: false + boot: true + - !Generic + name: IROM2 + range: + start: 0x400000 + end: 0x480000 + cores: + - main + access: + write: false + - !Generic + name: IRAM1 + range: + start: 0x20000000 + end: 0x20010000 + cores: + - main + - !Generic + name: IRAM_Parity + range: + start: 0x20100000 + end: 0x20110000 + cores: + - main + - !Ram + name: IRAM_No_Parity + range: + start: 0x20200000 + end: 0x20220000 + cores: + - main + - !Generic + name: IRAM_Parity_Code + range: + start: 0x20300000 + end: 0x20310000 + cores: + - main + - !Generic + name: NonMain_ECC + range: + start: 0x41c00000 + end: 0x41c00800 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory_ECC + range: + start: 0x41c40000 + end: 0x41c40200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Data + range: + start: 0x41d00000 + end: 0x41d04000 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0gx51x_main_512kb + - mspm0gx51x_nonmain + - mspm0gx51x_data_16kb +- name: MSPM0G3518 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x40000 + cores: + - main + access: + write: false + boot: true + - !Generic + name: IROM2 + range: + start: 0x400000 + end: 0x440000 + cores: + - main + access: + write: false + - !Generic + name: IRAM1 + range: + start: 0x20000000 + end: 0x20010000 + cores: + - main + - !Generic + name: IRAM_Parity + range: + start: 0x20100000 + end: 0x20110000 + cores: + - main + - !Ram + name: IRAM_No_Parity + range: + start: 0x20200000 + end: 0x20220000 + cores: + - main + - !Generic + name: IRAM_Parity_Code + range: + start: 0x20300000 + end: 0x20310000 + cores: + - main + - !Generic + name: NonMain_ECC + range: + start: 0x41c00000 + end: 0x41c00800 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory_ECC + range: + start: 0x41c40000 + end: 0x41c40200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Data + range: + start: 0x41d00000 + end: 0x41d04000 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0gx51x_main_512kb + - mspm0gx51x_nonmain + - mspm0gx51x_data_16kb +- name: MSPM0G3519 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x80000 + cores: + - main + access: + write: false + boot: true + - !Generic + name: IROM2 + range: + start: 0x400000 + end: 0x480000 + cores: + - main + access: + write: false + - !Generic + name: IRAM1 + range: + start: 0x20000000 + end: 0x20010000 + cores: + - main + - !Generic + name: IRAM_Parity + range: + start: 0x20100000 + end: 0x20110000 + cores: + - main + - !Ram + name: IRAM_No_Parity + range: + start: 0x20200000 + end: 0x20220000 + cores: + - main + - !Generic + name: IRAM_Parity_Code + range: + start: 0x20300000 + end: 0x20310000 + cores: + - main + - !Generic + name: NonMain_ECC + range: + start: 0x41c00000 + end: 0x41c00800 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory_ECC + range: + start: 0x41c40000 + end: 0x41c40200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Data + range: + start: 0x41d00000 + end: 0x41d04000 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0gx51x_main_512kb + - mspm0gx51x_nonmain + - mspm0gx51x_data_16kb +flash_algorithms: +- name: mspm0gx51x_main_512kb + description: MSPM0GX51X MAIN 512KB + default: true + instructions: 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 + load_address: 0x20200008 + pc_init: 0x1d + pc_uninit: 0x99 + pc_program_page: 0x19d + pc_erase_sector: 0xcd + pc_erase_all: 0x9d + data_section_offset: 0x16e4 + flash_properties: + address_range: + start: 0x0 + end: 0x80000 + page_size: 0x400 + erased_byte_value: 0xff + program_page_timeout: 500 + erase_sector_timeout: 3000 + sectors: + - size: 0x400 + address: 0x0 +- name: mspm0gx51x_nonmain + description: MSPM0GX51X NON-MAIN + instructions: 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AAELQApJCmwAIAAqANBwRwhKEmhSB/rVCGjABQTUCGiABQPVAyBwRwIgcEcBIHBHAAELQBDtAOAHScprACABKgfRBkoSaFIHA9UIaIACAdUCIHBHASBwRwQBC0AQ7QDgELUISxxrASIiQAjRBkwgQBhgIUBZYNhqBEkBQ9liUEJQQRC9GCALQMD/PwAQAAB2ELUIS5xqASIiQAjRBkwgQBhgIUAZYFhqBEkBQ1liUEJQQRC9ICALQMD/PwBAAAB2ACIDCYtCLNMDCotCEdMAI5xGTuADRgtDPNQAIkMIi0Ix0wMJi0Ic0wMKi0IB05RGP+DDCYtCAdPLAcAaUkGDCYtCAdOLAcAaUkFDCYtCAdNLAcAaUkEDCYtCAdMLAcAaUkHDCItCAdPLAMAaUkGDCItCAdOLAMAaUkFDCItCAdNLAMAaUkFBGgDSAUZSQRBGcEdd4MoPANBJQgMQANNAQlNAnEYAIgMJi0It0wMKi0IS04kB/CISugMKi0IM04kBkhGLQgjTiQGSEYtCBNOJATrQkhEA4IkJwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJB2dJDCItCAdNLAMAaUkFBGgDSAUZSQRBGY0ZbEAHTQEIAKwDVSUJwR2NGWxAA00BCAbUFSQAoAtxJHAhAAOAIRsBGwEYCvQC/////fwAAAAS7qruqu6q7qv//////////u6q7qruqu6r//7uqu6q7qv///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9B/+hoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFgIVAgEDAgOoEv//r5YTdg9yY1+9tEpaCmPDnxKvMPlQpu5clxvhiOicQFH/////////////////////////////////////////////SADJWPEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + load_address: 0x20200008 + pc_init: 0x1d + pc_uninit: 0xb5 + pc_program_page: 0x1a9 + pc_erase_sector: 0x159 + pc_erase_all: 0x211 + data_section_offset: 0x1b84 + flash_properties: + address_range: + start: 0x41c00000 + end: 0x41c00400 + page_size: 0x40 + erased_byte_value: 0xff + program_page_timeout: 500 + erase_sector_timeout: 3000 + sectors: + - size: 0x400 + address: 0x0 +- name: mspm0gx51x_data_16kb + description: MSPM0GX51X DATA 16KB + instructions: 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 + load_address: 0x20200008 + pc_init: 0x1d + pc_uninit: 0x99 + pc_program_page: 0x19d + pc_erase_sector: 0xcd + pc_erase_all: 0x9d + data_section_offset: 0x16e4 + flash_properties: + address_range: + start: 0x0 + end: 0x4000 + page_size: 0x400 + erased_byte_value: 0xff + program_page_timeout: 500 + erase_sector_timeout: 3000 + sectors: + - size: 0x400 + address: 0x0 diff --git a/examples/mspm0g3519/README.md b/examples/mspm0g3519/README.md new file mode 100644 index 000000000..5034b1913 --- /dev/null +++ b/examples/mspm0g3519/README.md @@ -0,0 +1,27 @@ +# Examples for MSPM0G351x family + +Run individual examples with +``` +cargo run --bin +``` +for example +``` +cargo run --bin blinky +``` + +## Checklist before running examples +A large number of the examples are written for the [LP-MSPM0G3519](https://www.ti.com/tool/LP-MSPM0G3519) board. + +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. +* [ ] 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 + +If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: + +* Which example you are trying to run +* Which chip and board you are using + +Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org diff --git a/examples/mspm0g3519/build.rs b/examples/mspm0g3519/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/mspm0g3519/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/mspm0g3519/memory.x b/examples/mspm0g3519/memory.x new file mode 100644 index 000000000..e6e0ec9e9 --- /dev/null +++ b/examples/mspm0g3519/memory.x @@ -0,0 +1,6 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 512K + /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ + RAM : ORIGIN = 0x20200000, LENGTH = 128K +} diff --git a/examples/mspm0g3519/src/bin/blinky.rs b/examples/mspm0g3519/src/bin/blinky.rs new file mode 100644 index 000000000..11eee2d80 --- /dev/null +++ b/examples/mspm0g3519/src/bin/blinky.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Level, Output}, + Config, +}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + let p = embassy_mspm0::init(Config::default()); + + let mut led1 = Output::new(p.PA0, Level::Low); + led1.set_inversion(true); + + loop { + Timer::after_millis(400).await; + + info!("Toggle"); + led1.toggle(); + } +} diff --git a/examples/mspm0g3519/src/bin/button.rs b/examples/mspm0g3519/src/bin/button.rs new file mode 100644 index 000000000..2bdb2bcb1 --- /dev/null +++ b/examples/mspm0g3519/src/bin/button.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Input, Level, Output, Pull}, + Config, +}; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + + let p = embassy_mspm0::init(Config::default()); + + let led1 = p.PA0; + let s2 = p.PB3; + + let mut led1 = Output::new(led1, Level::Low); + + let mut s2 = Input::new(s2, Pull::Up); + + // led1 is active low + led1.set_high(); + + loop { + s2.wait_for_falling_edge().await; + + info!("Switch 2 was pressed"); + + led1.toggle(); + } +} diff --git a/examples/mspm0l1306/.cargo/config.toml b/examples/mspm0l1306/.cargo/config.toml new file mode 100644 index 000000000..93f148a71 --- /dev/null +++ b/examples/mspm0l1306/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace MSPM0L1306 with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip MSPM0L1306 --protocol=swd" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml new file mode 100644 index 000000000..6b87916b8 --- /dev/null +++ b/examples/mspm0l1306/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2021" +name = "embassy-mspm0-l1306-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l130x", "rt", "time-driver-any"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-1024", "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" +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"] } +panic-semihosting = "0.6.0" + +[profile.release] +debug = 2 diff --git a/examples/mspm0l1306/README.md b/examples/mspm0l1306/README.md new file mode 100644 index 000000000..5a55d721e --- /dev/null +++ b/examples/mspm0l1306/README.md @@ -0,0 +1,27 @@ +# Examples for MSPM0L130x family + +Run individual examples with +``` +cargo run --bin +``` +for example +``` +cargo run --bin blinky +``` + +## Checklist before running examples +A large number of the examples are written for the [LP-MSPM0L1306](https://www.ti.com/tool/LP-MSPM0L1306) board. + +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. +* [ ] 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 + +If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: + +* Which example you are trying to run +* Which chip and board you are using + +Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org diff --git a/examples/mspm0l1306/build.rs b/examples/mspm0l1306/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/mspm0l1306/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/mspm0l1306/memory.x b/examples/mspm0l1306/memory.x new file mode 100644 index 000000000..d93b61f44 --- /dev/null +++ b/examples/mspm0l1306/memory.x @@ -0,0 +1,5 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 64K + RAM : ORIGIN = 0x20000000, LENGTH = 4K +} diff --git a/examples/mspm0l1306/src/bin/blinky.rs b/examples/mspm0l1306/src/bin/blinky.rs new file mode 100644 index 000000000..11eee2d80 --- /dev/null +++ b/examples/mspm0l1306/src/bin/blinky.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Level, Output}, + Config, +}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + let p = embassy_mspm0::init(Config::default()); + + let mut led1 = Output::new(p.PA0, Level::Low); + led1.set_inversion(true); + + loop { + Timer::after_millis(400).await; + + info!("Toggle"); + led1.toggle(); + } +} diff --git a/examples/mspm0l1306/src/bin/button.rs b/examples/mspm0l1306/src/bin/button.rs new file mode 100644 index 000000000..2813518c2 --- /dev/null +++ b/examples/mspm0l1306/src/bin/button.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Input, Level, Output, Pull}, + Config, +}; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + + let p = embassy_mspm0::init(Config::default()); + + let led1 = p.PA0; + let s2 = p.PA14; + + let mut led1 = Output::new(led1, Level::Low); + + let mut s2 = Input::new(s2, Pull::Up); + + // led1 is active low + led1.set_high(); + + loop { + s2.wait_for_falling_edge().await; + + info!("Switch 2 was pressed"); + + led1.toggle(); + } +} diff --git a/examples/mspm0l2228/.cargo/config.toml b/examples/mspm0l2228/.cargo/config.toml new file mode 100644 index 000000000..4284749e9 --- /dev/null +++ b/examples/mspm0l2228/.cargo/config.toml @@ -0,0 +1,10 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace MSPM0L2228 with your chip as listed in `probe-rs chip list` +# TODO: Remove description path after new chiptool release +runner = "probe-rs run --restore-unwritten --verify --chip MSPM0L2228 --protocol=swd --chip-description-path ./MSPM0L122X_L222X_Series.yaml" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml new file mode 100644 index 000000000..9474c2ced --- /dev/null +++ b/examples/mspm0l2228/Cargo.toml @@ -0,0 +1,21 @@ +[package] +edition = "2021" +name = "embassy-mspm0-l2228-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l222x", "rt", "time-driver-any"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-1024", "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" +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"] } +panic-semihosting = "0.6.0" + +[profile.release] +debug = 2 diff --git a/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml b/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml new file mode 100644 index 000000000..ac52fda2e --- /dev/null +++ b/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml @@ -0,0 +1,239 @@ +name: MSPM0L122X_L222X Series +manufacturer: + id: 0x17 + cc: 0x0 +generated_from_pack: true +pack_file_release: 1.1.1 +variants: +- name: MSPM0L1227 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x20000 + cores: + - main + access: + write: false + boot: true + - !Ram + name: IRAM1 + range: + start: 0x20200000 + end: 0x20208000 + cores: + - main + - !Generic + name: NonMain + range: + start: 0x41c00000 + end: 0x41c00200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory + range: + start: 0x41c40000 + end: 0x41c40080 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0l122x_l222x_main_256kb + - mspm0l122x_l222x_nonmain +- name: MSPM0L1228 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x40000 + cores: + - main + access: + write: false + boot: true + - !Ram + name: IRAM1 + range: + start: 0x20200000 + end: 0x20208000 + cores: + - main + - !Generic + name: NonMain + range: + start: 0x41c00000 + end: 0x41c00200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory + range: + start: 0x41c40000 + end: 0x41c40080 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0l122x_l222x_main_256kb + - mspm0l122x_l222x_nonmain +- name: MSPM0L2227 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x20000 + cores: + - main + access: + write: false + boot: true + - !Ram + name: IRAM1 + range: + start: 0x20200000 + end: 0x20208000 + cores: + - main + - !Generic + name: NonMain + range: + start: 0x41c00000 + end: 0x41c00200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory + range: + start: 0x41c40000 + end: 0x41c40080 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0l122x_l222x_main_256kb + - mspm0l122x_l222x_nonmain +- name: MSPM0L2228 + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + memory_map: + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x40000 + cores: + - main + access: + write: false + boot: true + - !Ram + name: IRAM1 + range: + start: 0x20200000 + end: 0x20208000 + cores: + - main + - !Generic + name: NonMain + range: + start: 0x41c00000 + end: 0x41c00200 + cores: + - main + access: + write: false + execute: false + - !Generic + name: Factory + range: + start: 0x41c40000 + end: 0x41c40080 + cores: + - main + access: + write: false + execute: false + flash_algorithms: + - mspm0l122x_l222x_main_256kb + - mspm0l122x_l222x_nonmain +flash_algorithms: +- name: mspm0l122x_l222x_main_256kb + description: MSPM0L122X_222X MAIN 256KB + default: true + instructions: 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 + load_address: 0x20200008 + pc_init: 0x1d + pc_uninit: 0x5d + pc_program_page: 0x145 + pc_erase_sector: 0x61 + pc_erase_all: 0x131 + data_section_offset: 0x12dc + flash_properties: + address_range: + start: 0x0 + end: 0x40000 + page_size: 0x400 + erased_byte_value: 0xff + program_page_timeout: 500 + erase_sector_timeout: 3000 + sectors: + - size: 0x400 + address: 0x0 +- name: mspm0l122x_l222x_nonmain + description: MSPM0L122X_222X NON-MAIN + instructions: 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A0gBaIkD/NRwR8BGAAELQAQCC0ABIAAEBEkKaIJDCmADSAFoyQb81HBHwEYEAQtABAILQAAiAwmLQizTAwqLQhHTACOcRk7gA0YLQzzUACJDCItCMdMDCYtCHNMDCotCAdOURj/gwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJBQwiLQgHTSwDAGlJBQRoA0gFGUkEQRnBHXeDKDwDQSUIDEADTQEJTQJxGACIDCYtCLdMDCotCEtOJAfwiEroDCotCDNOJAZIRi0II04kBkhGLQgTTiQE60JIRAOCJCcMJi0IB08sBwBpSQYMJi0IB04sBwBpSQUMJi0IB00sBwBpSQQMJi0IB0wsBwBpSQcMIi0IB08sAwBpSQYMIi0IB04sAwBpSQdnSQwiLQgHTSwDAGlJBQRoA0gFGUkEQRmNGWxAB00BCACsA1UlCcEdjRlsQANNAQgG1BUkAKALcSRwIQADgCEbARsBGAr0Av////38CAAABu6q7qruqu6r//////////7uqu6q7qruq//+7qruqu6r///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+yIGk/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABoCGQIBAwIDshL//6+WE3YPcmNfvbRKWgpjw58SrzD5UKbuXJcb4YjonEBR/////////////////////////////////////////////0gA0UsBbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + load_address: 0x20200008 + pc_init: 0x1d + pc_uninit: 0x7d + pc_program_page: 0x18d + pc_erase_sector: 0x121 + pc_erase_all: 0x79 + data_section_offset: 0x1774 + flash_properties: + address_range: + start: 0x41c00000 + end: 0x41c00200 + page_size: 0x40 + erased_byte_value: 0xff + program_page_timeout: 500 + erase_sector_timeout: 3000 + sectors: + - size: 0x200 + address: 0x0 diff --git a/examples/mspm0l2228/README.md b/examples/mspm0l2228/README.md new file mode 100644 index 000000000..c73fa13b6 --- /dev/null +++ b/examples/mspm0l2228/README.md @@ -0,0 +1,27 @@ +# Examples for MSPM0L222x family + +Run individual examples with +``` +cargo run --bin +``` +for example +``` +cargo run --bin blinky +``` + +## Checklist before running examples +A large number of the examples are written for the [LP-MSPM0L2228](https://www.ti.com/tool/LP-MSPM0L2228) board. + +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. +* [ ] 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 + +If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: + +* Which example you are trying to run +* Which chip and board you are using + +Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org diff --git a/examples/mspm0l2228/build.rs b/examples/mspm0l2228/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/mspm0l2228/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/mspm0l2228/memory.x b/examples/mspm0l2228/memory.x new file mode 100644 index 000000000..aba414a88 --- /dev/null +++ b/examples/mspm0l2228/memory.x @@ -0,0 +1,6 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 256K + /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ + RAM : ORIGIN = 0x20200000, LENGTH = 32K +} diff --git a/examples/mspm0l2228/src/bin/blinky.rs b/examples/mspm0l2228/src/bin/blinky.rs new file mode 100644 index 000000000..11eee2d80 --- /dev/null +++ b/examples/mspm0l2228/src/bin/blinky.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Level, Output}, + Config, +}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + let p = embassy_mspm0::init(Config::default()); + + let mut led1 = Output::new(p.PA0, Level::Low); + led1.set_inversion(true); + + loop { + Timer::after_millis(400).await; + + info!("Toggle"); + led1.toggle(); + } +} diff --git a/examples/mspm0l2228/src/bin/button.rs b/examples/mspm0l2228/src/bin/button.rs new file mode 100644 index 000000000..f26929dde --- /dev/null +++ b/examples/mspm0l2228/src/bin/button.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_mspm0::{ + gpio::{Input, Level, Output, Pull}, + Config, +}; +use {defmt_rtt as _, panic_halt as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + info!("Hello world!"); + + let p = embassy_mspm0::init(Config::default()); + + let led1 = p.PA0; + let s2 = p.PB8; + + let mut led1 = Output::new(led1, Level::Low); + + let mut s2 = Input::new(s2, Pull::Up); + + // led1 is active low + led1.set_high(); + + loop { + s2.wait_for_falling_edge().await; + + info!("Switch 2 was pressed"); + + led1.toggle(); + } +} From 9531b7422b0bf231d5782bb60b65eeb823b199ff Mon Sep 17 00:00:00 2001 From: i509VCB Date: Thu, 13 Mar 2025 22:26:06 -0500 Subject: [PATCH 03/44] rustfmt... --- embassy-mspm0/build.rs | 9 ++------- embassy-mspm0/src/gpio.rs | 22 ++++++---------------- embassy-mspm0/src/lib.rs | 9 ++------- embassy-mspm0/src/time_driver.rs | 30 ++++++++---------------------- 4 files changed, 18 insertions(+), 52 deletions(-) diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index ffbe15c56..8c6dd4a5c 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -107,11 +107,7 @@ fn generate_code() { } // Generate timers - for peripheral in METADATA - .peripherals - .iter() - .filter(|p| p.name.starts_with("TIM")) - { + for peripheral in METADATA.peripherals.iter().filter(|p| p.name.starts_with("TIM")) { let name = Ident::new(&peripheral.name, Span::call_site()); let timers = &*TIMERS; @@ -225,8 +221,7 @@ fn time_driver(singletons: &[String], cfgs: &mut CfgSet) { // TODO: 32-bit timers are not considered yet [ // 16-bit, 2 channel - "TIMG0", "TIMG1", "TIMG2", "TIMG3", - // 16-bit, 2 channel with shadow registers + "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel "TIMG14", // 16-bit with QEI "TIMG8", "TIMG9", "TIMG10", "TIMG11", // Advanced timers diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index fd4dc55ab..e1eb7eecf 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs @@ -7,13 +7,12 @@ use core::task::{Context, Poll}; use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; + +use crate::pac::gpio::vals::*; +use crate::pac::gpio::{self}; #[cfg(all(feature = "rt", feature = "mspm0c110x"))] use crate::pac::interrupt; - -use crate::pac::{ - self, - gpio::{self, vals::*}, -}; +use crate::pac::{self}; /// Represents a digital input or output level. #[derive(Debug, Eq, PartialEq, Clone, Copy)] @@ -88,9 +87,7 @@ impl<'d> Flex<'d> { into_ref!(pin); // Pin will be in disconnected state. - Self { - pin: pin.map_into(), - } + Self { pin: pin.map_into() } } /// Set the pin's pull. @@ -974,14 +971,7 @@ impl<'d> Future for InputFuture<'d> { waker.register(cx.waker()); // The interrupt handler will mask the interrupt if the event has occurred. - if self - .pin - .block() - .cpu_int() - .ris() - .read() - .dio(self.pin.bit_index()) - { + if self.pin.block().cpu_int().ris().read().dio(self.pin.bit_index()) { return Poll::Ready(()); } diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index ee629f063..1191b1010 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -1,10 +1,6 @@ #![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, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))] // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; @@ -40,6 +36,7 @@ pub(crate) mod _generated { } // Reexports +pub(crate) use _generated::gpio_pincm; pub use _generated::{peripherals, Peripherals}; pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; #[cfg(feature = "unstable-pac")] @@ -48,8 +45,6 @@ pub use mspm0_metapac as pac; pub(crate) use mspm0_metapac as pac; pub use crate::_generated::interrupt; -pub(crate) use _generated::gpio_pincm; - /// `embassy-mspm0` global configuration. #[non_exhaustive] diff --git a/embassy-mspm0/src/time_driver.rs b/embassy-mspm0/src/time_driver.rs index 3af7a5edb..937ce58d4 100644 --- a/embassy-mspm0/src/time_driver.rs +++ b/embassy-mspm0/src/time_driver.rs @@ -1,19 +1,13 @@ -use core::{ - cell::{Cell, RefCell}, - sync::atomic::{compiler_fence, AtomicU32, Ordering}, - task::Waker, -}; +use core::cell::{Cell, RefCell}; +use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; +use core::task::Waker; use critical_section::{CriticalSection, Mutex}; use embassy_time_driver::Driver; use embassy_time_queue_utils::Queue; -use mspm0_metapac::{ - interrupt, - tim::{ - vals::{Cm, Cvae, CxC, EvtCfg, PwrenKey, Ratio, Repeat, ResetKey}, - Counterregs16, Tim, - }, -}; +use mspm0_metapac::interrupt; +use mspm0_metapac::tim::vals::{Cm, Cvae, CxC, EvtCfg, PwrenKey, Ratio, Repeat, ResetKey}; +use mspm0_metapac::tim::{Counterregs16, Tim}; use crate::peripherals; use crate::timer::SealedTimer; @@ -244,18 +238,10 @@ impl TimxDriver { } fn trigger_alarm(&self, cs: CriticalSection) { - let mut next = self - .queue - .borrow(cs) - .borrow_mut() - .next_expiration(self.now()); + let mut next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); while !self.set_alarm(cs, next) { - next = self - .queue - .borrow(cs) - .borrow_mut() - .next_expiration(self.now()); + next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); } } From 0c8dadf0ca2dfa7fac3767d0c33276bd694c5824 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Thu, 13 Mar 2025 22:30:45 -0500 Subject: [PATCH 04/44] rustfmt 2: electric boogaloo --- examples/mspm0c1104/src/bin/blinky.rs | 6 ++---- examples/mspm0c1104/src/bin/button.rs | 6 ++---- examples/mspm0g3507/src/bin/blinky.rs | 6 ++---- examples/mspm0g3507/src/bin/button.rs | 6 ++---- examples/mspm0g3519/src/bin/blinky.rs | 6 ++---- examples/mspm0g3519/src/bin/button.rs | 6 ++---- examples/mspm0l1306/src/bin/blinky.rs | 6 ++---- examples/mspm0l1306/src/bin/button.rs | 6 ++---- examples/mspm0l2228/src/bin/blinky.rs | 6 ++---- examples/mspm0l2228/src/bin/button.rs | 6 ++---- 10 files changed, 20 insertions(+), 40 deletions(-) diff --git a/examples/mspm0c1104/src/bin/blinky.rs b/examples/mspm0c1104/src/bin/blinky.rs index 264ea3eb5..0d974cc5e 100644 --- a/examples/mspm0c1104/src/bin/blinky.rs +++ b/examples/mspm0c1104/src/bin/blinky.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Level, Output}, - Config, -}; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_halt as _}; diff --git a/examples/mspm0c1104/src/bin/button.rs b/examples/mspm0c1104/src/bin/button.rs index 988170ef9..7face1618 100644 --- a/examples/mspm0c1104/src/bin/button.rs +++ b/examples/mspm0c1104/src/bin/button.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Input, Level, Output, Pull}, - Config, -}; +use embassy_mspm0::gpio::{Input, Level, Output, Pull}; +use embassy_mspm0::Config; use {defmt_rtt as _, panic_halt as _}; #[embassy_executor::main] diff --git a/examples/mspm0g3507/src/bin/blinky.rs b/examples/mspm0g3507/src/bin/blinky.rs index 11eee2d80..055a5cd81 100644 --- a/examples/mspm0g3507/src/bin/blinky.rs +++ b/examples/mspm0g3507/src/bin/blinky.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Level, Output}, - Config, -}; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_halt as _}; diff --git a/examples/mspm0g3507/src/bin/button.rs b/examples/mspm0g3507/src/bin/button.rs index 1d9a37c5c..cde1f2892 100644 --- a/examples/mspm0g3507/src/bin/button.rs +++ b/examples/mspm0g3507/src/bin/button.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Input, Level, Output, Pull}, - Config, -}; +use embassy_mspm0::gpio::{Input, Level, Output, Pull}; +use embassy_mspm0::Config; use {defmt_rtt as _, panic_halt as _}; #[embassy_executor::main] diff --git a/examples/mspm0g3519/src/bin/blinky.rs b/examples/mspm0g3519/src/bin/blinky.rs index 11eee2d80..055a5cd81 100644 --- a/examples/mspm0g3519/src/bin/blinky.rs +++ b/examples/mspm0g3519/src/bin/blinky.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Level, Output}, - Config, -}; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_halt as _}; diff --git a/examples/mspm0g3519/src/bin/button.rs b/examples/mspm0g3519/src/bin/button.rs index 2bdb2bcb1..c81cc2918 100644 --- a/examples/mspm0g3519/src/bin/button.rs +++ b/examples/mspm0g3519/src/bin/button.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Input, Level, Output, Pull}, - Config, -}; +use embassy_mspm0::gpio::{Input, Level, Output, Pull}; +use embassy_mspm0::Config; use {defmt_rtt as _, panic_halt as _}; #[embassy_executor::main] diff --git a/examples/mspm0l1306/src/bin/blinky.rs b/examples/mspm0l1306/src/bin/blinky.rs index 11eee2d80..055a5cd81 100644 --- a/examples/mspm0l1306/src/bin/blinky.rs +++ b/examples/mspm0l1306/src/bin/blinky.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Level, Output}, - Config, -}; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_halt as _}; diff --git a/examples/mspm0l1306/src/bin/button.rs b/examples/mspm0l1306/src/bin/button.rs index 2813518c2..d8c85947f 100644 --- a/examples/mspm0l1306/src/bin/button.rs +++ b/examples/mspm0l1306/src/bin/button.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Input, Level, Output, Pull}, - Config, -}; +use embassy_mspm0::gpio::{Input, Level, Output, Pull}; +use embassy_mspm0::Config; use {defmt_rtt as _, panic_halt as _}; #[embassy_executor::main] diff --git a/examples/mspm0l2228/src/bin/blinky.rs b/examples/mspm0l2228/src/bin/blinky.rs index 11eee2d80..055a5cd81 100644 --- a/examples/mspm0l2228/src/bin/blinky.rs +++ b/examples/mspm0l2228/src/bin/blinky.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Level, Output}, - Config, -}; +use embassy_mspm0::gpio::{Level, Output}; +use embassy_mspm0::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_halt as _}; diff --git a/examples/mspm0l2228/src/bin/button.rs b/examples/mspm0l2228/src/bin/button.rs index f26929dde..47bfd274b 100644 --- a/examples/mspm0l2228/src/bin/button.rs +++ b/examples/mspm0l2228/src/bin/button.rs @@ -3,10 +3,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_mspm0::{ - gpio::{Input, Level, Output, Pull}, - Config, -}; +use embassy_mspm0::gpio::{Input, Level, Output, Pull}; +use embassy_mspm0::Config; use {defmt_rtt as _, panic_halt as _}; #[embassy_executor::main] From 0f57a18f199f67c805e199361636823d1178d586 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:35:24 -0500 Subject: [PATCH 05/44] Remove temporary target yamls These will be in the next probe-rs release --- examples/mspm0g3519/.cargo/config.toml | 3 +- examples/mspm0g3519/MSPM0GX51X_Series.yaml | 424 ------------------ examples/mspm0l2228/.cargo/config.toml | 3 +- .../mspm0l2228/MSPM0L122X_L222X_Series.yaml | 239 ---------- 4 files changed, 2 insertions(+), 667 deletions(-) delete mode 100644 examples/mspm0g3519/MSPM0GX51X_Series.yaml delete mode 100644 examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml diff --git a/examples/mspm0g3519/.cargo/config.toml b/examples/mspm0g3519/.cargo/config.toml index 1a4768682..7bba4646f 100644 --- a/examples/mspm0g3519/.cargo/config.toml +++ b/examples/mspm0g3519/.cargo/config.toml @@ -1,7 +1,6 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # replace MSPM0G3519 with your chip as listed in `probe-rs chip list` -# TODO: Remove description path after new chiptool release -runner = "probe-rs run --restore-unwritten --verify --chip MSPM0G3519 --protocol=swd --chip-description-path ./MSPM0GX51X_Series.yaml" +runner = "probe-rs run --restore-unwritten --verify --chip MSPM0G3519 --protocol=swd" [build] target = "thumbv6m-none-eabi" diff --git a/examples/mspm0g3519/MSPM0GX51X_Series.yaml b/examples/mspm0g3519/MSPM0GX51X_Series.yaml deleted file mode 100644 index 375623b94..000000000 --- a/examples/mspm0g3519/MSPM0GX51X_Series.yaml +++ /dev/null @@ -1,424 +0,0 @@ -name: MSPM0GX51X Series -manufacturer: - id: 0x17 - cc: 0x0 -generated_from_pack: true -pack_file_release: 1.0.0 -variants: -- name: MSPM0G1518 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x40000 - cores: - - main - access: - write: false - boot: true - - !Generic - name: IROM2 - range: - start: 0x400000 - end: 0x440000 - cores: - - main - access: - write: false - - !Generic - name: IRAM1 - range: - start: 0x20000000 - end: 0x20010000 - cores: - - main - - !Generic - name: IRAM_Parity - range: - start: 0x20100000 - end: 0x20110000 - cores: - - main - - !Ram - name: IRAM_No_Parity - range: - start: 0x20200000 - end: 0x20220000 - cores: - - main - - !Generic - name: IRAM_Parity_Code - range: - start: 0x20300000 - end: 0x20310000 - cores: - - main - - !Generic - name: NonMain_ECC - range: - start: 0x41c00000 - end: 0x41c00800 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory_ECC - range: - start: 0x41c40000 - end: 0x41c40200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Data - range: - start: 0x41d00000 - end: 0x41d04000 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0gx51x_main_512kb - - mspm0gx51x_nonmain - - mspm0gx51x_data_16kb -- name: MSPM0G1519 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x80000 - cores: - - main - access: - write: false - boot: true - - !Generic - name: IROM2 - range: - start: 0x400000 - end: 0x480000 - cores: - - main - access: - write: false - - !Generic - name: IRAM1 - range: - start: 0x20000000 - end: 0x20010000 - cores: - - main - - !Generic - name: IRAM_Parity - range: - start: 0x20100000 - end: 0x20110000 - cores: - - main - - !Ram - name: IRAM_No_Parity - range: - start: 0x20200000 - end: 0x20220000 - cores: - - main - - !Generic - name: IRAM_Parity_Code - range: - start: 0x20300000 - end: 0x20310000 - cores: - - main - - !Generic - name: NonMain_ECC - range: - start: 0x41c00000 - end: 0x41c00800 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory_ECC - range: - start: 0x41c40000 - end: 0x41c40200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Data - range: - start: 0x41d00000 - end: 0x41d04000 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0gx51x_main_512kb - - mspm0gx51x_nonmain - - mspm0gx51x_data_16kb -- name: MSPM0G3518 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x40000 - cores: - - main - access: - write: false - boot: true - - !Generic - name: IROM2 - range: - start: 0x400000 - end: 0x440000 - cores: - - main - access: - write: false - - !Generic - name: IRAM1 - range: - start: 0x20000000 - end: 0x20010000 - cores: - - main - - !Generic - name: IRAM_Parity - range: - start: 0x20100000 - end: 0x20110000 - cores: - - main - - !Ram - name: IRAM_No_Parity - range: - start: 0x20200000 - end: 0x20220000 - cores: - - main - - !Generic - name: IRAM_Parity_Code - range: - start: 0x20300000 - end: 0x20310000 - cores: - - main - - !Generic - name: NonMain_ECC - range: - start: 0x41c00000 - end: 0x41c00800 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory_ECC - range: - start: 0x41c40000 - end: 0x41c40200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Data - range: - start: 0x41d00000 - end: 0x41d04000 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0gx51x_main_512kb - - mspm0gx51x_nonmain - - mspm0gx51x_data_16kb -- name: MSPM0G3519 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x80000 - cores: - - main - access: - write: false - boot: true - - !Generic - name: IROM2 - range: - start: 0x400000 - end: 0x480000 - cores: - - main - access: - write: false - - !Generic - name: IRAM1 - range: - start: 0x20000000 - end: 0x20010000 - cores: - - main - - !Generic - name: IRAM_Parity - range: - start: 0x20100000 - end: 0x20110000 - cores: - - main - - !Ram - name: IRAM_No_Parity - range: - start: 0x20200000 - end: 0x20220000 - cores: - - main - - !Generic - name: IRAM_Parity_Code - range: - start: 0x20300000 - end: 0x20310000 - cores: - - main - - !Generic - name: NonMain_ECC - range: - start: 0x41c00000 - end: 0x41c00800 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory_ECC - range: - start: 0x41c40000 - end: 0x41c40200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Data - range: - start: 0x41d00000 - end: 0x41d04000 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0gx51x_main_512kb - - mspm0gx51x_nonmain - - mspm0gx51x_data_16kb -flash_algorithms: -- name: mspm0gx51x_main_512kb - description: MSPM0GX51X MAIN 512KB - default: true - instructions: ESEJAgEiQlADSUEYCmgHIBBABCj60HBH0BMAABC1FEgBaAcikUMBYBJMYWggaAMikEMgYBEgAAQIQAEhCgWQQgXQCQSIQgTRAfC2+QHgAfCL+WBoDyGIQ2BgAfCF+QZIAWgEIpFDAWAA8Aj4ACAQvQATQEAAAQtAEO0A4ARIBSFBYAEhAWADSAFoSQf81HBHAOEMQNDjDEAAIHBHcLUEIMZDACQITeAHB9EALgXQKEYA8Oj5BEZ2HPXnASBEQARA//fc/yBGcL0A0AxA+LUERm1GKUYA8Cj4AUYBICp4ACoB0IUCAOBFAgApGtAEIMdDACAMTsEHEdEALw/Q//e+/zBGIUYqRgDwp/xAIjBGIUYA8ND4fxwA8Cn46+cBIUhACED4vQDQDEAQtQxKE2gFJBRgByQcQApLG2gUYIIKCUgQQAlKGkCQQgHSACMLcJBCAdMAIBC9ASAQvcBGABNAQBgAxEH/7z8A/w8AAIGwCkgBaAciCkAAkgCZybIDKQPQAJnJsgEp89EAmMCywR5IQkhBAbBwR8BG0OMMQP61FEYNRgZGAqn/97//ASEAKCjQAC0m0AcgKEAj0QKoAXgBIAApAdCBAgDgQQIBkQ9PACEALRbQwAcU0P/3UP8KSDFGAZoA8Dn8OGhAB/zUBkgxRiJGAPAf+wg2CDQIPf/3tv/l5whG/r3ARgDQDEDQ4wxAELUFTAFRABkAKwPQAspBYFse+eeAaBC9BBEAABC1BUwBUQAZmkIC2ALKQWD654BoEL3ARgQRAAC8tQpMBBkAlACcIYAISUEYACsG0BSIAZEBnSyAkhxbHvbnBElAWICyvL3ARgQRAAAIEQAADBEAALy1CUwEGQCUAJwhgAdJQRiaQgXYFIgBkQGdLICSHPfnA0lAWICyvL0EEQAACBEAAAwRAAAQtQIjE0MRIhIChBhjYCFiASGBUBC9wEaAtQIjE0MDSoNQghjRYf/3kf6AvQQRAAAQtQRGEUgAISFQIBhBYIFgykMCZBEgAAIiGFIjU2ARYgEhIVAgRgDwKfgJSQpoBSMLYAcjE0AHShJoC2CRDgTQACgC0CBGAPAx+BC90BEAAAATQEAYAMRBA0kAIkJQQBhCYIJgcEfARtARAAAAIclDAUqBUHBHwEYQEgAAgbAKSUAYAWgHIgpAAJIAmcmyAykD0ACZybIBKfPRAJjAssEeSEJIQQGwcEfQEwAA/rUYSxloBSIaYAciCkAWSQloGmARIhICApCAGAGQjw4STQEgAp7/sv83+bK5QhXQwQcT0DBGAPD5+AEkYgIwRilGAPBB+0IgAZlIYA1iDGCgAi0YMEb/97v/5OcBIQhA/r3ARgATQEAYAMRBAADQQRC1BEYQSAAhIVAgGEFggWDKQwJkDUhSIiJQIBjBYSBG//fu/QpJCmgFIwtgByMTQAhKEmgLYJEOBNABKALQIEYA8Ar4EL3ARtARAAAEEQAAABNAQBgAxEGAtQdJACJCUEEYSmCKYAVJUiJCUEEYBErKYf/3xf2AvdARAAAEEQAAAADQQfC1h7AERgDwhfgFRjpIAWgFIgJgByIKQDhJCWgCYDhIIBgCkBEgAAIElCYYNUgIQClGAfBf+CpGgAIBkGgIBpAQIAWQACcBJD1GIEYDkgCUlUJJ0sEHR9AGmIVCAdIAIQDgASEoSABoQAUgRgDVCEYpBokOBdH5FTtGJKd5Wh9GBZEAKCBGKtAEnCBGAPBU+AEgAQSyaApDsmAfIQkBBZoKQLNoi0OZGLFgDyFJArJoikNBAlEYsWAAIQKaEWBRYJFgyUMRZFIhcWApRgGaUUMxYjBgIEYAnP/3AP8DmgEhCQZ/GG0cs+cBIQoEs2iTQ7NgCEAHsPC9ABNAQBgAxEHQEQAA/w8AAEggC0AQACAAQACAAAZIAWgFIgJgByIKQARJCWgCYIgEgA9AHHBHwEYAE0BAGADEQREhCQJCGAUjU2ABIkJQAkgBaEkH/NRwR9DjDEAQtQRG//eC/gAoENAJSCAYESEJAmEYACICYEIgSGAGSAhiASAIYCBG//eu/hC9ACAQvcBGEBIAAAAAwEEBSQAiQlBwRxASAAAQtQRG//fs/gMoDNEGSCAYBklhGAAiCmBCIQFgBEnBYSBG//fd/BC9BBEAABASAAAAAMBBELUERv/3FP8AKBDQCUggGBEhCQJhGAAiAmBCIEhgBkgIYgEgCGAgRv/3cP4QvQAgEL3ARhASAAAAAMBBsLURIxsCxBgBJWVgZWIhYhF4IWPFULC9ELUFSwEkxFDDGBxi2WEReNli//eh/BC9BBEAAHC1ESMbAsQYASVlYAMmZmIhYhGIIWPFUHC9wEYQtQZLASTEUMMYAyQcYtlhEYjZYv/3hPwQvcBGBBEAAHC1ESMbAsQYASVlYA8mZmIhYhFoIWPFUHC9wEYQtQZLASTEUMMYDyQcYtlhEWjZYv/3ZvwQvcBGBBEAAHC1ESMbAsQYASVlYP8mZmIhYhFoIWNRaGFjxVBwvcBGELUHSwEkxFDDGP8kHGLZYRFo2WJRaBlj//dE/BC9wEYEEQAAcLURIxsCxBgBJWVg/yYCNmZiIWIReCFjxVBwvRC1BksBJMRQwxj/JAI0HGLZYRF42WL/9yX8EL0EEQAAcLURIxsCxBgBJWVg/yYENmZiIWIRiCFjxVBwvRC1BksBJMRQwxj/JAQ0HGLZYRGI2WL/9wf8EL0EEQAAcLURIxsCxBgBJWVg/yYQNmZiIWIRaCFjxVBwvRC1BksBJMRQwxj/JBA0HGLZYRFo2WL/9+n7EL0EEQAAcLURIxsCxBgBJWVgBE5mYiFiEWghY1FoYWPFUHC9wEb/AQAAELUHSwEkxFDDGAZMHGLZYRFo2WJRaBlj//fG+xC9wEYEEQAA/wEAAPC1ESQkAgUZASZuYP8nAjdvYiliEXgpYxl4AkqBUAZR8L3ARrARAACwtQhMASUFUQQZ/yUCNSVi4WEReOFiGXgDSoFQ//ec+7C9wEYEEQAAsBEAAPC1ESQkAgUZASZuYP8nBDdvYiliEYgpYxl4AkqBUAZR8L3ARrARAACwtQhMASUFUQQZ/yUENSVi4WERiOFiGXgDSoFQ//dy+7C9wEYEEQAAsBEAAPC1ESQkAgUZASZuYP8nEDdvYiliEWgpYxl4AkqBUAZR8L3ARrARAACwtQhMASUFUQQZ/yUQNSVi4WERaOFiGXgDSoFQ//dI+7C9wEYEEQAAsBEAAPC1ESQkAgUZASZuYAVPb2IpYhFoKWNRaGljGXgCSoFQBlHwvf8BAACwEQAAsLUITAElBVEEGQdNJWLhYRFo4WJRaCFjGXgESoFQ//cb+7C9BBEAAP8BAACwEQAA8LWHsB9GBpIFkQRGASEYRgSRCEBBQkFBWh4YRpBBCEARIQkCA5RhGAKRDJkBkQOdAC8f0MEHHdAoRv/30/0oRgWcIUYBmgDwG/gEmQKaUWAKSFBiFGIGnjBoEGNwaFBjEWAINAWUvx4oRv/3jfwINgaW3ecEmQhAB7Dwvf8BAABwtRVGDEYLSUYYIEYA8D75ASGKApVCBNBKApVCCNHACALgPDZgBMAOgUAwaIhDMGBwvcBG1BEAAPi1HEYVRg5GB0YBIdgHAdAIRgDgBCAALADRCEYGmQCRACwQ0MGyASkN0DhGMUYAmv/3yv84RjFGKkb/98X+CDYINaQe7OfAsvi9wEbwtYewBpMEkgORA0YBIQyfOEYCkQhAQUJBQXoeOEaQQQhAGElZGAGRESEJAgWTXBgNmQCRAC8h0MEHH9AFmAOdKUYAmv/3mv8CmmJgDkhgYiViBJ4waCBjcGhgYwaZCHgBmxhgImAINQOVSRwGkb8eBZj/9wf8CDYEltvnApkIQAew8L2wEQAA/wEAAP61ApMVRg5GAZAInwEh+AcB0AhGAOAEIAAvANEIRgmZAJEALxXQwbIBKRLQAZwgRjFGAJr/91z/IEYxRipGApwjRv/3/f4INmQcApQINb8e5+fAsv69/rUfRhRGDUYCRlkeGEaIQREhCQICklYYCJkBkQAvJdDBByPQApgpRgGa//c2/wEgcGABLwvQ/yFxYjViIWgxY2FocWMwYL8eCCECIAfgDyFxYjViIWgxYzBgACcEIW0YgAAkGAKY//ec+9fnASEIQP69+LUfRhRGDUYGRgArAdAEIADgASAGmQCRAC8b0MGyASkY0DBGKUYAmv/3/v4wRilGIkYBLwXQ//d5/b8eCCECIgTg//dT/QAnBCEBIm0YkQBkGOHnwLL4vQNJACJCUEAYQmCCYHBHwEbQEQAAACHJQwJKgVCAGEFggWBwR9ARAAAESQAiQlBAGEJggmACZEJkgmRwR9ARAAAAIclDBEqBUIAYQWCBYAFkQWSBZHBHwEbQEQAAELUERv/3VvwBRgtKEGgFIxNgByMDQAlIAGgTYKQKAikI0wdKEEAA8DX8AUYgRgDwMfwMRiBGEL0AE0BAGADEQf8PAABwtRVGDEYLSUYYIEb/99b/ASGKApVCBNBKApVCCNHACALgPDZgBMAOgUAwaAhDMGBwvcBG1BEAALC1ESMbAsQYAyVlYCFiASFhYhJ4ImPBULC9sLURIxsCxBgDJWVgIWJlYhGIIWMBIcFQsL2wtREjGwLEGAMlZWAhYg8hYWIRaCFjASHBULC9sLURIxsCxBgDJWVgIWL/IWFiEWghY1FoYWMBIcFQsL0QtQZLAyTEUMMYASQcYtlhEXjZYv/3DPkQvcBGBBEAABC1BUsDJMRQwxgcYtlhEYjZYv/3/fgQvQQRAAAQtQZLAyTEUMMYDyQcYtlhEWjZYv/37vgQvcBGBBEAABC1B0sDJMRQwxj/JBxi2WERaNliUWgZY//33PgQvcBGBBEAABC1BksDJMRQwxj/JAI0HGLZYRF42WL/98v4EL0EEQAAELUGSwMkxFDDGP8kBDQcYtlhEYjZYv/3u/gQvQQRAAAQtQZLAyTEUMMY/yQQNBxi2WERaNli//er+BC9BBEAABC1B0sDJMRQwxgGTBxi2WERaNliUWgZY//3mvgQvcBGBBEAAP8BAACwtQhMAyUFUQQZ/yUCNSVi4WEReOFiGXgDSoFQ//eE+LC9wEYEEQAAsBEAALC1CEwDJQVRBBn/JQQ1JWLhYRGI4WIZeANKgVD/9274sL3ARgQRAACwEQAAsLUITAMlBVEEGf8lEDUlYuFhEWjhYhl4A0qBUP/3WPiwvcBGBBEAALARAACwtQhMAyUFUQQZB00lYuFhEWjhYlFoIWMZeARKgVD/90H4sL0EEQAA/wEAALARAACwtREjGwLEGAMlZWAhYv8hAjFhYhF4IWMBIcFQsL2wtREjGwLEGAMlZWAhYv8hBDFhYhGIIWMBIcFQsL2wtREjGwLEGAMlZWAhYv8hEDFhYhFoIWMBIcFQsL3ARrC1ESMbAsQYAyVlYCFiBElhYhFoIWNRaGFjASHBULC9/wEAAHC1ESQkAgUZAyZuYCli/yECMWliEXgpYxl4AkqBUAEhAVFwvbARAABwtREkJAIFGQMmbmApYv8hBDFpYhGIKWMZeAJKgVABIQFRcL2wEQAAcLURJCQCBRkDJm5gKWL/IRAxaWIRaCljGXgCSoFQASEBUXC9sBEAAHC1ESQkAgUZAyZuYCliBklpYhFoKWNRaGljGXgDSoFQASEBUXC9wEb/AQAAsBEAABC1ESISAoMYBiRcYBliASGBUBC9gLUESgYjg1CCGNFh/veU/4C9wEYEEQAAELUTRgRGBEoA8Aj4ESAAAgEhIVAQvcBG//8AALC1B0wRJQVRABkCYsFhGWjBYlloAWOZaEFj2WiBY7C9BBEAABC1E0YERgRK//fo/xEgAAIBISFQEL3ARv//AQCwtR1GE0YERgZK//fZ/yh4BUlgUGAYaXhBYBEgAAIBISFQsL3//wEAsBEAAPC1hbAfRhRGDUYCRhEgAQIAKwHQAy8B2AAgAOABIASSVhgKmQOR/yEQMQKRAZYALzrQwQc40ASYKUYDmv/3WPwBLxDQAy8a2AEgcGACmfAxcWI1YiFoMWNhaHFjMGC/HgghAiIJ4AEicmACmHBiNWIhaDFjMmAAJwQhBJgO4C5GJUYEnCBGMUYqRv/3lf8gRixGNUYBnj8fECEEIm0YkQBkGP/3qfjC5wEhCEAFsPC9/7UBJCICKksZaAOSkUMZYChJDWhtBPzVRX4lQJ5ppkN0GZxhICQEXQMlLEDeaa5DNBncYSBMJWgFJiZgRmo3aB9idmheYgcmLkAmYMRpfyUtAt5prkNkBmQMNBncYQdoRWiCaACSxmgCaQGSQmkCkpppEkwUQDoHEgstA62yqhgyQwCdLQctDRVDAZoVQwKaFUMAfihDCkoCQBAZmGEYaAOaEEMYYAhogAX81f+9wEYIAQtABAILQAATQECNAPD/cv8PALC1/yIEMg5JC2iTQ4J4AyQUQAJ4EgISGRpDCmAJSgpLE2AKTCVobQX81UB4ACgD0AhoECQEQwxgWBwQYLC9wEYUAQtAFAMLQAEAAJEEAgtADEkKaAAoA9ABIIACAkMG4AMggkMKYAEggAIKaIJDCmABIAAFSmgCQ0pgA0gBaIkD/NVwRwABC0AEAgtAASCBAgZKE2iLQxNgAAVRaIFDUWADSAFoiQP81HBHwEYAAQtABAILQAdJiGAHSAJokgL81QEiEgQLaBNDC2ABaMkG/NVwR8BGBAELQAQCC0ABIAAEBEkKaIJDCmADSAFoyQb81HBHwEYEAQtABAILQBC1D0kLaAEik0MLYAMjGwMYQIxonEMgGIhgiGgIIwND9yCDQ4tgCGgQQwhgEAeKaAJDimADSAFoyQX81RC9wEYIAQtABAILQHC1EUsdaAEkpUMdYAMlLQMoQJ5orkMwGJhgmGj/JahDybJAGJhgGGggQxhgmGghBwAqBtAIQ5hgBEgBaMkF/NVwvYhDmGBwvQgBC0AEAgtAsLU/IxsEBEwlaJ1DCEMQQxhAKBggYLC9OAELQAlIAGhABwjUCEhBaMkCBtQAaIAFBdUDIHBHACBwRwIgcEcBIHBHwEYQ7QDgAAELQApJCmwAIAAqANBwRwhKEmhSB/rVCGjABQTUCGiABQPVAyBwRwIgcEcBIHBHAAELQBDtAOAHScprACABKgfRBkoSaFIHA9UIaIACAdUCIHBHASBwRwQBC0AQ7QDgELUISxxrASIiQAjRBkwgQBhgIUBZYNhqBEkBQ9liUEJQQRC9GCALQMD/PwAQAAB2ELUIS5xqASIiQAjRBkwgQBhgIUAZYFhqBEkBQ1liUEJQQRC9ICALQMD/PwBAAAB2ACIDCYtCLNMDCotCEdMAI5xGTuADRgtDPNQAIkMIi0Ix0wMJi0Ic0wMKi0IB05RGP+DDCYtCAdPLAcAaUkGDCYtCAdOLAcAaUkFDCYtCAdNLAcAaUkEDCYtCAdMLAcAaUkHDCItCAdPLAMAaUkGDCItCAdOLAMAaUkFDCItCAdNLAMAaUkFBGgDSAUZSQRBGcEdd4MoPANBJQgMQANNAQlNAnEYAIgMJi0It0wMKi0IS04kB/CISugMKi0IM04kBkhGLQgjTiQGSEYtCBNOJATrQkhEA4IkJwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJB2dJDCItCAdNLAMAaUkFBGgDSAUZSQRBGY0ZbEAHTQEIAKwDVSUJwR2NGWxAA00BCAbUFSQAoAtxJHAhAAOAIRsBGwEYCvQC/////fwAAAAA= - load_address: 0x20200008 - pc_init: 0x1d - pc_uninit: 0x99 - pc_program_page: 0x19d - pc_erase_sector: 0xcd - pc_erase_all: 0x9d - data_section_offset: 0x16e4 - flash_properties: - address_range: - start: 0x0 - end: 0x80000 - page_size: 0x400 - erased_byte_value: 0xff - program_page_timeout: 500 - erase_sector_timeout: 3000 - sectors: - - size: 0x400 - address: 0x0 -- name: mspm0gx51x_nonmain - description: MSPM0GX51X NON-MAIN - instructions: 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AAELQApJCmwAIAAqANBwRwhKEmhSB/rVCGjABQTUCGiABQPVAyBwRwIgcEcBIHBHAAELQBDtAOAHScprACABKgfRBkoSaFIHA9UIaIACAdUCIHBHASBwRwQBC0AQ7QDgELUISxxrASIiQAjRBkwgQBhgIUBZYNhqBEkBQ9liUEJQQRC9GCALQMD/PwAQAAB2ELUIS5xqASIiQAjRBkwgQBhgIUAZYFhqBEkBQ1liUEJQQRC9ICALQMD/PwBAAAB2ACIDCYtCLNMDCotCEdMAI5xGTuADRgtDPNQAIkMIi0Ix0wMJi0Ic0wMKi0IB05RGP+DDCYtCAdPLAcAaUkGDCYtCAdOLAcAaUkFDCYtCAdNLAcAaUkEDCYtCAdMLAcAaUkHDCItCAdPLAMAaUkGDCItCAdOLAMAaUkFDCItCAdNLAMAaUkFBGgDSAUZSQRBGcEdd4MoPANBJQgMQANNAQlNAnEYAIgMJi0It0wMKi0IS04kB/CISugMKi0IM04kBkhGLQgjTiQGSEYtCBNOJATrQkhEA4IkJwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJB2dJDCItCAdNLAMAaUkFBGgDSAUZSQRBGY0ZbEAHTQEIAKwDVSUJwR2NGWxAA00BCAbUFSQAoAtxJHAhAAOAIRsBGwEYCvQC/////fwAAAAS7qruqu6q7qv//////////u6q7qruqu6r//7uqu6q7qv///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9B/+hoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFgIVAgEDAgOoEv//r5YTdg9yY1+9tEpaCmPDnxKvMPlQpu5clxvhiOicQFH/////////////////////////////////////////////SADJWPEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - load_address: 0x20200008 - pc_init: 0x1d - pc_uninit: 0xb5 - pc_program_page: 0x1a9 - pc_erase_sector: 0x159 - pc_erase_all: 0x211 - data_section_offset: 0x1b84 - flash_properties: - address_range: - start: 0x41c00000 - end: 0x41c00400 - page_size: 0x40 - erased_byte_value: 0xff - program_page_timeout: 500 - erase_sector_timeout: 3000 - sectors: - - size: 0x400 - address: 0x0 -- name: mspm0gx51x_data_16kb - description: MSPM0GX51X DATA 16KB - instructions: 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 - load_address: 0x20200008 - pc_init: 0x1d - pc_uninit: 0x99 - pc_program_page: 0x19d - pc_erase_sector: 0xcd - pc_erase_all: 0x9d - data_section_offset: 0x16e4 - flash_properties: - address_range: - start: 0x0 - end: 0x4000 - page_size: 0x400 - erased_byte_value: 0xff - program_page_timeout: 500 - erase_sector_timeout: 3000 - sectors: - - size: 0x400 - address: 0x0 diff --git a/examples/mspm0l2228/.cargo/config.toml b/examples/mspm0l2228/.cargo/config.toml index 4284749e9..f383afd9e 100644 --- a/examples/mspm0l2228/.cargo/config.toml +++ b/examples/mspm0l2228/.cargo/config.toml @@ -1,7 +1,6 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # replace MSPM0L2228 with your chip as listed in `probe-rs chip list` -# TODO: Remove description path after new chiptool release -runner = "probe-rs run --restore-unwritten --verify --chip MSPM0L2228 --protocol=swd --chip-description-path ./MSPM0L122X_L222X_Series.yaml" +runner = "probe-rs run --restore-unwritten --verify --chip MSPM0L2228 --protocol=swd" [build] target = "thumbv6m-none-eabi" diff --git a/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml b/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml deleted file mode 100644 index ac52fda2e..000000000 --- a/examples/mspm0l2228/MSPM0L122X_L222X_Series.yaml +++ /dev/null @@ -1,239 +0,0 @@ -name: MSPM0L122X_L222X Series -manufacturer: - id: 0x17 - cc: 0x0 -generated_from_pack: true -pack_file_release: 1.1.1 -variants: -- name: MSPM0L1227 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x20000 - cores: - - main - access: - write: false - boot: true - - !Ram - name: IRAM1 - range: - start: 0x20200000 - end: 0x20208000 - cores: - - main - - !Generic - name: NonMain - range: - start: 0x41c00000 - end: 0x41c00200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory - range: - start: 0x41c40000 - end: 0x41c40080 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0l122x_l222x_main_256kb - - mspm0l122x_l222x_nonmain -- name: MSPM0L1228 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x40000 - cores: - - main - access: - write: false - boot: true - - !Ram - name: IRAM1 - range: - start: 0x20200000 - end: 0x20208000 - cores: - - main - - !Generic - name: NonMain - range: - start: 0x41c00000 - end: 0x41c00200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory - range: - start: 0x41c40000 - end: 0x41c40080 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0l122x_l222x_main_256kb - - mspm0l122x_l222x_nonmain -- name: MSPM0L2227 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x20000 - cores: - - main - access: - write: false - boot: true - - !Ram - name: IRAM1 - range: - start: 0x20200000 - end: 0x20208000 - cores: - - main - - !Generic - name: NonMain - range: - start: 0x41c00000 - end: 0x41c00200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory - range: - start: 0x41c40000 - end: 0x41c40080 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0l122x_l222x_main_256kb - - mspm0l122x_l222x_nonmain -- name: MSPM0L2228 - cores: - - name: main - type: armv6m - core_access_options: !Arm - ap: 0 - memory_map: - - !Nvm - name: IROM1 - range: - start: 0x0 - end: 0x40000 - cores: - - main - access: - write: false - boot: true - - !Ram - name: IRAM1 - range: - start: 0x20200000 - end: 0x20208000 - cores: - - main - - !Generic - name: NonMain - range: - start: 0x41c00000 - end: 0x41c00200 - cores: - - main - access: - write: false - execute: false - - !Generic - name: Factory - range: - start: 0x41c40000 - end: 0x41c40080 - cores: - - main - access: - write: false - execute: false - flash_algorithms: - - mspm0l122x_l222x_main_256kb - - mspm0l122x_l222x_nonmain -flash_algorithms: -- name: mspm0l122x_l222x_main_256kb - description: MSPM0L122X_222X MAIN 256KB - default: true - instructions: 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 - load_address: 0x20200008 - pc_init: 0x1d - pc_uninit: 0x5d - pc_program_page: 0x145 - pc_erase_sector: 0x61 - pc_erase_all: 0x131 - data_section_offset: 0x12dc - flash_properties: - address_range: - start: 0x0 - end: 0x40000 - page_size: 0x400 - erased_byte_value: 0xff - program_page_timeout: 500 - erase_sector_timeout: 3000 - sectors: - - size: 0x400 - address: 0x0 -- name: mspm0l122x_l222x_nonmain - description: MSPM0L122X_222X NON-MAIN - instructions: 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A0gBaIkD/NRwR8BGAAELQAQCC0ABIAAEBEkKaIJDCmADSAFoyQb81HBHwEYEAQtABAILQAAiAwmLQizTAwqLQhHTACOcRk7gA0YLQzzUACJDCItCMdMDCYtCHNMDCotCAdOURj/gwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJBQwiLQgHTSwDAGlJBQRoA0gFGUkEQRnBHXeDKDwDQSUIDEADTQEJTQJxGACIDCYtCLdMDCotCEtOJAfwiEroDCotCDNOJAZIRi0II04kBkhGLQgTTiQE60JIRAOCJCcMJi0IB08sBwBpSQYMJi0IB04sBwBpSQUMJi0IB00sBwBpSQQMJi0IB0wsBwBpSQcMIi0IB08sAwBpSQYMIi0IB04sAwBpSQdnSQwiLQgHTSwDAGlJBQRoA0gFGUkEQRmNGWxAB00BCACsA1UlCcEdjRlsQANNAQgG1BUkAKALcSRwIQADgCEbARsBGAr0Av////38CAAABu6q7qruqu6r//////////7uqu6q7qruq//+7qruqu6r///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+yIGk/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABoCGQIBAwIDshL//6+WE3YPcmNfvbRKWgpjw58SrzD5UKbuXJcb4YjonEBR/////////////////////////////////////////////0gA0UsBbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= - load_address: 0x20200008 - pc_init: 0x1d - pc_uninit: 0x7d - pc_program_page: 0x18d - pc_erase_sector: 0x121 - pc_erase_all: 0x79 - data_section_offset: 0x1774 - flash_properties: - address_range: - start: 0x41c00000 - end: 0x41c00200 - page_size: 0x40 - erased_byte_value: 0xff - program_page_timeout: 500 - erase_sector_timeout: 3000 - sectors: - - size: 0x200 - address: 0x0 From 2195156b584cf3675002ee94e274c15fe60808b8 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:44:28 -0500 Subject: [PATCH 06/44] Add mspm0 chips to CI which have working int_group implementations Not all of these have been done yet, as I need to go through each datasheet and manually declare all interrupt groups for mspm0-metapac to then generate. --- ci.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ci.sh b/ci.sh index e32105b16..84312127f 100755 --- a/ci.sh +++ b/ci.sh @@ -170,6 +170,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 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' \ @@ -239,6 +244,11 @@ cargo batch \ --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ + --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \ + --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \ + --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \ + --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \ + --- build --release --manifest-path examples/mspm0l2228/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l2228 \ --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --artifact-dir out/examples/boot/nrf52840 \ --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --artifact-dir out/examples/boot/nrf9160 \ --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns,skip-include --artifact-dir out/examples/boot/nrf9120 \ From 7336ca549e17d899471cb96a5106dd6836a40eea Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:50:58 -0500 Subject: [PATCH 07/44] build C1104 with --release C1104 only has 1KB of ram, so we must build in release --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 84312127f..62e406f2c 100755 --- a/ci.sh +++ b/ci.sh @@ -244,7 +244,7 @@ cargo batch \ --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ - --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \ + --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 --release \ --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \ --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \ --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \ From 0642c3a7feb4f221c87f805d8e69f5a75f045248 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:51:43 -0500 Subject: [PATCH 08/44] Revert "build C1104 with --release" This reverts commit 7336ca549e17d899471cb96a5106dd6836a40eea. --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 62e406f2c..84312127f 100755 --- a/ci.sh +++ b/ci.sh @@ -244,7 +244,7 @@ cargo batch \ --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ - --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 --release \ + --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \ --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \ --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \ --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \ From 1dd129693318e15aa15cb50243c5be6547aa5159 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:56:23 -0500 Subject: [PATCH 09/44] more aggressive debug level for CI? --- examples/mspm0c1104/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml index 35c9b1358..a56086e2a 100644 --- a/examples/mspm0c1104/Cargo.toml +++ b/examples/mspm0c1104/Cargo.toml @@ -19,14 +19,14 @@ panic-semihosting = "0.6.0" # The chip only has 1KB of ram, so we must optimize binaries regardless [profile.dev] -debug = 2 +debug = 1 opt-level = "z" lto = true codegen-units = 1 # strip = true [profile.release] -debug = 2 +debug = 1 opt-level = "z" lto = true codegen-units = 1 From c5b3cc5f4796f721cac502485dd21875d0e1cc4e Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 15 Mar 2025 13:58:07 -0500 Subject: [PATCH 10/44] How about debug=0 for c1104? --- examples/mspm0c1104/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml index a56086e2a..3996939a5 100644 --- a/examples/mspm0c1104/Cargo.toml +++ b/examples/mspm0c1104/Cargo.toml @@ -19,14 +19,14 @@ panic-semihosting = "0.6.0" # The chip only has 1KB of ram, so we must optimize binaries regardless [profile.dev] -debug = 1 +debug = 0 opt-level = "z" lto = true codegen-units = 1 # strip = true [profile.release] -debug = 1 +debug = 0 opt-level = "z" lto = true codegen-units = 1 From f7f316ad179a1812ffa3f10869165bafc99d515e Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sun, 16 Mar 2025 13:52:12 -0500 Subject: [PATCH 11/44] correct group 0 int_group accesses --- embassy-mspm0/src/int_group/c110x.rs | 2 +- embassy-mspm0/src/int_group/g350x.rs | 2 +- embassy-mspm0/src/int_group/g351x.rs | 2 +- embassy-mspm0/src/int_group/l130x.rs | 2 +- embassy-mspm0/src/int_group/l222x.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embassy-mspm0/src/int_group/c110x.rs b/embassy-mspm0/src/int_group/c110x.rs index c503af631..e6a9ddb99 100644 --- a/embassy-mspm0/src/int_group/c110x.rs +++ b/embassy-mspm0/src/int_group/c110x.rs @@ -6,7 +6,7 @@ use crate::pac::interrupt; fn GROUP0() { use mspm0_metapac::Group0; - let group = pac::CPUSS.int_group(1); + let group = pac::CPUSS.int_group(0); // TODO: Decompose to direct u8 let iidx = group.iidx().read().stat().to_bits(); diff --git a/embassy-mspm0/src/int_group/g350x.rs b/embassy-mspm0/src/int_group/g350x.rs index 818dd6e1e..706ba2078 100644 --- a/embassy-mspm0/src/int_group/g350x.rs +++ b/embassy-mspm0/src/int_group/g350x.rs @@ -6,7 +6,7 @@ use crate::pac::interrupt; fn GROUP0() { use mspm0_metapac::Group0; - let group = pac::CPUSS.int_group(1); + 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; diff --git a/embassy-mspm0/src/int_group/g351x.rs b/embassy-mspm0/src/int_group/g351x.rs index b43e0a9db..e785018a7 100644 --- a/embassy-mspm0/src/int_group/g351x.rs +++ b/embassy-mspm0/src/int_group/g351x.rs @@ -6,7 +6,7 @@ use crate::pac::interrupt; fn GROUP0() { use mspm0_metapac::Group0; - let group = pac::CPUSS.int_group(1); + 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; diff --git a/embassy-mspm0/src/int_group/l130x.rs b/embassy-mspm0/src/int_group/l130x.rs index 6d033cc56..8be5adcad 100644 --- a/embassy-mspm0/src/int_group/l130x.rs +++ b/embassy-mspm0/src/int_group/l130x.rs @@ -6,7 +6,7 @@ use crate::pac::interrupt; fn GROUP0() { use mspm0_metapac::Group0; - let group = pac::CPUSS.int_group(1); + 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; diff --git a/embassy-mspm0/src/int_group/l222x.rs b/embassy-mspm0/src/int_group/l222x.rs index 703e16e78..eeb2ce70d 100644 --- a/embassy-mspm0/src/int_group/l222x.rs +++ b/embassy-mspm0/src/int_group/l222x.rs @@ -6,7 +6,7 @@ use crate::pac::interrupt; fn GROUP0() { use mspm0_metapac::Group0; - let group = pac::CPUSS.int_group(1); + 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; From 9afb385f6d92149ff15cf03c3bfaa8cb512a6191 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Wed, 19 Mar 2025 13:05:10 -0500 Subject: [PATCH 12/44] Add docs related things --- .github/ci/doc.sh | 1 + README.md | 1 + docs/pages/overview.adoc | 1 + embassy-mspm0/Cargo.toml | 8 +++++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/ci/doc.sh b/.github/ci/doc.sh index c92892406..58ffe5f2e 100755 --- a/.github/ci/doc.sh +++ b/.github/ci/doc.sh @@ -25,6 +25,7 @@ docserver-builder -i ./embassy-executor -o webroot/crates/embassy-executor/git.z docserver-builder -i ./embassy-futures -o webroot/crates/embassy-futures/git.zup docserver-builder -i ./embassy-nrf -o webroot/crates/embassy-nrf/git.zup docserver-builder -i ./embassy-rp -o webroot/crates/embassy-rp/git.zup +docserver-builder -i ./embassy-mspm0 -o webroot/crates/embassy-mspm0/git.zup docserver-builder -i ./embassy-sync -o webroot/crates/embassy-sync/git.zup docserver-builder -i ./cyw43 -o webroot/crates/cyw43/git.zup docserver-builder -i ./cyw43-pio -o webroot/crates/cyw43-pio/git.zup diff --git a/README.md b/README.md index ee5c42245..a682927c8 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Rust's async/await allows - embassy-stm32, for all STM32 microcontroller families. - embassy-nrf, for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series. - embassy-rp, for the Raspberry Pi RP2040 and RP23xx microcontrollers. + - embassy-mspm0, for the Texas Instruments MSPM0 microcontrollers. - esp-rs, for the Espressif Systems ESP32 series of chips. - Embassy HAL support for Espressif chips, as well as Async WiFi, Bluetooth and ESP-NOW, is being developed in the [esp-rs/esp-hal](https://github.com/esp-rs/esp-hal) repository. - ch32-hal, for the WCH 32-bit RISC-V(CH32V) series of chips. diff --git a/docs/pages/overview.adoc b/docs/pages/overview.adoc index 9b93ba10c..333a5dd9f 100644 --- a/docs/pages/overview.adoc +++ b/docs/pages/overview.adoc @@ -29,6 +29,7 @@ The Embassy project maintains HALs for select hardware, but you can still use HA * link:https://docs.embassy.dev/embassy-stm32/[embassy-stm32], for all STM32 microcontroller families. * link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series. * link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller. +* link:https://docs.embassy.dev/embassy-mspm0/[embassy-mspm0], for the Texas Instruments MSPM0 microcontrollers. * link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips. * link:https://github.com/ch32-rs/ch32-hal[ch32-hal], for the WCH 32-bit RISC-V(CH32V) series of chips. * link:https://github.com/AlexCharlton/mpfs-hal[mpfs-hal], for the Microchip PolarFire SoC. diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index 0f4092d8a..cfe0c85a9 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -9,6 +9,12 @@ categories = ["embedded", "hardware-support", "no-std", "asynchronous"] repository = "https://github.com/embassy-rs/embassy" documentation = "https://docs.embassy.dev/embassy-mspm0" +[package.metadata.embassy_docs] +src_base = "https://github.com/embassy-rs/embassy/blob/embassy-mspm0-v$VERSION/embassy-mspm0/src/" +src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-mspm0/src/" + +features = ["defmt", "unstable-pac", "time-driver-any"] + [package.metadata.docs.rs] features = ["defmt", "unstable-pac", "time-driver-any", "time", "mspm0g3507"] rustdoc-args = ["--cfg", "docsrs"] @@ -105,7 +111,7 @@ 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. `mspm0g3507`. +#! Select your chip by specifying the model as a feature, e.g. `mspm0g350x`. #! Check the `Cargo.toml` for the latest list of supported chips. #! #! **Important:** Do not forget to adapt the target chip in your toolchain, From 91684a11c8a15b62a773a1ace40791fcf80fdad2 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Wed, 19 Mar 2025 13:28:03 -0500 Subject: [PATCH 13/44] build c1104 seperately for defmt buffer size --- ci.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 84312127f..5b63c507b 100755 --- a/ci.sh +++ b/ci.sh @@ -244,7 +244,6 @@ cargo batch \ --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ - --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \ --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \ --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \ --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \ @@ -313,6 +312,11 @@ cargo batch \ $BUILD_EXTRA +# MSPM0C1104 must be built seperately since cargo batch does not consider env vars set in `.cargo/config.toml`. +# Since the target has 1KB of ram, we need to limit defmt's buffer size. +DEFMT_RTT_BUFFER_SIZE="72" cargo batch \ + --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \ + # temporarily disabled, these boards are dead. rm -rf out/tests/stm32f103c8 rm -rf out/tests/nrf52840-dk From f3b9be7beede167295e8dc431e417bea77bb2455 Mon Sep 17 00:00:00 2001 From: Alexander van Saase Date: Wed, 19 Mar 2025 19:32:05 +0100 Subject: [PATCH 14/44] embassy-sync: add lock_mut to blocking_mutex::Mutex --- embassy-sync/src/blocking_mutex/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/embassy-sync/src/blocking_mutex/mod.rs b/embassy-sync/src/blocking_mutex/mod.rs index beafdb43d..5b0e4144a 100644 --- a/embassy-sync/src/blocking_mutex/mod.rs +++ b/embassy-sync/src/blocking_mutex/mod.rs @@ -50,6 +50,20 @@ impl Mutex { f(inner) }) } + + /// Creates a critical section and grants temporary mutable access to the protected data. + /// + /// # Safety + /// This method is unsafe because calling this method when the mutex is already locked, + /// either using this method or `lock`, violates Rust's aliasing rules. + pub unsafe fn lock_mut(&self, f: impl FnOnce(&mut T) -> U) -> U { + self.raw.lock(|| { + let ptr = self.data.get() as *mut T; + // Safety: we have exclusive access to the data, as long as this mutex is not locked re-entrantly + let inner = unsafe { &mut *ptr }; + f(inner) + }) + } } impl Mutex { From d43acbb22b71e11b1731cbd2f6b4c6f56088d2f4 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Fri, 21 Mar 2025 15:16:27 -0500 Subject: [PATCH 15/44] Add missing flavors to docs for mspm0 --- embassy-mspm0/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index cfe0c85a9..b747d270e 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -14,6 +14,11 @@ src_base = "https://github.com/embassy-rs/embassy/blob/embassy-mspm0-v$VERSION/e src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-mspm0/src/" features = ["defmt", "unstable-pac", "time-driver-any"] +flavors = [ + { regex_feature = "mspm0c.*", target = "thumbv6m-none-eabi" }, + { regex_feature = "mspm0l.*", target = "thumbv6m-none-eabi" }, + { regex_feature = "mspm0g.*", target = "thumbv6m-none-eabi" }, +] [package.metadata.docs.rs] features = ["defmt", "unstable-pac", "time-driver-any", "time", "mspm0g3507"] From 7a031eed66ef27e83b8582e7c1e7ca00d16ccf64 Mon Sep 17 00:00:00 2001 From: Alexander van Saase Date: Fri, 21 Mar 2025 23:02:04 +0100 Subject: [PATCH 16/44] Add note about RefCell alternative --- embassy-sync/src/blocking_mutex/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/embassy-sync/src/blocking_mutex/mod.rs b/embassy-sync/src/blocking_mutex/mod.rs index 5b0e4144a..a41bc3569 100644 --- a/embassy-sync/src/blocking_mutex/mod.rs +++ b/embassy-sync/src/blocking_mutex/mod.rs @@ -54,8 +54,11 @@ impl Mutex { /// Creates a critical section and grants temporary mutable access to the protected data. /// /// # Safety - /// This method is unsafe because calling this method when the mutex is already locked, - /// either using this method or `lock`, violates Rust's aliasing rules. + /// + /// This method is marked unsafe because calling this method re-entrantly, i.e. within + /// another `lock_mut` or `lock` closure, violates Rust's aliasing rules. Calling this + /// method at the same time from different tasks is safe. For a safe alternative with + /// mutable access that never causes UB, use a `RefCell` in a `Mutex`. pub unsafe fn lock_mut(&self, f: impl FnOnce(&mut T) -> U) -> U { self.raw.lock(|| { let ptr = self.data.get() as *mut T; From 46a96ff68c7070c11e201f07ff4a21563b976542 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Fri, 21 Mar 2025 19:20:09 -0500 Subject: [PATCH 17/44] mspm0: Remove features for which int_group is not implemented in metapac yet These will be readded again when I eliminate int_group manual impls in the near future --- embassy-mspm0/Cargo.toml | 7 ------- embassy-mspm0/src/lib.rs | 7 ------- 2 files changed, 14 deletions(-) diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index b747d270e..e63a86103 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -123,14 +123,7 @@ time-driver-tima1 = ["_time-driver"] #! e.g. in `.cargo/config.toml`. mspm0c110x = [ "mspm0-metapac/mspm0c110x" ] -mspm0g110x = [ "mspm0-metapac/mspm0g110x" ] -mspm0g150x = [ "mspm0-metapac/mspm0g150x" ] -mspm0g151x = [ "mspm0-metapac/mspm0g151x" ] -mspm0g310x = [ "mspm0-metapac/mspm0g310x" ] mspm0g350x = [ "mspm0-metapac/mspm0g350x" ] mspm0g351x = [ "mspm0-metapac/mspm0g351x" ] -mspm0l110x = [ "mspm0-metapac/mspm0l110x" ] -mspm0l122x = [ "mspm0-metapac/mspm0l122x" ] mspm0l130x = [ "mspm0-metapac/mspm0l130x" ] -mspm0l134x = [ "mspm0-metapac/mspm0l134x" ] mspm0l222x = [ "mspm0-metapac/mspm0l222x" ] diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 1191b1010..3128bb3c7 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -13,16 +13,9 @@ mod time_driver; // Interrupt group handlers. #[cfg_attr(feature = "mspm0c110x", path = "int_group/c110x.rs")] -#[cfg_attr(feature = "mspm0g110x", path = "int_group/g110x.rs")] -#[cfg_attr(feature = "mspm0g150x", path = "int_group/g150x.rs")] -#[cfg_attr(feature = "mspm0g151x", path = "int_group/g151x.rs")] -#[cfg_attr(feature = "mspm0g310x", path = "int_group/g310x.rs")] #[cfg_attr(feature = "mspm0g350x", path = "int_group/g350x.rs")] #[cfg_attr(feature = "mspm0g351x", path = "int_group/g351x.rs")] -#[cfg_attr(feature = "mspm0l110x", path = "int_group/l110x.rs")] -#[cfg_attr(feature = "mspm0l122x", path = "int_group/l122x.rs")] #[cfg_attr(feature = "mspm0l130x", path = "int_group/l130x.rs")] -#[cfg_attr(feature = "mspm0l134x", path = "int_group/l134x.rs")] #[cfg_attr(feature = "mspm0l222x", path = "int_group/l222x.rs")] mod int_group; From 07387ea405b3228b9526d994da94e7d4a73339f7 Mon Sep 17 00:00:00 2001 From: elagil Date: Sat, 22 Mar 2025 11:46:28 +0100 Subject: [PATCH 18/44] fix: apply STM32H5 USB errata (OUT transfer delay) --- embassy-stm32/src/usb/usb.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 24983cf3c..d5cfa1bb8 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -7,6 +7,7 @@ use core::task::Poll; use embassy_hal_internal::into_ref; use embassy_sync::waitqueue::AtomicWaker; +use embassy_time::Timer; use embassy_usb_driver as driver; use embassy_usb_driver::{ Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, @@ -887,6 +888,16 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { }) .await; + // Errata for STM32H5, 2.20.1: + // During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses + // have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. + // + // Workaround: + // Software should ensure that a small delay is included before accessing the SRAM contents. This delay should be + // 800 ns in Full Speed mode and 6.4 μs in Low Speed mode. + #[cfg(stm32h5)] + Timer::after_nanos(800).await; + RX_COMPLETE[index].store(false, Ordering::Relaxed); if stat == Stat::DISABLED { From 5264d770079633786f6b34d6d656599bfc7efe7d Mon Sep 17 00:00:00 2001 From: elagil Date: Sat, 22 Mar 2025 11:46:38 +0100 Subject: [PATCH 19/44] fix: mute by default (UAC1) --- embassy-usb/src/class/uac1/speaker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-usb/src/class/uac1/speaker.rs b/embassy-usb/src/class/uac1/speaker.rs index 25de25d9c..1ff29088c 100644 --- a/embassy-usb/src/class/uac1/speaker.rs +++ b/embassy-usb/src/class/uac1/speaker.rs @@ -348,7 +348,7 @@ pub struct AudioSettings { impl Default for AudioSettings { fn default() -> Self { AudioSettings { - muted: [true; MAX_AUDIO_CHANNEL_COUNT], + muted: [false; MAX_AUDIO_CHANNEL_COUNT], volume_8q8_db: [MAX_VOLUME_DB * VOLUME_STEPS_PER_DB; MAX_AUDIO_CHANNEL_COUNT], } } From e34b4d69ee101f15f773381ca575a236f6dd452e Mon Sep 17 00:00:00 2001 From: elagil Date: Sat, 22 Mar 2025 11:58:50 +0100 Subject: [PATCH 20/44] fix: build --- embassy-stm32/src/usb/usb.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index d5cfa1bb8..f050c00ce 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -7,7 +7,6 @@ use core::task::Poll; use embassy_hal_internal::into_ref; use embassy_sync::waitqueue::AtomicWaker; -use embassy_time::Timer; use embassy_usb_driver as driver; use embassy_usb_driver::{ Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, @@ -896,7 +895,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { // Software should ensure that a small delay is included before accessing the SRAM contents. This delay should be // 800 ns in Full Speed mode and 6.4 μs in Low Speed mode. #[cfg(stm32h5)] - Timer::after_nanos(800).await; + embassy_time::Timer::after_nanos(800).await; RX_COMPLETE[index].store(false, Ordering::Relaxed); From 816aa9a06ced95e801f7245f4402ef7a8120045f Mon Sep 17 00:00:00 2001 From: drindr Date: Sun, 23 Mar 2025 00:01:01 +0800 Subject: [PATCH 21/44] clean the SAADC's register while dropping --- embassy-nrf/src/saadc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 70bda9f70..00e2b7402 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -465,6 +465,10 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> { fn drop(&mut self) { let r = Self::regs(); r.enable().write(|w| w.set_enable(false)); + for i in 0..N { + r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); + r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); + } } } From 07da54ec18ce5c8dbd07b3d894665e54b75dbe52 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Fri, 21 Mar 2025 19:18:19 -0500 Subject: [PATCH 22/44] mspm0: generate all singletons --- embassy-mspm0/Cargo.toml | 9 +- embassy-mspm0/build.rs | 415 +++++++++++++++++++++++-------- embassy-mspm0/src/lib.rs | 19 ++ embassy-mspm0/src/time_driver.rs | 3 + 4 files changed, 335 insertions(+), 111 deletions(-) diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index b747d270e..6aeafe932 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -45,14 +45,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-9faa5239a8eab04946086158f2a7fdff5a6a179d" } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a" } [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-9faa5239a8eab04946086158f2a7fdff5a6a179d", 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"] } [features] default = ["rt"] @@ -107,7 +107,10 @@ time-driver-timg9 = ["_time-driver"] time-driver-timg10 = ["_time-driver"] ## Use TIMG11 as time driver time-driver-timg11 = ["_time-driver"] -# TODO: Support TIMG12 and TIMG13 +## Use TIMG12 as time driver +time-driver-timg12 = ["_time-driver"] +## Use TIMG13 as time driver +time-driver-timg13 = ["_time-driver"] ## Use TIMG14 as time driver time-driver-timg14 = ["_time-driver"] ## Use TIMA0 as time driver diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 8c6dd4a5c..9025c337a 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -1,4 +1,5 @@ -use std::collections::HashMap; +use std::cmp::Ordering; +use std::collections::{BTreeSet, HashMap}; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Command; @@ -23,48 +24,131 @@ fn generate_code() { cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); - let mut singletons = Vec::new(); + let mut singletons = get_singletons(&mut cfgs); - // Generate singletons for GPIO pins. To only consider pins available on a family, use the name of - // the pins from the pincm mappings. - for pincm_mapping in METADATA.pincm_mappings.iter() { - singletons.push(pincm_mapping.pin.to_string()); - } + time_driver(&mut singletons, &mut cfgs); - for peri in METADATA.peripherals { - match peri.kind { - // Specially generated. - "gpio" => match peri.name { - "GPIOB" => cfgs.enable("gpio_pb"), - "GPIOC" => cfgs.enable("gpio_pc"), - _ => (), - }, - - // These peripherals are managed internally by the hal. - "iomux" | "cpuss" => {} - - _ => singletons.push(peri.name.to_string()), - } - } - - time_driver(&singletons, &mut cfgs); - - // ======== - // Write singletons let mut g = TokenStream::new(); - let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect(); + g.extend(generate_singletons(&singletons)); + g.extend(generate_pincm_mapping()); + g.extend(generate_pin()); + g.extend(generate_timers()); + g.extend(generate_interrupts()); + g.extend(generate_peripheral_instances()); + g.extend(generate_pin_trait_impls()); - g.extend(quote! { - embassy_hal_internal::peripherals_definition!(#(#singleton_tokens),*); - }); + let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); + fs::write(&out_file, g.to_string()).unwrap(); + rustfmt(&out_file); +} - g.extend(quote! { - embassy_hal_internal::peripherals_struct!(#(#singleton_tokens),*); - }); +#[derive(Debug, Clone)] +struct Singleton { + name: String, - // ======== - // Generate GPIO pincm lookup tables. + cfg: Option, +} + +impl PartialEq for Singleton { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +impl Eq for Singleton {} + +impl PartialOrd for Singleton { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Singleton { + fn cmp(&self, other: &Self) -> Ordering { + self.name.cmp(&other.name) + } +} + +fn get_singletons(cfgs: &mut common::CfgSet) -> Vec { + let mut singletons = Vec::::new(); + + for peripheral in METADATA.peripherals { + // Some peripherals do not generate a singleton, but generate a singleton for each pin. + let skip_peripheral_singleton = match peripheral.kind { + "gpio" => { + // Also enable ports that are present. + match peripheral.name { + "GPIOB" => cfgs.enable("gpio_pb"), + "GPIOC" => cfgs.enable("gpio_pc"), + _ => (), + } + + true + } + + // Each channel gets a singleton, handled separately. + "dma" => true, + + // These peripherals do not exist as singletons, and have no signals but are managed + // by the HAL. + "iomux" | "cpuss" => true, + + _ => false, + }; + + if !skip_peripheral_singleton { + singletons.push(Singleton { + name: peripheral.name.to_string(), + cfg: None, + }); + } + + let mut signals = BTreeSet::new(); + + // Pick out each unique signal. There may be multiple instances of each signal due to + // iomux mappings. + for pin in peripheral.pins { + let signal = if peripheral.name.starts_with("GPIO") + || peripheral.name.starts_with("VREF") + || peripheral.name.starts_with("RTC") + { + pin.signal.to_string() + } else { + format!("{}_{}", peripheral.name, pin.signal) + }; + + // We need to rename some signals to become valid Rust identifiers. + let signal = make_valid_identifier(&signal); + signals.insert(signal); + } + + singletons.extend(signals); + } + + // DMA channels get their own singletons + for dma_channel in METADATA.dma_channels.iter() { + singletons.push(Singleton { + name: format!("DMA_CH{}", dma_channel.number), + cfg: None, + }); + } + + // TODO: Remove `/` signals from metapac (PA1/NRST on C110x for example) + singletons.retain(|s| !s.name.contains('/')); + + singletons.sort_by(|a, b| a.name.cmp(&b.name)); + singletons +} + +fn make_valid_identifier(s: &str) -> Singleton { + let name = s.replace('+', "_P").replace("-", "_N"); + + Singleton { name, cfg: None } +} + +fn generate_pincm_mapping() -> TokenStream { let pincms = METADATA.pincm_mappings.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; @@ -81,7 +165,7 @@ fn generate_code() { } }); - g.extend(quote! { + quote! { #[doc = "Get the mapping from GPIO pin port to IOMUX PINCM index. This is required since the mapping from IO to PINCM index is not consistent across parts."] pub(crate) fn gpio_pincm(pin_port: u8) -> u8 { match pin_port { @@ -89,9 +173,11 @@ fn generate_code() { _ => unreachable!(), } } - }); + } +} - for pincm_mapping in METADATA.pincm_mappings.iter() { +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 port_letter = port_letter.chars().next().unwrap(); @@ -101,78 +187,19 @@ fn generate_code() { // TODO: Feature gate pins that can be used as NRST - g.extend(quote! { + quote! { impl_pin!(#name, crate::gpio::Port::#port, #pin_number); - }); - } - - // Generate timers - for peripheral in METADATA.peripherals.iter().filter(|p| p.name.starts_with("TIM")) { - let name = Ident::new(&peripheral.name, Span::call_site()); - let timers = &*TIMERS; - - let timer = timers.get(peripheral.name).expect("Timer does not exist"); - assert!(timer.bits == 16 || timer.bits == 32); - let bits = if timer.bits == 16 { - quote! { Bits16 } - } else { - quote! { Bits32 } - }; - - g.extend(quote! { - impl_timer!(#name, #bits); - }); - } - - // Generate interrupt module - let interrupts: Vec = METADATA - .interrupts - .iter() - .map(|interrupt| Ident::new(interrupt.name, Span::call_site())) - .collect(); - - g.extend(quote! { - embassy_hal_internal::interrupt_mod! { - #(#interrupts),* } }); - let group_interrupt_enables = METADATA - .interrupts - .iter() - .filter(|interrupt| interrupt.name.contains("GROUP")) - .map(|interrupt| { - let name = Ident::new(interrupt.name, Span::call_site()); - - quote! { - crate::interrupt::typelevel::#name::enable(); - } - }); - - // Generate interrupt enables for groups - g.extend(quote! { - pub fn enable_group_interrupts(_cs: critical_section::CriticalSection) { - use crate::interrupt::typelevel::Interrupt; - - unsafe { - #(#group_interrupt_enables)* - } - } - }); - - let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); - fs::write(&out_file, g.to_string()).unwrap(); - rustfmt(&out_file); + quote! { + #(#pin_impls)* + } } -fn time_driver(singletons: &[String], cfgs: &mut CfgSet) { +fn time_driver(singletons: &mut Vec, cfgs: &mut CfgSet) { // Timer features - for (timer, desc) in TIMERS.iter() { - if desc.bits != 16 { - continue; - } - + for (timer, _) in TIMERS.iter() { let name = timer.to_lowercase(); cfgs.declare(&format!("time_driver_{}", name)); } @@ -192,7 +219,7 @@ fn time_driver(singletons: &[String], cfgs: &mut CfgSet) { }; // Verify the selected timer is available - let singleton = match time_driver.as_ref().map(|x| x.as_ref()) { + let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) { None => "", Some("timg0") => "TIMG0", Some("timg1") => "TIMG1", @@ -228,14 +255,186 @@ fn time_driver(singletons: &[String], cfgs: &mut CfgSet) { "TIMA0", "TIMA1", ] .iter() - .find(|tim| singletons.contains(&tim.to_string())) + .find(|tim| singletons.iter().any(|s| s.name == **tim)) .expect("Could not find any timer") } _ => panic!("unknown time_driver {:?}", time_driver), }; - if !singleton.is_empty() { - cfgs.enable(format!("time_driver_{}", singleton.to_lowercase())); + if !selected_timer.is_empty() { + cfgs.enable(format!("time_driver_{}", selected_timer.to_lowercase())); + } + + // Apply cfgs to each timer and it's pins + for singleton in singletons.iter_mut() { + if singleton.name.starts_with("TIM") { + // Remove suffixes for pin singletons. + let name = if singleton.name.contains("_CCP") { + singleton.name.split_once("_CCP").unwrap().0 + } else if singleton.name.contains("_FAULT") { + singleton.name.split_once("_FAULT").unwrap().0 + } else if singleton.name.contains("_IDX") { + singleton.name.split_once("_IDX").unwrap().0 + } else { + &singleton.name + }; + + let feature = format!("time-driver-{}", name.to_lowercase()); + + if singleton.name.contains(selected_timer) { + singleton.cfg = Some(quote! { #[cfg(not(all(feature = "time-driver-any", feature = #feature)))] }); + } else { + singleton.cfg = Some(quote! { #[cfg(not(feature = #feature))] }); + } + } + } +} + +fn generate_singletons(singletons: &[Singleton]) -> TokenStream { + let singletons = singletons + .iter() + .map(|s| { + let cfg = s.cfg.clone().unwrap_or_default(); + + let ident = format_ident!("{}", s.name); + + quote! { + #cfg + #ident + } + }) + .collect::>(); + + quote! { + embassy_hal_internal::peripherals_definition!(#(#singletons),*); + embassy_hal_internal::peripherals_struct!(#(#singletons),*); + } +} + +fn generate_timers() -> TokenStream { + // Generate timers + let timer_impls = METADATA + .peripherals + .iter() + .filter(|p| p.name.starts_with("TIM")) + .map(|peripheral| { + let name = Ident::new(&peripheral.name, Span::call_site()); + let timers = &*TIMERS; + + let timer = timers.get(peripheral.name).expect("Timer does not exist"); + assert!(timer.bits == 16 || timer.bits == 32); + let bits = if timer.bits == 16 { + quote! { Bits16 } + } else { + quote! { Bits32 } + }; + + quote! { + impl_timer!(#name, #bits); + } + }); + + quote! { + #(#timer_impls)* + } +} + +fn generate_interrupts() -> TokenStream { + // Generate interrupt module + let interrupts: Vec = METADATA + .interrupts + .iter() + .map(|interrupt| Ident::new(interrupt.name, Span::call_site())) + .collect(); + + let group_interrupt_enables = METADATA + .interrupts + .iter() + .filter(|interrupt| interrupt.name.contains("GROUP")) + .map(|interrupt| { + let name = Ident::new(interrupt.name, Span::call_site()); + + quote! { + crate::interrupt::typelevel::#name::enable(); + } + }); + + // Generate interrupt enables for groups + quote! { + embassy_hal_internal::interrupt_mod! { + #(#interrupts),* + } + + pub fn enable_group_interrupts(_cs: critical_section::CriticalSection) { + use crate::interrupt::typelevel::Interrupt; + + unsafe { + #(#group_interrupt_enables)* + } + } + } +} + +fn generate_peripheral_instances() -> TokenStream { + let mut impls = Vec::::new(); + + for peripheral in METADATA.peripherals { + let peri = format_ident!("{}", peripheral.name); + + // Will be filled in when uart implementation is finished + let _ = peri; + let tokens = match peripheral.kind { + // "uart" => Some(quote! { impl_uart_instance!(#peri); }), + _ => None, + }; + + if let Some(tokens) = tokens { + impls.push(tokens); + } + } + + quote! { + #(#impls)* + } +} + +fn generate_pin_trait_impls() -> TokenStream { + let mut impls = Vec::::new(); + + for peripheral in METADATA.peripherals { + for pin in peripheral.pins { + // TODO: Remove `/` signals from metapac (PA1/NRST on C110x for example) + if pin.pin.contains('/') { + continue; + } + + let key = (peripheral.kind, pin.signal); + + let pin_name = format_ident!("{}", pin.pin); + let peri = format_ident!("{}", peripheral.name); + let pf = pin.pf; + + // Will be filled in when uart implementation is finished + let _ = pin_name; + let _ = peri; + let _ = pf; + + let tokens = match key { + // ("uart", "TX") => Some(quote! { impl_uart_tx_pin!(#peri, #pin_name, #pf); }), + // ("uart", "RX") => Some(quote! { impl_uart_rx_pin!(#peri, #pin_name, #pf); }), + // ("uart", "CTS") => Some(quote! { impl_uart_cts_pin!(#peri, #pin_name, #pf); }), + // ("uart", "RTS") => Some(quote! { impl_uart_rts_pin!(#peri, #pin_name, #pf); }), + _ => None, + }; + + if let Some(tokens) = tokens { + impls.push(tokens); + } + } + } + + quote! { + #(#impls)* } } diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 1191b1010..f13245453 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -8,6 +8,25 @@ pub(crate) mod fmt; pub mod gpio; pub mod timer; +/// Operating modes for peripherals. +pub mod mode { + trait SealedMode {} + + /// Operating mode for a peripheral. + #[allow(private_bounds)] + pub trait Mode: SealedMode {} + + /// Blocking mode. + pub struct Blocking; + impl SealedMode for Blocking {} + impl Mode for Blocking {} + + /// Async mode. + pub struct Async; + impl SealedMode for Async {} + impl Mode for Async {} +} + #[cfg(feature = "_time-driver")] mod time_driver; diff --git a/embassy-mspm0/src/time_driver.rs b/embassy-mspm0/src/time_driver.rs index 937ce58d4..e80e89e55 100644 --- a/embassy-mspm0/src/time_driver.rs +++ b/embassy-mspm0/src/time_driver.rs @@ -12,6 +12,9 @@ use mspm0_metapac::tim::{Counterregs16, Tim}; use crate::peripherals; use crate::timer::SealedTimer; +#[cfg(any(time_driver_timg12, time_driver_timg13))] +compile_error!("TIMG12 and TIMG13 are not supported by the time driver yet"); + // Currently TIMG12 and TIMG13 are excluded because those are 32-bit timers. #[cfg(time_driver_timg0)] type T = peripherals::TIMG0; From 73c0bad8ad398c072215c8ff4382dffbe1a6a057 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Sat, 22 Mar 2025 19:27:52 -0500 Subject: [PATCH 23/44] mspm0: remove todo comment about pin names with slash these are now gone from metapac --- embassy-mspm0/build.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 9025c337a..39d8b2f8a 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs @@ -135,9 +135,6 @@ fn get_singletons(cfgs: &mut common::CfgSet) -> Vec { }); } - // TODO: Remove `/` signals from metapac (PA1/NRST on C110x for example) - singletons.retain(|s| !s.name.contains('/')); - singletons.sort_by(|a, b| a.name.cmp(&b.name)); singletons } @@ -403,11 +400,6 @@ fn generate_pin_trait_impls() -> TokenStream { for peripheral in METADATA.peripherals { for pin in peripheral.pins { - // TODO: Remove `/` signals from metapac (PA1/NRST on C110x for example) - if pin.pin.contains('/') { - continue; - } - let key = (peripheral.kind, pin.signal); let pin_name = format_ident!("{}", pin.pin); From 15394ae5fa9b8e3490fa7a600382ef549bff8f02 Mon Sep 17 00:00:00 2001 From: elagil Date: Mon, 24 Mar 2025 19:49:44 +0100 Subject: [PATCH 24/44] fix(usb): blocking wait --- embassy-stm32/src/usb/usb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index f050c00ce..6682374d3 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -895,7 +895,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { // Software should ensure that a small delay is included before accessing the SRAM contents. This delay should be // 800 ns in Full Speed mode and 6.4 μs in Low Speed mode. #[cfg(stm32h5)] - embassy_time::Timer::after_nanos(800).await; + embassy_time::block_for(embassy_time::Duration::from_nanos(800)); RX_COMPLETE[index].store(false, Ordering::Relaxed); From eff9168846df1b0b4fa2be75e061c63c2bb8c942 Mon Sep 17 00:00:00 2001 From: Bailey Quarters Date: Mon, 24 Mar 2025 19:53:36 +0100 Subject: [PATCH 25/44] Make CDC ACM state constructor `const` --- embassy-usb/src/class/cdc_acm.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index c5b1a56fe..ea9d9fb7b 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -47,10 +47,10 @@ impl<'a> Default for State<'a> { impl<'a> State<'a> { /// Create a new `State`. - pub fn new() -> Self { + pub const fn new() -> Self { Self { control: MaybeUninit::uninit(), - shared: ControlShared::default(), + shared: ControlShared::new(), } } } @@ -92,6 +92,12 @@ struct ControlShared { impl Default for ControlShared { fn default() -> Self { + Self::new() + } +} + +impl ControlShared { + const fn new() -> Self { ControlShared { dtr: AtomicBool::new(false), rts: AtomicBool::new(false), @@ -105,9 +111,7 @@ impl Default for ControlShared { changed: AtomicBool::new(false), } } -} -impl ControlShared { fn changed(&self) -> impl Future + '_ { poll_fn(|cx| { if self.changed.load(Ordering::Relaxed) { From 3e63a2e5df6e720c1582e32492d3d9302e34bc29 Mon Sep 17 00:00:00 2001 From: John Kjellberg Date: Tue, 25 Mar 2025 11:10:51 +0100 Subject: [PATCH 26/44] Clarified ADC API documentation for some STM32s. --- embassy-stm32/src/adc/v3.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index fc20974dd..7a608a44e 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -262,6 +262,9 @@ impl<'d, T: Instance> Adc<'d, T> { /// /// `sequence` iterator and `readings` must have the same length. /// + /// Note: The order of values in `readings` is defined by the pin ADC + /// channel number and not the pin order in `sequence`. + /// /// Example /// ```rust,ignore /// use embassy_stm32::adc::{Adc, AdcChannel} From f007b53db3b850e1186f9cde26160951b14ba2e7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 25 Mar 2025 20:33:47 +0100 Subject: [PATCH 27/44] stm32/dac: dedup pin and DMA traits, demacrofify. --- embassy-stm32/build.rs | 17 +-- embassy-stm32/src/dac/mod.rs | 220 ++++++++++++++++++----------------- 2 files changed, 115 insertions(+), 122 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index eb0437bc2..8ca79eadf 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1151,6 +1151,8 @@ fn main() { (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), + (("dac", "OUT1"), quote!(crate::dac::DacPin)), + (("dac", "OUT2"), quote!(crate::dac::DacPin)), ].into(); for p in METADATA.peripherals { @@ -1250,17 +1252,6 @@ fn main() { } } - // DAC is special - if regs.kind == "dac" { - let peri = format_ident!("{}", p.name); - let pin_name = format_ident!("{}", pin.pin); - let ch: u8 = pin.signal.strip_prefix("OUT").unwrap().parse().unwrap(); - - g.extend(quote! { - impl_dac_pin!( #peri, #pin_name, #ch); - }) - } - if regs.kind == "spdifrx" { let peri = format_ident!("{}", p.name); let pin_name = format_ident!("{}", pin.pin); @@ -1304,8 +1295,8 @@ fn main() { (("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)), (("octospi", "OCTOSPI1"), quote!(crate::ospi::OctoDma)), (("hspi", "HSPI1"), quote!(crate::hspi::HspiDma)), - (("dac", "CH1"), quote!(crate::dac::DacDma1)), - (("dac", "CH2"), quote!(crate::dac::DacDma2)), + (("dac", "CH1"), quote!(crate::dac::Dma)), + (("dac", "CH2"), quote!(crate::dac::Dma)), (("timer", "UP"), quote!(crate::timer::UpDma)), (("hash", "IN"), quote!(crate::hash::Dma)), (("cryp", "IN"), quote!(crate::cryp::DmaIn)), diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 8bba5ded0..4406f2960 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -100,20 +100,18 @@ pub enum ValueArray<'a> { /// /// If you want to use both channels, either together or independently, /// create a [`Dac`] first and use it to access each channel. -pub struct DacChannel<'d, T: Instance, const N: u8, DMA = NoDma> { - phantom: PhantomData<&'d mut T>, +pub struct DacChannel<'d, T: Instance, C: Channel, DMA = NoDma> { + phantom: PhantomData<&'d mut (T, C)>, #[allow(unused)] dma: PeripheralRef<'d, DMA>, } /// DAC channel 1 type alias. -pub type DacCh1<'d, T, DMA = NoDma> = DacChannel<'d, T, 1, DMA>; +pub type DacCh1<'d, T, DMA = NoDma> = DacChannel<'d, T, Ch1, DMA>; /// DAC channel 2 type alias. -pub type DacCh2<'d, T, DMA = NoDma> = DacChannel<'d, T, 2, DMA>; - -impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { - const IDX: usize = (N - 1) as usize; +pub type DacCh2<'d, T, DMA = NoDma> = DacChannel<'d, T, Ch2, DMA>; +impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral. /// /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. @@ -127,7 +125,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { pub fn new( _peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd, - pin: impl Peripheral

+ crate::gpio::Pin> + 'd, + pin: impl Peripheral

+ crate::gpio::Pin> + 'd, ) -> Self { into_ref!(dma, pin); pin.set_as_analog(); @@ -173,7 +171,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { pub fn set_enable(&mut self, on: bool) { critical_section::with(|_| { T::regs().cr().modify(|reg| { - reg.set_en(Self::IDX, on); + reg.set_en(C::IDX, on); }); }); } @@ -194,8 +192,8 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { pub fn set_trigger(&mut self, source: TriggerSel) { critical_section::with(|_| { T::regs().cr().modify(|reg| { - reg.set_en(Self::IDX, false); - reg.set_tsel(Self::IDX, source as u8); + reg.set_en(C::IDX, false); + reg.set_tsel(C::IDX, source as u8); }); }); } @@ -204,7 +202,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { pub fn set_triggering(&mut self, on: bool) { critical_section::with(|_| { T::regs().cr().modify(|reg| { - reg.set_ten(Self::IDX, on); + reg.set_ten(C::IDX, on); }); }); } @@ -212,7 +210,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { /// Software trigger this channel. pub fn trigger(&mut self) { T::regs().swtrigr().write(|reg| { - reg.set_swtrig(Self::IDX, true); + reg.set_swtrig(C::IDX, true); }); } @@ -223,10 +221,10 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { pub fn set_mode(&mut self, mode: Mode) { critical_section::with(|_| { T::regs().cr().modify(|reg| { - reg.set_en(Self::IDX, false); + reg.set_en(C::IDX, false); }); T::regs().mcr().modify(|reg| { - reg.set_mode(Self::IDX, mode.mode()); + reg.set_mode(C::IDX, mode.mode()); }); }); } @@ -237,15 +235,15 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { /// it will be output after the next trigger. pub fn set(&mut self, value: Value) { match value { - Value::Bit8(v) => T::regs().dhr8r(Self::IDX).write(|reg| reg.set_dhr(v)), - Value::Bit12Left(v) => T::regs().dhr12l(Self::IDX).write(|reg| reg.set_dhr(v)), - Value::Bit12Right(v) => T::regs().dhr12r(Self::IDX).write(|reg| reg.set_dhr(v)), + Value::Bit8(v) => T::regs().dhr8r(C::IDX).write(|reg| reg.set_dhr(v)), + Value::Bit12Left(v) => T::regs().dhr12l(C::IDX).write(|reg| reg.set_dhr(v)), + Value::Bit12Right(v) => T::regs().dhr12r(C::IDX).write(|reg| reg.set_dhr(v)), } } /// Read the current output value of the DAC. pub fn read(&self) -> u16 { - T::regs().dor(Self::IDX).read().dor() + T::regs().dor(C::IDX).read().dor() } /// Set HFSEL as appropriate for the current peripheral clock frequency. @@ -277,84 +275,75 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { }); } } + + /// Write `data` to this channel via DMA. + /// + /// To prevent delays or glitches when outputing a periodic waveform, the `circular` + /// flag can be set. This configures a circular DMA transfer that continually outputs + /// `data`. Note that for performance reasons in circular mode the transfer-complete + /// interrupt is disabled. + #[cfg(not(gpdma))] + pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) + where + DMA: Dma, + { + // Enable DAC and DMA + T::regs().cr().modify(|w| { + w.set_en(C::IDX, true); + w.set_dmaen(C::IDX, true); + }); + + let tx_request = self.dma.request(); + let dma_channel = &mut self.dma; + + let tx_options = crate::dma::TransferOptions { + circular, + half_transfer_ir: false, + complete_transfer_ir: !circular, + ..Default::default() + }; + + // Initiate the correct type of DMA transfer depending on what data is passed + let tx_f = match data { + ValueArray::Bit8(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr8r(C::IDX).as_ptr() as *mut u8, + tx_options, + ) + }, + ValueArray::Bit12Left(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr12l(C::IDX).as_ptr() as *mut u16, + tx_options, + ) + }, + ValueArray::Bit12Right(buf) => unsafe { + crate::dma::Transfer::new_write( + dma_channel, + tx_request, + buf, + T::regs().dhr12r(C::IDX).as_ptr() as *mut u16, + tx_options, + ) + }, + }; + + tx_f.await; + + T::regs().cr().modify(|w| { + w.set_en(C::IDX, false); + w.set_dmaen(C::IDX, false); + }); + } } -macro_rules! impl_dma_methods { - ($n:literal, $trait:ident) => { - impl<'d, T: Instance, DMA> DacChannel<'d, T, $n, DMA> - where - DMA: $trait, - { - /// Write `data` to this channel via DMA. - /// - /// To prevent delays or glitches when outputing a periodic waveform, the `circular` - /// flag can be set. This configures a circular DMA transfer that continually outputs - /// `data`. Note that for performance reasons in circular mode the transfer-complete - /// interrupt is disabled. - #[cfg(not(gpdma))] - pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) { - // Enable DAC and DMA - T::regs().cr().modify(|w| { - w.set_en(Self::IDX, true); - w.set_dmaen(Self::IDX, true); - }); - - let tx_request = self.dma.request(); - let dma_channel = &mut self.dma; - - let tx_options = crate::dma::TransferOptions { - circular, - half_transfer_ir: false, - complete_transfer_ir: !circular, - ..Default::default() - }; - - // Initiate the correct type of DMA transfer depending on what data is passed - let tx_f = match data { - ValueArray::Bit8(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr8r(Self::IDX).as_ptr() as *mut u8, - tx_options, - ) - }, - ValueArray::Bit12Left(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12l(Self::IDX).as_ptr() as *mut u16, - tx_options, - ) - }, - ValueArray::Bit12Right(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12r(Self::IDX).as_ptr() as *mut u16, - tx_options, - ) - }, - }; - - tx_f.await; - - T::regs().cr().modify(|w| { - w.set_en(Self::IDX, false); - w.set_dmaen(Self::IDX, false); - }); - } - } - }; -} - -impl_dma_methods!(1, DacDma1); -impl_dma_methods!(2, DacDma2); - -impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { +impl<'d, T: Instance, C: Channel, DMA> Drop for DacChannel<'d, T, C, DMA> { fn drop(&mut self) { rcc::disable::(); } @@ -371,8 +360,8 @@ impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { /// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split(); /// ``` pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { - ch1: DacChannel<'d, T, 1, DMACh1>, - ch2: DacChannel<'d, T, 2, DMACh2>, + ch1: DacChannel<'d, T, Ch1, DMACh1>, + ch2: DacChannel<'d, T, Ch2, DMACh2>, } impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { @@ -392,8 +381,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { _peri: impl Peripheral

+ 'd, dma_ch1: impl Peripheral

+ 'd, dma_ch2: impl Peripheral

+ 'd, - pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, - pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, + pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, + pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, ) -> Self { into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); pin_ch1.set_as_analog(); @@ -514,11 +503,30 @@ trait SealedInstance { /// DAC instance. #[allow(private_bounds)] pub trait Instance: SealedInstance + RccPeripheral + 'static {} -dma_trait!(DacDma1, Instance); -dma_trait!(DacDma2, Instance); -/// Marks a pin that can be used with the DAC -pub trait DacPin: crate::gpio::Pin + 'static {} +/// Channel 1 marker type. +pub enum Ch1 {} +/// Channel 2 marker type. +pub enum Ch2 {} + +trait SealedChannel { + const IDX: usize; +} +/// DAC channel trait. +#[allow(private_bounds)] +pub trait Channel: SealedChannel {} + +impl SealedChannel for Ch1 { + const IDX: usize = 0; +} +impl SealedChannel for Ch2 { + const IDX: usize = 1; +} +impl Channel for Ch1 {} +impl Channel for Ch2 {} + +dma_trait!(Dma, Instance, Channel); +pin_trait!(DacPin, Instance, Channel); foreach_peripheral!( (dac, $inst:ident) => { @@ -531,9 +539,3 @@ foreach_peripheral!( impl crate::dac::Instance for peripherals::$inst {} }; ); - -macro_rules! impl_dac_pin { - ($inst:ident, $pin:ident, $ch:expr) => { - impl crate::dac::DacPin for crate::peripherals::$pin {} - }; -} From 73ec3a7506f48bc76bc462a83213992436b55eb7 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 25 Mar 2025 21:31:28 +0100 Subject: [PATCH 28/44] stm32/dac: remove DMA generic params. --- embassy-stm32/src/dac/mod.rs | 332 +++++++++++++++++----------- examples/stm32f4/src/bin/dac.rs | 3 +- examples/stm32h7/src/bin/dac.rs | 3 +- examples/stm32h7/src/bin/dac_dma.rs | 7 +- examples/stm32l4/src/bin/dac.rs | 3 +- examples/stm32l4/src/bin/dac_dma.rs | 7 +- examples/stm32u0/src/bin/dac.rs | 3 +- tests/stm32/src/bin/dac.rs | 3 +- tests/stm32/src/bin/dac_l1.rs | 3 +- 9 files changed, 215 insertions(+), 149 deletions(-) diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 4406f2960..7a63dc5fc 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -3,9 +3,10 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::into_ref; -use crate::dma::NoDma; +use crate::dma::ChannelAndRequest; +use crate::mode::{Async, Blocking, Mode as PeriMode}; #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] use crate::pac::dac; use crate::rcc::{self, RccPeripheral}; @@ -100,22 +101,20 @@ pub enum ValueArray<'a> { /// /// If you want to use both channels, either together or independently, /// create a [`Dac`] first and use it to access each channel. -pub struct DacChannel<'d, T: Instance, C: Channel, DMA = NoDma> { - phantom: PhantomData<&'d mut (T, C)>, +pub struct DacChannel<'d, T: Instance, C: Channel, M: PeriMode> { + phantom: PhantomData<&'d mut (T, C, M)>, #[allow(unused)] - dma: PeripheralRef<'d, DMA>, + dma: Option>, } /// DAC channel 1 type alias. -pub type DacCh1<'d, T, DMA = NoDma> = DacChannel<'d, T, Ch1, DMA>; +pub type DacCh1<'d, T, M> = DacChannel<'d, T, Ch1, M>; /// DAC channel 2 type alias. -pub type DacCh2<'d, T, DMA = NoDma> = DacChannel<'d, T, Ch2, DMA>; +pub type DacCh2<'d, T, M> = DacChannel<'d, T, Ch2, M>; -impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { +impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> { /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral. /// - /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. - /// /// The channel is enabled on creation and begin to drive the output pin. /// Note that some methods, such as `set_trigger()` and `set_mode()`, will /// disable the channel; you must re-enable it with `enable()`. @@ -123,21 +122,18 @@ impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. pub fn new( - _peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, - pin: impl Peripheral

+ crate::gpio::Pin> + 'd, + peri: impl Peripheral

+ 'd, + dma: impl Peripheral

> + 'd, + pin: impl Peripheral

> + 'd, ) -> Self { into_ref!(dma, pin); pin.set_as_analog(); - rcc::enable_and_reset::(); - let mut dac = Self { - phantom: PhantomData, - dma, - }; - #[cfg(any(dac_v5, dac_v6, dac_v7))] - dac.set_hfsel(); - dac.enable(); - dac + Self::new_inner( + peri, + new_dma!(dma), + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + Mode::NormalExternalBuffered, + ) } /// Create a new `DacChannel` instance where the external output pin is not used, @@ -148,13 +144,99 @@ impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the /// channel; you must re-enable it with `enable()`. /// - /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. + /// By default, triggering is disabled, but it can be enabled using + /// [`DacChannel::set_trigger()`]. + #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] + pub fn new_internal(peri: impl Peripheral

+ 'd, dma: impl Peripheral

> + 'd) -> Self { + into_ref!(dma); + Self::new_inner(peri, new_dma!(dma), Mode::NormalInternalUnbuffered) + } + + /// Write `data` to this channel via DMA. + /// + /// To prevent delays or glitches when outputing a periodic waveform, the `circular` + /// flag can be set. This configures a circular DMA transfer that continually outputs + /// `data`. Note that for performance reasons in circular mode the transfer-complete + /// interrupt is disabled. + #[cfg(not(gpdma))] + pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) { + // Enable DAC and DMA + T::regs().cr().modify(|w| { + w.set_en(C::IDX, true); + w.set_dmaen(C::IDX, true); + }); + + let dma = self.dma.as_mut().unwrap(); + + let tx_options = crate::dma::TransferOptions { + circular, + half_transfer_ir: false, + complete_transfer_ir: !circular, + ..Default::default() + }; + + // Initiate the correct type of DMA transfer depending on what data is passed + let tx_f = match data { + ValueArray::Bit8(buf) => unsafe { dma.write(buf, T::regs().dhr8r(C::IDX).as_ptr() as *mut u8, tx_options) }, + ValueArray::Bit12Left(buf) => unsafe { + dma.write(buf, T::regs().dhr12l(C::IDX).as_ptr() as *mut u16, tx_options) + }, + ValueArray::Bit12Right(buf) => unsafe { + dma.write(buf, T::regs().dhr12r(C::IDX).as_ptr() as *mut u16, tx_options) + }, + }; + + tx_f.await; + + T::regs().cr().modify(|w| { + w.set_en(C::IDX, false); + w.set_dmaen(C::IDX, false); + }); + } +} + +impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> { + /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral. + /// + /// The channel is enabled on creation and begin to drive the output pin. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will + /// disable the channel; you must re-enable it with `enable()`. + /// + /// By default, triggering is disabled, but it can be enabled using + /// [`DacChannel::set_trigger()`]. + pub fn new_blocking(peri: impl Peripheral

+ 'd, pin: impl Peripheral

> + 'd) -> Self { + into_ref!(pin); + pin.set_as_analog(); + Self::new_inner( + peri, + None, + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + Mode::NormalExternalBuffered, + ) + } + + /// Create a new `DacChannel` instance where the external output pin is not used, + /// so the DAC can only be used to generate internal signals. + /// The GPIO pin is therefore available to be used for other functions. + /// + /// The channel is set to [`Mode::NormalInternalUnbuffered`] and enabled on creation. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the + /// channel; you must re-enable it with `enable()`. /// /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] - pub fn new_internal(_peri: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd) -> Self { - into_ref!(dma); + pub fn new_internal_blocking(peri: impl Peripheral

+ 'd) -> Self { + Self::new_inner(peri, None, Mode::NormalInternalUnbuffered) + } +} + +impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> { + fn new_inner( + _peri: impl Peripheral

+ 'd, + dma: Option>, + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, + ) -> Self { rcc::enable_and_reset::(); let mut dac = Self { phantom: PhantomData, @@ -162,7 +244,8 @@ impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { }; #[cfg(any(dac_v5, dac_v6, dac_v7))] dac.set_hfsel(); - dac.set_mode(Mode::NormalInternalUnbuffered); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + dac.set_mode(mode); dac.enable(); dac } @@ -275,75 +358,9 @@ impl<'d, T: Instance, C: Channel, DMA> DacChannel<'d, T, C, DMA> { }); } } - - /// Write `data` to this channel via DMA. - /// - /// To prevent delays or glitches when outputing a periodic waveform, the `circular` - /// flag can be set. This configures a circular DMA transfer that continually outputs - /// `data`. Note that for performance reasons in circular mode the transfer-complete - /// interrupt is disabled. - #[cfg(not(gpdma))] - pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) - where - DMA: Dma, - { - // Enable DAC and DMA - T::regs().cr().modify(|w| { - w.set_en(C::IDX, true); - w.set_dmaen(C::IDX, true); - }); - - let tx_request = self.dma.request(); - let dma_channel = &mut self.dma; - - let tx_options = crate::dma::TransferOptions { - circular, - half_transfer_ir: false, - complete_transfer_ir: !circular, - ..Default::default() - }; - - // Initiate the correct type of DMA transfer depending on what data is passed - let tx_f = match data { - ValueArray::Bit8(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr8r(C::IDX).as_ptr() as *mut u8, - tx_options, - ) - }, - ValueArray::Bit12Left(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12l(C::IDX).as_ptr() as *mut u16, - tx_options, - ) - }, - ValueArray::Bit12Right(buf) => unsafe { - crate::dma::Transfer::new_write( - dma_channel, - tx_request, - buf, - T::regs().dhr12r(C::IDX).as_ptr() as *mut u16, - tx_options, - ) - }, - }; - - tx_f.await; - - T::regs().cr().modify(|w| { - w.set_en(C::IDX, false); - w.set_dmaen(C::IDX, false); - }); - } } -impl<'d, T: Instance, C: Channel, DMA> Drop for DacChannel<'d, T, C, DMA> { +impl<'d, T: Instance, C: Channel, M: PeriMode> Drop for DacChannel<'d, T, C, M> { fn drop(&mut self) { rcc::disable::(); } @@ -357,14 +374,14 @@ impl<'d, T: Instance, C: Channel, DMA> Drop for DacChannel<'d, T, C, DMA> { /// /// ```ignore /// // Pins may need to be changed for your specific device. -/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split(); +/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new_blocking(p.DAC1, p.PA4, p.PA5).split(); /// ``` -pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { - ch1: DacChannel<'d, T, Ch1, DMACh1>, - ch2: DacChannel<'d, T, Ch2, DMACh2>, +pub struct Dac<'d, T: Instance, M: PeriMode> { + ch1: DacChannel<'d, T, Ch1, M>, + ch2: DacChannel<'d, T, Ch2, M>, } -impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { +impl<'d, T: Instance> Dac<'d, T, Async> { /// Create a new `Dac` instance, consuming the underlying DAC peripheral. /// /// This struct allows you to access both channels of the DAC, where available. You can either @@ -378,37 +395,22 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// method on the underlying channels. pub fn new( - _peri: impl Peripheral

+ 'd, - dma_ch1: impl Peripheral

+ 'd, - dma_ch2: impl Peripheral

+ 'd, + peri: impl Peripheral

+ 'd, + dma_ch1: impl Peripheral

> + 'd, + dma_ch2: impl Peripheral

> + 'd, pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, ) -> Self { into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); - - // Enable twice to increment the DAC refcount for each channel. - rcc::enable_and_reset::(); - rcc::enable_and_reset::(); - - let mut ch1 = DacCh1 { - phantom: PhantomData, - dma: dma_ch1, - }; - #[cfg(any(dac_v5, dac_v6, dac_v7))] - ch1.set_hfsel(); - ch1.enable(); - - let mut ch2 = DacCh2 { - phantom: PhantomData, - dma: dma_ch2, - }; - #[cfg(any(dac_v5, dac_v6, dac_v7))] - ch2.set_hfsel(); - ch2.enable(); - - Self { ch1, ch2 } + Self::new_inner( + peri, + new_dma!(dma_ch1), + new_dma!(dma_ch2), + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + Mode::NormalExternalBuffered, + ) } /// Create a new `Dac` instance where the external output pins are not used, @@ -427,11 +429,77 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { /// method on the underlying channels. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] pub fn new_internal( - _peri: impl Peripheral

+ 'd, - dma_ch1: impl Peripheral

+ 'd, - dma_ch2: impl Peripheral

+ 'd, + peri: impl Peripheral

+ 'd, + dma_ch1: impl Peripheral

> + 'd, + dma_ch2: impl Peripheral

> + 'd, ) -> Self { into_ref!(dma_ch1, dma_ch2); + Self::new_inner( + peri, + new_dma!(dma_ch1), + new_dma!(dma_ch2), + Mode::NormalInternalUnbuffered, + ) + } +} + +impl<'d, T: Instance> Dac<'d, T, Blocking> { + /// Create a new `Dac` instance, consuming the underlying DAC peripheral. + /// + /// This struct allows you to access both channels of the DAC, where available. You can either + /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use + /// the two channels together. + /// + /// The channels are enabled on creation and begin to drive their output pins. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will + /// disable the channel; you must re-enable them with `enable()`. + /// + /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` + /// method on the underlying channels. + pub fn new_blocking( + peri: impl Peripheral

+ 'd, + pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, + pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, + ) -> Self { + into_ref!(pin_ch1, pin_ch2); + pin_ch1.set_as_analog(); + pin_ch2.set_as_analog(); + Self::new_inner( + peri, + None, + None, + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + Mode::NormalExternalBuffered, + ) + } + + /// Create a new `Dac` instance where the external output pins are not used, + /// so the DAC can only be used to generate internal signals but the GPIO + /// pins remain available for other functions. + /// + /// This struct allows you to access both channels of the DAC, where available. You can either + /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use the two + /// channels together. + /// + /// The channels are set to [`Mode::NormalInternalUnbuffered`] and enabled on creation. + /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the + /// channel; you must re-enable them with `enable()`. + /// + /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` + /// method on the underlying channels. + #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] + pub fn new_internal(peri: impl Peripheral

+ 'd) -> Self { + Self::new_inner(peri, None, None, Mode::NormalInternalUnbuffered) + } +} + +impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> { + fn new_inner( + _peri: impl Peripheral

+ 'd, + dma_ch1: Option>, + dma_ch2: Option>, + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, + ) -> Self { // Enable twice to increment the DAC refcount for each channel. rcc::enable_and_reset::(); rcc::enable_and_reset::(); @@ -442,7 +510,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { }; #[cfg(any(dac_v5, dac_v6, dac_v7))] ch1.set_hfsel(); - ch1.set_mode(Mode::NormalInternalUnbuffered); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + ch1.set_mode(mode); ch1.enable(); let mut ch2 = DacCh2 { @@ -451,7 +520,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { }; #[cfg(any(dac_v5, dac_v6, dac_v7))] ch2.set_hfsel(); - ch2.set_mode(Mode::NormalInternalUnbuffered); + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] + ch2.set_mode(mode); ch2.enable(); Self { ch1, ch2 } @@ -460,17 +530,17 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { /// Split this `Dac` into separate channels. /// /// You can access and move the channels around separately after splitting. - pub fn split(self) -> (DacCh1<'d, T, DMACh1>, DacCh2<'d, T, DMACh2>) { + pub fn split(self) -> (DacCh1<'d, T, M>, DacCh2<'d, T, M>) { (self.ch1, self.ch2) } /// Temporarily access channel 1. - pub fn ch1(&mut self) -> &mut DacCh1<'d, T, DMACh1> { + pub fn ch1(&mut self) -> &mut DacCh1<'d, T, M> { &mut self.ch1 } /// Temporarily access channel 2. - pub fn ch2(&mut self) -> &mut DacCh2<'d, T, DMACh2> { + pub fn ch2(&mut self) -> &mut DacCh2<'d, T, M> { &mut self.ch2 } diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index dd2a45718..68fe6cabd 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs @@ -4,7 +4,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -12,7 +11,7 @@ async fn main(_spawner: Spawner) -> ! { let p = embassy_stm32::init(Default::default()); info!("Hello World, dude!"); - let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); + let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4); loop { for v in 0..=255 { diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index a6f969aba..27df80336 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs @@ -4,7 +4,6 @@ use cortex_m_rt::entry; use defmt::*; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use embassy_stm32::Config; use {defmt_rtt as _, panic_probe as _}; @@ -44,7 +43,7 @@ fn main() -> ! { } let p = embassy_stm32::init(config); - let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); + let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4); loop { for v in 0..=255 { diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 3a9887e3c..98c9f1e90 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -4,8 +4,9 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; +use embassy_stm32::mode::Async; use embassy_stm32::pac::timer::vals::Mms; -use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; +use embassy_stm32::peripherals::{DAC1, TIM6, TIM7}; use embassy_stm32::rcc::frequency; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Timer; @@ -56,7 +57,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { +async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", frequency::()); @@ -99,7 +100,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { } #[embassy_executor::task] -async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { +async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", frequency::()); diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs index fdbf1d374..50db0e082 100644 --- a/examples/stm32l4/src/bin/dac.rs +++ b/examples/stm32l4/src/bin/dac.rs @@ -3,7 +3,6 @@ use defmt::*; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] @@ -11,7 +10,7 @@ fn main() -> ! { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); + let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4); loop { for v in 0..=255 { diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index d01b016c0..6c9219080 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -4,8 +4,9 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; +use embassy_stm32::mode::Async; use embassy_stm32::pac::timer::vals::Mms; -use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; +use embassy_stm32::peripherals::{DAC1, TIM6, TIM7}; use embassy_stm32::rcc::frequency; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Timer; @@ -27,7 +28,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { +async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", frequency::()); @@ -70,7 +71,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { } #[embassy_executor::task] -async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { +async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", frequency::()); diff --git a/examples/stm32u0/src/bin/dac.rs b/examples/stm32u0/src/bin/dac.rs index fdbf1d374..50db0e082 100644 --- a/examples/stm32u0/src/bin/dac.rs +++ b/examples/stm32u0/src/bin/dac.rs @@ -3,7 +3,6 @@ use defmt::*; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] @@ -11,7 +10,7 @@ fn main() -> ! { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); + let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4); loop { for v in 0..=255 { diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs index 88e661525..d34bbb255 100644 --- a/tests/stm32/src/bin/dac.rs +++ b/tests/stm32/src/bin/dac.rs @@ -12,7 +12,6 @@ use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use embassy_time::Timer; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -27,7 +26,7 @@ async fn main(_spawner: Spawner) { let dac_pin = peri!(p, DAC_PIN); let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; - let mut dac = DacCh1::new(dac, NoDma, dac_pin); + let mut dac = DacCh1::new_blocking(dac, dac_pin); let mut adc = Adc::new(adc); #[cfg(feature = "stm32h755zi")] diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs index 925db617d..e6400f28e 100644 --- a/tests/stm32/src/bin/dac_l1.rs +++ b/tests/stm32/src/bin/dac_l1.rs @@ -12,7 +12,6 @@ use defmt::assert; use embassy_executor::Spawner; use embassy_stm32::adc::Adc; use embassy_stm32::dac::{DacCh1, Value}; -use embassy_stm32::dma::NoDma; use embassy_stm32::{bind_interrupts, peripherals}; use embassy_time::Timer; use micromath::F32Ext; @@ -32,7 +31,7 @@ async fn main(_spawner: Spawner) { let dac_pin = peri!(p, DAC_PIN); let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; - let mut dac = DacCh1::new(dac, NoDma, dac_pin); + let mut dac = DacCh1::new_blocking(dac, dac_pin); let mut adc = Adc::new(adc, Irqs); #[cfg(feature = "stm32h755zi")] From 9a0afa7bf4821d89b56265b67b7c76be382046ac Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 25 Mar 2025 21:43:47 +0100 Subject: [PATCH 29/44] stm32/sdmmc: remove DMA generic param. --- embassy-stm32/src/macros.rs | 12 ++++ embassy-stm32/src/sdmmc/mod.rs | 104 +++++++++++++++++---------------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index ae53deb08..000773e2d 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs @@ -85,6 +85,18 @@ macro_rules! dma_trait_impl { }; } +#[allow(unused)] +macro_rules! new_dma_nonopt { + ($name:ident) => {{ + let dma = $name.into_ref(); + let request = dma.request(); + crate::dma::ChannelAndRequest { + channel: dma.map_into(), + request, + } + }}; +} + macro_rules! new_dma { ($name:ident) => {{ let dma = $name.into_ref(); diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 8af2f8381..d8671caf7 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -12,7 +12,8 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; -use crate::dma::NoDma; +#[cfg(sdmmc_v1)] +use crate::dma::ChannelAndRequest; #[cfg(gpio_v2)] use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; @@ -301,10 +302,10 @@ impl Default for Config { } /// Sdmmc device -pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma = NoDma> { +pub struct Sdmmc<'d, T: Instance> { _peri: PeripheralRef<'d, T>, - #[allow(unused)] - dma: PeripheralRef<'d, Dma>, + #[cfg(sdmmc_v1)] + dma: ChannelAndRequest<'d>, clk: PeripheralRef<'d, AnyPin>, cmd: PeripheralRef<'d, AnyPin>, @@ -334,18 +335,18 @@ const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh const DATA_AF: AfType = CMD_AF; #[cfg(sdmmc_v1)] -impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { +impl<'d, T: Instance> Sdmmc<'d, T> { /// Create a new SDMMC driver, with 1 data lane. pub fn new_1bit( sdmmc: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, - dma: impl Peripheral

+ 'd, + dma: impl Peripheral

> + 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, d0: impl Peripheral

> + 'd, config: Config, ) -> Self { - into_ref!(clk, cmd, d0); + into_ref!(dma, clk, cmd, d0); critical_section::with(|_| { clk.set_as_af(clk.af_num(), CLK_AF); @@ -355,7 +356,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { Self::new_inner( sdmmc, - dma, + new_dma_nonopt!(dma), clk.map_into(), cmd.map_into(), d0.map_into(), @@ -370,7 +371,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { pub fn new_4bit( sdmmc: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, - dma: impl Peripheral

+ 'd, + dma: impl Peripheral

> + 'd, clk: impl Peripheral

> + 'd, cmd: impl Peripheral

> + 'd, d0: impl Peripheral

> + 'd, @@ -392,7 +393,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { Self::new_inner( sdmmc, - dma, + new_dma_nonopt!(dma), clk.map_into(), cmd.map_into(), d0.map_into(), @@ -405,7 +406,7 @@ impl<'d, T: Instance, Dma: SdmmcDma> Sdmmc<'d, T, Dma> { } #[cfg(sdmmc_v2)] -impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { +impl<'d, T: Instance> Sdmmc<'d, T> { /// Create a new SDMMC driver, with 1 data lane. pub fn new_1bit( sdmmc: impl Peripheral

+ 'd, @@ -425,7 +426,6 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { Self::new_inner( sdmmc, - NoDma.into_ref(), clk.map_into(), cmd.map_into(), d0.map_into(), @@ -461,7 +461,6 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { Self::new_inner( sdmmc, - NoDma.into_ref(), clk.map_into(), cmd.map_into(), d0.map_into(), @@ -473,10 +472,10 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { } } -impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { +impl<'d, T: Instance> Sdmmc<'d, T> { fn new_inner( sdmmc: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>, clk: PeripheralRef<'d, AnyPin>, cmd: PeripheralRef<'d, AnyPin>, d0: PeripheralRef<'d, AnyPin>, @@ -485,7 +484,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { d3: Option>, config: Config, ) -> Self { - into_ref!(sdmmc, dma); + into_ref!(sdmmc); rcc::enable_and_reset::(); @@ -514,6 +513,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { Self { _peri: sdmmc, + #[cfg(sdmmc_v1)] dma, clk, @@ -567,7 +567,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { #[allow(unused_variables)] fn prepare_datapath_read<'a>( config: &Config, - dma: &'a mut PeripheralRef<'d, Dma>, + #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>, buffer: &'a mut [u32], length_bytes: u32, block_size: u8, @@ -583,16 +583,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { regs.dlenr().write(|w| w.set_datalength(length_bytes)); #[cfg(sdmmc_v1)] - let transfer = unsafe { - let request = dma.request(); - Transfer::new_read( - dma, - request, - regs.fifor().as_ptr() as *mut u32, - buffer, - DMA_TRANSFER_OPTIONS, - ) - }; + let transfer = unsafe { dma.read(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) }; #[cfg(sdmmc_v2)] let transfer = { regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32)); @@ -632,14 +623,8 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { #[cfg(sdmmc_v1)] let transfer = unsafe { - let request = self.dma.request(); - Transfer::new_write( - &mut self.dma, - request, - buffer, - regs.fifor().as_ptr() as *mut u32, - DMA_TRANSFER_OPTIONS, - ) + self.dma + .write(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS) }; #[cfg(sdmmc_v2)] let transfer = { @@ -735,7 +720,14 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { let regs = T::regs(); let on_drop = OnDrop::new(|| Self::on_drop()); - let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, status.as_mut(), 64, 6); + let transfer = Self::prepare_datapath_read( + &self.config, + #[cfg(sdmmc_v1)] + &mut self.dma, + status.as_mut(), + 64, + 6, + ); InterruptHandler::::data_interrupts(true); Self::cmd(Cmd::cmd6(set_function), true)?; // CMD6 @@ -821,7 +813,14 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { let regs = T::regs(); let on_drop = OnDrop::new(|| Self::on_drop()); - let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, status.as_mut(), 64, 6); + let transfer = Self::prepare_datapath_read( + &self.config, + #[cfg(sdmmc_v1)] + &mut self.dma, + status.as_mut(), + 64, + 6, + ); InterruptHandler::::data_interrupts(true); Self::cmd(Cmd::card_status(0), true)?; @@ -924,7 +923,14 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { let regs = T::regs(); let on_drop = OnDrop::new(|| Self::on_drop()); - let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, scr, 8, 3); + let transfer = Self::prepare_datapath_read( + &self.config, + #[cfg(sdmmc_v1)] + &mut self.dma, + scr, + 8, + 3, + ); InterruptHandler::::data_interrupts(true); Self::cmd(Cmd::cmd51(), true)?; @@ -1214,7 +1220,14 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { let regs = T::regs(); let on_drop = OnDrop::new(|| Self::on_drop()); - let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, buffer, 512, 9); + let transfer = Self::prepare_datapath_read( + &self.config, + #[cfg(sdmmc_v1)] + &mut self.dma, + buffer, + 512, + 9, + ); InterruptHandler::::data_interrupts(true); Self::cmd(Cmd::read_single_block(address), true)?; @@ -1347,7 +1360,7 @@ impl<'d, T: Instance, Dma: SdmmcDma + 'd> Sdmmc<'d, T, Dma> { } } -impl<'d, T: Instance, Dma: SdmmcDma + 'd> Drop for Sdmmc<'d, T, Dma> { +impl<'d, T: Instance> Drop for Sdmmc<'d, T> { fn drop(&mut self) { T::Interrupt::disable(); Self::on_drop(); @@ -1484,15 +1497,6 @@ pin_trait!(D7Pin, Instance); #[cfg(sdmmc_v1)] dma_trait!(SdmmcDma, Instance); -/// DMA instance trait. -/// -/// This is only implemented for `NoDma`, since SDMMCv2 has DMA built-in, instead of -/// using ST's system-wide DMA peripheral. -#[cfg(sdmmc_v2)] -pub trait SdmmcDma {} -#[cfg(sdmmc_v2)] -impl SdmmcDma for NoDma {} - foreach_peripheral!( (sdmmc, $inst:ident) => { impl SealedInstance for peripherals::$inst { @@ -1512,7 +1516,7 @@ foreach_peripheral!( }; ); -impl<'d, T: Instance, Dma: SdmmcDma + 'd> block_device_driver::BlockDevice<512> for Sdmmc<'d, T, Dma> { +impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> { type Error = Error; type Align = aligned::A4; From db86aba841851d1a25f9bec7a1686db34c94c885 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 25 Mar 2025 21:57:37 +0100 Subject: [PATCH 30/44] stm32/hash: remove DMA generic param. --- embassy-stm32/src/dma/util.rs | 6 +- embassy-stm32/src/hash/mod.rs | 286 ++++++++++++++++++---------------- embassy-stm32/src/spi/mod.rs | 2 +- tests/stm32/src/bin/hash.rs | 3 +- 4 files changed, 153 insertions(+), 144 deletions(-) diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs index 5aaca57c9..5e1158182 100644 --- a/embassy-stm32/src/dma/util.rs +++ b/embassy-stm32/src/dma/util.rs @@ -39,10 +39,10 @@ impl<'d> ChannelAndRequest<'d> { Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options) } - pub unsafe fn write_raw<'a, W: Word>( + pub unsafe fn write_raw<'a, MW: Word, PW: Word>( &'a mut self, - buf: *const [W], - peri_addr: *mut W, + buf: *const [MW], + peri_addr: *mut PW, options: TransferOptions, ) -> Transfer<'a> { Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options) diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs index 3c2125498..3951e9d63 100644 --- a/embassy-stm32/src/hash/mod.rs +++ b/embassy-stm32/src/hash/mod.rs @@ -12,10 +12,12 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use stm32_metapac::hash::regs::*; -use crate::dma::NoDma; #[cfg(hash_v2)] -use crate::dma::Transfer; +use crate::dma::ChannelAndRequest; use crate::interrupt::typelevel::Interrupt; +#[cfg(hash_v2)] +use crate::mode::Async; +use crate::mode::{Blocking, Mode}; use crate::peripherals::HASH; use crate::{interrupt, pac, peripherals, rcc, Peripheral}; @@ -116,24 +118,26 @@ pub struct Context<'c> { type HmacKey<'k> = Option<&'k [u8]>; /// HASH driver. -pub struct Hash<'d, T: Instance, D = NoDma> { +pub struct Hash<'d, T: Instance, M: Mode> { _peripheral: PeripheralRef<'d, T>, - #[allow(dead_code)] - dma: PeripheralRef<'d, D>, + _phantom: PhantomData, + #[cfg(hash_v2)] + dma: Option>, } -impl<'d, T: Instance, D> Hash<'d, T, D> { +impl<'d, T: Instance> Hash<'d, T, Blocking> { /// Instantiates, resets, and enables the HASH peripheral. - pub fn new( + pub fn new_blocking( peripheral: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peripheral, dma); + into_ref!(peripheral); let instance = Self { _peripheral: peripheral, - dma: dma, + _phantom: PhantomData, + #[cfg(hash_v2)] + dma: None, }; T::Interrupt::unpend(); @@ -141,7 +145,9 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { instance } +} +impl<'d, T: Instance, M: Mode> Hash<'d, T, M> { /// Starts computation of a new hash and returns the saved peripheral state. pub fn start<'c>(&mut self, algorithm: Algorithm, format: DataType, key: HmacKey<'c>) -> Context<'c> { // Define a context for this new computation. @@ -282,14 +288,136 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { self.store_context(ctx); } + /// Computes a digest for the given context. + /// The digest buffer must be large enough to accomodate a digest for the selected algorithm. + /// The largest returned digest size is 128 bytes for SHA-512. + /// Panics if the supplied digest buffer is too short. + pub fn finish_blocking<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize { + // Restore the peripheral state. + self.load_context(&ctx); + + // Hash the leftover bytes, if any. + self.accumulate_blocking(&ctx.buffer[0..ctx.buflen]); + ctx.buflen = 0; + + //Start the digest calculation. + T::regs().str().write(|w| w.set_dcal(true)); + + // Load the HMAC key if provided. + if let Some(key) = ctx.key { + while !T::regs().sr().read().dinis() {} + self.accumulate_blocking(key); + T::regs().str().write(|w| w.set_dcal(true)); + } + + // Block until digest computation is complete. + while !T::regs().sr().read().dcis() {} + + // Return the digest. + let digest_words = match ctx.algo { + Algorithm::SHA1 => 5, + #[cfg(any(hash_v1, hash_v2, hash_v4))] + Algorithm::MD5 => 4, + Algorithm::SHA224 => 7, + Algorithm::SHA256 => 8, + #[cfg(hash_v3)] + Algorithm::SHA384 => 12, + #[cfg(hash_v3)] + Algorithm::SHA512_224 => 7, + #[cfg(hash_v3)] + Algorithm::SHA512_256 => 8, + #[cfg(hash_v3)] + Algorithm::SHA512 => 16, + }; + + let digest_len_bytes = digest_words * 4; + // Panics if the supplied digest buffer is too short. + if digest.len() < digest_len_bytes { + panic!("Digest buffer must be at least {} bytes long.", digest_words * 4); + } + + let mut i = 0; + while i < digest_words { + let word = T::regs().hr(i).read(); + digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice()); + i += 1; + } + digest_len_bytes + } + + /// Push data into the hash core. + fn accumulate_blocking(&mut self, input: &[u8]) { + // Set the number of valid bits. + let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8; + T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); + + let mut i = 0; + while i < input.len() { + let mut word: [u8; 4] = [0; 4]; + let copy_idx = min(i + 4, input.len()); + word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]); + T::regs().din().write_value(u32::from_ne_bytes(word)); + i += 4; + } + } + + /// Save the peripheral state to a context. + fn store_context<'c>(&mut self, ctx: &mut Context<'c>) { + // Block waiting for data in ready. + while !T::regs().sr().read().dinis() {} + + // Store peripheral context. + ctx.imr = T::regs().imr().read().0; + ctx.str = T::regs().str().read().0; + ctx.cr = T::regs().cr().read().0; + let mut i = 0; + while i < NUM_CONTEXT_REGS { + ctx.csr[i] = T::regs().csr(i).read(); + i += 1; + } + } + + /// Restore the peripheral state from a context. + fn load_context(&mut self, ctx: &Context) { + // Restore the peripheral state from the context. + T::regs().imr().write_value(Imr { 0: ctx.imr }); + T::regs().str().write_value(Str { 0: ctx.str }); + T::regs().cr().write_value(Cr { 0: ctx.cr }); + T::regs().cr().modify(|w| w.set_init(true)); + let mut i = 0; + while i < NUM_CONTEXT_REGS { + T::regs().csr(i).write_value(ctx.csr[i]); + i += 1; + } + } +} + +#[cfg(hash_v2)] +impl<'d, T: Instance> Hash<'d, T, Async> { + /// Instantiates, resets, and enables the HASH peripheral. + pub fn new( + peripheral: impl Peripheral

+ 'd, + dma: impl Peripheral

> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { + rcc::enable_and_reset::(); + into_ref!(peripheral, dma); + let instance = Self { + _peripheral: peripheral, + _phantom: PhantomData, + dma: new_dma!(dma), + }; + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + instance + } + /// Restores the peripheral state using the given context, /// then updates the state with the provided data. /// Peripheral state is saved upon return. - #[cfg(hash_v2)] - pub async fn update<'c>(&mut self, ctx: &mut Context<'c>, input: &[u8]) - where - D: crate::hash::Dma, - { + pub async fn update(&mut self, ctx: &mut Context<'_>, input: &[u8]) { // Restore the peripheral state. self.load_context(&ctx); @@ -353,68 +481,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { /// The digest buffer must be large enough to accomodate a digest for the selected algorithm. /// The largest returned digest size is 128 bytes for SHA-512. /// Panics if the supplied digest buffer is too short. - pub fn finish_blocking<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize { - // Restore the peripheral state. - self.load_context(&ctx); - - // Hash the leftover bytes, if any. - self.accumulate_blocking(&ctx.buffer[0..ctx.buflen]); - ctx.buflen = 0; - - //Start the digest calculation. - T::regs().str().write(|w| w.set_dcal(true)); - - // Load the HMAC key if provided. - if let Some(key) = ctx.key { - while !T::regs().sr().read().dinis() {} - self.accumulate_blocking(key); - T::regs().str().write(|w| w.set_dcal(true)); - } - - // Block until digest computation is complete. - while !T::regs().sr().read().dcis() {} - - // Return the digest. - let digest_words = match ctx.algo { - Algorithm::SHA1 => 5, - #[cfg(any(hash_v1, hash_v2, hash_v4))] - Algorithm::MD5 => 4, - Algorithm::SHA224 => 7, - Algorithm::SHA256 => 8, - #[cfg(hash_v3)] - Algorithm::SHA384 => 12, - #[cfg(hash_v3)] - Algorithm::SHA512_224 => 7, - #[cfg(hash_v3)] - Algorithm::SHA512_256 => 8, - #[cfg(hash_v3)] - Algorithm::SHA512 => 16, - }; - - let digest_len_bytes = digest_words * 4; - // Panics if the supplied digest buffer is too short. - if digest.len() < digest_len_bytes { - panic!("Digest buffer must be at least {} bytes long.", digest_words * 4); - } - - let mut i = 0; - while i < digest_words { - let word = T::regs().hr(i).read(); - digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice()); - i += 1; - } - digest_len_bytes - } - - /// Computes a digest for the given context. - /// The digest buffer must be large enough to accomodate a digest for the selected algorithm. - /// The largest returned digest size is 128 bytes for SHA-512. - /// Panics if the supplied digest buffer is too short. - #[cfg(hash_v2)] - pub async fn finish<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize - where - D: crate::hash::Dma, - { + pub async fn finish<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize { // Restore the peripheral state. self.load_context(&ctx); @@ -483,27 +550,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { } /// Push data into the hash core. - fn accumulate_blocking(&mut self, input: &[u8]) { - // Set the number of valid bits. - let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8; - T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); - - let mut i = 0; - while i < input.len() { - let mut word: [u8; 4] = [0; 4]; - let copy_idx = min(i + 4, input.len()); - word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]); - T::regs().din().write_value(u32::from_ne_bytes(word)); - i += 4; - } - } - - /// Push data into the hash core. - #[cfg(hash_v2)] - async fn accumulate(&mut self, input: &[u8]) - where - D: crate::hash::Dma, - { + async fn accumulate(&mut self, input: &[u8]) { // Ignore an input length of 0. if input.len() == 0 { return; @@ -514,57 +561,20 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); // Configure DMA to transfer input to hash core. - let dma_request = self.dma.request(); let dst_ptr: *mut u32 = T::regs().din().as_ptr(); let mut num_words = input.len() / 4; if input.len() % 4 > 0 { num_words += 1; } let src_ptr: *const [u8] = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words); - let dma_transfer = unsafe { - Transfer::new_write_raw( - &mut self.dma, - dma_request, - src_ptr, - dst_ptr as *mut u32, - Default::default(), - ) - }; + + let dma = self.dma.as_mut().unwrap(); + let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr as *mut u32, Default::default()) }; T::regs().cr().modify(|w| w.set_dmae(true)); // Wait for the transfer to complete. dma_transfer.await; } - - /// Save the peripheral state to a context. - fn store_context<'c>(&mut self, ctx: &mut Context<'c>) { - // Block waiting for data in ready. - while !T::regs().sr().read().dinis() {} - - // Store peripheral context. - ctx.imr = T::regs().imr().read().0; - ctx.str = T::regs().str().read().0; - ctx.cr = T::regs().cr().read().0; - let mut i = 0; - while i < NUM_CONTEXT_REGS { - ctx.csr[i] = T::regs().csr(i).read(); - i += 1; - } - } - - /// Restore the peripheral state from a context. - fn load_context(&mut self, ctx: &Context) { - // Restore the peripheral state from the context. - T::regs().imr().write_value(Imr { 0: ctx.imr }); - T::regs().str().write_value(Str { 0: ctx.str }); - T::regs().cr().write_value(Cr { 0: ctx.cr }); - T::regs().cr().modify(|w| w.set_init(true)); - let mut i = 0; - while i < NUM_CONTEXT_REGS { - T::regs().csr(i).write_value(ctx.csr[i]); - i += 1; - } - } } trait SealedInstance { diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 44dda6a9e..a43da1b5a 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -839,7 +839,7 @@ impl<'d> Spi<'d, Async> { let rx_src = self.info.regs.rx_ptr(); let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; - let tx_dst = self.info.regs.tx_ptr(); + let tx_dst: *mut W = self.info.regs.tx_ptr(); let tx_f = unsafe { self.tx_dma .as_mut() diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs index bdb3c9a69..52b84a499 100644 --- a/tests/stm32/src/bin/hash.rs +++ b/tests/stm32/src/bin/hash.rs @@ -6,7 +6,6 @@ mod common; use common::*; use embassy_executor::Spawner; -use embassy_stm32::dma::NoDma; use embassy_stm32::hash::*; use embassy_stm32::{bind_interrupts, hash, peripherals}; use hmac::{Hmac, Mac}; @@ -36,7 +35,7 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let p: embassy_stm32::Peripherals = init(); - let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); + let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs); let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; From a592acb8068011787453944963b384fd43a52e65 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 25 Mar 2025 22:18:21 +0100 Subject: [PATCH 31/44] stm32/cryp: remove DMA generic param. --- embassy-stm32/src/cryp/mod.rs | 897 +++++++++++++++++----------------- embassy-stm32/src/dma/mod.rs | 11 - 2 files changed, 445 insertions(+), 463 deletions(-) diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs index 6afe68a39..54d2c30e5 100644 --- a/embassy-stm32/src/cryp/mod.rs +++ b/embassy-stm32/src/cryp/mod.rs @@ -7,8 +7,9 @@ use core::ptr; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use crate::dma::{NoDma, Transfer, TransferOptions}; +use crate::dma::{ChannelAndRequest, TransferOptions}; use crate::interrupt::typelevel::Interrupt; +use crate::mode::{Async, Blocking, Mode}; use crate::{interrupt, pac, peripherals, rcc, Peripheral}; const DES_BLOCK_SIZE: usize = 8; // 64 bits @@ -57,15 +58,10 @@ pub trait Cipher<'c> { fn prepare_key(&self, _p: pac::cryp::Cryp) {} /// Performs any cipher-specific initialization. - fn init_phase_blocking(&self, _p: pac::cryp::Cryp, _cryp: &Cryp) {} + fn init_phase_blocking(&self, _p: pac::cryp::Cryp, _cryp: &Cryp) {} /// Performs any cipher-specific initialization. - async fn init_phase(&self, _p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) - where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { - } + async fn init_phase(&self, _p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) {} /// Called prior to processing the last data block for cipher-specific operations. fn pre_final(&self, _p: pac::cryp::Cryp, _dir: Direction, _padding_len: usize) -> [u32; 4] { @@ -73,10 +69,10 @@ pub trait Cipher<'c> { } /// Called after processing the last data block for cipher-specific operations. - fn post_final_blocking( + fn post_final_blocking( &self, _p: pac::cryp::Cryp, - _cryp: &Cryp, + _cryp: &Cryp, _dir: Direction, _int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], @@ -85,18 +81,15 @@ pub trait Cipher<'c> { } /// Called after processing the last data block for cipher-specific operations. - async fn post_final( + async fn post_final( &self, _p: pac::cryp::Cryp, - _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, + _cryp: &mut Cryp<'_, T, Async>, _dir: Direction, _int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], _padding_mask: [u8; 16], - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { + ) { } /// Returns the AAD header block as required by the cipher. @@ -474,13 +467,13 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { p.cr().modify(|w| w.set_algomode3(true)); } - fn init_phase_blocking(&self, p: pac::cryp::Cryp, _cryp: &Cryp) { + fn init_phase_blocking(&self, p: pac::cryp::Cryp, _cryp: &Cryp) { p.cr().modify(|w| w.set_gcm_ccmph(0)); p.cr().modify(|w| w.set_crypen(true)); while p.cr().read().crypen() {} } - async fn init_phase(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) { + async fn init_phase(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) { p.cr().modify(|w| w.set_gcm_ccmph(0)); p.cr().modify(|w| w.set_crypen(true)); while p.cr().read().crypen() {} @@ -508,10 +501,10 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { } #[cfg(cryp_v2)] - fn post_final_blocking( + fn post_final_blocking( &self, p: pac::cryp::Cryp, - cryp: &Cryp, + cryp: &Cryp, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], @@ -534,18 +527,15 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { } #[cfg(cryp_v2)] - async fn post_final( + async fn post_final( &self, p: pac::cryp::Cryp, - cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, + cryp: &mut Cryp<'_, T, Async>, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], padding_mask: [u8; AES_BLOCK_SIZE], - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { + ) { if dir == Direction::Encrypt { // Handle special GCM partial block process. p.cr().modify(|w| w.set_crypen(false)); @@ -559,8 +549,8 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> { let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; - let read = Cryp::::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data); - let write = Cryp::::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data); + let read = Cryp::::read_bytes(cryp.outdma.as_mut().unwrap(), Self::BLOCK_SIZE, &mut out_data); + let write = Cryp::::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, int_data); embassy_futures::join::join(read, write).await; @@ -615,13 +605,13 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { p.cr().modify(|w| w.set_algomode3(true)); } - fn init_phase_blocking(&self, p: pac::cryp::Cryp, _cryp: &Cryp) { + fn init_phase_blocking(&self, p: pac::cryp::Cryp, _cryp: &Cryp) { p.cr().modify(|w| w.set_gcm_ccmph(0)); p.cr().modify(|w| w.set_crypen(true)); while p.cr().read().crypen() {} } - async fn init_phase(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) { + async fn init_phase(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) { p.cr().modify(|w| w.set_gcm_ccmph(0)); p.cr().modify(|w| w.set_crypen(true)); while p.cr().read().crypen() {} @@ -649,10 +639,10 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { } #[cfg(cryp_v2)] - fn post_final_blocking( + fn post_final_blocking( &self, p: pac::cryp::Cryp, - cryp: &Cryp, + cryp: &Cryp, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], @@ -675,18 +665,15 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { } #[cfg(cryp_v2)] - async fn post_final( + async fn post_final( &self, p: pac::cryp::Cryp, - cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, + cryp: &mut Cryp<'_, T, Async>, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], _temp1: [u32; 4], padding_mask: [u8; AES_BLOCK_SIZE], - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { + ) { if dir == Direction::Encrypt { // Handle special GCM partial block process. p.cr().modify(|w| w.set_crypen(false)); @@ -700,8 +687,8 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> { let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; - let read = Cryp::::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data); - let write = Cryp::::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data); + let read = Cryp::::read_bytes(cryp.outdma.as_mut().unwrap(), Self::BLOCK_SIZE, &mut out_data); + let write = Cryp::::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, int_data); embassy_futures::join::join(read, write).await; } @@ -812,7 +799,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip p.cr().modify(|w| w.set_algomode3(true)); } - fn init_phase_blocking(&self, p: pac::cryp::Cryp, cryp: &Cryp) { + fn init_phase_blocking(&self, p: pac::cryp::Cryp, cryp: &Cryp) { p.cr().modify(|w| w.set_gcm_ccmph(0)); cryp.write_bytes_blocking(Self::BLOCK_SIZE, &self.block0); @@ -821,14 +808,10 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip while p.cr().read().crypen() {} } - async fn init_phase(&self, p: pac::cryp::Cryp, cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) - where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { + async fn init_phase(&self, p: pac::cryp::Cryp, cryp: &mut Cryp<'_, T, Async>) { p.cr().modify(|w| w.set_gcm_ccmph(0)); - Cryp::::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, &self.block0).await; + Cryp::::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, &self.block0).await; p.cr().modify(|w| w.set_crypen(true)); while p.cr().read().crypen() {} @@ -865,10 +848,10 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip } #[cfg(cryp_v2)] - fn post_final_blocking( + fn post_final_blocking( &self, p: pac::cryp::Cryp, - cryp: &Cryp, + cryp: &Cryp, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], temp1: [u32; 4], @@ -902,18 +885,15 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip } #[cfg(cryp_v2)] - async fn post_final( + async fn post_final( &self, p: pac::cryp::Cryp, - cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, + cryp: &mut Cryp<'_, T, Async>, dir: Direction, int_data: &mut [u8; AES_BLOCK_SIZE], temp1: [u32; 4], padding_mask: [u8; 16], - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { + ) { if dir == Direction::Decrypt { //Handle special CCM partial block process. let mut temp2 = [0; 4]; @@ -937,7 +917,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip in_data[i] = int_word; in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i]; } - Cryp::::write_words(&mut cryp.indma, Self::BLOCK_SIZE, &in_data).await; + Cryp::::write_words(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, &in_data).await; } } } @@ -1007,26 +987,26 @@ pub enum Direction { } /// Crypto Accelerator Driver -pub struct Cryp<'d, T: Instance, DmaIn = NoDma, DmaOut = NoDma> { +pub struct Cryp<'d, T: Instance, M: Mode> { _peripheral: PeripheralRef<'d, T>, - indma: PeripheralRef<'d, DmaIn>, - outdma: PeripheralRef<'d, DmaOut>, + _phantom: PhantomData, + indma: Option>, + outdma: Option>, } -impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { - /// Create a new CRYP driver. - pub fn new( +impl<'d, T: Instance> Cryp<'d, T, Blocking> { + /// Create a new CRYP driver in blocking mode. + pub fn new_blocking( peri: impl Peripheral

+ 'd, - indma: impl Peripheral

+ 'd, - outdma: impl Peripheral

+ 'd, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peri, indma, outdma); + into_ref!(peri); let instance = Self { _peripheral: peri, - indma: indma, - outdma: outdma, + _phantom: PhantomData, + indma: None, + outdma: None, }; T::Interrupt::unpend(); @@ -1034,7 +1014,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { instance } +} +impl<'d, T: Instance, M: Mode> Cryp<'d, T, M> { /// Start a new encrypt or decrypt operation for the given cipher. pub fn start_blocking<'c, C: Cipher<'c> + CipherSized + IVSized>( &self, @@ -1114,89 +1096,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { ctx } - /// Start a new encrypt or decrypt operation for the given cipher. - pub async fn start<'c, C: Cipher<'c> + CipherSized + IVSized>( - &mut self, - cipher: &'c C, - dir: Direction, - ) -> Context<'c, C> - where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { - let mut ctx: Context<'c, C> = Context { - dir, - last_block_processed: false, - cr: 0, - iv: [0; 4], - csgcmccm: [0; 8], - csgcm: [0; 8], - aad_complete: false, - header_len: 0, - payload_len: 0, - cipher: cipher, - phantom_data: PhantomData, - header_processed: false, - aad_buffer: [0; 16], - aad_buffer_len: 0, - }; - - T::regs().cr().modify(|w| w.set_crypen(false)); - - let key = ctx.cipher.key(); - - if key.len() == (128 / 8) { - T::regs().cr().modify(|w| w.set_keysize(0)); - } else if key.len() == (192 / 8) { - T::regs().cr().modify(|w| w.set_keysize(1)); - } else if key.len() == (256 / 8) { - T::regs().cr().modify(|w| w.set_keysize(2)); - } - - self.load_key(key); - - // Set data type to 8-bit. This will match software implementations. - T::regs().cr().modify(|w| w.set_datatype(2)); - - ctx.cipher.prepare_key(T::regs()); - - ctx.cipher.set_algomode(T::regs()); - - // Set encrypt/decrypt - if dir == Direction::Encrypt { - T::regs().cr().modify(|w| w.set_algodir(false)); - } else { - T::regs().cr().modify(|w| w.set_algodir(true)); - } - - // Load the IV into the registers. - let iv = ctx.cipher.iv(); - let mut full_iv: [u8; 16] = [0; 16]; - full_iv[0..iv.len()].copy_from_slice(iv); - let mut iv_idx = 0; - let mut iv_word: [u8; 4] = [0; 4]; - iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); - iv_idx += 4; - T::regs().init(0).ivlr().write_value(u32::from_be_bytes(iv_word)); - iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); - iv_idx += 4; - T::regs().init(0).ivrr().write_value(u32::from_be_bytes(iv_word)); - iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); - iv_idx += 4; - T::regs().init(1).ivlr().write_value(u32::from_be_bytes(iv_word)); - iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); - T::regs().init(1).ivrr().write_value(u32::from_be_bytes(iv_word)); - - // Flush in/out FIFOs - T::regs().cr().modify(|w| w.fflush()); - - ctx.cipher.init_phase(T::regs(), self).await; - - self.store_context(&mut ctx); - - ctx - } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// Controls the header phase of cipher processing. /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. @@ -1294,101 +1193,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { self.store_context(ctx); } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] - /// Controls the header phase of cipher processing. - /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. - /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`. - /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block. - /// When supplying the last block of AAD, `last_aad_block` must be `true`. - pub async fn aad<'c, const TAG_SIZE: usize, C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated>( - &mut self, - ctx: &mut Context<'c, C>, - aad: &[u8], - last_aad_block: bool, - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { - self.load_context(ctx); - - // Perform checks for correctness. - if ctx.aad_complete { - panic!("Cannot update AAD after starting payload!") - } - - ctx.header_len += aad.len() as u64; - - // Header phase - T::regs().cr().modify(|w| w.set_crypen(false)); - T::regs().cr().modify(|w| w.set_gcm_ccmph(1)); - T::regs().cr().modify(|w| w.set_crypen(true)); - - // First write the header B1 block if not yet written. - if !ctx.header_processed { - ctx.header_processed = true; - let header = ctx.cipher.get_header_block(); - ctx.aad_buffer[0..header.len()].copy_from_slice(header); - ctx.aad_buffer_len += header.len(); - } - - // Fill the header block to make a full block. - let len_to_copy = min(aad.len(), C::BLOCK_SIZE - ctx.aad_buffer_len); - ctx.aad_buffer[ctx.aad_buffer_len..ctx.aad_buffer_len + len_to_copy].copy_from_slice(&aad[..len_to_copy]); - ctx.aad_buffer_len += len_to_copy; - ctx.aad_buffer[ctx.aad_buffer_len..].fill(0); - let mut aad_len_remaining = aad.len() - len_to_copy; - - if ctx.aad_buffer_len < C::BLOCK_SIZE { - // The buffer isn't full and this is the last buffer, so process it as is (already padded). - if last_aad_block { - Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await; - assert_eq!(T::regs().sr().read().ifem(), true); - - // Switch to payload phase. - ctx.aad_complete = true; - T::regs().cr().modify(|w| w.set_crypen(false)); - T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); - T::regs().cr().modify(|w| w.fflush()); - } else { - // Just return because we don't yet have a full block to process. - return; - } - } else { - // Load the full block from the buffer. - Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await; - assert_eq!(T::regs().sr().read().ifem(), true); - } - - // Handle a partial block that is passed in. - ctx.aad_buffer_len = 0; - let leftovers = aad_len_remaining % C::BLOCK_SIZE; - ctx.aad_buffer[..leftovers].copy_from_slice(&aad[aad.len() - leftovers..aad.len()]); - ctx.aad_buffer_len += leftovers; - ctx.aad_buffer[ctx.aad_buffer_len..].fill(0); - aad_len_remaining -= leftovers; - assert_eq!(aad_len_remaining % C::BLOCK_SIZE, 0); - - // Load full data blocks into core. - let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE; - let start_index = len_to_copy; - let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks); - Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &aad[start_index..end_index]).await; - - if last_aad_block { - if leftovers > 0 { - Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await; - assert_eq!(T::regs().sr().read().ifem(), true); - } - // Switch to payload phase. - ctx.aad_complete = true; - T::regs().cr().modify(|w| w.set_crypen(false)); - T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); - T::regs().cr().modify(|w| w.fflush()); - } - - self.store_context(ctx); - } - /// Performs encryption/decryption on the provided context. /// The context determines algorithm, mode, and state of the crypto accelerator. /// When the last piece of data is supplied, `last_block` should be `true`. @@ -1478,105 +1282,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { self.store_context(ctx); } - /// Performs encryption/decryption on the provided context. - /// The context determines algorithm, mode, and state of the crypto accelerator. - /// When the last piece of data is supplied, `last_block` should be `true`. - /// This function panics under various mismatches of parameters. - /// Output buffer must be at least as long as the input buffer. - /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes. - /// Padding or ciphertext stealing must be managed by the application for these modes. - /// Data must also be a multiple of block size unless `last_block` is `true`. - pub async fn payload<'c, C: Cipher<'c> + CipherSized + IVSized>( - &mut self, - ctx: &mut Context<'c, C>, - input: &[u8], - output: &mut [u8], - last_block: bool, - ) where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { - self.load_context(ctx); - - let last_block_remainder = input.len() % C::BLOCK_SIZE; - - // Perform checks for correctness. - if !ctx.aad_complete && ctx.header_len > 0 { - panic!("Additional associated data must be processed first!"); - } else if !ctx.aad_complete { - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] - { - ctx.aad_complete = true; - T::regs().cr().modify(|w| w.set_crypen(false)); - T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); - T::regs().cr().modify(|w| w.fflush()); - T::regs().cr().modify(|w| w.set_crypen(true)); - } - } - if ctx.last_block_processed { - panic!("The last block has already been processed!"); - } - if input.len() > output.len() { - panic!("Output buffer length must match input length."); - } - if !last_block { - if last_block_remainder != 0 { - panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE); - } - } - if C::REQUIRES_PADDING { - if last_block_remainder != 0 { - panic!("Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.", C::BLOCK_SIZE); - } - } - if last_block { - ctx.last_block_processed = true; - } - - // Load data into core, block by block. - let num_full_blocks = input.len() / C::BLOCK_SIZE; - for block in 0..num_full_blocks { - let index = block * C::BLOCK_SIZE; - // Read block out - let read = Self::read_bytes( - &mut self.outdma, - C::BLOCK_SIZE, - &mut output[index..index + C::BLOCK_SIZE], - ); - // Write block in - let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &input[index..index + C::BLOCK_SIZE]); - embassy_futures::join::join(read, write).await; - } - - // Handle the final block, which is incomplete. - if last_block_remainder > 0 { - let padding_len = C::BLOCK_SIZE - last_block_remainder; - let temp1 = ctx.cipher.pre_final(T::regs(), ctx.dir, padding_len); - - let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; - let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; - last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]); - let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut intermediate_data); - let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &last_block); - embassy_futures::join::join(read, write).await; - - // Handle the last block depending on mode. - let output_len = output.len(); - output[output_len - last_block_remainder..output_len] - .copy_from_slice(&intermediate_data[0..last_block_remainder]); - - let mut mask: [u8; 16] = [0; 16]; - mask[..last_block_remainder].fill(0xFF); - ctx.cipher - .post_final(T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask) - .await; - } - - ctx.payload_len += input.len() as u64; - - self.store_context(ctx); - } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. /// Called after the all data has been encrypted/decrypted by `payload`. @@ -1623,57 +1328,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { tag } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] - // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. - /// Called after the all data has been encrypted/decrypted by `payload`. - pub async fn finish< - 'c, - const TAG_SIZE: usize, - C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated, - >( - &mut self, - mut ctx: Context<'c, C>, - ) -> [u8; TAG_SIZE] - where - DmaIn: crate::cryp::DmaIn, - DmaOut: crate::cryp::DmaOut, - { - self.load_context(&mut ctx); - - T::regs().cr().modify(|w| w.set_crypen(false)); - T::regs().cr().modify(|w| w.set_gcm_ccmph(3)); - T::regs().cr().modify(|w| w.set_crypen(true)); - - let headerlen1: u32 = ((ctx.header_len * 8) >> 32) as u32; - let headerlen2: u32 = (ctx.header_len * 8) as u32; - let payloadlen1: u32 = ((ctx.payload_len * 8) >> 32) as u32; - let payloadlen2: u32 = (ctx.payload_len * 8) as u32; - - #[cfg(cryp_v2)] - let footer: [u32; 4] = [ - headerlen1.swap_bytes(), - headerlen2.swap_bytes(), - payloadlen1.swap_bytes(), - payloadlen2.swap_bytes(), - ]; - #[cfg(any(cryp_v3, cryp_v4))] - let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; - - let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer); - - let mut full_tag: [u8; 16] = [0; 16]; - let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut full_tag); - - embassy_futures::join::join(read, write).await; - - let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE]; - tag.copy_from_slice(&full_tag[0..TAG_SIZE]); - - T::regs().cr().modify(|w| w.set_crypen(false)); - - tag - } - fn load_key(&self, key: &[u8]) { // Load the key into the registers. let mut keyidx = 0; @@ -1774,31 +1428,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { } } - async fn write_bytes(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u8]) - where - DmaIn: crate::cryp::DmaIn, - { - if blocks.len() == 0 { - return; - } - // Ensure input is a multiple of block size. - assert_eq!(blocks.len() % block_size, 0); - // Configure DMA to transfer input to crypto core. - let dma_request = dma.request(); - let dst_ptr: *mut u32 = T::regs().din().as_ptr(); - let num_words = blocks.len() / 4; - let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); - let options = TransferOptions { - #[cfg(not(gpdma))] - priority: crate::dma::Priority::High, - ..Default::default() - }; - let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; - T::regs().dmacr().modify(|w| w.set_dien(true)); - // Wait for the transfer to complete. - dma_transfer.await; - } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) { assert_eq!((blocks.len() * 4) % block_size, 0); @@ -1813,32 +1442,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { } } - #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] - async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32]) - where - DmaIn: crate::cryp::DmaIn, - { - if blocks.len() == 0 { - return; - } - // Ensure input is a multiple of block size. - assert_eq!((blocks.len() * 4) % block_size, 0); - // Configure DMA to transfer input to crypto core. - let dma_request = dma.request(); - let dst_ptr: *mut u32 = T::regs().din().as_ptr(); - let num_words = blocks.len(); - let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); - let options = TransferOptions { - #[cfg(not(gpdma))] - priority: crate::dma::Priority::High, - ..Default::default() - }; - let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; - T::regs().dmacr().modify(|w| w.set_dien(true)); - // Wait for the transfer to complete. - dma_transfer.await; - } - fn read_bytes_blocking(&self, block_size: usize, blocks: &mut [u8]) { // Block until there is output to read. while !T::regs().sr().read().ofne() {} @@ -1853,18 +1456,408 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { index += 4; } } +} - async fn read_bytes(dma: &mut PeripheralRef<'_, DmaOut>, block_size: usize, blocks: &mut [u8]) - where - DmaOut: crate::cryp::DmaOut, - { +impl<'d, T: Instance> Cryp<'d, T, Async> { + /// Create a new CRYP driver. + pub fn new( + peri: impl Peripheral

+ 'd, + indma: impl Peripheral

> + 'd, + outdma: impl Peripheral

> + 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { + rcc::enable_and_reset::(); + into_ref!(peri, indma, outdma); + let instance = Self { + _peripheral: peri, + _phantom: PhantomData, + indma: new_dma!(indma), + outdma: new_dma!(outdma), + }; + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + + instance + } + + /// Start a new encrypt or decrypt operation for the given cipher. + pub async fn start<'c, C: Cipher<'c> + CipherSized + IVSized>( + &mut self, + cipher: &'c C, + dir: Direction, + ) -> Context<'c, C> { + let mut ctx: Context<'c, C> = Context { + dir, + last_block_processed: false, + cr: 0, + iv: [0; 4], + csgcmccm: [0; 8], + csgcm: [0; 8], + aad_complete: false, + header_len: 0, + payload_len: 0, + cipher: cipher, + phantom_data: PhantomData, + header_processed: false, + aad_buffer: [0; 16], + aad_buffer_len: 0, + }; + + T::regs().cr().modify(|w| w.set_crypen(false)); + + let key = ctx.cipher.key(); + + if key.len() == (128 / 8) { + T::regs().cr().modify(|w| w.set_keysize(0)); + } else if key.len() == (192 / 8) { + T::regs().cr().modify(|w| w.set_keysize(1)); + } else if key.len() == (256 / 8) { + T::regs().cr().modify(|w| w.set_keysize(2)); + } + + self.load_key(key); + + // Set data type to 8-bit. This will match software implementations. + T::regs().cr().modify(|w| w.set_datatype(2)); + + ctx.cipher.prepare_key(T::regs()); + + ctx.cipher.set_algomode(T::regs()); + + // Set encrypt/decrypt + if dir == Direction::Encrypt { + T::regs().cr().modify(|w| w.set_algodir(false)); + } else { + T::regs().cr().modify(|w| w.set_algodir(true)); + } + + // Load the IV into the registers. + let iv = ctx.cipher.iv(); + let mut full_iv: [u8; 16] = [0; 16]; + full_iv[0..iv.len()].copy_from_slice(iv); + let mut iv_idx = 0; + let mut iv_word: [u8; 4] = [0; 4]; + iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); + iv_idx += 4; + T::regs().init(0).ivlr().write_value(u32::from_be_bytes(iv_word)); + iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); + iv_idx += 4; + T::regs().init(0).ivrr().write_value(u32::from_be_bytes(iv_word)); + iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); + iv_idx += 4; + T::regs().init(1).ivlr().write_value(u32::from_be_bytes(iv_word)); + iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]); + T::regs().init(1).ivrr().write_value(u32::from_be_bytes(iv_word)); + + // Flush in/out FIFOs + T::regs().cr().modify(|w| w.fflush()); + + ctx.cipher.init_phase(T::regs(), self).await; + + self.store_context(&mut ctx); + + ctx + } + + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] + /// Controls the header phase of cipher processing. + /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. + /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`. + /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block. + /// When supplying the last block of AAD, `last_aad_block` must be `true`. + pub async fn aad< + 'c, + const TAG_SIZE: usize, + C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated, + >( + &mut self, + ctx: &mut Context<'c, C>, + aad: &[u8], + last_aad_block: bool, + ) { + self.load_context(ctx); + + // Perform checks for correctness. + if ctx.aad_complete { + panic!("Cannot update AAD after starting payload!") + } + + ctx.header_len += aad.len() as u64; + + // Header phase + T::regs().cr().modify(|w| w.set_crypen(false)); + T::regs().cr().modify(|w| w.set_gcm_ccmph(1)); + T::regs().cr().modify(|w| w.set_crypen(true)); + + // First write the header B1 block if not yet written. + if !ctx.header_processed { + ctx.header_processed = true; + let header = ctx.cipher.get_header_block(); + ctx.aad_buffer[0..header.len()].copy_from_slice(header); + ctx.aad_buffer_len += header.len(); + } + + // Fill the header block to make a full block. + let len_to_copy = min(aad.len(), C::BLOCK_SIZE - ctx.aad_buffer_len); + ctx.aad_buffer[ctx.aad_buffer_len..ctx.aad_buffer_len + len_to_copy].copy_from_slice(&aad[..len_to_copy]); + ctx.aad_buffer_len += len_to_copy; + ctx.aad_buffer[ctx.aad_buffer_len..].fill(0); + let mut aad_len_remaining = aad.len() - len_to_copy; + + if ctx.aad_buffer_len < C::BLOCK_SIZE { + // The buffer isn't full and this is the last buffer, so process it as is (already padded). + if last_aad_block { + Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await; + assert_eq!(T::regs().sr().read().ifem(), true); + + // Switch to payload phase. + ctx.aad_complete = true; + T::regs().cr().modify(|w| w.set_crypen(false)); + T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); + T::regs().cr().modify(|w| w.fflush()); + } else { + // Just return because we don't yet have a full block to process. + return; + } + } else { + // Load the full block from the buffer. + Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await; + assert_eq!(T::regs().sr().read().ifem(), true); + } + + // Handle a partial block that is passed in. + ctx.aad_buffer_len = 0; + let leftovers = aad_len_remaining % C::BLOCK_SIZE; + ctx.aad_buffer[..leftovers].copy_from_slice(&aad[aad.len() - leftovers..aad.len()]); + ctx.aad_buffer_len += leftovers; + ctx.aad_buffer[ctx.aad_buffer_len..].fill(0); + aad_len_remaining -= leftovers; + assert_eq!(aad_len_remaining % C::BLOCK_SIZE, 0); + + // Load full data blocks into core. + let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE; + let start_index = len_to_copy; + let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks); + Self::write_bytes( + self.indma.as_mut().unwrap(), + C::BLOCK_SIZE, + &aad[start_index..end_index], + ) + .await; + + if last_aad_block { + if leftovers > 0 { + Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await; + assert_eq!(T::regs().sr().read().ifem(), true); + } + // Switch to payload phase. + ctx.aad_complete = true; + T::regs().cr().modify(|w| w.set_crypen(false)); + T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); + T::regs().cr().modify(|w| w.fflush()); + } + + self.store_context(ctx); + } + + /// Performs encryption/decryption on the provided context. + /// The context determines algorithm, mode, and state of the crypto accelerator. + /// When the last piece of data is supplied, `last_block` should be `true`. + /// This function panics under various mismatches of parameters. + /// Output buffer must be at least as long as the input buffer. + /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes. + /// Padding or ciphertext stealing must be managed by the application for these modes. + /// Data must also be a multiple of block size unless `last_block` is `true`. + pub async fn payload<'c, C: Cipher<'c> + CipherSized + IVSized>( + &mut self, + ctx: &mut Context<'c, C>, + input: &[u8], + output: &mut [u8], + last_block: bool, + ) { + self.load_context(ctx); + + let last_block_remainder = input.len() % C::BLOCK_SIZE; + + // Perform checks for correctness. + if !ctx.aad_complete && ctx.header_len > 0 { + panic!("Additional associated data must be processed first!"); + } else if !ctx.aad_complete { + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] + { + ctx.aad_complete = true; + T::regs().cr().modify(|w| w.set_crypen(false)); + T::regs().cr().modify(|w| w.set_gcm_ccmph(2)); + T::regs().cr().modify(|w| w.fflush()); + T::regs().cr().modify(|w| w.set_crypen(true)); + } + } + if ctx.last_block_processed { + panic!("The last block has already been processed!"); + } + if input.len() > output.len() { + panic!("Output buffer length must match input length."); + } + if !last_block { + if last_block_remainder != 0 { + panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE); + } + } + if C::REQUIRES_PADDING { + if last_block_remainder != 0 { + panic!("Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.", C::BLOCK_SIZE); + } + } + if last_block { + ctx.last_block_processed = true; + } + + // Load data into core, block by block. + let num_full_blocks = input.len() / C::BLOCK_SIZE; + for block in 0..num_full_blocks { + let index = block * C::BLOCK_SIZE; + // Read block out + let read = Self::read_bytes( + self.outdma.as_mut().unwrap(), + C::BLOCK_SIZE, + &mut output[index..index + C::BLOCK_SIZE], + ); + // Write block in + let write = Self::write_bytes( + self.indma.as_mut().unwrap(), + C::BLOCK_SIZE, + &input[index..index + C::BLOCK_SIZE], + ); + embassy_futures::join::join(read, write).await; + } + + // Handle the final block, which is incomplete. + if last_block_remainder > 0 { + let padding_len = C::BLOCK_SIZE - last_block_remainder; + let temp1 = ctx.cipher.pre_final(T::regs(), ctx.dir, padding_len); + + let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; + let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; + last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]); + let read = Self::read_bytes(self.outdma.as_mut().unwrap(), C::BLOCK_SIZE, &mut intermediate_data); + let write = Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &last_block); + embassy_futures::join::join(read, write).await; + + // Handle the last block depending on mode. + let output_len = output.len(); + output[output_len - last_block_remainder..output_len] + .copy_from_slice(&intermediate_data[0..last_block_remainder]); + + let mut mask: [u8; 16] = [0; 16]; + mask[..last_block_remainder].fill(0xFF); + ctx.cipher + .post_final(T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask) + .await; + } + + ctx.payload_len += input.len() as u64; + + self.store_context(ctx); + } + + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] + // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. + /// Called after the all data has been encrypted/decrypted by `payload`. + pub async fn finish< + 'c, + const TAG_SIZE: usize, + C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated, + >( + &mut self, + mut ctx: Context<'c, C>, + ) -> [u8; TAG_SIZE] { + self.load_context(&mut ctx); + + T::regs().cr().modify(|w| w.set_crypen(false)); + T::regs().cr().modify(|w| w.set_gcm_ccmph(3)); + T::regs().cr().modify(|w| w.set_crypen(true)); + + let headerlen1: u32 = ((ctx.header_len * 8) >> 32) as u32; + let headerlen2: u32 = (ctx.header_len * 8) as u32; + let payloadlen1: u32 = ((ctx.payload_len * 8) >> 32) as u32; + let payloadlen2: u32 = (ctx.payload_len * 8) as u32; + + #[cfg(cryp_v2)] + let footer: [u32; 4] = [ + headerlen1.swap_bytes(), + headerlen2.swap_bytes(), + payloadlen1.swap_bytes(), + payloadlen2.swap_bytes(), + ]; + #[cfg(any(cryp_v3, cryp_v4))] + let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2]; + + let write = Self::write_words(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &footer); + + let mut full_tag: [u8; 16] = [0; 16]; + let read = Self::read_bytes(self.outdma.as_mut().unwrap(), C::BLOCK_SIZE, &mut full_tag); + + embassy_futures::join::join(read, write).await; + + let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE]; + tag.copy_from_slice(&full_tag[0..TAG_SIZE]); + + T::regs().cr().modify(|w| w.set_crypen(false)); + + tag + } + + async fn write_bytes(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &[u8]) { + if blocks.len() == 0 { + return; + } + // Ensure input is a multiple of block size. + assert_eq!(blocks.len() % block_size, 0); + // Configure DMA to transfer input to crypto core. + let dst_ptr: *mut u32 = T::regs().din().as_ptr(); + let num_words = blocks.len() / 4; + let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); + let options = TransferOptions { + #[cfg(not(gpdma))] + priority: crate::dma::Priority::High, + ..Default::default() + }; + let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) }; + T::regs().dmacr().modify(|w| w.set_dien(true)); + // Wait for the transfer to complete. + dma_transfer.await; + } + + #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] + async fn write_words(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &[u32]) { + if blocks.len() == 0 { + return; + } + // Ensure input is a multiple of block size. + assert_eq!((blocks.len() * 4) % block_size, 0); + // Configure DMA to transfer input to crypto core. + let dst_ptr: *mut u32 = T::regs().din().as_ptr(); + let num_words = blocks.len(); + let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); + let options = TransferOptions { + #[cfg(not(gpdma))] + priority: crate::dma::Priority::High, + ..Default::default() + }; + let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) }; + T::regs().dmacr().modify(|w| w.set_dien(true)); + // Wait for the transfer to complete. + dma_transfer.await; + } + + async fn read_bytes(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &mut [u8]) { if blocks.len() == 0 { return; } // Ensure input is a multiple of block size. assert_eq!(blocks.len() % block_size, 0); // Configure DMA to get output from crypto core. - let dma_request = dma.request(); let src_ptr = T::regs().dout().as_ptr(); let num_words = blocks.len() / 4; let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words); @@ -1873,7 +1866,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { priority: crate::dma::Priority::VeryHigh, ..Default::default() }; - let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) }; + let dma_transfer = unsafe { dma.read_raw(src_ptr, dst_ptr, options) }; T::regs().dmacr().modify(|w| w.set_doen(true)); // Wait for the transfer to complete. dma_transfer.await; diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 66c4aa53c..ac4a0f98e 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -108,17 +108,6 @@ impl Channel for AnyChannel {} const CHANNEL_COUNT: usize = crate::_generated::DMA_CHANNELS.len(); static STATE: [ChannelState; CHANNEL_COUNT] = [ChannelState::NEW; CHANNEL_COUNT]; -/// "No DMA" placeholder. -/// -/// You may pass this in place of a real DMA channel when creating a driver -/// to indicate it should not use DMA. -/// -/// This often causes async functionality to not be available on the instance, -/// leaving only blocking functionality. -pub struct NoDma; - -impl_peripheral!(NoDma); - // safety: must be called only once at startup pub(crate) unsafe fn init( cs: critical_section::CriticalSection, From db7759ea7db24b00e6f585f560c73bad9fdc1def Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 25 Mar 2025 23:47:28 -0500 Subject: [PATCH 32/44] mspm0: disable events before clearing gpio ris --- embassy-mspm0/src/gpio.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index e1eb7eecf..1048d980e 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs @@ -935,15 +935,32 @@ impl<'d> InputFuture<'d> { fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { let block = pin.block(); + // Before clearing any previous edge events, we must disable events. + // + // If we don't do this, it is possible that after we clear the interrupt, the current event + // the hardware is listening for may not be the same event we will configure. This may result + // in RIS being set. Then when interrupts are unmasked and RIS is set, we may get the wrong event + // causing an interrupt. + // + // Selecting which polarity events happen is a RMW operation. + critical_section::with(|_cs| { + if pin.bit_index() >= 16 { + block.polarity31_16().modify(|w| { + w.set_dio(pin.bit_index() - 16, Polarity::DISABLE); + }); + } else { + block.polarity15_0().modify(|w| { + w.set_dio(pin.bit_index(), Polarity::DISABLE); + }); + }; + }); + // First clear the bit for this event. Otherwise previous edge events may be recorded. block.cpu_int().iclr().write(|w| { w.set_dio(pin.bit_index(), true); }); - // Selecting which polarity events happens is a RMW operation. - // - // Guard with a critical section in case two different threads try to select events at the - // same time. + // Selecting which polarity events happen is a RMW operation. critical_section::with(|_cs| { // Tell the hardware which pin event we want to receive. if pin.bit_index() >= 16 { From 1b6e563260ec2b00cb518e0e801222ebd1ba9902 Mon Sep 17 00:00:00 2001 From: Adrian Wowk Date: Wed, 26 Mar 2025 17:11:27 -0500 Subject: [PATCH 33/44] rp/adc: fix potential race condition This commit rearranges the Adc::wait_for_ready function to make sure that wakers are registered before the interrupt is enabled, and keeps enabling the interrupt until the ADC is ready --- embassy-rp/src/adc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index 8defb5231..1265a22a0 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -205,11 +205,13 @@ impl<'d> Adc<'d, Async> { fn wait_for_ready() -> impl Future { let r = Self::regs(); - r.inte().write(|w| w.set_fifo(true)); - compiler_fence(Ordering::SeqCst); poll_fn(move |cx| { WAKER.register(cx.waker()); + + r.inte().write(|w| w.set_fifo(true)); + compiler_fence(Ordering::SeqCst); + if r.cs().read().ready() { return Poll::Ready(()); } From 5777284304ec4b718204ed67d004f1e20856e3f9 Mon Sep 17 00:00:00 2001 From: Adrian Wowk Date: Wed, 26 Mar 2025 19:05:27 -0500 Subject: [PATCH 34/44] rp: rename BOOTROM_BASE to BOOTRAM_BASE Previously the constant pointing at the base of the bootram was incorrectly called BOOTROM_BASE. According to the datasheet, the bootrom is a 32K region starting at 0x00000000 while the bootram is a 1K region of SRAM starting at 0x400e0000. --- embassy-rp/src/flash.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index fbc8b35ec..a69b44961 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -19,7 +19,7 @@ pub const FLASH_BASE: *const u32 = 0x10000000 as _; /// Address for xip setup function set up by the 235x bootrom. #[cfg(feature = "_rp235x")] -pub const BOOTROM_BASE: *const u32 = 0x400e0000 as _; +pub const BOOTRAM_BASE: *const u32 = 0x400e0000 as _; /// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead. // TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance. @@ -527,7 +527,7 @@ mod ram_helpers { #[cfg(feature = "rp2040")] rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); #[cfg(feature = "_rp235x")] - core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); + core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); flash_function_pointers_with_boot2(true, false, &boot2) } else { flash_function_pointers(true, false) @@ -560,7 +560,7 @@ mod ram_helpers { #[cfg(feature = "rp2040")] rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); #[cfg(feature = "_rp235x")] - core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, (boot2).as_mut_ptr() as *mut u8, 256); + core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, (boot2).as_mut_ptr() as *mut u8, 256); flash_function_pointers_with_boot2(true, true, &boot2) } else { flash_function_pointers(true, true) @@ -598,7 +598,7 @@ mod ram_helpers { #[cfg(feature = "rp2040")] rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); #[cfg(feature = "_rp235x")] - core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); + core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); flash_function_pointers_with_boot2(false, true, &boot2) } else { flash_function_pointers(false, true) From d41eeeae79388f219bf6a84e2f7bde9f6b532516 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 26 Mar 2025 16:01:37 +0100 Subject: [PATCH 35/44] Remove Peripheral trait, rename PeripheralRef->Peri. --- README.md | 6 +- cyw43-pio/src/lib.rs | 22 +- embassy-boot-nrf/src/lib.rs | 4 +- embassy-boot-rp/src/lib.rs | 3 +- embassy-hal-internal/src/lib.rs | 2 +- embassy-hal-internal/src/macros.rs | 40 ++- embassy-hal-internal/src/peripheral.rs | 151 ++-------- embassy-mspm0/src/gpio.rs | 38 ++- embassy-mspm0/src/lib.rs | 2 +- embassy-nrf/src/buffered_uarte.rs | 186 ++++++------ embassy-nrf/src/egu.rs | 11 +- embassy-nrf/src/gpio.rs | 39 ++- embassy-nrf/src/gpiote.rs | 49 ++-- embassy-nrf/src/i2s.rs | 68 +++-- embassy-nrf/src/lib.rs | 2 +- embassy-nrf/src/nfct.rs | 9 +- embassy-nrf/src/nvmc.rs | 8 +- embassy-nrf/src/pdm.rs | 26 +- embassy-nrf/src/ppi/dppi.rs | 16 +- embassy-nrf/src/ppi/mod.rs | 76 ++--- embassy-nrf/src/ppi/ppi.rs | 16 +- embassy-nrf/src/pwm.rs | 159 ++++------- embassy-nrf/src/qdec.rs | 36 ++- embassy-nrf/src/qspi.rs | 24 +- embassy-nrf/src/radio/ble.rs | 8 +- embassy-nrf/src/radio/ieee802154.rs | 9 +- embassy-nrf/src/radio/mod.rs | 5 +- embassy-nrf/src/rng.rs | 12 +- embassy-nrf/src/saadc.rs | 73 ++--- embassy-nrf/src/spim.rs | 60 ++-- embassy-nrf/src/spis.rs | 84 +++--- embassy-nrf/src/temp.rs | 9 +- embassy-nrf/src/timer.rs | 18 +- embassy-nrf/src/twim.rs | 16 +- embassy-nrf/src/twis.rs | 16 +- embassy-nrf/src/uarte.rs | 124 ++++---- embassy-nrf/src/usb/mod.rs | 16 +- embassy-nrf/src/wdt.rs | 30 +- embassy-nxp/src/gpio.rs | 35 +-- embassy-nxp/src/lib.rs | 2 +- embassy-nxp/src/pint.rs | 18 +- embassy-rp/src/adc.rs | 30 +- embassy-rp/src/bootsel.rs | 21 +- embassy-rp/src/clocks.rs | 25 +- embassy-rp/src/dma.rs | 33 +-- embassy-rp/src/flash.rs | 15 +- embassy-rp/src/gpio.rs | 41 ++- embassy-rp/src/i2c.rs | 34 +-- embassy-rp/src/i2c_slave.rs | 11 +- embassy-rp/src/lib.rs | 2 +- embassy-rp/src/multicore.rs | 4 +- embassy-rp/src/pio/mod.rs | 18 +- embassy-rp/src/pio_programs/hd44780.rs | 24 +- embassy-rp/src/pio_programs/i2s.rs | 39 ++- embassy-rp/src/pio_programs/onewire.rs | 3 +- embassy-rp/src/pio_programs/pwm.rs | 4 +- embassy-rp/src/pio_programs/rotary_encoder.rs | 5 +- embassy-rp/src/pio_programs/stepper.rs | 9 +- embassy-rp/src/pio_programs/uart.rs | 45 +-- embassy-rp/src/pio_programs/ws2812.rs | 15 +- embassy-rp/src/pwm.rs | 80 ++---- embassy-rp/src/rtc/mod.rs | 10 +- embassy-rp/src/spi.rs | 136 +++++---- embassy-rp/src/trng.rs | 10 +- embassy-rp/src/uart/buffered.rs | 66 ++--- embassy-rp/src/uart/mod.rs | 168 +++++------ embassy-rp/src/usb.rs | 7 +- embassy-rp/src/watchdog.rs | 4 +- embassy-stm32-wpan/src/lib.rs | 8 +- embassy-stm32/build.rs | 4 +- embassy-stm32/src/adc/c0.rs | 11 +- embassy-stm32/src/adc/f1.rs | 7 +- embassy-stm32/src/adc/f3.rs | 8 +- embassy-stm32/src/adc/f3_v1_1.rs | 7 +- embassy-stm32/src/adc/g4.rs | 11 +- embassy-stm32/src/adc/mod.rs | 15 +- embassy-stm32/src/adc/ringbuffered_v2.rs | 10 +- embassy-stm32/src/adc/u5_adc4.rs | 19 +- embassy-stm32/src/adc/v1.rs | 6 +- embassy-stm32/src/adc/v2.rs | 7 +- embassy-stm32/src/adc/v3.rs | 8 +- embassy-stm32/src/adc/v4.rs | 11 +- embassy-stm32/src/can/bxcan/mod.rs | 13 +- embassy-stm32/src/can/fdcan.rs | 16 +- embassy-stm32/src/cordic/mod.rs | 30 +- embassy-stm32/src/crc/v1.rs | 11 +- embassy-stm32/src/crc/v2v3.rs | 9 +- embassy-stm32/src/cryp/mod.rs | 18 +- embassy-stm32/src/dac/mod.rs | 53 ++-- embassy-stm32/src/dcmi.rs | 267 +++++++++--------- embassy-stm32/src/dma/dma_bdma.rs | 44 ++- embassy-stm32/src/dma/gpdma.rs | 28 +- embassy-stm32/src/dma/mod.rs | 20 +- embassy-stm32/src/dma/util.rs | 22 +- embassy-stm32/src/dsihost.rs | 14 +- embassy-stm32/src/dts/mod.rs | 9 +- embassy-stm32/src/eth/mod.rs | 3 +- embassy-stm32/src/eth/v1/mod.rs | 48 ++-- embassy-stm32/src/eth/v2/mod.rs | 112 ++++---- embassy-stm32/src/exti.rs | 35 +-- embassy-stm32/src/flash/asynch.rs | 7 +- embassy-stm32/src/flash/common.rs | 9 +- embassy-stm32/src/flash/f4.rs | 11 +- embassy-stm32/src/fmc.rs | 23 +- embassy-stm32/src/gpio.rs | 43 ++- embassy-stm32/src/hash/mod.rs | 16 +- embassy-stm32/src/hrtim/mod.rs | 26 +- embassy-stm32/src/hrtim/traits.rs | 4 +- embassy-stm32/src/hsem/mod.rs | 16 +- embassy-stm32/src/hspi/mod.rs | 164 ++++++----- embassy-stm32/src/i2c/mod.rs | 28 +- embassy-stm32/src/i2s.rs | 87 +++--- embassy-stm32/src/lib.rs | 2 +- embassy-stm32/src/lptim/mod.rs | 3 +- embassy-stm32/src/lptim/pwm.rs | 24 +- embassy-stm32/src/lptim/timer/mod.rs | 8 +- embassy-stm32/src/ltdc.rs | 68 +++-- embassy-stm32/src/macros.rs | 14 +- embassy-stm32/src/opamp.rs | 27 +- embassy-stm32/src/ospi/mod.rs | 224 ++++++++------- embassy-stm32/src/qspi/mod.rs | 96 +++---- embassy-stm32/src/rcc/mco.rs | 15 +- embassy-stm32/src/rng.rs | 11 +- embassy-stm32/src/rtc/mod.rs | 4 +- embassy-stm32/src/sai/mod.rs | 71 +++-- embassy-stm32/src/sdmmc/mod.rs | 133 ++++----- embassy-stm32/src/spdifrx/mod.rs | 19 +- embassy-stm32/src/spi/mod.rs | 85 +++--- embassy-stm32/src/timer/complementary_pwm.rs | 14 +- embassy-stm32/src/timer/input_capture.rs | 15 +- embassy-stm32/src/timer/low_level.rs | 8 +- embassy-stm32/src/timer/mod.rs | 4 +- embassy-stm32/src/timer/pwm_input.rs | 24 +- embassy-stm32/src/timer/qei.rs | 14 +- embassy-stm32/src/timer/simple_pwm.rs | 42 +-- embassy-stm32/src/tsc/mod.rs | 5 +- embassy-stm32/src/tsc/pin_groups.rs | 14 +- embassy-stm32/src/tsc/tsc.rs | 22 +- embassy-stm32/src/ucpd.rs | 22 +- embassy-stm32/src/usart/buffered.rs | 82 +++--- embassy-stm32/src/usart/mod.rs | 172 +++++------ embassy-stm32/src/usart/ringbuffered.rs | 6 +- embassy-stm32/src/usb/otg.rs | 76 +++-- embassy-stm32/src/usb/usb.rs | 23 +- embassy-stm32/src/wdg/mod.rs | 9 +- examples/nrf52840-rtic/src/bin/blinky.rs | 4 +- .../src/bin/channel_sender_receiver.rs | 7 +- examples/nrf52840/src/bin/pdm_continuous.rs | 4 +- examples/nrf52840/src/bin/qspi_lowpower.rs | 14 +- examples/nrf52840/src/bin/saadc.rs | 2 +- examples/nrf52840/src/bin/saadc_continuous.rs | 12 +- examples/nrf52840/src/bin/twim_lowpower.rs | 8 +- examples/nrf9160/src/bin/modem_tcp_client.rs | 8 +- examples/rp/Cargo.toml | 2 +- examples/rp/src/bin/adc_dma.rs | 4 +- examples/rp/src/bin/assign_resources.rs | 7 +- examples/rp/src/bin/blinky_two_channels.rs | 4 +- examples/rp/src/bin/blinky_two_tasks.rs | 4 +- examples/rp/src/bin/orchestrate_tasks.rs | 2 +- examples/rp/src/bin/pio_async.rs | 8 +- examples/rp/src/bin/pio_dma.rs | 6 +- examples/rp/src/bin/pio_i2s.rs | 7 +- examples/rp/src/bin/pwm.rs | 5 +- examples/rp/src/bin/shared_bus.rs | 6 +- examples/rp/src/bin/zerocopy.rs | 9 +- examples/rp235x/Cargo.toml | 2 +- examples/rp235x/src/bin/adc_dma.rs | 4 +- examples/rp235x/src/bin/assign_resources.rs | 7 +- .../rp235x/src/bin/blinky_two_channels.rs | 4 +- examples/rp235x/src/bin/blinky_two_tasks.rs | 4 +- examples/rp235x/src/bin/pio_async.rs | 4 +- examples/rp235x/src/bin/pio_dma.rs | 6 +- .../rp235x/src/bin/pio_rotary_encoder_rxf.rs | 6 +- examples/rp235x/src/bin/pwm.rs | 5 +- .../src/bin/pwm_tb6612fng_motor_driver.rs | 2 +- examples/rp235x/src/bin/shared_bus.rs | 6 +- examples/rp235x/src/bin/zerocopy.rs | 9 +- examples/stm32c0/src/bin/adc.rs | 5 +- .../src/bin/button_controlled_blink.rs | 7 +- examples/stm32f1/src/bin/input_capture.rs | 4 +- examples/stm32f1/src/bin/pwm_input.rs | 4 +- examples/stm32f1/src/bin/usb_serial.rs | 2 +- examples/stm32f334/src/bin/opamp.rs | 2 +- examples/stm32f4/src/bin/can.rs | 2 +- examples/stm32f4/src/bin/flash_async.rs | 8 +- examples/stm32f4/src/bin/input_capture.rs | 4 +- examples/stm32f4/src/bin/pwm_input.rs | 4 +- examples/stm32f4/src/bin/ws2812_pwm.rs | 2 +- examples/stm32f7/src/bin/can.rs | 2 +- examples/stm32g0/src/bin/adc_dma.rs | 2 +- examples/stm32g0/src/bin/input_capture.rs | 4 +- examples/stm32g0/src/bin/pwm_input.rs | 4 +- examples/stm32g4/src/bin/adc_dma.rs | 2 +- examples/stm32h5/src/bin/cordic.rs | 6 +- examples/stm32h5/src/bin/stop.rs | 4 +- examples/stm32h7/src/bin/adc_dma.rs | 2 +- examples/stm32h7/src/bin/dac_dma.rs | 5 +- .../stm32h7/src/bin/low_level_timer_api.rs | 14 +- examples/stm32h723/src/bin/spdifrx.rs | 34 ++- examples/stm32l4/src/bin/dac_dma.rs | 5 +- examples/stm32l5/src/bin/stop.rs | 4 +- examples/stm32u5/src/bin/adc.rs | 4 +- tests/nrf/src/bin/buffered_uart.rs | 14 +- tests/nrf/src/bin/buffered_uart_halves.rs | 16 +- tests/nrf/src/bin/buffered_uart_spam.rs | 6 +- tests/nrf/src/bin/spim.rs | 8 +- tests/nrf/src/bin/uart_halves.rs | 14 +- tests/nrf/src/bin/uart_split.rs | 6 +- tests/rp/src/bin/adc.rs | 61 ++-- tests/rp/src/bin/bootsel.rs | 5 +- tests/rp/src/bin/gpio.rs | 40 +-- tests/rp/src/bin/gpio_async.rs | 24 +- tests/rp/src/bin/gpio_multicore.rs | 5 +- tests/rp/src/bin/pwm.rs | 50 ++-- tests/rp/src/bin/uart.rs | 14 +- tests/rp/src/bin/uart_buffered.rs | 38 ++- tests/rp/src/bin/uart_dma.rs | 38 +-- tests/stm32/src/bin/can.rs | 2 +- tests/stm32/src/bin/cordic.rs | 4 +- tests/stm32/src/bin/gpio.rs | 44 +-- tests/stm32/src/bin/sdmmc.rs | 26 +- tests/stm32/src/bin/spi.rs | 16 +- tests/stm32/src/bin/spi_dma.rs | 34 ++- tests/stm32/src/bin/ucpd.rs | 10 +- tests/stm32/src/bin/usart.rs | 6 +- 225 files changed, 2645 insertions(+), 3215 deletions(-) diff --git a/README.md b/README.md index c64a07be8..383fb6671 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,11 @@ use defmt::info; use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; -use embassy_nrf::Peripherals; +use embassy_nrf::{Peri, Peripherals}; // Declare async tasks #[embassy_executor::task] -async fn blink(pin: AnyPin) { +async fn blink(pin: Peri<'static, AnyPin>) { let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); loop { @@ -77,7 +77,7 @@ async fn main(spawner: Spawner) { let p = embassy_nrf::init(Default::default()); // Spawned tasks run in the background, concurrently. - spawner.spawn(blink(p.P0_13.degrade())).unwrap(); + spawner.spawn(blink(p.P0_13.into())).unwrap(); let mut button = Input::new(p.P0_11, Pull::Up); loop { diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs index c1b301547..b0be19358 100644 --- a/cyw43-pio/src/lib.rs +++ b/cyw43-pio/src/lib.rs @@ -10,16 +10,16 @@ use embassy_rp::dma::Channel; use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; -use embassy_rp::{Peripheral, PeripheralRef}; +use embassy_rp::Peri; use fixed::types::extra::U8; use fixed::FixedU32; /// SPI comms driven by PIO. -pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA> { +pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA: Channel> { cs: Output<'d>, sm: StateMachine<'d, PIO, SM>, irq: Irq<'d, PIO, 0>, - dma: PeripheralRef<'d, DMA>, + dma: Peri<'d, DMA>, wrap_target: u8, } @@ -48,20 +48,16 @@ where PIO: Instance, { /// Create a new instance of PioSpi. - pub fn new( + pub fn new( common: &mut Common<'d, PIO>, mut sm: StateMachine<'d, PIO, SM>, clock_divider: FixedU32, irq: Irq<'d, PIO, 0>, cs: Output<'d>, - dio: DIO, - clk: CLK, - dma: impl Peripheral

+ 'd, - ) -> Self - where - DIO: PioPin, - CLK: PioPin, - { + dio: Peri<'d, impl PioPin>, + clk: Peri<'d, impl PioPin>, + dma: Peri<'d, DMA>, + ) -> Self { let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER { let overclock_program = pio_asm!( ".side_set 1" @@ -146,7 +142,7 @@ where cs, sm, irq, - dma: dma.into_ref(), + dma: dma, wrap_target: loaded_program.wrap.target, } } diff --git a/embassy-boot-nrf/src/lib.rs b/embassy-boot-nrf/src/lib.rs index e5bc870b5..46c1994e2 100644 --- a/embassy-boot-nrf/src/lib.rs +++ b/embassy-boot-nrf/src/lib.rs @@ -9,7 +9,7 @@ pub use embassy_boot::{ }; use embassy_nrf::nvmc::PAGE_SIZE; use embassy_nrf::peripherals::WDT; -use embassy_nrf::wdt; +use embassy_nrf::{wdt, Peri}; use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; /// A bootloader for nRF devices. @@ -113,7 +113,7 @@ pub struct WatchdogFlash { impl WatchdogFlash { /// Start a new watchdog with a given flash and WDT peripheral and a timeout - pub fn start(flash: FLASH, wdt: WDT, config: wdt::Config) -> Self { + pub fn start(flash: FLASH, wdt: Peri<'static, WDT>, config: wdt::Config) -> Self { let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) { Ok(x) => x, Err(_) => { diff --git a/embassy-boot-rp/src/lib.rs b/embassy-boot-rp/src/lib.rs index 6ec33a580..f704380ef 100644 --- a/embassy-boot-rp/src/lib.rs +++ b/embassy-boot-rp/src/lib.rs @@ -10,6 +10,7 @@ pub use embassy_boot::{ use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE}; use embassy_rp::peripherals::{FLASH, WATCHDOG}; use embassy_rp::watchdog::Watchdog; +use embassy_rp::Peri; use embassy_time::Duration; use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; @@ -68,7 +69,7 @@ pub struct WatchdogFlash<'d, const SIZE: usize> { impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { /// Start a new watchdog with a given flash and watchdog peripheral and a timeout - pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self { + pub fn start(flash: Peri<'static, FLASH>, watchdog: Peri<'static, WATCHDOG>, timeout: Duration) -> Self { let flash = Flash::<_, Blocking, SIZE>::new_blocking(flash); let mut watchdog = Watchdog::new(watchdog); watchdog.start(timeout); diff --git a/embassy-hal-internal/src/lib.rs b/embassy-hal-internal/src/lib.rs index 89f20e993..7addb71e2 100644 --- a/embassy-hal-internal/src/lib.rs +++ b/embassy-hal-internal/src/lib.rs @@ -11,7 +11,7 @@ pub mod drop; mod macros; mod peripheral; pub mod ratio; -pub use peripheral::{Peripheral, PeripheralRef}; +pub use peripheral::{Peri, PeripheralType}; #[cfg(feature = "cortex-m")] pub mod interrupt; diff --git a/embassy-hal-internal/src/macros.rs b/embassy-hal-internal/src/macros.rs index 07cd89487..cd2bc3cab 100644 --- a/embassy-hal-internal/src/macros.rs +++ b/embassy-hal-internal/src/macros.rs @@ -18,8 +18,8 @@ macro_rules! peripherals_definition { /// /// You must ensure that you're only using one instance of this type at a time. #[inline] - pub unsafe fn steal() -> Self { - Self{ _private: ()} + pub unsafe fn steal() -> $crate::Peri<'static, Self> { + $crate::Peri::new_unchecked(Self{ _private: ()}) } } @@ -42,7 +42,7 @@ macro_rules! peripherals_struct { $( #[doc = concat!(stringify!($name), " peripheral")] $(#[$cfg])? - pub $name: peripherals::$name, + pub $name: $crate::Peri<'static, peripherals::$name>, )* } @@ -108,28 +108,26 @@ macro_rules! peripherals { }; } -/// Convenience converting into reference. -#[macro_export] -macro_rules! into_ref { - ($($name:ident),*) => { - $( - let mut $name = $name.into_ref(); - )* - } -} - /// Implement the peripheral trait. #[macro_export] macro_rules! impl_peripheral { - ($type:ident) => { - impl $crate::Peripheral for $type { - type P = $type; - - #[inline] - unsafe fn clone_unchecked(&self) -> Self::P { - #[allow(clippy::needless_update)] - $type { ..*self } + ($type:ident<$($T:ident $(: $bound:tt $(+ $others:tt )*)?),*>) => { + impl<$($T: $($bound $(+$others)*)?),*> Copy for $type <$($T),*> {} + impl<$($T: $($bound $(+$others)*)?),*> Clone for $type <$($T),*> { + fn clone(&self) -> Self { + *self } } + impl<$($T: $($bound $(+$others)*)?),*> PeripheralType for $type <$($T),*> {} + }; + + ($type:ident) => { + impl Copy for $type {} + impl Clone for $type { + fn clone(&self) -> Self { + *self + } + } + impl $crate::PeripheralType for $type {} }; } diff --git a/embassy-hal-internal/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs index 0b0f13338..803259bb8 100644 --- a/embassy-hal-internal/src/peripheral.rs +++ b/embassy-hal-internal/src/peripheral.rs @@ -1,5 +1,5 @@ use core::marker::PhantomData; -use core::ops::{Deref, DerefMut}; +use core::ops::Deref; /// An exclusive reference to a peripheral. /// @@ -9,20 +9,26 @@ use core::ops::{Deref, DerefMut}; /// - Memory efficiency: Peripheral singletons are typically either zero-sized (for concrete /// peripherals like `PA9` or `SPI4`) or very small (for example `AnyPin`, which is 1 byte). /// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized. -/// PeripheralRef stores a copy of `T` instead, so it's the same size. +/// Peripheral stores a copy of `T` instead, so it's the same size. /// - Code size efficiency. If the user uses the same driver with both `SPI4` and `&mut SPI4`, -/// the driver code would be monomorphized two times. With PeripheralRef, the driver is generic -/// over a lifetime only. `SPI4` becomes `PeripheralRef<'static, SPI4>`, and `&mut SPI4` becomes -/// `PeripheralRef<'a, SPI4>`. Lifetimes don't cause monomorphization. -pub struct PeripheralRef<'a, T> { +/// 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. +pub struct Peri<'a, T: PeripheralType> { inner: T, _lifetime: PhantomData<&'a mut T>, } -impl<'a, T> PeripheralRef<'a, T> { - /// Create a new reference to a peripheral. +impl<'a, T: PeripheralType> Peri<'a, T> { + /// Create a new owned a peripheral. + /// + /// For use by HALs only. + /// + /// If you're an end user you shouldn't use this, you should use `steal()` + /// on the actual peripheral types instead. #[inline] - pub fn new(inner: T) -> Self { + #[doc(hidden)] + pub unsafe fn new_unchecked(inner: T) -> Self { Self { inner, _lifetime: PhantomData, @@ -38,46 +44,38 @@ impl<'a, T> PeripheralRef<'a, T> { /// create two SPI drivers on `SPI1`, because they will "fight" each other. /// /// You should strongly prefer using `reborrow()` instead. It returns a - /// `PeripheralRef` that borrows `self`, which allows the borrow checker + /// `Peri` that borrows `self`, which allows the borrow checker /// to enforce this at compile time. - pub unsafe fn clone_unchecked(&self) -> PeripheralRef<'a, T> - where - T: Peripheral

, - { - PeripheralRef::new(self.inner.clone_unchecked()) + pub unsafe fn clone_unchecked(&self) -> Peri<'a, T> { + Peri::new_unchecked(self.inner) } - /// Reborrow into a "child" PeripheralRef. + /// Reborrow into a "child" Peri. /// - /// `self` will stay borrowed until the child PeripheralRef is dropped. - pub fn reborrow(&mut self) -> PeripheralRef<'_, T> - where - T: Peripheral

, - { - // safety: we're returning the clone inside a new PeripheralRef that borrows + /// `self` will stay borrowed until the child Peripheral is dropped. + pub fn reborrow(&mut self) -> Peri<'_, T> { + // safety: we're returning the clone inside a new Peripheral that borrows // self, so user code can't use both at the same time. - PeripheralRef::new(unsafe { self.inner.clone_unchecked() }) + unsafe { self.clone_unchecked() } } /// Map the inner peripheral using `Into`. /// - /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an + /// This converts from `Peri<'a, T>` to `Peri<'a, U>`, using an /// `Into` impl to convert from `T` to `U`. /// - /// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`. + /// For example, this can be useful to.into() GPIO pins: converting from Peri<'a, PB11>` to `Peri<'a, AnyPin>`. #[inline] - pub fn map_into(self) -> PeripheralRef<'a, U> + pub fn into(self) -> Peri<'a, U> where T: Into, + U: PeripheralType, { - PeripheralRef { - inner: self.inner.into(), - _lifetime: PhantomData, - } + unsafe { Peri::new_unchecked(self.inner.into()) } } } -impl<'a, T> Deref for PeripheralRef<'a, T> { +impl<'a, T: PeripheralType> Deref for Peri<'a, T> { type Target = T; #[inline] @@ -86,92 +84,5 @@ impl<'a, T> Deref for PeripheralRef<'a, T> { } } -/// Trait for any type that can be used as a peripheral of type `P`. -/// -/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`), -/// or borrowed peripherals (e.g. `&mut TWISPI0`). -/// -/// For example, if you have a driver with a constructor like this: -/// -/// ```ignore -/// impl<'d, T: Instance> Twim<'d, T> { -/// pub fn new( -/// twim: impl Peripheral

+ 'd, -/// irq: impl Peripheral

+ 'd, -/// sda: impl Peripheral

+ 'd, -/// scl: impl Peripheral

+ 'd, -/// config: Config, -/// ) -> Self { .. } -/// } -/// ``` -/// -/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`): -/// -/// ```ignore -/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); -/// ``` -/// -/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long -/// as the borrows last: -/// -/// ```ignore -/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config); -/// ``` -/// -/// # Implementation details, for HAL authors -/// -/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral

` in -/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`, -/// and storing that in the driver struct. -/// -/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`. -/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`. -pub trait Peripheral: Sized { - /// Peripheral singleton type - type P; - - /// Unsafely clone (duplicate) a peripheral singleton. - /// - /// # Safety - /// - /// This returns an owned clone of the peripheral. You must manually ensure - /// only one copy of the peripheral is in use at a time. For example, don't - /// create two SPI drivers on `SPI1`, because they will "fight" each other. - /// - /// You should strongly prefer using `into_ref()` instead. It returns a - /// `PeripheralRef`, which allows the borrow checker to enforce this at compile time. - unsafe fn clone_unchecked(&self) -> Self::P; - - /// Convert a value into a `PeripheralRef`. - /// - /// When called on an owned `T`, yields a `PeripheralRef<'static, T>`. - /// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`. - #[inline] - fn into_ref<'a>(self) -> PeripheralRef<'a, Self::P> - where - Self: 'a, - { - PeripheralRef::new(unsafe { self.clone_unchecked() }) - } -} - -impl<'b, T: DerefMut> Peripheral for T -where - T::Target: Peripheral, -{ - type P = ::P; - - #[inline] - unsafe fn clone_unchecked(&self) -> Self::P { - T::Target::clone_unchecked(self) - } -} - -impl<'b, T: Peripheral> Peripheral for PeripheralRef<'_, T> { - type P = T::P; - - #[inline] - unsafe fn clone_unchecked(&self) -> Self::P { - T::clone_unchecked(self) - } -} +/// Marker trait for peripheral types. +pub trait PeripheralType: Copy + Sized {} diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index 1048d980e..2edadbc5a 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs @@ -5,7 +5,7 @@ use core::future::Future; use core::pin::Pin as FuturePin; use core::task::{Context, Poll}; -use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::pac::gpio::vals::*; @@ -74,7 +74,7 @@ pub enum Port { /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// mode. pub struct Flex<'d> { - pin: PeripheralRef<'d, AnyPin>, + pin: Peri<'d, AnyPin>, } impl<'d> Flex<'d> { @@ -83,11 +83,9 @@ impl<'d> Flex<'d> { /// The pin remains disconnected. The initial output level is unspecified, but can be changed /// before the pin is put into output mode. #[inline] - pub fn new(pin: impl Peripheral

+ 'd) -> Self { - into_ref!(pin); - + pub fn new(pin: Peri<'d, impl Pin>) -> Self { // Pin will be in disconnected state. - Self { pin: pin.map_into() } + Self { pin: pin.into() } } /// Set the pin's pull. @@ -345,7 +343,7 @@ pub struct Input<'d> { impl<'d> Input<'d> { /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { let mut pin = Flex::new(pin); pin.set_as_input(); pin.set_pull(pull); @@ -421,7 +419,7 @@ pub struct Output<'d> { impl<'d> Output<'d> { /// Create GPIO output driver for a [Pin] with the provided [Level] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { let mut pin = Flex::new(pin); pin.set_as_output(); pin.set_level(initial_output); @@ -491,7 +489,7 @@ pub struct OutputOpenDrain<'d> { impl<'d> OutputOpenDrain<'d> { /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level]. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { let mut pin = Flex::new(pin); pin.set_level(initial_output); pin.set_as_input_output(); @@ -599,7 +597,7 @@ impl<'d> OutputOpenDrain<'d> { /// Type-erased GPIO pin pub struct AnyPin { - pin_port: u8, + pub(crate) pin_port: u8, } impl AnyPin { @@ -608,8 +606,8 @@ impl AnyPin { /// # Safety /// - `pin_port` should not in use by another driver. #[inline] - pub unsafe fn steal(pin_port: u8) -> Self { - Self { pin_port } + pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> { + Peri::new_unchecked(Self { pin_port }) } } @@ -625,13 +623,7 @@ impl SealedPin for AnyPin { /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. #[allow(private_bounds)] -pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { - fn degrade(self) -> AnyPin { - AnyPin { - pin_port: self.pin_port(), - } - } - +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// The index of this pin in PINCM (pin control management) registers. #[inline] fn pin_cm(&self) -> u8 { @@ -866,7 +858,9 @@ macro_rules! impl_pin { impl From for crate::gpio::AnyPin { fn from(val: crate::peripherals::$name) -> Self { - crate::gpio::Pin::degrade(val) + Self { + pin_port: crate::gpio::SealedPin::pin_port(&val), + } } } }; @@ -928,11 +922,11 @@ pub(crate) trait SealedPin { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputFuture<'d> { - pin: PeripheralRef<'d, AnyPin>, + pin: Peri<'d, AnyPin>, } impl<'d> InputFuture<'d> { - fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { + fn new(pin: Peri<'d, AnyPin>, polarity: Polarity) -> Self { let block = pin.block(); // Before clearing any previous edge events, we must disable events. diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 1df85a520..99b7ed4a1 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -50,7 +50,7 @@ pub(crate) mod _generated { // Reexports pub(crate) use _generated::gpio_pincm; pub use _generated::{peripherals, Peripherals}; -pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +pub use embassy_hal_internal::Peri; #[cfg(feature = "unstable-pac")] pub use mspm0_metapac as pac; #[cfg(not(feature = "unstable-pac"))] diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index c3fcfd06e..f939be004 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -16,7 +16,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Orde use core::task::Poll; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use pac::uarte::vals; // Re-export SVD variants to allow user to directly set values pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; @@ -28,7 +28,7 @@ use crate::ppi::{ }; use crate::timer::{Instance as TimerInstance, Timer}; use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; -use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; +use crate::{interrupt, pac, EASY_DMA_SIZE}; pub(crate) struct State { tx_buf: RingBuffer, @@ -222,27 +222,26 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { /// Panics if `rx_buffer.len()` is odd. #[allow(clippy::too_many_arguments)] pub fn new( - uarte: impl Peripheral

+ 'd, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, - ppi_group: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, impl ConfigurableChannel>, + ppi_ch2: Peri<'d, impl ConfigurableChannel>, + ppi_group: Peri<'d, impl Group>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - txd: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + txd: Peri<'d, impl GpioPin>, config: Config, rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, timer, rxd, txd, ppi_ch1, ppi_ch2, ppi_group); Self::new_inner( uarte, timer, - ppi_ch1.map_into(), - ppi_ch2.map_into(), - ppi_group.map_into(), - rxd.map_into(), - txd.map_into(), + ppi_ch1.into(), + ppi_ch2.into(), + ppi_group.into(), + rxd.into(), + txd.into(), None, None, config, @@ -258,31 +257,30 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { /// Panics if `rx_buffer.len()` is odd. #[allow(clippy::too_many_arguments)] pub fn new_with_rtscts( - uarte: impl Peripheral

+ 'd, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, - ppi_group: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, impl ConfigurableChannel>, + ppi_ch2: Peri<'d, impl ConfigurableChannel>, + ppi_group: Peri<'d, impl Group>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - txd: impl Peripheral

+ 'd, - cts: impl Peripheral

+ 'd, - rts: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + txd: Peri<'d, impl GpioPin>, + cts: Peri<'d, impl GpioPin>, + rts: Peri<'d, impl GpioPin>, config: Config, rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, timer, rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group); Self::new_inner( uarte, timer, - ppi_ch1.map_into(), - ppi_ch2.map_into(), - ppi_group.map_into(), - rxd.map_into(), - txd.map_into(), - Some(cts.map_into()), - Some(rts.map_into()), + ppi_ch1.into(), + ppi_ch2.into(), + ppi_group.into(), + rxd.into(), + txd.into(), + Some(cts.into()), + Some(rts.into()), config, rx_buffer, tx_buffer, @@ -291,15 +289,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { #[allow(clippy::too_many_arguments)] fn new_inner( - peri: PeripheralRef<'d, U>, - timer: PeripheralRef<'d, T>, - ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_group: PeripheralRef<'d, AnyGroup>, - rxd: PeripheralRef<'d, AnyPin>, - txd: PeripheralRef<'d, AnyPin>, - cts: Option>, - rts: Option>, + peri: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, AnyConfigurableChannel>, + ppi_ch2: Peri<'d, AnyConfigurableChannel>, + ppi_group: Peri<'d, AnyGroup>, + rxd: Peri<'d, AnyPin>, + txd: Peri<'d, AnyPin>, + cts: Option>, + rts: Option>, config: Config, rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], @@ -372,20 +370,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { /// Reader part of the buffered UARTE driver. pub struct BufferedUarteTx<'d, U: UarteInstance> { - _peri: PeripheralRef<'d, U>, + _peri: Peri<'d, U>, } impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { /// Create a new BufferedUarteTx without hardware flow control. pub fn new( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, _irq: impl interrupt::typelevel::Binding> + 'd, - txd: impl Peripheral

+ 'd, + txd: Peri<'d, impl GpioPin>, config: Config, tx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, txd); - Self::new_inner(uarte, txd.map_into(), None, config, tx_buffer) + Self::new_inner(uarte, txd.into(), None, config, tx_buffer) } /// Create a new BufferedUarte with hardware flow control (RTS/CTS) @@ -394,21 +391,20 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { /// /// Panics if `rx_buffer.len()` is odd. pub fn new_with_cts( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, _irq: impl interrupt::typelevel::Binding> + 'd, - txd: impl Peripheral

+ 'd, - cts: impl Peripheral

+ 'd, + txd: Peri<'d, impl GpioPin>, + cts: Peri<'d, impl GpioPin>, config: Config, tx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, txd, cts); - Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config, tx_buffer) + Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer) } fn new_inner( - peri: PeripheralRef<'d, U>, - txd: PeripheralRef<'d, AnyPin>, - cts: Option>, + peri: Peri<'d, U>, + txd: Peri<'d, AnyPin>, + cts: Option>, config: Config, tx_buffer: &'d mut [u8], ) -> Self { @@ -426,9 +422,9 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { } fn new_innerer( - peri: PeripheralRef<'d, U>, - txd: PeripheralRef<'d, AnyPin>, - cts: Option>, + peri: Peri<'d, U>, + txd: Peri<'d, AnyPin>, + cts: Option>, tx_buffer: &'d mut [u8], ) -> Self { let r = U::regs(); @@ -542,7 +538,7 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { /// Reader part of the buffered UARTE driver. pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { - _peri: PeripheralRef<'d, U>, + _peri: Peri<'d, U>, timer: Timer<'d, T>, _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, @@ -557,24 +553,23 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { /// Panics if `rx_buffer.len()` is odd. #[allow(clippy::too_many_arguments)] pub fn new( - uarte: impl Peripheral

+ 'd, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, - ppi_group: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, impl ConfigurableChannel>, + ppi_ch2: Peri<'d, impl ConfigurableChannel>, + ppi_group: Peri<'d, impl Group>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, config: Config, rx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, timer, rxd, ppi_ch1, ppi_ch2, ppi_group); Self::new_inner( uarte, timer, - ppi_ch1.map_into(), - ppi_ch2.map_into(), - ppi_group.map_into(), - rxd.map_into(), + ppi_ch1.into(), + ppi_ch2.into(), + ppi_group.into(), + rxd.into(), None, config, rx_buffer, @@ -588,26 +583,25 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { /// Panics if `rx_buffer.len()` is odd. #[allow(clippy::too_many_arguments)] pub fn new_with_rts( - uarte: impl Peripheral

+ 'd, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, - ppi_group: impl Peripheral

+ 'd, + uarte: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, impl ConfigurableChannel>, + ppi_ch2: Peri<'d, impl ConfigurableChannel>, + ppi_group: Peri<'d, impl Group>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - rts: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + rts: Peri<'d, impl GpioPin>, config: Config, rx_buffer: &'d mut [u8], ) -> Self { - into_ref!(uarte, timer, rxd, rts, ppi_ch1, ppi_ch2, ppi_group); Self::new_inner( uarte, timer, - ppi_ch1.map_into(), - ppi_ch2.map_into(), - ppi_group.map_into(), - rxd.map_into(), - Some(rts.map_into()), + ppi_ch1.into(), + ppi_ch2.into(), + ppi_group.into(), + rxd.into(), + Some(rts.into()), config, rx_buffer, ) @@ -615,13 +609,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { #[allow(clippy::too_many_arguments)] fn new_inner( - peri: PeripheralRef<'d, U>, - timer: PeripheralRef<'d, T>, - ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_group: PeripheralRef<'d, AnyGroup>, - rxd: PeripheralRef<'d, AnyPin>, - rts: Option>, + peri: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, AnyConfigurableChannel>, + ppi_ch2: Peri<'d, AnyConfigurableChannel>, + ppi_group: Peri<'d, AnyGroup>, + rxd: Peri<'d, AnyPin>, + rts: Option>, config: Config, rx_buffer: &'d mut [u8], ) -> Self { @@ -640,13 +634,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { #[allow(clippy::too_many_arguments)] fn new_innerer( - peri: PeripheralRef<'d, U>, - timer: PeripheralRef<'d, T>, - ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, - ppi_group: PeripheralRef<'d, AnyGroup>, - rxd: PeripheralRef<'d, AnyPin>, - rts: Option>, + peri: Peri<'d, U>, + timer: Peri<'d, T>, + ppi_ch1: Peri<'d, AnyConfigurableChannel>, + ppi_ch2: Peri<'d, AnyConfigurableChannel>, + ppi_group: Peri<'d, AnyGroup>, + rxd: Peri<'d, AnyPin>, + rts: Option>, rx_buffer: &'d mut [u8], ) -> Self { assert!(rx_buffer.len() % 2 == 0); diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs index 7f9abdac4..028396c7c 100644 --- a/embassy-nrf/src/egu.rs +++ b/embassy-nrf/src/egu.rs @@ -7,20 +7,19 @@ use core::marker::PhantomData; -use embassy_hal_internal::into_ref; +use embassy_hal_internal::PeripheralType; use crate::ppi::{Event, Task}; -use crate::{interrupt, pac, Peripheral, PeripheralRef}; +use crate::{interrupt, pac, Peri}; /// An instance of the EGU. pub struct Egu<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Egu<'d, T> { /// Create a new EGU instance. - pub fn new(_p: impl Peripheral

+ 'd) -> Self { - into_ref!(_p); + pub fn new(_p: Peri<'d, T>) -> Self { Self { _p } } @@ -39,7 +38,7 @@ pub(crate) trait SealedInstance { /// Basic Egu instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index c78fa4df5..d02da9ac5 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -5,14 +5,14 @@ use core::convert::Infallible; use core::hint::unreachable_unchecked; use cfg_if::cfg_if; -use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; +use crate::pac; use crate::pac::common::{Reg, RW}; use crate::pac::gpio; use crate::pac::gpio::vals; #[cfg(not(feature = "_nrf51"))] use crate::pac::shared::{regs::Psel, vals::Connect}; -use crate::{pac, Peripheral}; /// A GPIO port with up to 32 pins. #[derive(Debug, Eq, PartialEq)] @@ -49,7 +49,7 @@ pub struct Input<'d> { impl<'d> Input<'d> { /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { let mut pin = Flex::new(pin); pin.set_as_input(pull); @@ -210,7 +210,7 @@ pub struct Output<'d> { impl<'d> Output<'d> { /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level, drive: OutputDrive) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, drive: OutputDrive) -> Self { let mut pin = Flex::new(pin); match initial_output { Level::High => pin.set_high(), @@ -310,7 +310,7 @@ fn convert_pull(pull: Pull) -> vals::Pull { /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// mode. pub struct Flex<'d> { - pub(crate) pin: PeripheralRef<'d, AnyPin>, + pub(crate) pin: Peri<'d, AnyPin>, } impl<'d> Flex<'d> { @@ -319,10 +319,9 @@ impl<'d> Flex<'d> { /// The pin remains disconnected. The initial output level is unspecified, but can be changed /// before the pin is put into output mode. #[inline] - pub fn new(pin: impl Peripheral

+ 'd) -> Self { - into_ref!(pin); + pub fn new(pin: Peri<'d, impl Pin>) -> Self { // Pin will be in disconnected state. - Self { pin: pin.map_into() } + Self { pin: pin.into() } } /// Put the pin into input mode. @@ -503,7 +502,7 @@ pub(crate) trait SealedPin { /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. #[allow(private_bounds)] -pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// Number of the pin within the port (0..31) #[inline] fn pin(&self) -> u8 { @@ -529,19 +528,11 @@ pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static fn psel_bits(&self) -> pac::shared::regs::Psel { pac::shared::regs::Psel(self.pin_port() as u32) } - - /// Convert from concrete pin type PX_XX to type erased `AnyPin`. - #[inline] - fn degrade(self) -> AnyPin { - AnyPin { - pin_port: self.pin_port(), - } - } } /// Type-erased GPIO pin pub struct AnyPin { - pin_port: u8, + pub(crate) pin_port: u8, } impl AnyPin { @@ -550,8 +541,8 @@ impl AnyPin { /// # Safety /// - `pin_port` should not in use by another driver. #[inline] - pub unsafe fn steal(pin_port: u8) -> Self { - Self { pin_port } + pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> { + Peri::new_unchecked(Self { pin_port }) } } @@ -573,7 +564,7 @@ pub(crate) trait PselBits { } #[cfg(not(feature = "_nrf51"))] -impl<'a, P: Pin> PselBits for Option> { +impl<'a, P: Pin> PselBits for Option> { #[inline] fn psel_bits(&self) -> pac::shared::regs::Psel { match self { @@ -611,8 +602,10 @@ macro_rules! impl_pin { } impl From for crate::gpio::AnyPin { - fn from(val: peripherals::$type) -> Self { - crate::gpio::Pin::degrade(val) + fn from(_val: peripherals::$type) -> Self { + Self { + pin_port: $port_num * 32 + $pin_num, + } } } }; diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 8771f9f08..d169b49f9 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -4,7 +4,7 @@ use core::convert::Infallible; use core::future::{poll_fn, Future}; use core::task::{Context, Poll}; -use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; @@ -189,7 +189,7 @@ impl Iterator for BitIter { /// GPIOTE channel driver in input mode pub struct InputChannel<'d> { - ch: PeripheralRef<'d, AnyChannel>, + ch: Peri<'d, AnyChannel>, pin: Input<'d>, } @@ -204,9 +204,7 @@ impl<'d> Drop for InputChannel<'d> { impl<'d> InputChannel<'d> { /// Create a new GPIOTE input channel driver. - pub fn new(ch: impl Peripheral

+ 'd, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { - into_ref!(ch); - + pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { let g = regs(); let num = ch.number(); @@ -228,7 +226,7 @@ impl<'d> InputChannel<'d> { g.events_in(num).write_value(0); - InputChannel { ch: ch.map_into(), pin } + InputChannel { ch: ch.into(), pin } } /// Asynchronously wait for an event in this channel. @@ -261,7 +259,7 @@ impl<'d> InputChannel<'d> { /// GPIOTE channel driver in output mode pub struct OutputChannel<'d> { - ch: PeripheralRef<'d, AnyChannel>, + ch: Peri<'d, AnyChannel>, _pin: Output<'d>, } @@ -276,8 +274,7 @@ impl<'d> Drop for OutputChannel<'d> { impl<'d> OutputChannel<'d> { /// Create a new GPIOTE output channel driver. - pub fn new(ch: impl Peripheral

+ 'd, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { - into_ref!(ch); + pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { let g = regs(); let num = ch.number(); @@ -301,7 +298,7 @@ impl<'d> OutputChannel<'d> { }); OutputChannel { - ch: ch.map_into(), + ch: ch.into(), _pin: pin, } } @@ -351,14 +348,12 @@ impl<'d> OutputChannel<'d> { #[must_use = "futures do nothing unless you `.await` or poll them"] pub(crate) struct PortInputFuture<'a> { - pin: PeripheralRef<'a, AnyPin>, + pin: Peri<'a, AnyPin>, } impl<'a> PortInputFuture<'a> { - fn new(pin: impl Peripheral

+ 'a) -> Self { - Self { - pin: pin.into_ref().map_into(), - } + fn new(pin: Peri<'a, impl GpioPin>) -> Self { + Self { pin: pin.into() } } } @@ -415,13 +410,13 @@ impl<'d> Flex<'d> { /// Wait until the pin is high. If it is already high, return immediately. pub async fn wait_for_high(&mut self) { self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); - PortInputFuture::new(&mut self.pin).await + PortInputFuture::new(self.pin.reborrow()).await } /// Wait until the pin is low. If it is already low, return immediately. pub async fn wait_for_low(&mut self) { self.pin.conf().modify(|w| w.set_sense(Sense::LOW)); - PortInputFuture::new(&mut self.pin).await + PortInputFuture::new(self.pin.reborrow()).await } /// Wait for the pin to undergo a transition from low to high. @@ -443,7 +438,7 @@ impl<'d> Flex<'d> { } else { self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); } - PortInputFuture::new(&mut self.pin).await + PortInputFuture::new(self.pin.reborrow()).await } } @@ -455,24 +450,14 @@ trait SealedChannel {} /// /// Implemented by all GPIOTE channels. #[allow(private_bounds)] -pub trait Channel: SealedChannel + Into + Sized + 'static { +pub trait Channel: PeripheralType + SealedChannel + Into + Sized + 'static { /// Get the channel number. fn number(&self) -> usize; - - /// Convert this channel to a type-erased `AnyChannel`. - /// - /// This allows using several channels in situations that might require - /// them to be the same type, like putting them in an array. - fn degrade(self) -> AnyChannel { - AnyChannel { - number: self.number() as u8, - } - } } /// Type-erased channel. /// -/// Obtained by calling `Channel::degrade`. +/// Obtained by calling `Channel::into()`. /// /// This allows using several channels in situations that might require /// them to be the same type, like putting them in an array. @@ -498,7 +483,9 @@ macro_rules! impl_channel { impl From for AnyChannel { fn from(val: peripherals::$type) -> Self { - Channel::degrade(val) + Self { + number: val.number() as u8, + } } } }; diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index 384a1637b..a7dde8cd7 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs @@ -10,14 +10,14 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; use crate::interrupt::typelevel::Interrupt; use crate::pac::i2s::vals; use crate::util::slice_in_ram_or; -use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; +use crate::{interrupt, pac, EASY_DMA_SIZE}; /// Type alias for `MultiBuffering` with 2 buffers. pub type DoubleBuffering = MultiBuffering; @@ -406,12 +406,12 @@ impl interrupt::typelevel::Handler for InterruptHandl /// I2S driver. pub struct I2S<'d, T: Instance> { - i2s: PeripheralRef<'d, T>, - mck: Option>, - sck: PeripheralRef<'d, AnyPin>, - lrck: PeripheralRef<'d, AnyPin>, - sdin: Option>, - sdout: Option>, + i2s: Peri<'d, T>, + mck: Option>, + sck: Peri<'d, AnyPin>, + lrck: Peri<'d, AnyPin>, + sdin: Option>, + sdout: Option>, master_clock: Option, config: Config, } @@ -419,20 +419,19 @@ pub struct I2S<'d, T: Instance> { impl<'d, T: Instance> I2S<'d, T> { /// Create a new I2S in master mode pub fn new_master( - i2s: impl Peripheral

+ 'd, + i2s: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - mck: impl Peripheral

+ 'd, - sck: impl Peripheral

+ 'd, - lrck: impl Peripheral

+ 'd, + mck: Peri<'d, impl GpioPin>, + sck: Peri<'d, impl GpioPin>, + lrck: Peri<'d, impl GpioPin>, master_clock: MasterClock, config: Config, ) -> Self { - into_ref!(i2s, mck, sck, lrck); Self { i2s, - mck: Some(mck.map_into()), - sck: sck.map_into(), - lrck: lrck.map_into(), + mck: Some(mck.into()), + sck: sck.into(), + lrck: lrck.into(), sdin: None, sdout: None, master_clock: Some(master_clock), @@ -442,18 +441,17 @@ impl<'d, T: Instance> I2S<'d, T> { /// Create a new I2S in slave mode pub fn new_slave( - i2s: impl Peripheral

+ 'd, + i2s: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sck: impl Peripheral

+ 'd, - lrck: impl Peripheral

+ 'd, + sck: Peri<'d, impl GpioPin>, + lrck: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(i2s, sck, lrck); Self { i2s, mck: None, - sck: sck.map_into(), - lrck: lrck.map_into(), + sck: sck.into(), + lrck: lrck.into(), sdin: None, sdout: None, master_clock: None, @@ -464,10 +462,10 @@ impl<'d, T: Instance> I2S<'d, T> { /// I2S output only pub fn output( mut self, - sdout: impl Peripheral

+ 'd, + sdout: Peri<'d, impl GpioPin>, buffers: MultiBuffering, ) -> OutputStream<'d, T, S, NB, NS> { - self.sdout = Some(sdout.into_ref().map_into()); + self.sdout = Some(sdout.into()); OutputStream { _p: self.build(), buffers, @@ -477,10 +475,10 @@ impl<'d, T: Instance> I2S<'d, T> { /// I2S input only pub fn input( mut self, - sdin: impl Peripheral

+ 'd, + sdin: Peri<'d, impl GpioPin>, buffers: MultiBuffering, ) -> InputStream<'d, T, S, NB, NS> { - self.sdin = Some(sdin.into_ref().map_into()); + self.sdin = Some(sdin.into()); InputStream { _p: self.build(), buffers, @@ -490,13 +488,13 @@ impl<'d, T: Instance> I2S<'d, T> { /// I2S full duplex (input and output) pub fn full_duplex( mut self, - sdin: impl Peripheral

+ 'd, - sdout: impl Peripheral

+ 'd, + sdin: Peri<'d, impl GpioPin>, + sdout: Peri<'d, impl GpioPin>, buffers_out: MultiBuffering, buffers_in: MultiBuffering, ) -> FullDuplexStream<'d, T, S, NB, NS> { - self.sdout = Some(sdout.into_ref().map_into()); - self.sdin = Some(sdin.into_ref().map_into()); + self.sdout = Some(sdout.into()); + self.sdin = Some(sdin.into()); FullDuplexStream { _p: self.build(), @@ -505,7 +503,7 @@ impl<'d, T: Instance> I2S<'d, T> { } } - fn build(self) -> PeripheralRef<'d, T> { + fn build(self) -> Peri<'d, T> { self.apply_config(); self.select_pins(); self.setup_interrupt(); @@ -702,7 +700,7 @@ impl<'d, T: Instance> I2S<'d, T> { /// I2S output pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, buffers: MultiBuffering, } @@ -756,7 +754,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream< /// I2S input pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, buffers: MultiBuffering, } @@ -811,7 +809,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<' /// I2S full duplex stream (input & output) pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, buffers_out: MultiBuffering, buffers_in: MultiBuffering, } @@ -1148,7 +1146,7 @@ pub(crate) trait SealedInstance { /// I2S peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 5cd0efa58..d2ff054f4 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -263,7 +263,7 @@ pub use chip::pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; -pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +pub use embassy_hal_internal::{Peri, PeripheralType}; pub use crate::chip::interrupt; #[cfg(feature = "rt")] diff --git a/embassy-nrf/src/nfct.rs b/embassy-nrf/src/nfct.rs index 8b4b6dfe0..8d70ec954 100644 --- a/embassy-nrf/src/nfct.rs +++ b/embassy-nrf/src/nfct.rs @@ -13,7 +13,6 @@ use core::future::poll_fn; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode}; @@ -22,7 +21,7 @@ use crate::pac::nfct::vals; use crate::pac::NFCT; use crate::peripherals::NFCT; use crate::util::slice_in_ram; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac, Peri}; /// NFCID1 (aka UID) of different sizes. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] @@ -96,7 +95,7 @@ pub enum Error { /// NFC tag emulator driver. pub struct NfcT<'d> { - _p: PeripheralRef<'d, NFCT>, + _p: Peri<'d, NFCT>, rx_buf: [u8; 256], tx_buf: [u8; 256], } @@ -104,12 +103,10 @@ pub struct NfcT<'d> { impl<'d> NfcT<'d> { /// Create an Nfc Tag driver pub fn new( - _p: impl Peripheral

+ 'd, + _p: Peri<'d, NFCT>, _irq: impl interrupt::typelevel::Binding + 'd, config: &Config, ) -> Self { - into_ref!(_p); - let r = pac::NFCT; unsafe { diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs index 6973b4847..c46af0b34 100644 --- a/embassy-nrf/src/nvmc.rs +++ b/embassy-nrf/src/nvmc.rs @@ -2,14 +2,13 @@ use core::{ptr, slice}; -use embassy_hal_internal::{into_ref, PeripheralRef}; use embedded_storage::nor_flash::{ ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, }; use crate::pac::nvmc::vals; use crate::peripherals::NVMC; -use crate::{pac, Peripheral}; +use crate::{pac, Peri}; #[cfg(not(feature = "_nrf5340-net"))] /// Erase size of NVMC flash in bytes. @@ -42,13 +41,12 @@ impl NorFlashError for Error { /// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits. pub struct Nvmc<'d> { - _p: PeripheralRef<'d, NVMC>, + _p: Peri<'d, NVMC>, } impl<'d> Nvmc<'d> { /// Create Nvmc driver. - pub fn new(_p: impl Peripheral

+ 'd) -> Self { - into_ref!(_p); + pub fn new(_p: Peri<'d, NVMC>) -> Self { Self { _p } } diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index 483d1a644..c2a4ba65f 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs @@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use fixed::types::I7F1; @@ -25,7 +25,7 @@ pub use crate::pac::pdm::vals::Freq as Frequency; feature = "_nrf91", ))] pub use crate::pac::pdm::vals::Ratio; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// Interrupt handler pub struct InterruptHandler { @@ -54,7 +54,7 @@ impl interrupt::typelevel::Handler for InterruptHandl /// PDM microphone interface pub struct Pdm<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, } /// PDM error @@ -89,24 +89,16 @@ pub enum SamplerState { impl<'d, T: Instance> Pdm<'d, T> { /// Create PDM driver pub fn new( - pdm: impl Peripheral

+ 'd, + pdm: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - clk: impl Peripheral

+ 'd, - din: impl Peripheral

+ 'd, + clk: Peri<'d, impl GpioPin>, + din: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(pdm, clk, din); - Self::new_inner(pdm, clk.map_into(), din.map_into(), config) + Self::new_inner(pdm, clk.into(), din.into(), config) } - fn new_inner( - pdm: PeripheralRef<'d, T>, - clk: PeripheralRef<'d, AnyPin>, - din: PeripheralRef<'d, AnyPin>, - config: Config, - ) -> Self { - into_ref!(pdm); - + fn new_inner(pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self { let r = T::regs(); // setup gpio pins @@ -452,7 +444,7 @@ pub(crate) trait SealedInstance { /// PDM peripheral instance #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 3c7b96df7..686f66987 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs @@ -1,7 +1,5 @@ -use embassy_hal_internal::into_ref; - use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; -use crate::{pac, Peripheral}; +use crate::{pac, Peri}; const DPPI_ENABLE_BIT: u32 = 0x8000_0000; const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; @@ -12,14 +10,14 @@ pub(crate) fn regs() -> pac::dppic::Dppic { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { /// Configure PPI channel to trigger `task` on `event`. - pub fn new_one_to_one(ch: impl Peripheral

+ 'd, event: Event<'d>, task: Task<'d>) -> Self { + pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self { Ppi::new_many_to_many(ch, [event], [task]) } } impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { /// Configure PPI channel to trigger both `task1` and `task2` on `event`. - pub fn new_one_to_two(ch: impl Peripheral

+ 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { + pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { Ppi::new_many_to_many(ch, [event], [task1, task2]) } } @@ -28,13 +26,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi Ppi<'d, C, EVENT_COUNT, TASK_COUNT> { /// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires. - pub fn new_many_to_many( - ch: impl Peripheral

+ 'd, - events: [Event<'d>; EVENT_COUNT], - tasks: [Task<'d>; TASK_COUNT], - ) -> Self { - into_ref!(ch); - + pub fn new_many_to_many(ch: Peri<'d, C>, events: [Event<'d>; EVENT_COUNT], tasks: [Task<'d>; TASK_COUNT]) -> Self { let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK); for task in tasks { if unsafe { task.subscribe_reg().read_volatile() } != 0 { diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 325e4ce00..531777205 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -18,10 +18,10 @@ use core::marker::PhantomData; use core::ptr::NonNull; -use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use crate::pac::common::{Reg, RW, W}; -use crate::{peripherals, Peripheral}; +use crate::peripherals; #[cfg_attr(feature = "_dppi", path = "dppi.rs")] #[cfg_attr(feature = "_ppi", path = "ppi.rs")] @@ -30,7 +30,7 @@ pub(crate) use _version::*; /// PPI channel driver. pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { - ch: PeripheralRef<'d, C>, + ch: Peri<'d, C>, #[cfg(feature = "_dppi")] events: [Event<'d>; EVENT_COUNT], #[cfg(feature = "_dppi")] @@ -39,16 +39,14 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize /// PPI channel group driver. pub struct PpiGroup<'d, G: Group> { - g: PeripheralRef<'d, G>, + g: Peri<'d, G>, } impl<'d, G: Group> PpiGroup<'d, G> { /// Create a new PPI group driver. /// /// The group is initialized as containing no channels. - pub fn new(g: impl Peripheral

+ 'd) -> Self { - into_ref!(g); - + pub fn new(g: Peri<'d, G>) -> Self { let r = regs(); let n = g.number(); r.chg(n).write(|_| ()); @@ -210,34 +208,22 @@ pub(crate) trait SealedGroup {} /// Interface for PPI channels. #[allow(private_bounds)] -pub trait Channel: SealedChannel + Peripheral

+ Sized + 'static { +pub trait Channel: SealedChannel + PeripheralType + Sized + 'static { /// Returns the number of the channel fn number(&self) -> usize; } /// Interface for PPI channels that can be configured. -pub trait ConfigurableChannel: Channel + Into { - /// Convert into a type erased configurable channel. - fn degrade(self) -> AnyConfigurableChannel; -} +pub trait ConfigurableChannel: Channel + Into {} /// Interface for PPI channels that cannot be configured. -pub trait StaticChannel: Channel + Into { - /// Convert into a type erased static channel. - fn degrade(self) -> AnyStaticChannel; -} +pub trait StaticChannel: Channel + Into {} /// Interface for a group of PPI channels. #[allow(private_bounds)] -pub trait Group: SealedGroup + Peripheral

+ Into + Sized + 'static { +pub trait Group: SealedGroup + PeripheralType + Into + Sized + 'static { /// Returns the number of the group. fn number(&self) -> usize; - /// Convert into a type erased group. - fn degrade(self) -> AnyGroup { - AnyGroup { - number: self.number() as u8, - } - } } // ====================== @@ -255,11 +241,7 @@ impl Channel for AnyStaticChannel { self.number as usize } } -impl StaticChannel for AnyStaticChannel { - fn degrade(self) -> AnyStaticChannel { - self - } -} +impl StaticChannel for AnyStaticChannel {} /// The any configurable channel can represent any configurable channel at runtime. /// This can be used to have fewer generic parameters in some places. @@ -273,11 +255,7 @@ impl Channel for AnyConfigurableChannel { self.number as usize } } -impl ConfigurableChannel for AnyConfigurableChannel { - fn degrade(self) -> AnyConfigurableChannel { - self - } -} +impl ConfigurableChannel for AnyConfigurableChannel {} #[cfg(not(feature = "_nrf51"))] macro_rules! impl_ppi_channel { @@ -291,35 +269,23 @@ macro_rules! impl_ppi_channel { }; ($type:ident, $number:expr => static) => { impl_ppi_channel!($type, $number); - impl crate::ppi::StaticChannel for peripherals::$type { - fn degrade(self) -> crate::ppi::AnyStaticChannel { - use crate::ppi::Channel; - crate::ppi::AnyStaticChannel { - number: self.number() as u8, - } - } - } - + impl crate::ppi::StaticChannel for peripherals::$type {} impl From for crate::ppi::AnyStaticChannel { fn from(val: peripherals::$type) -> Self { - crate::ppi::StaticChannel::degrade(val) + Self { + number: crate::ppi::Channel::number(&val) as u8, + } } } }; ($type:ident, $number:expr => configurable) => { impl_ppi_channel!($type, $number); - impl crate::ppi::ConfigurableChannel for peripherals::$type { - fn degrade(self) -> crate::ppi::AnyConfigurableChannel { - use crate::ppi::Channel; - crate::ppi::AnyConfigurableChannel { - number: self.number() as u8, - } - } - } - + impl crate::ppi::ConfigurableChannel for peripherals::$type {} impl From for crate::ppi::AnyConfigurableChannel { fn from(val: peripherals::$type) -> Self { - crate::ppi::ConfigurableChannel::degrade(val) + Self { + number: crate::ppi::Channel::number(&val) as u8, + } } } }; @@ -351,7 +317,9 @@ macro_rules! impl_group { impl From for crate::ppi::AnyGroup { fn from(val: peripherals::$type) -> Self { - crate::ppi::Group::degrade(val) + Self { + number: crate::ppi::Group::number(&val) as u8, + } } } }; diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index a1beb9dcd..e04dacbc0 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -1,7 +1,5 @@ -use embassy_hal_internal::into_ref; - use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; -use crate::{pac, Peripheral}; +use crate::{pac, Peri}; impl<'d> Task<'d> { fn reg_val(&self) -> u32 { @@ -21,9 +19,7 @@ pub(crate) fn regs() -> pac::ppi::Ppi { #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { /// Configure PPI channel to trigger `task`. - pub fn new_zero_to_one(ch: impl Peripheral

+ 'd, task: Task) -> Self { - into_ref!(ch); - + pub fn new_zero_to_one(ch: Peri<'d, C>, task: Task) -> Self { let r = regs(); let n = ch.number(); r.fork(n).tep().write_value(task.reg_val()); @@ -34,9 +30,7 @@ impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { /// Configure PPI channel to trigger `task` on `event`. - pub fn new_one_to_one(ch: impl Peripheral

+ 'd, event: Event<'d>, task: Task<'d>) -> Self { - into_ref!(ch); - + pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self { let r = regs(); let n = ch.number(); r.ch(n).eep().write_value(event.reg_val()); @@ -49,9 +43,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { /// Configure PPI channel to trigger both `task1` and `task2` on `event`. - pub fn new_one_to_two(ch: impl Peripheral

+ 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { - into_ref!(ch); - + pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { let r = regs(); let n = ch.number(); r.ch(n).eep().write_value(event.reg_val()); diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 6247ff6a5..a2e153e26 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -4,34 +4,34 @@ use core::sync::atomic::{compiler_fence, Ordering}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; use crate::pac::gpio::vals as gpiovals; use crate::pac::pwm::vals; use crate::ppi::{Event, Task}; use crate::util::slice_in_ram_or; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// SimplePwm is the traditional pwm interface you're probably used to, allowing /// to simply set a duty cycle across up to four channels. pub struct SimplePwm<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, duty: [u16; 4], - ch0: Option>, - ch1: Option>, - ch2: Option>, - ch3: Option>, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, } /// SequencePwm allows you to offload the updating of a sequence of duty cycles /// to up to four channels, as well as repeat that sequence n times. pub struct SequencePwm<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, - ch0: Option>, - ch1: Option>, - ch2: Option>, - ch3: Option>, + _peri: Peri<'d, T>, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, } /// PWM error @@ -54,78 +54,61 @@ pub const PWM_CLK_HZ: u32 = 16_000_000; impl<'d, T: Instance> SequencePwm<'d, T> { /// Create a new 1-channel PWM #[allow(unused_unsafe)] - pub fn new_1ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - config: Config, - ) -> Result { - into_ref!(ch0); - Self::new_inner(pwm, Some(ch0.map_into()), None, None, None, config) + pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result { + Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) } /// Create a new 2-channel PWM #[allow(unused_unsafe)] pub fn new_2ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, + pwm: Peri<'d, T>, + ch0: Peri<'d, impl GpioPin>, + ch1: Peri<'d, impl GpioPin>, config: Config, ) -> Result { - into_ref!(ch0, ch1); - Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config) + Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None, config) } /// Create a new 3-channel PWM #[allow(unused_unsafe)] pub fn new_3ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, - ch2: impl Peripheral

+ 'd, + pwm: Peri<'d, T>, + ch0: Peri<'d, impl GpioPin>, + ch1: Peri<'d, impl GpioPin>, + ch2: Peri<'d, impl GpioPin>, config: Config, ) -> Result { - into_ref!(ch0, ch1, ch2); - Self::new_inner( - pwm, - Some(ch0.map_into()), - Some(ch1.map_into()), - Some(ch2.map_into()), - None, - config, - ) + Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None, config) } /// Create a new 4-channel PWM #[allow(unused_unsafe)] pub fn new_4ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, - ch2: impl Peripheral

+ 'd, - ch3: impl Peripheral

+ 'd, + pwm: Peri<'d, T>, + ch0: Peri<'d, impl GpioPin>, + ch1: Peri<'d, impl GpioPin>, + ch2: Peri<'d, impl GpioPin>, + ch3: Peri<'d, impl GpioPin>, config: Config, ) -> Result { - into_ref!(ch0, ch1, ch2, ch3); Self::new_inner( pwm, - Some(ch0.map_into()), - Some(ch1.map_into()), - Some(ch2.map_into()), - Some(ch3.map_into()), + Some(ch0.into()), + Some(ch1.into()), + Some(ch2.into()), + Some(ch3.into()), config, ) } fn new_inner( - _pwm: impl Peripheral

+ 'd, - ch0: Option>, - ch1: Option>, - ch2: Option>, - ch3: Option>, + _pwm: Peri<'d, T>, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, config: Config, ) -> Result { - into_ref!(_pwm); - let r = T::regs(); if let Some(pin) = &ch0 { @@ -610,74 +593,54 @@ pub enum CounterMode { impl<'d, T: Instance> SimplePwm<'d, T> { /// Create a new 1-channel PWM #[allow(unused_unsafe)] - pub fn new_1ch(pwm: impl Peripheral

+ 'd, ch0: impl Peripheral

+ 'd) -> Self { - unsafe { - into_ref!(ch0); - Self::new_inner(pwm, Some(ch0.map_into()), None, None, None) - } + pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { + unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } } /// Create a new 2-channel PWM #[allow(unused_unsafe)] - pub fn new_2ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, - ) -> Self { - into_ref!(ch0, ch1); - Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None) + pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { + Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) } /// Create a new 3-channel PWM #[allow(unused_unsafe)] pub fn new_3ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, - ch2: impl Peripheral

+ 'd, + pwm: Peri<'d, T>, + ch0: Peri<'d, impl GpioPin>, + ch1: Peri<'d, impl GpioPin>, + ch2: Peri<'d, impl GpioPin>, ) -> Self { - unsafe { - into_ref!(ch0, ch1, ch2); - Self::new_inner( - pwm, - Some(ch0.map_into()), - Some(ch1.map_into()), - Some(ch2.map_into()), - None, - ) - } + unsafe { Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None) } } /// Create a new 4-channel PWM #[allow(unused_unsafe)] pub fn new_4ch( - pwm: impl Peripheral

+ 'd, - ch0: impl Peripheral

+ 'd, - ch1: impl Peripheral

+ 'd, - ch2: impl Peripheral

+ 'd, - ch3: impl Peripheral

+ 'd, + pwm: Peri<'d, T>, + ch0: Peri<'d, impl GpioPin>, + ch1: Peri<'d, impl GpioPin>, + ch2: Peri<'d, impl GpioPin>, + ch3: Peri<'d, impl GpioPin>, ) -> Self { unsafe { - into_ref!(ch0, ch1, ch2, ch3); Self::new_inner( pwm, - Some(ch0.map_into()), - Some(ch1.map_into()), - Some(ch2.map_into()), - Some(ch3.map_into()), + Some(ch0.into()), + Some(ch1.into()), + Some(ch2.into()), + Some(ch3.into()), ) } } fn new_inner( - _pwm: impl Peripheral

+ 'd, - ch0: Option>, - ch1: Option>, - ch2: Option>, - ch3: Option>, + _pwm: Peri<'d, T>, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, ) -> Self { - into_ref!(_pwm); - let r = T::regs(); for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() { @@ -896,7 +859,7 @@ pub(crate) trait SealedInstance { /// PWM peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index efd2a134c..69bfab0bb 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs @@ -6,18 +6,18 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; use crate::interrupt::typelevel::Interrupt; use crate::pac::gpio::vals as gpiovals; use crate::pac::qdec::vals; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// Quadrature decoder driver. pub struct Qdec<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } /// QDEC config @@ -62,34 +62,32 @@ impl interrupt::typelevel::Handler for InterruptHandl impl<'d, T: Instance> Qdec<'d, T> { /// Create a new QDEC. pub fn new( - qdec: impl Peripheral

+ 'd, + qdec: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - a: impl Peripheral

+ 'd, - b: impl Peripheral

+ 'd, + a: Peri<'d, impl GpioPin>, + b: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(qdec, a, b); - Self::new_inner(qdec, a.map_into(), b.map_into(), None, config) + Self::new_inner(qdec, a.into(), b.into(), None, config) } /// Create a new QDEC, with a pin for LED output. pub fn new_with_led( - qdec: impl Peripheral

+ 'd, + qdec: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - a: impl Peripheral

+ 'd, - b: impl Peripheral

+ 'd, - led: impl Peripheral

+ 'd, + a: Peri<'d, impl GpioPin>, + b: Peri<'d, impl GpioPin>, + led: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(qdec, a, b, led); - Self::new_inner(qdec, a.map_into(), b.map_into(), Some(led.map_into()), config) + Self::new_inner(qdec, a.into(), b.into(), Some(led.into()), config) } fn new_inner( - p: PeripheralRef<'d, T>, - a: PeripheralRef<'d, AnyPin>, - b: PeripheralRef<'d, AnyPin>, - led: Option>, + p: Peri<'d, T>, + a: Peri<'d, AnyPin>, + b: Peri<'d, AnyPin>, + led: Option>, config: Config, ) -> Self { let r = T::regs(); @@ -272,7 +270,7 @@ pub(crate) trait SealedInstance { /// qdec peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index 17e127700..e6e829f6e 100755 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs @@ -8,7 +8,7 @@ use core::ptr; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; @@ -19,7 +19,7 @@ use crate::pac::qspi::vals; pub use crate::pac::qspi::vals::{ Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode, }; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// Deep power-down config. pub struct DeepPowerDownConfig { @@ -139,7 +139,7 @@ impl interrupt::typelevel::Handler for InterruptHandl /// QSPI flash driver. pub struct Qspi<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, dpm_enabled: bool, capacity: u32, } @@ -147,18 +147,16 @@ pub struct Qspi<'d, T: Instance> { impl<'d, T: Instance> Qspi<'d, T> { /// Create a new QSPI driver. pub fn new( - qspi: impl Peripheral

+ 'd, + qspi: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sck: impl Peripheral

+ 'd, - csn: impl Peripheral

+ 'd, - io0: impl Peripheral

+ 'd, - io1: impl Peripheral

+ 'd, - io2: impl Peripheral

+ 'd, - io3: impl Peripheral

+ 'd, + sck: Peri<'d, impl GpioPin>, + csn: Peri<'d, impl GpioPin>, + io0: Peri<'d, impl GpioPin>, + io1: Peri<'d, impl GpioPin>, + io2: Peri<'d, impl GpioPin>, + io3: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(qspi, sck, csn, io0, io1, io2, io3); - let r = T::regs(); macro_rules! config_pin { @@ -664,7 +662,7 @@ pub(crate) trait SealedInstance { /// QSPI peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/radio/ble.rs b/embassy-nrf/src/radio/ble.rs index 682ca1c79..d42bbe5f6 100644 --- a/embassy-nrf/src/radio/ble.rs +++ b/embassy-nrf/src/radio/ble.rs @@ -5,7 +5,6 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; pub use pac::radio::vals::Mode; #[cfg(not(feature = "_nrf51"))] use pac::radio::vals::Plen as PreambleLength; @@ -15,20 +14,19 @@ use crate::pac::radio::vals; use crate::radio::*; pub use crate::radio::{Error, TxPower}; use crate::util::slice_in_ram_or; +use crate::Peri; /// Radio driver. pub struct Radio<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Radio<'d, T> { /// Create a new radio driver. pub fn new( - radio: impl Peripheral

+ 'd, + radio: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(radio); - let r = T::regs(); r.pcnf1().write(|w| { diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs index 083842f4a..2f0bcbe04 100644 --- a/embassy-nrf/src/radio/ieee802154.rs +++ b/embassy-nrf/src/radio/ieee802154.rs @@ -4,13 +4,12 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower}; use crate::interrupt::typelevel::Interrupt; use crate::interrupt::{self}; use crate::pac::radio::vals; -use crate::Peripheral; +use crate::Peri; /// Default (IEEE compliant) Start of Frame Delimiter pub const DEFAULT_SFD: u8 = 0xA7; @@ -33,18 +32,16 @@ pub enum Cca { /// IEEE 802.15.4 radio driver. pub struct Radio<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, needs_enable: bool, } impl<'d, T: Instance> Radio<'d, T> { /// Create a new IEEE 802.15.4 radio driver. pub fn new( - radio: impl Peripheral

+ 'd, + radio: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(radio); - let r = T::regs(); // Disable and enable to reset peripheral diff --git a/embassy-nrf/src/radio/mod.rs b/embassy-nrf/src/radio/mod.rs index 251f37d3d..982436266 100644 --- a/embassy-nrf/src/radio/mod.rs +++ b/embassy-nrf/src/radio/mod.rs @@ -19,11 +19,12 @@ pub mod ieee802154; use core::marker::PhantomData; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use pac::radio::vals::State as RadioState; pub use pac::radio::vals::Txpower as TxPower; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// RADIO error. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -94,7 +95,7 @@ macro_rules! impl_radio { /// Radio peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index 7a98ab2fb..e75ffda00 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs @@ -10,11 +10,11 @@ use core::task::Poll; use critical_section::{CriticalSection, Mutex}; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::WakerRegistration; use crate::interrupt::typelevel::Interrupt; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// Interrupt handler. pub struct InterruptHandler { @@ -56,7 +56,7 @@ impl interrupt::typelevel::Handler for InterruptHandl /// /// It has a non-blocking API, and a blocking api through `rand`. pub struct Rng<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, } impl<'d, T: Instance> Rng<'d, T> { @@ -67,11 +67,9 @@ impl<'d, T: Instance> Rng<'d, T> { /// /// The synchronous API is safe. pub fn new( - rng: impl Peripheral

+ 'd, + rng: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(rng); - let this = Self { _peri: rng }; this.stop(); @@ -250,7 +248,7 @@ pub(crate) trait SealedInstance { /// RNG peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 00e2b7402..92b6fb01f 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -3,11 +3,12 @@ #![macro_use] use core::future::poll_fn; +use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri}; use embassy_sync::waitqueue::AtomicWaker; pub(crate) use vals::Psel as InputChannel; @@ -15,7 +16,7 @@ use crate::interrupt::InterruptExt; use crate::pac::saadc::vals; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; -use crate::{interrupt, pac, peripherals, Peripheral}; +use crate::{interrupt, pac, peripherals}; /// SAADC error #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -87,37 +88,32 @@ pub struct ChannelConfig<'d> { /// Acquisition time in microseconds. pub time: Time, /// Positive channel to sample - p_channel: PeripheralRef<'d, AnyInput>, + p_channel: AnyInput<'d>, /// An optional negative channel to sample - n_channel: Option>, + n_channel: Option>, } impl<'d> ChannelConfig<'d> { /// Default configuration for single ended channel sampling. - pub fn single_ended(input: impl Peripheral

+ 'd) -> Self { - into_ref!(input); + pub fn single_ended(input: impl Input + 'd) -> Self { Self { reference: Reference::INTERNAL, gain: Gain::GAIN1_6, resistor: Resistor::BYPASS, time: Time::_10US, - p_channel: input.map_into(), + p_channel: input.degrade_saadc(), n_channel: None, } } /// Default configuration for differential channel sampling. - pub fn differential( - p_input: impl Peripheral

+ 'd, - n_input: impl Peripheral

+ 'd, - ) -> Self { - into_ref!(p_input, n_input); + pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { Self { reference: Reference::INTERNAL, gain: Gain::GAIN1_6, resistor: Resistor::BYPASS, time: Time::_10US, - p_channel: p_input.map_into(), - n_channel: Some(n_input.map_into()), + p_channel: p_input.degrade_saadc(), + n_channel: Some(n_input.degrade_saadc()), } } } @@ -133,19 +129,17 @@ pub enum CallbackResult { /// One-shot and continuous SAADC. pub struct Saadc<'d, const N: usize> { - _p: PeripheralRef<'d, peripherals::SAADC>, + _p: Peri<'d, peripherals::SAADC>, } impl<'d, const N: usize> Saadc<'d, N> { /// Create a new SAADC driver. pub fn new( - saadc: impl Peripheral

+ 'd, + saadc: Peri<'d, peripherals::SAADC>, _irq: impl interrupt::typelevel::Binding + 'd, config: Config, channel_configs: [ChannelConfig; N], ) -> Self { - into_ref!(saadc); - let r = pac::SAADC; let Config { resolution, oversample } = config; @@ -284,9 +278,9 @@ impl<'d, const N: usize> Saadc<'d, N> { pub async fn run_task_sampler( &mut self, - timer: &mut T, - ppi_ch1: &mut impl ConfigurableChannel, - ppi_ch2: &mut impl ConfigurableChannel, + timer: Peri<'_, T>, + ppi_ch1: Peri<'_, impl ConfigurableChannel>, + ppi_ch2: Peri<'_, impl ConfigurableChannel>, frequency: Frequency, sample_counter: u32, bufs: &mut [[[i16; N]; N0]; 2], @@ -655,14 +649,18 @@ pub(crate) trait SealedInput { /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. #[allow(private_bounds)] -pub trait Input: SealedInput + Into + Peripheral

+ Sized + 'static { +pub trait Input: SealedInput + Sized { /// Convert this SAADC input to a type-erased `AnyInput`. /// /// This allows using several inputs in situations that might require /// them to be the same type, like putting them in an array. - fn degrade_saadc(self) -> AnyInput { + fn degrade_saadc<'a>(self) -> AnyInput<'a> + where + Self: 'a, + { AnyInput { channel: self.channel(), + _phantom: core::marker::PhantomData, } } } @@ -671,23 +669,36 @@ pub trait Input: SealedInput + Into + Peripheral

+ Sized + ' /// /// This allows using several inputs in situations that might require /// them to be the same type, like putting them in an array. -pub struct AnyInput { +pub struct AnyInput<'a> { channel: InputChannel, + _phantom: PhantomData<&'a ()>, } -impl_peripheral!(AnyInput); +impl<'a> AnyInput<'a> { + /// Reborrow into a "child" AnyInput. + /// + /// `self` will stay borrowed until the child AnyInput is dropped. + pub fn reborrow(&mut self) -> AnyInput<'_> { + // safety: we're returning the clone inside a new Peripheral that borrows + // self, so user code can't use both at the same time. + Self { + channel: self.channel, + _phantom: PhantomData, + } + } +} -impl SealedInput for AnyInput { +impl SealedInput for AnyInput<'_> { fn channel(&self) -> InputChannel { self.channel } } -impl Input for AnyInput {} +impl Input for AnyInput<'_> {} macro_rules! impl_saadc_input { ($pin:ident, $ch:ident) => { - impl_saadc_input!(@local, crate::peripherals::$pin, $ch); + impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); }; (@local, $pin:ty, $ch:ident) => { impl crate::saadc::SealedInput for $pin { @@ -696,12 +707,6 @@ macro_rules! impl_saadc_input { } } impl crate::saadc::Input for $pin {} - - impl From<$pin> for crate::saadc::AnyInput { - fn from(val: $pin) -> Self { - crate::saadc::Input::degrade_saadc(val) - } - } }; } diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index bd193cfe8..59f5b6d58 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -10,7 +10,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use pac::spim::vals::{Frequency, Order as BitOrder}; @@ -21,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::pac::gpio::vals as gpiovals; use crate::pac::spim::vals; use crate::util::slice_in_ram_or; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// SPIM error #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -100,73 +100,61 @@ impl interrupt::typelevel::Handler for InterruptHandl /// SPIM driver. pub struct Spim<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Spim<'d, T> { /// Create a new SPIM driver. pub fn new( - spim: impl Peripheral

+ 'd, + spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sck: impl Peripheral

+ 'd, - miso: impl Peripheral

+ 'd, - mosi: impl Peripheral

+ 'd, + sck: Peri<'d, impl GpioPin>, + miso: Peri<'d, impl GpioPin>, + mosi: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(sck, miso, mosi); - Self::new_inner( - spim, - Some(sck.map_into()), - Some(miso.map_into()), - Some(mosi.map_into()), - config, - ) + Self::new_inner(spim, Some(sck.into()), Some(miso.into()), Some(mosi.into()), config) } /// Create a new SPIM driver, capable of TX only (MOSI only). pub fn new_txonly( - spim: impl Peripheral

+ 'd, + spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sck: impl Peripheral

+ 'd, - mosi: impl Peripheral

+ 'd, + sck: Peri<'d, impl GpioPin>, + mosi: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(sck, mosi); - Self::new_inner(spim, Some(sck.map_into()), None, Some(mosi.map_into()), config) + Self::new_inner(spim, Some(sck.into()), None, Some(mosi.into()), config) } /// Create a new SPIM driver, capable of RX only (MISO only). pub fn new_rxonly( - spim: impl Peripheral

+ 'd, + spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sck: impl Peripheral

+ 'd, - miso: impl Peripheral

+ 'd, + sck: Peri<'d, impl GpioPin>, + miso: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(sck, miso); - Self::new_inner(spim, Some(sck.map_into()), Some(miso.map_into()), None, config) + Self::new_inner(spim, Some(sck.into()), Some(miso.into()), None, config) } /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin. pub fn new_txonly_nosck( - spim: impl Peripheral

+ 'd, + spim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - mosi: impl Peripheral

+ 'd, + mosi: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(mosi); - Self::new_inner(spim, None, None, Some(mosi.map_into()), config) + Self::new_inner(spim, None, None, Some(mosi.into()), config) } fn new_inner( - spim: impl Peripheral

+ 'd, - sck: Option>, - miso: Option>, - mosi: Option>, + spim: Peri<'d, T>, + sck: Option>, + miso: Option>, + mosi: Option>, config: Config, ) -> Self { - into_ref!(spim); - let r = T::regs(); // Configure pins @@ -511,7 +499,7 @@ pub(crate) trait SealedInstance { /// SPIM peripheral instance #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 88230fa26..2a3928d25 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -7,7 +7,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; pub use pac::spis::vals::Order as BitOrder; @@ -18,7 +18,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::pac::gpio::vals as gpiovals; use crate::pac::spis::vals; use crate::util::slice_in_ram_or; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// SPIS error #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -98,95 +98,75 @@ impl interrupt::typelevel::Handler for InterruptHandl /// SPIS driver. pub struct Spis<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Spis<'d, T> { /// Create a new SPIS driver. pub fn new( - spis: impl Peripheral

+ 'd, + spis: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - cs: impl Peripheral

+ 'd, - sck: impl Peripheral

+ 'd, - miso: impl Peripheral

+ 'd, - mosi: impl Peripheral

+ 'd, + cs: Peri<'d, impl GpioPin>, + sck: Peri<'d, impl GpioPin>, + miso: Peri<'d, impl GpioPin>, + mosi: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(cs, sck, miso, mosi); Self::new_inner( spis, - cs.map_into(), - Some(sck.map_into()), - Some(miso.map_into()), - Some(mosi.map_into()), + cs.into(), + Some(sck.into()), + Some(miso.into()), + Some(mosi.into()), config, ) } /// Create a new SPIS driver, capable of TX only (MISO only). pub fn new_txonly( - spis: impl Peripheral

+ 'd, + spis: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - cs: impl Peripheral

+ 'd, - sck: impl Peripheral

+ 'd, - miso: impl Peripheral

+ 'd, + cs: Peri<'d, impl GpioPin>, + sck: Peri<'d, impl GpioPin>, + miso: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(cs, sck, miso); - Self::new_inner( - spis, - cs.map_into(), - Some(sck.map_into()), - Some(miso.map_into()), - None, - config, - ) + Self::new_inner(spis, cs.into(), Some(sck.into()), Some(miso.into()), None, config) } /// Create a new SPIS driver, capable of RX only (MOSI only). pub fn new_rxonly( - spis: impl Peripheral

+ 'd, + spis: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - cs: impl Peripheral

+ 'd, - sck: impl Peripheral

+ 'd, - mosi: impl Peripheral

+ 'd, + cs: Peri<'d, impl GpioPin>, + sck: Peri<'d, impl GpioPin>, + mosi: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(cs, sck, mosi); - Self::new_inner( - spis, - cs.map_into(), - Some(sck.map_into()), - None, - Some(mosi.map_into()), - config, - ) + Self::new_inner(spis, cs.into(), Some(sck.into()), None, Some(mosi.into()), config) } /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. pub fn new_txonly_nosck( - spis: impl Peripheral

+ 'd, + spis: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - cs: impl Peripheral

+ 'd, - miso: impl Peripheral

+ 'd, + cs: Peri<'d, impl GpioPin>, + miso: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(cs, miso); - Self::new_inner(spis, cs.map_into(), None, Some(miso.map_into()), None, config) + Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config) } fn new_inner( - spis: impl Peripheral

+ 'd, - cs: PeripheralRef<'d, AnyPin>, - sck: Option>, - miso: Option>, - mosi: Option>, + spis: Peri<'d, T>, + cs: Peri<'d, AnyPin>, + sck: Option>, + miso: Option>, + mosi: Option>, config: Config, ) -> Self { compiler_fence(Ordering::SeqCst); - into_ref!(spis, cs); - let r = T::regs(); // Configure pins. @@ -485,7 +465,7 @@ pub(crate) trait SealedInstance { /// SPIS peripheral instance #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs index 1488c5c24..44be0f6d1 100644 --- a/embassy-nrf/src/temp.rs +++ b/embassy-nrf/src/temp.rs @@ -4,13 +4,12 @@ use core::future::poll_fn; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use fixed::types::I30F2; use crate::interrupt::InterruptExt; use crate::peripherals::TEMP; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac, Peri}; /// Interrupt handler. pub struct InterruptHandler { @@ -27,7 +26,7 @@ impl interrupt::typelevel::Handler for InterruptHand /// Builtin temperature sensor driver. pub struct Temp<'d> { - _peri: PeripheralRef<'d, TEMP>, + _peri: Peri<'d, TEMP>, } static WAKER: AtomicWaker = AtomicWaker::new(); @@ -35,11 +34,9 @@ static WAKER: AtomicWaker = AtomicWaker::new(); impl<'d> Temp<'d> { /// Create a new temperature sensor driver. pub fn new( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, TEMP>, _irq: impl interrupt::typelevel::Binding + 'd, ) -> Self { - into_ref!(_peri); - // Enable interrupt that signals temperature values interrupt::TEMP.unpend(); unsafe { interrupt::TEMP.enable() }; diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index a9aeb40fa..5b58b0a50 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -6,11 +6,11 @@ #![macro_use] -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; +use crate::pac; use crate::pac::timer::vals; use crate::ppi::{Event, Task}; -use crate::{pac, Peripheral}; pub(crate) trait SealedInstance { /// The number of CC registers this instance has. @@ -20,7 +20,7 @@ pub(crate) trait SealedInstance { /// Basic Timer instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: crate::interrupt::typelevel::Interrupt; } @@ -84,7 +84,7 @@ pub enum Frequency { /// Timer driver. pub struct Timer<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Timer<'d, T> { @@ -92,7 +92,7 @@ impl<'d, T: Instance> Timer<'d, T> { /// /// This can be useful for triggering tasks via PPI /// `Uarte` uses this internally. - pub fn new(timer: impl Peripheral

+ 'd) -> Self { + pub fn new(timer: Peri<'d, T>) -> Self { Self::new_inner(timer, false) } @@ -100,13 +100,11 @@ impl<'d, T: Instance> Timer<'d, T> { /// /// This can be useful for triggering tasks via PPI /// `Uarte` uses this internally. - pub fn new_counter(timer: impl Peripheral

+ 'd) -> Self { + pub fn new_counter(timer: Peri<'d, T>) -> Self { Self::new_inner(timer, true) } - fn new_inner(timer: impl Peripheral

+ 'd, _is_counter: bool) -> Self { - into_ref!(timer); - + fn new_inner(timer: Peri<'d, T>, _is_counter: bool) -> Self { let regs = T::regs(); let this = Self { _p: timer }; @@ -229,7 +227,7 @@ impl<'d, T: Instance> Timer<'d, T> { /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register pub struct Cc<'d, T: Instance> { n: usize, - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Cc<'d, T> { diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index bfce00f1b..083b54b99 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -10,7 +10,7 @@ use core::sync::atomic::Ordering::SeqCst; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; #[cfg(feature = "time")] use embassy_time::{Duration, Instant}; @@ -23,7 +23,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::pac::gpio::vals as gpiovals; use crate::pac::twim::vals; use crate::util::slice_in_ram; -use crate::{gpio, interrupt, pac, Peripheral}; +use crate::{gpio, interrupt, pac}; /// TWIM config. #[non_exhaustive] @@ -114,20 +114,18 @@ impl interrupt::typelevel::Handler for InterruptHandl /// TWI driver. pub struct Twim<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Twim<'d, T> { /// Create a new TWI driver. pub fn new( - twim: impl Peripheral

+ 'd, + twim: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sda: impl Peripheral

+ 'd, - scl: impl Peripheral

+ 'd, + sda: Peri<'d, impl GpioPin>, + scl: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(twim, sda, scl); - let r = T::regs(); // Configure pins @@ -847,7 +845,7 @@ pub(crate) trait SealedInstance { /// TWIM peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index 60de2ed9d..3e4d537ae 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs @@ -8,7 +8,7 @@ use core::sync::atomic::compiler_fence; use core::sync::atomic::Ordering::SeqCst; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; #[cfg(feature = "time")] use embassy_time::{Duration, Instant}; @@ -19,7 +19,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::pac::gpio::vals as gpiovals; use crate::pac::twis::vals; use crate::util::slice_in_ram_or; -use crate::{gpio, interrupt, pac, Peripheral}; +use crate::{gpio, interrupt, pac}; /// TWIS config. #[non_exhaustive] @@ -141,20 +141,18 @@ impl interrupt::typelevel::Handler for InterruptHandl /// TWIS driver. pub struct Twis<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Twis<'d, T> { /// Create a new TWIS driver. pub fn new( - twis: impl Peripheral

+ 'd, + twis: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - sda: impl Peripheral

+ 'd, - scl: impl Peripheral

+ 'd, + sda: Peri<'d, impl GpioPin>, + scl: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(twis, sda, scl); - let r = T::regs(); // Configure pins @@ -791,7 +789,7 @@ pub(crate) trait SealedInstance { /// TWIS peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index ebb4dd941..b44edfe84 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -19,7 +19,7 @@ use core::sync::atomic::{compiler_fence, AtomicU8, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; // Re-export SVD variants to allow user to directly set values. pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; @@ -32,7 +32,7 @@ use crate::pac::uarte::vals; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::util::slice_in_ram_or; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; /// UARTE config. #[derive(Clone)] @@ -141,56 +141,54 @@ pub struct Uarte<'d, T: Instance> { /// /// This can be obtained via [`Uarte::split`], or created directly. pub struct UarteTx<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } /// Receiver part of the UARTE driver. /// /// This can be obtained via [`Uarte::split`], or created directly. pub struct UarteRx<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, } impl<'d, T: Instance> Uarte<'d, T> { /// Create a new UARTE without hardware flow control pub fn new( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - txd: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + txd: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, rxd, txd); - Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config) + Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config) } /// Create a new UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - txd: impl Peripheral

+ 'd, - cts: impl Peripheral

+ 'd, - rts: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + txd: Peri<'d, impl GpioPin>, + cts: Peri<'d, impl GpioPin>, + rts: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, rxd, txd, cts, rts); Self::new_inner( uarte, - rxd.map_into(), - txd.map_into(), - Some(cts.map_into()), - Some(rts.map_into()), + rxd.into(), + txd.into(), + Some(cts.into()), + Some(rts.into()), config, ) } fn new_inner( - uarte: PeripheralRef<'d, T>, - rxd: PeripheralRef<'d, AnyPin>, - txd: PeripheralRef<'d, AnyPin>, - cts: Option>, - rts: Option>, + uarte: Peri<'d, T>, + rxd: Peri<'d, AnyPin>, + txd: Peri<'d, AnyPin>, + cts: Option>, + rts: Option>, config: Config, ) -> Self { let r = T::regs(); @@ -239,9 +237,9 @@ impl<'d, T: Instance> Uarte<'d, T> { /// This is useful to concurrently transmit and receive from independent tasks. pub fn split_with_idle( self, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, + timer: Peri<'d, U>, + ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, + ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) { (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2)) } @@ -283,11 +281,7 @@ impl<'d, T: Instance> Uarte<'d, T> { } } -pub(crate) fn configure_tx_pins( - r: pac::uarte::Uarte, - txd: PeripheralRef<'_, AnyPin>, - cts: Option>, -) { +pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts: Option>) { txd.set_high(); txd.conf().write(|w| { w.set_dir(gpiovals::Dir::OUTPUT); @@ -306,11 +300,7 @@ pub(crate) fn configure_tx_pins( r.psel().cts().write_value(cts.psel_bits()); } -pub(crate) fn configure_rx_pins( - r: pac::uarte::Uarte, - rxd: PeripheralRef<'_, AnyPin>, - rts: Option>, -) { +pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts: Option>) { rxd.conf().write(|w| { w.set_dir(gpiovals::Dir::INPUT); w.set_input(gpiovals::Input::CONNECT); @@ -356,33 +346,26 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont impl<'d, T: Instance> UarteTx<'d, T> { /// Create a new tx-only UARTE without hardware flow control pub fn new( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - txd: impl Peripheral

+ 'd, + txd: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, txd); - Self::new_inner(uarte, txd.map_into(), None, config) + Self::new_inner(uarte, txd.into(), None, config) } /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - txd: impl Peripheral

+ 'd, - cts: impl Peripheral

+ 'd, + txd: Peri<'d, impl GpioPin>, + cts: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, txd, cts); - Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config) + Self::new_inner(uarte, txd.into(), Some(cts.into()), config) } - fn new_inner( - uarte: PeripheralRef<'d, T>, - txd: PeripheralRef<'d, AnyPin>, - cts: Option>, - config: Config, - ) -> Self { + fn new_inner(uarte: Peri<'d, T>, txd: Peri<'d, AnyPin>, cts: Option>, config: Config) -> Self { let r = T::regs(); configure(r, config, cts.is_some()); @@ -539,25 +522,23 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> { impl<'d, T: Instance> UarteRx<'d, T> { /// Create a new rx-only UARTE without hardware flow control pub fn new( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, rxd); - Self::new_inner(uarte, rxd.map_into(), None, config) + Self::new_inner(uarte, rxd.into(), None, config) } /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) pub fn new_with_rtscts( - uarte: impl Peripheral

+ 'd, + uarte: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rxd: impl Peripheral

+ 'd, - rts: impl Peripheral

+ 'd, + rxd: Peri<'d, impl GpioPin>, + rts: Peri<'d, impl GpioPin>, config: Config, ) -> Self { - into_ref!(uarte, rxd, rts); - Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config) + Self::new_inner(uarte, rxd.into(), Some(rts.into()), config) } /// Check for errors and clear the error register if an error occured. @@ -568,12 +549,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { ErrorSource::from_bits_truncate(err_bits.0).check() } - fn new_inner( - uarte: PeripheralRef<'d, T>, - rxd: PeripheralRef<'d, AnyPin>, - rts: Option>, - config: Config, - ) -> Self { + fn new_inner(uarte: Peri<'d, T>, rxd: Peri<'d, AnyPin>, rts: Option>, config: Config) -> Self { let r = T::regs(); configure(r, config, rts.is_some()); @@ -592,14 +568,12 @@ impl<'d, T: Instance> UarteRx<'d, T> { /// Upgrade to an instance that supports idle line detection. pub fn with_idle( self, - timer: impl Peripheral

+ 'd, - ppi_ch1: impl Peripheral

+ 'd, - ppi_ch2: impl Peripheral

+ 'd, + timer: Peri<'d, U>, + ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, + ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, ) -> UarteRxWithIdle<'d, T, U> { let timer = Timer::new(timer); - into_ref!(ppi_ch1, ppi_ch2); - let r = T::regs(); // BAUDRATE register values are `baudrate * 2^32 / 16000000` @@ -617,7 +591,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { timer.cc(0).short_compare_stop(); let mut ppi_ch1 = Ppi::new_one_to_two( - ppi_ch1.map_into(), + ppi_ch1.into(), Event::from_reg(r.events_rxdrdy()), timer.task_clear(), timer.task_start(), @@ -625,7 +599,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { ppi_ch1.enable(); let mut ppi_ch2 = Ppi::new_one_to_one( - ppi_ch2.map_into(), + ppi_ch2.into(), timer.cc(0).event_compare(), Task::from_reg(r.tasks_stoprx()), ); @@ -992,7 +966,7 @@ pub(crate) trait SealedInstance { /// UARTE peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index 06dae694b..6cc1b0111 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs @@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; use core::task::Poll; use cortex_m::peripheral::NVIC; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use embassy_usb_driver as driver; use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; @@ -20,7 +20,7 @@ use self::vbus_detect::VbusDetect; use crate::interrupt::typelevel::Interrupt; use crate::pac::usbd::vals; use crate::util::slice_in_ram; -use crate::{interrupt, pac, Peripheral}; +use crate::{interrupt, pac}; static BUS_WAKER: AtomicWaker = AtomicWaker::new(); static EP0_WAKER: AtomicWaker = AtomicWaker::new(); @@ -87,7 +87,7 @@ impl interrupt::typelevel::Handler for InterruptHandl /// USB driver. pub struct Driver<'d, T: Instance, V: VbusDetect> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, alloc_in: Allocator, alloc_out: Allocator, vbus_detect: V, @@ -96,12 +96,10 @@ pub struct Driver<'d, T: Instance, V: VbusDetect> { impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { /// Create a new USB driver. pub fn new( - usb: impl Peripheral

+ 'd, + usb: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, vbus_detect: V, ) -> Self { - into_ref!(usb); - T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; @@ -169,7 +167,7 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V /// USB bus. pub struct Bus<'d, T: Instance, V: VbusDetect> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, power_available: bool, vbus_detect: V, } @@ -592,7 +590,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { /// USB control pipe. pub struct ControlPipe<'d, T: Instance> { - _p: PeripheralRef<'d, T>, + _p: Peri<'d, T>, max_packet_size: u16, } @@ -779,7 +777,7 @@ pub(crate) trait SealedInstance { /// USB peripheral instance. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index f7812258c..11cfa398e 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs @@ -3,9 +3,11 @@ //! This HAL implements a basic watchdog timer with 1..=8 handles. //! Once the watchdog has been started, it cannot be stopped. +use core::marker::PhantomData; + use crate::pac::wdt::vals; pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; -use crate::peripherals; +use crate::{peripherals, Peri}; const MIN_TICKS: u32 = 15; @@ -61,7 +63,7 @@ impl Default for Config { /// Watchdog driver. pub struct Watchdog { - _private: (), + _wdt: Peri<'static, peripherals::WDT>, } impl Watchdog { @@ -74,9 +76,9 @@ impl Watchdog { /// `N` must be between 1 and 8, inclusive. #[inline] pub fn try_new( - wdt: peripherals::WDT, + wdt: Peri<'static, peripherals::WDT>, config: Config, - ) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> { + ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> { assert!(N >= 1 && N <= 8); let r = crate::pac::WDT; @@ -110,11 +112,19 @@ impl Watchdog { r.tasks_start().write_value(1); } - let this = Self { _private: () }; + let this = Self { _wdt: wdt }; - let mut handles = [const { WatchdogHandle { index: 0 } }; N]; + let mut handles = [const { + WatchdogHandle { + _wdt: PhantomData, + index: 0, + } + }; N]; for i in 0..N { - handles[i] = WatchdogHandle { index: i as u8 }; + handles[i] = WatchdogHandle { + _wdt: PhantomData, + index: i as u8, + }; handles[i].pet(); } @@ -155,6 +165,7 @@ impl Watchdog { /// Watchdog handle. pub struct WatchdogHandle { + _wdt: PhantomData>, index: u8, } @@ -183,6 +194,9 @@ impl WatchdogHandle { /// Watchdog must be initialized and `index` must be between `0` and `N-1` /// where `N` is the handle count when initializing. pub unsafe fn steal(index: u8) -> Self { - Self { index } + Self { + _wdt: PhantomData, + index, + } } } diff --git a/embassy-nxp/src/gpio.rs b/embassy-nxp/src/gpio.rs index d5d04ee69..c7c78ce61 100644 --- a/embassy-nxp/src/gpio.rs +++ b/embassy-nxp/src/gpio.rs @@ -1,7 +1,7 @@ -use embassy_hal_internal::impl_peripheral; +use embassy_hal_internal::{impl_peripheral, PeripheralType}; use crate::pac_utils::*; -use crate::{peripherals, Peripheral, PeripheralRef}; +use crate::{peripherals, Peri}; pub(crate) fn init() { // Enable clocks for GPIO, PINT, and IOCON @@ -45,7 +45,7 @@ pub struct Output<'d> { impl<'d> Output<'d> { /// Create GPIO output driver for a [Pin] with the provided [initial output](Level). #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { let mut pin = Flex::new(pin); pin.set_as_output(); let mut result = Self { pin }; @@ -90,7 +90,7 @@ pub struct Input<'d> { impl<'d> Input<'d> { /// Create GPIO output driver for a [Pin] with the provided [Pull]. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { let mut pin = Flex::new(pin); pin.set_as_input(); let mut result = Self { pin }; @@ -124,7 +124,7 @@ impl<'d> Input<'d> { /// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a /// reference to a type-erased pin called ["AnyPin"](AnyPin). pub struct Flex<'d> { - pub(crate) pin: PeripheralRef<'d, AnyPin>, + pub(crate) pin: Peri<'d, AnyPin>, } impl<'d> Flex<'d> { @@ -132,10 +132,8 @@ impl<'d> Flex<'d> { /// /// Note: you cannot assume that the pin will be in Digital mode after this call. #[inline] - pub fn new(pin: impl Peripheral

+ 'd) -> Self { - Self { - pin: pin.into_ref().map_into(), - } + pub fn new(pin: Peri<'d, impl Pin>) -> Self { + Self { pin: pin.into() } } /// Get the bank of this pin. See also [Bank]. @@ -218,15 +216,7 @@ pub(crate) trait SealedPin: Sized { /// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the /// `embassy-nxp` crate due to the [SealedPin] trait. #[allow(private_bounds)] -pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { - /// Degrade to a generic pin struct - fn degrade(self) -> AnyPin { - AnyPin { - pin_bank: self.pin_bank(), - pin_number: self.pin_number(), - } - } - +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// Returns the pin number within a bank #[inline] fn pin(&self) -> u8 { @@ -252,8 +242,8 @@ impl AnyPin { /// # Safety /// /// You must ensure that you’re only using one instance of this type at a time. - pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Self { - Self { pin_bank, pin_number } + pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> { + Peri::new_unchecked(Self { pin_bank, pin_number }) } } @@ -289,7 +279,10 @@ macro_rules! impl_pin { impl From for crate::gpio::AnyPin { fn from(val: peripherals::$name) -> Self { - crate::gpio::Pin::degrade(val) + Self { + pin_bank: val.pin_bank(), + pin_number: val.pin_number(), + } } } }; diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs index 80fdecb2e..ad2056c06 100644 --- a/embassy-nxp/src/lib.rs +++ b/embassy-nxp/src/lib.rs @@ -4,7 +4,7 @@ pub mod gpio; mod pac_utils; pub mod pint; -pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +pub use embassy_hal_internal::Peri; pub use lpc55_pac as pac; /// Initialize the `embassy-nxp` HAL with the provided configuration. diff --git a/embassy-nxp/src/pint.rs b/embassy-nxp/src/pint.rs index 809be4bff..8d6dc1277 100644 --- a/embassy-nxp/src/pint.rs +++ b/embassy-nxp/src/pint.rs @@ -5,12 +5,12 @@ use core::pin::Pin as FuturePin; use core::task::{Context, Poll}; use critical_section::Mutex; -use embassy_hal_internal::{Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{self, AnyPin, Level, SealedPin}; use crate::pac::interrupt; use crate::pac_utils::*; +use crate::Peri; struct PinInterrupt { assigned: bool, @@ -107,14 +107,14 @@ pub(crate) fn init() { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputFuture<'d> { #[allow(dead_code)] - pin: PeripheralRef<'d, AnyPin>, + pin: Peri<'d, AnyPin>, interrupt_number: usize, } impl<'d> InputFuture<'d> { /// Create a new input future. Returns None if all interrupts are in use. - fn new(pin: impl Peripheral

+ 'd, interrupt_on: InterruptOn) -> Option { - let pin = pin.into_ref().map_into(); + fn new(pin: Peri<'d, impl gpio::Pin>, interrupt_on: InterruptOn) -> Option { + let pin = pin.into(); let interrupt_number = next_available_interrupt()?; // Clear interrupt, just in case @@ -344,35 +344,35 @@ impl gpio::Flex<'_> { /// Wait for a falling or rising edge on the pin. You can have at most 8 pins waiting. If you /// try to wait for more than 8 pins, this function will return `None`. pub async fn wait_for_any_edge(&mut self) -> Option<()> { - InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Both))?.await; + InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Both))?.await; Some(()) } /// Wait for a falling edge on the pin. You can have at most 8 pins waiting. If you try to wait /// for more than 8 pins, this function will return `None`. pub async fn wait_for_falling_edge(&mut self) -> Option<()> { - InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Falling))?.await; + InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Falling))?.await; Some(()) } /// Wait for a rising edge on the pin. You can have at most 8 pins waiting. If you try to wait /// for more than 8 pins, this function will return `None`. pub async fn wait_for_rising_edge(&mut self) -> Option<()> { - InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Rising))?.await; + InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Rising))?.await; Some(()) } /// Wait for a low level on the pin. You can have at most 8 pins waiting. If you try to wait for /// more than 8 pins, this function will return `None`. pub async fn wait_for_low(&mut self) -> Option<()> { - InputFuture::new(&mut self.pin, InterruptOn::Level(Level::Low))?.await; + InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::Low))?.await; Some(()) } /// Wait for a high level on the pin. You can have at most 8 pins waiting. If you try to wait for /// more than 8 pins, this function will return `None`. pub async fn wait_for_high(&mut self) -> Option<()> { - InputFuture::new(&mut self.pin, InterruptOn::Level(Level::High))?.await; + InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::High))?.await; Some(()) } } diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index 8defb5231..ba9ec732d 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs @@ -5,7 +5,6 @@ use core::mem; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin}; @@ -13,7 +12,7 @@ use crate::interrupt::typelevel::Binding; use crate::interrupt::InterruptExt; use crate::pac::dma::vals::TreqSel; use crate::peripherals::{ADC, ADC_TEMP_SENSOR}; -use crate::{dma, interrupt, pac, peripherals, Peripheral, RegExt}; +use crate::{dma, interrupt, pac, peripherals, Peri, RegExt}; static WAKER: AtomicWaker = AtomicWaker::new(); @@ -23,8 +22,8 @@ static WAKER: AtomicWaker = AtomicWaker::new(); pub struct Config {} enum Source<'p> { - Pin(PeripheralRef<'p, AnyPin>), - TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>), + Pin(Peri<'p, AnyPin>), + TempSensor(Peri<'p, ADC_TEMP_SENSOR>), } /// ADC channel. @@ -32,8 +31,7 @@ pub struct Channel<'p>(Source<'p>); impl<'p> Channel<'p> { /// Create a new ADC channel from pin with the provided [Pull] configuration. - pub fn new_pin(pin: impl Peripheral

+ 'p, pull: Pull) -> Self { - into_ref!(pin); + pub fn new_pin(pin: Peri<'p, impl AdcPin + 'p>, pull: Pull) -> Self { pin.pad_ctrl().modify(|w| { #[cfg(feature = "_rp235x")] w.set_iso(false); @@ -47,14 +45,14 @@ impl<'p> Channel<'p> { w.set_pue(pull == Pull::Up); w.set_pde(pull == Pull::Down); }); - Self(Source::Pin(pin.map_into())) + Self(Source::Pin(pin.into())) } /// Create a new ADC channel for the internal temperature sensor. - pub fn new_temp_sensor(s: impl Peripheral

+ 'p) -> Self { + pub fn new_temp_sensor(s: Peri<'p, ADC_TEMP_SENSOR>) -> Self { let r = pac::ADC; r.cs().write_set(|w| w.set_ts_en(true)); - Self(Source::TempSensor(s.into_ref())) + Self(Source::TempSensor(s)) } fn channel(&self) -> u8 { @@ -190,7 +188,7 @@ impl<'d, M: Mode> Adc<'d, M> { impl<'d> Adc<'d, Async> { /// Create ADC driver in async mode. pub fn new( - _inner: impl Peripheral

+ 'd, + _inner: Peri<'d, ADC>, _irq: impl Binding, _config: Config, ) -> Self { @@ -240,7 +238,7 @@ impl<'d> Adc<'d, Async> { buf: &mut [W], fcs_err: bool, div: u16, - dma: impl Peripheral

, + dma: Peri<'_, impl dma::Channel>, ) -> Result<(), Error> { #[cfg(feature = "rp2040")] let mut rrobin = 0_u8; @@ -321,7 +319,7 @@ impl<'d> Adc<'d, Async> { ch: &mut [Channel<'_>], buf: &mut [S], div: u16, - dma: impl Peripheral

, + dma: Peri<'_, impl dma::Channel>, ) -> Result<(), Error> { self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma) .await @@ -337,7 +335,7 @@ impl<'d> Adc<'d, Async> { ch: &mut [Channel<'_>], buf: &mut [Sample], div: u16, - dma: impl Peripheral

, + dma: Peri<'_, impl dma::Channel>, ) { // errors are reported in individual samples let _ = self @@ -360,7 +358,7 @@ impl<'d> Adc<'d, Async> { ch: &mut Channel<'_>, buf: &mut [S], div: u16, - dma: impl Peripheral

, + dma: Peri<'_, impl dma::Channel>, ) -> Result<(), Error> { self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma) .await @@ -375,7 +373,7 @@ impl<'d> Adc<'d, Async> { ch: &mut Channel<'_>, buf: &mut [Sample], div: u16, - dma: impl Peripheral

, + dma: Peri<'_, impl dma::Channel>, ) { // errors are reported in individual samples let _ = self @@ -392,7 +390,7 @@ impl<'d> Adc<'d, Async> { impl<'d> Adc<'d, Blocking> { /// Create ADC driver in blocking mode. - pub fn new_blocking(_inner: impl Peripheral

+ 'd, _config: Config) -> Self { + pub fn new_blocking(_inner: Peri<'d, ADC>, _config: Config) -> Self { Self::setup(); Self { phantom: PhantomData } diff --git a/embassy-rp/src/bootsel.rs b/embassy-rp/src/bootsel.rs index d24ce7bd8..14f9e46aa 100644 --- a/embassy-rp/src/bootsel.rs +++ b/embassy-rp/src/bootsel.rs @@ -8,20 +8,19 @@ //! This module provides functionality to poll BOOTSEL from an embassy application. use crate::flash::in_ram; +use crate::Peri; -impl crate::peripherals::BOOTSEL { - /// Polls the BOOTSEL button. Returns true if the button is pressed. - /// - /// Polling isn't cheap, as this function waits for core 1 to finish it's current - /// task and for any DMAs from flash to complete - pub fn is_pressed(&mut self) -> bool { - let mut cs_status = Default::default(); +/// Reads the BOOTSEL button. Returns true if the button is pressed. +/// +/// Reading isn't cheap, as this function waits for core 1 to finish it's current +/// task and for any DMAs from flash to complete +pub fn is_bootsel_pressed(_p: Peri<'_, crate::peripherals::BOOTSEL>) -> bool { + let mut cs_status = Default::default(); - unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); + unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); - // bootsel is active low, so invert - !cs_status.infrompad() - } + // bootsel is active low, so invert + !cs_status.infrompad() } mod ram_helpers { diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 705dde62a..67aa5e540 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs @@ -7,13 +7,12 @@ use core::marker::PhantomData; use core::sync::atomic::AtomicU16; use core::sync::atomic::{AtomicU32, Ordering}; -use embassy_hal_internal::{into_ref, PeripheralRef}; use pac::clocks::vals::*; use crate::gpio::{AnyPin, SealedPin}; #[cfg(feature = "rp2040")] use crate::pac::common::{Reg, RW}; -use crate::{pac, reset, Peripheral}; +use crate::{pac, reset, Peri}; // NOTE: all gpin handling is commented out for future reference. // gpin is not usually safe to use during the boot init() call, so it won't @@ -200,8 +199,8 @@ impl ClockConfig { // pub fn bind_gpin(&mut self, gpin: Gpin<'static, P>, hz: u32) { // match P::NR { - // 0 => self.gpin0 = Some((hz, gpin.map_into())), - // 1 => self.gpin1 = Some((hz, gpin.map_into())), + // 0 => self.gpin0 = Some((hz, gpin.into())), + // 1 => self.gpin1 = Some((hz, gpin.into())), // _ => unreachable!(), // } // // pin is now provisionally bound. if the config is applied it must be forgotten, @@ -845,15 +844,13 @@ impl_gpinpin!(PIN_22, 22, 1); /// General purpose clock input driver. pub struct Gpin<'d, T: GpinPin> { - gpin: PeripheralRef<'d, AnyPin>, + gpin: Peri<'d, AnyPin>, _phantom: PhantomData, } impl<'d, T: GpinPin> Gpin<'d, T> { /// Create new gpin driver. - pub fn new(gpin: impl Peripheral

+ 'd) -> Self { - into_ref!(gpin); - + pub fn new(gpin: Peri<'d, T>) -> Self { #[cfg(feature = "rp2040")] gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08)); @@ -867,14 +864,10 @@ impl<'d, T: GpinPin> Gpin<'d, T> { }); Gpin { - gpin: gpin.map_into(), + gpin: gpin.into(), _phantom: PhantomData, } } - - // fn map_into(self) -> Gpin<'d, AnyPin> { - // unsafe { core::mem::transmute(self) } - // } } impl<'d, T: GpinPin> Drop for Gpin<'d, T> { @@ -936,14 +929,12 @@ pub enum GpoutSrc { /// General purpose clock output driver. pub struct Gpout<'d, T: GpoutPin> { - gpout: PeripheralRef<'d, T>, + gpout: Peri<'d, T>, } impl<'d, T: GpoutPin> Gpout<'d, T> { /// Create new general purpose clock output. - pub fn new(gpout: impl Peripheral

+ 'd) -> Self { - into_ref!(gpout); - + pub fn new(gpout: Peri<'d, T>) -> Self { #[cfg(feature = "rp2040")] gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08)); diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 2edcfdf5b..d31d1e159 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -4,7 +4,7 @@ use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::{Context, Poll}; -use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use pac::dma::vals::DataSize; @@ -42,7 +42,7 @@ pub(crate) unsafe fn init() { /// /// SAFETY: Slice must point to a valid location reachable by DMA. pub unsafe fn read<'a, C: Channel, W: Word>( - ch: impl Peripheral

+ 'a, + ch: Peri<'a, C>, from: *const W, to: *mut [W], dreq: vals::TreqSel, @@ -63,7 +63,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>( /// /// SAFETY: Slice must point to a valid location reachable by DMA. pub unsafe fn write<'a, C: Channel, W: Word>( - ch: impl Peripheral

+ 'a, + ch: Peri<'a, C>, from: *const [W], to: *mut W, dreq: vals::TreqSel, @@ -87,7 +87,7 @@ static mut DUMMY: u32 = 0; /// /// SAFETY: Slice must point to a valid location reachable by DMA. pub unsafe fn write_repeated<'a, C: Channel, W: Word>( - ch: impl Peripheral

+ 'a, + ch: Peri<'a, C>, to: *mut W, len: usize, dreq: vals::TreqSel, @@ -107,11 +107,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>( /// DMA copy between slices. /// /// SAFETY: Slices must point to locations reachable by DMA. -pub unsafe fn copy<'a, C: Channel, W: Word>( - ch: impl Peripheral

+ 'a, - from: &[W], - to: &mut [W], -) -> Transfer<'a, C> { +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); @@ -128,7 +124,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>( } fn copy_inner<'a, C: Channel>( - ch: impl Peripheral

+ 'a, + ch: Peri<'a, C>, from: *const u32, to: *mut u32, len: usize, @@ -137,8 +133,6 @@ fn copy_inner<'a, C: Channel>( incr_write: bool, dreq: vals::TreqSel, ) -> Transfer<'a, C> { - into_ref!(ch); - let p = ch.regs(); p.read_addr().write_value(from as u32); @@ -171,13 +165,11 @@ fn copy_inner<'a, C: Channel>( /// DMA transfer driver. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Transfer<'a, C: Channel> { - channel: PeripheralRef<'a, C>, + channel: Peri<'a, C>, } impl<'a, C: Channel> Transfer<'a, C> { - pub(crate) fn new(channel: impl Peripheral

+ 'a) -> Self { - into_ref!(channel); - + pub(crate) fn new(channel: Peri<'a, C>) -> Self { Self { channel } } } @@ -219,7 +211,7 @@ trait SealedWord {} /// DMA channel interface. #[allow(private_bounds)] -pub trait Channel: Peripheral

+ SealedChannel + Into + Sized + 'static { +pub trait Channel: PeripheralType + SealedChannel + Into + Sized + 'static { /// Channel number. fn number(&self) -> u8; @@ -227,11 +219,6 @@ pub trait Channel: Peripheral

+ SealedChannel + Into + Siz fn regs(&self) -> pac::dma::Channel { pac::DMA.ch(self.number() as _) } - - /// Convert into type-erased [AnyChannel]. - fn degrade(self) -> AnyChannel { - AnyChannel { number: self.number() } - } } /// DMA word. @@ -287,7 +274,7 @@ macro_rules! channel { impl From for crate::dma::AnyChannel { fn from(val: peripherals::$name) -> Self { - crate::dma::Channel::degrade(val) + Self { number: val.number() } } } }; diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index fbc8b35ec..b30cbdd36 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use core::pin::Pin; use core::task::{Context, Poll}; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embedded_storage::nor_flash::{ check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, @@ -114,7 +114,7 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, ' /// Flash driver. pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> { - dma: Option>, + dma: Option>, phantom: PhantomData<(&'d mut T, M)>, } @@ -253,7 +253,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> { /// Create a new flash driver in blocking mode. - pub fn new_blocking(_flash: impl Peripheral

+ 'd) -> Self { + pub fn new_blocking(_flash: Peri<'d, T>) -> Self { Self { dma: None, phantom: PhantomData, @@ -263,10 +263,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { /// Create a new flash driver in async mode. - pub fn new(_flash: impl Peripheral

+ 'd, dma: impl Peripheral

+ 'd) -> Self { - into_ref!(dma); + pub fn new(_flash: Peri<'d, T>, dma: Peri<'d, impl Channel>) -> Self { Self { - dma: Some(dma.map_into()), + dma: Some(dma.into()), phantom: PhantomData, } } @@ -316,7 +315,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _; let transfer = unsafe { crate::dma::read( - self.dma.as_mut().unwrap(), + self.dma.as_mut().unwrap().reborrow(), XIP_AUX_BASE, data, pac::dma::vals::TreqSel::XIP_STREAM, @@ -965,7 +964,7 @@ trait SealedMode {} /// Flash instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance {} +pub trait Instance: SealedInstance + PeripheralType {} /// Flash mode. #[allow(private_bounds)] pub trait Mode: SealedMode {} diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 111e03356..af0837f6a 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -5,13 +5,13 @@ use core::future::Future; use core::pin::Pin as FuturePin; use core::task::{Context, Poll}; -use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::interrupt::InterruptExt; use crate::pac::common::{Reg, RW}; use crate::pac::SIO; -use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; +use crate::{interrupt, pac, peripherals, RegExt}; #[cfg(any(feature = "rp2040", feature = "rp235xa"))] pub(crate) const BANK0_PIN_COUNT: usize = 30; @@ -115,7 +115,7 @@ pub struct Input<'d> { impl<'d> Input<'d> { /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { let mut pin = Flex::new(pin); pin.set_as_input(); pin.set_pull(pull); @@ -266,11 +266,11 @@ fn IO_IRQ_QSPI() { #[must_use = "futures do nothing unless you `.await` or poll them"] struct InputFuture<'d> { - pin: PeripheralRef<'d, AnyPin>, + pin: Peri<'d, AnyPin>, } impl<'d> InputFuture<'d> { - fn new(pin: PeripheralRef<'d, AnyPin>, level: InterruptTrigger) -> Self { + fn new(pin: Peri<'d, AnyPin>, level: InterruptTrigger) -> Self { let pin_group = (pin.pin() % 8) as usize; // first, clear the INTR register bits. without this INTR will still // contain reports of previous edges, causing the IRQ to fire early @@ -359,7 +359,7 @@ pub struct Output<'d> { impl<'d> Output<'d> { /// Create GPIO output driver for a [Pin] with the provided [Level]. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { let mut pin = Flex::new(pin); match initial_output { Level::High => pin.set_high(), @@ -440,7 +440,7 @@ pub struct OutputOpenDrain<'d> { impl<'d> OutputOpenDrain<'d> { /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level]. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self { let mut pin = Flex::new(pin); pin.set_low(); match initial_output { @@ -581,7 +581,7 @@ impl<'d> OutputOpenDrain<'d> { /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// mode. pub struct Flex<'d> { - pin: PeripheralRef<'d, AnyPin>, + pin: Peri<'d, AnyPin>, } impl<'d> Flex<'d> { @@ -590,9 +590,7 @@ impl<'d> Flex<'d> { /// The pin remains disconnected. The initial output level is unspecified, but can be changed /// before the pin is put into output mode. #[inline] - pub fn new(pin: impl Peripheral

+ 'd) -> Self { - into_ref!(pin); - + pub fn new(pin: Peri<'d, impl Pin>) -> Self { pin.pad_ctrl().write(|w| { #[cfg(feature = "_rp235x")] w.set_iso(false); @@ -606,7 +604,7 @@ impl<'d> Flex<'d> { w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _); }); - Self { pin: pin.map_into() } + Self { pin: pin.into() } } #[inline] @@ -829,7 +827,7 @@ impl<'d> Drop for Flex<'d> { /// Dormant wake driver. pub struct DormantWake<'w> { - pin: PeripheralRef<'w, AnyPin>, + pin: Peri<'w, AnyPin>, cfg: DormantWakeConfig, } @@ -919,14 +917,7 @@ pub(crate) trait SealedPin: Sized { /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. #[allow(private_bounds)] -pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { - /// Degrade to a generic pin struct - fn degrade(self) -> AnyPin { - AnyPin { - pin_bank: self.pin_bank(), - } - } - +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// Returns the pin number within a bank #[inline] fn pin(&self) -> u8 { @@ -951,8 +942,8 @@ impl AnyPin { /// # Safety /// /// You must ensure that you’re only using one instance of this type at a time. - pub unsafe fn steal(pin_bank: u8) -> Self { - Self { pin_bank } + pub unsafe fn steal(pin_bank: u8) -> Peri<'static, Self> { + Peri::new_unchecked(Self { pin_bank }) } } @@ -979,7 +970,9 @@ macro_rules! impl_pin { impl From for crate::gpio::AnyPin { fn from(val: peripherals::$name) -> Self { - crate::gpio::Pin::degrade(val) + Self { + pin_bank: val.pin_bank(), + } } } }; diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 3a2ee666c..adc38b73d 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -5,13 +5,13 @@ use core::future; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use pac::i2c; use crate::gpio::AnyPin; use crate::interrupt::typelevel::{Binding, Interrupt}; -use crate::{interrupt, pac, peripherals, Peripheral}; +use crate::{interrupt, pac, peripherals}; /// I2C error abort reason #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -83,28 +83,25 @@ pub struct I2c<'d, T: Instance, M: Mode> { impl<'d, T: Instance> I2c<'d, T, Blocking> { /// Create a new driver instance in blocking mode. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - scl: impl Peripheral

> + 'd, - sda: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + scl: Peri<'d, impl SclPin>, + sda: Peri<'d, impl SdaPin>, config: Config, ) -> Self { - into_ref!(scl, sda); - Self::new_inner(peri, scl.map_into(), sda.map_into(), config) + Self::new_inner(peri, scl.into(), sda.into(), config) } } impl<'d, T: Instance> I2c<'d, T, Async> { /// Create a new driver instance in async mode. pub fn new_async( - peri: impl Peripheral

+ 'd, - scl: impl Peripheral

> + 'd, - sda: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + scl: Peri<'d, impl SclPin>, + sda: Peri<'d, impl SdaPin>, _irq: impl Binding>, config: Config, ) -> Self { - into_ref!(scl, sda); - - let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config); + let i2c = Self::new_inner(peri, scl.into(), sda.into(), config); let r = T::regs(); @@ -378,14 +375,7 @@ where } impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { - fn new_inner( - _peri: impl Peripheral

+ 'd, - scl: PeripheralRef<'d, AnyPin>, - sda: PeripheralRef<'d, AnyPin>, - config: Config, - ) -> Self { - into_ref!(_peri); - + fn new_inner(_peri: Peri<'d, T>, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self { let reset = T::reset(); crate::reset::reset(reset); crate::reset::unreset_wait(reset); @@ -804,7 +794,7 @@ impl_mode!(Async); /// I2C instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance { +pub trait Instance: SealedInstance + PeripheralType { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index d17b11d14..d420030d8 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs @@ -3,12 +3,11 @@ use core::future; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::into_ref; use pac::i2c; use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; use crate::interrupt::typelevel::{Binding, Interrupt}; -use crate::{pac, Peripheral}; +use crate::{pac, Peri}; /// I2C error #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -87,14 +86,12 @@ pub struct I2cSlave<'d, T: Instance> { impl<'d, T: Instance> I2cSlave<'d, T> { /// Create a new instance. pub fn new( - _peri: impl Peripheral

+ 'd, - scl: impl Peripheral

> + 'd, - sda: impl Peripheral

> + 'd, + _peri: Peri<'d, T>, + scl: Peri<'d, impl SclPin>, + sda: Peri<'d, impl SdaPin>, _irq: impl Binding>, config: Config, ) -> Self { - into_ref!(_peri, scl, sda); - assert!(config.addr != 0); // Configure SCL & SDA pins diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index de60af890..35099d07b 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -54,7 +54,7 @@ pub mod pio; pub(crate) mod relocate; // Reexports -pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] pub use rp_pac as pac; #[cfg(not(feature = "unstable-pac"))] diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs index 1450505b9..d10b6837c 100644 --- a/embassy-rp/src/multicore.rs +++ b/embassy-rp/src/multicore.rs @@ -51,7 +51,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; use crate::interrupt::InterruptExt; use crate::peripherals::CORE1; -use crate::{gpio, install_stack_guard, interrupt, pac}; +use crate::{gpio, install_stack_guard, interrupt, pac, Peri}; const PAUSE_TOKEN: u32 = 0xDEADBEEF; const RESUME_TOKEN: u32 = !0xDEADBEEF; @@ -139,7 +139,7 @@ unsafe fn SIO_IRQ_FIFO() { } /// Spawn a function on this core -pub fn spawn_core1(_core1: CORE1, stack: &'static mut Stack, entry: F) +pub fn spawn_core1(_core1: Peri<'static, CORE1>, stack: &'static mut Stack, entry: F) where F: FnOnce() -> bad::Never + Send + 'static, { diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index fd09d4bba..ec698d99c 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs @@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::{Context, Poll}; use atomic_polyfill::{AtomicU64, AtomicU8}; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use fixed::types::extra::U8; use fixed::FixedU32; @@ -235,7 +235,7 @@ impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> { /// Type representing a PIO pin. pub struct Pin<'l, PIO: Instance> { - pin: PeripheralRef<'l, AnyPin>, + pin: Peri<'l, AnyPin>, pio: PhantomData, } @@ -360,7 +360,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> { /// Prepare DMA transfer from RX FIFO. pub fn dma_pull<'a, C: Channel, W: Word>( &'a mut self, - ch: PeripheralRef<'a, C>, + ch: Peri<'a, C>, data: &'a mut [W], bswap: bool, ) -> Transfer<'a, C> { @@ -451,7 +451,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> { /// Prepare a DMA transfer to TX FIFO. pub fn dma_push<'a, C: Channel, W: Word>( &'a mut self, - ch: PeripheralRef<'a, C>, + ch: Peri<'a, C>, data: &'a [W], bswap: bool, ) -> Transfer<'a, C> { @@ -1147,9 +1147,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> { /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and* /// all [`StateMachine`]s for this block have been dropped. **Other members /// of [`Pio`] do not keep pin registrations alive.** - pub fn make_pio_pin(&mut self, pin: impl Peripheral

+ 'd) -> Pin<'d, PIO> { - into_ref!(pin); - + pub fn make_pio_pin(&mut self, pin: Peri<'d, impl PioPin + 'd>) -> Pin<'d, PIO> { // enable the outputs pin.pad_ctrl().write(|w| w.set_od(false)); // especially important on the 235x, where IE defaults to 0 @@ -1171,7 +1169,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> { // we can be relaxed about this because we're &mut here and nothing is cached PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); Pin { - pin: pin.into_ref().map_into(), + pin: pin.into(), pio: PhantomData::default(), } } @@ -1304,7 +1302,7 @@ pub struct Pio<'d, PIO: Instance> { impl<'d, PIO: Instance> Pio<'d, PIO> { /// Create a new instance of a PIO peripheral. - pub fn new(_pio: impl Peripheral

+ 'd, _irq: impl Binding>) -> Self { + pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding>) -> Self { PIO::state().users.store(5, Ordering::Release); PIO::state().used_pins.store(0, Ordering::Release); PIO::Interrupt::unpend(); @@ -1389,7 +1387,7 @@ trait SealedInstance { /// PIO instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance + Sized + Unpin { +pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin { /// Interrupt for this peripheral. type Interrupt: crate::interrupt::typelevel::Interrupt; } diff --git a/embassy-rp/src/pio_programs/hd44780.rs b/embassy-rp/src/pio_programs/hd44780.rs index 6997b91f3..5846a8027 100644 --- a/embassy-rp/src/pio_programs/hd44780.rs +++ b/embassy-rp/src/pio_programs/hd44780.rs @@ -5,7 +5,7 @@ use crate::pio::{ Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, }; -use crate::{into_ref, Peripheral, PeripheralRef}; +use crate::Peri; /// This struct represents a HD44780 program that takes command words ( <0:4>) pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> { @@ -99,7 +99,7 @@ impl<'a, PIO: Instance> PioHD44780CommandSequenceProgram<'a, PIO> { /// Pio backed HD44780 driver pub struct PioHD44780<'l, P: Instance, const S: usize> { - dma: PeripheralRef<'l, AnyChannel>, + dma: Peri<'l, AnyChannel>, sm: StateMachine<'l, P, S>, buf: [u8; 40], @@ -111,19 +111,17 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> { common: &mut Common<'l, P>, mut sm: StateMachine<'l, P, S>, mut irq: Irq<'l, P, S>, - dma: impl Peripheral

+ 'l, - rs: impl PioPin, - rw: impl PioPin, - e: impl PioPin, - db4: impl PioPin, - db5: impl PioPin, - db6: impl PioPin, - db7: impl PioPin, + mut dma: Peri<'l, impl Channel>, + rs: Peri<'l, impl PioPin>, + rw: Peri<'l, impl PioPin>, + e: Peri<'l, impl PioPin>, + db4: Peri<'l, impl PioPin>, + db5: Peri<'l, impl PioPin>, + db6: Peri<'l, impl PioPin>, + db7: Peri<'l, impl PioPin>, word_prg: &PioHD44780CommandWordProgram<'l, P>, seq_prg: &PioHD44780CommandSequenceProgram<'l, P>, ) -> PioHD44780<'l, P, S> { - into_ref!(dma); - let rs = common.make_pio_pin(rs); let rw = common.make_pio_pin(rw); let e = common.make_pio_pin(e); @@ -176,7 +174,7 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> { sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await; Self { - dma: dma.map_into(), + dma: dma.into(), sm, buf: [0x20; 40], } diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs index 17e321405..b967f0160 100644 --- a/embassy-rp/src/pio_programs/i2s.rs +++ b/embassy-rp/src/pio_programs/i2s.rs @@ -6,16 +6,16 @@ use crate::dma::{AnyChannel, Channel, Transfer}; use crate::pio::{ Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, }; -use crate::{into_ref, Peripheral, PeripheralRef}; +use crate::Peri; /// This struct represents an i2s output driver program -pub struct PioI2sOutProgram<'a, PIO: Instance> { - prg: LoadedProgram<'a, PIO>, +pub struct PioI2sOutProgram<'d, PIO: Instance> { + prg: LoadedProgram<'d, PIO>, } -impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> { +impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> { /// Load the program into the given pio - pub fn new(common: &mut Common<'a, PIO>) -> Self { + 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 @@ -37,27 +37,25 @@ impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> { } /// Pio backed I2s output driver -pub struct PioI2sOut<'a, P: Instance, const S: usize> { - dma: PeripheralRef<'a, AnyChannel>, - sm: StateMachine<'a, P, S>, +pub struct PioI2sOut<'d, P: Instance, const S: usize> { + dma: Peri<'d, AnyChannel>, + sm: StateMachine<'d, P, S>, } -impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> { +impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { /// Configure a state machine to output I2s pub fn new( - common: &mut Common<'a, P>, - mut sm: StateMachine<'a, P, S>, - dma: impl Peripheral

+ 'a, - data_pin: impl PioPin, - bit_clock_pin: impl PioPin, - lr_clock_pin: impl PioPin, + common: &mut Common<'d, P>, + mut sm: StateMachine<'d, P, S>, + dma: Peri<'d, impl Channel>, + data_pin: Peri<'d, impl PioPin>, + bit_clock_pin: Peri<'d, impl PioPin>, + lr_clock_pin: Peri<'d, impl PioPin>, sample_rate: u32, bit_depth: u32, channels: u32, - program: &PioI2sOutProgram<'a, P>, + program: &PioI2sOutProgram<'d, P>, ) -> Self { - into_ref!(dma); - let data_pin = common.make_pio_pin(data_pin); let bit_clock_pin = common.make_pio_pin(bit_clock_pin); let left_right_clock_pin = common.make_pio_pin(lr_clock_pin); @@ -82,10 +80,7 @@ impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> { sm.set_enable(true); - Self { - dma: dma.map_into(), - sm, - } + Self { dma: dma.into(), sm } } /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. diff --git a/embassy-rp/src/pio_programs/onewire.rs b/embassy-rp/src/pio_programs/onewire.rs index 040333e76..00783aab0 100644 --- a/embassy-rp/src/pio_programs/onewire.rs +++ b/embassy-rp/src/pio_programs/onewire.rs @@ -1,6 +1,7 @@ //! OneWire pio driver use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine}; +use crate::Peri; /// This struct represents an onewire driver program pub struct PioOneWireProgram<'a, PIO: Instance> { @@ -69,7 +70,7 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> { pub fn new( common: &mut Common<'d, PIO>, mut sm: StateMachine<'d, PIO, SM>, - pin: impl PioPin, + pin: Peri<'d, impl PioPin>, program: &PioOneWireProgram<'d, PIO>, ) -> Self { let pin = common.make_pio_pin(pin); diff --git a/embassy-rp/src/pio_programs/pwm.rs b/embassy-rp/src/pio_programs/pwm.rs index 01ffe012a..f0f837bc5 100644 --- a/embassy-rp/src/pio_programs/pwm.rs +++ b/embassy-rp/src/pio_programs/pwm.rs @@ -4,9 +4,9 @@ use core::time::Duration; use pio::InstructionOperands; -use crate::clocks; use crate::gpio::Level; use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine}; +use crate::{clocks, Peri}; /// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time fn to_pio_cycles(duration: Duration) -> u32 { @@ -52,7 +52,7 @@ impl<'d, T: Instance, const SM: usize> PioPwm<'d, T, SM> { pub fn new( pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, - pin: impl PioPin, + pin: Peri<'d, impl PioPin>, program: &PioPwmProgram<'d, T>, ) -> Self { let pin = pio.make_pio_pin(pin); diff --git a/embassy-rp/src/pio_programs/rotary_encoder.rs b/embassy-rp/src/pio_programs/rotary_encoder.rs index f2fb02aca..e520da8a3 100644 --- a/embassy-rp/src/pio_programs/rotary_encoder.rs +++ b/embassy-rp/src/pio_programs/rotary_encoder.rs @@ -6,6 +6,7 @@ use crate::gpio::Pull; use crate::pio::{ Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, }; +use crate::Peri; /// This struct represents an Encoder program loaded into pio instruction memory. pub struct PioEncoderProgram<'a, PIO: Instance> { @@ -33,8 +34,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { pub fn new( pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, - pin_a: impl PioPin, - pin_b: impl PioPin, + pin_a: Peri<'d, impl PioPin>, + pin_b: Peri<'d, impl PioPin>, program: &PioEncoderProgram<'d, T>, ) -> Self { let mut pin_a = pio.make_pio_pin(pin_a); diff --git a/embassy-rp/src/pio_programs/stepper.rs b/embassy-rp/src/pio_programs/stepper.rs index c8f74167d..495191659 100644 --- a/embassy-rp/src/pio_programs/stepper.rs +++ b/embassy-rp/src/pio_programs/stepper.rs @@ -7,6 +7,7 @@ use fixed::types::extra::U8; use fixed::FixedU32; use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine}; +use crate::Peri; /// This struct represents a Stepper driver program loaded into pio instruction memory. pub struct PioStepperProgram<'a, PIO: Instance> { @@ -50,10 +51,10 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> { pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, irq: Irq<'d, T, SM>, - pin0: impl PioPin, - pin1: impl PioPin, - pin2: impl PioPin, - pin3: impl PioPin, + pin0: Peri<'d, impl PioPin>, + pin1: Peri<'d, impl PioPin>, + pin2: Peri<'d, impl PioPin>, + pin3: Peri<'d, impl PioPin>, program: &PioStepperProgram<'d, T>, ) -> Self { let pin0 = pio.make_pio_pin(pin0); diff --git a/embassy-rp/src/pio_programs/uart.rs b/embassy-rp/src/pio_programs/uart.rs index 641daca61..04e39a571 100644 --- a/embassy-rp/src/pio_programs/uart.rs +++ b/embassy-rp/src/pio_programs/uart.rs @@ -10,15 +10,16 @@ use crate::gpio::Level; use crate::pio::{ Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, }; +use crate::Peri; /// This struct represents a uart tx program loaded into pio instruction memory. -pub struct PioUartTxProgram<'a, PIO: Instance> { - prg: LoadedProgram<'a, PIO>, +pub struct PioUartTxProgram<'d, PIO: Instance> { + prg: LoadedProgram<'d, PIO>, } -impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> { +impl<'d, PIO: Instance> PioUartTxProgram<'d, PIO> { /// Load the uart tx program into the given pio - pub fn new(common: &mut Common<'a, PIO>) -> Self { + pub fn new(common: &mut Common<'d, PIO>) -> Self { let prg = pio::pio_asm!( r#" .side_set 1 opt @@ -41,18 +42,18 @@ impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> { } /// PIO backed Uart transmitter -pub struct PioUartTx<'a, PIO: Instance, const SM: usize> { - sm_tx: StateMachine<'a, PIO, SM>, +pub struct PioUartTx<'d, PIO: Instance, const SM: usize> { + sm_tx: StateMachine<'d, PIO, SM>, } -impl<'a, PIO: Instance, const SM: usize> PioUartTx<'a, PIO, SM> { +impl<'d, PIO: Instance, const SM: usize> PioUartTx<'d, PIO, SM> { /// Configure a pio state machine to use the loaded tx program. pub fn new( baud: u32, - common: &mut Common<'a, PIO>, - mut sm_tx: StateMachine<'a, PIO, SM>, - tx_pin: impl PioPin, - program: &PioUartTxProgram<'a, PIO>, + common: &mut Common<'d, PIO>, + mut sm_tx: StateMachine<'d, PIO, SM>, + tx_pin: Peri<'d, impl PioPin>, + program: &PioUartTxProgram<'d, PIO>, ) -> Self { let tx_pin = common.make_pio_pin(tx_pin); sm_tx.set_pins(Level::High, &[&tx_pin]); @@ -92,13 +93,13 @@ impl Write for PioUartTx<'_, PIO, SM> { } /// This struct represents a Uart Rx program loaded into pio instruction memory. -pub struct PioUartRxProgram<'a, PIO: Instance> { - prg: LoadedProgram<'a, PIO>, +pub struct PioUartRxProgram<'d, PIO: Instance> { + prg: LoadedProgram<'d, PIO>, } -impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> { +impl<'d, PIO: Instance> PioUartRxProgram<'d, PIO> { /// Load the uart rx program into the given pio - pub fn new(common: &mut Common<'a, PIO>) -> Self { + pub fn new(common: &mut Common<'d, PIO>) -> Self { let prg = pio::pio_asm!( r#" ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and @@ -130,18 +131,18 @@ impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> { } /// PIO backed Uart reciever -pub struct PioUartRx<'a, PIO: Instance, const SM: usize> { - sm_rx: StateMachine<'a, PIO, SM>, +pub struct PioUartRx<'d, PIO: Instance, const SM: usize> { + sm_rx: StateMachine<'d, PIO, SM>, } -impl<'a, PIO: Instance, const SM: usize> PioUartRx<'a, PIO, SM> { +impl<'d, PIO: Instance, const SM: usize> PioUartRx<'d, PIO, SM> { /// Configure a pio state machine to use the loaded rx program. pub fn new( baud: u32, - common: &mut Common<'a, PIO>, - mut sm_rx: StateMachine<'a, PIO, SM>, - rx_pin: impl PioPin, - program: &PioUartRxProgram<'a, PIO>, + common: &mut Common<'d, PIO>, + mut sm_rx: StateMachine<'d, PIO, SM>, + rx_pin: Peri<'d, impl PioPin>, + program: &PioUartRxProgram<'d, PIO>, ) -> Self { let mut cfg = Config::default(); cfg.use_program(&program.prg, &[]); diff --git a/embassy-rp/src/pio_programs/ws2812.rs b/embassy-rp/src/pio_programs/ws2812.rs index 2462a64e6..578937e11 100644 --- a/embassy-rp/src/pio_programs/ws2812.rs +++ b/embassy-rp/src/pio_programs/ws2812.rs @@ -9,7 +9,7 @@ use crate::dma::{AnyChannel, Channel}; use crate::pio::{ Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, }; -use crate::{into_ref, Peripheral, PeripheralRef}; +use crate::Peri; const T1: u8 = 2; // start bit const T2: u8 = 5; // data bit @@ -53,7 +53,7 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> { /// Pio backed ws2812 driver /// Const N is the number of ws2812 leds attached to this pin pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> { - dma: PeripheralRef<'d, AnyChannel>, + dma: Peri<'d, AnyChannel>, sm: StateMachine<'d, P, S>, } @@ -62,12 +62,10 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { pub fn new( pio: &mut Common<'d, P>, mut sm: StateMachine<'d, P, S>, - dma: impl Peripheral

+ 'd, - pin: impl PioPin, + dma: Peri<'d, impl Channel>, + pin: Peri<'d, impl PioPin>, program: &PioWs2812Program<'d, P>, ) -> Self { - into_ref!(dma); - // Setup sm0 let mut cfg = Config::default(); @@ -95,10 +93,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { sm.set_config(&cfg); sm.set_enable(true); - Self { - dma: dma.map_into(), - sm, - } + Self { dma: dma.into(), sm } } /// Write a buffer of [smart_leds::RGB8] to the ws2812 string diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 4fb8ade12..f631402a2 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -1,6 +1,6 @@ //! Pulse Width Modulation (PWM) -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; pub use embedded_hal_1::pwm::SetDutyCycle; use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType}; use fixed::traits::ToFixed; @@ -99,8 +99,8 @@ impl Error for PwmError { /// PWM driver. pub struct Pwm<'d> { - pin_a: Option>, - pin_b: Option>, + pin_a: Option>, + pin_b: Option>, slice: usize, } @@ -131,8 +131,8 @@ impl<'d> SetDutyCycle for Pwm<'d> { impl<'d> Pwm<'d> { fn new_inner( slice: usize, - a: Option>, - b: Option>, + a: Option>, + b: Option>, b_pull: Pull, config: Config, divmode: Divmode, @@ -171,60 +171,34 @@ impl<'d> Pwm<'d> { /// Create PWM driver without any configured pins. #[inline] - pub fn new_free(slice: impl Peripheral

+ 'd, config: Config) -> Self { - into_ref!(slice); + pub fn new_free(slice: Peri<'d, T>, config: Config) -> Self { Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) } /// Create PWM driver with a single 'a' pin as output. #[inline] - pub fn new_output_a( - slice: impl Peripheral

+ 'd, - a: impl Peripheral

> + 'd, - config: Config, - ) -> Self { - into_ref!(slice, a); - Self::new_inner( - slice.number(), - Some(a.map_into()), - None, - Pull::None, - config, - Divmode::DIV, - ) + pub fn new_output_a(slice: Peri<'d, T>, a: Peri<'d, impl ChannelAPin>, config: Config) -> Self { + Self::new_inner(slice.number(), Some(a.into()), None, Pull::None, config, Divmode::DIV) } /// Create PWM driver with a single 'b' pin as output. #[inline] - pub fn new_output_b( - slice: impl Peripheral

+ 'd, - b: impl Peripheral

> + 'd, - config: Config, - ) -> Self { - into_ref!(slice, b); - Self::new_inner( - slice.number(), - None, - Some(b.map_into()), - Pull::None, - config, - Divmode::DIV, - ) + pub fn new_output_b(slice: Peri<'d, T>, b: Peri<'d, impl ChannelBPin>, config: Config) -> Self { + Self::new_inner(slice.number(), None, Some(b.into()), Pull::None, config, Divmode::DIV) } /// Create PWM driver with a 'a' and 'b' pins as output. #[inline] pub fn new_output_ab( - slice: impl Peripheral

+ 'd, - a: impl Peripheral

> + 'd, - b: impl Peripheral

> + 'd, + slice: Peri<'d, T>, + a: Peri<'d, impl ChannelAPin>, + b: Peri<'d, impl ChannelBPin>, config: Config, ) -> Self { - into_ref!(slice, a, b); Self::new_inner( slice.number(), - Some(a.map_into()), - Some(b.map_into()), + Some(a.into()), + Some(b.into()), Pull::None, config, Divmode::DIV, @@ -234,31 +208,29 @@ impl<'d> Pwm<'d> { /// Create PWM driver with a single 'b' as input pin. #[inline] pub fn new_input( - slice: impl Peripheral

+ 'd, - b: impl Peripheral

> + 'd, + slice: Peri<'d, T>, + b: Peri<'d, impl ChannelBPin>, b_pull: Pull, mode: InputMode, config: Config, ) -> Self { - into_ref!(slice, b); - Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into()) + Self::new_inner(slice.number(), None, Some(b.into()), b_pull, config, mode.into()) } /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. #[inline] pub fn new_output_input( - slice: impl Peripheral

+ 'd, - a: impl Peripheral

> + 'd, - b: impl Peripheral

> + 'd, + slice: Peri<'d, T>, + a: Peri<'d, impl ChannelAPin>, + b: Peri<'d, impl ChannelBPin>, b_pull: Pull, mode: InputMode, config: Config, ) -> Self { - into_ref!(slice, a, b); Self::new_inner( slice.number(), - Some(a.map_into()), - Some(b.map_into()), + Some(a.into()), + Some(b.into()), b_pull, config, mode.into(), @@ -373,8 +345,8 @@ impl<'d> Pwm<'d> { } enum PwmChannelPin<'d> { - A(PeripheralRef<'d, AnyPin>), - B(PeripheralRef<'d, AnyPin>), + A(Peri<'d, AnyPin>), + B(Peri<'d, AnyPin>), } /// Single channel of Pwm driver. @@ -498,7 +470,7 @@ trait SealedSlice {} /// PWM Slice. #[allow(private_bounds)] -pub trait Slice: Peripheral

+ SealedSlice + Sized + 'static { +pub trait Slice: PeripheralType + SealedSlice + Sized + 'static { /// Slice number. fn number(&self) -> usize; } diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs index 2ce7ac645..63cf91d28 100644 --- a/embassy-rp/src/rtc/mod.rs +++ b/embassy-rp/src/rtc/mod.rs @@ -1,7 +1,7 @@ //! RTC driver. mod filter; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; pub use self::filter::DateTimeFilter; @@ -14,7 +14,7 @@ use crate::clocks::clk_rtc_freq; /// A reference to the real time clock of the system pub struct Rtc<'d, T: Instance> { - inner: PeripheralRef<'d, T>, + inner: Peri<'d, T>, } impl<'d, T: Instance> Rtc<'d, T> { @@ -23,9 +23,7 @@ impl<'d, T: Instance> Rtc<'d, T> { /// # Errors /// /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. - pub fn new(inner: impl Peripheral

+ 'd) -> Self { - into_ref!(inner); - + pub fn new(inner: Peri<'d, T>) -> Self { // Set the RTC divider inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1)); @@ -194,7 +192,7 @@ trait SealedInstance { /// RTC peripheral instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance {} +pub trait Instance: SealedInstance + PeripheralType {} impl SealedInstance for crate::peripherals::RTC { fn regs(&self) -> crate::pac::rtc::Rtc { diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index c48b5c54f..559b3b909 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -3,12 +3,12 @@ use core::marker::PhantomData; use embassy_embedded_hal::SetConfig; use embassy_futures::join::join; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; pub use embedded_hal_02::spi::{Phase, Polarity}; use crate::dma::{AnyChannel, Channel}; use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; -use crate::{pac, peripherals, Peripheral}; +use crate::{pac, peripherals}; /// SPI errors. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -42,9 +42,9 @@ impl Default for Config { /// SPI driver. pub struct Spi<'d, T: Instance, M: Mode> { - inner: PeripheralRef<'d, T>, - tx_dma: Option>, - rx_dma: Option>, + inner: Peri<'d, T>, + tx_dma: Option>, + rx_dma: Option>, phantom: PhantomData<(&'d mut T, M)>, } @@ -73,17 +73,15 @@ fn calc_prescs(freq: u32) -> (u8, u8) { impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { fn new_inner( - inner: impl Peripheral

+ 'd, - clk: Option>, - mosi: Option>, - miso: Option>, - cs: Option>, - tx_dma: Option>, - rx_dma: Option>, + inner: Peri<'d, T>, + clk: Option>, + mosi: Option>, + miso: Option>, + cs: Option>, + tx_dma: Option>, + rx_dma: Option>, config: Config, ) -> Self { - into_ref!(inner); - Self::apply_config(&inner, &config); let p = inner.regs(); @@ -161,7 +159,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { /// /// Driver should be disabled before making changes and reenabled after the modifications /// are applied. - fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) { + fn apply_config(inner: &Peri<'d, T>, config: &Config) { let p = inner.regs(); let (presc, postdiv) = calc_prescs(config.frequency); @@ -273,18 +271,17 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { impl<'d, T: Instance> Spi<'d, T, Blocking> { /// Create an SPI driver in blocking mode. pub fn new_blocking( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - mosi: impl Peripheral

+ 'd> + 'd, - miso: impl Peripheral

+ 'd> + 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + mosi: Peri<'d, impl MosiPin + 'd>, + miso: Peri<'d, impl MisoPin + 'd>, config: Config, ) -> Self { - into_ref!(clk, mosi, miso); Self::new_inner( inner, - Some(clk.map_into()), - Some(mosi.map_into()), - Some(miso.map_into()), + Some(clk.into()), + Some(mosi.into()), + Some(miso.into()), None, None, None, @@ -294,16 +291,15 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { /// Create an SPI driver in blocking mode supporting writes only. pub fn new_blocking_txonly( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - mosi: impl Peripheral

+ 'd> + 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + mosi: Peri<'d, impl MosiPin + 'd>, config: Config, ) -> Self { - into_ref!(clk, mosi); Self::new_inner( inner, - Some(clk.map_into()), - Some(mosi.map_into()), + Some(clk.into()), + Some(mosi.into()), None, None, None, @@ -314,17 +310,16 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { /// Create an SPI driver in blocking mode supporting reads only. pub fn new_blocking_rxonly( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - miso: impl Peripheral

+ 'd> + 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + miso: Peri<'d, impl MisoPin + 'd>, config: Config, ) -> Self { - into_ref!(clk, miso); Self::new_inner( inner, - Some(clk.map_into()), + Some(clk.into()), None, - Some(miso.map_into()), + Some(miso.into()), None, None, None, @@ -336,43 +331,41 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { impl<'d, T: Instance> Spi<'d, T, Async> { /// Create an SPI driver in async mode supporting DMA operations. pub fn new( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - mosi: impl Peripheral

+ 'd> + 'd, - miso: impl Peripheral

+ 'd> + 'd, - tx_dma: impl Peripheral

+ 'd, - rx_dma: impl Peripheral

+ 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + mosi: Peri<'d, impl MosiPin + 'd>, + miso: Peri<'d, impl MisoPin + 'd>, + tx_dma: Peri<'d, impl Channel>, + rx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx_dma, rx_dma, clk, mosi, miso); Self::new_inner( inner, - Some(clk.map_into()), - Some(mosi.map_into()), - Some(miso.map_into()), + Some(clk.into()), + Some(mosi.into()), + Some(miso.into()), None, - Some(tx_dma.map_into()), - Some(rx_dma.map_into()), + Some(tx_dma.into()), + Some(rx_dma.into()), config, ) } /// Create an SPI driver in async mode supporting DMA write operations only. pub fn new_txonly( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - mosi: impl Peripheral

+ 'd> + 'd, - tx_dma: impl Peripheral

+ 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + mosi: Peri<'d, impl MosiPin + 'd>, + tx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx_dma, clk, mosi); Self::new_inner( inner, - Some(clk.map_into()), - Some(mosi.map_into()), + Some(clk.into()), + Some(mosi.into()), None, None, - Some(tx_dma.map_into()), + Some(tx_dma.into()), None, config, ) @@ -380,29 +373,28 @@ impl<'d, T: Instance> Spi<'d, T, Async> { /// Create an SPI driver in async mode supporting DMA read operations only. pub fn new_rxonly( - inner: impl Peripheral

+ 'd, - clk: impl Peripheral

+ 'd> + 'd, - miso: impl Peripheral

+ 'd> + 'd, - tx_dma: impl Peripheral

+ 'd, - rx_dma: impl Peripheral

+ 'd, + inner: Peri<'d, T>, + clk: Peri<'d, impl ClkPin + 'd>, + miso: Peri<'d, impl MisoPin + 'd>, + tx_dma: Peri<'d, impl Channel>, + rx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx_dma, rx_dma, clk, miso); Self::new_inner( inner, - Some(clk.map_into()), + Some(clk.into()), None, - Some(miso.map_into()), + Some(miso.into()), None, - Some(tx_dma.map_into()), - Some(rx_dma.map_into()), + Some(tx_dma.into()), + Some(rx_dma.into()), config, ) } /// Write data to SPI using DMA. pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { - let tx_ch = self.tx_dma.as_mut().unwrap(); + let tx_ch = self.tx_dma.as_mut().unwrap().reborrow(); let tx_transfer = unsafe { // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. @@ -427,14 +419,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> { pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { // Start RX first. Transfer starts when TX starts, if RX // is not started yet we might lose bytes. - let rx_ch = self.rx_dma.as_mut().unwrap(); + let rx_ch = self.rx_dma.as_mut().unwrap().reborrow(); let rx_transfer = unsafe { // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ) }; - let tx_ch = self.tx_dma.as_mut().unwrap(); + let tx_ch = self.tx_dma.as_mut().unwrap().reborrow(); let tx_transfer = unsafe { // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. @@ -462,20 +454,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> { async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { // Start RX first. Transfer starts when TX starts, if RX // is not started yet we might lose bytes. - let rx_ch = self.rx_dma.as_mut().unwrap(); + let rx_ch = self.rx_dma.as_mut().unwrap().reborrow(); let rx_transfer = unsafe { // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ) }; - let mut tx_ch = self.tx_dma.as_mut().unwrap(); + let mut tx_ch = self.tx_dma.as_mut().unwrap().reborrow(); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. let tx_transfer = async { let p = self.inner.regs(); unsafe { - crate::dma::write(&mut tx_ch, tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await; + crate::dma::write(tx_ch.reborrow(), tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await; if rx.len() > tx.len() { let write_bytes_len = rx.len() - tx.len(); @@ -519,7 +511,7 @@ pub trait Mode: SealedMode {} /// SPI instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance {} +pub trait Instance: SealedInstance + PeripheralType {} macro_rules! impl_instance { ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { diff --git a/embassy-rp/src/trng.rs b/embassy-rp/src/trng.rs index 9f2f33c4b..44b1bb996 100644 --- a/embassy-rp/src/trng.rs +++ b/embassy-rp/src/trng.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use core::ops::Not; use core::task::Poll; -use embassy_hal_internal::Peripheral; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use rand_core::Error; @@ -20,7 +20,7 @@ trait SealedInstance { /// TRNG peripheral instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance { +pub trait Instance: SealedInstance + PeripheralType { /// Interrupt for this peripheral. type Interrupt: Interrupt; } @@ -158,11 +158,7 @@ const TRNG_BLOCK_SIZE_BYTES: usize = TRNG_BLOCK_SIZE_BITS / 8; impl<'d, T: Instance> Trng<'d, T> { /// Create a new TRNG driver. - pub fn new( - _trng: impl Peripheral

+ 'd, - _irq: impl Binding> + 'd, - config: Config, - ) -> Self { + pub fn new(_trng: Peri<'d, T>, _irq: impl Binding> + 'd, config: Config) -> Self { let regs = T::regs(); regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false)); diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 152a432c9..5b5159d22 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs @@ -90,17 +90,15 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>( impl<'d, T: Instance> BufferedUart<'d, T> { /// Create a buffered UART instance. pub fn new( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(tx, rx); - - super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config); + super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config); init_buffers::(irq, Some(tx_buffer), Some(rx_buffer)); Self { @@ -111,23 +109,21 @@ impl<'d, T: Instance> BufferedUart<'d, T> { /// Create a buffered UART instance with flow control. pub fn new_with_rtscts( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(tx, rx, cts, rts); - super::Uart::<'d, T, Async>::init( - Some(tx.map_into()), - Some(rx.map_into()), - Some(rts.map_into()), - Some(cts.map_into()), + Some(tx.into()), + Some(rx.into()), + Some(rts.into()), + Some(cts.into()), config, ); init_buffers::(irq, Some(tx_buffer), Some(rx_buffer)); @@ -184,15 +180,13 @@ impl<'d, T: Instance> BufferedUart<'d, T> { impl<'d, T: Instance> BufferedUartRx<'d, T> { /// Create a new buffered UART RX. pub fn new( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - rx: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, rx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(rx); - - super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config); + super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config); init_buffers::(irq, None, Some(rx_buffer)); Self { phantom: PhantomData } @@ -200,16 +194,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { /// Create a new buffered UART RX with flow control. pub fn new_with_rts( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, rx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(rx, rts); - - super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config); + super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config); init_buffers::(irq, None, Some(rx_buffer)); Self { phantom: PhantomData } @@ -338,15 +330,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { impl<'d, T: Instance> BufferedUartTx<'d, T> { /// Create a new buffered UART TX. pub fn new( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - tx: impl Peripheral

> + 'd, + tx: Peri<'d, impl TxPin>, tx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(tx); - - super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config); + super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config); init_buffers::(irq, Some(tx_buffer), None); Self { phantom: PhantomData } @@ -354,16 +344,14 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { /// Create a new buffered UART TX with flow control. pub fn new_with_cts( - _uart: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, irq: impl Binding>, - tx: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + tx: Peri<'d, impl TxPin>, + cts: Peri<'d, impl CtsPin>, tx_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(tx, cts); - - super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config); + super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config); init_buffers::(irq, Some(tx_buffer), None); Self { phantom: PhantomData } diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 8d12aeef6..90c7655be 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -5,7 +5,7 @@ use core::task::Poll; use atomic_polyfill::{AtomicU16, Ordering}; use embassy_futures::select::{select, Either}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use embassy_time::{Delay, Timer}; use pac::uart::regs::Uartris; @@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel}; use crate::gpio::{AnyPin, SealedPin}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::pac::io::vals::{Inover, Outover}; -use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; +use crate::{interrupt, pac, peripherals, RegExt}; mod buffered; pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; @@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> { /// UART TX driver. pub struct UartTx<'d, T: Instance, M: Mode> { - tx_dma: Option>, + tx_dma: Option>, phantom: PhantomData<(&'d mut T, M)>, } /// UART RX driver. pub struct UartRx<'d, T: Instance, M: Mode> { - rx_dma: Option>, + rx_dma: Option>, phantom: PhantomData<(&'d mut T, M)>, } impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { /// Create a new DMA-enabled UART which can only send data pub fn new( - _uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

+ 'd, + _uart: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + tx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx, tx_dma); - Uart::::init(Some(tx.map_into()), None, None, None, config); - Self::new_inner(Some(tx_dma.map_into())) + Uart::::init(Some(tx.into()), None, None, None, config); + Self::new_inner(Some(tx_dma.into())) } - fn new_inner(tx_dma: Option>) -> Self { + fn new_inner(tx_dma: Option>) -> Self { Self { tx_dma, phantom: PhantomData, @@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { impl<'d, T: Instance> UartTx<'d, T, Blocking> { /// Create a new UART TX instance for blocking mode operations. - pub fn new_blocking( - _uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - config: Config, - ) -> Self { - into_ref!(tx); - Uart::::init(Some(tx.map_into()), None, None, None, config); + pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin>, config: Config) -> Self { + Uart::::init(Some(tx.into()), None, None, None, config); Self::new_inner(None) } @@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> { impl<'d, T: Instance> UartTx<'d, T, Async> { /// Write to UART TX from the provided buffer using DMA. pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { - let ch = self.tx_dma.as_mut().unwrap(); + let ch = self.tx_dma.as_mut().unwrap().reborrow(); let transfer = unsafe { T::regs().uartdmacr().write_set(|reg| { reg.set_txdmae(true); @@ -268,18 +262,17 @@ impl<'d, T: Instance> UartTx<'d, T, Async> { impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { /// Create a new DMA-enabled UART which can only receive data pub fn new( - _uart: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, + _uart: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, _irq: impl Binding>, - rx_dma: impl Peripheral

+ 'd, + rx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(rx, rx_dma); - Uart::::init(None, Some(rx.map_into()), None, None, config); - Self::new_inner(true, Some(rx_dma.map_into())) + Uart::::init(None, Some(rx.into()), None, None, config); + Self::new_inner(true, Some(rx_dma.into())) } - fn new_inner(has_irq: bool, rx_dma: Option>) -> Self { + fn new_inner(has_irq: bool, rx_dma: Option>) -> Self { debug_assert_eq!(has_irq, rx_dma.is_some()); if has_irq { // disable all error interrupts initially @@ -346,13 +339,8 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> { impl<'d, T: Instance> UartRx<'d, T, Blocking> { /// Create a new UART RX instance for blocking mode operations. - pub fn new_blocking( - _uart: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - config: Config, - ) -> Self { - into_ref!(rx); - Uart::::init(None, Some(rx.map_into()), None, None, config); + pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin>, config: Config) -> Self { + Uart::::init(None, Some(rx.into()), None, None, config); Self::new_inner(false, None) } @@ -419,7 +407,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { // start a dma transfer. if errors have happened in the interim some error // interrupt flags will have been raised, and those will be picked up immediately // by the interrupt handler. - let ch = self.rx_dma.as_mut().unwrap(); + let ch = self.rx_dma.as_mut().unwrap().reborrow(); T::regs().uartimsc().write_set(|w| { w.set_oeim(true); w.set_beim(true); @@ -566,7 +554,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { // start a dma transfer. if errors have happened in the interim some error // interrupt flags will have been raised, and those will be picked up immediately // by the interrupt handler. - let mut ch = self.rx_dma.as_mut().unwrap(); + let ch = self.rx_dma.as_mut().unwrap(); T::regs().uartimsc().write_set(|w| { w.set_oeim(true); w.set_beim(true); @@ -583,7 +571,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. crate::dma::read( - &mut ch, + ch.reborrow(), T::regs().uartdr().as_ptr() as *const _, sbuffer, T::RX_DREQ.into(), @@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { impl<'d, T: Instance> Uart<'d, T, Blocking> { /// Create a new UART without hardware flow control pub fn new_blocking( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, + uart: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, config: Config, ) -> Self { - into_ref!(tx, rx); - Self::new_inner( - uart, - tx.map_into(), - rx.map_into(), - None, - None, - false, - None, - None, - config, - ) + Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config) } /// Create a new UART with hardware flow control (RTS/CTS) pub fn new_with_rtscts_blocking( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + uart: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, config: Config, ) -> Self { - into_ref!(tx, rx, cts, rts); Self::new_inner( uart, - tx.map_into(), - rx.map_into(), - Some(rts.map_into()), - Some(cts.map_into()), + tx.into(), + rx.into(), + Some(rts.into()), + Some(cts.into()), false, None, None, @@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { impl<'d, T: Instance> Uart<'d, T, Async> { /// Create a new DMA enabled UART without hardware flow control pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, + uart: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, _irq: impl Binding>, - tx_dma: impl Peripheral

+ 'd, - rx_dma: impl Peripheral

+ 'd, + tx_dma: Peri<'d, impl Channel>, + rx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx, rx, tx_dma, rx_dma); Self::new_inner( uart, - tx.map_into(), - rx.map_into(), + tx.into(), + rx.into(), None, None, true, - Some(tx_dma.map_into()), - Some(rx_dma.map_into()), + Some(tx_dma.into()), + Some(rx_dma.into()), config, ) } /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) pub fn new_with_rtscts( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + uart: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, _irq: impl Binding>, - tx_dma: impl Peripheral

+ 'd, - rx_dma: impl Peripheral

+ 'd, + tx_dma: Peri<'d, impl Channel>, + rx_dma: Peri<'d, impl Channel>, config: Config, ) -> Self { - into_ref!(tx, rx, cts, rts, tx_dma, rx_dma); Self::new_inner( uart, - tx.map_into(), - rx.map_into(), - Some(rts.map_into()), - Some(cts.map_into()), + tx.into(), + rx.into(), + Some(rts.into()), + Some(cts.into()), true, - Some(tx_dma.map_into()), - Some(rx_dma.map_into()), + Some(tx_dma.into()), + Some(rx_dma.into()), config, ) } @@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> { impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { fn new_inner( - _uart: impl Peripheral

+ 'd, - mut tx: PeripheralRef<'d, AnyPin>, - mut rx: PeripheralRef<'d, AnyPin>, - mut rts: Option>, - mut cts: Option>, + _uart: Peri<'d, T>, + mut tx: Peri<'d, AnyPin>, + mut rx: Peri<'d, AnyPin>, + mut rts: Option>, + mut cts: Option>, has_irq: bool, - tx_dma: Option>, - rx_dma: Option>, + tx_dma: Option>, + rx_dma: Option>, config: Config, ) -> Self { Self::init( @@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { } fn init( - tx: Option>, - rx: Option>, - rts: Option>, - cts: Option>, + tx: Option>, + rx: Option>, + rts: Option>, + cts: Option>, config: Config, ) { let r = T::regs(); @@ -1326,7 +1300,7 @@ impl_mode!(Async); /// UART instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance { +pub trait Instance: SealedInstance + PeripheralType { /// Interrupt for this instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index 26cb90d89..96541ade6 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs @@ -5,6 +5,7 @@ use core::slice; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use embassy_usb_driver as driver; use embassy_usb_driver::{ @@ -12,7 +13,7 @@ use embassy_usb_driver::{ }; use crate::interrupt::typelevel::{Binding, Interrupt}; -use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; +use crate::{interrupt, pac, peripherals, Peri, RegExt}; trait SealedInstance { fn regs() -> crate::pac::usb::Usb; @@ -21,7 +22,7 @@ trait SealedInstance { /// USB peripheral instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } @@ -107,7 +108,7 @@ pub struct Driver<'d, T: Instance> { impl<'d, T: Instance> Driver<'d, T> { /// Create a new USB driver. - pub fn new(_usb: impl Peripheral

+ 'd, _irq: impl Binding>) -> Self { + pub fn new(_usb: Peri<'d, T>, _irq: impl Binding>) -> Self { T::Interrupt::unpend(); unsafe { T::Interrupt::enable() }; diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs index 553936602..760d6aac2 100644 --- a/embassy-rp/src/watchdog.rs +++ b/embassy-rp/src/watchdog.rs @@ -10,8 +10,8 @@ use core::marker::PhantomData; use embassy_time::Duration; -use crate::pac; use crate::peripherals::WATCHDOG; +use crate::{pac, Peri}; /// The reason for a system reset from the watchdog. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -30,7 +30,7 @@ pub struct Watchdog { impl Watchdog { /// Create a new `Watchdog` - pub fn new(_watchdog: WATCHDOG) -> Self { + pub fn new(_watchdog: Peri<'static, WATCHDOG>) -> Self { Self { phantom: PhantomData, load_value: 0, diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 25e6d965a..40ff14795 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -23,7 +23,7 @@ mod fmt; use core::mem::MaybeUninit; use core::sync::atomic::{compiler_fence, Ordering}; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::peripherals::IPCC; @@ -52,7 +52,7 @@ type PacketHeader = LinkedListNode; /// Transport Layer for the Mailbox interface pub struct TlMbox<'d> { - _ipcc: PeripheralRef<'d, IPCC>, + _ipcc: Peri<'d, IPCC>, pub sys_subsystem: Sys, pub mm_subsystem: MemoryManager, @@ -92,13 +92,11 @@ impl<'d> TlMbox<'d> { /// Figure 66. // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem pub fn init( - ipcc: impl Peripheral

+ 'd, + ipcc: Peri<'d, IPCC>, _irqs: impl interrupt::typelevel::Binding + interrupt::typelevel::Binding, config: Config, ) -> Self { - into_ref!(ipcc); - // this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289. // HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this // implementation diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8ca79eadf..798133162 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -324,7 +324,7 @@ fn main() { let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); flash_regions.extend(quote! { #[cfg(flash)] - pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData); + pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData); }); } @@ -356,7 +356,7 @@ fn main() { #[cfg(flash)] impl<'d, MODE> FlashLayout<'d, MODE> { - pub(crate) fn new(p: embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { + pub(crate) fn new(p: embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>) -> Self { Self { #(#inits),*, _mode: core::marker::PhantomData, diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs index 84763ad4f..a9c1d8faf 100644 --- a/embassy-stm32/src/adc/c0.rs +++ b/embassy-stm32/src/adc/c0.rs @@ -8,7 +8,7 @@ use super::{ }; use crate::dma::Transfer; use crate::time::Hertz; -use crate::{pac, rcc, Peripheral}; +use crate::{pac, rcc, Peri}; /// Default VREF voltage used for sample conversion to millivolts. pub const VREF_DEFAULT_MV: u32 = 3300; @@ -154,8 +154,7 @@ pub enum Averaging { impl<'d, T: Instance> Adc<'d, T> { /// Create a new ADC driver. - pub fn new(adc: impl Peripheral

+ 'd, sample_time: SampleTime, resolution: Resolution) -> Self { - embassy_hal_internal::into_ref!(adc); + pub fn new(adc: Peri<'d, T>, sample_time: SampleTime, resolution: Resolution) -> Self { rcc::enable_and_reset::(); T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK)); @@ -319,7 +318,7 @@ impl<'d, T: Instance> Adc<'d, T> { Self::apply_channel_conf() } - async fn dma_convert(&mut self, rx_dma: &mut impl RxDma, readings: &mut [u16]) { + async fn dma_convert(&mut self, rx_dma: Peri<'_, impl RxDma>, readings: &mut [u16]) { // Enable overrun control, so no new DMA requests will be generated until // previous DR values is read. T::regs().isr().modify(|reg| { @@ -374,7 +373,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// TODO(chudsaviet): externalize generic code and merge with read(). pub async fn read_in_hw_order( &mut self, - rx_dma: &mut impl RxDma, + rx_dma: Peri<'_, impl RxDma>, hw_channel_selection: u32, scandir: Scandir, readings: &mut [u16], @@ -415,7 +414,7 @@ impl<'d, T: Instance> Adc<'d, T> { // For other channels, use `read_in_hw_order()` or blocking read. pub async fn read( &mut self, - rx_dma: &mut impl RxDma, + rx_dma: Peri<'_, impl RxDma>, channel_sequence: impl ExactSizeIterator>, readings: &mut [u16], ) { diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index b37ec260f..fa6255c23 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs @@ -2,12 +2,10 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::into_ref; - use super::blocking_delay_us; use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::time::Hertz; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc, Peri}; pub const VDDA_CALIB_MV: u32 = 3300; pub const ADC_MAX: u32 = (1 << 12) - 1; @@ -48,8 +46,7 @@ impl super::SealedAdcChannel for Temperature { } impl<'d, T: Instance> Adc<'d, T> { - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); T::regs().cr2().modify(|reg| reg.set_adon(true)); diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index 0ebeb8a9e..3aeb6f2c7 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs @@ -2,13 +2,11 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::into_ref; - use super::blocking_delay_us; use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::interrupt::typelevel::Interrupt; use crate::time::Hertz; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc, Peri}; pub const VDDA_CALIB_MV: u32 = 3300; pub const ADC_MAX: u32 = (1 << 12) - 1; @@ -56,13 +54,11 @@ impl super::SealedAdcChannel for Temperature { impl<'d, T: Instance> Adc<'d, T> { pub fn new( - adc: impl Peripheral

+ 'd, + adc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { use crate::pac::adc::vals; - into_ref!(adc); - rcc::enable_and_reset::(); // Enable the adc regulator diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs index 291a3861e..944e971bb 100644 --- a/embassy-stm32/src/adc/f3_v1_1.rs +++ b/embassy-stm32/src/adc/f3_v1_1.rs @@ -3,14 +3,13 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_futures::yield_now; -use embassy_hal_internal::into_ref; use embassy_time::Instant; use super::Resolution; use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; use crate::interrupt::typelevel::Interrupt; use crate::time::Hertz; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc, Peri}; const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ; @@ -138,11 +137,9 @@ impl Drop for Temperature { impl<'d, T: Instance> Adc<'d, T> { pub fn new( - adc: impl Peripheral

+ 'd, + adc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(adc); - rcc::enable_and_reset::(); //let r = T::regs(); diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 0291ef4de..6a00e788e 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs @@ -11,7 +11,7 @@ use super::{blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolut use crate::adc::SealedAdcChannel; use crate::dma::Transfer; use crate::time::Hertz; -use crate::{pac, rcc, Peripheral}; +use crate::{pac, rcc, Peri}; /// Default VREF voltage used for sample conversion to millivolts. pub const VREF_DEFAULT_MV: u32 = 3300; @@ -135,8 +135,7 @@ impl Prescaler { impl<'d, T: Instance> Adc<'d, T> { /// Create a new ADC driver. - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - embassy_hal_internal::into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); let prescaler = Prescaler::from_ker_ck(T::frequency()); @@ -364,8 +363,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// use embassy_stm32::adc::{Adc, AdcChannel} /// /// let mut adc = Adc::new(p.ADC1); - /// let mut adc_pin0 = p.PA0.degrade_adc(); - /// let mut adc_pin1 = p.PA1.degrade_adc(); + /// let mut adc_pin0 = p.PA0.into(); + /// let mut adc_pin1 = p.PA1.into(); /// let mut measurements = [0u16; 2]; /// /// adc.read_async( @@ -382,7 +381,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// ``` pub async fn read( &mut self, - rx_dma: &mut impl RxDma, + rx_dma: Peri<'_, impl RxDma>, sequence: impl ExactSizeIterator, SampleTime)>, readings: &mut [u16], ) { diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 31a08b6eb..321db7431 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -22,6 +22,7 @@ use core::marker::PhantomData; #[allow(unused)] #[cfg(not(any(adc_f3_v2)))] pub use _version::*; +use embassy_hal_internal::{impl_peripheral, PeripheralType}; #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] use embassy_sync::waitqueue::AtomicWaker; @@ -42,7 +43,7 @@ dma_trait!(RxDma4, adc4::Instance); /// Analog to Digital driver. pub struct Adc<'d, T: Instance> { #[allow(unused)] - adc: crate::PeripheralRef<'d, T>, + adc: crate::Peri<'d, T>, #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))] sample_time: SampleTime, } @@ -111,7 +112,7 @@ pub(crate) fn blocking_delay_us(us: u32) { adc_c0 )))] #[allow(private_bounds)] -pub trait Instance: SealedInstance + crate::Peripheral

{ +pub trait Instance: SealedInstance + crate::PeripheralType { type Interrupt: crate::interrupt::typelevel::Interrupt; } /// ADC instance. @@ -132,7 +133,7 @@ pub trait Instance: SealedInstance + crate::Peripheral

{ adc_c0 ))] #[allow(private_bounds)] -pub trait Instance: SealedInstance + crate::Peripheral

+ crate::rcc::RccPeripheral { +pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral { type Interrupt: crate::interrupt::typelevel::Interrupt; } @@ -159,7 +160,7 @@ pub struct AnyAdcChannel { channel: u8, _phantom: PhantomData, } - +impl_peripheral!(AnyAdcChannel); impl AdcChannel for AnyAdcChannel {} impl SealedAdcChannel for AnyAdcChannel { fn channel(&self) -> u8 { @@ -233,11 +234,11 @@ foreach_adc!( macro_rules! impl_adc_pin { ($inst:ident, $pin:ident, $ch:expr) => { - impl crate::adc::AdcChannel for crate::peripherals::$pin {} - impl crate::adc::SealedAdcChannel for crate::peripherals::$pin { + impl crate::adc::AdcChannel for crate::Peri<'_, crate::peripherals::$pin> {} + impl crate::adc::SealedAdcChannel for crate::Peri<'_, crate::peripherals::$pin> { #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] fn setup(&mut self) { - ::set_as_analog(self); + ::set_as_analog(self); } fn channel(&self) -> u8 { diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs index f3d1ca0ab..fabf0284b 100644 --- a/embassy-stm32/src/adc/ringbuffered_v2.rs +++ b/embassy-stm32/src/adc/ringbuffered_v2.rs @@ -2,13 +2,12 @@ use core::marker::PhantomData; use core::mem; use core::sync::atomic::{compiler_fence, Ordering}; -use embassy_hal_internal::{into_ref, Peripheral}; use stm32_metapac::adc::vals::SampleTime; use crate::adc::{Adc, AdcChannel, Instance, RxDma}; use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; use crate::pac::adc::vals; -use crate::rcc; +use crate::{rcc, Peri}; #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OverrunError; @@ -103,13 +102,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// It is critical to call `read` frequently to prevent DMA buffer overrun. /// /// [`read`]: #method.read - pub fn into_ring_buffered( - self, - dma: impl Peripheral

> + 'd, - dma_buf: &'d mut [u16], - ) -> RingBufferedAdc<'d, T> { + pub fn into_ring_buffered(self, dma: Peri<'d, impl RxDma>, dma_buf: &'d mut [u16]) -> RingBufferedAdc<'d, T> { assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); - into_ref!(dma); let opts: crate::dma::TransferOptions = TransferOptions { half_transfer_ir: true, diff --git a/embassy-stm32/src/adc/u5_adc4.rs b/embassy-stm32/src/adc/u5_adc4.rs index cec88d482..a5cfbfdcf 100644 --- a/embassy-stm32/src/adc/u5_adc4.rs +++ b/embassy-stm32/src/adc/u5_adc4.rs @@ -6,7 +6,7 @@ use crate::dma::Transfer; pub use crate::pac::adc::regs::Adc4Chselrmod0; pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime}; use crate::time::Hertz; -use crate::{pac, rcc, Peripheral}; +use crate::{pac, rcc, Peri}; const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); @@ -169,13 +169,13 @@ pub trait SealedInstance { fn regs() -> crate::pac::adc::Adc4; } -pub trait Instance: SealedInstance + crate::Peripheral

+ crate::rcc::RccPeripheral { +pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral { type Interrupt: crate::interrupt::typelevel::Interrupt; } pub struct Adc4<'d, T: Instance> { #[allow(unused)] - adc: crate::PeripheralRef<'d, T>, + adc: crate::Peri<'d, T>, } #[derive(Debug)] @@ -186,8 +186,7 @@ pub enum Adc4Error { impl<'d, T: Instance> Adc4<'d, T> { /// Create a new ADC driver. - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - embassy_hal_internal::into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); let prescaler = Prescaler::from_ker_ck(T::frequency()); @@ -379,15 +378,15 @@ impl<'d, T: Instance> Adc4<'d, T> { /// let mut adc4 = adc4::Adc4::new(p.ADC4); /// let mut adc4_pin1 = p.PC1; /// let mut adc4_pin2 = p.PC0; - /// let mut degraded41 = adc4_pin1.degrade_adc(); - /// let mut degraded42 = adc4_pin2.degrade_adc(); + /// let mut.into()d41 = adc4_pin1.into(); + /// let mut.into()d42 = adc4_pin2.into(); /// let mut measurements = [0u16; 2]; /// // not that the channels must be in ascending order /// adc4.read( /// &mut p.GPDMA1_CH1, /// [ - /// &mut degraded42, - /// &mut degraded41, + /// &mut.into()d42, + /// &mut.into()d41, /// ] /// .into_iter(), /// &mut measurements, @@ -395,7 +394,7 @@ impl<'d, T: Instance> Adc4<'d, T> { /// ``` pub async fn read( &mut self, - rx_dma: &mut impl RxDma4, + rx_dma: Peri<'_, impl RxDma4>, sequence: impl ExactSizeIterator>, readings: &mut [u16], ) -> Result<(), Adc4Error> { diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index d5cd14661..fb6f5b7d0 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs @@ -2,7 +2,6 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::into_ref; #[cfg(adc_l0)] use stm32_metapac::adc::vals::Ckmode; @@ -10,7 +9,7 @@ use super::blocking_delay_us; use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::interrupt::typelevel::Interrupt; use crate::peripherals::ADC1; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc, Peri}; pub const VDDA_CALIB_MV: u32 = 3300; pub const VREF_INT: u32 = 1230; @@ -63,10 +62,9 @@ impl super::SealedAdcChannel for Temperature { impl<'d, T: Instance> Adc<'d, T> { pub fn new( - adc: impl Peripheral

+ 'd, + adc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(adc); rcc::enable_and_reset::(); // Delay 1μs when using HSI14 as the ADC clock. diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 842a5ee6d..e94a25b24 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -1,10 +1,8 @@ -use embassy_hal_internal::into_ref; - use super::blocking_delay_us; use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::peripherals::ADC1; use crate::time::Hertz; -use crate::{rcc, Peripheral}; +use crate::{rcc, Peri}; mod ringbuffered_v2; pub use ringbuffered_v2::{RingBufferedAdc, Sequence}; @@ -97,8 +95,7 @@ impl<'d, T> Adc<'d, T> where T: Instance, { - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); let presc = Prescaler::from_pclk2(T::frequency()); diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 7a608a44e..2de12d1d6 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -1,12 +1,11 @@ use cfg_if::cfg_if; -use embassy_hal_internal::into_ref; use pac::adc::vals::Dmacfg; use super::{ blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, }; use crate::dma::Transfer; -use crate::{pac, rcc, Peripheral}; +use crate::{pac, rcc, Peri}; /// Default VREF voltage used for sample conversion to millivolts. pub const VREF_DEFAULT_MV: u32 = 3300; @@ -95,8 +94,7 @@ cfg_if! { } impl<'d, T: Instance> Adc<'d, T> { - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); T::regs().cr().modify(|reg| { #[cfg(not(any(adc_g0, adc_u0)))] @@ -288,7 +286,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// ``` pub async fn read( &mut self, - rx_dma: &mut impl RxDma, + rx_dma: Peri<'_, impl RxDma>, sequence: impl ExactSizeIterator, SampleTime)>, readings: &mut [u16], ) { diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 9860efa8a..5910eef30 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -9,7 +9,7 @@ use super::{ }; use crate::dma::Transfer; use crate::time::Hertz; -use crate::{pac, rcc, Peripheral}; +use crate::{pac, rcc, Peri}; /// Default VREF voltage used for sample conversion to millivolts. pub const VREF_DEFAULT_MV: u32 = 3300; @@ -158,8 +158,7 @@ pub enum Averaging { impl<'d, T: Instance> Adc<'d, T> { /// Create a new ADC driver. - pub fn new(adc: impl Peripheral

+ 'd) -> Self { - embassy_hal_internal::into_ref!(adc); + pub fn new(adc: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); let prescaler = Prescaler::from_ker_ck(T::frequency()); @@ -344,8 +343,8 @@ impl<'d, T: Instance> Adc<'d, T> { /// use embassy_stm32::adc::{Adc, AdcChannel} /// /// let mut adc = Adc::new(p.ADC1); - /// let mut adc_pin0 = p.PA0.degrade_adc(); - /// let mut adc_pin2 = p.PA2.degrade_adc(); + /// let mut adc_pin0 = p.PA0.into(); + /// let mut adc_pin2 = p.PA2.into(); /// let mut measurements = [0u16; 2]; /// /// adc.read_async( @@ -362,7 +361,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// ``` pub async fn read( &mut self, - rx_dma: &mut impl RxDma, + rx_dma: Peri<'_, impl RxDma>, sequence: impl ExactSizeIterator, SampleTime)>, readings: &mut [u16], ) { diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs index c0b3c730b..305666d5b 100644 --- a/embassy-stm32/src/can/bxcan/mod.rs +++ b/embassy-stm32/src/can/bxcan/mod.rs @@ -6,7 +6,7 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_hal_internal::interrupt::InterruptExt; -use embassy_hal_internal::into_ref; +use embassy_hal_internal::PeripheralType; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; use embassy_sync::waitqueue::AtomicWaker; @@ -21,7 +21,7 @@ use crate::can::enums::{BusError, InternalOperation, TryReadError}; use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; -use crate::{interrupt, peripherals, Peripheral}; +use crate::{interrupt, peripherals, Peri}; /// Interrupt handler. pub struct TxInterruptHandler { @@ -173,16 +173,15 @@ impl<'d> Can<'d> { /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. /// You must call [Can::enable_non_blocking] to use the peripheral. pub fn new( - _peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + _peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, _irqs: impl interrupt::typelevel::Binding> + interrupt::typelevel::Binding> + interrupt::typelevel::Binding> + interrupt::typelevel::Binding> + 'd, ) -> Self { - into_ref!(_peri, rx, tx); let info = T::info(); let regs = &T::info().regs; @@ -1083,7 +1082,7 @@ trait SealedInstance { /// CAN instance trait. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral + 'static { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static { /// TX interrupt for this instance. type TXInterrupt: crate::interrupt::typelevel::Interrupt; /// RX0 interrupt for this instance. diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index f950b6f99..5467a40f1 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use core::task::Poll; use embassy_hal_internal::interrupt::InterruptExt; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; use embassy_sync::waitqueue::AtomicWaker; @@ -13,7 +13,7 @@ use crate::can::fd::peripheral::Registers; use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; -use crate::{interrupt, peripherals, Peripheral}; +use crate::{interrupt, peripherals, Peri}; pub(crate) mod fd; @@ -175,15 +175,13 @@ impl<'d> CanConfigurator<'d> { /// Creates a new Fdcan instance, keeping the peripheral in sleep mode. /// You must call [Fdcan::enable_non_blocking] to use the peripheral. pub fn new( - _peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + _peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, _irqs: impl interrupt::typelevel::Binding> + interrupt::typelevel::Binding> + 'd, ) -> CanConfigurator<'d> { - into_ref!(_peri, rx, tx); - rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); @@ -957,7 +955,7 @@ trait SealedInstance { /// Instance trait #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static { /// Interrupt 0 type IT0Interrupt: crate::interrupt::typelevel::Interrupt; /// Interrupt 1 @@ -965,7 +963,7 @@ pub trait Instance: SealedInstance + RccPeripheral + 'static { } /// Fdcan Instance struct -pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); +pub struct FdcanInstance<'a, T: Instance>(Peri<'a, T>); macro_rules! impl_fdcan { ($inst:ident, diff --git a/embassy-stm32/src/cordic/mod.rs b/embassy-stm32/src/cordic/mod.rs index fb342d2e7..320774857 100644 --- a/embassy-stm32/src/cordic/mod.rs +++ b/embassy-stm32/src/cordic/mod.rs @@ -1,7 +1,7 @@ //! coordinate rotation digital computer (CORDIC) use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use crate::pac::cordic::vals; use crate::{dma, peripherals, rcc}; @@ -16,7 +16,7 @@ pub mod utils; /// CORDIC driver pub struct Cordic<'d, T: Instance> { - peri: PeripheralRef<'d, T>, + peri: Peri<'d, T>, config: Config, } @@ -137,7 +137,7 @@ trait SealedInstance { /// CORDIC instance trait #[allow(private_bounds)] -pub trait Instance: SealedInstance + Peripheral

+ crate::rcc::RccPeripheral {} +pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral {} /// CORDIC configuration #[derive(Debug)] @@ -198,11 +198,9 @@ impl<'d, T: Instance> Cordic<'d, T> { /// Note: /// If you need a peripheral -> CORDIC -> peripheral mode, /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config] - pub fn new(peri: impl Peripheral

+ 'd, config: Config) -> Self { + pub fn new(peri: Peri<'d, T>, config: Config) -> Self { rcc::enable_and_reset::(); - into_ref!(peri); - let mut instance = Self { peri, config }; instance.reconfigure(); @@ -378,8 +376,8 @@ impl<'d, T: Instance> Cordic<'d, T> { /// If you want to make sure ARG2 is set to +1, consider run [.reconfigure()](Self::reconfigure). pub async fn async_calc_32bit( &mut self, - write_dma: impl Peripheral

>, - read_dma: impl Peripheral

>, + mut write_dma: Peri<'_, impl WriteDma>, + mut read_dma: Peri<'_, impl ReadDma>, arg: &[u32], res: &mut [u32], arg1_only: bool, @@ -393,8 +391,6 @@ impl<'d, T: Instance> Cordic<'d, T> { let active_res_buf = &mut res[..res_cnt]; - into_ref!(write_dma, read_dma); - self.peri .set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two }); @@ -416,7 +412,7 @@ impl<'d, T: Instance> Cordic<'d, T> { unsafe { let write_transfer = dma::Transfer::new_write( - &mut write_dma, + write_dma.reborrow(), write_req, arg, T::regs().wdata().as_ptr() as *mut _, @@ -424,7 +420,7 @@ impl<'d, T: Instance> Cordic<'d, T> { ); let read_transfer = dma::Transfer::new_read( - &mut read_dma, + read_dma.reborrow(), read_req, T::regs().rdata().as_ptr() as *mut _, active_res_buf, @@ -519,8 +515,8 @@ impl<'d, T: Instance> Cordic<'d, T> { /// User will take respond to merge two u16 arguments into one u32 data, and/or split one u32 data into two u16 results. pub async fn async_calc_16bit( &mut self, - write_dma: impl Peripheral

>, - read_dma: impl Peripheral

>, + mut write_dma: Peri<'_, impl WriteDma>, + mut read_dma: Peri<'_, impl ReadDma>, arg: &[u32], res: &mut [u32], ) -> Result { @@ -536,8 +532,6 @@ impl<'d, T: Instance> Cordic<'d, T> { let active_res_buf = &mut res[..res_cnt]; - into_ref!(write_dma, read_dma); - // In q1.15 mode, 1 write/read to access 2 arguments/results self.peri.set_argument_count(AccessCount::One); self.peri.set_result_count(AccessCount::One); @@ -557,7 +551,7 @@ impl<'d, T: Instance> Cordic<'d, T> { unsafe { let write_transfer = dma::Transfer::new_write( - &mut write_dma, + write_dma.reborrow(), write_req, arg, T::regs().wdata().as_ptr() as *mut _, @@ -565,7 +559,7 @@ impl<'d, T: Instance> Cordic<'d, T> { ); let read_transfer = dma::Transfer::new_read( - &mut read_dma, + read_dma.reborrow(), read_req, T::regs().rdata().as_ptr() as *mut _, active_res_buf, diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index f3d13de7c..a78b3c2b7 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -1,23 +1,18 @@ -use embassy_hal_internal::{into_ref, PeripheralRef}; - use crate::pac::CRC as PAC_CRC; use crate::peripherals::CRC; -use crate::{rcc, Peripheral}; +use crate::{rcc, Peri}; /// CRC driver. pub struct Crc<'d> { - _peri: PeripheralRef<'d, CRC>, + _peri: Peri<'d, CRC>, } impl<'d> Crc<'d> { /// Instantiates the CRC32 peripheral and initializes it to default values. - pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { - into_ref!(peripheral); - + pub fn new(peripheral: Peri<'d, CRC>) -> Self { // Note: enable and reset come from RccPeripheral. // enable CRC clock in RCC. rcc::enable_and_reset::(); - // Peripheral the peripheral let mut instance = Self { _peri: peripheral }; instance.reset(); instance diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index ecb507ff4..c94c9f380 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs @@ -1,13 +1,11 @@ -use embassy_hal_internal::{into_ref, PeripheralRef}; - use crate::pac::crc::vals; use crate::pac::CRC as PAC_CRC; use crate::peripherals::CRC; -use crate::{rcc, Peripheral}; +use crate::{rcc, Peri}; /// CRC driver. pub struct Crc<'d> { - _peripheral: PeripheralRef<'d, CRC>, + _peripheral: Peri<'d, CRC>, _config: Config, } @@ -80,11 +78,10 @@ pub enum PolySize { impl<'d> Crc<'d> { /// Instantiates the CRC32 peripheral and initializes it to default values. - pub fn new(peripheral: impl Peripheral

+ 'd, config: Config) -> Self { + pub fn new(peripheral: Peri<'d, CRC>, config: Config) -> Self { // Note: enable and reset come from RccPeripheral. // reset to default values and enable CRC clock in RCC. rcc::enable_and_reset::(); - into_ref!(peripheral); let mut instance = Self { _peripheral: peripheral, _config: config, diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs index 54d2c30e5..fba3c0fd7 100644 --- a/embassy-stm32/src/cryp/mod.rs +++ b/embassy-stm32/src/cryp/mod.rs @@ -4,13 +4,13 @@ use core::cmp::min; use core::marker::PhantomData; use core::ptr; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::dma::{ChannelAndRequest, TransferOptions}; use crate::interrupt::typelevel::Interrupt; use crate::mode::{Async, Blocking, Mode}; -use crate::{interrupt, pac, peripherals, rcc, Peripheral}; +use crate::{interrupt, pac, peripherals, rcc}; const DES_BLOCK_SIZE: usize = 8; // 64 bits const AES_BLOCK_SIZE: usize = 16; // 128 bits @@ -988,7 +988,7 @@ pub enum Direction { /// Crypto Accelerator Driver pub struct Cryp<'d, T: Instance, M: Mode> { - _peripheral: PeripheralRef<'d, T>, + _peripheral: Peri<'d, T>, _phantom: PhantomData, indma: Option>, outdma: Option>, @@ -997,11 +997,10 @@ pub struct Cryp<'d, T: Instance, M: Mode> { impl<'d, T: Instance> Cryp<'d, T, Blocking> { /// Create a new CRYP driver in blocking mode. pub fn new_blocking( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peri); let instance = Self { _peripheral: peri, _phantom: PhantomData, @@ -1461,13 +1460,12 @@ impl<'d, T: Instance, M: Mode> Cryp<'d, T, M> { impl<'d, T: Instance> Cryp<'d, T, Async> { /// Create a new CRYP driver. pub fn new( - peri: impl Peripheral

+ 'd, - indma: impl Peripheral

> + 'd, - outdma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + indma: Peri<'d, impl DmaIn>, + outdma: Peri<'d, impl DmaOut>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peri, indma, outdma); let instance = Self { _peripheral: peri, _phantom: PhantomData, @@ -1879,7 +1877,7 @@ trait SealedInstance { /// CRYP instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + Peripheral

+ crate::rcc::RccPeripheral + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send { /// Interrupt for this CRYP instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 7a63dc5fc..30046849b 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -3,16 +3,15 @@ use core::marker::PhantomData; -use embassy_hal_internal::into_ref; - use crate::dma::ChannelAndRequest; use crate::mode::{Async, Blocking, Mode as PeriMode}; #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] use crate::pac::dac; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; mod tsel; +use embassy_hal_internal::PeripheralType; pub use tsel::TriggerSel; /// Operating mode for DAC channel @@ -121,12 +120,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> { /// /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. - pub fn new( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

> + 'd, - pin: impl Peripheral

> + 'd, - ) -> Self { - into_ref!(dma, pin); + pub fn new(peri: Peri<'d, T>, dma: Peri<'d, impl Dma>, pin: Peri<'d, impl DacPin>) -> Self { pin.set_as_analog(); Self::new_inner( peri, @@ -147,8 +141,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> { /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] - pub fn new_internal(peri: impl Peripheral

+ 'd, dma: impl Peripheral

> + 'd) -> Self { - into_ref!(dma); + pub fn new_internal(peri: Peri<'d, T>, dma: Peri<'d, impl Dma>) -> Self { Self::new_inner(peri, new_dma!(dma), Mode::NormalInternalUnbuffered) } @@ -204,8 +197,7 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> { /// /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. - pub fn new_blocking(peri: impl Peripheral

+ 'd, pin: impl Peripheral

> + 'd) -> Self { - into_ref!(pin); + pub fn new_blocking(peri: Peri<'d, T>, pin: Peri<'d, impl DacPin>) -> Self { pin.set_as_analog(); Self::new_inner( peri, @@ -226,14 +218,14 @@ impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> { /// By default, triggering is disabled, but it can be enabled using /// [`DacChannel::set_trigger()`]. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] - pub fn new_internal_blocking(peri: impl Peripheral

+ 'd) -> Self { + pub fn new_internal_blocking(peri: Peri<'d, T>) -> Self { Self::new_inner(peri, None, Mode::NormalInternalUnbuffered) } } impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, dma: Option>, #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, ) -> Self { @@ -395,13 +387,12 @@ impl<'d, T: Instance> Dac<'d, T, Async> { /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// method on the underlying channels. pub fn new( - peri: impl Peripheral

+ 'd, - dma_ch1: impl Peripheral

> + 'd, - dma_ch2: impl Peripheral

> + 'd, - pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, - pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, + peri: Peri<'d, T>, + dma_ch1: Peri<'d, impl Dma>, + dma_ch2: Peri<'d, impl Dma>, + pin_ch1: Peri<'d, impl DacPin + crate::gpio::Pin>, + pin_ch2: Peri<'d, impl DacPin + crate::gpio::Pin>, ) -> Self { - into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); Self::new_inner( @@ -429,11 +420,10 @@ impl<'d, T: Instance> Dac<'d, T, Async> { /// method on the underlying channels. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] pub fn new_internal( - peri: impl Peripheral

+ 'd, - dma_ch1: impl Peripheral

> + 'd, - dma_ch2: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + dma_ch1: Peri<'d, impl Dma>, + dma_ch2: Peri<'d, impl Dma>, ) -> Self { - into_ref!(dma_ch1, dma_ch2); Self::new_inner( peri, new_dma!(dma_ch1), @@ -457,11 +447,10 @@ impl<'d, T: Instance> Dac<'d, T, Blocking> { /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// method on the underlying channels. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - pin_ch1: impl Peripheral

+ crate::gpio::Pin> + 'd, - pin_ch2: impl Peripheral

+ crate::gpio::Pin> + 'd, + peri: Peri<'d, T>, + pin_ch1: Peri<'d, impl DacPin + crate::gpio::Pin>, + pin_ch2: Peri<'d, impl DacPin + crate::gpio::Pin>, ) -> Self { - into_ref!(pin_ch1, pin_ch2); pin_ch1.set_as_analog(); pin_ch2.set_as_analog(); Self::new_inner( @@ -488,14 +477,14 @@ impl<'d, T: Instance> Dac<'d, T, Blocking> { /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` /// method on the underlying channels. #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] - pub fn new_internal(peri: impl Peripheral

+ 'd) -> Self { + pub fn new_internal(peri: Peri<'d, T>) -> Self { Self::new_inner(peri, None, None, Mode::NormalInternalUnbuffered) } } impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, dma_ch1: Option>, dma_ch2: Option>, #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode, @@ -572,7 +561,7 @@ trait SealedInstance { /// DAC instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {} /// Channel 1 marker type. pub enum Ch1 {} diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index 4ba4e824e..d05faee21 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -3,13 +3,13 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use crate::dma::Transfer; use crate::gpio::{AfType, Pull}; use crate::interrupt::typelevel::Interrupt; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc, Peri}; /// Interrupt handler. pub struct InterruptHandler { @@ -106,8 +106,7 @@ impl Default for Config { macro_rules! config_pins { ($($pin:ident),*) => { - into_ref!($($pin),*); - critical_section::with(|_| { + critical_section::with(|_| { $( $pin.set_as_af($pin.af_num(), AfType::input(Pull::None)); )* @@ -117,8 +116,8 @@ macro_rules! config_pins { /// DCMI driver. pub struct Dcmi<'d, T: Instance, Dma: FrameDma> { - inner: PeripheralRef<'d, T>, - dma: PeripheralRef<'d, Dma>, + inner: Peri<'d, T>, + dma: Peri<'d, Dma>, } impl<'d, T, Dma> Dcmi<'d, T, Dma> @@ -128,23 +127,22 @@ where { /// Create a new DCMI driver with 8 data bits. pub fn new_8bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - v_sync: impl Peripheral

> + 'd, - h_sync: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + v_sync: Peri<'d, impl VSyncPin>, + h_sync: Peri<'d, impl HSyncPin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(v_sync, h_sync, pixclk); @@ -153,25 +151,24 @@ where /// Create a new DCMI driver with 10 data bits. pub fn new_10bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - v_sync: impl Peripheral

> + 'd, - h_sync: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + v_sync: Peri<'d, impl VSyncPin>, + h_sync: Peri<'d, impl HSyncPin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(v_sync, h_sync, pixclk); @@ -180,27 +177,26 @@ where /// Create a new DCMI driver with 12 data bits. pub fn new_12bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - d10: impl Peripheral

> + 'd, - d11: impl Peripheral

> + 'd, - v_sync: impl Peripheral

> + 'd, - h_sync: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + d10: Peri<'d, impl D10Pin>, + d11: Peri<'d, impl D11Pin>, + v_sync: Peri<'d, impl VSyncPin>, + h_sync: Peri<'d, impl HSyncPin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); config_pins!(v_sync, h_sync, pixclk); @@ -209,29 +205,28 @@ where /// Create a new DCMI driver with 14 data bits. pub fn new_14bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - d10: impl Peripheral

> + 'd, - d11: impl Peripheral

> + 'd, - d12: impl Peripheral

> + 'd, - d13: impl Peripheral

> + 'd, - v_sync: impl Peripheral

> + 'd, - h_sync: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + d10: Peri<'d, impl D10Pin>, + d11: Peri<'d, impl D11Pin>, + d12: Peri<'d, impl D12Pin>, + d13: Peri<'d, impl D13Pin>, + v_sync: Peri<'d, impl VSyncPin>, + h_sync: Peri<'d, impl HSyncPin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); config_pins!(v_sync, h_sync, pixclk); @@ -240,21 +235,20 @@ where /// Create a new DCMI driver with 8 data bits, with embedded synchronization. pub fn new_es_8bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); config_pins!(pixclk); @@ -263,23 +257,22 @@ where /// Create a new DCMI driver with 10 data bits, with embedded synchronization. pub fn new_es_10bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); config_pins!(pixclk); @@ -288,25 +281,24 @@ where /// Create a new DCMI driver with 12 data bits, with embedded synchronization. pub fn new_es_12bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - d10: impl Peripheral

> + 'd, - d11: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + d10: Peri<'d, impl D10Pin>, + d11: Peri<'d, impl D11Pin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); config_pins!(pixclk); @@ -315,27 +307,26 @@ where /// Create a new DCMI driver with 14 data bits, with embedded synchronization. pub fn new_es_14bit( - peri: impl Peripheral

+ 'd, - dma: impl Peripheral

+ 'd, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - d8: impl Peripheral

> + 'd, - d9: impl Peripheral

> + 'd, - d10: impl Peripheral

> + 'd, - d11: impl Peripheral

> + 'd, - d12: impl Peripheral

> + 'd, - d13: impl Peripheral

> + 'd, - pixclk: impl Peripheral

> + 'd, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + d8: Peri<'d, impl D8Pin>, + d9: Peri<'d, impl D9Pin>, + d10: Peri<'d, impl D10Pin>, + d11: Peri<'d, impl D11Pin>, + d12: Peri<'d, impl D12Pin>, + d13: Peri<'d, impl D13Pin>, + pixclk: Peri<'d, impl PixClkPin>, config: Config, ) -> Self { - into_ref!(peri, dma); config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); config_pins!(pixclk); @@ -343,8 +334,8 @@ where } fn new_inner( - peri: PeripheralRef<'d, T>, - dma: PeripheralRef<'d, Dma>, + peri: Peri<'d, T>, + dma: Peri<'d, Dma>, config: Config, use_embedded_synchronization: bool, edm: u8, @@ -396,7 +387,7 @@ where let r = self.inner.regs(); let src = r.dr().as_ptr() as *mut u32; let request = self.dma.request(); - let dma_read = unsafe { Transfer::new_read(&mut self.dma, request, src, buffer, Default::default()) }; + let dma_read = unsafe { Transfer::new_read(self.dma.reborrow(), request, src, buffer, Default::default()) }; Self::clear_interrupt_flags(); Self::enable_irqs(); @@ -435,7 +426,7 @@ trait SealedInstance: crate::rcc::RccPeripheral { /// DCMI instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static { +pub trait Instance: SealedInstance + PeripheralType + 'static { /// Interrupt for this instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs index d31f4d01a..7dbbe7b72 100644 --- a/embassy-stm32/src/dma/dma_bdma.rs +++ b/embassy-stm32/src/dma/dma_bdma.rs @@ -3,7 +3,7 @@ use core::pin::Pin; use core::sync::atomic::{fence, AtomicUsize, Ordering}; use core::task::{Context, Poll, Waker}; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_sync::waitqueue::AtomicWaker; use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; @@ -571,13 +571,13 @@ impl AnyChannel { /// DMA transfer. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Transfer<'a> { - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, } impl<'a> Transfer<'a> { /// Create a new read DMA transfer (peripheral to memory). pub unsafe fn new_read( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, peri_addr: *mut W, buf: &'a mut [W], @@ -588,16 +588,14 @@ impl<'a> Transfer<'a> { /// Create a new read DMA transfer (peripheral to memory), using raw pointers. pub unsafe fn new_read_raw( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, peri_addr: *mut W, buf: *mut [W], options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::PeripheralToMemory, peri_addr as *const u32, @@ -612,7 +610,7 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral). pub unsafe fn new_write( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, buf: &'a [MW], peri_addr: *mut PW, @@ -623,16 +621,14 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral), using raw pointers. pub unsafe fn new_write_raw( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, buf: *const [MW], peri_addr: *mut PW, options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::MemoryToPeripheral, peri_addr as *const u32, @@ -647,17 +643,15 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. pub unsafe fn new_write_repeated( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, repeated: &'a W, count: usize, peri_addr: *mut W, options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::MemoryToPeripheral, peri_addr as *const u32, @@ -671,7 +665,7 @@ impl<'a> Transfer<'a> { } unsafe fn new_inner( - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, _request: Request, dir: Dir, peri_addr: *const u32, @@ -769,7 +763,7 @@ impl<'a> Future for Transfer<'a> { // ============================== -struct DmaCtrlImpl<'a>(PeripheralRef<'a, AnyChannel>); +struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); impl<'a> DmaCtrl for DmaCtrlImpl<'a> { fn get_remaining_transfers(&self) -> usize { @@ -795,21 +789,20 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> { /// Ringbuffer for receiving data using DMA circular mode. pub struct ReadableRingBuffer<'a, W: Word> { - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, ringbuf: ReadableDmaRingBuffer<'a, W>, } impl<'a, W: Word> ReadableRingBuffer<'a, W> { /// Create a new ring buffer. pub unsafe fn new( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, _request: Request, peri_addr: *mut W, buffer: &'a mut [W], mut options: TransferOptions, ) -> Self { - into_ref!(channel); - let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); + let channel: Peri<'a, AnyChannel> = channel.into(); let buffer_ptr = buffer.as_mut_ptr(); let len = buffer.len(); @@ -948,21 +941,20 @@ impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> { /// Ringbuffer for writing data using DMA circular mode. pub struct WritableRingBuffer<'a, W: Word> { - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, ringbuf: WritableDmaRingBuffer<'a, W>, } impl<'a, W: Word> WritableRingBuffer<'a, W> { /// Create a new ring buffer. pub unsafe fn new( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, _request: Request, peri_addr: *mut W, buffer: &'a mut [W], mut options: TransferOptions, ) -> Self { - into_ref!(channel); - let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); + let channel: Peri<'a, AnyChannel> = channel.into(); let len = buffer.len(); let dir = Dir::MemoryToPeripheral; diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 799b8b355..ade70fb55 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -5,7 +5,7 @@ use core::pin::Pin; use core::sync::atomic::{fence, Ordering}; use core::task::{Context, Poll}; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_sync::waitqueue::AtomicWaker; use super::word::{Word, WordSize}; @@ -109,13 +109,13 @@ impl AnyChannel { /// DMA transfer. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Transfer<'a> { - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, } impl<'a> Transfer<'a> { /// Create a new read DMA transfer (peripheral to memory). pub unsafe fn new_read( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, peri_addr: *mut W, buf: &'a mut [W], @@ -126,16 +126,14 @@ impl<'a> Transfer<'a> { /// Create a new read DMA transfer (peripheral to memory), using raw pointers. pub unsafe fn new_read_raw( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, peri_addr: *mut W, buf: *mut [W], options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::PeripheralToMemory, peri_addr as *const u32, @@ -150,7 +148,7 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral). pub unsafe fn new_write( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, buf: &'a [MW], peri_addr: *mut PW, @@ -161,16 +159,14 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral), using raw pointers. pub unsafe fn new_write_raw( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, buf: *const [MW], peri_addr: *mut PW, options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::MemoryToPeripheral, peri_addr as *const u32, @@ -185,17 +181,15 @@ impl<'a> Transfer<'a> { /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. pub unsafe fn new_write_repeated( - channel: impl Peripheral

+ 'a, + channel: Peri<'a, impl Channel>, request: Request, repeated: &'a MW, count: usize, peri_addr: *mut PW, options: TransferOptions, ) -> Self { - into_ref!(channel); - Self::new_inner( - channel.map_into(), + channel.into(), request, Dir::MemoryToPeripheral, peri_addr as *const u32, @@ -209,7 +203,7 @@ impl<'a> Transfer<'a> { } unsafe fn new_inner( - channel: PeripheralRef<'a, AnyChannel>, + channel: Peri<'a, AnyChannel>, request: Request, dir: Dir, peri_addr: *const u32, diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index ac4a0f98e..d3b070a6d 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -22,7 +22,7 @@ pub(crate) use util::*; pub(crate) mod ringbuffer; pub mod word; -use embassy_hal_internal::{impl_peripheral, Peripheral}; +use embassy_hal_internal::{impl_peripheral, PeripheralType}; use crate::interrupt; @@ -51,17 +51,7 @@ pub(crate) trait ChannelInterrupt { /// DMA channel. #[allow(private_bounds)] -pub trait Channel: SealedChannel + Peripheral

+ Into + 'static { - /// Type-erase (degrade) this pin into an `AnyChannel`. - /// - /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which - /// are all different types, into the same type. It is useful for - /// creating arrays of channels, or avoiding generics. - #[inline] - fn degrade(self) -> AnyChannel { - AnyChannel { id: self.id() } - } -} +pub trait Channel: SealedChannel + PeripheralType + Into + 'static {} macro_rules! dma_channel_impl { ($channel_peri:ident, $index:expr) => { @@ -79,8 +69,10 @@ macro_rules! dma_channel_impl { impl crate::dma::Channel for crate::peripherals::$channel_peri {} impl From for crate::dma::AnyChannel { - fn from(x: crate::peripherals::$channel_peri) -> Self { - crate::dma::Channel::degrade(x) + fn from(val: crate::peripherals::$channel_peri) -> Self { + Self { + id: crate::dma::SealedChannel::id(&val), + } } } }; diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs index 5e1158182..8bf89e2fe 100644 --- a/embassy-stm32/src/dma/util.rs +++ b/embassy-stm32/src/dma/util.rs @@ -1,13 +1,12 @@ -use embassy_hal_internal::PeripheralRef; - use super::word::Word; use super::{AnyChannel, Request, Transfer, TransferOptions}; +use crate::Peri; /// Convenience wrapper, contains a channel and a request number. /// /// Commonly used in peripheral drivers that own DMA channels. pub(crate) struct ChannelAndRequest<'d> { - pub channel: PeripheralRef<'d, AnyChannel>, + pub channel: Peri<'d, AnyChannel>, pub request: Request, } @@ -18,7 +17,7 @@ impl<'d> ChannelAndRequest<'d> { buf: &'a mut [W], options: TransferOptions, ) -> Transfer<'a> { - Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options) + Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) } pub unsafe fn read_raw<'a, W: Word>( @@ -27,7 +26,7 @@ impl<'d> ChannelAndRequest<'d> { buf: *mut [W], options: TransferOptions, ) -> Transfer<'a> { - Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options) + Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) } pub unsafe fn write<'a, W: Word>( @@ -36,7 +35,7 @@ impl<'d> ChannelAndRequest<'d> { peri_addr: *mut W, options: TransferOptions, ) -> Transfer<'a> { - Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options) + Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options) } pub unsafe fn write_raw<'a, MW: Word, PW: Word>( @@ -45,7 +44,7 @@ impl<'d> ChannelAndRequest<'d> { peri_addr: *mut PW, options: TransferOptions, ) -> Transfer<'a> { - Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options) + Transfer::new_write_raw(self.channel.reborrow(), self.request, buf, peri_addr, options) } #[allow(dead_code)] @@ -56,6 +55,13 @@ impl<'d> ChannelAndRequest<'d> { peri_addr: *mut W, options: TransferOptions, ) -> Transfer<'a> { - Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options) + Transfer::new_write_repeated( + self.channel.reborrow(), + self.request, + repeated, + count, + peri_addr, + options, + ) } } diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs index 77c3d95c3..e97ccd9d0 100644 --- a/embassy-stm32/src/dsihost.rs +++ b/embassy-stm32/src/dsihost.rs @@ -2,12 +2,12 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; //use crate::gpio::{AnyPin, SealedPin}; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; /// Performs a busy-wait delay for a specified number of microseconds. pub fn blocking_delay_ms(ms: u32) { @@ -69,14 +69,12 @@ impl From for u8 { /// DSIHOST driver. pub struct DsiHost<'d, T: Instance> { _peri: PhantomData<&'d mut T>, - _te: PeripheralRef<'d, AnyPin>, + _te: Peri<'d, AnyPin>, } impl<'d, T: Instance> DsiHost<'d, T> { /// Note: Full-Duplex modes are not supported at this time - pub fn new(_peri: impl Peripheral

+ 'd, te: impl Peripheral

> + 'd) -> Self { - into_ref!(te); - + pub fn new(_peri: Peri<'d, T>, te: Peri<'d, impl TePin>) -> Self { rcc::enable_and_reset::(); // Set Tearing Enable pin according to CubeMx example @@ -88,7 +86,7 @@ impl<'d, T: Instance> DsiHost<'d, T> { */ Self { _peri: PhantomData, - _te: te.map_into(), + _te: te.into(), } } @@ -412,7 +410,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral { /// DSI instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {} pin_trait!(TePin, Instance); diff --git a/embassy-stm32/src/dts/mod.rs b/embassy-stm32/src/dts/mod.rs index 58d7cf841..1f39c8db5 100644 --- a/embassy-stm32/src/dts/mod.rs +++ b/embassy-stm32/src/dts/mod.rs @@ -4,13 +4,13 @@ use core::future::poll_fn; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_sync::waitqueue::AtomicWaker; use crate::interrupt::InterruptExt; use crate::peripherals::DTS; use crate::time::Hertz; -use crate::{interrupt, pac, rcc, Peripheral}; +use crate::{interrupt, pac, rcc}; mod tsel; pub use tsel::TriggerSel; @@ -72,7 +72,7 @@ const MAX_DTS_CLK_FREQ: Hertz = Hertz::mhz(1); /// Digital temperature sensor driver. pub struct Dts<'d> { - _peri: PeripheralRef<'d, DTS>, + _peri: Peri<'d, DTS>, } static WAKER: AtomicWaker = AtomicWaker::new(); @@ -80,11 +80,10 @@ static WAKER: AtomicWaker = AtomicWaker::new(); impl<'d> Dts<'d> { /// Create a new temperature sensor driver. pub fn new( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, DTS>, _irq: impl interrupt::typelevel::Binding + 'd, config: Config, ) -> Self { - into_ref!(_peri); rcc::enable_and_reset::(); let prescaler = rcc::frequency::() / MAX_DTS_CLK_FREQ; diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index 109ceeeb3..97d7b4347 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs @@ -9,6 +9,7 @@ mod generic_phy; use core::mem::MaybeUninit; use core::task::Context; +use embassy_hal_internal::PeripheralType; use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_sync::waitqueue::AtomicWaker; @@ -199,7 +200,7 @@ trait SealedInstance { /// Ethernet instance. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + Send + 'static {} impl SealedInstance for crate::peripherals::ETH { fn regs() -> crate::pac::eth::Eth { diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index e12ac2fef..640191d69 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -6,7 +6,7 @@ mod tx_desc; use core::marker::PhantomData; use core::sync::atomic::{fence, Ordering}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; pub(crate) use self::rx_desc::{RDes, RDesRing}; @@ -15,6 +15,7 @@ use super::*; #[cfg(eth_v1a)] use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; +use crate::interrupt; use crate::interrupt::InterruptExt; #[cfg(eth_v1a)] use crate::pac::AFIO; @@ -22,7 +23,6 @@ use crate::pac::AFIO; use crate::pac::SYSCFG; use crate::pac::{ETH, RCC}; use crate::rcc::SealedRccPeripheral; -use crate::{interrupt, Peripheral}; /// Interrupt handler. pub struct InterruptHandler {} @@ -47,11 +47,11 @@ impl interrupt::typelevel::Handler for InterruptHandl /// Ethernet driver. pub struct Ethernet<'d, T: Instance, P: Phy> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, pub(crate) tx: TDesRing<'d>, pub(crate) rx: RDesRing<'d>, - pins: [PeripheralRef<'d, AnyPin>; 9], + pins: [Peri<'d, AnyPin>; 9], pub(crate) phy: P, pub(crate) station_management: EthernetStationManagement, pub(crate) mac_addr: [u8; 6], @@ -95,22 +95,20 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { /// safety: the returned instance is not leak-safe pub fn new( queue: &'d mut PacketQueue, - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding + 'd, - ref_clk: impl Peripheral

> + 'd, - mdio: impl Peripheral

> + 'd, - mdc: impl Peripheral

> + 'd, - crs: impl Peripheral

> + 'd, - rx_d0: impl Peripheral

> + 'd, - rx_d1: impl Peripheral

> + 'd, - tx_d0: impl Peripheral

> + 'd, - tx_d1: impl Peripheral

> + 'd, - tx_en: impl Peripheral

> + 'd, + ref_clk: Peri<'d, impl RefClkPin>, + mdio: Peri<'d, impl MDIOPin>, + mdc: Peri<'d, impl MDCPin>, + crs: Peri<'d, impl CRSPin>, + rx_d0: Peri<'d, impl RXD0Pin>, + rx_d1: Peri<'d, impl RXD1Pin>, + tx_d0: Peri<'d, impl TXD0Pin>, + tx_d1: Peri<'d, impl TXD1Pin>, + tx_en: Peri<'d, impl TXEnPin>, phy: P, mac_addr: [u8; 6], ) -> Self { - into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); - // Enable the necessary Clocks #[cfg(eth_v1a)] critical_section::with(|_| { @@ -213,15 +211,15 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { }; let pins = [ - ref_clk.map_into(), - mdio.map_into(), - mdc.map_into(), - crs.map_into(), - rx_d0.map_into(), - rx_d1.map_into(), - tx_d0.map_into(), - tx_d1.map_into(), - tx_en.map_into(), + ref_clk.into(), + mdio.into(), + mdc.into(), + crs.into(), + rx_d0.into(), + rx_d1.into(), + tx_d0.into(), + tx_d1.into(), + tx_en.into(), ]; let mut this = Self { diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 26e4eeb63..034c5dd88 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -3,16 +3,16 @@ mod descriptors; use core::marker::PhantomData; use core::sync::atomic::{fence, Ordering}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use stm32_metapac::syscfg::vals::EthSelPhy; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; use super::*; use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; +use crate::interrupt; use crate::interrupt::InterruptExt; use crate::pac::ETH; use crate::rcc::SealedRccPeripheral; -use crate::{interrupt, Peripheral}; /// Interrupt handler. pub struct InterruptHandler {} @@ -37,7 +37,7 @@ impl interrupt::typelevel::Handler for InterruptHandl /// Ethernet driver. pub struct Ethernet<'d, T: Instance, P: Phy> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, pub(crate) tx: TDesRing<'d>, pub(crate) rx: RDesRing<'d>, pins: Pins<'d>, @@ -48,8 +48,8 @@ pub struct Ethernet<'d, T: Instance, P: Phy> { /// Pins of ethernet driver. enum Pins<'d> { - Rmii([PeripheralRef<'d, AnyPin>; 9]), - Mii([PeripheralRef<'d, AnyPin>; 14]), + Rmii([Peri<'d, AnyPin>; 9]), + Mii([Peri<'d, AnyPin>; 14]), } macro_rules! config_pins { @@ -67,17 +67,17 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { /// Create a new RMII ethernet driver using 9 pins. pub fn new( queue: &'d mut PacketQueue, - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, irq: impl interrupt::typelevel::Binding + 'd, - ref_clk: impl Peripheral

> + 'd, - mdio: impl Peripheral

> + 'd, - mdc: impl Peripheral

> + 'd, - crs: impl Peripheral

> + 'd, - rx_d0: impl Peripheral

> + 'd, - rx_d1: impl Peripheral

> + 'd, - tx_d0: impl Peripheral

> + 'd, - tx_d1: impl Peripheral

> + 'd, - tx_en: impl Peripheral

> + 'd, + ref_clk: Peri<'d, impl RefClkPin>, + mdio: Peri<'d, impl MDIOPin>, + mdc: Peri<'d, impl MDCPin>, + crs: Peri<'d, impl CRSPin>, + rx_d0: Peri<'d, impl RXD0Pin>, + rx_d1: Peri<'d, impl RXD1Pin>, + tx_d0: Peri<'d, impl TXD0Pin>, + tx_d1: Peri<'d, impl TXD1Pin>, + tx_en: Peri<'d, impl TXEnPin>, phy: P, mac_addr: [u8; 6], ) -> Self { @@ -92,19 +92,18 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII)); }); - into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); let pins = Pins::Rmii([ - ref_clk.map_into(), - mdio.map_into(), - mdc.map_into(), - crs.map_into(), - rx_d0.map_into(), - rx_d1.map_into(), - tx_d0.map_into(), - tx_d1.map_into(), - tx_en.map_into(), + ref_clk.into(), + mdio.into(), + mdc.into(), + crs.into(), + rx_d0.into(), + rx_d1.into(), + tx_d0.into(), + tx_d1.into(), + tx_en.into(), ]); Self::new_inner(queue, peri, irq, pins, phy, mac_addr) @@ -113,22 +112,22 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { /// Create a new MII ethernet driver using 14 pins. pub fn new_mii( queue: &'d mut PacketQueue, - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, irq: impl interrupt::typelevel::Binding + 'd, - rx_clk: impl Peripheral

> + 'd, - tx_clk: impl Peripheral

> + 'd, - mdio: impl Peripheral

> + 'd, - mdc: impl Peripheral

> + 'd, - rxdv: impl Peripheral

> + 'd, - rx_d0: impl Peripheral

> + 'd, - rx_d1: impl Peripheral

> + 'd, - rx_d2: impl Peripheral

> + 'd, - rx_d3: impl Peripheral

> + 'd, - tx_d0: impl Peripheral

> + 'd, - tx_d1: impl Peripheral

> + 'd, - tx_d2: impl Peripheral

> + 'd, - tx_d3: impl Peripheral

> + 'd, - tx_en: impl Peripheral

> + 'd, + rx_clk: Peri<'d, impl RXClkPin>, + tx_clk: Peri<'d, impl TXClkPin>, + mdio: Peri<'d, impl MDIOPin>, + mdc: Peri<'d, impl MDCPin>, + rxdv: Peri<'d, impl RXDVPin>, + rx_d0: Peri<'d, impl RXD0Pin>, + rx_d1: Peri<'d, impl RXD1Pin>, + rx_d2: Peri<'d, impl RXD2Pin>, + rx_d3: Peri<'d, impl RXD3Pin>, + tx_d0: Peri<'d, impl TXD0Pin>, + tx_d1: Peri<'d, impl TXD1Pin>, + tx_d2: Peri<'d, impl TXD2Pin>, + tx_d3: Peri<'d, impl TXD3Pin>, + tx_en: Peri<'d, impl TXEnPin>, phy: P, mac_addr: [u8; 6], ) -> Self { @@ -145,24 +144,23 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII)); }); - into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); let pins = Pins::Mii([ - rx_clk.map_into(), - tx_clk.map_into(), - mdio.map_into(), - mdc.map_into(), - rxdv.map_into(), - rx_d0.map_into(), - rx_d1.map_into(), - rx_d2.map_into(), - rx_d3.map_into(), - tx_d0.map_into(), - tx_d1.map_into(), - tx_d2.map_into(), - tx_d3.map_into(), - tx_en.map_into(), + rx_clk.into(), + tx_clk.into(), + mdio.into(), + mdc.into(), + rxdv.into(), + rx_d0.into(), + rx_d1.into(), + rx_d2.into(), + rx_d3.into(), + tx_d0.into(), + tx_d1.into(), + tx_d2.into(), + tx_d3.into(), + tx_en.into(), ]); Self::new_inner(queue, peri, irq, pins, phy, mac_addr) @@ -170,7 +168,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { fn new_inner( queue: &'d mut PacketQueue, - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding + 'd, pins: Pins<'d>, phy: P, @@ -254,7 +252,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { }; let mut this = Self { - _peri: peri.into_ref(), + _peri: peri, tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), pins, diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 9604c5149..9fce78f95 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -5,13 +5,13 @@ use core::marker::PhantomData; use core::pin::Pin; use core::task::{Context, Poll}; -use embassy_hal_internal::{impl_peripheral, into_ref}; +use embassy_hal_internal::{impl_peripheral, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull}; use crate::pac::exti::regs::Lines; use crate::pac::EXTI; -use crate::{interrupt, pac, peripherals, Peripheral}; +use crate::{interrupt, pac, peripherals, Peri}; const EXTI_COUNT: usize = 16; static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; @@ -105,13 +105,7 @@ impl<'d> Unpin for ExtiInput<'d> {} impl<'d> ExtiInput<'d> { /// Create an EXTI input. - pub fn new( - pin: impl Peripheral

+ 'd, - ch: impl Peripheral

+ 'd, - pull: Pull, - ) -> Self { - into_ref!(pin, ch); - + pub fn new(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull) -> Self { // Needed if using AnyPin+AnyChannel. assert_eq!(pin.pin(), ch.number()); @@ -338,23 +332,12 @@ trait SealedChannel {} /// EXTI channel trait. #[allow(private_bounds)] -pub trait Channel: SealedChannel + Sized { +pub trait Channel: PeripheralType + SealedChannel + Sized { /// Get the EXTI channel number. fn number(&self) -> u8; - - /// Type-erase (degrade) this channel into an `AnyChannel`. - /// - /// This converts EXTI channel singletons (`EXTI0`, `EXTI1`, ...), which - /// are all different types, into the same type. It is useful for - /// creating arrays of channels, or avoiding generics. - fn degrade(self) -> AnyChannel { - AnyChannel { - number: self.number() as u8, - } - } } -/// Type-erased (degraded) EXTI channel. +/// Type-erased EXTI channel. /// /// This represents ownership over any EXTI channel, known at runtime. pub struct AnyChannel { @@ -377,6 +360,14 @@ macro_rules! impl_exti { $number } } + + impl From for AnyChannel { + fn from(val: peripherals::$type) -> Self { + Self { + number: val.number() as u8, + } + } + } }; } diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs index 9468ac632..599b7bb4e 100644 --- a/embassy-stm32/src/flash/asynch.rs +++ b/embassy-stm32/src/flash/asynch.rs @@ -2,7 +2,6 @@ use core::marker::PhantomData; use core::sync::atomic::{fence, Ordering}; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::into_ref; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::Mutex; @@ -12,18 +11,16 @@ use super::{ }; use crate::interrupt::InterruptExt; use crate::peripherals::FLASH; -use crate::{interrupt, Peripheral}; +use crate::{interrupt, Peri}; pub(super) static REGION_ACCESS: Mutex = Mutex::new(()); impl<'d> Flash<'d, Async> { /// Create a new flash driver with async capabilities. pub fn new( - p: impl Peripheral

+ 'd, + p: Peri<'d, FLASH>, _irq: impl interrupt::typelevel::Binding + 'd, ) -> Self { - into_ref!(p); - crate::interrupt::FLASH.unpend(); unsafe { crate::interrupt::FLASH.enable() }; diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index 0004a7488..1376ca4b4 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs @@ -2,27 +2,24 @@ use core::marker::PhantomData; use core::sync::atomic::{fence, Ordering}; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; use super::{ family, Async, Blocking, Error, FlashBank, FlashLayout, FlashRegion, FlashSector, FLASH_SIZE, MAX_ERASE_SIZE, READ_SIZE, WRITE_SIZE, }; +use crate::Peri; use crate::_generated::FLASH_BASE; use crate::peripherals::FLASH; -use crate::Peripheral; /// Internal flash memory driver. pub struct Flash<'d, MODE = Async> { - pub(crate) inner: PeripheralRef<'d, FLASH>, + pub(crate) inner: Peri<'d, FLASH>, pub(crate) _mode: PhantomData, } impl<'d> Flash<'d, Blocking> { /// Create a new flash driver, usable in blocking mode. - pub fn new_blocking(p: impl Peripheral

+ 'd) -> Self { - into_ref!(p); - + pub fn new_blocking(p: Peri<'d, FLASH>) -> Self { Self { inner: p, _mode: PhantomData, diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 86afdce8a..687eabaeb 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -13,8 +13,7 @@ use crate::pac; mod alt_regions { use core::marker::PhantomData; - use embassy_hal_internal::PeripheralRef; - + use crate::Peri; use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; use crate::_generated::FLASH_SIZE; use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion}; @@ -50,10 +49,10 @@ mod alt_regions { &ALT_BANK2_REGION3, ]; - pub struct AltBank1Region3<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData); - pub struct AltBank2Region1<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData); - pub struct AltBank2Region2<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData); - pub struct AltBank2Region3<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData); + pub struct AltBank1Region3<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData); + pub struct AltBank2Region1<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData); + pub struct AltBank2Region2<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData); + pub struct AltBank2Region3<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData); pub struct AltFlashLayout<'d, MODE = Async> { pub bank1_region1: Bank1Region1<'d, MODE>, diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 83b49a3dd..71ca775cb 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs @@ -1,10 +1,10 @@ //! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC) use core::marker::PhantomData; -use embassy_hal_internal::into_ref; +use embassy_hal_internal::PeripheralType; use crate::gpio::{AfType, OutputType, Pull, Speed}; -use crate::{rcc, Peripheral}; +use crate::{rcc, Peri}; /// FMC driver pub struct Fmc<'d, T: Instance> { @@ -21,7 +21,7 @@ where /// /// **Note:** This is currently used to provide access to some basic FMC functions /// for manual configuration for memory types that stm32-fmc does not support. - pub fn new_raw(_instance: impl Peripheral

+ 'd) -> Self { + pub fn new_raw(_instance: Peri<'d, T>) -> Self { Self { peri: PhantomData } } @@ -74,8 +74,7 @@ where macro_rules! config_pins { ($($pin:ident),*) => { - into_ref!($($pin),*); - $( + $( $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)); )* }; @@ -92,12 +91,12 @@ macro_rules! fmc_sdram_constructor { )) => { /// Create a new FMC instance. pub fn $name( - _instance: impl Peripheral

+ 'd, - $($addr_pin_name: impl Peripheral

> + 'd),*, - $($ba_pin_name: impl Peripheral

> + 'd),*, - $($d_pin_name: impl Peripheral

> + 'd),*, - $($nbl_pin_name: impl Peripheral

> + 'd),*, - $($ctrl_pin_name: impl Peripheral

> + 'd),*, + _instance: Peri<'d, T>, + $($addr_pin_name: Peri<'d, impl $addr_signal>),*, + $($ba_pin_name: Peri<'d, impl $ba_signal>),*, + $($d_pin_name: Peri<'d, impl $d_signal>),*, + $($nbl_pin_name: Peri<'d, impl $nbl_signal>),*, + $($ctrl_pin_name: Peri<'d, impl $ctrl_signal>),*, chip: CHIP ) -> stm32_fmc::Sdram, CHIP> { @@ -245,7 +244,7 @@ trait SealedInstance: crate::rcc::RccPeripheral { /// FMC instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static {} +pub trait Instance: SealedInstance + PeripheralType + 'static {} foreach_peripheral!( (fmc, $inst:ident) => { diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 65e1bfb8c..bb37c4194 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -4,10 +4,10 @@ use core::convert::Infallible; use critical_section::CriticalSection; -use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; +use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; use crate::pac::gpio::{self, vals}; -use crate::{peripherals, Peripheral}; +use crate::peripherals; /// GPIO flexible pin. /// @@ -15,7 +15,7 @@ use crate::{peripherals, Peripheral}; /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// mode. pub struct Flex<'d> { - pub(crate) pin: PeripheralRef<'d, AnyPin>, + pub(crate) pin: Peri<'d, AnyPin>, } impl<'d> Flex<'d> { @@ -25,10 +25,9 @@ impl<'d> Flex<'d> { /// before the pin is put into output mode. /// #[inline] - pub fn new(pin: impl Peripheral

+ 'd) -> Self { - into_ref!(pin); + pub fn new(pin: Peri<'d, impl Pin>) -> Self { // Pin will be in disconnected state. - Self { pin: pin.map_into() } + Self { pin: pin.into() } } /// Put the pin into input mode. @@ -310,7 +309,7 @@ pub struct Input<'d> { impl<'d> Input<'d> { /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, pull: Pull) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self { let mut pin = Flex::new(pin); pin.set_as_input(pull); Self { pin } @@ -375,7 +374,7 @@ pub struct Output<'d> { impl<'d> Output<'d> { /// Create GPIO output driver for a [Pin] with the provided [Level] and [Speed] configuration. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level, speed: Speed) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed) -> Self { let mut pin = Flex::new(pin); match initial_output { Level::High => pin.set_high(), @@ -440,7 +439,7 @@ pub struct OutputOpenDrain<'d> { impl<'d> OutputOpenDrain<'d> { /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed]. #[inline] - pub fn new(pin: impl Peripheral

+ 'd, initial_output: Level, speed: Speed) -> Self { + pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed) -> Self { let mut pin = Flex::new(pin); match initial_output { Level::High => pin.set_high(), @@ -454,7 +453,7 @@ impl<'d> OutputOpenDrain<'d> { /// and [Pull]. #[inline] #[cfg(gpio_v2)] - pub fn new_pull(pin: impl Peripheral

+ 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { + pub fn new_pull(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed, pull: Pull) -> Self { let mut pin = Flex::new(pin); match initial_output { Level::High => pin.set_high(), @@ -780,7 +779,7 @@ pub(crate) trait SealedPin { /// GPIO pin trait. #[allow(private_bounds)] -pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static { +pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// EXTI channel assigned to this pin. /// /// For example, PC4 uses EXTI4. @@ -798,18 +797,6 @@ pub trait Pin: Peripheral

+ Into + SealedPin + Sized + 'static fn port(&self) -> u8 { self._port() } - - /// Type-erase (degrade) this pin into an `AnyPin`. - /// - /// This converts pin singletons (`PA5`, `PB6`, ...), which - /// are all different types, into the same type. It is useful for - /// creating arrays of pins, or avoiding generics. - #[inline] - fn degrade(self) -> AnyPin { - AnyPin { - pin_port: self.pin_port(), - } - } } /// Type-erased GPIO pin @@ -822,8 +809,8 @@ impl AnyPin { /// /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc... #[inline] - pub unsafe fn steal(pin_port: u8) -> Self { - Self { pin_port } + pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> { + Peri::new_unchecked(Self { pin_port }) } #[inline] @@ -867,8 +854,10 @@ foreach_pin!( } impl From for AnyPin { - fn from(x: peripherals::$pin_name) -> Self { - x.degrade() + fn from(val: peripherals::$pin_name) -> Self { + Self { + pin_port: val.pin_port(), + } } } }; diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs index 3951e9d63..1258e8923 100644 --- a/embassy-stm32/src/hash/mod.rs +++ b/embassy-stm32/src/hash/mod.rs @@ -8,7 +8,7 @@ use core::ptr; #[cfg(hash_v2)] use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use stm32_metapac::hash::regs::*; @@ -19,7 +19,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::mode::Async; use crate::mode::{Blocking, Mode}; use crate::peripherals::HASH; -use crate::{interrupt, pac, peripherals, rcc, Peripheral}; +use crate::{interrupt, pac, peripherals, rcc, Peri}; #[cfg(hash_v1)] const NUM_CONTEXT_REGS: usize = 51; @@ -119,7 +119,7 @@ type HmacKey<'k> = Option<&'k [u8]>; /// HASH driver. pub struct Hash<'d, T: Instance, M: Mode> { - _peripheral: PeripheralRef<'d, T>, + _peripheral: Peri<'d, T>, _phantom: PhantomData, #[cfg(hash_v2)] dma: Option>, @@ -128,11 +128,10 @@ pub struct Hash<'d, T: Instance, M: Mode> { impl<'d, T: Instance> Hash<'d, T, Blocking> { /// Instantiates, resets, and enables the HASH peripheral. pub fn new_blocking( - peripheral: impl Peripheral

+ 'd, + peripheral: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peripheral); let instance = Self { _peripheral: peripheral, _phantom: PhantomData, @@ -396,12 +395,11 @@ impl<'d, T: Instance, M: Mode> Hash<'d, T, M> { impl<'d, T: Instance> Hash<'d, T, Async> { /// Instantiates, resets, and enables the HASH peripheral. pub fn new( - peripheral: impl Peripheral

+ 'd, - dma: impl Peripheral

> + 'd, + peripheral: Peri<'d, T>, + dma: Peri<'d, impl Dma>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(peripheral, dma); let instance = Self { _peripheral: peripheral, _phantom: PhantomData, @@ -583,7 +581,7 @@ trait SealedInstance { /// HASH instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + Peripheral

+ crate::rcc::RccPeripheral + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send { /// Interrupt for this HASH instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index d9b7c16fb..1d0594125 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs @@ -4,12 +4,12 @@ mod traits; use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; pub use traits::Instance; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; +use crate::rcc; use crate::time::Hertz; -use crate::{rcc, Peripheral}; /// HRTIM burst controller instance. pub struct BurstController { @@ -62,13 +62,13 @@ pub trait AdvancedChannel: SealedAdvancedChannel {} /// HRTIM PWM pin. pub struct PwmPin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } /// HRTIM complementary PWM pin. pub struct ComplementaryPwmPin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } @@ -76,8 +76,7 @@ macro_rules! advanced_channel_impl { ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => { impl<'d, T: Instance> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -86,7 +85,7 @@ macro_rules! advanced_channel_impl { ); }); PwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -94,8 +93,7 @@ macro_rules! advanced_channel_impl { impl<'d, T: Instance> ComplementaryPwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $complementary_pin_trait>) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -104,7 +102,7 @@ macro_rules! advanced_channel_impl { ); }); ComplementaryPwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -129,7 +127,7 @@ advanced_channel_impl!(new_chf, ChF, 5, ChannelFPin, ChannelFComplementaryPin); /// Struct used to divide a high resolution timer into multiple channels pub struct AdvancedPwm<'d, T: Instance> { - _inner: PeripheralRef<'d, T>, + _inner: Peri<'d, T>, /// Master instance. pub master: Master, /// Burst controller. @@ -154,7 +152,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> { /// /// This splits the HRTIM into its constituent parts, which you can then use individually. pub fn new( - tim: impl Peripheral

+ 'd, + tim: Peri<'d, T>, _cha: Option>>, _chan: Option>>, _chb: Option>>, @@ -171,9 +169,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> { Self::new_inner(tim) } - fn new_inner(tim: impl Peripheral

+ 'd) -> Self { - into_ref!(tim); - + fn new_inner(tim: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); #[cfg(stm32f334)] diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs index 75f9971e2..6c0661146 100644 --- a/embassy-stm32/src/hrtim/traits.rs +++ b/embassy-stm32/src/hrtim/traits.rs @@ -1,3 +1,5 @@ +use embassy_hal_internal::PeripheralType; + use crate::rcc::RccPeripheral; use crate::time::Hertz; @@ -153,7 +155,7 @@ pub(crate) trait SealedInstance: RccPeripheral { /// HRTIM instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static {} +pub trait Instance: SealedInstance + PeripheralType + 'static {} foreach_interrupt! { ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs index 06ab7a9bc..31527bcdb 100644 --- a/embassy-stm32/src/hsem/mod.rs +++ b/embassy-stm32/src/hsem/mod.rs @@ -1,13 +1,14 @@ //! Hardware Semaphore (HSEM) +use embassy_hal_internal::PeripheralType; + +use crate::pac; +use crate::rcc::RccPeripheral; // TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs. // Those MCUs have a different HSEM implementation (Secure semaphore lock support, // Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute), // which is not yet supported by this code. -use embassy_hal_internal::{into_ref, PeripheralRef}; - -use crate::rcc::RccPeripheral; -use crate::{pac, Peripheral}; +use crate::Peri; /// HSEM error. #[derive(Debug)] @@ -73,13 +74,12 @@ fn core_id_to_index(core: CoreId) -> usize { /// HSEM driver pub struct HardwareSemaphore<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, } impl<'d, T: Instance> HardwareSemaphore<'d, T> { /// Creates a new HardwareSemaphore instance. - pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { - into_ref!(peripheral); + pub fn new(peripheral: Peri<'d, T>) -> Self { HardwareSemaphore { _peri: peripheral } } @@ -177,7 +177,7 @@ trait SealedInstance { /// HSEM instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + Send + 'static {} impl SealedInstance for crate::peripherals::HSEM { fn regs() -> crate::pac::hsem::Hsem { diff --git a/embassy-stm32/src/hspi/mod.rs b/embassy-stm32/src/hspi/mod.rs index 54b442481..62bc0e979 100644 --- a/embassy-stm32/src/hspi/mod.rs +++ b/embassy-stm32/src/hspi/mod.rs @@ -13,15 +13,15 @@ pub mod enums; use core::marker::PhantomData; use embassy_embedded_hal::{GetConfig, SetConfig}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; pub use enums::*; use crate::dma::{word, ChannelAndRequest}; use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::hspi::Hspi as Regs; +use crate::peripherals; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; /// HSPI driver config. #[derive(Clone, Copy)] @@ -163,27 +163,27 @@ pub enum HspiError { /// HSPI driver. pub struct Hspi<'d, T: Instance, M: PeriMode> { - _peri: PeripheralRef<'d, T>, - sck: Option>, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - d4: Option>, - d5: Option>, - d6: Option>, - d7: Option>, - d8: Option>, - d9: Option>, - d10: Option>, - d11: Option>, - d12: Option>, - d13: Option>, - d14: Option>, - d15: Option>, - nss: Option>, - dqs0: Option>, - dqs1: Option>, + _peri: Peri<'d, T>, + sck: Option>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + d4: Option>, + d5: Option>, + d6: Option>, + d7: Option>, + d8: Option>, + d9: Option>, + d10: Option>, + d11: Option>, + d12: Option>, + d13: Option>, + d14: Option>, + d15: Option>, + nss: Option>, + dqs0: Option>, + dqs1: Option>, dma: Option>, _phantom: PhantomData, config: Config, @@ -247,34 +247,32 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> { } fn new_inner( - peri: impl Peripheral

+ 'd, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - d4: Option>, - d5: Option>, - d6: Option>, - d7: Option>, - d8: Option>, - d9: Option>, - d10: Option>, - d11: Option>, - d12: Option>, - d13: Option>, - d14: Option>, - d15: Option>, - sck: Option>, - nss: Option>, - dqs0: Option>, - dqs1: Option>, + peri: Peri<'d, T>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + d4: Option>, + d5: Option>, + d6: Option>, + d7: Option>, + d8: Option>, + d9: Option>, + d10: Option>, + d11: Option>, + d12: Option>, + d13: Option>, + d14: Option>, + d15: Option>, + sck: Option>, + nss: Option>, + dqs0: Option>, + dqs1: Option>, dma: Option>, config: Config, width: HspiWidth, dual_memory_mode: bool, ) -> Self { - into_ref!(peri); - // System configuration rcc::enable_and_reset::(); @@ -579,11 +577,11 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> { impl<'d, T: Instance> Hspi<'d, T, Blocking> { /// Create new blocking HSPI driver for single spi external chip pub fn new_blocking_singlespi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -620,18 +618,18 @@ impl<'d, T: Instance> Hspi<'d, T, Blocking> { /// Create new blocking HSPI driver for octospi external chip pub fn new_blocking_octospi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dqs0: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, + dqs0: Peri<'d, impl DQS0Pin>, config: Config, ) -> Self { Self::new_inner( @@ -670,12 +668,12 @@ impl<'d, T: Instance> Hspi<'d, T, Blocking> { impl<'d, T: Instance> Hspi<'d, T, Async> { /// Create new HSPI driver for a single spi external chip pub fn new_singlespi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl HspiDma>, config: Config, ) -> Self { Self::new_inner( @@ -712,19 +710,19 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { /// Create new HSPI driver for octospi external chip pub fn new_octospi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dqs0: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, + dqs0: Peri<'d, impl DQS0Pin>, + dma: Peri<'d, impl HspiDma>, config: Config, ) -> Self { Self::new_inner( @@ -943,7 +941,7 @@ pub(crate) trait SealedInstance { /// HSPI instance trait. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {} pin_trait!(SckPin, Instance); pin_trait!(NckPin, Instance); diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 3a9954663..1689fdb84 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -9,7 +9,7 @@ use core::future::Future; use core::iter; use core::marker::PhantomData; -use embassy_hal_internal::{Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_sync::waitqueue::AtomicWaker; #[cfg(feature = "time")] use embassy_time::{Duration, Instant}; @@ -131,8 +131,8 @@ pub struct I2c<'d, M: Mode> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - scl: Option>, - sda: Option>, + scl: Option>, + sda: Option>, tx_dma: Option>, rx_dma: Option>, #[cfg(feature = "time")] @@ -143,14 +143,14 @@ pub struct I2c<'d, M: Mode> { impl<'d> I2c<'d, Async> { /// Create a new I2C driver. pub fn new( - peri: impl Peripheral

+ 'd, - scl: impl Peripheral

> + 'd, - sda: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + scl: Peri<'d, impl SclPin>, + sda: Peri<'d, impl SdaPin>, _irq: impl interrupt::typelevel::Binding> + interrupt::typelevel::Binding> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, freq: Hertz, config: Config, ) -> Self { @@ -169,9 +169,9 @@ impl<'d> I2c<'d, Async> { impl<'d> I2c<'d, Blocking> { /// Create a new blocking I2C driver. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - scl: impl Peripheral

> + 'd, - sda: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + scl: Peri<'d, impl SclPin>, + sda: Peri<'d, impl SdaPin>, freq: Hertz, config: Config, ) -> Self { @@ -190,9 +190,9 @@ impl<'d> I2c<'d, Blocking> { impl<'d, M: Mode> I2c<'d, M> { /// Create a new I2C driver. fn new_inner( - _peri: impl Peripheral

+ 'd, - scl: Option>, - sda: Option>, + _peri: Peri<'d, T>, + scl: Option>, + sda: Option>, tx_dma: Option>, rx_dma: Option>, freq: Hertz, diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index ce166d718..5005a5cdb 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -1,7 +1,6 @@ //! Inter-IC Sound (I2S) use embassy_futures::join::join; -use embassy_hal_internal::into_ref; use stm32_metapac::spi::vals; use crate::dma::{ringbuffer, ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer}; @@ -9,7 +8,7 @@ use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::mode::Async; use crate::spi::{Config as SpiConfig, RegsExt as _, *}; use crate::time::Hertz; -use crate::{Peripheral, PeripheralRef}; +use crate::Peri; /// I2S mode #[derive(Copy, Clone)] @@ -225,11 +224,11 @@ pub struct I2S<'d, W: Word> { #[allow(dead_code)] mode: Mode, spi: Spi<'d, Async>, - txsd: Option>, - rxsd: Option>, - ws: Option>, - ck: Option>, - mck: Option>, + txsd: Option>, + rxsd: Option>, + ws: Option>, + ck: Option>, + mck: Option>, tx_ring_buffer: Option>, rx_ring_buffer: Option>, } @@ -237,12 +236,12 @@ pub struct I2S<'d, W: Word> { impl<'d, W: Word> I2S<'d, W> { /// Create a transmitter driver. pub fn new_txonly( - peri: impl Peripheral

+ 'd, - sd: impl Peripheral

> + 'd, - ws: impl Peripheral

> + 'd, - ck: impl Peripheral

> + 'd, - mck: impl Peripheral

> + 'd, - txdma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sd: Peri<'d, impl MosiPin>, + ws: Peri<'d, impl WsPin>, + ck: Peri<'d, impl CkPin>, + mck: Peri<'d, impl MckPin>, + txdma: Peri<'d, impl TxDma>, txdma_buf: &'d mut [W], freq: Hertz, config: Config, @@ -264,11 +263,11 @@ impl<'d, W: Word> I2S<'d, W> { /// Create a transmitter driver without a master clock pin. pub fn new_txonly_nomck( - peri: impl Peripheral

+ 'd, - sd: impl Peripheral

> + 'd, - ws: impl Peripheral

> + 'd, - ck: impl Peripheral

> + 'd, - txdma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sd: Peri<'d, impl MosiPin>, + ws: Peri<'d, impl WsPin>, + ck: Peri<'d, impl CkPin>, + txdma: Peri<'d, impl TxDma>, txdma_buf: &'d mut [W], freq: Hertz, config: Config, @@ -290,12 +289,12 @@ impl<'d, W: Word> I2S<'d, W> { /// Create a receiver driver. pub fn new_rxonly( - peri: impl Peripheral

+ 'd, - sd: impl Peripheral

> + 'd, - ws: impl Peripheral

> + 'd, - ck: impl Peripheral

> + 'd, - mck: impl Peripheral

> + 'd, - rxdma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sd: Peri<'d, impl MisoPin>, + ws: Peri<'d, impl WsPin>, + ck: Peri<'d, impl CkPin>, + mck: Peri<'d, impl MckPin>, + rxdma: Peri<'d, impl RxDma>, rxdma_buf: &'d mut [W], freq: Hertz, config: Config, @@ -318,15 +317,15 @@ impl<'d, W: Word> I2S<'d, W> { #[cfg(spi_v3)] /// Create a full duplex driver. pub fn new_full_duplex( - peri: impl Peripheral

+ 'd, - txsd: impl Peripheral

> + 'd, - rxsd: impl Peripheral

> + 'd, - ws: impl Peripheral

> + 'd, - ck: impl Peripheral

> + 'd, - mck: impl Peripheral

> + 'd, - txdma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + txsd: Peri<'d, impl MosiPin>, + rxsd: Peri<'d, impl MisoPin>, + ws: Peri<'d, impl WsPin>, + ck: Peri<'d, impl CkPin>, + mck: Peri<'d, impl MckPin>, + txdma: Peri<'d, impl TxDma>, txdma_buf: &'d mut [W], - rxdma: impl Peripheral

> + 'd, + rxdma: Peri<'d, impl RxDma>, rxdma_buf: &'d mut [W], freq: Hertz, config: Config, @@ -466,20 +465,18 @@ impl<'d, W: Word> I2S<'d, W> { } fn new_inner( - peri: impl Peripheral

+ 'd, - txsd: Option>, - rxsd: Option>, - ws: impl Peripheral

> + 'd, - ck: impl Peripheral

> + 'd, - mck: Option>, + peri: Peri<'d, T>, + txsd: Option>, + rxsd: Option>, + ws: Peri<'d, impl WsPin>, + ck: Peri<'d, impl CkPin>, + mck: Option>, txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>, rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>, freq: Hertz, config: Config, function: Function, ) -> Self { - into_ref!(ws, ck); - ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); @@ -583,11 +580,11 @@ impl<'d, W: Word> I2S<'d, W> { Self { mode: config.mode, spi, - txsd: txsd.map(|w| w.map_into()), - rxsd: rxsd.map(|w| w.map_into()), - ws: Some(ws.map_into()), - ck: Some(ck.map_into()), - mck: mck.map(|w| w.map_into()), + txsd: txsd.map(|w| w.into()), + rxsd: rxsd.map(|w| w.into()), + ws: Some(ws.into()), + ck: Some(ck.into()), + mck: mck.map(|w| w.into()), tx_ring_buffer: txdma.map(|(ch, buf)| unsafe { WritableRingBuffer::new(ch.channel, ch.request, regs.tx_ptr(), buf, opts) }), diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index c37908dbc..4d7aac81f 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -211,7 +211,7 @@ macro_rules! bind_interrupts { // Reexports pub use _generated::{peripherals, Peripherals}; -pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +pub use embassy_hal_internal::{Peri, PeripheralType}; #[cfg(feature = "unstable-pac")] pub use stm32_metapac as pac; #[cfg(not(feature = "unstable-pac"))] diff --git a/embassy-stm32/src/lptim/mod.rs b/embassy-stm32/src/lptim/mod.rs index 1649cc5b4..e0ddba1c7 100644 --- a/embassy-stm32/src/lptim/mod.rs +++ b/embassy-stm32/src/lptim/mod.rs @@ -10,6 +10,7 @@ use crate::rcc::RccPeripheral; mod channel; #[cfg(any(lptim_v2a, lptim_v2b))] pub use channel::Channel; +use embassy_hal_internal::PeripheralType; pin_trait!(OutputPin, BasicInstance); pin_trait!(Channel1Pin, BasicInstance); @@ -22,7 +23,7 @@ pub(crate) trait SealedBasicInstance: RccPeripheral {} /// LPTIM basic instance trait. #[allow(private_bounds)] -pub trait BasicInstance: SealedBasicInstance + 'static {} +pub trait BasicInstance: PeripheralType + SealedBasicInstance + 'static {} /// LPTIM instance trait. #[allow(private_bounds)] diff --git a/embassy-stm32/src/lptim/pwm.rs b/embassy-stm32/src/lptim/pwm.rs index 132f5815e..2f2d7ba01 100644 --- a/embassy-stm32/src/lptim/pwm.rs +++ b/embassy-stm32/src/lptim/pwm.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use super::timer::Timer; #[cfg(not(any(lptim_v2a, lptim_v2b)))] @@ -14,7 +14,6 @@ use super::{BasicInstance, Instance}; use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::time::Hertz; -use crate::Peripheral; /// Output marker type. pub enum Output {} @@ -27,7 +26,7 @@ pub enum Ch2 {} /// /// This wraps a pin to make it usable with PWM. pub struct PwmPin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } @@ -48,8 +47,7 @@ macro_rules! channel_impl { ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -58,16 +56,12 @@ macro_rules! channel_impl { ); }); PwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] - pub fn $new_chx_with_config( - pin: impl Peripheral

> + 'd, - pin_config: PwmPinConfig, - ) -> Self { - into_ref!(pin); + pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait>, pin_config: PwmPinConfig) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -79,7 +73,7 @@ macro_rules! channel_impl { ); }); PwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -102,7 +96,7 @@ pub struct Pwm<'d, T: Instance> { #[cfg(not(any(lptim_v2a, lptim_v2b)))] impl<'d, T: Instance> Pwm<'d, T> { /// Create a new PWM driver. - pub fn new(tim: impl Peripheral

+ 'd, _output_pin: PwmPin<'d, T, Output>, freq: Hertz) -> Self { + pub fn new(tim: Peri<'d, T>, _output_pin: PwmPin<'d, T, Output>, freq: Hertz) -> Self { Self::new_inner(tim, freq) } @@ -128,7 +122,7 @@ impl<'d, T: Instance> Pwm<'d, T> { impl<'d, T: Instance> Pwm<'d, T> { /// Create a new PWM driver. pub fn new( - tim: impl Peripheral

+ 'd, + tim: Peri<'d, T>, _ch1_pin: Option>, _ch2_pin: Option>, freq: Hertz, @@ -174,7 +168,7 @@ impl<'d, T: Instance> Pwm<'d, T> { } impl<'d, T: Instance> Pwm<'d, T> { - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz) -> Self { let mut this = Self { inner: Timer::new(tim) }; this.inner.enable(); diff --git a/embassy-stm32/src/lptim/timer/mod.rs b/embassy-stm32/src/lptim/timer/mod.rs index e62fcab49..a629be62b 100644 --- a/embassy-stm32/src/lptim/timer/mod.rs +++ b/embassy-stm32/src/lptim/timer/mod.rs @@ -1,7 +1,7 @@ //! Low-level timer driver. mod prescaler; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; #[cfg(any(lptim_v2a, lptim_v2b))] use super::channel::Channel; @@ -17,14 +17,12 @@ use crate::time::Hertz; /// Low-level timer driver. pub struct Timer<'d, T: Instance> { - _tim: PeripheralRef<'d, T>, + _tim: Peri<'d, T>, } impl<'d, T: Instance> Timer<'d, T> { /// Create a new timer driver. - pub fn new(tim: impl Peripheral

+ 'd) -> Self { - into_ref!(tim); - + pub fn new(tim: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); Self { _tim: tim } diff --git a/embassy-stm32/src/ltdc.rs b/embassy-stm32/src/ltdc.rs index 16210b7dc..0f6ef569c 100644 --- a/embassy-stm32/src/ltdc.rs +++ b/embassy-stm32/src/ltdc.rs @@ -6,7 +6,7 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use stm32_metapac::ltdc::regs::Dccr; use stm32_metapac::ltdc::vals::{Bf1, Bf2, Cfuif, Clif, Crrif, Cterrif, Pf, Vbr}; @@ -14,7 +14,7 @@ use stm32_metapac::ltdc::vals::{Bf1, Bf2, Cfuif, Clif, Crrif, Cterrif, Pf, Vbr}; use crate::gpio::{AfType, OutputType, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::interrupt::{self}; -use crate::{peripherals, rcc, Peripheral}; +use crate::{peripherals, rcc, Peri}; static LTDC_WAKER: AtomicWaker = AtomicWaker::new(); @@ -83,7 +83,7 @@ pub enum PolarityActive { /// LTDC driver. pub struct Ltdc<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, } /// LTDC interrupt handler. @@ -178,47 +178,45 @@ impl interrupt::typelevel::Handler for InterruptHandl impl<'d, T: Instance> Ltdc<'d, T> { // Create a new LTDC driver without specifying color and control pins. This is typically used if you want to drive a display though a DsiHost /// Note: Full-Duplex modes are not supported at this time - pub fn new(peri: impl Peripheral

+ 'd) -> Self { + pub fn new(peri: Peri<'d, T>) -> Self { Self::setup_clocks(); - into_ref!(peri); Self { _peri: peri } } /// Create a new LTDC driver. 8 pins per color channel for blue, green and red #[allow(clippy::too_many_arguments)] pub fn new_with_pins( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - clk: impl Peripheral

> + 'd, - hsync: impl Peripheral

> + 'd, - vsync: impl Peripheral

> + 'd, - b0: impl Peripheral

> + 'd, - b1: impl Peripheral

> + 'd, - b2: impl Peripheral

> + 'd, - b3: impl Peripheral

> + 'd, - b4: impl Peripheral

> + 'd, - b5: impl Peripheral

> + 'd, - b6: impl Peripheral

> + 'd, - b7: impl Peripheral

> + 'd, - g0: impl Peripheral

> + 'd, - g1: impl Peripheral

> + 'd, - g2: impl Peripheral

> + 'd, - g3: impl Peripheral

> + 'd, - g4: impl Peripheral

> + 'd, - g5: impl Peripheral

> + 'd, - g6: impl Peripheral

> + 'd, - g7: impl Peripheral

> + 'd, - r0: impl Peripheral

> + 'd, - r1: impl Peripheral

> + 'd, - r2: impl Peripheral

> + 'd, - r3: impl Peripheral

> + 'd, - r4: impl Peripheral

> + 'd, - r5: impl Peripheral

> + 'd, - r6: impl Peripheral

> + 'd, - r7: impl Peripheral

> + 'd, + clk: Peri<'d, impl ClkPin>, + hsync: Peri<'d, impl HsyncPin>, + vsync: Peri<'d, impl VsyncPin>, + b0: Peri<'d, impl B0Pin>, + b1: Peri<'d, impl B1Pin>, + b2: Peri<'d, impl B2Pin>, + b3: Peri<'d, impl B3Pin>, + b4: Peri<'d, impl B4Pin>, + b5: Peri<'d, impl B5Pin>, + b6: Peri<'d, impl B6Pin>, + b7: Peri<'d, impl B7Pin>, + g0: Peri<'d, impl G0Pin>, + g1: Peri<'d, impl G1Pin>, + g2: Peri<'d, impl G2Pin>, + g3: Peri<'d, impl G3Pin>, + g4: Peri<'d, impl G4Pin>, + g5: Peri<'d, impl G5Pin>, + g6: Peri<'d, impl G6Pin>, + g7: Peri<'d, impl G7Pin>, + r0: Peri<'d, impl R0Pin>, + r1: Peri<'d, impl R1Pin>, + r2: Peri<'d, impl R2Pin>, + r3: Peri<'d, impl R3Pin>, + r4: Peri<'d, impl R4Pin>, + r5: Peri<'d, impl R5Pin>, + r6: Peri<'d, impl R6Pin>, + r7: Peri<'d, impl R7Pin>, ) -> Self { Self::setup_clocks(); - into_ref!(peri); new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)); new_pin!(hsync, AfType::output(OutputType::PushPull, Speed::VeryHigh)); new_pin!(vsync, AfType::output(OutputType::PushPull, Speed::VeryHigh)); @@ -529,7 +527,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral { /// LTDC instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + Peripheral

+ crate::rcc::RccPeripheral + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send { /// Interrupt for this LTDC instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index 000773e2d..2c181a254 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs @@ -14,7 +14,7 @@ macro_rules! peri_trait { /// Peripheral instance trait. #[allow(private_bounds)] - pub trait Instance: crate::Peripheral

+ SealedInstance + crate::rcc::RccPeripheral { + pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral { $($( /// Interrupt for this peripheral. type $irq: crate::interrupt::typelevel::Interrupt; @@ -88,10 +88,10 @@ macro_rules! dma_trait_impl { #[allow(unused)] macro_rules! new_dma_nonopt { ($name:ident) => {{ - let dma = $name.into_ref(); + let dma = $name; let request = dma.request(); crate::dma::ChannelAndRequest { - channel: dma.map_into(), + channel: dma.into(), request, } }}; @@ -99,10 +99,10 @@ macro_rules! new_dma_nonopt { macro_rules! new_dma { ($name:ident) => {{ - let dma = $name.into_ref(); + let dma = $name; let request = dma.request(); Some(crate::dma::ChannelAndRequest { - channel: dma.map_into(), + channel: dma.into(), request, }) }}; @@ -110,8 +110,8 @@ macro_rules! new_dma { macro_rules! new_pin { ($name:ident, $af_type:expr) => {{ - let pin = $name.into_ref(); + let pin = $name; pin.set_as_af(pin.af_num(), $af_type); - Some(pin.map_into()) + Some(pin.into()) }}; } diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index c7610f4b5..a81493c1b 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -1,10 +1,10 @@ //! Operational Amplifier (OPAMP) #![macro_use] -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use crate::pac::opamp::vals::*; -use crate::Peripheral; +use crate::Peri; /// Gain #[allow(missing_docs)] @@ -52,16 +52,14 @@ pub struct OpAmpInternalOutput<'d, T: Instance> { /// OpAmp driver. pub struct OpAmp<'d, T: Instance> { - _inner: PeripheralRef<'d, T>, + _inner: Peri<'d, T>, } impl<'d, T: Instance> OpAmp<'d, T> { /// Create a new driver instance. /// /// Does not enable the opamp, but does set the speed mode on some families. - pub fn new(opamp: impl Peripheral

+ 'd, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { - into_ref!(opamp); - + pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { #[cfg(opamp_g4)] T::regs().csr().modify(|w| { w.set_opahsm(speed.into()); @@ -82,12 +80,10 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// [`OpAmpOutput`] is dropped. pub fn buffer_ext( &mut self, - in_pin: impl Peripheral

+ crate::gpio::Pin>, - out_pin: impl Peripheral

+ crate::gpio::Pin>, + in_pin: Peri<'_, impl NonInvertingPin + crate::gpio::Pin>, + out_pin: Peri<'_, impl OutputPin + crate::gpio::Pin>, gain: OpAmpGain, ) -> OpAmpOutput<'_, T> { - into_ref!(in_pin); - into_ref!(out_pin); in_pin.set_as_analog(); out_pin.set_as_analog(); @@ -119,11 +115,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// directly used as an ADC input. The opamp will be disabled when the /// [`OpAmpOutput`] is dropped. #[cfg(opamp_g4)] - pub fn buffer_dac( - &mut self, - out_pin: impl Peripheral

+ crate::gpio::Pin>, - ) -> OpAmpOutput<'_, T> { - into_ref!(out_pin); + pub fn buffer_dac(&mut self, out_pin: Peri<'_, impl OutputPin + crate::gpio::Pin>) -> OpAmpOutput<'_, T> { out_pin.set_as_analog(); T::regs().csr().modify(|w| { @@ -149,10 +141,9 @@ impl<'d, T: Instance> OpAmp<'d, T> { #[cfg(opamp_g4)] pub fn buffer_int( &mut self, - pin: impl Peripheral

+ crate::gpio::Pin>, + pin: Peri<'_, impl NonInvertingPin + crate::gpio::Pin>, gain: OpAmpGain, ) -> OpAmpInternalOutput<'_, T> { - into_ref!(pin); pin.set_as_analog(); // PGA_GAIN value may have different meaning in different MCU serials, use with caution. @@ -211,7 +202,7 @@ pub(crate) trait SealedOutputPin {} /// Opamp instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + 'static {} +pub trait Instance: SealedInstance + PeripheralType + 'static {} /// Non-inverting pin trait. #[allow(private_bounds)] pub trait NonInvertingPin: SealedNonInvertingPin {} diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs index 5dff3c4c3..74edfd5e4 100644 --- a/embassy-stm32/src/ospi/mod.rs +++ b/embassy-stm32/src/ospi/mod.rs @@ -8,7 +8,7 @@ pub mod enums; use core::marker::PhantomData; use embassy_embedded_hal::{GetConfig, SetConfig}; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; pub use enums::*; use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits}; @@ -19,7 +19,7 @@ use crate::pac::octospi::{vals, Octospi as Regs}; #[cfg(octospim_v1)] use crate::pac::octospim::Octospim; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; /// OPSI driver config. #[derive(Clone, Copy)] @@ -160,18 +160,18 @@ pub enum OspiError { /// OSPI driver. pub struct Ospi<'d, T: Instance, M: PeriMode> { - _peri: PeripheralRef<'d, T>, - sck: Option>, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - d4: Option>, - d5: Option>, - d6: Option>, - d7: Option>, - nss: Option>, - dqs: Option>, + _peri: Peri<'d, T>, + sck: Option>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + d4: Option>, + d5: Option>, + d6: Option>, + d7: Option>, + nss: Option>, + dqs: Option>, dma: Option>, _phantom: PhantomData, config: Config, @@ -245,25 +245,23 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { } fn new_inner( - peri: impl Peripheral

+ 'd, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - d4: Option>, - d5: Option>, - d6: Option>, - d7: Option>, - sck: Option>, - nss: Option>, - dqs: Option>, + peri: Peri<'d, T>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + d4: Option>, + d5: Option>, + d6: Option>, + d7: Option>, + sck: Option>, + nss: Option>, + dqs: Option>, dma: Option>, config: Config, width: OspiWidth, dual_quad: bool, ) -> Self { - into_ref!(peri); - #[cfg(octospim_v1)] { // RCC for octospim should be enabled before writing register @@ -685,11 +683,11 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { impl<'d, T: Instance> Ospi<'d, T, Blocking> { /// Create new blocking OSPI driver for a single spi external chip pub fn new_blocking_singlespi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -717,11 +715,11 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { /// Create new blocking OSPI driver for a dualspi external chip pub fn new_blocking_dualspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -749,13 +747,13 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { /// Create new blocking OSPI driver for a quadspi external chip pub fn new_blocking_quadspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -783,17 +781,17 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { /// Create new blocking OSPI driver for two quadspi external chips pub fn new_blocking_dualquadspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -821,17 +819,17 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { /// Create new blocking OSPI driver for octospi external chips pub fn new_blocking_octospi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -861,12 +859,12 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { impl<'d, T: Instance> Ospi<'d, T, Async> { /// Create new blocking OSPI driver for a single spi external chip pub fn new_singlespi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl OctoDma>, config: Config, ) -> Self { Self::new_inner( @@ -894,12 +892,12 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { /// Create new blocking OSPI driver for a dualspi external chip pub fn new_dualspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl OctoDma>, config: Config, ) -> Self { Self::new_inner( @@ -927,14 +925,14 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { /// Create new blocking OSPI driver for a quadspi external chip pub fn new_quadspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl OctoDma>, config: Config, ) -> Self { Self::new_inner( @@ -962,18 +960,18 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { /// Create new blocking OSPI driver for two quadspi external chips pub fn new_dualquadspi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl OctoDma>, config: Config, ) -> Self { Self::new_inner( @@ -1001,18 +999,18 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { /// Create new blocking OSPI driver for octospi external chips pub fn new_octospi( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - d4: impl Peripheral

> + 'd, - d5: impl Peripheral

> + 'd, - d6: impl Peripheral

> + 'd, - d7: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, + d4: Peri<'d, impl D4Pin>, + d5: Peri<'d, impl D5Pin>, + d6: Peri<'d, impl D6Pin>, + d7: Peri<'d, impl D7Pin>, + nss: Peri<'d, impl NSSPin>, + dma: Peri<'d, impl OctoDma>, config: Config, ) -> Self { Self::new_inner( @@ -1221,12 +1219,12 @@ pub(crate) trait SealedInstance { /// OSPI instance trait. #[cfg(octospim_v1)] #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral + SealedOctospimInstance {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + SealedOctospimInstance {} /// OSPI instance trait. #[cfg(not(octospim_v1))] #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {} pin_trait!(SckPin, Instance); pin_trait!(NckPin, Instance); diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 411e533c9..0df057c53 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -6,7 +6,7 @@ pub mod enums; use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; use enums::*; use crate::dma::ChannelAndRequest; @@ -14,7 +14,7 @@ use crate::gpio::{AfType, AnyPin, OutputType, Pull, Speed}; use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::quadspi::Quadspi as Regs; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; /// QSPI transfer configuration. pub struct TransferConfig { @@ -75,13 +75,13 @@ impl Default for Config { /// QSPI driver. #[allow(dead_code)] pub struct Qspi<'d, T: Instance, M: PeriMode> { - _peri: PeripheralRef<'d, T>, - sck: Option>, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - nss: Option>, + _peri: Peri<'d, T>, + sck: Option>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + nss: Option>, dma: Option>, _phantom: PhantomData, config: Config, @@ -89,19 +89,17 @@ pub struct Qspi<'d, T: Instance, M: PeriMode> { impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { fn new_inner( - peri: impl Peripheral

+ 'd, - d0: Option>, - d1: Option>, - d2: Option>, - d3: Option>, - sck: Option>, - nss: Option>, + peri: Peri<'d, T>, + d0: Option>, + d1: Option>, + d2: Option>, + d3: Option>, + sck: Option>, + nss: Option>, dma: Option>, config: Config, fsel: FlashSelection, ) -> Self { - into_ref!(peri); - rcc::enable_and_reset::(); while T::REGS.sr().read().busy() {} @@ -272,13 +270,13 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { impl<'d, T: Instance> Qspi<'d, T, Blocking> { /// Create a new QSPI driver for bank 1, in blocking mode. pub fn new_blocking_bank1( - peri: impl Peripheral

+ 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - sck: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + d0: Peri<'d, impl BK1D0Pin>, + d1: Peri<'d, impl BK1D1Pin>, + d2: Peri<'d, impl BK1D2Pin>, + d3: Peri<'d, impl BK1D3Pin>, + sck: Peri<'d, impl SckPin>, + nss: Peri<'d, impl BK1NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -300,13 +298,13 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> { /// Create a new QSPI driver for bank 2, in blocking mode. pub fn new_blocking_bank2( - peri: impl Peripheral

+ 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - sck: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + d0: Peri<'d, impl BK2D0Pin>, + d1: Peri<'d, impl BK2D1Pin>, + d2: Peri<'d, impl BK2D2Pin>, + d3: Peri<'d, impl BK2D3Pin>, + sck: Peri<'d, impl SckPin>, + nss: Peri<'d, impl BK2NSSPin>, config: Config, ) -> Self { Self::new_inner( @@ -330,14 +328,14 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> { impl<'d, T: Instance> Qspi<'d, T, Async> { /// Create a new QSPI driver for bank 1. pub fn new_bank1( - peri: impl Peripheral

+ 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - sck: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + d0: Peri<'d, impl BK1D0Pin>, + d1: Peri<'d, impl BK1D1Pin>, + d2: Peri<'d, impl BK1D2Pin>, + d3: Peri<'d, impl BK1D3Pin>, + sck: Peri<'d, impl SckPin>, + nss: Peri<'d, impl BK1NSSPin>, + dma: Peri<'d, impl QuadDma>, config: Config, ) -> Self { Self::new_inner( @@ -359,14 +357,14 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { /// Create a new QSPI driver for bank 2. pub fn new_bank2( - peri: impl Peripheral

+ 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, - sck: impl Peripheral

> + 'd, - nss: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + d0: Peri<'d, impl BK2D0Pin>, + d1: Peri<'d, impl BK2D1Pin>, + d2: Peri<'d, impl BK2D2Pin>, + d3: Peri<'d, impl BK2D3Pin>, + sck: Peri<'d, impl SckPin>, + nss: Peri<'d, impl BK2NSSPin>, + dma: Peri<'d, impl QuadDma>, config: Config, ) -> Self { Self::new_inner( @@ -465,7 +463,7 @@ trait SealedInstance { /// QSPI instance trait. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {} pin_trait!(SckPin, Instance); pin_trait!(BK1D0Pin, Instance); diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index d1ce14c86..c50e071fb 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; -use embassy_hal_internal::into_ref; +use embassy_hal_internal::PeripheralType; use crate::gpio::{AfType, OutputType, Speed}; #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] @@ -32,7 +32,7 @@ pub use crate::pac::rcc::vals::Mcosel as McoSource; ))] pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source}; use crate::pac::RCC; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; #[cfg(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37))] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] @@ -43,7 +43,7 @@ pub enum McoPrescaler { pub(crate) trait SealedMcoInstance {} #[allow(private_bounds)] -pub trait McoInstance: SealedMcoInstance + 'static { +pub trait McoInstance: PeripheralType + SealedMcoInstance + 'static { type Source; #[doc(hidden)] @@ -91,14 +91,7 @@ pub struct Mco<'d, T: McoInstance> { impl<'d, T: McoInstance> Mco<'d, T> { /// Create a new MCO instance. - pub fn new( - _peri: impl Peripheral

+ 'd, - pin: impl Peripheral

> + 'd, - source: T::Source, - prescaler: McoPrescaler, - ) -> Self { - into_ref!(pin); - + pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin>, source: T::Source, prescaler: McoPrescaler) -> Self { critical_section::with(|_| unsafe { T::_apply_clock_settings(source, prescaler); pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index b96200e5e..250a08a39 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -5,12 +5,12 @@ use core::future::poll_fn; use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +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, Peripheral}; +use crate::{interrupt, pac, peripherals, rcc, Peri}; static RNG_WAKER: AtomicWaker = AtomicWaker::new(); @@ -43,17 +43,16 @@ impl interrupt::typelevel::Handler for InterruptHandl /// RNG driver. pub struct Rng<'d, T: Instance> { - _inner: PeripheralRef<'d, T>, + _inner: Peri<'d, T>, } impl<'d, T: Instance> Rng<'d, T> { /// Create a new RNG driver. pub fn new( - inner: impl Peripheral

+ 'd, + inner: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, ) -> Self { rcc::enable_and_reset::(); - into_ref!(inner); let mut random = Self { _inner: inner }; random.reset(); @@ -228,7 +227,7 @@ trait SealedInstance { /// RNG instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + Peripheral

+ crate::rcc::RccPeripheral + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send { /// Interrupt for this RNG instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index c2919e2bd..b16c6fdca 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -29,9 +29,9 @@ use crate::time::Hertz; mod _version; #[allow(unused_imports)] pub use _version::*; -use embassy_hal_internal::Peripheral; use crate::peripherals::RTC; +use crate::Peri; /// Errors that can occur on methods on [RtcClock] #[non_exhaustive] @@ -151,7 +151,7 @@ pub enum RtcCalibrationCyclePeriod { impl Rtc { /// Create a new RTC instance. - pub fn new(_rtc: impl Peripheral

, rtc_config: RtcConfig) -> Self { + pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> Self { #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] crate::rcc::enable_and_reset::(); diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 39ed44712..0c9c27797 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::PeripheralType; pub use crate::dma::word; #[cfg(not(gpdma))] @@ -12,7 +12,7 @@ use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptio use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::pac::sai::{vals, Sai as Regs}; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; +use crate::{peripherals, Peri}; /// SAI error #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -679,7 +679,7 @@ fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AfType, AfType) { #[cfg(not(gpdma))] fn get_ring_buffer<'d, T: Instance, W: word::Word>( - dma: impl Peripheral

+ 'd, + dma: Peri<'d, impl Channel>, dma_buf: &'d mut [W], request: Request, sub_block: WhichSubBlock, @@ -718,16 +718,15 @@ fn update_synchronous_config(config: &mut Config) { } /// SAI subblock instance. -pub struct SubBlock<'d, T, S: SubBlockInstance> { - peri: PeripheralRef<'d, T>, +pub struct SubBlock<'d, T: Instance, S: SubBlockInstance> { + peri: Peri<'d, T>, _phantom: PhantomData, } /// Split the main SAIx peripheral into the two subblocks. /// /// You can then create a [`Sai`] driver for each each half. -pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral

+ 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { - into_ref!(peri); +pub fn split_subblocks<'d, T: Instance>(peri: Peri<'d, T>) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { rcc::enable_and_reset::(); ( @@ -744,11 +743,11 @@ pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral

+ 'd) -> (S /// SAI sub-block driver. pub struct Sai<'d, T: Instance, W: word::Word> { - _peri: PeripheralRef<'d, T>, - sd: Option>, - fs: Option>, - sck: Option>, - mclk: Option>, + _peri: Peri<'d, T>, + sd: Option>, + fs: Option>, + sck: Option>, + mclk: Option>, #[cfg(gpdma)] ring_buffer: PhantomData, #[cfg(not(gpdma))] @@ -763,16 +762,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { /// You can obtain the [`SubBlock`] with [`split_subblocks`]. pub fn new_asynchronous_with_mclk( peri: SubBlock<'d, T, S>, - sck: impl Peripheral

> + 'd, - sd: impl Peripheral

> + 'd, - fs: impl Peripheral

> + 'd, - mclk: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + sck: Peri<'d, impl SckPin>, + sd: Peri<'d, impl SdPin>, + fs: Peri<'d, impl FsPin>, + mclk: Peri<'d, impl MclkPin>, + dma: Peri<'d, impl Channel + Dma>, dma_buf: &'d mut [W], mut config: Config, ) -> Self { - into_ref!(mclk); - let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); mclk.set_as_af(mclk.af_num(), ck_af_type); @@ -788,15 +785,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { /// You can obtain the [`SubBlock`] with [`split_subblocks`]. pub fn new_asynchronous( peri: SubBlock<'d, T, S>, - sck: impl Peripheral

> + 'd, - sd: impl Peripheral

> + 'd, - fs: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + sck: Peri<'d, impl SckPin>, + sd: Peri<'d, impl SdPin>, + fs: Peri<'d, impl FsPin>, + dma: Peri<'d, impl Channel + Dma>, dma_buf: &'d mut [W], config: Config, ) -> Self { let peri = peri.peri; - into_ref!(peri, dma, sck, sd, fs); let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); sd.set_as_af(sd.af_num(), sd_af_type); @@ -809,10 +805,10 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { Self::new_inner( peri, sub_block, - Some(sck.map_into()), + Some(sck.into()), None, - Some(sd.map_into()), - Some(fs.map_into()), + Some(sd.into()), + Some(fs.into()), get_ring_buffer::(dma, dma_buf, request, sub_block, config.tx_rx), config, ) @@ -823,15 +819,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { /// You can obtain the [`SubBlock`] with [`split_subblocks`]. pub fn new_synchronous( peri: SubBlock<'d, T, S>, - sd: impl Peripheral

> + 'd, - dma: impl Peripheral

> + 'd, + sd: Peri<'d, impl SdPin>, + dma: Peri<'d, impl Channel + Dma>, dma_buf: &'d mut [W], mut config: Config, ) -> Self { update_synchronous_config(&mut config); let peri = peri.peri; - into_ref!(dma, peri, sd); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); sd.set_as_af(sd.af_num(), sd_af_type); @@ -844,7 +839,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { sub_block, None, None, - Some(sd.map_into()), + Some(sd.into()), None, get_ring_buffer::(dma, dma_buf, request, sub_block, config.tx_rx), config, @@ -852,12 +847,12 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { } fn new_inner( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, sub_block: WhichSubBlock, - sck: Option>, - mclk: Option>, - sd: Option>, - fs: Option>, + sck: Option>, + mclk: Option>, + sd: Option>, + fs: Option>, ring_buffer: RingBuffer<'d, W>, config: Config, ) -> Self { @@ -947,7 +942,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { } Self { - _peri: peri.into_ref(), + _peri: peri, sub_block, sck, mclk, @@ -1106,7 +1101,7 @@ impl SubBlockInstance for B {} /// SAI instance trait. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral {} +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {} pin_trait!(SckPin, Instance, SubBlockInstance); pin_trait!(FsPin, Instance, SubBlockInstance); diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index d8671caf7..8f3c45f50 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -8,7 +8,7 @@ use core::ops::{Deref, DerefMut}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::{Peri, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; @@ -21,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt; use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::rcc::{self, RccPeripheral}; use crate::time::Hertz; -use crate::{interrupt, peripherals, Peripheral}; +use crate::{interrupt, peripherals}; /// Interrupt handler. pub struct InterruptHandler { @@ -303,16 +303,16 @@ impl Default for Config { /// Sdmmc device pub struct Sdmmc<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>, - clk: PeripheralRef<'d, AnyPin>, - cmd: PeripheralRef<'d, AnyPin>, - d0: PeripheralRef<'d, AnyPin>, - d1: Option>, - d2: Option>, - d3: Option>, + clk: Peri<'d, AnyPin>, + cmd: Peri<'d, AnyPin>, + d0: Peri<'d, AnyPin>, + d1: Option>, + d2: Option>, + d3: Option>, config: Config, /// Current clock to card @@ -338,16 +338,14 @@ const DATA_AF: AfType = CMD_AF; impl<'d, T: Instance> Sdmmc<'d, T> { /// Create a new SDMMC driver, with 1 data lane. pub fn new_1bit( - sdmmc: impl Peripheral

+ 'd, + sdmmc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - dma: impl Peripheral

> + 'd, - clk: impl Peripheral

> + 'd, - cmd: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, + dma: Peri<'d, impl SdmmcDma>, + clk: Peri<'d, impl CkPin>, + cmd: Peri<'d, impl CmdPin>, + d0: Peri<'d, impl D0Pin>, config: Config, ) -> Self { - into_ref!(dma, clk, cmd, d0); - critical_section::with(|_| { clk.set_as_af(clk.af_num(), CLK_AF); cmd.set_as_af(cmd.af_num(), CMD_AF); @@ -357,9 +355,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> { Self::new_inner( sdmmc, new_dma_nonopt!(dma), - clk.map_into(), - cmd.map_into(), - d0.map_into(), + clk.into(), + cmd.into(), + d0.into(), None, None, None, @@ -369,19 +367,17 @@ impl<'d, T: Instance> Sdmmc<'d, T> { /// Create a new SDMMC driver, with 4 data lanes. pub fn new_4bit( - sdmmc: impl Peripheral

+ 'd, + sdmmc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - dma: impl Peripheral

> + 'd, - clk: impl Peripheral

> + 'd, - cmd: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, + dma: Peri<'d, impl SdmmcDma>, + clk: Peri<'d, impl CkPin>, + cmd: Peri<'d, impl CmdPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, config: Config, ) -> Self { - into_ref!(clk, cmd, d0, d1, d2, d3); - critical_section::with(|_| { clk.set_as_af(clk.af_num(), CLK_AF); cmd.set_as_af(cmd.af_num(), CMD_AF); @@ -394,12 +390,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> { Self::new_inner( sdmmc, new_dma_nonopt!(dma), - clk.map_into(), - cmd.map_into(), - d0.map_into(), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), + clk.into(), + cmd.into(), + d0.into(), + Some(d1.into()), + Some(d2.into()), + Some(d3.into()), config, ) } @@ -409,47 +405,34 @@ impl<'d, T: Instance> Sdmmc<'d, T> { impl<'d, T: Instance> Sdmmc<'d, T> { /// Create a new SDMMC driver, with 1 data lane. pub fn new_1bit( - sdmmc: impl Peripheral

+ 'd, + sdmmc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - clk: impl Peripheral

> + 'd, - cmd: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, + clk: Peri<'d, impl CkPin>, + cmd: Peri<'d, impl CmdPin>, + d0: Peri<'d, impl D0Pin>, config: Config, ) -> Self { - into_ref!(clk, cmd, d0); - critical_section::with(|_| { clk.set_as_af(clk.af_num(), CLK_AF); cmd.set_as_af(cmd.af_num(), CMD_AF); d0.set_as_af(d0.af_num(), DATA_AF); }); - Self::new_inner( - sdmmc, - clk.map_into(), - cmd.map_into(), - d0.map_into(), - None, - None, - None, - config, - ) + Self::new_inner(sdmmc, clk.into(), cmd.into(), d0.into(), None, None, None, config) } /// Create a new SDMMC driver, with 4 data lanes. pub fn new_4bit( - sdmmc: impl Peripheral

+ 'd, + sdmmc: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - clk: impl Peripheral

> + 'd, - cmd: impl Peripheral

> + 'd, - d0: impl Peripheral

> + 'd, - d1: impl Peripheral

> + 'd, - d2: impl Peripheral

> + 'd, - d3: impl Peripheral

> + 'd, + clk: Peri<'d, impl CkPin>, + cmd: Peri<'d, impl CmdPin>, + d0: Peri<'d, impl D0Pin>, + d1: Peri<'d, impl D1Pin>, + d2: Peri<'d, impl D2Pin>, + d3: Peri<'d, impl D3Pin>, config: Config, ) -> Self { - into_ref!(clk, cmd, d0, d1, d2, d3); - critical_section::with(|_| { clk.set_as_af(clk.af_num(), CLK_AF); cmd.set_as_af(cmd.af_num(), CMD_AF); @@ -461,12 +444,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> { Self::new_inner( sdmmc, - clk.map_into(), - cmd.map_into(), - d0.map_into(), - Some(d1.map_into()), - Some(d2.map_into()), - Some(d3.map_into()), + clk.into(), + cmd.into(), + d0.into(), + Some(d1.into()), + Some(d2.into()), + Some(d3.into()), config, ) } @@ -474,18 +457,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> { impl<'d, T: Instance> Sdmmc<'d, T> { fn new_inner( - sdmmc: impl Peripheral

+ 'd, + sdmmc: Peri<'d, T>, #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>, - clk: PeripheralRef<'d, AnyPin>, - cmd: PeripheralRef<'d, AnyPin>, - d0: PeripheralRef<'d, AnyPin>, - d1: Option>, - d2: Option>, - d3: Option>, + clk: Peri<'d, AnyPin>, + cmd: Peri<'d, AnyPin>, + d0: Peri<'d, AnyPin>, + d1: Option>, + d2: Option>, + d3: Option>, config: Config, ) -> Self { - into_ref!(sdmmc); - rcc::enable_and_reset::(); T::Interrupt::unpend(); @@ -1478,7 +1459,7 @@ trait SealedInstance { /// SDMMC instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static { /// Interrupt for this instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/spdifrx/mod.rs b/embassy-stm32/src/spdifrx/mod.rs index a205780ad..08dba04fe 100644 --- a/embassy-stm32/src/spdifrx/mod.rs +++ b/embassy-stm32/src/spdifrx/mod.rs @@ -4,7 +4,6 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use crate::dma::ringbuffer::Error as RingbufferError; @@ -16,7 +15,7 @@ use crate::gpio::{AfType, AnyPin, Pull, SealedPin as _}; use crate::interrupt::typelevel::Interrupt; use crate::pac::spdifrx::Spdifrx as Regs; use crate::rcc::{RccInfo, SealedRccPeripheral}; -use crate::{interrupt, peripherals, Peripheral}; +use crate::{interrupt, peripherals, Peri}; /// Possible S/PDIF preamble types. #[allow(dead_code)] @@ -36,10 +35,10 @@ enum PreambleType { macro_rules! new_spdifrx_pin { ($name:ident, $af_type:expr) => {{ - let pin = $name.into_ref(); + let pin = $name; let input_sel = pin.input_sel(); pin.set_as_af(pin.af_num(), $af_type); - (Some(pin.map_into()), input_sel) + (Some(pin.into()), input_sel) }}; } @@ -61,8 +60,8 @@ macro_rules! impl_spdifrx_pin { /// Data is read by DMAs and stored in a ring buffer. #[cfg(not(gpdma))] pub struct Spdifrx<'d, T: Instance> { - _peri: PeripheralRef<'d, T>, - spdifrx_in: Option>, + _peri: Peri<'d, T>, + spdifrx_in: Option>, data_ring_buffer: ReadableRingBuffer<'d, u32>, } @@ -131,18 +130,16 @@ impl<'d, T: Instance> Spdifrx<'d, T> { /// Create a new `Spdifrx` instance. pub fn new( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, config: Config, - spdifrx_in: impl Peripheral

> + 'd, - data_dma: impl Peripheral

> + 'd, + spdifrx_in: Peri<'d, impl InPin>, + data_dma: Peri<'d, impl Channel + Dma>, data_dma_buf: &'d mut [u32], ) -> Self { let (spdifrx_in, input_sel) = new_spdifrx_pin!(spdifrx_in, AfType::input(Pull::None)); Self::setup(config, input_sel); - into_ref!(peri, data_dma); - let regs = T::info().regs; let dr_request = data_dma.request(); let dr_ring_buffer = diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index a43da1b5a..6578aa1aa 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -6,7 +6,6 @@ use core::ptr; use embassy_embedded_hal::SetConfig; use embassy_futures::join::join; -use embassy_hal_internal::PeripheralRef; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; use crate::dma::{word, ChannelAndRequest}; @@ -15,7 +14,7 @@ use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::spi::{regs, vals, Spi as Regs}; use crate::rcc::{RccInfo, SealedRccPeripheral}; use crate::time::Hertz; -use crate::Peripheral; +use crate::Peri; /// SPI error. #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -130,9 +129,9 @@ impl Config { pub struct Spi<'d, M: PeriMode> { pub(crate) info: &'static Info, kernel_clock: Hertz, - sck: Option>, - mosi: Option>, - miso: Option>, + sck: Option>, + mosi: Option>, + miso: Option>, tx_dma: Option>, rx_dma: Option>, _phantom: PhantomData, @@ -142,10 +141,10 @@ pub struct Spi<'d, M: PeriMode> { impl<'d, M: PeriMode> Spi<'d, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, - sck: Option>, - mosi: Option>, - miso: Option>, + _peri: Peri<'d, T>, + sck: Option>, + mosi: Option>, + miso: Option>, tx_dma: Option>, rx_dma: Option>, config: Config, @@ -465,10 +464,10 @@ impl<'d, M: PeriMode> Spi<'d, M> { impl<'d> Spi<'d, Blocking> { /// Create a new blocking SPI driver. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - mosi: impl Peripheral

> + 'd, - miso: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + mosi: Peri<'d, impl MosiPin>, + miso: Peri<'d, impl MisoPin>, config: Config, ) -> Self { Self::new_inner( @@ -484,9 +483,9 @@ impl<'d> Spi<'d, Blocking> { /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI). pub fn new_blocking_rxonly( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - miso: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + miso: Peri<'d, impl MisoPin>, config: Config, ) -> Self { Self::new_inner( @@ -502,9 +501,9 @@ impl<'d> Spi<'d, Blocking> { /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO). pub fn new_blocking_txonly( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - mosi: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + mosi: Peri<'d, impl MosiPin>, config: Config, ) -> Self { Self::new_inner( @@ -522,8 +521,8 @@ impl<'d> Spi<'d, Blocking> { /// /// This can be useful for bit-banging non-SPI protocols. pub fn new_blocking_txonly_nosck( - peri: impl Peripheral

+ 'd, - mosi: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + mosi: Peri<'d, impl MosiPin>, config: Config, ) -> Self { Self::new_inner( @@ -541,12 +540,12 @@ impl<'d> Spi<'d, Blocking> { impl<'d> Spi<'d, Async> { /// Create a new SPI driver. pub fn new( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - mosi: impl Peripheral

> + 'd, - miso: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + mosi: Peri<'d, impl MosiPin>, + miso: Peri<'d, impl MisoPin>, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Self { Self::new_inner( @@ -562,11 +561,11 @@ impl<'d> Spi<'d, Async> { /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). pub fn new_rxonly( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - miso: impl Peripheral

> + 'd, - #[cfg(any(spi_v1, spi_f1, spi_v2))] tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + miso: Peri<'d, impl MisoPin>, + #[cfg(any(spi_v1, spi_f1, spi_v2))] tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Self { Self::new_inner( @@ -585,10 +584,10 @@ impl<'d> Spi<'d, Async> { /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). pub fn new_txonly( - peri: impl Peripheral

+ 'd, - sck: impl Peripheral

> + 'd, - mosi: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + sck: Peri<'d, impl SckPin>, + mosi: Peri<'d, impl MosiPin>, + tx_dma: Peri<'d, impl TxDma>, config: Config, ) -> Self { Self::new_inner( @@ -606,9 +605,9 @@ impl<'d> Spi<'d, Async> { /// /// This can be useful for bit-banging non-SPI protocols. pub fn new_txonly_nosck( - peri: impl Peripheral

+ 'd, - mosi: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + mosi: Peri<'d, impl MosiPin>, + tx_dma: Peri<'d, impl TxDma>, config: Config, ) -> Self { Self::new_inner( @@ -625,9 +624,9 @@ impl<'d> Spi<'d, Async> { #[cfg(stm32wl)] /// Useful for on chip peripherals like SUBGHZ which are hardwired. pub fn new_subghz( - peri: impl Peripheral

+ 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, ) -> Self { // see RM0453 rev 1 section 7.2.13 page 291 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. @@ -644,7 +643,7 @@ impl<'d> Spi<'d, Async> { #[allow(dead_code)] pub(crate) fn new_internal( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, tx_dma: Option>, rx_dma: Option>, config: Config, diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 02c01e900..f543bafab 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -2,7 +2,6 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; use stm32_metapac::timer::vals::Ckd; use super::low_level::{CountingMode, OutputPolarity, Timer}; @@ -14,13 +13,13 @@ use super::{ use crate::gpio::{AnyPin, OutputType}; use crate::time::Hertz; use crate::timer::low_level::OutputCompareMode; -use crate::Peripheral; +use crate::Peri; /// Complementary PWM pin wrapper. /// /// This wraps a pin to make it usable with PWM. pub struct ComplementaryPwmPin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } @@ -28,8 +27,7 @@ macro_rules! complementary_channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd, output_type: OutputType) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -38,7 +36,7 @@ macro_rules! complementary_channel_impl { ); }); ComplementaryPwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -60,7 +58,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { /// Create a new complementary PWM driver. #[allow(clippy::too_many_arguments)] pub fn new( - tim: impl Peripheral

+ 'd, + tim: Peri<'d, T>, _ch1: Option>, _ch1n: Option>, _ch2: Option>, @@ -75,7 +73,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self { let mut this = Self { inner: Timer::new(tim) }; this.inner.set_counting_mode(counting_mode); diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index b7c13343c..0450f14fa 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -5,8 +5,6 @@ use core::marker::PhantomData; use core::pin::Pin; use core::task::{Context, Poll}; -use embassy_hal_internal::{into_ref, PeripheralRef}; - use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; use super::{ CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, @@ -15,7 +13,7 @@ use super::{ use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::time::Hertz; -use crate::Peripheral; +use crate::Peri; /// Channel 1 marker type. pub enum Ch1 {} @@ -30,7 +28,7 @@ pub enum Ch4 {} /// /// This wraps a pin to make it usable with capture. pub struct CapturePin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } @@ -38,11 +36,10 @@ macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd, pull: Pull) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, pull: Pull) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); CapturePin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -63,7 +60,7 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> { impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { /// Create a new input capture driver. pub fn new( - tim: impl Peripheral

+ 'd, + tim: Peri<'d, T>, _ch1: Option>, _ch2: Option>, _ch3: Option>, @@ -75,7 +72,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self { let mut this = Self { inner: Timer::new(tim) }; this.inner.set_counting_mode(counting_mode); diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 5b0c95109..8fc32c1f3 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs @@ -8,7 +8,7 @@ use core::mem::ManuallyDrop; -use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; // Re-export useful enums pub use stm32_metapac::timer::vals::{FilterValue, Sms as SlaveMode, Ts as TriggerSource}; @@ -181,7 +181,7 @@ impl From for bool { /// Low-level timer driver. pub struct Timer<'d, T: CoreInstance> { - tim: PeripheralRef<'d, T>, + tim: Peri<'d, T>, } impl<'d, T: CoreInstance> Drop for Timer<'d, T> { @@ -192,9 +192,7 @@ impl<'d, T: CoreInstance> Drop for Timer<'d, T> { impl<'d, T: CoreInstance> Timer<'d, T> { /// Create a new timer driver. - pub fn new(tim: impl Peripheral

+ 'd) -> Self { - into_ref!(tim); - + pub fn new(tim: Peri<'d, T>) -> Self { rcc::enable_and_reset::(); Self { tim } diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 97740c2ed..765a3d9fa 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; -use embassy_hal_internal::Peripheral; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; #[cfg(not(stm32l0))] @@ -66,7 +66,7 @@ impl State { } } -trait SealedInstance: RccPeripheral + Peripheral

{ +trait SealedInstance: RccPeripheral + PeripheralType { /// Async state for this timer fn state() -> &'static State; } diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index e3eb6042a..98b798634 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs @@ -1,12 +1,10 @@ //! PWM Input driver. -use embassy_hal_internal::into_ref; - use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; use crate::gpio::{AfType, Pull}; use crate::time::Hertz; -use crate::Peripheral; +use crate::Peri; /// PWM Input driver. pub struct PwmInput<'d, T: GeneralInstance4Channel> { @@ -16,34 +14,20 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> { impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { /// Create a new PWM input driver. - pub fn new( - tim: impl Peripheral

+ 'd, - pin: impl Peripheral

> + 'd, - pull: Pull, - freq: Hertz, - ) -> Self { - into_ref!(pin); - + pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl Channel1Pin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) } /// Create a new PWM input driver. - pub fn new_alt( - tim: impl Peripheral

+ 'd, - pin: impl Peripheral

> + 'd, - pull: Pull, - freq: Hertz, - ) -> Self { - into_ref!(pin); - + pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl Channel2Pin>, pull: Pull, freq: Hertz) -> Self { pin.set_as_af(pin.af_num(), AfType::input(pull)); Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { let mut inner = Timer::new(tim); inner.set_counting_mode(CountingMode::EdgeAlignedUp); diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index fc5835414..bac290f28 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -2,13 +2,12 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, PeripheralRef}; use stm32_metapac::timer::vals; use super::low_level::Timer; use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; use crate::gpio::{AfType, AnyPin, Pull}; -use crate::Peripheral; +use crate::Peri; /// Counting direction pub enum Direction { @@ -25,7 +24,7 @@ pub enum Ch2 {} /// Wrapper for using a pin with QEI. pub struct QeiPin<'d, T, Channel> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, Channel)>, } @@ -33,14 +32,13 @@ macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); }); QeiPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -58,11 +56,11 @@ pub struct Qei<'d, T: GeneralInstance4Channel> { impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { /// Create a new quadrature decoder driver. - pub fn new(tim: impl Peripheral

+ 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { + pub fn new(tim: Peri<'d, T>, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { Self::new_inner(tim) } - fn new_inner(tim: impl Peripheral

+ 'd) -> Self { + fn new_inner(tim: Peri<'d, T>) -> Self { let inner = Timer::new(tim); let r = inner.regs_gp16(); diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index c5a366cd5..54ab7d0d5 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -3,15 +3,13 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; -use embassy_hal_internal::{into_ref, PeripheralRef}; - use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; #[cfg(gpio_v2)] use crate::gpio::Pull; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::time::Hertz; -use crate::Peripheral; +use crate::Peri; /// Channel 1 marker type. pub enum Ch1 {} @@ -26,7 +24,7 @@ pub enum Ch4 {} /// /// This wraps a pin to make it usable with PWM. pub struct PwmPin<'d, T, C> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, phantom: PhantomData<(T, C)>, } @@ -47,24 +45,19 @@ macro_rules! channel_impl { ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] - pub fn $new_chx(pin: impl Peripheral

> + 'd, output_type: OutputType) -> Self { - into_ref!(pin); + pub fn $new_chx(pin: Peri<'d, impl $pin_trait>, output_type: OutputType) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); }); PwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] - pub fn $new_chx_with_config( - pin: impl Peripheral

> + 'd, - pin_config: PwmPinConfig, - ) -> Self { - into_ref!(pin); + pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait>, pin_config: PwmPinConfig) -> Self { critical_section::with(|_| { pin.set_low(); pin.set_as_af( @@ -76,7 +69,7 @@ macro_rules! channel_impl { ); }); PwmPin { - _pin: pin.map_into(), + _pin: pin.into(), phantom: PhantomData, } } @@ -202,7 +195,7 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> { impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// Create a new simple PWM driver. pub fn new( - tim: impl Peripheral

+ 'd, + tim: Peri<'d, T>, _ch1: Option>, _ch2: Option>, _ch3: Option>, @@ -213,7 +206,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { Self::new_inner(tim, freq, counting_mode) } - fn new_inner(tim: impl Peripheral

+ 'd, freq: Hertz, counting_mode: CountingMode) -> Self { + fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self { let mut this = Self { inner: Timer::new(tim) }; this.inner.set_counting_mode(counting_mode); @@ -331,14 +324,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// /// Note: /// you will need to provide corresponding TIMx_UP DMA channel to use this method. - pub async fn waveform_up( - &mut self, - dma: impl Peripheral

>, - channel: Channel, - duty: &[u16], - ) { - into_ref!(dma); - + pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma>, channel: Channel, duty: &[u16]) { #[allow(clippy::let_unit_value)] // eg. stm32f334 let req = dma.request(); @@ -368,7 +354,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { }; Transfer::new_write( - &mut dma, + dma, req, duty, self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16, @@ -399,11 +385,9 @@ macro_rules! impl_waveform_chx { ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { /// Generate a sequence of PWM waveform - pub async fn $fn_name(&mut self, dma: impl Peripheral

>, duty: &[u16]) { + pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch>, duty: &[u16]) { use crate::pac::timer::vals::Ccds; - into_ref!(dma); - #[allow(clippy::let_unit_value)] // eg. stm32f334 let req = dma.request(); @@ -443,7 +427,7 @@ macro_rules! impl_waveform_chx { match self.inner.bits() { TimerBits::Bits16 => { Transfer::new_write( - &mut dma, + dma, req, duty, self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, @@ -458,7 +442,7 @@ macro_rules! impl_waveform_chx { #[cfg(any(bdma, gpdma))] Transfer::new_write( - &mut dma, + dma, req, duty, self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index 0d5c27465..9359d83e9 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -98,6 +98,7 @@ use core::marker::PhantomData; pub use acquisition_banks::*; pub use config::*; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; pub use errors::*; pub use io_pin::*; @@ -106,7 +107,7 @@ pub use tsc::*; pub use types::*; use crate::rcc::RccPeripheral; -use crate::{interrupt, peripherals, Peripheral}; +use crate::{interrupt, peripherals}; #[cfg(tsc_v1)] const TSC_NUM_GROUPS: usize = 6; @@ -142,7 +143,7 @@ pub(crate) trait SealedInstance { /// TSC instance trait #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral { /// Interrupt for this TSC instance type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/tsc/pin_groups.rs b/embassy-stm32/src/tsc/pin_groups.rs index 1f3aafa35..6f914a94e 100644 --- a/embassy-stm32/src/tsc/pin_groups.rs +++ b/embassy-stm32/src/tsc/pin_groups.rs @@ -1,13 +1,11 @@ use core::marker::PhantomData; use core::ops::BitOr; -use embassy_hal_internal::{into_ref, PeripheralRef}; - use super::errors::GroupError; use super::io_pin::*; use super::Instance; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; -use crate::Peripheral; +use crate::Peri; /// Pin type definition to control IO parameters #[derive(PartialEq, Clone, Copy)] @@ -23,7 +21,7 @@ pub enum PinType { /// Pin struct that maintains usage #[allow(missing_docs)] pub struct Pin<'d, T, Group> { - _pin: PeripheralRef<'d, AnyPin>, + _pin: Peri<'d, AnyPin>, role: PinType, tsc_io_pin: IOPin, phantom: PhantomData<(T, Group)>, @@ -426,17 +424,13 @@ macro_rules! trait_to_io_pin { macro_rules! impl_set_io { ($method:ident, $group:ident, $trait:ident, $index:expr) => { #[doc = concat!("Create a new pin1 for ", stringify!($group), " TSC group instance.")] - pub fn $method( - &mut self, - pin: impl Peripheral

> + 'd, - ) -> IOPinWithRole<$group, Role> { - into_ref!(pin); + pub fn $method(&mut self, pin: Peri<'d, impl $trait>) -> IOPinWithRole<$group, Role> { critical_section::with(|_| { pin.set_low(); pin.set_as_af(pin.af_num(), AfType::output(Role::output_type(), Speed::VeryHigh)); let tsc_io_pin = trait_to_io_pin!($trait); let new_pin = Pin { - _pin: pin.map_into(), + _pin: pin.into(), role: Role::pin_type(), tsc_io_pin, phantom: PhantomData, diff --git a/embassy-stm32/src/tsc/tsc.rs b/embassy-stm32/src/tsc/tsc.rs index 17d2da82f..e92479c26 100644 --- a/embassy-stm32/src/tsc/tsc.rs +++ b/embassy-stm32/src/tsc/tsc.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use core::ops::BitOr; use core::task::Poll; -use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_hal_internal::Peri; use super::acquisition_banks::*; use super::config::*; @@ -14,7 +14,7 @@ use super::types::*; use super::{Instance, InterruptHandler, TSC_NUM_GROUPS}; use crate::interrupt::typelevel::Interrupt; use crate::mode::{Async, Blocking, Mode as PeriMode}; -use crate::{interrupt, rcc, Peripheral}; +use crate::{interrupt, rcc}; /// Internal structure holding masks for different types of TSC IOs. /// @@ -31,7 +31,7 @@ struct IOMasks { /// TSC driver pub struct Tsc<'d, T: Instance, K: PeriMode> { - _peri: PeripheralRef<'d, T>, + _peri: Peri<'d, T>, _pin_groups: PinGroups<'d, T>, state: State, config: Config, @@ -218,13 +218,7 @@ impl<'d, T: Instance, K: PeriMode> Tsc<'d, T, K> { groups } - fn new_inner( - peri: impl Peripheral

+ 'd, - pin_groups: PinGroups<'d, T>, - config: Config, - ) -> Result { - into_ref!(peri); - + fn new_inner(peri: Peri<'d, T>, pin_groups: PinGroups<'d, T>, config: Config) -> Result { pin_groups.check()?; let masks = IOMasks { @@ -410,7 +404,7 @@ impl<'d, T: Instance, K: PeriMode> Drop for Tsc<'d, T, K> { impl<'d, T: Instance> Tsc<'d, T, Async> { /// Create a Tsc instance that can be awaited for completion pub fn new_async( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, pin_groups: PinGroups<'d, T>, config: Config, _irq: impl interrupt::typelevel::Binding> + 'd, @@ -441,11 +435,7 @@ impl<'d, T: Instance> Tsc<'d, T, Async> { impl<'d, T: Instance> Tsc<'d, T, Blocking> { /// Create a Tsc instance that must be polled for completion - pub fn new_blocking( - peri: impl Peripheral

+ 'd, - pin_groups: PinGroups<'d, T>, - config: Config, - ) -> Result { + pub fn new_blocking(peri: Peri<'d, T>, pin_groups: PinGroups<'d, T>, config: Config) -> Result { Self::new_inner(peri, pin_groups, config) } diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index c40ee8ad0..87693f148 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs @@ -20,15 +20,15 @@ use core::sync::atomic::{AtomicBool, Ordering}; use core::task::Poll; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::{into_ref, Peripheral}; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use crate::dma::{ChannelAndRequest, TransferOptions}; -use crate::interrupt; use crate::interrupt::typelevel::Interrupt; use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode}; pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, Rxordset, TypecVstateCc as CcVState}; use crate::rcc::{self, RccPeripheral}; +use crate::{interrupt, Peri}; pub(crate) fn init( _cs: critical_section::CriticalSection, @@ -122,13 +122,12 @@ pub struct Ucpd<'d, T: Instance> { impl<'d, T: Instance> Ucpd<'d, T> { /// Creates a new UCPD driver instance. pub fn new( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - cc1: impl Peripheral

> + 'd, - cc2: impl Peripheral

> + 'd, + cc1: Peri<'d, impl Cc1Pin>, + cc2: Peri<'d, impl Cc2Pin>, config: Config, ) -> Self { - into_ref!(cc1, cc2); cc1.set_as_analog(); cc2.set_as_analog(); @@ -208,8 +207,8 @@ impl<'d, T: Instance> Ucpd<'d, T> { /// and a Power Delivery (PD) PHY with receiver and transmitter. pub fn split_pd_phy( self, - rx_dma: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, + rx_dma: Peri<'d, impl RxDma>, + tx_dma: Peri<'d, impl TxDma>, cc_sel: CcSel, ) -> (CcPhy<'d, T>, PdPhy<'d, T>) { let r = T::REGS; @@ -229,7 +228,6 @@ impl<'d, T: Instance> Ucpd<'d, T> { // Both parts must be dropped before the peripheral can be disabled. T::state().drop_not_ready.store(true, Ordering::Relaxed); - into_ref!(rx_dma, tx_dma); let rx_dma_req = rx_dma.request(); let tx_dma_req = tx_dma.request(); ( @@ -237,11 +235,11 @@ impl<'d, T: Instance> Ucpd<'d, T> { PdPhy { _lifetime: PhantomData, rx_dma: ChannelAndRequest { - channel: rx_dma.map_into(), + channel: rx_dma.into(), request: rx_dma_req, }, tx_dma: ChannelAndRequest { - channel: tx_dma.map_into(), + channel: tx_dma.into(), request: tx_dma_req, }, }, @@ -689,7 +687,7 @@ trait SealedInstance { /// UCPD instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral { /// Interrupt for this instance. type Interrupt: crate::interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 7fa9ee08e..b1640b6dc 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -6,7 +6,7 @@ use core::task::Poll; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::atomic_ring_buffer::RingBuffer; -use embassy_hal_internal::{Peripheral, PeripheralRef}; +use embassy_hal_internal::Peri; use embassy_sync::waitqueue::AtomicWaker; #[cfg(not(any(usart_v1, usart_v2)))] @@ -159,9 +159,9 @@ pub struct BufferedUartTx<'d> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - tx: Option>, - cts: Option>, - de: Option>, + tx: Option>, + cts: Option>, + de: Option>, is_borrowed: bool, } @@ -172,8 +172,8 @@ pub struct BufferedUartRx<'d> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - rx: Option>, - rts: Option>, + rx: Option>, + rts: Option>, is_borrowed: bool, } @@ -207,10 +207,10 @@ impl<'d> SetConfig for BufferedUartTx<'d> { impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver pub fn new( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -230,12 +230,12 @@ impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins pub fn new_with_rtscts( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -255,11 +255,11 @@ impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin pub fn new_with_rts_as_de( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + rts: Peri<'d, impl RtsPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -279,11 +279,11 @@ impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver with only the request-to-send pin pub fn new_with_rts( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + rts: Peri<'d, impl RtsPin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -304,11 +304,11 @@ impl<'d> BufferedUart<'d> { /// Create a new bidirectional buffered UART driver with a driver-enable pin #[cfg(not(any(usart_v1, usart_v2)))] pub fn new_with_de( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - de: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + de: Peri<'d, impl DePin>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -339,8 +339,8 @@ impl<'d> BufferedUart<'d> { /// on the line must be managed by software (for instance by using a centralized arbiter). #[doc(alias("HDSEL"))] pub fn new_half_duplex( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], @@ -379,8 +379,8 @@ impl<'d> BufferedUart<'d> { #[cfg(not(any(usart_v1, usart_v2)))] #[doc(alias("HDSEL"))] pub fn new_half_duplex_on_rx( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], @@ -405,12 +405,12 @@ impl<'d> BufferedUart<'d> { } fn new_inner( - _peri: impl Peripheral

+ 'd, - rx: Option>, - tx: Option>, - rts: Option>, - cts: Option>, - de: Option>, + _peri: Peri<'d, T>, + rx: Option>, + tx: Option>, + rts: Option>, + cts: Option>, + de: Option>, tx_buffer: &'d mut [u8], rx_buffer: &'d mut [u8], config: Config, @@ -505,17 +505,17 @@ impl<'d> BufferedUart<'d> { info: self.tx.info, state: self.tx.state, kernel_clock: self.tx.kernel_clock, - tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow), - cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow), - de: self.tx.de.as_mut().map(PeripheralRef::reborrow), + tx: self.tx.tx.as_mut().map(Peri::reborrow), + cts: self.tx.cts.as_mut().map(Peri::reborrow), + de: self.tx.de.as_mut().map(Peri::reborrow), is_borrowed: true, }, BufferedUartRx { info: self.rx.info, state: self.rx.state, kernel_clock: self.rx.kernel_clock, - rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow), - rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow), + rx: self.rx.rx.as_mut().map(Peri::reborrow), + rts: self.rx.rts.as_mut().map(Peri::reborrow), is_borrowed: true, }, ) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 568067360..675e90c7f 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -9,7 +9,7 @@ use core::task::Poll; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::drop::OnDrop; -use embassy_hal_internal::PeripheralRef; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use futures_util::future::{select, Either}; @@ -30,7 +30,7 @@ use crate::pac::usart::Usart as Regs; use crate::pac::usart::{regs, vals}; use crate::rcc::{RccInfo, SealedRccPeripheral}; use crate::time::Hertz; -use crate::Peripheral; +use crate::Peri; /// Interrupt handler. pub struct InterruptHandler { @@ -348,9 +348,9 @@ pub struct UartTx<'d, M: Mode> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - tx: Option>, - cts: Option>, - de: Option>, + tx: Option>, + cts: Option>, + de: Option>, tx_dma: Option>, duplex: Duplex, _phantom: PhantomData, @@ -398,8 +398,8 @@ pub struct UartRx<'d, M: Mode> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - rx: Option>, - rts: Option>, + rx: Option>, + rts: Option>, rx_dma: Option>, detect_previous_overrun: bool, #[cfg(any(usart_v1, usart_v2))] @@ -419,9 +419,9 @@ impl<'d, M: Mode> SetConfig for UartRx<'d, M> { impl<'d> UartTx<'d, Async> { /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. pub fn new( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + tx_dma: Peri<'d, impl TxDma>, config: Config, ) -> Result { Self::new_inner( @@ -435,10 +435,10 @@ impl<'d> UartTx<'d, Async> { /// Create a new tx-only UART with a clear-to-send pin pub fn new_with_cts( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + cts: Peri<'d, impl CtsPin>, + tx_dma: Peri<'d, impl TxDma>, config: Config, ) -> Result { Self::new_inner( @@ -478,8 +478,8 @@ impl<'d> UartTx<'d, Blocking> { /// /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, config: Config, ) -> Result { Self::new_inner( @@ -493,9 +493,9 @@ impl<'d> UartTx<'d, Blocking> { /// Create a new blocking tx-only UART with a clear-to-send pin pub fn new_blocking_with_cts( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, + cts: Peri<'d, impl CtsPin>, config: Config, ) -> Result { Self::new_inner( @@ -510,9 +510,9 @@ impl<'d> UartTx<'d, Blocking> { impl<'d, M: Mode> UartTx<'d, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, - tx: Option>, - cts: Option>, + _peri: Peri<'d, T>, + tx: Option>, + cts: Option>, tx_dma: Option>, config: Config, ) -> Result { @@ -650,10 +650,10 @@ impl<'d> UartRx<'d, Async> { /// /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. pub fn new( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Result { Self::new_inner( @@ -667,11 +667,11 @@ impl<'d> UartRx<'d, Async> { /// Create a new rx-only UART with a request-to-send pin pub fn new_with_rts( - peri: impl Peripheral

+ 'd, + peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Result { Self::new_inner( @@ -908,8 +908,8 @@ impl<'d> UartRx<'d, Blocking> { /// /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, config: Config, ) -> Result { Self::new_inner(peri, new_pin!(rx, AfType::input(config.rx_pull)), None, None, config) @@ -917,9 +917,9 @@ impl<'d> UartRx<'d, Blocking> { /// Create a new rx-only UART with a request-to-send pin pub fn new_blocking_with_rts( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + rts: Peri<'d, impl RtsPin>, config: Config, ) -> Result { Self::new_inner( @@ -934,9 +934,9 @@ impl<'d> UartRx<'d, Blocking> { impl<'d, M: Mode> UartRx<'d, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, - rx: Option>, - rts: Option>, + _peri: Peri<'d, T>, + rx: Option>, + rts: Option>, rx_dma: Option>, config: Config, ) -> Result { @@ -1104,12 +1104,12 @@ fn drop_tx_rx(info: &Info, state: &State) { impl<'d> Uart<'d, Async> { /// Create a new bidirectional UART pub fn new( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Result { Self::new_inner( @@ -1127,14 +1127,14 @@ impl<'d> Uart<'d, Async> { /// Create a new bidirectional UART with request-to-send and clear-to-send pins pub fn new_with_rtscts( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Result { Self::new_inner( @@ -1153,13 +1153,13 @@ impl<'d> Uart<'d, Async> { #[cfg(not(any(usart_v1, usart_v2)))] /// Create a new bidirectional UART with a driver-enable pin pub fn new_with_de( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, - de: impl Peripheral

> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + de: Peri<'d, impl DePin>, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, config: Config, ) -> Result { Self::new_inner( @@ -1188,11 +1188,11 @@ impl<'d> Uart<'d, Async> { /// on the line must be managed by software (for instance by using a centralized arbiter). #[doc(alias("HDSEL"))] pub fn new_half_duplex( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, mut config: Config, readback: HalfDuplexReadback, half_duplex: HalfDuplexConfig, @@ -1228,11 +1228,11 @@ impl<'d> Uart<'d, Async> { #[cfg(not(any(usart_v1, usart_v2)))] #[doc(alias("HDSEL"))] pub fn new_half_duplex_on_rx( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, _irq: impl interrupt::typelevel::Binding> + 'd, - tx_dma: impl Peripheral

> + 'd, - rx_dma: impl Peripheral

> + 'd, + tx_dma: Peri<'d, impl TxDma>, + rx_dma: Peri<'d, impl RxDma>, mut config: Config, readback: HalfDuplexReadback, half_duplex: HalfDuplexConfig, @@ -1277,9 +1277,9 @@ impl<'d> Uart<'d, Async> { impl<'d> Uart<'d, Blocking> { /// Create a new blocking bidirectional UART. pub fn new_blocking( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, config: Config, ) -> Result { Self::new_inner( @@ -1297,11 +1297,11 @@ impl<'d> Uart<'d, Blocking> { /// Create a new bidirectional UART with request-to-send and clear-to-send pins pub fn new_blocking_with_rtscts( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - rts: impl Peripheral

> + 'd, - cts: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + rts: Peri<'d, impl RtsPin>, + cts: Peri<'d, impl CtsPin>, config: Config, ) -> Result { Self::new_inner( @@ -1320,10 +1320,10 @@ impl<'d> Uart<'d, Blocking> { #[cfg(not(any(usart_v1, usart_v2)))] /// Create a new bidirectional UART with a driver-enable pin pub fn new_blocking_with_de( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, - tx: impl Peripheral

> + 'd, - de: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, + tx: Peri<'d, impl TxPin>, + de: Peri<'d, impl DePin>, config: Config, ) -> Result { Self::new_inner( @@ -1351,8 +1351,8 @@ impl<'d> Uart<'d, Blocking> { /// on the line must be managed by software (for instance by using a centralized arbiter). #[doc(alias("HDSEL"))] pub fn new_blocking_half_duplex( - peri: impl Peripheral

+ 'd, - tx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + tx: Peri<'d, impl TxPin>, mut config: Config, readback: HalfDuplexReadback, half_duplex: HalfDuplexConfig, @@ -1388,8 +1388,8 @@ impl<'d> Uart<'d, Blocking> { #[cfg(not(any(usart_v1, usart_v2)))] #[doc(alias("HDSEL"))] pub fn new_blocking_half_duplex_on_rx( - peri: impl Peripheral

+ 'd, - rx: impl Peripheral

> + 'd, + peri: Peri<'d, T>, + rx: Peri<'d, impl RxPin>, mut config: Config, readback: HalfDuplexReadback, half_duplex: HalfDuplexConfig, @@ -1413,12 +1413,12 @@ impl<'d> Uart<'d, Blocking> { impl<'d, M: Mode> Uart<'d, M> { fn new_inner( - _peri: impl Peripheral

+ 'd, - rx: Option>, - tx: Option>, - rts: Option>, - cts: Option>, - de: Option>, + _peri: Peri<'d, T>, + rx: Option>, + tx: Option>, + rts: Option>, + cts: Option>, + de: Option>, tx_dma: Option>, rx_dma: Option>, config: Config, @@ -2050,7 +2050,7 @@ pub(crate) trait SealedInstance: crate::rcc::RccPeripheral { /// USART peripheral instance trait. #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + 'static + Send { +pub trait Instance: SealedInstance + PeripheralType + 'static + Send { /// Interrupt for this peripheral. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index ffd4ee544..600e72582 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -4,7 +4,6 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_internal::PeripheralRef; use embedded_io_async::ReadReady; use futures_util::future::{select, Either}; @@ -18,6 +17,7 @@ use crate::mode::Async; use crate::pac::usart::regs; use crate::time::Hertz; use crate::usart::{Regs, Sr}; +use crate::Peri; /// Rx-only Ring-buffered UART Driver /// @@ -26,8 +26,8 @@ pub struct RingBufferedUartRx<'d> { info: &'static Info, state: &'static State, kernel_clock: Hertz, - rx: Option>, - rts: Option>, + rx: Option>, + rts: Option>, ring_buf: ReadableRingBuffer<'d, u8>, } diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index d3c7978e4..51429b8cc 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, Peripheral}; +use embassy_hal_internal::PeripheralType; use embassy_usb_driver::{EndpointAddress, EndpointAllocError, EndpointType, Event, Unsupported}; use embassy_usb_synopsys_otg::otg_v1::vals::Dspd; use embassy_usb_synopsys_otg::otg_v1::Otg; @@ -11,9 +11,9 @@ use embassy_usb_synopsys_otg::{ }; use crate::gpio::{AfType, OutputType, Speed}; -use crate::interrupt; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; +use crate::{interrupt, Peri}; const MAX_EP_COUNT: usize = 9; @@ -32,8 +32,7 @@ impl interrupt::typelevel::Handler for InterruptHandl macro_rules! config_ulpi_pins { ($($pin:ident),*) => { - into_ref!($($pin),*); - critical_section::with(|_| { + critical_section::with(|_| { $( $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); )* @@ -62,15 +61,13 @@ impl<'d, T: Instance> Driver<'d, T> { /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_fs( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - dp: impl Peripheral

> + 'd, - dm: impl Peripheral

> + 'd, + dp: Peri<'d, impl DpPin>, + dm: Peri<'d, impl DmPin>, ep_out_buffer: &'d mut [u8], config: Config, ) -> Self { - into_ref!(dp, dm); - dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); @@ -100,17 +97,16 @@ impl<'d, T: Instance> Driver<'d, T> { /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_hs( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - _dp: impl Peripheral

> + 'd, - _dm: impl Peripheral

> + 'd, + _dp: Peri<'d, impl DpPin>, + _dm: Peri<'d, impl DmPin>, ep_out_buffer: &'d mut [u8], config: Config, ) -> Self { // For STM32U5 High speed pins need to be left in analog mode #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] { - into_ref!(_dp, _dm); _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); } @@ -139,20 +135,20 @@ impl<'d, T: Instance> Driver<'d, T> { /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_fs_ulpi( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - ulpi_clk: impl Peripheral

> + 'd, - ulpi_dir: impl Peripheral

> + 'd, - ulpi_nxt: impl Peripheral

> + 'd, - ulpi_stp: impl Peripheral

> + 'd, - ulpi_d0: impl Peripheral

> + 'd, - ulpi_d1: impl Peripheral

> + 'd, - ulpi_d2: impl Peripheral

> + 'd, - ulpi_d3: impl Peripheral

> + 'd, - ulpi_d4: impl Peripheral

> + 'd, - ulpi_d5: impl Peripheral

> + 'd, - ulpi_d6: impl Peripheral

> + 'd, - ulpi_d7: impl Peripheral

> + 'd, + ulpi_clk: Peri<'d, impl UlpiClkPin>, + ulpi_dir: Peri<'d, impl UlpiDirPin>, + ulpi_nxt: Peri<'d, impl UlpiNxtPin>, + ulpi_stp: Peri<'d, impl UlpiStpPin>, + ulpi_d0: Peri<'d, impl UlpiD0Pin>, + ulpi_d1: Peri<'d, impl UlpiD1Pin>, + ulpi_d2: Peri<'d, impl UlpiD2Pin>, + ulpi_d3: Peri<'d, impl UlpiD3Pin>, + ulpi_d4: Peri<'d, impl UlpiD4Pin>, + ulpi_d5: Peri<'d, impl UlpiD5Pin>, + ulpi_d6: Peri<'d, impl UlpiD6Pin>, + ulpi_d7: Peri<'d, impl UlpiD7Pin>, ep_out_buffer: &'d mut [u8], config: Config, ) -> Self { @@ -185,20 +181,20 @@ impl<'d, T: Instance> Driver<'d, T> { /// Must be large enough to fit all OUT endpoint max packet sizes. /// Endpoint allocation will fail if it is too small. pub fn new_hs_ulpi( - _peri: impl Peripheral

+ 'd, + _peri: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - ulpi_clk: impl Peripheral

> + 'd, - ulpi_dir: impl Peripheral

> + 'd, - ulpi_nxt: impl Peripheral

> + 'd, - ulpi_stp: impl Peripheral

> + 'd, - ulpi_d0: impl Peripheral

> + 'd, - ulpi_d1: impl Peripheral

> + 'd, - ulpi_d2: impl Peripheral

> + 'd, - ulpi_d3: impl Peripheral

> + 'd, - ulpi_d4: impl Peripheral

> + 'd, - ulpi_d5: impl Peripheral

> + 'd, - ulpi_d6: impl Peripheral

> + 'd, - ulpi_d7: impl Peripheral

> + 'd, + ulpi_clk: Peri<'d, impl UlpiClkPin>, + ulpi_dir: Peri<'d, impl UlpiDirPin>, + ulpi_nxt: Peri<'d, impl UlpiNxtPin>, + ulpi_stp: Peri<'d, impl UlpiStpPin>, + ulpi_d0: Peri<'d, impl UlpiD0Pin>, + ulpi_d1: Peri<'d, impl UlpiD1Pin>, + ulpi_d2: Peri<'d, impl UlpiD2Pin>, + ulpi_d3: Peri<'d, impl UlpiD3Pin>, + ulpi_d4: Peri<'d, impl UlpiD4Pin>, + ulpi_d5: Peri<'d, impl UlpiD5Pin>, + ulpi_d6: Peri<'d, impl UlpiD6Pin>, + ulpi_d7: Peri<'d, impl UlpiD7Pin>, ep_out_buffer: &'d mut [u8], config: Config, ) -> Self { @@ -411,7 +407,7 @@ trait SealedInstance { /// USB instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static { /// Interrupt for this USB instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 6682374d3..0b878915a 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use core::sync::atomic::{AtomicBool, Ordering}; use core::task::Poll; -use embassy_hal_internal::into_ref; +use embassy_hal_internal::PeripheralType; use embassy_sync::waitqueue::AtomicWaker; use embassy_usb_driver as driver; use embassy_usb_driver::{ @@ -16,7 +16,7 @@ use crate::pac::usb::regs; use crate::pac::usb::vals::{EpType, Stat}; use crate::pac::USBRAM; use crate::rcc::RccPeripheral; -use crate::{interrupt, Peripheral}; +use crate::{interrupt, Peri}; /// Interrupt handler. pub struct InterruptHandler { @@ -290,13 +290,12 @@ impl<'d, T: Instance> Driver<'d, T> { /// Create a new USB driver with start-of-frame (SOF) output. #[cfg(not(stm32l1))] pub fn new_with_sof( - _usb: impl Peripheral

+ 'd, + _usb: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - dp: impl Peripheral

> + 'd, - dm: impl Peripheral

> + 'd, - sof: impl Peripheral

> + 'd, + dp: Peri<'d, impl DpPin>, + dm: Peri<'d, impl DmPin>, + sof: Peri<'d, impl SofPin>, ) -> Self { - into_ref!(sof); { use crate::gpio::{AfType, OutputType, Speed}; sof.set_as_af(sof.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); @@ -307,13 +306,11 @@ impl<'d, T: Instance> Driver<'d, T> { /// Create a new USB driver. pub fn new( - _usb: impl Peripheral

+ 'd, + _usb: Peri<'d, T>, _irq: impl interrupt::typelevel::Binding> + 'd, - dp: impl Peripheral

> + 'd, - dm: impl Peripheral

> + 'd, + dp: Peri<'d, impl DpPin>, + dm: Peri<'d, impl DmPin>, ) -> Self { - into_ref!(dp, dm); - super::common_init::(); let regs = T::regs(); @@ -1236,7 +1233,7 @@ trait SealedInstance { /// USB instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance + RccPeripheral + 'static { +pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static { /// Interrupt for this USB instance. type Interrupt: interrupt::typelevel::Interrupt; } diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index ab21c4b6b..fb5c3d930 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs @@ -1,10 +1,11 @@ //! Watchdog Timer (IWDG, WWDG) use core::marker::PhantomData; -use embassy_hal_internal::{into_ref, Peripheral}; +use embassy_hal_internal::PeripheralType; use stm32_metapac::iwdg::vals::{Key, Pr}; use crate::rcc::LSI_FREQ; +use crate::Peri; /// Independent watchdog (IWDG) driver. pub struct IndependentWatchdog<'d, T: Instance> { @@ -29,9 +30,7 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { /// /// [Self] has to be started with [Self::unleash()]. /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval. - pub fn new(_instance: impl Peripheral

+ 'd, timeout_us: u32) -> Self { - into_ref!(_instance); - + pub fn new(_instance: Peri<'d, T>, timeout_us: u32) -> Self { // Find lowest prescaler value, which makes watchdog period longer or equal to timeout. // This iterates from 4 (2^2) to 256 (2^8). let psc_power = unwrap!((2..=8).find(|psc_power| { @@ -86,7 +85,7 @@ trait SealedInstance { /// IWDG instance trait. #[allow(private_bounds)] -pub trait Instance: SealedInstance {} +pub trait Instance: SealedInstance + PeripheralType {} foreach_peripheral!( (iwdg, $inst:ident) => { diff --git a/examples/nrf52840-rtic/src/bin/blinky.rs b/examples/nrf52840-rtic/src/bin/blinky.rs index 5a074ea17..719e22729 100644 --- a/examples/nrf52840-rtic/src/bin/blinky.rs +++ b/examples/nrf52840-rtic/src/bin/blinky.rs @@ -8,7 +8,7 @@ use {defmt_rtt as _, panic_probe as _}; mod app { use defmt::info; use embassy_nrf::gpio::{Level, Output, OutputDrive}; - use embassy_nrf::peripherals; + use embassy_nrf::{peripherals, Peri}; use embassy_time::Timer; #[shared] @@ -28,7 +28,7 @@ mod app { } #[task(priority = 1)] - async fn blink(_cx: blink::Context, pin: peripherals::P0_13) { + async fn blink(_cx: blink::Context, pin: Peri<'static, peripherals::P0_13>) { let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); loop { diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs index 29f70f91c..74c62ca20 100644 --- a/examples/nrf52840/src/bin/channel_sender_receiver.rs +++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs @@ -3,7 +3,8 @@ use defmt::unwrap; use embassy_executor::Spawner; -use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; +use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive}; +use embassy_nrf::Peri; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::channel::{Channel, Receiver, Sender}; use embassy_time::Timer; @@ -28,7 +29,7 @@ async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) { } #[embassy_executor::task] -async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) { +async fn recv_task(led: Peri<'static, AnyPin>, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) { let mut led = Output::new(led, Level::Low, OutputDrive::Standard); loop { @@ -45,5 +46,5 @@ async fn main(spawner: Spawner) { let channel = CHANNEL.init(Channel::new()); unwrap!(spawner.spawn(send_task(channel.sender()))); - unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver()))); + unwrap!(spawner.spawn(recv_task(p.P0_13.into(), channel.receiver()))); } diff --git a/examples/nrf52840/src/bin/pdm_continuous.rs b/examples/nrf52840/src/bin/pdm_continuous.rs index e948203a5..0d76636b0 100644 --- a/examples/nrf52840/src/bin/pdm_continuous.rs +++ b/examples/nrf52840/src/bin/pdm_continuous.rs @@ -20,14 +20,14 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_p: Spawner) { - let mut p = embassy_nrf::init(Default::default()); + let p = embassy_nrf::init(Default::default()); let mut config = Config::default(); // Pins are correct for the onboard microphone on the Feather nRF52840 Sense. config.frequency = Frequency::_1280K; // 16 kHz sample rate config.ratio = Ratio::RATIO80; config.operation_mode = OperationMode::Mono; config.gain_left = I7F1::from_bits(5); // 2.5 dB - let mut pdm = Pdm::new(p.PDM, Irqs, &mut p.P0_00, &mut p.P0_01, config); + let mut pdm = Pdm::new(p.PDM, Irqs, p.P0_00, p.P0_01, config); let mut bufs = [[0; 1024]; 2]; diff --git a/examples/nrf52840/src/bin/qspi_lowpower.rs b/examples/nrf52840/src/bin/qspi_lowpower.rs index 516c9b481..238a0d941 100644 --- a/examples/nrf52840/src/bin/qspi_lowpower.rs +++ b/examples/nrf52840/src/bin/qspi_lowpower.rs @@ -37,14 +37,14 @@ async fn main(_p: Spawner) { }); let mut q = qspi::Qspi::new( - &mut p.QSPI, + p.QSPI.reborrow(), Irqs, - &mut p.P0_19, - &mut p.P0_17, - &mut p.P0_20, - &mut p.P0_21, - &mut p.P0_22, - &mut p.P0_23, + p.P0_19.reborrow(), + p.P0_17.reborrow(), + p.P0_20.reborrow(), + p.P0_21.reborrow(), + p.P0_22.reborrow(), + p.P0_23.reborrow(), config, ); diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs index 653b7d606..cf2d860ab 100644 --- a/examples/nrf52840/src/bin/saadc.rs +++ b/examples/nrf52840/src/bin/saadc.rs @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { async fn main(_p: Spawner) { let mut p = embassy_nrf::init(Default::default()); let config = Config::default(); - let channel_config = ChannelConfig::single_ended(&mut p.P0_02); + let channel_config = ChannelConfig::single_ended(p.P0_02.reborrow()); let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]); loop { diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs index f76fa3570..e8f169c8c 100644 --- a/examples/nrf52840/src/bin/saadc_continuous.rs +++ b/examples/nrf52840/src/bin/saadc_continuous.rs @@ -18,9 +18,9 @@ bind_interrupts!(struct Irqs { async fn main(_p: Spawner) { let mut p = embassy_nrf::init(Default::default()); let config = Config::default(); - let channel_1_config = ChannelConfig::single_ended(&mut p.P0_02); - let channel_2_config = ChannelConfig::single_ended(&mut p.P0_03); - let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04); + let channel_1_config = ChannelConfig::single_ended(p.P0_02.reborrow()); + let channel_2_config = ChannelConfig::single_ended(p.P0_03.reborrow()); + let channel_3_config = ChannelConfig::single_ended(p.P0_04.reborrow()); let mut saadc = Saadc::new( p.SAADC, Irqs, @@ -40,9 +40,9 @@ async fn main(_p: Spawner) { saadc .run_task_sampler( - &mut p.TIMER0, - &mut p.PPI_CH0, - &mut p.PPI_CH1, + p.TIMER0.reborrow(), + p.PPI_CH0.reborrow(), + p.PPI_CH1.reborrow(), Frequency::F1MHz, 1000, // We want to sample at 1KHz &mut bufs, diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs index e2efbdd8d..8a6f958eb 100644 --- a/examples/nrf52840/src/bin/twim_lowpower.rs +++ b/examples/nrf52840/src/bin/twim_lowpower.rs @@ -32,7 +32,13 @@ async fn main(_p: Spawner) { let config = twim::Config::default(); // Create the TWIM instance with borrowed singletons, so they're not consumed. - let mut twi = Twim::new(&mut p.TWISPI0, Irqs, &mut p.P0_03, &mut p.P0_04, config); + let mut twi = Twim::new( + p.TWISPI0.reborrow(), + Irqs, + p.P0_03.reborrow(), + p.P0_04.reborrow(), + config, + ); info!("Reading..."); diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs index 35900cdd8..2ba964b1f 100644 --- a/examples/nrf9160/src/bin/modem_tcp_client.rs +++ b/examples/nrf9160/src/bin/modem_tcp_client.rs @@ -13,9 +13,9 @@ use embassy_net::{Ipv4Cidr, Stack, StackResources}; use embassy_net_nrf91::context::Status; use embassy_net_nrf91::{context, Runner, State, TraceBuffer, TraceReader}; use embassy_nrf::buffered_uarte::{self, BufferedUarteTx}; -use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; +use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive}; use embassy_nrf::uarte::Baudrate; -use embassy_nrf::{bind_interrupts, interrupt, peripherals, uarte}; +use embassy_nrf::{bind_interrupts, interrupt, peripherals, uarte, Peri}; use embassy_time::{Duration, Timer}; use embedded_io_async::Write; use heapless::Vec; @@ -91,7 +91,7 @@ fn status_to_config(status: &Status) -> embassy_net::ConfigV4 { } #[embassy_executor::task] -async fn blink_task(pin: AnyPin) { +async fn blink_task(pin: Peri<'static, AnyPin>) { let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); loop { led.set_high(); @@ -112,7 +112,7 @@ async fn main(spawner: Spawner) { info!("Hello World!"); - unwrap!(spawner.spawn(blink_task(p.P0_02.degrade()))); + unwrap!(spawner.spawn(blink_task(p.P0_02.into()))); let ipc_mem = unsafe { let ipc_start = &__start_ipc as *const u8 as *mut MaybeUninit; diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index cde804a15..4fc1d35d6 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -30,7 +30,7 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] } serde-json-core = "0.5.1" # for assign resources example -assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" } +assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "bd22cb7a92031fb16f74a5da42469d466c33383e" } #cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m = { version = "0.7.6", features = ["inline-asm"] } diff --git a/examples/rp/src/bin/adc_dma.rs b/examples/rp/src/bin/adc_dma.rs index f755cf5bf..b42c13fde 100644 --- a/examples/rp/src/bin/adc_dma.rs +++ b/examples/rp/src/bin/adc_dma.rs @@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) { // Read 100 samples from a single channel let mut buf = [0_u16; BLOCK_SIZE]; let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1) - adc.read_many(&mut pin, &mut buf, div, &mut dma).await.unwrap(); + adc.read_many(&mut pin, &mut buf, div, dma.reborrow()).await.unwrap(); info!("single: {:?} ...etc", buf[..8]); // Read 100 samples from 4 channels interleaved let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }]; let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1) - adc.read_many_multichannel(&mut pins, &mut buf, div, &mut dma) + adc.read_many_multichannel(&mut pins, &mut buf, div, dma.reborrow()) .await .unwrap(); info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]); diff --git a/examples/rp/src/bin/assign_resources.rs b/examples/rp/src/bin/assign_resources.rs index ff6eff4a2..341f54d22 100644 --- a/examples/rp/src/bin/assign_resources.rs +++ b/examples/rp/src/bin/assign_resources.rs @@ -16,6 +16,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::{self, PIN_20, PIN_21}; +use embassy_rp::Peri; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -38,7 +39,11 @@ async fn main(spawner: Spawner) { // 1) Assigning a resource to a task by passing parts of the peripherals. #[embassy_executor::task] -async fn double_blinky_manually_assigned(_spawner: Spawner, pin_20: PIN_20, pin_21: PIN_21) { +async fn double_blinky_manually_assigned( + _spawner: Spawner, + pin_20: Peri<'static, PIN_20>, + pin_21: Peri<'static, PIN_21>, +) { let mut led_20 = Output::new(pin_20, Level::Low); let mut led_21 = Output::new(pin_21, Level::High); diff --git a/examples/rp/src/bin/blinky_two_channels.rs b/examples/rp/src/bin/blinky_two_channels.rs index b2eec2a21..51e139e94 100644 --- a/examples/rp/src/bin/blinky_two_channels.rs +++ b/examples/rp/src/bin/blinky_two_channels.rs @@ -11,7 +11,7 @@ use embassy_rp::gpio; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::{Channel, Sender}; use embassy_time::{Duration, Ticker}; -use gpio::{AnyPin, Level, Output}; +use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; enum LedState { @@ -22,7 +22,7 @@ static CHANNEL: Channel = Channel::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_rp::init(Default::default()); - let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High); + let mut led = Output::new(p.PIN_25, Level::High); let dt = 100 * 1_000_000; let k = 1.003; diff --git a/examples/rp/src/bin/blinky_two_tasks.rs b/examples/rp/src/bin/blinky_two_tasks.rs index a57b513d6..67a9108c0 100644 --- a/examples/rp/src/bin/blinky_two_tasks.rs +++ b/examples/rp/src/bin/blinky_two_tasks.rs @@ -11,7 +11,7 @@ use embassy_rp::gpio; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::mutex::Mutex; use embassy_time::{Duration, Ticker}; -use gpio::{AnyPin, Level, Output}; +use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; type LedType = Mutex>>; @@ -21,7 +21,7 @@ static LED: LedType = Mutex::new(None); async fn main(spawner: Spawner) { let p = embassy_rp::init(Default::default()); // set the content of the global LED reference to the real LED pin - let led = Output::new(AnyPin::from(p.PIN_25), Level::High); + let led = Output::new(p.PIN_25, Level::High); // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the // Mutex is released { diff --git a/examples/rp/src/bin/orchestrate_tasks.rs b/examples/rp/src/bin/orchestrate_tasks.rs index 7ff004860..5e2775793 100644 --- a/examples/rp/src/bin/orchestrate_tasks.rs +++ b/examples/rp/src/bin/orchestrate_tasks.rs @@ -24,7 +24,7 @@ use embassy_futures::select::{select, Either}; use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; use embassy_rp::clocks::RoscRng; use embassy_rp::gpio::{Input, Pull}; -use embassy_rp::{bind_interrupts, peripherals}; +use embassy_rp::{bind_interrupts, peripherals, Peri}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::Mutex; use embassy_sync::{channel, signal}; diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 08c702347..bf6dbee69 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -4,10 +4,10 @@ #![no_main] use defmt::info; use embassy_executor::Spawner; -use embassy_rp::bind_interrupts; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; +use embassy_rp::{bind_interrupts, Peri}; use fixed::traits::ToFixed; use fixed_macro::types::U56F8; use {defmt_rtt as _, panic_probe as _}; @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { PIO0_IRQ_0 => InterruptHandler; }); -fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { +fn setup_pio_task_sm0<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 0>, pin: Peri<'d, impl PioPin>) { // Setup sm0 // Send data serially to pin @@ -50,7 +50,7 @@ async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) { } } -fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 1>) { +fn setup_pio_task_sm1<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 1>) { // Setupm sm1 // Read 0b10101 repeatedly until ISR is full @@ -80,7 +80,7 @@ async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) { } } -fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 2>) { +fn setup_pio_task_sm2<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 2>) { // Setup sm2 // Repeatedly trigger IRQ 3 diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index da6e47a1b..64d603ba4 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs @@ -5,10 +5,10 @@ use defmt::info; use embassy_executor::Spawner; use embassy_futures::join::join; +use embassy_rp::bind_interrupts; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; -use embassy_rp::{bind_interrupts, Peripheral}; use fixed::traits::ToFixed; use fixed_macro::types::U56F8; use {defmt_rtt as _, panic_probe as _}; @@ -62,8 +62,8 @@ async fn main(_spawner: Spawner) { sm.set_config(&cfg); sm.set_enable(true); - let mut dma_out_ref = p.DMA_CH0.into_ref(); - let mut dma_in_ref = p.DMA_CH1.into_ref(); + let mut dma_out_ref = p.DMA_CH0; + let mut dma_in_ref = p.DMA_CH1; let mut dout = [0x12345678u32; 29]; for i in 1..dout.len() { dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7; diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs index 447100ddf..192c8f854 100644 --- a/examples/rp/src/bin/pio_i2s.rs +++ b/examples/rp/src/bin/pio_i2s.rs @@ -14,6 +14,7 @@ use core::mem; use embassy_executor::Spawner; use embassy_rp::bind_interrupts; +use embassy_rp::bootsel::is_bootsel_pressed; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::{InterruptHandler, Pio}; use embassy_rp::pio_programs::i2s::{PioI2sOut, PioI2sOutProgram}; @@ -70,7 +71,11 @@ async fn main(_spawner: Spawner) { let dma_future = i2s.write(front_buffer); // fade in audio when bootsel is pressed - let fade_target = if p.BOOTSEL.is_pressed() { i32::MAX } else { 0 }; + let fade_target = if is_bootsel_pressed(p.BOOTSEL.reborrow()) { + i32::MAX + } else { + 0 + }; // fill back buffer with fresh audio samples before awaiting the dma future for s in back_buffer.iter_mut() { diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs index 2f5f94870..04374323d 100644 --- a/examples/rp/src/bin/pwm.rs +++ b/examples/rp/src/bin/pwm.rs @@ -11,6 +11,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4}; use embassy_rp::pwm::{Config, Pwm, SetDutyCycle}; +use embassy_rp::Peri; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -26,7 +27,7 @@ async fn main(spawner: Spawner) { /// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant) /// you must use another slice & pin and an appropriate resistor. #[embassy_executor::task] -async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { +async fn pwm_set_config(slice4: Peri<'static, PWM_SLICE4>, pin25: Peri<'static, PIN_25>) { let mut c = Config::default(); c.top = 32_768; c.compare_b = 8; @@ -44,7 +45,7 @@ async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { /// /// Using GP4 in Slice2, make sure to use an appropriate resistor. #[embassy_executor::task] -async fn pwm_set_dutycycle(slice2: PWM_SLICE2, pin4: PIN_4) { +async fn pwm_set_dutycycle(slice2: Peri<'static, PWM_SLICE2>, pin4: Peri<'static, PIN_4>) { // If we aim for a specific frequency, here is how we can calculate the top value. // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0. // Every such wraparound is one PWM cycle. So here is how we get 25KHz: diff --git a/examples/rp/src/bin/shared_bus.rs b/examples/rp/src/bin/shared_bus.rs index c6cb5d64c..9267dfccb 100644 --- a/examples/rp/src/bin/shared_bus.rs +++ b/examples/rp/src/bin/shared_bus.rs @@ -8,7 +8,7 @@ use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice; use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice; use embassy_executor::Spawner; use embassy_rp::bind_interrupts; -use embassy_rp::gpio::{AnyPin, Level, Output}; +use embassy_rp::gpio::{Level, Output}; use embassy_rp::i2c::{self, I2c, InterruptHandler}; use embassy_rp::peripherals::{I2C1, SPI1}; use embassy_rp::spi::{self, Spi}; @@ -45,8 +45,8 @@ async fn main(spawner: Spawner) { let spi_bus = SPI_BUS.init(Mutex::new(spi)); // Chip select pins for the SPI devices - let cs_a = Output::new(AnyPin::from(p.PIN_0), Level::High); - let cs_b = Output::new(AnyPin::from(p.PIN_1), Level::High); + let cs_a = Output::new(p.PIN_0, Level::High); + let cs_b = Output::new(p.PIN_1, Level::High); spawner.must_spawn(spi_task_a(spi_bus, cs_a)); spawner.must_spawn(spi_task_b(spi_bus, cs_b)); diff --git a/examples/rp/src/bin/zerocopy.rs b/examples/rp/src/bin/zerocopy.rs index 39f03c8e4..d1fb0eb00 100644 --- a/examples/rp/src/bin/zerocopy.rs +++ b/examples/rp/src/bin/zerocopy.rs @@ -9,9 +9,9 @@ use core::sync::atomic::{AtomicU16, Ordering}; use defmt::*; use embassy_executor::Spawner; use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler}; -use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; use embassy_rp::peripherals::DMA_CH0; +use embassy_rp::{bind_interrupts, Peri}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender}; use embassy_time::{Duration, Ticker, Timer}; @@ -31,7 +31,7 @@ static MAX: AtomicU16 = AtomicU16::new(0); struct AdcParts { adc: Adc<'static, Async>, pin: adc::Channel<'static>, - dma: DMA_CH0, + dma: Peri<'static, DMA_CH0>, } #[embassy_executor::main] @@ -70,7 +70,10 @@ async fn producer(mut sender: Sender<'static, NoopRawMutex, SampleBuffer>, mut a let buf = sender.send().await; // Fill it with data - adc.adc.read_many(&mut adc.pin, buf, 1, &mut adc.dma).await.unwrap(); + adc.adc + .read_many(&mut adc.pin, buf, 1, adc.dma.reborrow()) + .await + .unwrap(); // Notify the channel that the buffer is now ready to be received sender.send_done(); diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml index 4e9c93e7c..c9e0ee120 100644 --- a/examples/rp235x/Cargo.toml +++ b/examples/rp235x/Cargo.toml @@ -28,7 +28,7 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] } serde-json-core = "0.5.1" # for assign resources example -assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" } +assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "bd22cb7a92031fb16f74a5da42469d466c33383e" } # for TB6612FNG example tb6612fng = "1.0.0" diff --git a/examples/rp235x/src/bin/adc_dma.rs b/examples/rp235x/src/bin/adc_dma.rs index f755cf5bf..b42c13fde 100644 --- a/examples/rp235x/src/bin/adc_dma.rs +++ b/examples/rp235x/src/bin/adc_dma.rs @@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) { // Read 100 samples from a single channel let mut buf = [0_u16; BLOCK_SIZE]; let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1) - adc.read_many(&mut pin, &mut buf, div, &mut dma).await.unwrap(); + adc.read_many(&mut pin, &mut buf, div, dma.reborrow()).await.unwrap(); info!("single: {:?} ...etc", buf[..8]); // Read 100 samples from 4 channels interleaved let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }]; let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1) - adc.read_many_multichannel(&mut pins, &mut buf, div, &mut dma) + adc.read_many_multichannel(&mut pins, &mut buf, div, dma.reborrow()) .await .unwrap(); info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]); diff --git a/examples/rp235x/src/bin/assign_resources.rs b/examples/rp235x/src/bin/assign_resources.rs index ff6eff4a2..341f54d22 100644 --- a/examples/rp235x/src/bin/assign_resources.rs +++ b/examples/rp235x/src/bin/assign_resources.rs @@ -16,6 +16,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::{self, PIN_20, PIN_21}; +use embassy_rp::Peri; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -38,7 +39,11 @@ async fn main(spawner: Spawner) { // 1) Assigning a resource to a task by passing parts of the peripherals. #[embassy_executor::task] -async fn double_blinky_manually_assigned(_spawner: Spawner, pin_20: PIN_20, pin_21: PIN_21) { +async fn double_blinky_manually_assigned( + _spawner: Spawner, + pin_20: Peri<'static, PIN_20>, + pin_21: Peri<'static, PIN_21>, +) { let mut led_20 = Output::new(pin_20, Level::Low); let mut led_21 = Output::new(pin_21, Level::High); diff --git a/examples/rp235x/src/bin/blinky_two_channels.rs b/examples/rp235x/src/bin/blinky_two_channels.rs index b2eec2a21..51e139e94 100644 --- a/examples/rp235x/src/bin/blinky_two_channels.rs +++ b/examples/rp235x/src/bin/blinky_two_channels.rs @@ -11,7 +11,7 @@ use embassy_rp::gpio; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::channel::{Channel, Sender}; use embassy_time::{Duration, Ticker}; -use gpio::{AnyPin, Level, Output}; +use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; enum LedState { @@ -22,7 +22,7 @@ static CHANNEL: Channel = Channel::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_rp::init(Default::default()); - let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High); + let mut led = Output::new(p.PIN_25, Level::High); let dt = 100 * 1_000_000; let k = 1.003; diff --git a/examples/rp235x/src/bin/blinky_two_tasks.rs b/examples/rp235x/src/bin/blinky_two_tasks.rs index a57b513d6..67a9108c0 100644 --- a/examples/rp235x/src/bin/blinky_two_tasks.rs +++ b/examples/rp235x/src/bin/blinky_two_tasks.rs @@ -11,7 +11,7 @@ use embassy_rp::gpio; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::mutex::Mutex; use embassy_time::{Duration, Ticker}; -use gpio::{AnyPin, Level, Output}; +use gpio::{Level, Output}; use {defmt_rtt as _, panic_probe as _}; type LedType = Mutex>>; @@ -21,7 +21,7 @@ static LED: LedType = Mutex::new(None); async fn main(spawner: Spawner) { let p = embassy_rp::init(Default::default()); // set the content of the global LED reference to the real LED pin - let led = Output::new(AnyPin::from(p.PIN_25), Level::High); + let led = Output::new(p.PIN_25, Level::High); // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the // Mutex is released { diff --git a/examples/rp235x/src/bin/pio_async.rs b/examples/rp235x/src/bin/pio_async.rs index 08c702347..baf567b58 100644 --- a/examples/rp235x/src/bin/pio_async.rs +++ b/examples/rp235x/src/bin/pio_async.rs @@ -4,10 +4,10 @@ #![no_main] use defmt::info; use embassy_executor::Spawner; -use embassy_rp::bind_interrupts; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; +use embassy_rp::{bind_interrupts, Peri}; use fixed::traits::ToFixed; use fixed_macro::types::U56F8; use {defmt_rtt as _, panic_probe as _}; @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { PIO0_IRQ_0 => InterruptHandler; }); -fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { +fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: Peri<'a, impl PioPin>) { // Setup sm0 // Send data serially to pin diff --git a/examples/rp235x/src/bin/pio_dma.rs b/examples/rp235x/src/bin/pio_dma.rs index da6e47a1b..64d603ba4 100644 --- a/examples/rp235x/src/bin/pio_dma.rs +++ b/examples/rp235x/src/bin/pio_dma.rs @@ -5,10 +5,10 @@ use defmt::info; use embassy_executor::Spawner; use embassy_futures::join::join; +use embassy_rp::bind_interrupts; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::program::pio_asm; use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; -use embassy_rp::{bind_interrupts, Peripheral}; use fixed::traits::ToFixed; use fixed_macro::types::U56F8; use {defmt_rtt as _, panic_probe as _}; @@ -62,8 +62,8 @@ async fn main(_spawner: Spawner) { sm.set_config(&cfg); sm.set_enable(true); - let mut dma_out_ref = p.DMA_CH0.into_ref(); - let mut dma_in_ref = p.DMA_CH1.into_ref(); + let mut dma_out_ref = p.DMA_CH0; + let mut dma_in_ref = p.DMA_CH1; let mut dout = [0x12345678u32; 29]; for i in 1..dout.len() { dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7; diff --git a/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs index 0216c131b..ccc601661 100644 --- a/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs +++ b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs @@ -9,7 +9,7 @@ use embassy_executor::Spawner; use embassy_rp::gpio::Pull; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::program::pio_asm; -use embassy_rp::{bind_interrupts, pio}; +use embassy_rp::{bind_interrupts, pio, Peri}; use embassy_time::Timer; use fixed::traits::ToFixed; use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine}; @@ -37,8 +37,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { pub fn new( pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, - pin_a: impl PioPin, - pin_b: impl PioPin, + pin_a: Peri<'d, impl PioPin>, + pin_b: Peri<'d, impl PioPin>, ) -> Self { let mut pin_a = pio.make_pio_pin(pin_a); let mut pin_b = pio.make_pio_pin(pin_b); diff --git a/examples/rp235x/src/bin/pwm.rs b/examples/rp235x/src/bin/pwm.rs index a3c0f7e49..da1acc18a 100644 --- a/examples/rp235x/src/bin/pwm.rs +++ b/examples/rp235x/src/bin/pwm.rs @@ -11,6 +11,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4}; use embassy_rp::pwm::{Config, Pwm, SetDutyCycle}; +use embassy_rp::Peri; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -26,7 +27,7 @@ async fn main(spawner: Spawner) { /// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant) /// you must use another slice & pin and an appropriate resistor. #[embassy_executor::task] -async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { +async fn pwm_set_config(slice4: Peri<'static, PWM_SLICE4>, pin25: Peri<'static, PIN_25>) { let mut c = Config::default(); c.top = 32_768; c.compare_b = 8; @@ -44,7 +45,7 @@ async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { /// /// Using GP4 in Slice2, make sure to use an appropriate resistor. #[embassy_executor::task] -async fn pwm_set_dutycycle(slice2: PWM_SLICE2, pin4: PIN_4) { +async fn pwm_set_dutycycle(slice2: Peri<'static, PWM_SLICE2>, pin4: Peri<'static, PIN_4>) { // If we aim for a specific frequency, here is how we can calculate the top value. // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0. // Every such wraparound is one PWM cycle. So here is how we get 25KHz: diff --git a/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs b/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs index 3b700884c..2cfb2038d 100644 --- a/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs +++ b/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs @@ -10,7 +10,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::config::Config; use embassy_rp::gpio::Output; -use embassy_rp::{gpio, peripherals, pwm}; +use embassy_rp::{gpio, peripherals, pwm, Peri}; use embassy_time::{Duration, Timer}; use tb6612fng::{DriveCommand, Motor, Tb6612fng}; use {defmt_rtt as _, panic_probe as _}; diff --git a/examples/rp235x/src/bin/shared_bus.rs b/examples/rp235x/src/bin/shared_bus.rs index c6cb5d64c..9267dfccb 100644 --- a/examples/rp235x/src/bin/shared_bus.rs +++ b/examples/rp235x/src/bin/shared_bus.rs @@ -8,7 +8,7 @@ use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice; use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice; use embassy_executor::Spawner; use embassy_rp::bind_interrupts; -use embassy_rp::gpio::{AnyPin, Level, Output}; +use embassy_rp::gpio::{Level, Output}; use embassy_rp::i2c::{self, I2c, InterruptHandler}; use embassy_rp::peripherals::{I2C1, SPI1}; use embassy_rp::spi::{self, Spi}; @@ -45,8 +45,8 @@ async fn main(spawner: Spawner) { let spi_bus = SPI_BUS.init(Mutex::new(spi)); // Chip select pins for the SPI devices - let cs_a = Output::new(AnyPin::from(p.PIN_0), Level::High); - let cs_b = Output::new(AnyPin::from(p.PIN_1), Level::High); + let cs_a = Output::new(p.PIN_0, Level::High); + let cs_b = Output::new(p.PIN_1, Level::High); spawner.must_spawn(spi_task_a(spi_bus, cs_a)); spawner.must_spawn(spi_task_b(spi_bus, cs_b)); diff --git a/examples/rp235x/src/bin/zerocopy.rs b/examples/rp235x/src/bin/zerocopy.rs index 39f03c8e4..d1fb0eb00 100644 --- a/examples/rp235x/src/bin/zerocopy.rs +++ b/examples/rp235x/src/bin/zerocopy.rs @@ -9,9 +9,9 @@ use core::sync::atomic::{AtomicU16, Ordering}; use defmt::*; use embassy_executor::Spawner; use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler}; -use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; use embassy_rp::peripherals::DMA_CH0; +use embassy_rp::{bind_interrupts, Peri}; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender}; use embassy_time::{Duration, Ticker, Timer}; @@ -31,7 +31,7 @@ static MAX: AtomicU16 = AtomicU16::new(0); struct AdcParts { adc: Adc<'static, Async>, pin: adc::Channel<'static>, - dma: DMA_CH0, + dma: Peri<'static, DMA_CH0>, } #[embassy_executor::main] @@ -70,7 +70,10 @@ async fn producer(mut sender: Sender<'static, NoopRawMutex, SampleBuffer>, mut a let buf = sender.send().await; // Fill it with data - adc.adc.read_many(&mut adc.pin, buf, 1, &mut adc.dma).await.unwrap(); + adc.adc + .read_many(&mut adc.pin, buf, 1, adc.dma.reborrow()) + .await + .unwrap(); // Notify the channel that the buffer is now ready to be received sender.send_done(); diff --git a/examples/stm32c0/src/bin/adc.rs b/examples/stm32c0/src/bin/adc.rs index 10481f4d2..1f54b0b18 100644 --- a/examples/stm32c0/src/bin/adc.rs +++ b/examples/stm32c0/src/bin/adc.rs @@ -36,7 +36,8 @@ async fn main(_spawner: Spawner) { ); let channels_seqence: [&mut AnyAdcChannel; 3] = [&mut vref, &mut temp, &mut pin0]; - adc.read(&mut dma, channels_seqence.into_iter(), &mut read_buffer).await; + adc.read(dma.reborrow(), channels_seqence.into_iter(), &mut read_buffer) + .await; // Values are ordered according to hardware ADC channel number! info!( "DMA ADC read in set: vref = {}, temp = {}, pin0 = {}.", @@ -45,7 +46,7 @@ async fn main(_spawner: Spawner) { let hw_channel_selection: u32 = (1 << temp.get_hw_channel()) + (1 << vref.get_hw_channel()) + (1 << pin0.get_hw_channel()); - adc.read_in_hw_order(&mut dma, hw_channel_selection, Scandir::UP, &mut read_buffer) + adc.read_in_hw_order(dma.reborrow(), hw_channel_selection, Scandir::UP, &mut read_buffer) .await; info!( "DMA ADC read in hardware order: vref = {}, temp = {}, pin0 = {}.", diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index 4465483d9..744df3e3b 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs @@ -8,14 +8,15 @@ use core::sync::atomic::{AtomicU32, Ordering}; use defmt::info; use embassy_executor::Spawner; use embassy_stm32::exti::ExtiInput; -use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Pull, Speed}; +use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed}; +use embassy_stm32::Peri; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; static BLINK_MS: AtomicU32 = AtomicU32::new(0); #[embassy_executor::task] -async fn led_task(led: AnyPin) { +async fn led_task(led: Peri<'static, AnyPin>) { // Configure the LED pin as a push pull output and obtain handler. // On the Nucleo F091RC there's an on-board LED connected to pin PA5. let mut led = Output::new(led, Level::Low, Speed::Low); @@ -45,7 +46,7 @@ async fn main(spawner: Spawner) { BLINK_MS.store(del_var, Ordering::Relaxed); // Spawn LED blinking task - spawner.spawn(led_task(p.PA5.degrade())).unwrap(); + spawner.spawn(led_task(p.PA5.into())).unwrap(); loop { // Check if button got pressed diff --git a/examples/stm32f1/src/bin/input_capture.rs b/examples/stm32f1/src/bin/input_capture.rs index 5e2dab9e6..6fe8e0b50 100644 --- a/examples/stm32f1/src/bin/input_capture.rs +++ b/examples/stm32f1/src/bin/input_capture.rs @@ -7,14 +7,14 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed}; use embassy_stm32::time::khz; use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; use embassy_stm32::timer::{self, Channel}; -use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_stm32::{bind_interrupts, peripherals, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Connect PA2 and PC13 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PC13) { +async fn blinky(led: Peri<'static, peripherals::PC13>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32f1/src/bin/pwm_input.rs b/examples/stm32f1/src/bin/pwm_input.rs index f74853d4e..afbef3edb 100644 --- a/examples/stm32f1/src/bin/pwm_input.rs +++ b/examples/stm32f1/src/bin/pwm_input.rs @@ -6,14 +6,14 @@ use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; use embassy_stm32::time::khz; use embassy_stm32::timer::pwm_input::PwmInput; -use embassy_stm32::{bind_interrupts, peripherals, timer}; +use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Connect PA0 and PC13 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PC13) { +async fn blinky(led: Peri<'static, peripherals::PC13>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index ee99acf41..77ec307b9 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { // Pull the D+ pin down to send a RESET condition to the USB bus. // This forced reset is needed only for development, without it host // will not reset your device when you upload new firmware. - let _dp = Output::new(&mut p.PA12, Level::Low, Speed::Low); + let _dp = Output::new(p.PA12.reborrow(), Level::Low, Speed::Low); Timer::after_millis(10).await; } diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 2dbf1bdab..b30445ead 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs @@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) -> ! { let mut vrefint = adc.enable_vref(); let mut temperature = adc.enable_temperature(); - let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); + let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow(), OpAmpGain::Mul1); loop { let vref = adc.read(&mut vrefint).await; diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs index 8e3beee24..fd90e0d6d 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { // To synchronise to the bus the RX input needs to see a high level. // Use `mem::forget()` to release the borrow on the pin but keep the // pull-up resistor enabled. - let rx_pin = Input::new(&mut p.PA11, Pull::Up); + let rx_pin = Input::new(p.PA11.reborrow(), Pull::Up); core::mem::forget(rx_pin); let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs); diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs index 493a536f3..755713542 100644 --- a/examples/stm32f4/src/bin/flash_async.rs +++ b/examples/stm32f4/src/bin/flash_async.rs @@ -3,9 +3,9 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::bind_interrupts; use embassy_stm32::flash::{Flash, InterruptHandler}; -use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Speed}; +use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; +use embassy_stm32::{bind_interrupts, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -21,14 +21,14 @@ async fn main(spawner: Spawner) { let mut f = Flash::new(p.FLASH, Irqs); // Led should blink uninterrupted during ~2sec erase operation - spawner.spawn(blinky(p.PB7.degrade())).unwrap(); + spawner.spawn(blinky(p.PB7.into())).unwrap(); // Test on bank 2 in order not to stall CPU. test_flash(&mut f, 1024 * 1024, 128 * 1024).await; } #[embassy_executor::task] -async fn blinky(p: AnyPin) { +async fn blinky(p: Peri<'static, AnyPin>) { let mut led = Output::new(p, Level::High, Speed::Low); loop { diff --git a/examples/stm32f4/src/bin/input_capture.rs b/examples/stm32f4/src/bin/input_capture.rs index 49de33d2b..fe5e2bdfc 100644 --- a/examples/stm32f4/src/bin/input_capture.rs +++ b/examples/stm32f4/src/bin/input_capture.rs @@ -7,14 +7,14 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed}; use embassy_stm32::time::khz; use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; use embassy_stm32::timer::{self, Channel}; -use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_stm32::{bind_interrupts, peripherals, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Connect PB2 and PB10 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PB2) { +async fn blinky(led: Peri<'static, peripherals::PB2>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32f4/src/bin/pwm_input.rs b/examples/stm32f4/src/bin/pwm_input.rs index ce200549d..465cbe4f5 100644 --- a/examples/stm32f4/src/bin/pwm_input.rs +++ b/examples/stm32f4/src/bin/pwm_input.rs @@ -6,14 +6,14 @@ use embassy_executor::Spawner; use embassy_stm32::gpio::{Level, Output, Pull, Speed}; use embassy_stm32::time::khz; use embassy_stm32::timer::pwm_input::PwmInput; -use embassy_stm32::{bind_interrupts, peripherals, timer}; +use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; /// Connect PB2 and PA6 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PB2) { +async fn blinky(led: Peri<'static, peripherals::PB2>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs index 3ab93d6e0..ca924e181 100644 --- a/examples/stm32f4/src/bin/ws2812_pwm.rs +++ b/examples/stm32f4/src/bin/ws2812_pwm.rs @@ -92,7 +92,7 @@ async fn main(_spawner: Spawner) { loop { for &color in color_list { // with &mut, we can easily reuse same DMA channel multiple times - ws2812_pwm.waveform_up(&mut dp.DMA1_CH2, pwm_channel, color).await; + ws2812_pwm.waveform_up(dp.DMA1_CH2.reborrow(), pwm_channel, color).await; // ws2812 need at least 50 us low level input to confirm the input data and change it's state Timer::after_micros(50).await; // wait until ticker tick diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs index a82e335a9..58ba940a8 100644 --- a/examples/stm32f7/src/bin/can.rs +++ b/examples/stm32f7/src/bin/can.rs @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) { // To synchronise to the bus the RX input needs to see a high level. // Use `mem::forget()` to release the borrow on the pin but keep the // pull-up resistor enabled. - let rx_pin = Input::new(&mut p.PA15, Pull::Up); + let rx_pin = Input::new(p.PA15.reborrow(), Pull::Up); core::mem::forget(rx_pin); static CAN: StaticCell> = StaticCell::new(); diff --git a/examples/stm32g0/src/bin/adc_dma.rs b/examples/stm32g0/src/bin/adc_dma.rs index 3713e5a21..d7515933c 100644 --- a/examples/stm32g0/src/bin/adc_dma.rs +++ b/examples/stm32g0/src/bin/adc_dma.rs @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { loop { adc.read( - &mut dma, + dma.reborrow(), [ (&mut vrefint_channel, SampleTime::CYCLES160_5), (&mut pa0, SampleTime::CYCLES160_5), diff --git a/examples/stm32g0/src/bin/input_capture.rs b/examples/stm32g0/src/bin/input_capture.rs index bc814cb13..08df4e043 100644 --- a/examples/stm32g0/src/bin/input_capture.rs +++ b/examples/stm32g0/src/bin/input_capture.rs @@ -16,14 +16,14 @@ use embassy_stm32::time::khz; use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::Channel; -use embassy_stm32::{bind_interrupts, peripherals, timer}; +use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // Connect PB1 and PA6 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PB1) { +async fn blinky(led: Peri<'static, peripherals::PB1>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32g0/src/bin/pwm_input.rs b/examples/stm32g0/src/bin/pwm_input.rs index db9cf4f8a..9d6b5fe97 100644 --- a/examples/stm32g0/src/bin/pwm_input.rs +++ b/examples/stm32g0/src/bin/pwm_input.rs @@ -14,13 +14,13 @@ use embassy_stm32::gpio::{Level, Output, OutputType, Pull, Speed}; use embassy_stm32::time::khz; use embassy_stm32::timer::pwm_input::PwmInput; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; -use embassy_stm32::{bind_interrupts, peripherals, timer}; +use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; // Connect PB1 and PA6 with a 1k Ohm resistor #[embassy_executor::task] -async fn blinky(led: peripherals::PB1) { +async fn blinky(led: Peri<'static, peripherals::PB1>) { let mut led = Output::new(led, Level::High, Speed::Low); loop { diff --git a/examples/stm32g4/src/bin/adc_dma.rs b/examples/stm32g4/src/bin/adc_dma.rs index 970623b32..202704085 100644 --- a/examples/stm32g4/src/bin/adc_dma.rs +++ b/examples/stm32g4/src/bin/adc_dma.rs @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { loop { adc.read( - &mut dma, + dma.reborrow(), [ (&mut vrefint_channel, SampleTime::CYCLES247_5), (&mut pa0, SampleTime::CYCLES247_5), diff --git a/examples/stm32h5/src/bin/cordic.rs b/examples/stm32h5/src/bin/cordic.rs index 73e873574..cbf854704 100644 --- a/examples/stm32h5/src/bin/cordic.rs +++ b/examples/stm32h5/src/bin/cordic.rs @@ -11,7 +11,7 @@ async fn main(_spawner: Spawner) { let mut dp = embassy_stm32::init(Default::default()); let mut cordic = cordic::Cordic::new( - &mut dp.CORDIC, + dp.CORDIC.reborrow(), unwrap!(cordic::Config::new( cordic::Function::Sin, Default::default(), @@ -59,8 +59,8 @@ async fn main(_spawner: Spawner) { let cnt1 = unwrap!( cordic .async_calc_32bit( - &mut dp.GPDMA1_CH0, - &mut dp.GPDMA1_CH1, + dp.GPDMA1_CH0.reborrow(), + dp.GPDMA1_CH1.reborrow(), &input_buf[..arg1.len() - 1], // limit input buf to its actual length &mut output_u32, true, diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs index 0d14c0668..e650791c5 100644 --- a/examples/stm32h5/src/bin/stop.rs +++ b/examples/stm32h5/src/bin/stop.rs @@ -10,7 +10,7 @@ use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; use embassy_stm32::low_power::Executor; use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_stm32::Config; +use embassy_stm32::{Config, Peri}; use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -48,7 +48,7 @@ async fn async_main(spawner: Spawner) { } #[embassy_executor::task] -async fn blinky(led: AnyPin) { +async fn blinky(led: Peri<'static, AnyPin>) { let mut led = Output::new(led, Level::Low, Speed::Low); loop { info!("high"); diff --git a/examples/stm32h7/src/bin/adc_dma.rs b/examples/stm32h7/src/bin/adc_dma.rs index 0b905d227..dc775f18a 100644 --- a/examples/stm32h7/src/bin/adc_dma.rs +++ b/examples/stm32h7/src/bin/adc_dma.rs @@ -57,7 +57,7 @@ async fn main(_spawner: Spawner) { loop { adc.read( - &mut dma, + dma.reborrow(), [ (&mut vrefint_channel, SampleTime::CYCLES387_5), (&mut pc0, SampleTime::CYCLES810_5), diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 98c9f1e90..8314754bc 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -10,6 +10,7 @@ use embassy_stm32::peripherals::{DAC1, TIM6, TIM7}; use embassy_stm32::rcc::frequency; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Timer; +use embassy_stm32::Peri; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -57,7 +58,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { +async fn dac_task1(tim: Peri<'static, TIM6>, mut dac: DacCh1<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", frequency::()); @@ -100,7 +101,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { } #[embassy_executor::task] -async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, Async>) { +async fn dac_task2(tim: Peri<'static, TIM7>, mut dac: DacCh2<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", frequency::()); diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index b796996ea..8de31ea5b 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -7,7 +7,7 @@ use embassy_stm32::gpio::{AfType, Flex, OutputType, Speed}; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; -use embassy_stm32::{into_ref, Config, Peripheral}; +use embassy_stm32::{Config, Peri}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -66,15 +66,13 @@ pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { pub fn new( - tim: impl Peripheral

+ 'd, - ch1: impl Peripheral

> + 'd, - ch2: impl Peripheral

> + 'd, - ch3: impl Peripheral

> + 'd, - ch4: impl Peripheral

> + 'd, + tim: Peri<'d, T>, + ch1: Peri<'d, impl Channel1Pin>, + ch2: Peri<'d, impl Channel2Pin>, + ch3: Peri<'d, impl Channel3Pin>, + ch4: Peri<'d, impl Channel4Pin>, freq: Hertz, ) -> Self { - into_ref!(ch1, ch2, ch3, ch4); - let af1 = ch1.af_num(); let af2 = ch2.af_num(); let af3 = ch3.af_num(); diff --git a/examples/stm32h723/src/bin/spdifrx.rs b/examples/stm32h723/src/bin/spdifrx.rs index 69ef5cd07..bc8249ced 100644 --- a/examples/stm32h723/src/bin/spdifrx.rs +++ b/examples/stm32h723/src/bin/spdifrx.rs @@ -77,14 +77,19 @@ async fn main(_spawner: Spawner) { }; let mut sai_transmitter = new_sai_transmitter( - &mut p.SAI4, - &mut p.PD13, - &mut p.PC1, - &mut p.PD12, - &mut p.BDMA_CH0, + p.SAI4.reborrow(), + p.PD13.reborrow(), + p.PC1.reborrow(), + p.PD12.reborrow(), + p.BDMA_CH0.reborrow(), sai_buffer, ); - let mut spdif_receiver = new_spdif_receiver(&mut p.SPDIFRX1, &mut p.PD7, &mut p.DMA2_CH7, spdifrx_buffer); + let mut spdif_receiver = new_spdif_receiver( + p.SPDIFRX1.reborrow(), + p.PD7.reborrow(), + p.DMA2_CH7.reborrow(), + spdifrx_buffer, + ); spdif_receiver.start(); let mut renew_sai = false; @@ -96,11 +101,11 @@ async fn main(_spawner: Spawner) { trace!("Renew SAI."); drop(sai_transmitter); sai_transmitter = new_sai_transmitter( - &mut p.SAI4, - &mut p.PD13, - &mut p.PC1, - &mut p.PD12, - &mut p.BDMA_CH0, + p.SAI4.reborrow(), + p.PD13.reborrow(), + p.PC1.reborrow(), + p.PD12.reborrow(), + p.BDMA_CH0.reborrow(), sai_buffer, ); } @@ -111,7 +116,12 @@ async fn main(_spawner: Spawner) { Err(spdifrx::Error::RingbufferError(_)) => { trace!("SPDIFRX ringbuffer error. Renew."); drop(spdif_receiver); - spdif_receiver = new_spdif_receiver(&mut p.SPDIFRX1, &mut p.PD7, &mut p.DMA2_CH7, spdifrx_buffer); + spdif_receiver = new_spdif_receiver( + p.SPDIFRX1.reborrow(), + p.PD7.reborrow(), + p.DMA2_CH7.reborrow(), + spdifrx_buffer, + ); spdif_receiver.start(); continue; } diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 6c9219080..cde24f411 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -10,6 +10,7 @@ use embassy_stm32::peripherals::{DAC1, TIM6, TIM7}; use embassy_stm32::rcc::frequency; use embassy_stm32::time::Hertz; use embassy_stm32::timer::low_level::Timer; +use embassy_stm32::Peri; use micromath::F32Ext; use {defmt_rtt as _, panic_probe as _}; @@ -28,7 +29,7 @@ async fn main(spawner: Spawner) { } #[embassy_executor::task] -async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { +async fn dac_task1(tim: Peri<'static, TIM6>, mut dac: DacCh1<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM6 frequency is {}", frequency::()); @@ -71,7 +72,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, Async>) { } #[embassy_executor::task] -async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, Async>) { +async fn dac_task2(tim: Peri<'static, TIM7>, mut dac: DacCh2<'static, DAC1, Async>) { let data: &[u8; 256] = &calculate_array::<256>(); info!("TIM7 frequency is {}", frequency::()); diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs index 32a736de8..d7a1efea9 100644 --- a/examples/stm32l5/src/bin/stop.rs +++ b/examples/stm32l5/src/bin/stop.rs @@ -7,7 +7,7 @@ use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; use embassy_stm32::low_power::Executor; use embassy_stm32::rcc::LsConfig; use embassy_stm32::rtc::{Rtc, RtcConfig}; -use embassy_stm32::Config; +use embassy_stm32::{Config, Peri}; use embassy_time::Timer; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -39,7 +39,7 @@ async fn async_main(spawner: Spawner) { } #[embassy_executor::task] -async fn blinky(led: AnyPin) -> ! { +async fn blinky(led: Peri<'static, AnyPin>) -> ! { let mut led = Output::new(led, Level::Low, Speed::Low); loop { info!("high"); diff --git a/examples/stm32u5/src/bin/adc.rs b/examples/stm32u5/src/bin/adc.rs index 6ba21cc63..d2aa28087 100644 --- a/examples/stm32u5/src/bin/adc.rs +++ b/examples/stm32u5/src/bin/adc.rs @@ -72,7 +72,7 @@ async fn main(_spawner: embassy_executor::Spawner) { let mut measurements = [0u16; 2]; adc1.read( - &mut p.GPDMA1_CH0, + p.GPDMA1_CH0.reborrow(), [ (&mut degraded11, adc::SampleTime::CYCLES160_5), (&mut degraded12, adc::SampleTime::CYCLES160_5), @@ -96,7 +96,7 @@ async fn main(_spawner: embassy_executor::Spawner) { // The channels must be in ascending order and can't repeat for ADC4 adc4.read( - &mut p.GPDMA1_CH1, + p.GPDMA1_CH1.reborrow(), [&mut degraded42, &mut degraded41].into_iter(), &mut measurements, ) diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs index 04f32832f..2eecafb95 100644 --- a/tests/nrf/src/bin/buffered_uart.rs +++ b/tests/nrf/src/bin/buffered_uart.rs @@ -25,14 +25,14 @@ async fn main(_spawner: Spawner) { // test teardown + recreate of the buffereduarte works fine. for _ in 0..2 { let u = BufferedUarte::new( - &mut peri!(p, UART0), - &mut p.TIMER0, - &mut p.PPI_CH0, - &mut p.PPI_CH1, - &mut p.PPI_GROUP0, + peri!(p, UART0).reborrow(), + p.TIMER0.reborrow(), + p.PPI_CH0.reborrow(), + p.PPI_CH1.reborrow(), + p.PPI_GROUP0.reborrow(), irqs!(UART0_BUFFERED), - &mut peri!(p, PIN_A), - &mut peri!(p, PIN_B), + peri!(p, PIN_A).reborrow(), + peri!(p, PIN_B).reborrow(), config.clone(), &mut rx_buffer, &mut tx_buffer, diff --git a/tests/nrf/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs index bdf5ad726..adfba509d 100644 --- a/tests/nrf/src/bin/buffered_uart_halves.rs +++ b/tests/nrf/src/bin/buffered_uart_halves.rs @@ -27,21 +27,21 @@ async fn main(_spawner: Spawner) { const COUNT: usize = 40_000; let mut tx = BufferedUarteTx::new( - &mut peri!(p, UART1), + peri!(p, UART1).reborrow(), irqs!(UART1_BUFFERED), - &mut peri!(p, PIN_A), + peri!(p, PIN_A).reborrow(), config.clone(), &mut tx_buffer, ); let mut rx = BufferedUarteRx::new( - &mut peri!(p, UART0), - &mut p.TIMER0, - &mut p.PPI_CH0, - &mut p.PPI_CH1, - &mut p.PPI_GROUP0, + peri!(p, UART0).reborrow(), + p.TIMER0.reborrow(), + p.PPI_CH0.reborrow(), + p.PPI_CH1.reborrow(), + p.PPI_GROUP0.reborrow(), irqs!(UART0_BUFFERED), - &mut peri!(p, PIN_B), + peri!(p, PIN_B).reborrow(), config.clone(), &mut rx_buffer, ); diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index cf9ca50d2..24ddd06f3 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs @@ -27,7 +27,11 @@ async fn main(_spawner: Spawner) { let mut rx_buffer = [0u8; 1024]; - mem::forget(Output::new(&mut peri!(p, PIN_A), Level::High, OutputDrive::Standard)); + mem::forget(Output::new( + peri!(p, PIN_A).reborrow(), + Level::High, + OutputDrive::Standard, + )); let mut u = BufferedUarteRx::new( peri!(p, UART0), diff --git a/tests/nrf/src/bin/spim.rs b/tests/nrf/src/bin/spim.rs index c2ec90b88..2b38f0409 100644 --- a/tests/nrf/src/bin/spim.rs +++ b/tests/nrf/src/bin/spim.rs @@ -17,11 +17,11 @@ async fn main(_spawner: Spawner) { let mut config = spim::Config::default(); config.frequency = spim::Frequency::M1; let mut spim = Spim::new( - &mut peri!(p, SPIM0), + peri!(p, SPIM0).reborrow(), irqs!(SPIM0), - &mut peri!(p, PIN_X), - &mut peri!(p, PIN_A), // MISO - &mut peri!(p, PIN_B), // MOSI + peri!(p, PIN_X).reborrow(), + peri!(p, PIN_A).reborrow(), // MISO + peri!(p, PIN_B).reborrow(), // MOSI config.clone(), ); let data = [ diff --git a/tests/nrf/src/bin/uart_halves.rs b/tests/nrf/src/bin/uart_halves.rs index f48ea43a1..a462f80ce 100644 --- a/tests/nrf/src/bin/uart_halves.rs +++ b/tests/nrf/src/bin/uart_halves.rs @@ -19,8 +19,18 @@ async fn main(_spawner: Spawner) { config.parity = uarte::Parity::EXCLUDED; config.baudrate = uarte::Baudrate::BAUD1M; - let mut tx = UarteTx::new(&mut peri!(p, UART0), irqs!(UART0), &mut peri!(p, PIN_A), config.clone()); - let mut rx = UarteRx::new(&mut peri!(p, UART1), irqs!(UART1), &mut peri!(p, PIN_B), config.clone()); + let mut tx = UarteTx::new( + peri!(p, UART0).reborrow(), + irqs!(UART0), + peri!(p, PIN_A).reborrow(), + config.clone(), + ); + let mut rx = UarteRx::new( + peri!(p, UART1).reborrow(), + irqs!(UART1), + peri!(p, PIN_B).reborrow(), + config.clone(), + ); let data = [ 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs index 70d8b2e33..f24903297 100644 --- a/tests/nrf/src/bin/uart_split.rs +++ b/tests/nrf/src/bin/uart_split.rs @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { config.baudrate = uarte::Baudrate::BAUD9600; let uarte = Uarte::new( - &mut peri!(p, UART0), + peri!(p, UART0).reborrow(), irqs!(UART0), - &mut peri!(p, PIN_A), - &mut peri!(p, PIN_B), + peri!(p, PIN_A).reborrow(), + peri!(p, PIN_B).reborrow(), config.clone(), ); let (mut tx, mut rx) = uarte.split(); diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 87e9709cc..c2175bc03 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -30,12 +30,12 @@ async fn main(_spawner: Spawner) { { { - let mut p = Channel::new_pin(&mut a, Pull::Down); + let mut p = Channel::new_pin(a.reborrow(), Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); } { - let mut p = Channel::new_pin(&mut a, Pull::Up); + let mut p = Channel::new_pin(a.reborrow(), Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); } @@ -43,21 +43,21 @@ async fn main(_spawner: Spawner) { // not bothering with async reads from now on { { - let mut p = Channel::new_pin(&mut b, Pull::Down); + let mut p = Channel::new_pin(b.reborrow(), Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); } { - let mut p = Channel::new_pin(&mut b, Pull::Up); + let mut p = Channel::new_pin(b.reborrow(), Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); } } { { - let mut p = Channel::new_pin(&mut c, Pull::Down); + let mut p = Channel::new_pin(c.reborrow(), Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); } { - let mut p = Channel::new_pin(&mut c, Pull::Up); + let mut p = Channel::new_pin(c.reborrow(), Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); } } @@ -65,15 +65,15 @@ async fn main(_spawner: Spawner) { // gp29 is connected to vsys through a 200k/100k divider, // adding pulls should change the value let low = { - let mut p = Channel::new_pin(&mut d, Pull::Down); + let mut p = Channel::new_pin(d.reborrow(), Pull::Down); adc.blocking_read(&mut p).unwrap() }; let none = { - let mut p = Channel::new_pin(&mut d, Pull::None); + let mut p = Channel::new_pin(d.reborrow(), Pull::None); adc.blocking_read(&mut p).unwrap() }; let up = { - let mut p = Channel::new_pin(&mut d, Pull::Up); + let mut p = Channel::new_pin(d.reborrow(), Pull::Up); adc.blocking_read(&mut p).unwrap() }; defmt::assert!(low < none); @@ -81,7 +81,7 @@ async fn main(_spawner: Spawner) { } { let temp = convert_to_celsius( - adc.read(&mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR)) + adc.read(&mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow())) .await .unwrap(), ); @@ -97,14 +97,29 @@ async fn main(_spawner: Spawner) { let mut low = [0u16; 16]; let mut none = [0u8; 16]; let mut up = [Sample::default(); 16]; - adc.read_many(&mut Channel::new_pin(&mut d, Pull::Down), &mut low, 1, &mut p.DMA_CH0) - .await - .unwrap(); - adc.read_many(&mut Channel::new_pin(&mut d, Pull::None), &mut none, 1, &mut p.DMA_CH0) - .await - .unwrap(); - adc.read_many_raw(&mut Channel::new_pin(&mut d, Pull::Up), &mut up, 1, &mut p.DMA_CH0) - .await; + adc.read_many( + &mut Channel::new_pin(d.reborrow(), Pull::Down), + &mut low, + 1, + p.DMA_CH0.reborrow(), + ) + .await + .unwrap(); + adc.read_many( + &mut Channel::new_pin(d.reborrow(), Pull::None), + &mut none, + 1, + p.DMA_CH0.reborrow(), + ) + .await + .unwrap(); + adc.read_many_raw( + &mut Channel::new_pin(d.reborrow(), Pull::Up), + &mut up, + 1, + p.DMA_CH0.reborrow(), + ) + .await; defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); defmt::assert!(up.iter().all(|s| s.good())); defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value())); @@ -112,10 +127,10 @@ async fn main(_spawner: Spawner) { { let mut temp = [0u16; 16]; adc.read_many( - &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), + &mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()), &mut temp, 1, - &mut p.DMA_CH0, + p.DMA_CH0.reborrow(), ) .await .unwrap(); @@ -126,10 +141,10 @@ async fn main(_spawner: Spawner) { { let mut multi = [0u16; 2]; let mut channels = [ - Channel::new_pin(&mut a, Pull::Up), - Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), + Channel::new_pin(a.reborrow(), Pull::Up), + Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()), ]; - adc.read_many_multichannel(&mut channels, &mut multi, 1, &mut p.DMA_CH0) + adc.read_many_multichannel(&mut channels, &mut multi, 1, p.DMA_CH0.reborrow()) .await .unwrap(); defmt::assert!(multi[0] > 3_000); diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs index e88d8bf6c..aa123ab03 100644 --- a/tests/rp/src/bin/bootsel.rs +++ b/tests/rp/src/bin/bootsel.rs @@ -4,12 +4,13 @@ teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; +use embassy_rp::bootsel::is_bootsel_pressed; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let mut p = embassy_rp::init(Default::default()); + let p = embassy_rp::init(Default::default()); info!("Hello World!"); // add some delay to give an attached debug probe time to parse the @@ -18,7 +19,7 @@ async fn main(_spawner: Spawner) { // https://github.com/knurling-rs/defmt/pull/683 Timer::after_millis(10).await; - assert_eq!(p.BOOTSEL.is_pressed(), false); + assert_eq!(is_bootsel_pressed(p.BOOTSEL), false); info!("Test OK"); cortex_m::asm::bkpt(); diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs index 6c37ac5be..614b6317a 100644 --- a/tests/rp/src/bin/gpio.rs +++ b/tests/rp/src/bin/gpio.rs @@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) { // Test initial output { - let b = Input::new(&mut b, Pull::None); + let b = Input::new(b.reborrow(), Pull::None); { - let a = Output::new(&mut a, Level::Low); + let a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); assert!(!b.is_high()); @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) { assert!(!a.is_set_high()); } { - let mut a = Output::new(&mut a, Level::High); + let mut a = Output::new(a.reborrow(), Level::High); delay(); assert!(!b.is_low()); assert!(b.is_high()); @@ -69,10 +69,10 @@ async fn main(_spawner: Spawner) { // Test input no pull { - let b = Input::new(&mut b, Pull::None); + let b = Input::new(b.reborrow(), Pull::None); // no pull, the status is undefined - let mut a = Output::new(&mut a, Level::Low); + let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -83,11 +83,11 @@ async fn main(_spawner: Spawner) { // Test input pulldown #[cfg(feature = "rp2040")] { - let b = Input::new(&mut b, Pull::Down); + let b = Input::new(b.reborrow(), Pull::Down); delay(); assert!(b.is_low()); - let mut a = Output::new(&mut a, Level::Low); + let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -97,11 +97,11 @@ async fn main(_spawner: Spawner) { // Test input pullup { - let b = Input::new(&mut b, Pull::Up); + let b = Input::new(b.reborrow(), Pull::Up); delay(); assert!(b.is_high()); - let mut a = Output::new(&mut a, Level::Low); + let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -112,8 +112,8 @@ async fn main(_spawner: Spawner) { // OUTPUT OPEN DRAIN #[cfg(feature = "rp2040")] { - let mut b = OutputOpenDrain::new(&mut b, Level::High); - let mut a = Flex::new(&mut a); + let mut b = OutputOpenDrain::new(b.reborrow(), Level::High); + let mut a = Flex::new(a.reborrow()); a.set_as_input(); // When an OutputOpenDrain is high, it doesn't drive the pin. @@ -170,12 +170,12 @@ async fn main(_spawner: Spawner) { // Test initial output { //Flex pin configured as input - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(); { //Flex pin configured as output - let mut a = Flex::new(&mut a); //Flex pin configured as output + let mut a = Flex::new(a.reborrow()); //Flex pin configured as output a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state a.set_as_output(); delay(); @@ -183,7 +183,7 @@ async fn main(_spawner: Spawner) { } { //Flex pin configured as output - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(); @@ -194,10 +194,10 @@ async fn main(_spawner: Spawner) { // Test input no pull { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(); // no pull by default. - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(); @@ -211,13 +211,13 @@ async fn main(_spawner: Spawner) { // Test input pulldown #[cfg(feature = "rp2040")] { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(); b.set_pull(Pull::Down); delay(); assert!(b.is_low()); - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(); delay(); @@ -229,13 +229,13 @@ async fn main(_spawner: Spawner) { // Test input pullup { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(); b.set_pull(Pull::Up); delay(); assert!(b.is_high()); - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(); delay(); diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs index 39e3d6337..72fb0910d 100644 --- a/tests/rp/src/bin/gpio_async.rs +++ b/tests/rp/src/bin/gpio_async.rs @@ -22,8 +22,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_high"); - let mut output = Output::new(&mut output_pin, Level::Low); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::Low); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_low(), "input was expected to be low"); @@ -43,8 +43,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_low"); - let mut output = Output::new(&mut output_pin, Level::High); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::High); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_high(), "input was expected to be high"); @@ -63,8 +63,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_rising_edge"); - let mut output = Output::new(&mut output_pin, Level::Low); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::Low); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_low(), "input was expected to be low"); @@ -83,8 +83,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_falling_edge"); - let mut output = Output::new(&mut output_pin, Level::High); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::High); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_high(), "input was expected to be high"); @@ -103,8 +103,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_any_edge (falling)"); - let mut output = Output::new(&mut output_pin, Level::High); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::High); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_high(), "input was expected to be high"); @@ -123,8 +123,8 @@ async fn main(_spawner: Spawner) { { info!("test wait_for_any_edge (rising)"); - let mut output = Output::new(&mut output_pin, Level::Low); - let mut input = Input::new(&mut input_pin, Pull::None); + let mut output = Output::new(output_pin.reborrow(), Level::Low); + let mut input = Input::new(input_pin.reborrow(), Pull::None); assert!(input.is_low(), "input was expected to be low"); diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index 3caa8ef35..857f36975 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs @@ -10,6 +10,7 @@ use embassy_executor::Executor; use embassy_rp::gpio::{Input, Level, Output, Pull}; use embassy_rp::multicore::{spawn_core1, Stack}; use embassy_rp::peripherals::{PIN_0, PIN_1}; +use embassy_rp::Peri; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; use static_cell::StaticCell; @@ -37,7 +38,7 @@ fn main() -> ! { } #[embassy_executor::task] -async fn core0_task(p: PIN_0) { +async fn core0_task(p: Peri<'static, PIN_0>) { info!("CORE0 is running"); let mut pin = Output::new(p, Level::Low); @@ -54,7 +55,7 @@ async fn core0_task(p: PIN_0) { } #[embassy_executor::task] -async fn core1_task(p: PIN_1) { +async fn core1_task(p: Peri<'static, PIN_1>) { info!("CORE1 is running"); CHANNEL0.receive().await; diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index d8ee78dcd..5f890cd50 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs @@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) { // Test free-running clock { - let pwm = Pwm::new_free(&mut p.PWM_SLICE3, cfg.clone()); + let pwm = Pwm::new_free(p.PWM_SLICE3.reborrow(), cfg.clone()); cortex_m::asm::delay(125); let ctr = pwm.counter(); assert!(ctr > 0); @@ -50,8 +50,8 @@ async fn main(_spawner: Spawner) { // Test output from A { - let pin1 = Input::new(&mut p9, Pull::None); - let _pwm = Pwm::new_output_a(&mut p.PWM_SLICE3, &mut p6, cfg.clone()); + let pin1 = Input::new(p9.reborrow(), Pull::None); + let _pwm = Pwm::new_output_a(p.PWM_SLICE3.reborrow(), p6.reborrow(), cfg.clone()); Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); Timer::after_millis(5).await; @@ -64,8 +64,8 @@ async fn main(_spawner: Spawner) { // Test output from B { - let pin2 = Input::new(&mut p11, Pull::None); - let _pwm = Pwm::new_output_b(&mut p.PWM_SLICE3, &mut p7, cfg.clone()); + let pin2 = Input::new(p11.reborrow(), Pull::None); + let _pwm = Pwm::new_output_b(p.PWM_SLICE3.reborrow(), p7.reborrow(), cfg.clone()); Timer::after_millis(1).await; assert_ne!(pin2.is_low(), invert_a); Timer::after_millis(5).await; @@ -78,9 +78,9 @@ async fn main(_spawner: Spawner) { // Test output from A+B { - let pin1 = Input::new(&mut p9, Pull::None); - let pin2 = Input::new(&mut p11, Pull::None); - let _pwm = Pwm::new_output_ab(&mut p.PWM_SLICE3, &mut p6, &mut p7, cfg.clone()); + let pin1 = Input::new(p9.reborrow(), Pull::None); + let pin2 = Input::new(p11.reborrow(), Pull::None); + let _pwm = Pwm::new_output_ab(p.PWM_SLICE3.reborrow(), p6.reborrow(), p7.reborrow(), cfg.clone()); Timer::after_millis(1).await; assert_eq!(pin1.is_low(), invert_a); assert_ne!(pin2.is_low(), invert_a); @@ -99,8 +99,14 @@ async fn main(_spawner: Spawner) { // Test level-gated #[cfg(feature = "rp2040")] { - let mut pin2 = Output::new(&mut p11, Level::Low); - let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, Pull::None, InputMode::Level, cfg.clone()); + let mut pin2 = Output::new(p11.reborrow(), Level::Low); + let pwm = Pwm::new_input( + p.PWM_SLICE3.reborrow(), + p7.reborrow(), + Pull::None, + InputMode::Level, + cfg.clone(), + ); assert_eq!(pwm.counter(), 0); Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); @@ -117,10 +123,10 @@ async fn main(_spawner: Spawner) { // Test rising-gated #[cfg(feature = "rp2040")] { - let mut pin2 = Output::new(&mut p11, Level::Low); + let mut pin2 = Output::new(p11.reborrow(), Level::Low); let pwm = Pwm::new_input( - &mut p.PWM_SLICE3, - &mut p7, + p.PWM_SLICE3.reborrow(), + p7.reborrow(), Pull::None, InputMode::RisingEdge, cfg.clone(), @@ -139,10 +145,10 @@ async fn main(_spawner: Spawner) { // Test falling-gated #[cfg(feature = "rp2040")] { - let mut pin2 = Output::new(&mut p11, Level::High); + let mut pin2 = Output::new(p11.reborrow(), Level::High); let pwm = Pwm::new_input( - &mut p.PWM_SLICE3, - &mut p7, + p.PWM_SLICE3.reborrow(), + p7.reborrow(), Pull::None, InputMode::FallingEdge, cfg.clone(), @@ -160,10 +166,10 @@ async fn main(_spawner: Spawner) { // pull-down { - let pin2 = Input::new(&mut p11, Pull::None); + let pin2 = Input::new(p11.reborrow(), Pull::None); Pwm::new_input( - &mut p.PWM_SLICE3, - &mut p7, + p.PWM_SLICE3.reborrow(), + p7.reborrow(), Pull::Down, InputMode::FallingEdge, cfg.clone(), @@ -174,10 +180,10 @@ async fn main(_spawner: Spawner) { // pull-up { - let pin2 = Input::new(&mut p11, Pull::None); + let pin2 = Input::new(p11.reborrow(), Pull::None); Pwm::new_input( - &mut p.PWM_SLICE3, - &mut p7, + p.PWM_SLICE3.reborrow(), + p7.reborrow(), Pull::Up, InputMode::FallingEdge, cfg.clone(), diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index 67cfa6bc8..84744ab77 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs @@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) { { let config = Config::default(); - let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); + let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); // We can't send too many bytes, they have to fit in the FIFO. // This is because we aren't sending+receiving at the same time. @@ -69,7 +69,7 @@ async fn main(_spawner: Spawner) { info!("test overflow detection"); { let config = Config::default(); - let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); + let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); let data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, @@ -93,7 +93,7 @@ async fn main(_spawner: Spawner) { info!("test break detection"); { let config = Config::default(); - let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); + let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config); // break on empty fifo uart.send_break(20).await; @@ -113,11 +113,11 @@ async fn main(_spawner: Spawner) { // parity detection. here we bitbang to not require two uarts. info!("test parity error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); let mut config = Config::default(); config.baudrate = 1000; config.parity = Parity::ParityEven; - let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); + let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config); async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { send(pin, v, Some(parity != 0)).await; @@ -140,10 +140,10 @@ async fn main(_spawner: Spawner) { // framing error detection. here we bitbang because there's no other way. info!("test framing error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); let mut config = Config::default(); config.baudrate = 1000; - let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); + let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config); async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { if good { diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index a543320e0..b270a60ce 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs @@ -73,7 +73,15 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let tx_buf = &mut [0u8; 16]; let rx_buf = &mut [0u8; 16]; - let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); + let mut uart = BufferedUart::new( + uart.reborrow(), + Irqs, + tx.reborrow(), + rx.reborrow(), + tx_buf, + rx_buf, + config, + ); // Make sure we send more bytes than fits in the FIFO, to test the actual // bufferedUart. @@ -93,7 +101,15 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let tx_buf = &mut [0u8; 16]; let rx_buf = &mut [0u8; 16]; - let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); + let mut uart = BufferedUart::new( + uart.reborrow(), + Irqs, + tx.reborrow(), + rx.reborrow(), + tx_buf, + rx_buf, + config, + ); // Make sure we send more bytes than fits in the FIFO, to test the actual // bufferedUart. @@ -128,7 +144,15 @@ async fn main(_spawner: Spawner) { config.baudrate = 1000; let tx_buf = &mut [0u8; 16]; let rx_buf = &mut [0u8; 16]; - let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); + let mut uart = BufferedUart::new( + uart.reborrow(), + Irqs, + tx.reborrow(), + rx.reborrow(), + tx_buf, + rx_buf, + config, + ); // break on empty buffer uart.send_break(20).await; @@ -156,13 +180,13 @@ async fn main(_spawner: Spawner) { // parity detection. here we bitbang to not require two uarts. info!("test parity error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); // choose a very slow baud rate to make tests reliable even with O0 let mut config = Config::default(); config.baudrate = 1000; config.parity = Parity::ParityEven; let rx_buf = &mut [0u8; 16]; - let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); + let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config); async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { send(pin, v, Some(parity != 0)).await; @@ -204,12 +228,12 @@ async fn main(_spawner: Spawner) { // framing error detection. here we bitbang because there's no other way. info!("test framing error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); // choose a very slow baud rate to make tests reliable even with O0 let mut config = Config::default(); config.baudrate = 1000; let rx_buf = &mut [0u8; 16]; - let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); + let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config); async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { if good { diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index bdf94e78c..a09101223 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs @@ -65,12 +65,12 @@ async fn main(_spawner: Spawner) { { let config = Config::default(); let mut uart = Uart::new( - &mut uart, - &mut tx, - &mut rx, + uart.reborrow(), + tx.reborrow(), + rx.reborrow(), Irqs, - &mut p.DMA_CH0, - &mut p.DMA_CH1, + p.DMA_CH0.reborrow(), + p.DMA_CH1.reborrow(), config, ); @@ -86,12 +86,12 @@ async fn main(_spawner: Spawner) { { let config = Config::default(); let mut uart = Uart::new( - &mut uart, - &mut tx, - &mut rx, + uart.reborrow(), + tx.reborrow(), + rx.reborrow(), Irqs, - &mut p.DMA_CH0, - &mut p.DMA_CH1, + p.DMA_CH0.reborrow(), + p.DMA_CH1.reborrow(), config, ); @@ -115,12 +115,12 @@ async fn main(_spawner: Spawner) { { let config = Config::default(); let (mut tx, mut rx) = Uart::new( - &mut uart, - &mut tx, - &mut rx, + uart.reborrow(), + tx.reborrow(), + rx.reborrow(), Irqs, - &mut p.DMA_CH0, - &mut p.DMA_CH1, + p.DMA_CH0.reborrow(), + p.DMA_CH1.reborrow(), config, ) .split(); @@ -156,12 +156,12 @@ async fn main(_spawner: Spawner) { // parity detection. here we bitbang to not require two uarts. info!("test parity error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); // choose a very slow baud rate to make tests reliable even with O0 let mut config = Config::default(); config.baudrate = 1000; config.parity = Parity::ParityEven; - let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); + let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config); async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { send(pin, v, Some(parity != 0)).await; @@ -202,11 +202,11 @@ async fn main(_spawner: Spawner) { // framing error detection. here we bitbang because there's no other way. info!("test framing error detection"); { - let mut pin = Output::new(&mut tx, Level::High); + let mut pin = Output::new(tx.reborrow(), Level::High); // choose a very slow baud rate to make tests reliable even with O0 let mut config = Config::default(); config.baudrate = 1000; - let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); + let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config); async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { if good { diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs index 85a5f8d83..778d88a7b 100644 --- a/tests/stm32/src/bin/can.rs +++ b/tests/stm32/src/bin/can.rs @@ -43,7 +43,7 @@ async fn main(_spawner: Spawner) { // To synchronise to the bus the RX input needs to see a high level. // Use `mem::forget()` to release the borrow on the pin but keep the // pull-up resistor enabled. - let rx_pin = Input::new(&mut rx, Pull::Up); + let rx_pin = Input::new(rx.reborrow(), Pull::Up); core::mem::forget(rx_pin); let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs index 879ad56b6..e86eea58b 100644 --- a/tests/stm32/src/bin/cordic.rs +++ b/tests/stm32/src/bin/cordic.rs @@ -82,8 +82,8 @@ async fn main(_spawner: Spawner) { let cnt1 = defmt::unwrap!( cordic .async_calc_32bit( - &mut write_dma, - &mut read_dma, + write_dma.reborrow(), + read_dma.reborrow(), &input_q1_31[2..], &mut output_q1_31[cnt0..], true, diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index 4a2584b4e..40b03201c 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs @@ -20,10 +20,10 @@ async fn main(_spawner: Spawner) { // Test initial output { - let b = Input::new(&mut b, Pull::None); + let b = Input::new(b.reborrow(), Pull::None); { - let a = Output::new(&mut a, Level::Low, Speed::Low); + let a = Output::new(a.reborrow(), Level::Low, Speed::Low); delay(); assert!(b.is_low()); assert!(!b.is_high()); @@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) { assert!(!a.is_set_high()); } { - let mut a = Output::new(&mut a, Level::High, Speed::Low); + let mut a = Output::new(a.reborrow(), Level::High, Speed::Low); delay(); assert!(!b.is_low()); assert!(b.is_high()); @@ -68,10 +68,10 @@ async fn main(_spawner: Spawner) { // Test input no pull { - let b = Input::new(&mut b, Pull::None); + let b = Input::new(b.reborrow(), Pull::None); // no pull, the status is undefined - let mut a = Output::new(&mut a, Level::Low, Speed::Low); + let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -81,11 +81,11 @@ async fn main(_spawner: Spawner) { // Test input pulldown { - let b = Input::new(&mut b, Pull::Down); + let b = Input::new(b.reborrow(), Pull::Down); delay(); assert!(b.is_low()); - let mut a = Output::new(&mut a, Level::Low, Speed::Low); + let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -95,11 +95,11 @@ async fn main(_spawner: Spawner) { // Test input pullup { - let b = Input::new(&mut b, Pull::Up); + let b = Input::new(b.reborrow(), Pull::Up); delay(); assert!(b.is_high()); - let mut a = Output::new(&mut a, Level::Low, Speed::Low); + let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low); delay(); assert!(b.is_low()); a.set_high(); @@ -109,10 +109,10 @@ async fn main(_spawner: Spawner) { // Test output open drain { - let b = Input::new(&mut b, Pull::Down); + let b = Input::new(b.reborrow(), Pull::Down); // no pull, the status is undefined - let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low); + let mut a = OutputOpenDrain::new(a.reborrow(), Level::Low, Speed::Low); delay(); assert!(b.is_low()); a.set_high(); // High-Z output @@ -124,12 +124,12 @@ async fn main(_spawner: Spawner) { // Test initial output { //Flex pin configured as input - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(Pull::None); { //Flex pin configured as output - let mut a = Flex::new(&mut a); //Flex pin configured as output + let mut a = Flex::new(a.reborrow()); //Flex pin configured as output a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state a.set_as_output(Speed::Low); delay(); @@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) { } { //Flex pin configured as output - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(Speed::Low); @@ -148,10 +148,10 @@ async fn main(_spawner: Spawner) { // Test input no pull { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(Pull::None); // no pull, the status is undefined - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(Speed::Low); @@ -164,12 +164,12 @@ async fn main(_spawner: Spawner) { // Test input pulldown { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(Pull::Down); delay(); assert!(b.is_low()); - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(Speed::Low); delay(); @@ -181,12 +181,12 @@ async fn main(_spawner: Spawner) { // Test input pullup { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(Pull::Up); delay(); assert!(b.is_high()); - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(Speed::Low); delay(); @@ -198,10 +198,10 @@ async fn main(_spawner: Spawner) { // Test output open drain { - let mut b = Flex::new(&mut b); + let mut b = Flex::new(b.reborrow()); b.set_as_input(Pull::Down); - let mut a = Flex::new(&mut a); + let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_input_output(Speed::Low); delay(); diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs index a6bc117c0..07f17b569 100644 --- a/tests/stm32/src/bin/sdmmc.rs +++ b/tests/stm32/src/bin/sdmmc.rs @@ -40,15 +40,15 @@ async fn main(_spawner: Spawner) { // ======== Try 4bit. ============== info!("initializing in 4-bit mode..."); let mut s = Sdmmc::new_4bit( - &mut sdmmc, + sdmmc.reborrow(), Irqs, - &mut dma, - &mut clk, - &mut cmd, - &mut d0, - &mut d1, - &mut d2, - &mut d3, + dma.reborrow(), + clk.reborrow(), + cmd.reborrow(), + d0.reborrow(), + d1.reborrow(), + d2.reborrow(), + d3.reborrow(), Default::default(), ); @@ -89,12 +89,12 @@ async fn main(_spawner: Spawner) { // ======== Try 1bit. ============== info!("initializing in 1-bit mode..."); let mut s = Sdmmc::new_1bit( - &mut sdmmc, + sdmmc.reborrow(), Irqs, - &mut dma, - &mut clk, - &mut cmd, - &mut d0, + dma.reborrow(), + clk.reborrow(), + cmd.reborrow(), + d0.reborrow(), Default::default(), ); diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index 9712a8c5a..e8310866a 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs @@ -25,10 +25,10 @@ async fn main(_spawner: Spawner) { spi_config.frequency = Hertz(1_000_000); let mut spi = Spi::new_blocking( - &mut spi_peri, - &mut sck, // Arduino D13 - &mut mosi, // Arduino D11 - &mut miso, // Arduino D12 + spi_peri.reborrow(), + sck.reborrow(), // Arduino D13 + mosi.reborrow(), // Arduino D11 + miso.reborrow(), // Arduino D12 spi_config, ); @@ -43,20 +43,20 @@ async fn main(_spawner: Spawner) { defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); // test rx-only configuration - let mut spi = Spi::new_blocking_rxonly(&mut spi_peri, &mut sck, &mut miso, spi_config); - let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); + let mut spi = Spi::new_blocking_rxonly(spi_peri.reborrow(), sck.reborrow(), miso.reborrow(), spi_config); + let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh); test_rx::(&mut spi, &mut mosi_out); test_rx::(&mut spi, &mut mosi_out); drop(spi); drop(mosi_out); - let mut spi = Spi::new_blocking_txonly(&mut spi_peri, &mut sck, &mut mosi, spi_config); + let mut spi = Spi::new_blocking_txonly(spi_peri.reborrow(), sck.reborrow(), mosi.reborrow(), spi_config); test_tx::(&mut spi); test_tx::(&mut spi); drop(spi); - let mut spi = Spi::new_blocking_txonly_nosck(&mut spi_peri, &mut mosi, spi_config); + let mut spi = Spi::new_blocking_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), spi_config); test_tx::(&mut spi); test_tx::(&mut spi); drop(spi); diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index 307409a16..b4fdb8faa 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs @@ -27,12 +27,12 @@ async fn main(_spawner: Spawner) { spi_config.frequency = Hertz(1_000_000); let mut spi = Spi::new( - &mut spi_peri, - &mut sck, // Arduino D13 - &mut mosi, // Arduino D11 - &mut miso, // Arduino D12 - &mut tx_dma, - &mut rx_dma, + spi_peri.reborrow(), + sck.reborrow(), // Arduino D13 + mosi.reborrow(), // Arduino D11 + miso.reborrow(), // Arduino D12 + tx_dma.reborrow(), + rx_dma.reborrow(), spi_config, ); @@ -42,28 +42,34 @@ async fn main(_spawner: Spawner) { // test rx-only configuration let mut spi = Spi::new_rxonly( - &mut spi_peri, - &mut sck, - &mut miso, + spi_peri.reborrow(), + sck.reborrow(), + miso.reborrow(), // SPIv1/f1 requires txdma even if rxonly. #[cfg(not(feature = "spi-v345"))] - &mut tx_dma, - &mut rx_dma, + tx_dma.reborrow(), + rx_dma.reborrow(), spi_config, ); - let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); + let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh); test_rx::(&mut spi, &mut mosi_out).await; test_rx::(&mut spi, &mut mosi_out).await; drop(spi); drop(mosi_out); - let mut spi = Spi::new_txonly(&mut spi_peri, &mut sck, &mut mosi, &mut tx_dma, spi_config); + let mut spi = Spi::new_txonly( + spi_peri.reborrow(), + sck.reborrow(), + mosi.reborrow(), + tx_dma.reborrow(), + spi_config, + ); test_tx::(&mut spi).await; test_tx::(&mut spi).await; drop(spi); - let mut spi = Spi::new_txonly_nosck(&mut spi_peri, &mut mosi, &mut tx_dma, spi_config); + let mut spi = Spi::new_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), tx_dma.reborrow(), spi_config); test_tx::(&mut spi).await; test_tx::(&mut spi).await; drop(spi); diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs index bd7b35d6b..97aefe1a0 100644 --- a/tests/stm32/src/bin/ucpd.rs +++ b/tests/stm32/src/bin/ucpd.rs @@ -9,7 +9,7 @@ use defmt::{assert, assert_eq}; use embassy_executor::Spawner; use embassy_futures::join::join; use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; -use embassy_stm32::{bind_interrupts, peripherals}; +use embassy_stm32::{bind_interrupts, peripherals, Peri}; use embassy_time::Timer; bind_interrupts!(struct Irqs { @@ -28,8 +28,8 @@ async fn wait_for_vstate(cc_phy: &mut CcPhy<'_, T>, vstate: C async fn source( mut ucpd: Ucpd<'static, peripherals::UCPD1>, - rx_dma: peripherals::DMA1_CH1, - tx_dma: peripherals::DMA1_CH2, + rx_dma: Peri<'static, peripherals::DMA1_CH1>, + tx_dma: Peri<'static, peripherals::DMA1_CH2>, ) { debug!("source: setting default current pull-up"); ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); @@ -65,8 +65,8 @@ async fn source( async fn sink( mut ucpd: Ucpd<'static, peripherals::UCPD2>, - rx_dma: peripherals::DMA1_CH3, - tx_dma: peripherals::DMA1_CH4, + rx_dma: Peri<'static, peripherals::DMA1_CH3>, + tx_dma: Peri<'static, peripherals::DMA1_CH4>, ) { debug!("sink: setting pull down"); ucpd.cc_phy().set_pull(CcPull::Sink); diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs index 2f601ad0e..129c7b692 100644 --- a/tests/stm32/src/bin/usart.rs +++ b/tests/stm32/src/bin/usart.rs @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { { let config = Config::default(); - let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); + let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); // We can't send too many bytes, they have to fit in the FIFO. // This is because we aren't sending+receiving at the same time. @@ -45,7 +45,7 @@ async fn main(_spawner: Spawner) { // Test error handling with with an overflow error { let config = Config::default(); - let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); + let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); // Send enough bytes to fill the RX FIFOs off all USART versions. let data = [0; 64]; @@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.baudrate = baudrate; - let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { + let mut usart = match Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config) { Ok(x) => x, Err(ConfigError::BaudrateTooHigh) => { info!("baudrate too high"); From 0621087f6ff12d1e6fc0d566fabc2ca9130f633f Mon Sep 17 00:00:00 2001 From: techmccat Date: Thu, 27 Mar 2025 17:42:55 +0100 Subject: [PATCH 36/44] stm32: allow using LSI/LSE as SYSCLK on g0/c0 --- embassy-stm32/src/rcc/c0.rs | 7 +++++-- embassy-stm32/src/rcc/g0.rs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 04cbe83ed..4ec8e7780 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -3,6 +3,7 @@ pub use crate::pac::rcc::vals::{ Hpre as AHBPrescaler, Hsidiv as HsiSysDiv, Hsikerdiv as HsiKerDiv, Ppre as APBPrescaler, Sw as Sysclk, }; use crate::pac::{FLASH, RCC}; +use crate::rcc::LSI_FREQ; use crate::time::Hertz; /// HSI speed @@ -121,9 +122,13 @@ pub(crate) unsafe fn init(config: Config) { } }; + let rtc = config.ls.init(); + let sys = match config.sys { Sysclk::HSISYS => unwrap!(hsisys), Sysclk::HSE => unwrap!(hse), + Sysclk::LSI => { assert!(config.ls.lsi); LSI_FREQ } + Sysclk::LSE => unwrap!(config.ls.lse).frequency, _ => unreachable!(), }; @@ -162,8 +167,6 @@ pub(crate) unsafe fn init(config: Config) { RCC.cr().modify(|w| w.set_hsion(false)); } - let rtc = config.ls.init(); - config.mux.init(); set_clocks!( diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index f55b18290..c84ac5166 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -5,6 +5,7 @@ pub use crate::pac::rcc::vals::{ Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, }; use crate::pac::{FLASH, PWR, RCC}; +use crate::rcc::LSI_FREQ; use crate::time::Hertz; /// HSI speed @@ -234,10 +235,14 @@ pub(crate) unsafe fn init(config: Config) { }) .unwrap_or_default(); + let rtc = config.ls.init(); + let sys = match config.sys { Sysclk::HSI => unwrap!(hsisys), Sysclk::HSE => unwrap!(hse), Sysclk::PLL1_R => unwrap!(pll.pll_r), + Sysclk::LSI => { assert!(config.ls.lsi); LSI_FREQ } + Sysclk::LSE => unwrap!(config.ls.lse).frequency, _ => unreachable!(), }; @@ -286,8 +291,6 @@ pub(crate) unsafe fn init(config: Config) { PWR.cr1().modify(|w| w.set_lpr(true)); } - let rtc = config.ls.init(); - config.mux.init(); set_clocks!( From ce578b62b8ac7d1d4ad3a96e7a085e6f3c0722eb Mon Sep 17 00:00:00 2001 From: techmccat Date: Fri, 28 Mar 2025 10:45:14 +0100 Subject: [PATCH 37/44] stm32: run cargo fmt --- embassy-stm32/src/rcc/c0.rs | 5 ++++- embassy-stm32/src/rcc/g0.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 4ec8e7780..0b749bcff 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs @@ -127,7 +127,10 @@ pub(crate) unsafe fn init(config: Config) { let sys = match config.sys { Sysclk::HSISYS => unwrap!(hsisys), Sysclk::HSE => unwrap!(hse), - Sysclk::LSI => { assert!(config.ls.lsi); LSI_FREQ } + Sysclk::LSI => { + assert!(config.ls.lsi); + LSI_FREQ + } Sysclk::LSE => unwrap!(config.ls.lse).frequency, _ => unreachable!(), }; diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index c84ac5166..2dbf62a9f 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -241,7 +241,10 @@ pub(crate) unsafe fn init(config: Config) { Sysclk::HSI => unwrap!(hsisys), Sysclk::HSE => unwrap!(hse), Sysclk::PLL1_R => unwrap!(pll.pll_r), - Sysclk::LSI => { assert!(config.ls.lsi); LSI_FREQ } + Sysclk::LSI => { + assert!(config.ls.lsi); + LSI_FREQ + } Sysclk::LSE => unwrap!(config.ls.lse).frequency, _ => unreachable!(), }; From 695a6da322aa2d75c8f702b2ed8b67f9ad12c3a0 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 28 Mar 2025 18:59:02 +0100 Subject: [PATCH 38/44] Statically allocate task pools on stable Rust. Thanks @0e4ef622 for the awesome idea of how to do it and the first implementation. Co-Authored-By: Matthew Tran <0e4ef622@gmail.com> --- embassy-executor-macros/src/macros/task.rs | 38 +++- embassy-executor/Cargo.toml | 95 ---------- embassy-executor/README.md | 27 +-- embassy-executor/build.rs | 92 --------- embassy-executor/src/lib.rs | 176 ++++++++++-------- examples/boot/application/nrf/Cargo.toml | 2 +- examples/boot/application/rp/Cargo.toml | 2 +- examples/boot/application/stm32f3/Cargo.toml | 2 +- examples/boot/application/stm32f7/Cargo.toml | 2 +- examples/boot/application/stm32h7/Cargo.toml | 2 +- examples/boot/application/stm32l0/Cargo.toml | 2 +- examples/boot/application/stm32l1/Cargo.toml | 2 +- examples/boot/application/stm32l4/Cargo.toml | 2 +- .../boot/application/stm32wb-dfu/Cargo.toml | 2 +- examples/boot/application/stm32wl/Cargo.toml | 2 +- examples/lpc55s69/Cargo.toml | 2 +- examples/mspm0c1104/Cargo.toml | 2 +- examples/mspm0g3507/Cargo.toml | 2 +- examples/mspm0g3519/Cargo.toml | 2 +- examples/mspm0l1306/Cargo.toml | 2 +- examples/mspm0l2228/Cargo.toml | 2 +- examples/nrf51/Cargo.toml | 2 +- examples/nrf52810/Cargo.toml | 2 +- examples/nrf52840/Cargo.toml | 2 +- examples/nrf5340/Cargo.toml | 2 +- examples/nrf54l15/Cargo.toml | 2 +- examples/nrf9151/ns/Cargo.toml | 2 +- examples/nrf9151/s/Cargo.toml | 2 +- examples/nrf9160/Cargo.toml | 2 +- examples/rp/Cargo.toml | 2 +- examples/rp235x/Cargo.toml | 2 +- examples/std/Cargo.toml | 2 +- examples/stm32f4/Cargo.toml | 2 +- examples/stm32f469/Cargo.toml | 2 +- examples/stm32f7/Cargo.toml | 2 +- examples/stm32h5/Cargo.toml | 2 +- examples/stm32h7/Cargo.toml | 2 +- examples/stm32h723/Cargo.toml | 2 +- examples/stm32h735/Cargo.toml | 2 +- examples/stm32h755cm4/Cargo.toml | 2 +- examples/stm32h755cm7/Cargo.toml | 2 +- examples/stm32h7b0/Cargo.toml | 2 +- examples/stm32h7rs/Cargo.toml | 2 +- examples/stm32l4/Cargo.toml | 2 +- examples/stm32l432/Cargo.toml | 2 +- examples/stm32l5/Cargo.toml | 2 +- examples/stm32u5/Cargo.toml | 2 +- examples/stm32wb/Cargo.toml | 2 +- examples/stm32wba/Cargo.toml | 2 +- examples/stm32wl/Cargo.toml | 2 +- tests/nrf/Cargo.toml | 2 +- tests/rp/Cargo.toml | 2 +- tests/stm32/Cargo.toml | 2 +- 53 files changed, 187 insertions(+), 337 deletions(-) diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index e8134c6a9..8a2a7fdb9 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs @@ -145,9 +145,43 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { }; #[cfg(not(feature = "nightly"))] let mut task_outer_body = quote! { + const fn __task_pool_size(_: F) -> usize + where + F: #embassy_executor::_export::TaskFn, + { + ::core::mem::size_of::< + #embassy_executor::raw::TaskPool + >() + } + const fn __task_pool_align(_: F) -> usize + where + F: #embassy_executor::_export::TaskFn, + { + ::core::mem::align_of::< + #embassy_executor::raw::TaskPool + >() + } + + const fn __task_pool_new(_: F) -> #embassy_executor::raw::TaskPool + where + F: #embassy_executor::_export::TaskFn, + { + #embassy_executor::raw::TaskPool::new() + } + + const fn __task_pool_get(_: F) -> &'static #embassy_executor::raw::TaskPool + where + F: #embassy_executor::_export::TaskFn + { + unsafe { &*POOL.get().cast() } + } + const POOL_SIZE: usize = #pool_size; - static POOL: #embassy_executor::_export::TaskPoolRef = #embassy_executor::_export::TaskPoolRef::new(); - unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } + static POOL: #embassy_executor::_export::TaskPoolHolder< + {__task_pool_size(#task_inner_ident)}, + {__task_pool_align(#task_inner_ident)}, + > = unsafe { ::core::mem::transmute(__task_pool_new(#task_inner_ident)) }; + unsafe { __task_pool_get(#task_inner_ident)._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } }; let task_outer_attrs = task_inner.attrs.clone(); diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index d6f24ce84..79d899c61 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -108,98 +108,3 @@ timer-item-payload-size-2 = ["_timer-item-payload"] timer-item-payload-size-4 = ["_timer-item-payload"] ## 8 bytes timer-item-payload-size-8 = ["_timer-item-payload"] - -#! ### Task Arena Size -#! Sets the [task arena](#task-arena) size. Necessary if you’re not using `nightly`. -#! -#!

-#! Preconfigured Task Arena Sizes: -#! -#! - -# BEGIN AUTOGENERATED CONFIG FEATURES -# Generated by gen_config.py. DO NOT EDIT. -## 64 -task-arena-size-64 = [] -## 128 -task-arena-size-128 = [] -## 192 -task-arena-size-192 = [] -## 256 -task-arena-size-256 = [] -## 320 -task-arena-size-320 = [] -## 384 -task-arena-size-384 = [] -## 512 -task-arena-size-512 = [] -## 640 -task-arena-size-640 = [] -## 768 -task-arena-size-768 = [] -## 1024 -task-arena-size-1024 = [] -## 1280 -task-arena-size-1280 = [] -## 1536 -task-arena-size-1536 = [] -## 2048 -task-arena-size-2048 = [] -## 2560 -task-arena-size-2560 = [] -## 3072 -task-arena-size-3072 = [] -## 4096 (default) -task-arena-size-4096 = [] # Default -## 5120 -task-arena-size-5120 = [] -## 6144 -task-arena-size-6144 = [] -## 8192 -task-arena-size-8192 = [] -## 10240 -task-arena-size-10240 = [] -## 12288 -task-arena-size-12288 = [] -## 16384 -task-arena-size-16384 = [] -## 20480 -task-arena-size-20480 = [] -## 24576 -task-arena-size-24576 = [] -## 32768 -task-arena-size-32768 = [] -## 40960 -task-arena-size-40960 = [] -## 49152 -task-arena-size-49152 = [] -## 65536 -task-arena-size-65536 = [] -## 81920 -task-arena-size-81920 = [] -## 98304 -task-arena-size-98304 = [] -## 131072 -task-arena-size-131072 = [] -## 163840 -task-arena-size-163840 = [] -## 196608 -task-arena-size-196608 = [] -## 262144 -task-arena-size-262144 = [] -## 327680 -task-arena-size-327680 = [] -## 393216 -task-arena-size-393216 = [] -## 524288 -task-arena-size-524288 = [] -## 655360 -task-arena-size-655360 = [] -## 786432 -task-arena-size-786432 = [] -## 1048576 -task-arena-size-1048576 = [] - -# END AUTOGENERATED CONFIG FEATURES - -#!
diff --git a/embassy-executor/README.md b/embassy-executor/README.md index 074c73555..85f15edbb 100644 --- a/embassy-executor/README.md +++ b/embassy-executor/README.md @@ -3,35 +3,10 @@ An async/await executor designed for embedded usage. - No `alloc`, no heap needed. -- With nightly Rust, task futures can be fully statically allocated. +- Tasks are statically allocated. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible. - No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. - Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. - No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. - Efficient polling: a wake will only poll the woken task, not all of them. - Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. - Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks. - -## Task arena - -When the `nightly` Cargo feature is not enabled, `embassy-executor` allocates tasks out of an arena (a very simple bump allocator). - -If the task arena gets full, the program will panic at runtime. To guarantee this doesn't happen, you must set the size to the sum of sizes of all tasks. - -Tasks are allocated from the arena when spawned for the first time. If the task exits, the allocation is not released to the arena, but can be reused to spawn the task again. For multiple-instance tasks (like `#[embassy_executor::task(pool_size = 4)]`), the first spawn will allocate memory for all instances. This is done for performance and to increase predictability (for example, spawning at least 1 instance of every task at boot guarantees an immediate panic if the arena is too small, while allocating instances on-demand could delay the panic to only when the program is under load). - -The arena size can be configured in two ways: - -- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values - is available, see [Task Area Sizes](#task-arena-size) for reference. -- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example - `EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`. - Any value can be set, unlike with Cargo features. - -Environment variables take precedence over Cargo features. If two Cargo features are enabled for the same setting -with different values, compilation fails. - -## Statically allocating tasks - -When using nightly Rust, enable the `nightly` Cargo feature. This will make `embassy-executor` use the `type_alias_impl_trait` feature to allocate all tasks in `static`s. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible. - -The configured arena size is ignored, no arena is used at all. diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs index 8a41d7503..37becde3e 100644 --- a/embassy-executor/build.rs +++ b/embassy-executor/build.rs @@ -1,99 +1,7 @@ -use std::collections::HashMap; -use std::fmt::Write; -use std::path::PathBuf; -use std::{env, fs}; - #[path = "./build_common.rs"] mod common; -static CONFIGS: &[(&str, usize)] = &[ - // BEGIN AUTOGENERATED CONFIG FEATURES - // Generated by gen_config.py. DO NOT EDIT. - ("TASK_ARENA_SIZE", 4096), - // END AUTOGENERATED CONFIG FEATURES -]; - -struct ConfigState { - value: usize, - seen_feature: bool, - seen_env: bool, -} - fn main() { - let crate_name = env::var("CARGO_PKG_NAME") - .unwrap() - .to_ascii_uppercase() - .replace('-', "_"); - - // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any - // other file changed. - println!("cargo:rerun-if-changed=build.rs"); - - // Rebuild if config envvar changed. - for (name, _) in CONFIGS { - println!("cargo:rerun-if-env-changed={crate_name}_{name}"); - } - - let mut configs = HashMap::new(); - for (name, default) in CONFIGS { - configs.insert( - *name, - ConfigState { - value: *default, - seen_env: false, - seen_feature: false, - }, - ); - } - - let prefix = format!("{crate_name}_"); - for (var, value) in env::vars() { - if let Some(name) = var.strip_prefix(&prefix) { - let Some(cfg) = configs.get_mut(name) else { - panic!("Unknown env var {name}") - }; - - let Ok(value) = value.parse::() else { - panic!("Invalid value for env var {name}: {value}") - }; - - cfg.value = value; - cfg.seen_env = true; - } - - if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") { - if let Some(i) = feature.rfind('_') { - let name = &feature[..i]; - let value = &feature[i + 1..]; - if let Some(cfg) = configs.get_mut(name) { - let Ok(value) = value.parse::() else { - panic!("Invalid value for feature {name}: {value}") - }; - - // envvars take priority. - if !cfg.seen_env { - if cfg.seen_feature { - panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value); - } - - cfg.value = value; - cfg.seen_feature = true; - } - } - } - } - } - - let mut data = String::new(); - - for (name, cfg) in &configs { - writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap(); - } - - let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let out_file = out_dir.join("config.rs").to_string_lossy().to_string(); - fs::write(out_file, data).unwrap(); - let mut rustc_cfgs = common::CfgSet::new(); common::set_target_cfgs(&mut rustc_cfgs); } diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index d816539ac..5485f6a6a 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -50,101 +50,129 @@ pub mod raw; mod spawner; pub use spawner::*; -mod config { - #![allow(unused)] - include!(concat!(env!("OUT_DIR"), "/config.rs")); -} - /// Implementation details for embassy macros. /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. #[doc(hidden)] #[cfg(not(feature = "nightly"))] pub mod _export { - use core::alloc::Layout; - use core::cell::{Cell, UnsafeCell}; + use core::cell::UnsafeCell; use core::future::Future; use core::mem::MaybeUninit; - use core::ptr::null_mut; - use critical_section::{CriticalSection, Mutex}; - - use crate::raw::TaskPool; - - struct Arena { - buf: UnsafeCell>, - ptr: Mutex>, + pub trait TaskFn: Copy { + type Fut: Future + 'static; } - unsafe impl Sync for Arena {} - unsafe impl Send for Arena {} - - impl Arena { - const fn new() -> Self { - Self { - buf: UnsafeCell::new(MaybeUninit::uninit()), - ptr: Mutex::new(Cell::new(null_mut())), + macro_rules! task_fn_impl { + ($($Tn:ident),*) => { + impl TaskFn<($($Tn,)*)> for F + where + F: Copy + FnOnce($($Tn,)*) -> Fut, + Fut: Future + 'static, + { + type Fut = Fut; } - } + }; + } - fn alloc(&'static self, cs: CriticalSection) -> &'static mut MaybeUninit { - let layout = Layout::new::(); + task_fn_impl!(); + task_fn_impl!(T0); + task_fn_impl!(T0, T1); + task_fn_impl!(T0, T1, T2); + task_fn_impl!(T0, T1, T2, T3); + task_fn_impl!(T0, T1, T2, T3, T4); + task_fn_impl!(T0, T1, T2, T3, T4, T5); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14); + task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15); - let start = self.buf.get().cast::(); - let end = unsafe { start.add(N) }; + #[allow(private_bounds)] + #[repr(C)] + pub struct TaskPoolHolder + where + Align: Alignment, + { + data: UnsafeCell<[MaybeUninit; SIZE]>, + align: Align, + } - let mut ptr = self.ptr.borrow(cs).get(); - if ptr.is_null() { - ptr = self.buf.get().cast::(); - } + unsafe impl Send for TaskPoolHolder where Align: Alignment {} + unsafe impl Sync for TaskPoolHolder where Align: Alignment {} - let bytes_left = (end as usize) - (ptr as usize); - let align_offset = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize); - - if align_offset + layout.size() > bytes_left { - panic!("embassy-executor: task arena is full. You must increase the arena size, see the documentation for details: https://docs.embassy.dev/embassy-executor/"); - } - - let res = unsafe { ptr.add(align_offset) }; - let ptr = unsafe { ptr.add(align_offset + layout.size()) }; - - self.ptr.borrow(cs).set(ptr); - - unsafe { &mut *(res as *mut MaybeUninit) } + #[allow(private_bounds)] + impl TaskPoolHolder + where + Align: Alignment, + { + pub const fn get(&self) -> *const u8 { + self.data.get().cast() } } - static ARENA: Arena<{ crate::config::TASK_ARENA_SIZE }> = Arena::new(); + #[allow(private_bounds)] + #[repr(transparent)] + pub struct Align([::Archetype; 0]) + where + Self: Alignment; - pub struct TaskPoolRef { - // type-erased `&'static mut TaskPool` - // Needed because statics can't have generics. - ptr: Mutex>, + trait Alignment { + /// A zero-sized type of particular alignment. + type Archetype: Copy + Eq + PartialEq + Send + Sync + Unpin; } - unsafe impl Sync for TaskPoolRef {} - unsafe impl Send for TaskPoolRef {} - impl TaskPoolRef { - pub const fn new() -> Self { - Self { - ptr: Mutex::new(Cell::new(null_mut())), - } - } - - /// Get the pool for this ref, allocating it from the arena the first time. - /// - /// safety: for a given TaskPoolRef instance, must always call with the exact - /// same generic params. - pub unsafe fn get(&'static self) -> &'static TaskPool { - critical_section::with(|cs| { - let ptr = self.ptr.borrow(cs); - if ptr.get().is_null() { - let pool = ARENA.alloc::>(cs); - pool.write(TaskPool::new()); - ptr.set(pool as *mut _ as _); + macro_rules! aligns { + ($($AlignX:ident: $n:literal,)*) => { + $( + #[derive(Copy, Clone, Eq, PartialEq)] + #[repr(align($n))] + struct $AlignX {} + impl Alignment for Align<$n> { + type Archetype = $AlignX; } - - unsafe { &*(ptr.get() as *const _) } - }) - } + )* + }; } + + aligns!( + Align1: 1, + Align2: 2, + Align4: 4, + Align8: 8, + Align16: 16, + Align32: 32, + Align64: 64, + Align128: 128, + Align256: 256, + Align512: 512, + Align1024: 1024, + Align2048: 2048, + Align4096: 4096, + Align8192: 8192, + Align16384: 16384, + ); + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] + aligns!( + Align32768: 32768, + Align65536: 65536, + Align131072: 131072, + Align262144: 262144, + Align524288: 524288, + Align1048576: 1048576, + Align2097152: 2097152, + Align4194304: 4194304, + Align8388608: 8388608, + Align16777216: 16777216, + Align33554432: 33554432, + Align67108864: 67108864, + Align134217728: 134217728, + Align268435456: 268435456, + Align536870912: 536870912, + ); } diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 78227c49c..4ae0e6a77 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] } embassy-nrf = { version = "0.3.1", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features = [] } diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 3f0d4cd78..fa4a7d44f 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] } embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = ["time-driver", "rp2040"] } embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] } diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index 2590e9c49..f32727ea8 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" } diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index fac73afd7..6a5a500de 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 587d303ab..dd3a32e45 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index b3c580d3d..0b9e9b96a 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 8c49be914..490541a2e 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index 28c74303a..c3aa31161 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml index deaf4c388..a89e2bb6e 100644 --- a/examples/boot/application/stm32wb-dfu/Cargo.toml +++ b/examples/boot/application/stm32wb-dfu/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index 890d0b510..f4d7ae712 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } -embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } +embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] } embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } diff --git a/examples/lpc55s69/Cargo.toml b/examples/lpc55s69/Cargo.toml index afd76f9ac..f5a6e6995 100644 --- a/examples/lpc55s69/Cargo.toml +++ b/examples/lpc55s69/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml index 3996939a5..7c382482a 100644 --- a/examples/mspm0c1104/Cargo.toml +++ b/examples/mspm0c1104/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c110x", "rt", "time-driver-any"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-128", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml index c1f304174..9bc82151c 100644 --- a/examples/mspm0g3507/Cargo.toml +++ b/examples/mspm0g3507/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g350x", "rt", "time-driver-any"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml index fc6f0e31b..a28ce2f11 100644 --- a/examples/mspm0g3519/Cargo.toml +++ b/examples/mspm0g3519/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g351x", "rt", "time-driver-any"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml index 6b87916b8..3962eb156 100644 --- a/examples/mspm0l1306/Cargo.toml +++ b/examples/mspm0l1306/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l130x", "rt", "time-driver-any"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-1024", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml index 9474c2ced..abebcc00d 100644 --- a/examples/mspm0l2228/Cargo.toml +++ b/examples/mspm0l2228/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l222x", "rt", "time-driver-any"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-1024", "arch-cortex-m", "executor-thread", "executor-interrupt"] } +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" diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml index b6760a428..97b5b924a 100644 --- a/examples/nrf51/Cargo.toml +++ b/examples/nrf51/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml index 297a52537..cd59b86c3 100644 --- a/examples/nrf52810/Cargo.toml +++ b/examples/nrf52810/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index f479d6af6..902193f3a 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 2a83633b4..459c43221 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index 12808fc2a..8848065d8 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } diff --git a/examples/nrf9151/ns/Cargo.toml b/examples/nrf9151/ns/Cargo.toml index 27def8455..03f38fd63 100644 --- a/examples/nrf9151/ns/Cargo.toml +++ b/examples/nrf9151/ns/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } diff --git a/examples/nrf9151/s/Cargo.toml b/examples/nrf9151/s/Cargo.toml index e57f199c6..ba88f6da3 100644 --- a/examples/nrf9151/s/Cargo.toml +++ b/examples/nrf9151/s/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml index 6965ce202..a720f2d61 100644 --- a/examples/nrf9160/Cargo.toml +++ b/examples/nrf9160/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 4fc1d35d6..45ca30e4c 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp2040"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml index c9e0ee120..345a915af 100644 --- a/examples/rp235x/Cargo.toml +++ b/examples/rp235x/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index a32e75d08..f00953167 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["log"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log"] } +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log"] } embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["log", "std", ] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index e611564eb..7aa4354ca 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f429zi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-tim4", "exti", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt" ] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml index 2c0c9a6c8..4d403bae8 100644 --- a/examples/stm32f469/Cargo.toml +++ b/examples/stm32f469/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Specific examples only for stm32f469 embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } defmt = "0.3" diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index e8b246184..9fbe2efc3 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32f777zi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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", "tcp", "dhcpv4", "medium-ethernet"] } embedded-io-async = { version = "0.6.1" } diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 5b80e5486..5631ff746 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32h563zi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 4c18bb21c..2f98542bb 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml index 148d09dd6..749fd78ae 100644 --- a/examples/stm32h723/Cargo.toml +++ b/examples/stm32h723/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32h723zg to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h723zg", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32h735/Cargo.toml b/examples/stm32h735/Cargo.toml index 1ae6ed253..4d31dedf1 100644 --- a/examples/stm32h735/Cargo.toml +++ b/examples/stm32h735/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h735ig", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml index e3efa0aa2..7c17bc766 100644 --- a/examples/stm32h755cm4/Cargo.toml +++ b/examples/stm32h755cm4/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm4", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml index 1f05c71b5..3186929a8 100644 --- a/examples/stm32h755cm7/Cargo.toml +++ b/examples/stm32h755cm7/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm7", "time-driver-tim3", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml index e0db3c0cd..e5f2dfe86 100644 --- a/examples/stm32h7b0/Cargo.toml +++ b/examples/stm32h7b0/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7b0vb", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml index a47dbe21e..22d59be04 100644 --- a/examples/stm32h7rs/Cargo.toml +++ b/examples/stm32h7rs/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32h743bi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "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"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "medium-ethernet", "medium-ip", "proto-ipv4"] } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 495c12936..b609110af 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l4s5vi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4r5zi", "memory-x", "time-driver-any", "exti", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } diff --git a/examples/stm32l432/Cargo.toml b/examples/stm32l432/Cargo.toml index 71bff8667..e155b3e66 100644 --- a/examples/stm32l432/Cargo.toml +++ b/examples/stm32l432/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l4s5vi to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l432kc", "memory-x", "time-driver-any", "exti", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "task-arena-size-32768", "arch-cortex-m", "executor-thread", "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" diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 7894abb38..fbf68c890 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32l552ze to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 33e75cf1e..886c5cb2e 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32u5g9zj to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u5g9zj", "time-driver-any", "memory-x" ] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index e9959b905..96f66f3af 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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 } diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 0f55bee39..60b09adb4 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" [dependencies] embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba55cg", "time-driver-any", "memory-x", "exti"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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 } diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 194e58459..6b677914e 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" # Change stm32wl55jc-cm4 to your chip name, if necessary. embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "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-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 6aa5e2bcc..410d62bdd 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml @@ -33,7 +33,7 @@ portable-atomic = { version = "1.6.0" } nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] nrf52832 = ["embassy-nrf/nrf52832", "easydma"] nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"] -nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts", "embassy-executor/task-arena-size-16384"] +nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"] nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"] nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"] diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 503c4d67b..1335aa84b 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -13,7 +13,7 @@ rp235xb = ["embassy-rp/rp235xb"] teleprobe-meta = "1.1" embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } -embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "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", ] } embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 9c3b2780a..a676aee53 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -39,7 +39,7 @@ spi-v1 = [] spi-v345 = [] cryp = [] hash = [] -eth = ["embassy-executor/task-arena-size-16384"] +eth = [] rng = [] sdmmc = [] stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] From 49badcff1a4f3e448f81a1703ee55e5bc2d368d4 Mon Sep 17 00:00:00 2001 From: Caleb Jamison Date: Fri, 28 Mar 2025 17:45:41 -0400 Subject: [PATCH 39/44] RP235x watchdog doesn't have the double count bug --- embassy-rp/src/watchdog.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs index 760d6aac2..49cf03850 100644 --- a/embassy-rp/src/watchdog.rs +++ b/embassy-rp/src/watchdog.rs @@ -89,17 +89,25 @@ impl Watchdog { /// Start the watchdog timer pub fn start(&mut self, period: Duration) { + #[cfg(feature = "rp2040")] + const MAX_PERIOD: u32 = 0xFFFFFF / 2; + #[cfg(feature = "_rp235x")] const MAX_PERIOD: u32 = 0xFFFFFF; let delay_us = period.as_micros(); - if delay_us > (MAX_PERIOD / 2) as u64 { - panic!("Period cannot exceed {} microseconds", MAX_PERIOD / 2); + if delay_us > (MAX_PERIOD) as u64 { + panic!("Period cannot exceed {} microseconds", MAX_PERIOD); } let delay_us = delay_us as u32; // Due to a logic error, the watchdog decrements by 2 and // the load value must be compensated; see RP2040-E1 - self.load_value = delay_us * 2; + // This errata is fixed in the RP235x + if cfg!(feature = "rp2040") { + self.load_value = delay_us * 2; + } else { + self.load_value = delay_us; + } self.enable(false); self.configure_wdog_reset_triggers(); From c72e2c5d100fd42acdd3a39f6250c112c2a37495 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sat, 29 Mar 2025 02:45:38 -0500 Subject: [PATCH 40/44] Add test --- embassy-executor/tests/ui.rs | 1 + embassy-executor/tests/ui/type_error.rs | 8 ++++++++ embassy-executor/tests/ui/type_error.stderr | 7 +++++++ 3 files changed, 16 insertions(+) create mode 100644 embassy-executor/tests/ui/type_error.rs create mode 100644 embassy-executor/tests/ui/type_error.stderr diff --git a/embassy-executor/tests/ui.rs b/embassy-executor/tests/ui.rs index be4679485..278a4b903 100644 --- a/embassy-executor/tests/ui.rs +++ b/embassy-executor/tests/ui.rs @@ -19,5 +19,6 @@ fn ui() { t.compile_fail("tests/ui/not_async.rs"); t.compile_fail("tests/ui/self_ref.rs"); t.compile_fail("tests/ui/self.rs"); + t.compile_fail("tests/ui/type_error.rs"); t.compile_fail("tests/ui/where_clause.rs"); } diff --git a/embassy-executor/tests/ui/type_error.rs b/embassy-executor/tests/ui/type_error.rs new file mode 100644 index 000000000..1734bc6c4 --- /dev/null +++ b/embassy-executor/tests/ui/type_error.rs @@ -0,0 +1,8 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] + +#[embassy_executor::task] +async fn task() { + 5 +} + +fn main() {} diff --git a/embassy-executor/tests/ui/type_error.stderr b/embassy-executor/tests/ui/type_error.stderr new file mode 100644 index 000000000..bce315811 --- /dev/null +++ b/embassy-executor/tests/ui/type_error.stderr @@ -0,0 +1,7 @@ +error[E0308]: mismatched types + --> tests/ui/type_error.rs:5:5 + | +4 | async fn task() { + | - help: try adding a return type: `-> i32` +5 | 5 + | ^ expected `()`, found integer From 35b353ab948256f4ae959767a7652c24bd42cd57 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sat, 29 Mar 2025 02:06:49 -0500 Subject: [PATCH 41/44] Fix ugly compiler errors --- embassy-executor-macros/src/macros/task.rs | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index 8a2a7fdb9..e5523c5cd 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs @@ -145,33 +145,39 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { }; #[cfg(not(feature = "nightly"))] let mut task_outer_body = quote! { - const fn __task_pool_size(_: F) -> usize + // We use Fut instead of F::Fut because F::Fut causes the compiler to generate some ugly + // unrelated errors when the task has a compile error. + const fn __task_pool_size(_: F) -> usize where - F: #embassy_executor::_export::TaskFn, + F: #embassy_executor::_export::TaskFn, + Fut: ::core::future::Future + 'static, { ::core::mem::size_of::< - #embassy_executor::raw::TaskPool + #embassy_executor::raw::TaskPool >() } - const fn __task_pool_align(_: F) -> usize + const fn __task_pool_align(_: F) -> usize where - F: #embassy_executor::_export::TaskFn, + F: #embassy_executor::_export::TaskFn, + Fut: ::core::future::Future + 'static, { ::core::mem::align_of::< - #embassy_executor::raw::TaskPool + #embassy_executor::raw::TaskPool >() } - const fn __task_pool_new(_: F) -> #embassy_executor::raw::TaskPool + const fn __task_pool_new(_: F) -> #embassy_executor::raw::TaskPool where - F: #embassy_executor::_export::TaskFn, + F: #embassy_executor::_export::TaskFn, + Fut: ::core::future::Future + 'static, { #embassy_executor::raw::TaskPool::new() } - const fn __task_pool_get(_: F) -> &'static #embassy_executor::raw::TaskPool + const fn __task_pool_get(_: F) -> &'static #embassy_executor::raw::TaskPool where - F: #embassy_executor::_export::TaskFn + F: #embassy_executor::_export::TaskFn, + Fut: ::core::future::Future + 'static, { unsafe { &*POOL.get().cast() } } From 034e9fc218f1a348f451f56a5b9f3941fc046b1a Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sat, 29 Mar 2025 02:45:48 -0500 Subject: [PATCH 42/44] Move macro helper functions to embassy-executor --- embassy-executor-macros/src/macros/task.rs | 35 ++-------------------- embassy-executor/src/lib.rs | 26 ++++++++++++++++ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index e5523c5cd..91d6beee8 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs @@ -145,35 +145,6 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { }; #[cfg(not(feature = "nightly"))] let mut task_outer_body = quote! { - // We use Fut instead of F::Fut because F::Fut causes the compiler to generate some ugly - // unrelated errors when the task has a compile error. - const fn __task_pool_size(_: F) -> usize - where - F: #embassy_executor::_export::TaskFn, - Fut: ::core::future::Future + 'static, - { - ::core::mem::size_of::< - #embassy_executor::raw::TaskPool - >() - } - const fn __task_pool_align(_: F) -> usize - where - F: #embassy_executor::_export::TaskFn, - Fut: ::core::future::Future + 'static, - { - ::core::mem::align_of::< - #embassy_executor::raw::TaskPool - >() - } - - const fn __task_pool_new(_: F) -> #embassy_executor::raw::TaskPool - where - F: #embassy_executor::_export::TaskFn, - Fut: ::core::future::Future + 'static, - { - #embassy_executor::raw::TaskPool::new() - } - const fn __task_pool_get(_: F) -> &'static #embassy_executor::raw::TaskPool where F: #embassy_executor::_export::TaskFn, @@ -184,9 +155,9 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { const POOL_SIZE: usize = #pool_size; static POOL: #embassy_executor::_export::TaskPoolHolder< - {__task_pool_size(#task_inner_ident)}, - {__task_pool_align(#task_inner_ident)}, - > = unsafe { ::core::mem::transmute(__task_pool_new(#task_inner_ident)) }; + {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)}, + {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)}, + > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) }; unsafe { __task_pool_get(#task_inner_ident)._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } }; diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 5485f6a6a..d6bd63665 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -59,6 +59,8 @@ pub mod _export { use core::future::Future; use core::mem::MaybeUninit; + use crate::raw::TaskPool; + pub trait TaskFn: Copy { type Fut: Future + 'static; } @@ -116,6 +118,30 @@ pub mod _export { } } + pub const fn task_pool_size(_: F) -> usize + where + F: TaskFn, + Fut: Future + 'static, + { + size_of::>() + } + + pub const fn task_pool_align(_: F) -> usize + where + F: TaskFn, + Fut: Future + 'static, + { + align_of::>() + } + + pub const fn task_pool_new(_: F) -> TaskPool + where + F: TaskFn, + Fut: Future + 'static, + { + TaskPool::new() + } + #[allow(private_bounds)] #[repr(transparent)] pub struct Align([::Archetype; 0]) From ca8be1c976b82a368622899fdf7192294bd81363 Mon Sep 17 00:00:00 2001 From: elagil Date: Sat, 29 Mar 2025 22:01:54 +0100 Subject: [PATCH 43/44] fix: stm32g4 calibration delays --- embassy-stm32/src/adc/g4.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 6a00e788e..6b9182ad6 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs @@ -171,7 +171,7 @@ impl<'d, T: Instance> Adc<'d, T> { reg.set_advregen(true); }); - blocking_delay_us(10); + blocking_delay_us(20); } fn configure_differential_inputs(&mut self) { @@ -191,6 +191,8 @@ impl<'d, T: Instance> Adc<'d, T> { while T::regs().cr().read().adcal() {} + blocking_delay_us(20); + T::regs().cr().modify(|w| { w.set_adcaldif(Adcaldif::DIFFERENTIAL); }); @@ -198,6 +200,8 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().cr().modify(|w| w.set_adcal(true)); while T::regs().cr().read().adcal() {} + + blocking_delay_us(20); } fn enable(&mut self) { From f396579dff18eea80555ed56a4905ce9d9fab574 Mon Sep 17 00:00:00 2001 From: Cyril Marpaud <9333398+cyril-marpaud@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:07:03 +0200 Subject: [PATCH 44/44] docs: fix a typo --- embassy-sync/src/zerocopy_channel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-sync/src/zerocopy_channel.rs b/embassy-sync/src/zerocopy_channel.rs index ad6fe74c5..e3e5b2538 100644 --- a/embassy-sync/src/zerocopy_channel.rs +++ b/embassy-sync/src/zerocopy_channel.rs @@ -195,7 +195,7 @@ pub struct Receiver<'a, M: RawMutex, T> { } impl<'a, M: RawMutex, T> Receiver<'a, M, T> { - /// Creates one further [`Sender`] over the same channel. + /// Creates one further [`Receiver`] over the same channel. pub fn borrow(&mut self) -> Receiver<'_, M, T> { Receiver { channel: self.channel } }