diff --git a/src/generate/peripheral.rs b/src/generate/peripheral.rs index 2a244c9c..cc95ae74 100644 --- a/src/generate/peripheral.rs +++ b/src/generate/peripheral.rs @@ -5,6 +5,7 @@ use std::fmt; use svd_parser::expand::{ derive_cluster, derive_peripheral, derive_register, BlockPath, Index, RegisterPath, }; +use syn::LitInt; use crate::config::Config; use crate::svd::{ @@ -77,6 +78,89 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result /// no stolen instances are passed to such software. }; + let per_to_tokens = |feature_attribute: &TokenStream, + description: &str, + p_ty: &Ident, + doc_alias: Option, + address: LitInt| + -> TokenStream { + let mut tokens = if config.raw_access { + quote! { + #[doc = #description] + #doc_alias + #feature_attribute + pub struct #p_ty { rb: #base::RegisterBlock } + + #feature_attribute + unsafe impl Send for #p_ty {} + + #feature_attribute + impl #p_ty { + #steal_docs + pub unsafe fn steal() -> Self { + Self { rb: #base::RegisterBlock::new(#address as *mut u8) } + } + } + + #feature_attribute + impl Deref for #p_ty { + type Target = #base::RegisterBlock; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.rb + } + } + } + } else { + quote! { + #[doc = #description] + #doc_alias + #feature_attribute + pub struct #p_ty { _marker: PhantomData<*const ()> } + + #feature_attribute + unsafe impl Send for #p_ty {} + + #feature_attribute + impl #p_ty { + ///Pointer to the register block + pub const PTR: *const #base::RegisterBlock = #address as *const _; + + ///Return the pointer to the register block + #[inline(always)] + pub const fn ptr() -> *const #base::RegisterBlock { + Self::PTR + } + + #steal_docs + pub unsafe fn steal() -> Self { + Self { _marker: PhantomData } + } + } + + #feature_attribute + impl Deref for #p_ty { + type Target = #base::RegisterBlock; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } + } + } + }; + tokens.extend(quote! { + #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() + } + } + }); + tokens + }; + match &p { Peripheral::Array(p, dim) => { let mut feature_names = Vec::with_capacity(dim.dim as _); @@ -94,81 +178,13 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result feature_attribute_n.extend(quote! { #[cfg(feature = #p_feature)] }) }; // Insert the peripherals structure - out.extend(if config.raw_access { - quote! { - #[doc = #description] - #doc_alias - #feature_attribute_n - pub struct #p_ty { rb: #base::RegisterBlock } - - #feature_attribute_n - unsafe impl Send for #p_ty {} - - #feature_attribute_n - impl #p_ty { - #steal_docs - pub unsafe fn steal() -> Self { - Self { rb: #base::RegisterBlock::new(#address as *mut u8) } - } - } - - #feature_attribute_n - impl Deref for #p_ty { - type Target = #base::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.rb - } - } - } - } else { - quote! { - #[doc = #description] - #doc_alias - #feature_attribute_n - pub struct #p_ty { _marker: PhantomData<*const ()> } - - #feature_attribute_n - unsafe impl Send for #p_ty {} - - #feature_attribute_n - impl #p_ty { - ///Pointer to the register block - pub const PTR: *const #base::RegisterBlock = #address as *const _; - - ///Return the pointer to the register block - #[inline(always)] - pub const fn ptr() -> *const #base::RegisterBlock { - Self::PTR - } - - #steal_docs - pub unsafe fn steal() -> Self { - Self { _marker: PhantomData } - } - } - - #feature_attribute_n - impl Deref for #p_ty { - type Target = #base::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } - } - } - }); - - out.extend(quote! { - #feature_attribute_n - impl core::fmt::Debug for #p_ty { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.debug_struct(#name_str).finish() - } - } - }); + out.extend(per_to_tokens( + &feature_attribute_n, + description, + &p_ty, + doc_alias, + address, + )); } let feature_any_attribute = quote! {#[cfg(any(#(feature = #feature_names),*))]}; @@ -191,79 +207,13 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result feature_attribute.extend(quote! { #[cfg(feature = #p_feature)] }) }; // Insert the peripheral structure - out.extend(if config.raw_access { - quote! { - #[doc = #description] - #feature_attribute - #[repr(transparent)] - pub struct #p_ty { rb: #base::RegisterBlock } - - #feature_attribute - unsafe impl Send for #p_ty {} - - #feature_attribute - impl #p_ty { - #steal_docs - pub unsafe fn steal() -> Self { - Self { rb: #base::RegisterBlock::new(#address as *mut u8) } - } - } - - #feature_attribute - impl Deref for #p_ty { - type Target = #base::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.rb - } - } - } - } else { - quote! { - #[doc = #description] - #feature_attribute - pub struct #p_ty { _marker: PhantomData<*const ()> } - - #feature_attribute - unsafe impl Send for #p_ty {} - - #feature_attribute - impl #p_ty { - ///Pointer to the register block - pub const PTR: *const #base::RegisterBlock = #address as *const _; - - ///Return the pointer to the register block - #[inline(always)] - pub const fn ptr() -> *const #base::RegisterBlock { - Self::PTR - } - - #steal_docs - pub unsafe fn steal() -> Self { - Self { _marker: PhantomData } - } - } - - #feature_attribute - impl Deref for #p_ty { - type Target = #base::RegisterBlock; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*Self::PTR } - } - } - } - }); - out.extend(quote! { - #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() - } - } - }); + out.extend(per_to_tokens( + &feature_attribute, + &description, + &p_ty, + None, + address, + )); // Derived peripherals may not require re-implementation, and will instead // use a single definition of the non-derived version.