diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dc1d6f1..77c901d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] +- Use marker struct instead of address in `Periph` with `PeripheralSpec` trait + ## [v0.37.0] - 2025-08-14 - Fix new `mismatched-lifetime-syntaxes` lint warnings diff --git a/src/config.rs b/src/config.rs index e7b224fc..b2f1afd3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -284,11 +284,12 @@ impl IdentFormats { ("register".into(), pascal.clone()), ("cluster".into(), pascal.clone()), ("register_spec".into(), pascal.clone().suffix("Spec")), - ("peripheral".into(), pascal), + ("peripheral".into(), pascal.clone()), ( "peripheral_singleton".into(), IdentFormat::default().snake_case(), ), + ("peripheral_spec".into(), pascal.suffix("Spec")), ]); map @@ -309,7 +310,8 @@ impl IdentFormats { ("register".into(), constant.clone()), ("register_spec".into(), constant.clone().suffix("_SPEC")), ("peripheral".into(), constant.clone()), - ("peripheral_singleton".into(), constant), + ("peripheral_singleton".into(), constant.clone()), + ("peripheral_spec".into(), constant.suffix("_SPEC")), ]); map diff --git a/src/generate/generic.rs b/src/generate/generic.rs index e527a4a8..59b332de 100644 --- a/src/generate/generic.rs +++ b/src/generate/generic.rs @@ -1,19 +1,35 @@ use core::marker; /// Generic peripheral accessor -pub struct Periph { - _marker: marker::PhantomData, +pub struct Periph { + _marker: marker::PhantomData, } -unsafe impl Send for Periph {} +/// Peripheral data +pub trait PeripheralSpec { + /// RegisterBlock associated with peripheral + type RB; + /// Address of the register block + const ADDRESS: usize; + /// Debug name + const NAME: &'static str; +} + +unsafe impl Send for Periph {} + +impl core::fmt::Debug for Periph { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct(PER::NAME).finish() + } +} -impl Periph { +impl Periph { ///Pointer to the register block - pub const PTR: *const RB = A as *const _; + pub const PTR: *const PER::RB = PER::ADDRESS as *const _; ///Return the pointer to the register block #[inline(always)] - pub const fn ptr() -> *const RB { + pub const fn ptr() -> *const PER::RB { Self::PTR } @@ -37,8 +53,8 @@ impl Periph { } } -impl core::ops::Deref for Periph { - type Target = RB; +impl core::ops::Deref for Periph { + type Target = PER::RB; #[inline(always)] fn deref(&self) -> &Self::Target { diff --git a/src/generate/peripheral.rs b/src/generate/peripheral.rs index 618952eb..2b2ec74c 100644 --- a/src/generate/peripheral.rs +++ b/src/generate/peripheral.rs @@ -72,20 +72,25 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result feature_attribute: &TokenStream, doc: &str, p_ty: &Ident, + name_str: &str, doc_alias: Option, address: LitInt| { + let pspec = ident(name_str, config, "peripheral_spec", Span::call_site()); out.extend(quote! { #[doc = #doc] #phtml #doc_alias #feature_attribute - pub type #p_ty = crate::Periph<#base::RegisterBlock, #address>; + pub type #p_ty = crate::Periph<#pspec>; #feature_attribute - impl core::fmt::Debug for #p_ty { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.debug_struct(#name_str).finish() - } + pub struct #pspec; + + #feature_attribute + impl crate::PeripheralSpec for #pspec { + type RB = #base::RegisterBlock; + const ADDRESS: usize = #address; + const NAME: &'static str = #name_str; } }); }; @@ -113,6 +118,7 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result &feature_attribute_n, &doc, &p_ty, + &name_str, doc_alias, address, ); @@ -138,7 +144,15 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result feature_attribute.extend(quote! { #[cfg(feature = #p_feature)] }) }; // Insert the peripheral structure - per_to_tokens(&mut out, &feature_attribute, &doc, &p_ty, None, address); + per_to_tokens( + &mut out, + &feature_attribute, + &doc, + &p_ty, + &name_str, + None, + address, + ); // Derived peripherals may not require re-implementation, and will instead // use a single definition of the non-derived version.