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
mod access;
mod field;
mod peripheral;
mod register;
pub use self::{access::Access, field::Field, peripheral::Peripheral, register::Register};
pub(crate) use self::register::{Cluster, RegisterTree};
use anyhow::Result;
use indexmap::IndexMap;
use serde::{de, Deserialize, Deserializer};
use std::num::ParseIntError;
#[non_exhaustive]
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Device {
pub name: String,
#[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) peripherals: Peripherals,
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct Peripherals {
#[serde(default, deserialize_with = "deserialize_peripheral")]
pub(crate) peripheral: IndexMap<String, Peripheral>,
}
impl Device {
pub fn new(name: String) -> Self {
Self {
name,
size: None,
reset_value: None,
access: None,
peripherals: Peripherals::default(),
}
}
pub fn periph_names(&self) -> impl Iterator<Item = &String> + '_ {
self.peripherals.peripheral.keys()
}
pub fn periph(&mut self, name: &str) -> &mut Peripheral {
self.peripherals.peripheral.get_mut(name).unwrap()
}
pub fn add_periph(&mut self, peripheral: Peripheral) {
self.peripherals.peripheral.insert(peripheral.name.clone(), peripheral);
}
pub fn new_periph(&mut self, f: impl FnOnce(&mut Peripheral)) {
let mut peripheral = Peripheral::default();
f(&mut peripheral);
self.add_periph(peripheral);
}
pub fn remove_periph(&mut self, name: &str) -> Peripheral {
self.peripherals.peripheral.remove(name).unwrap()
}
}
fn deserialize_peripheral<'de, D>(deserializer: D) -> Result<IndexMap<String, Peripheral>, D::Error>
where
D: Deserializer<'de>,
{
let mut map = IndexMap::new();
for peripheral in Vec::<Peripheral>::deserialize(deserializer)? {
map.insert(peripheral.name.clone(), peripheral);
}
Ok(map)
}
fn deserialize_int<'de, D>(deserializer: D) -> Result<u32, D::Error>
where
D: Deserializer<'de>,
{
parse_int(&String::deserialize(deserializer)?).map_err(de::Error::custom)
}
fn deserialize_int_opt<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
where
D: Deserializer<'de>,
{
Option::<String>::deserialize(deserializer)?
.map_or(Ok(None), |s| parse_int(&s).map(Some).map_err(de::Error::custom))
}
fn parse_int(src: &str) -> Result<u32, ParseIntError> {
let mut range = 0..src.len();
let radix = if src.starts_with("0x") || src.starts_with("0X") {
range.start += 2;
16
} else if src.starts_with('0') && src.len() > 1 {
range.start += 1;
8
} else {
10
};
u32::from_str_radix(&src[range], radix)
}