Skip to content

Commit

Permalink
Merge pull request #886 from rust-embedded/settings
Browse files Browse the repository at this point in the history
inline Settings into Config
  • Loading branch information
burrbull authored Nov 11, 2024
2 parents 74eee32 + 8776231 commit 660f3dd
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 45 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- Add `crate_path` setting
- Inline `Settings` into `Config`, add `settings_file`
- Fix MSP430 PAC inner attribute generation when used with the `-m` switch.

## [v0.34.0] - 2024-11-05
Expand Down
59 changes: 57 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use anyhow::{bail, Result};
use proc_macro2::Span;
use std::{
collections::HashMap,
ops::{Deref, DerefMut},
path::{Path, PathBuf},
str::FromStr,
};
use syn::{punctuated::Punctuated, Ident};

use crate::util::path_segment;

#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]
#[derive(Clone, PartialEq, Eq, Debug, Default)]
Expand Down Expand Up @@ -35,9 +40,10 @@ pub struct Config {
pub ident_formats_theme: Option<IdentFormatsTheme>,
pub field_names_for_enums: bool,
pub base_address_shift: u64,
pub html_url: Option<url::Url>,
/// Path to YAML file with chip-specific settings
pub settings: Option<PathBuf>,
pub settings_file: Option<PathBuf>,
/// Chip-specific settings
pub settings: Settings,
}

#[allow(clippy::upper_case_acronyms)]
Expand Down Expand Up @@ -320,8 +326,57 @@ pub enum IdentFormatsTheme {
#[non_exhaustive]
/// Chip-specific settings
pub struct Settings {
/// Path to chip HTML generated by svdtools
pub html_url: Option<url::Url>,
pub crate_path: Option<CratePath>,
/// RISC-V specific settings
pub riscv_config: Option<riscv::RiscvConfig>,
}

impl Settings {
pub fn update_from(&mut self, source: Self) {
if source.html_url.is_some() {
self.html_url = source.html_url;
}
if source.crate_path.is_some() {
self.crate_path = source.crate_path;
}
if source.riscv_config.is_some() {
self.riscv_config = source.riscv_config;
}
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct CratePath(pub syn::Path);

impl Default for CratePath {
fn default() -> Self {
let mut segments = Punctuated::new();
segments.push(path_segment(Ident::new("crate", Span::call_site())));
Self(syn::Path {
leading_colon: None,
segments,
})
}
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for CratePath {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Self::from_str(&s).unwrap())
}
}

impl FromStr for CratePath {
type Err = syn::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
syn::parse_str(&s).map(Self)
}
}

pub mod riscv;
27 changes: 3 additions & 24 deletions src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,6 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
}
};

let settings = match config.settings.as_ref() {
#[cfg(feature = "yaml")]
Some(settings) => {
let file = std::fs::read_to_string(settings).context("could not read settings file")?;
Some(serde_yaml::from_str(&file).context("could not parse settings file")?)
}
#[cfg(not(feature = "yaml"))]
Some(_) => {
return Err(anyhow::anyhow!("Support for yaml config files is not available because svd2rust was compiled without the yaml feature"));
}
None => None,
};

// make_mod option explicitly disables inner attributes.
if config.target == Target::Msp430 && !config.make_mod {
out.extend(quote! {
Expand Down Expand Up @@ -203,7 +190,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke

match config.target {
Target::RISCV => {
if settings.is_none() {
if config.settings.riscv_config.is_none() {
warn!("No settings file provided for RISC-V target. Using legacy interrupts rendering");
warn!("Please, consider migrating your PAC to riscv 0.12.0 or later");
out.extend(interrupt::render(
Expand All @@ -214,12 +201,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
)?);
} else {
debug!("Rendering RISC-V specific code");
out.extend(riscv::render(
&d.peripherals,
device_x,
settings.as_ref().unwrap(),
config,
)?);
out.extend(riscv::render(&d.peripherals, device_x, config)?);
}
}
_ => {
Expand All @@ -241,10 +223,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
// Core peripherals are handled above
continue;
}
if config.target == Target::RISCV
&& settings.is_some()
&& riscv::is_riscv_peripheral(p, settings.as_ref().unwrap())
{
if config.target == Target::RISCV && riscv::is_riscv_peripheral(p, &config.settings) {
// RISC-V specific peripherals are handled above
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
}
};

let phtml = config.html_url.as_ref().map(|url| {
let phtml = config.settings.html_url.as_ref().map(|url| {
let doc = format!("See peripheral [structure]({url}#{})", &path.peripheral);
quote!(#[doc = ""] #[doc = #doc])
});
Expand Down
2 changes: 1 addition & 1 deletion src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ fn api_docs(

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

if let Some(url) = config.html_url.as_ref() {
if let Some(url) = config.settings.html_url.as_ref() {
let first_idx = if let Register::Array(_, dim) = &register {
dim.indexes().next()
} else {
Expand Down
5 changes: 2 additions & 3 deletions src/generate/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub fn is_riscv_peripheral(p: &Peripheral, s: &Settings) -> bool {
pub fn render(
peripherals: &[Peripheral],
device_x: &mut String,
settings: &Settings,
config: &Config,
) -> Result<TokenStream> {
let mut mod_items = TokenStream::new();
Expand All @@ -30,7 +29,7 @@ pub fn render(
.as_ref()
.map(|feature| quote!(#[cfg_attr(feature = #feature, derive(defmt::Format))]));

if let Some(c) = settings.riscv_config.as_ref() {
if let Some(c) = config.settings.riscv_config.as_ref() {
if !c.core_interrupts.is_empty() {
debug!("Rendering target-specific core interrupts");
writeln!(device_x, "/* Core interrupt sources and trap handlers */")?;
Expand Down Expand Up @@ -216,7 +215,7 @@ pub fn render(
}

let mut riscv_peripherals = TokenStream::new();
if let Some(c) = &settings.riscv_config {
if let Some(c) = config.settings.riscv_config.as_ref() {
let harts = match c.harts.is_empty() {
true => vec![],
false => c
Expand Down
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,22 @@ pub fn generate(input: &str, config: &Config) -> Result<Generation> {
use std::fmt::Write;

let mut config = config.clone();

match config.settings_file.as_ref() {
#[cfg(feature = "yaml")]
Some(settings) => {
let file = std::fs::read_to_string(settings).context("could not read settings file")?;
config
.settings
.update_from(serde_yaml::from_str(&file).context("could not parse settings file")?)
}
#[cfg(not(feature = "yaml"))]
Some(_) => {
return Err(anyhow::anyhow!("Support for yaml config files is not available because svd2rust was compiled without the yaml feature"));
}
None => {}
};

let mut ident_formats = match config.ident_formats_theme {
Some(IdentFormatsTheme::Legacy) => IdentFormats::legacy_theme(),
_ => IdentFormats::default_theme(),
Expand Down
25 changes: 16 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn run() -> Result<()> {
.value_name("TOML_FILE"),
)
.arg(
Arg::new("settings")
Arg::new("settings_file")
.long("settings")
.help("Target-specific settings YAML file")
.action(ArgAction::Set)
Expand Down Expand Up @@ -276,14 +276,6 @@ Allowed cases are `unchanged` (''), `pascal` ('p'), `constant` ('c') and `snake`
Useful for soft-cores where the peripheral address range isn't necessarily fixed.
Ignore this option if you are not building your own FPGA based soft-cores."),
)
.arg(
Arg::new("html_url")
.long("html-url")
.alias("html_url")
.help("Path to chip HTML generated by svdtools")
.action(ArgAction::Set)
.value_name("URL"),
)
.arg(
Arg::new("log_level")
.long("log")
Expand Down Expand Up @@ -330,6 +322,21 @@ Ignore this option if you are not building your own FPGA based soft-cores."),
}
}

match config.settings_file.as_ref() {
#[cfg(feature = "yaml")]
Some(settings) => {
let file = std::fs::read_to_string(settings).context("could not read settings file")?;
config
.settings
.update_from(serde_yaml::from_str(&file).context("could not parse settings file")?)
}
#[cfg(not(feature = "yaml"))]
Some(_) => {
return Err(anyhow::anyhow!("Support for yaml config files is not available because svd2rust was compiled without the yaml feature"));
}
None => {}
};

if let Some(file) = config.input.as_ref() {
config.source_type = SourceType::from_path(file)
}
Expand Down
10 changes: 5 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,18 @@ pub fn block_path_to_ty(
config: &Config,
span: Span,
) -> TypePath {
let mut segments = Punctuated::new();
segments.push(path_segment(Ident::new("crate", span)));
segments.push(path_segment(ident(
let mut path = config.settings.crate_path.clone().unwrap_or_default().0;
path.segments.push(path_segment(ident(
&bpath.peripheral,
config,
"peripheral_mod",
span,
)));
for ps in &bpath.path {
segments.push(path_segment(ident(ps, config, "cluster_mod", span)));
path.segments
.push(path_segment(ident(ps, config, "cluster_mod", span)));
}
type_path(segments)
TypePath { qself: None, path }
}

pub fn register_path_to_ty(
Expand Down

0 comments on commit 660f3dd

Please sign in to comment.