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
use crate::{deserialize_int_opt, peripheral::Peripheral, Access};
use anyhow::Result;
use serde::{Deserialize, Deserializer};
use std::{
collections::{BTreeMap, HashSet},
fs::File,
io::Write,
};
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Deserialize)]
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]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Default, Deserialize)]
pub(crate) struct Peripherals {
#[serde(default, deserialize_with = "deserialize_peripheral")]
pub(crate) peripheral: BTreeMap<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(&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()
}
pub fn generate_regs(
self,
regs: &mut File,
except: &[&str],
pool_number: usize,
pool_size: usize,
) -> Result<()> {
let mut counter = 0;
for peripheral in self.peripherals.peripheral.values() {
if except.iter().any(|&name| name == peripheral.name) {
continue;
}
peripheral.generate_regs(&self, regs, pool_number, pool_size, &mut counter)?;
}
Ok(())
}
pub fn generate_rest(
self,
reg_index: &mut File,
interrupts: &mut File,
except: &[&str],
reg_index_macro: &str,
) -> Result<()> {
let mut int_names = HashSet::new();
writeln!(reg_index, "reg::tokens! {{")?;
writeln!(
reg_index,
" /// Defines an index of {} register tokens.",
self.name
)?;
writeln!(reg_index, " pub macro {};", reg_index_macro)?;
writeln!(
reg_index,
" use macro drone_cortex_m::map::cortex_m_reg_tokens;"
)?;
writeln!(reg_index, " super::inner;")?;
writeln!(reg_index, " crate::reg;")?;
for peripheral in self.peripherals.peripheral.values() {
peripheral.generate_rest(&self, &mut int_names, reg_index, interrupts, except)?;
}
writeln!(reg_index, "}}")?;
Ok(())
}
}
fn deserialize_peripheral<'de, D>(deserializer: D) -> Result<BTreeMap<String, Peripheral>, D::Error>
where
D: Deserializer<'de>,
{
let mut map = BTreeMap::new();
for peripheral in Vec::<Peripheral>::deserialize(deserializer)? {
map.insert(peripheral.name.clone(), peripheral);
}
Ok(map)
}