ral_gen/
lib.rs

1//! Code generator for [ral](https://docs.rs/ral) crate
2//!
3//! # How to install
4//!
5//! ```bash
6//! $ cargo install ral-gen
7//! ```
8//!
9//! # How to use
10//!
11//! ```bash
12//! $ cargo ral-gen --svd <SVD file> --overrides <YML file> --out <Target dir>
13//! ```
14//! or short form
15//! ```bash
16//! $ cargo ral-gen -i <SVD file> -e <YML file> -o <Target dir>
17//! ```
18//!
19//! # Overrides
20//!
21//! Overrides can be specified in separate `yaml` file of the following structure
22//! ```yaml
23//! name: <alternate device name> // Must be identifier
24//! description: <alternate device description>
25//! peripherals:
26//!   <peripheral name>: // as can be found in .svd file
27//!     name: <alternate peripheral name> // Must be identifier
28//!     description: <alternate peripheral description>
29//!     features: // List of features for conditional compilation, e.g. packaging names
30//!       - <feature1> // to exclude peripheral if it's not available
31//!       - <feature2>
32//!     clusters:
33//!       <cluster name>: // as can be found in .svd file
34//!         name: <alternate cluster name> // Must be identifier
35//!         description: <alternate cluster description>
36//!         features: // List of features for conditional compilation, e.g. packaging names
37//!           - <feature1> // to exclude cluster if it's not available
38//!           - <feature2>
39//!     registers:
40//!         <register name>: // as can be found in .svd file
41//!           name: <alternate register name> // Must be identifier
42//!           description: <alternate register description>
43//!           features: // List of features for conditional compilation, e.g. packaging names
44//!             - <feature1> // to exclude register if it's not available
45//!             - <feature2>
46//!           uses: // use expressions required for field type overrides
47//!             - crate_name::types::CustomType
48//!           fields:
49//!             <field name>: // as can be found in .svd file
50//!               name: <alternate field name> // Must be identifier
51//!               description: <alternate field description>
52//!               type: CustomType // Required use expression must be specified in register's uses section
53//! ```
54//! All fields are optional
55//!
56//! # What will be generated
57//!
58//! Module structure described in [ral](https://docs.rs/ral) crate documentation will be generated
59//!
60//! Also `Cargo.toml` will be generated with content
61//! ```toml
62//! [package]
63//! name = "<device name in lowercase>"
64//! description = "<device description if present>"
65//! version = "<ral-gen version>"
66//! edition = "2018"
67//!
68//! [dependencies]
69//! ral = "<ral-gen version with patch section zeroed>"
70//!
71//! [features]
72//! feature1 = []
73//! feature2 = []
74//! ```
75use std::fs::File;
76use std::io::Read;
77use std::path::Path;
78
79use anyhow::Result;
80use svd_parser as svd;
81use svd_parser::Device;
82
83use crate::overrides::DeviceOverrides;
84use crate::package::_Package;
85
86#[macro_use]
87mod utils;
88mod cluster;
89mod device;
90mod field;
91mod generate;
92mod overrides;
93mod package;
94mod peripheral;
95mod register;
96
97/// Generates module structure
98pub fn generate(svd_file: &Path, overrides_file: Option<&Path>, project_dir: &Path) -> Result<()> {
99    let device = load_device(svd_file)?;
100    let overrides = load_overrides(overrides_file)?;
101    generate::generate_package(project_dir, _Package::build(&device, overrides.as_ref()))?;
102    Ok(())
103}
104
105fn load_device(svd_file: &Path) -> Result<Device> {
106    let file = &mut String::new();
107    File::open(svd_file)?.read_to_string(file)?;
108    svd::parse(file)
109}
110
111fn load_overrides(overrides_file: Option<&Path>) -> Result<Option<DeviceOverrides>> {
112    if overrides_file.is_none() {
113        return Ok(None);
114    }
115    let file = &mut String::new();
116    File::open(overrides_file.unwrap())?.read_to_string(file)?;
117
118    let overrides: DeviceOverrides = serde_yaml::from_str(file)?;
119    Ok(Some(overrides))
120}