1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#![feature(bool_to_option)]
#![feature(cell_update)]
#![feature(generator_trait)]
#![feature(generators)]
#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
#![warn(clippy::pedantic)]
#![allow(
clippy::cast_possible_truncation,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::module_name_repetitions,
clippy::must_use_candidate
)]
mod device;
mod register;
mod traverse;
mod variant;
pub use device::{Access, Device, Field, Peripheral, Register};
use self::{
register::{generate_index, generate_registers},
variant::trace_variants,
};
use anyhow::{anyhow, Result};
use std::{
env,
fs::File,
io::{prelude::*, BufReader},
mem,
ops::Range,
path::Path,
};
pub struct Config<'a> {
macro_name: &'a str,
bit_band: Option<Range<u32>>,
exclude_peripherals: Vec<&'a str>,
}
impl<'a> Config<'a> {
pub fn new(macro_name: &'a str) -> Self {
Self { macro_name, bit_band: None, exclude_peripherals: Vec::new() }
}
pub fn exclude_peripherals(&mut self, exclude_peripherals: &[&'a str]) -> &mut Self {
self.exclude_peripherals.extend(exclude_peripherals);
self
}
pub fn bit_band(&mut self, bit_band: Range<u32>) -> &mut Self {
self.bit_band = Some(bit_band);
self
}
pub fn generate_regs(
self,
output: &mut File,
mut device: Device,
pool_number: usize,
pool_size: usize,
) -> Result<()> {
normalize(&mut device);
trace_variants(&mut device, &self)?;
generate_registers(output, &device, pool_number, pool_size, &self)?;
Ok(())
}
pub fn generate_index(self, index_output: &mut File, mut device: Device) -> Result<()> {
normalize(&mut device);
trace_variants(&mut device, &self)?;
generate_index(index_output, &device, &self)?;
Ok(())
}
}
pub fn parse<P: AsRef<Path>>(path: P) -> Result<Device> {
let mut input = BufReader::new(File::open(path)?);
let mut xml = String::new();
input.read_to_string(&mut xml)?;
serde_xml_rs::from_reader(xml.as_bytes()).map_err(|err| anyhow!("{}", err))
}
pub fn rerun_if_env_changed() {
for (var, _) in env::vars_os() {
if let Some(var) = var.to_str() {
if var.ends_with("RUSTFLAGS") {
println!("cargo:rerun-if-env-changed={}", var);
}
}
}
}
fn normalize(device: &mut Device) {
device.peripherals.peripheral = mem::take(&mut device.peripherals.peripheral)
.into_iter()
.map(|(_, peripheral)| (peripheral.name.clone(), peripheral))
.collect();
}