Skip to content

Commit

Permalink
add register reader/writer links
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 7, 2023
1 parent d19c646 commit 196fe75
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]

- Fix when `atomics` features is generated but not enabled
- move hidden structs into module, add register reader/writer links into `SPEC` docs (#736)
- removed register writer & reader wrappers, generic `REG` in field writers (#731)
- Updated syn to version 2 (#732)
- Let readable field fetch doc from svd description (#734)
Expand Down
9 changes: 2 additions & 7 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,20 +245,15 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result

/// An enum describing the derivation status of an erc, which allows for disjoint arrays to be
/// implicitly derived from a common type.
#[derive(Debug, PartialEq)]
#[derive(Default, Debug, PartialEq)]
enum DeriveInfo {
#[default]
Root,
Explicit(RegisterPath),
Implicit(RegisterPath),
Cluster, // don't do anything different for clusters
}

impl Default for DeriveInfo {
fn default() -> Self {
DeriveInfo::Root
}
}

impl fmt::Display for DeriveInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
Expand Down
132 changes: 94 additions & 38 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
use quote::{quote, ToTokens};
use std::borrow::Cow;
use std::collections::HashSet;
use std::fmt::Write;
use svd_parser::expand::{
derive_enumerated_values, derive_field, BlockPath, EnumPath, FieldPath, Index, RegisterPath,
};
Expand Down Expand Up @@ -80,8 +81,24 @@ pub fn render(
} else {
return Err(anyhow!("Incorrect access of register {}", register.name));
};
let alias_doc =
format!("{name} ({accs}) register accessor: an alias for `Reg<{regspec_ident}>`");

let mut alias_doc = format!(
"{name} ({accs}) register accessor: {description}\n\n{}",
api_docs(
access.can_read(),
access.can_write(),
register.properties.reset_value.is_some(),
&name_snake_case,
false,
register.read_action,
)?
);
if name_snake_case != "cfg" {
alias_doc += format!(
"\n\nFor information about available fields see [`{name_snake_case}`] module"
)
.as_str();
}
let mut out = TokenStream::new();
out.extend(quote! {
#[doc = #alias_doc]
Expand All @@ -106,6 +123,68 @@ pub fn render(
}
}

fn api_docs(
can_read: bool,
can_write: bool,
can_reset: bool,
module: &Ident,
inmodule: bool,
read_action: Option<ReadAction>,
) -> Result<String, std::fmt::Error> {
fn method(s: &str) -> String {
format!("[`{s}`](crate::generic::Reg::{s})")
}

let mut doc = String::new();

if can_read {
write!(
doc,
"You can {} this register and get [`{module}::R`]{}. ",
method("read"),
if inmodule { "(R)" } else { "" },
)?;

if let Some(action) = read_action {
doc.push_str("WARN: ");
doc.push_str(match action {
ReadAction::Clear => "The register is **cleared** (set to zero) following a read operation.",
ReadAction::Set => "The register is **set** (set to ones) following a read operation.",
ReadAction::Modify => "The register is **modified** in some way after a read operation.",
ReadAction::ModifyExternal => "One or more dependent resources other than the current register are immediately affected by a read operation.",
});
}
doc.push(' ');
}

if can_write {
let mut methods = Vec::new();
if can_reset {
methods.push("reset");
methods.push("write");
}
methods.push("write_with_zero");
write!(
doc,
"You can {} this register using [`{module}::W`]{}. ",
methods
.iter()
.map(|m| method(m))
.collect::<Vec<_>>()
.join(", "),
if inmodule { "(W)" } else { "" },
)?;
}

if can_read && can_write {
write!(doc, "You can also {} this register. ", method("modify"),)?;
}

doc.push_str("See [API](https://docs.rs/svd2rust/#read--modify--write-api).");

Ok(doc)
}

pub fn render_register_mod(
register: &Register,
access: Access,
Expand Down Expand Up @@ -138,7 +217,6 @@ pub fn render_register_mod(
);

let mut mod_items = TokenStream::new();
let mut methods = vec![];

let can_read = access.can_read();
let can_write = access.can_write();
Expand All @@ -150,7 +228,6 @@ pub fn render_register_mod(
#[doc = #desc]
pub type R = crate::R<#regspec_ident>;
});
methods.push("read");
}

if can_write {
Expand All @@ -159,15 +236,6 @@ pub fn render_register_mod(
#[doc = #desc]
pub type W = crate::W<#regspec_ident>;
});
methods.push("write_with_zero");
if can_reset {
methods.push("reset");
methods.push("write");
}
}

if can_read && can_write {
methods.push("modify");
}

let mut r_impl_items = TokenStream::new();
Expand Down Expand Up @@ -310,29 +378,17 @@ pub fn render_register_mod(
close.to_tokens(&mut mod_items);
}

let methods = methods
.iter()
.map(|s| format!("[`{s}`](crate::generic::Reg::{s})"))
.collect::<Vec<_>>();
let mut doc = format!("{description}\n\nThis register you can {}. See [API](https://docs.rs/svd2rust/#read--modify--write-api).", methods.join(", "));

if name_snake_case != "cfg" {
doc += format!(
"\n\nFor information about available fields see [{name_snake_case}](index.html) module"
)
.as_str();
}

if can_read {
if let Some(action) = register.read_action {
doc += match action {
ReadAction::Clear => "\n\nThe register is **cleared** (set to zero) following a read operation.",
ReadAction::Set => "\n\nThe register is **set** (set to ones) following a read operation.",
ReadAction::Modify => "\n\nThe register is **modified** in some way after a read operation.",
ReadAction::ModifyExternal => "\n\nOne or more dependent resources other than the current register are immediately affected by a read operation.",
};
}
}
let doc = format!(
"{description}\n\n{}",
api_docs(
can_read,
can_write,
can_reset,
&name_snake_case,
true,
register.read_action,
)?
);

mod_items.extend(quote! {
#[doc = #doc]
Expand All @@ -344,15 +400,15 @@ pub fn render_register_mod(
});

if can_read {
let doc = format!("`read()` method returns [{name_snake_case}::R](R) reader structure",);
let doc = format!("`read()` method returns [`{name_snake_case}::R`](R) reader structure",);
mod_items.extend(quote! {
#[doc = #doc]
impl crate::Readable for #regspec_ident {}
});
}
if can_write {
let doc =
format!("`write(|w| ..)` method takes [{name_snake_case}::W](W) writer structure",);
format!("`write(|w| ..)` method takes [`{name_snake_case}::W`](W) writer structure",);

let zero_to_modify_fields_bitmap = util::hex(zero_to_modify_fields_bitmap);
let one_to_modify_fields_bitmap = util::hex(one_to_modify_fields_bitmap);
Expand Down

0 comments on commit 196fe75

Please sign in to comment.