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
126
127
128
129
130
131
132
133
134
135
136
137
use super::{
access::Access,
deserialize_int, deserialize_int_opt,
register::{tree_reg, tree_remove_reg, Register, RegisterTree},
Device,
};
use anyhow::{anyhow, Result};
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer};
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Peripheral {
pub derived_from: Option<String>,
#[serde(default, deserialize_with = "deserialize_int_opt")]
pub dim: Option<u32>,
#[serde(default, deserialize_with = "deserialize_int_opt")]
pub dim_increment: Option<u32>,
pub name: String,
pub description: Option<String>,
pub alternate_peripheral: Option<String>,
#[serde(deserialize_with = "deserialize_int")]
pub base_address: u32,
#[serde(default, deserialize_with = "deserialize_int_opt")]
pub size: Option<u32>,
#[serde(default, deserialize_with = "deserialize_int_opt")]
pub reset_value: Option<u32>,
pub access: Option<Access>,
#[serde(default)]
pub interrupt: Vec<Interrupt>,
pub(crate) registers: Option<Registers>,
#[serde(skip)]
pub(crate) variants: Vec<String>,
}
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Interrupt {
pub name: String,
#[serde(default)]
pub description: String,
#[serde(deserialize_with = "deserialize_int")]
pub value: u32,
}
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Default, Deserialize)]
pub(crate) struct Registers {
#[serde(rename = "$value", deserialize_with = "deserialize_register_tree")]
pub(crate) tree: IndexMap<String, RegisterTree>,
}
impl Peripheral {
pub fn reg(&mut self, path: &str) -> &mut Register {
tree_reg(&mut self.registers.as_mut().unwrap().tree, path)
}
pub fn add_reg(&mut self, register: Register) {
self.registers
.get_or_insert_with(Default::default)
.tree
.insert(register.name.clone(), RegisterTree::Register(register));
}
pub fn new_reg(&mut self, f: impl FnOnce(&mut Register)) {
let mut register = Register::default();
f(&mut register);
self.add_reg(register);
}
pub fn remove_reg(&mut self, path: &str) -> Register {
tree_remove_reg(&mut self.registers.as_mut().unwrap().tree, path)
}
pub(crate) fn derived_from<'a>(&'a self, device: &'a Device) -> Result<Option<&'a Self>> {
Ok(if let Some(derived_from) = &self.derived_from {
Some(
device
.peripherals
.peripheral
.get(derived_from)
.ok_or_else(|| anyhow!("peripheral referenced in `derivedFrom` not found"))?,
)
} else {
None
})
}
pub(crate) fn description<'a>(&'a self, parent: Option<&'a Peripheral>) -> Result<&'a str> {
self.description
.as_ref()
.or_else(|| parent.and_then(|parent| parent.description.as_ref()))
.map(String::as_str)
.ok_or_else(|| anyhow!("peripheral description not found"))
}
}
fn deserialize_register_tree<'de, D>(
deserializer: D,
) -> Result<IndexMap<String, RegisterTree>, D::Error>
where
D: Deserializer<'de>,
{
let mut map = IndexMap::new();
for tree in Vec::<RegisterTree>::deserialize(deserializer)? {
let name = match &tree {
RegisterTree::Register(register) => register.name.clone(),
RegisterTree::Cluster(cluster) => cluster.name.clone(),
};
map.insert(name, tree);
}
Ok(map)
}