Skip to content

Commit

Permalink
Add number functions for ptr -> N runtime query
Browse files Browse the repository at this point in the history
If you discard type information, it's nice to have a way to re-acquire
the N associated with a peripheral. This commit introduces the `number`
functions for that purpose. This can let users create thin drivers just
around a register block static reference, and only acquire the
number at runtime.

Document this new function as an advanced usage, along with one other
(unrelated) usage pattern.
  • Loading branch information
mciantyre committed Nov 7, 2022
1 parent d6557da commit f227302
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion raltool/src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ pub fn render(_opts: &super::Options, _ir: &IR, d: &Device) -> Result<TokenStrea
}
};

let number_fn: TokenStream;
let instances = if periphs.len() > 1
&& periphs
.iter()
.all(|periph| num_endings.is_match(&periph.name))
{
let mut instances = TokenStream::new();
let mut const_to_num: Vec<TokenStream> = Vec::new();
for peripheral in periphs.iter() {
let name = Ident::new(&peripheral.name, span);
let num = num_endings.captures(&peripheral.name).unwrap();
Expand All @@ -106,7 +108,7 @@ pub fn render(_opts: &super::Options, _ir: &IR, d: &Device) -> Result<TokenStrea
.and_then(|num| str::parse(num.as_str()).ok())
.unwrap(),
);

const_to_num.push(quote! { (#name, #num), });
instances.extend(quote! {
pub type #name = Instance<#num>;
impl crate::private::Sealed for #name {}
Expand All @@ -119,6 +121,14 @@ pub fn render(_opts: &super::Options, _ir: &IR, d: &Device) -> Result<TokenStrea
}
});
}
number_fn = quote! {
/// Returns the instance number `N` for a peripheral instance.
pub fn number(rb: *const RegisterBlock) -> Option<u8> {
[#(#const_to_num)*].into_iter()
.find(|(ptr, _)| core::ptr::eq(rb, *ptr))
.map(|(_, inst)| inst)
}
};
instances
} else {
assert!(
Expand All @@ -131,6 +141,12 @@ name."#
);
let peripheral = periphs.first().unwrap();
let name = Ident::new(&peripheral.name, span);
number_fn = quote! {
/// Returns the instance number `N` for a peripheral instance.
pub fn number(rb: *const RegisterBlock) -> Option<u8> {
core::ptr::eq(rb, #name).then_some(0)
}
};
quote! {
pub type #name = Instance<{crate::SOLE_INSTANCE}>;
impl crate::private::Sealed for #name {}
Expand All @@ -152,6 +168,7 @@ name."#

pub type Instance<const N: u8> = crate::Instance<RegisterBlock, N>;
#instances
#number_fn
}
})
}
Expand Down

0 comments on commit f227302

Please sign in to comment.