mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 17:17:08 +09:00
new(CodeGen): for Block
This commit is contained in:
parent
dfd28782dd
commit
6b5b5e0234
5 changed files with 90 additions and 25 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -79,6 +79,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"heck",
|
||||||
"log",
|
"log",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -109,6 +110,12 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
|
|
@ -14,6 +14,7 @@ path = "src/lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.95"
|
anyhow = "1.0.95"
|
||||||
env_logger = "0.11.6"
|
env_logger = "0.11.6"
|
||||||
|
heck = "0.5"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
proc-macro2 = "1.0.93"
|
proc-macro2 = "1.0.93"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
//! Generate register interface rust code from types in [`crate::types`].
|
//! Generate register interface rust code from types in [`crate::types`].
|
||||||
|
|
||||||
use crate::types::{Block, Module, ModuleBlockElements};
|
use crate::{
|
||||||
|
type_traits::GetName,
|
||||||
|
types::{Block, Module, ModuleBlockElements},
|
||||||
|
};
|
||||||
|
use heck::{ToSnakeCase, ToUpperCamelCase};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
|
@ -40,43 +44,65 @@ impl CodeGen for ModuleBlockElements {
|
||||||
|
|
||||||
impl CodeGen for Block {
|
impl CodeGen for Block {
|
||||||
fn generate_register_interface(self) -> proc_macro2::TokenStream {
|
fn generate_register_interface(self) -> proc_macro2::TokenStream {
|
||||||
let name = self.name;
|
let snake_case_name = self.name.to_snake_case();
|
||||||
|
let upper_camel_name = self.name.to_upper_camel_case();
|
||||||
|
let addr = format!("0x{:x}", self.addr);
|
||||||
let desc = self.desc.unwrap_or("".to_string());
|
let desc = self.desc.unwrap_or("".to_string());
|
||||||
|
|
||||||
|
let accessor_methods = {
|
||||||
|
let mut out = TokenStream::new();
|
||||||
|
for child_name in self.elements.iter().map(|e| e.get_name()) {
|
||||||
|
let snake_case_name = child_name.to_snake_case();
|
||||||
|
let upper_camel_name = child_name.to_upper_camel_case();
|
||||||
|
|
||||||
|
out.extend(quote! {
|
||||||
|
pub fn #snake_case_name(&self) -> #snake_case_name::#upper_camel_name {
|
||||||
|
#snake_case_name::#upper_camel_name::new(self.mem_ptr)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
};
|
||||||
|
|
||||||
|
let child_mods = {
|
||||||
|
let mut out = TokenStream::new();
|
||||||
|
for child_mod in self.elements.into_iter() {
|
||||||
|
let module = child_mod.generate_register_interface();
|
||||||
|
out.extend(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
pub mod #name {
|
pub mod #snake_case_name {
|
||||||
#[doc = #desc]
|
#[doc = #desc]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use super::RegisterInterface;
|
use super::RegisterInterface;
|
||||||
|
|
||||||
pub mod control;
|
#child_mods
|
||||||
pub mod status;
|
|
||||||
|
|
||||||
pub(crate) const SLR0_OFFSET: usize = 0x0000;
|
const OFFSET: usize = #addr;
|
||||||
pub(crate) const SLR0_SIZE: usize = 0x4000;
|
//pub(crate) const SIZE: usize = 0x4000;
|
||||||
|
|
||||||
/// Access to SLR0.
|
/// Access to SLR0.
|
||||||
pub struct Slr0<'a> {
|
pub struct #upper_camel_name<'a> {
|
||||||
mem_ptr: *mut u32,
|
mem_ptr: *mut u32,
|
||||||
_marker: PhantomData<&'a mut RegisterInterface>,
|
_marker: PhantomData<&'a mut RegisterInterface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slr0<'_> {
|
impl #upper_camel_name<'_> {
|
||||||
pub(crate) fn new(ptr: *mut u32) -> Self {
|
pub(crate) fn new(parent_ptr: *mut u32) -> Self {
|
||||||
Slr0 {
|
#upper_camel_name {
|
||||||
mem_ptr: ptr,
|
mem_ptr: unsafe { parent_ptr.add(OFFSET) },
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn control(&self) -> control::Control {
|
|
||||||
control::Control::new(unsafe { self.mem_ptr.add(control::OFFSET) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn status(&self) -> status::Status {
|
#accessor_methods
|
||||||
status::Status::new(unsafe { self.mem_ptr.add(status::OFFSET) })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Root document [`types::Module::from_xml_dom`]
|
//! Root document [`types::Module::from_xml_dom`]
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod type_traits;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod converter;
|
pub mod converter;
|
||||||
pub mod generator;
|
pub mod generator;
|
||||||
|
|
30
src/type_traits.rs
Normal file
30
src/type_traits.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//! Util traits to get info from types in [`crate::types`].
|
||||||
|
|
||||||
|
use crate::types::{Block, ModuleBlockElements, Register};
|
||||||
|
|
||||||
|
pub(crate) trait GetName {
|
||||||
|
fn get_name(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetName for ModuleBlockElements {
|
||||||
|
fn get_name(&self) -> String {
|
||||||
|
match self {
|
||||||
|
ModuleBlockElements::Block(block) => block.get_name(),
|
||||||
|
ModuleBlockElements::Register(register) => register.get_name(),
|
||||||
|
ModuleBlockElements::Memory(memory) => todo!(),
|
||||||
|
ModuleBlockElements::Fifo(fifo) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetName for Block {
|
||||||
|
fn get_name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetName for Register {
|
||||||
|
fn get_name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue