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
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]
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
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>,
pub(crate) registers: Option<Registers>,
#[serde(skip)]
pub(crate) variants: Vec<String>,
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
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)
}