Skip to content

Commit

Permalink
per_to_tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Jun 4, 2024
1 parent 9e2b681 commit 9062ce0
Showing 1 changed file with 98 additions and 148 deletions.
246 changes: 98 additions & 148 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<TokenStream>,
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 _);
Expand All @@ -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),*))]};
Expand All @@ -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.
Expand Down

0 comments on commit 9062ce0

Please sign in to comment.