Skip to content

Commit

Permalink
Emit RTIC-compatible Peripheral structs
Browse files Browse the repository at this point in the history
Hide the `steal()` method; it's only available for RTIC. Users should
call their own `instance()` methods.
  • Loading branch information
mciantyre committed Nov 7, 2022
1 parent 8b7721d commit 0b97844
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions raltool/src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn render(_opts: &super::Options, _ir: &IR, d: &Device) -> Result<TokenStrea
.push(peripheral)
}

for (mod_name, (block_path, periphs)) in block_to_peripherals {
for (mod_name, (block_path, periphs)) in &block_to_peripherals {
let mut consts = TokenStream::new();
for peripheral in periphs.iter() {
let name = Ident::new(&peripheral.name, span);
Expand Down Expand Up @@ -171,7 +171,7 @@ name."#
}
};

let mod_name = Ident::new(&mod_name, span);
let mod_name = Ident::new(mod_name, span);
peripherals.extend(quote! {
#[path = "."]
pub mod #mod_name {
Expand Down Expand Up @@ -229,5 +229,54 @@ name."#
pub const NVIC_PRIO_BITS: u8 = #bits;
});

//
// Emit RTIC peripheral struct.
//
let mut member_decls = TokenStream::new();
let mut member_inits = TokenStream::new();
for (mod_name, (_, peripherals)) in &block_to_peripherals {
for peripheral in peripherals {
let name = Ident::new(&peripheral.name, span);
let mod_name = Ident::new(mod_name, span);
member_decls.extend(quote! {
pub #name: #mod_name::#name,
});
member_inits.extend(quote! {
#name: #mod_name::#name::instance(),
});
}
}
out.extend(quote! {
/// Instances for all of this device's peripherals.
///
/// This is exposed for the RTIC framework. RTIC knows how
/// to safely acquire all instances so that you don't have
/// to use `unsafe`. See the RTIC documentation for more
/// information.
pub struct Peripherals {
#member_decls
}
impl Peripherals {
/// "Steal" all instances.
///
/// The name `steal()` is to meet RTIC requirements. Internally,
/// this constructor calls `instance()` on each member.
///
/// You shouldn't call this; let RTIC call this function.
///
/// # Safety
///
/// Since this calls `instance()` to initialize each of its members,
/// the `instance()` safety contract applies. See [the `Instance` safety
/// documentation](crate::Instance) for more information.
#[doc(hidden)] // This is only for RTIC.
pub const unsafe fn steal() -> Self {
Self {
#member_inits
}
}
}
});

Ok(out)
}

0 comments on commit 0b97844

Please sign in to comment.