1use std::collections::HashMap;
2use std::fmt::{Display, Formatter, Result};
3
4use svd_parser::{Cluster, Device, Peripheral, Register, RegisterCluster, RegisterProperties};
5
6use crate::cluster::_Cluster;
7use crate::overrides::{DeviceOverrides, PeripheralOverrides};
8use crate::register::_Register;
9use crate::utils::{array_names, build_children, build_ident, merge_defaults};
10
11pub(super) struct _Peripheral<'a> {
12 pub(super) name: String,
13 description: Option<&'a String>,
14 features: Option<&'a Vec<String>>,
15 base_address: u64,
16 pub(super) clusters: Vec<_Cluster<'a>>,
17 pub(super) registers: Vec<_Register<'a>>,
18}
19
20impl<'a> _Peripheral<'a> {
21 pub(super) fn build(
22 peripheral: &'a Peripheral,
23 peripherals: &HashMap<String, &'a Peripheral>,
24 defaults: RegisterProperties,
25 overrides: Option<&'a HashMap<String, PeripheralOverrides>>,
26 ) -> _Peripheral<'a> {
27 let overrides = peripheral.overrides(overrides);
28 let children = peripheral
29 .registers(peripherals)
30 .expect("There should be no empty peripherals");
31 let mut clusters = HashMap::<String, &'a Cluster>::new();
32 let mut registers = HashMap::<String, &'a Register>::new();
33 Self::collect_clusters_and_registers(&children, &mut clusters, &mut registers);
34
35 let defaults = merge_defaults(
36 peripheral.default_register_properties(peripherals),
37 defaults,
38 );
39 let cluster_overrides = overrides.and_then(|overrides| overrides.clusters.as_ref());
40 let register_overrides = overrides.and_then(|overrides| overrides.registers.as_ref());
41 let (clusters, registers) = build_children(
42 children,
43 &clusters,
44 ®isters,
45 defaults,
46 cluster_overrides,
47 register_overrides,
48 );
49 _Peripheral {
50 name: peripheral.name(overrides),
51 description: peripheral.description(overrides),
52 features: overrides.and_then(|overrides| overrides.features.as_ref()),
53 base_address: peripheral.base_address,
54 clusters,
55 registers,
56 }
57 }
58
59 fn collect_clusters_and_registers(
60 children: &'a Vec<RegisterCluster>,
61 clusters: &mut HashMap<String, &'a Cluster>,
62 registers: &mut HashMap<String, &'a Register>,
63 ) {
64 for register_cluster in children {
65 match register_cluster {
66 RegisterCluster::Cluster(cluster) => {
67 match cluster {
68 Cluster::Single(single) => {
69 clusters.insert(single.name.clone(), cluster);
70 }
71 Cluster::Array(array, dim) => {
72 for name in array_names(&array.name, dim) {
73 clusters.insert(name, cluster);
74 }
75 }
76 }
77 Self::collect_clusters_and_registers(&cluster.children, clusters, registers);
78 }
79 RegisterCluster::Register(register) => match register {
80 Register::Single(single) => {
81 registers.insert(single.name.clone(), register);
82 }
83 Register::Array(array, dim) => {
84 for name in array_names(&array.name, dim) {
85 registers.insert(name, register);
86 }
87 }
88 },
89 }
90 }
91 }
92}
93
94impl<'a> Display for _Peripheral<'a> {
95 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
96 if let Some(description) = self.description {
97 write!(
98 f,
99 "#![doc = \"{description}\"]\n\n",
100 description = description
101 )?;
102 }
103 write!(
104 f,
105 "const BASE_ADDRESS: usize = {base_address:#X};\n\n",
106 base_address = self.base_address
107 )?;
108 write_children!(self, f);
109 Ok(())
110 }
111}
112
113pub(super) struct _Peripherals<'a>(Vec<_Peripheral<'a>>);
114
115impl<'a> _Peripherals<'a> {
116 pub(super) fn build(
117 device: &'a Device,
118 overrides: Option<&'a DeviceOverrides>,
119 ) -> _Peripherals<'a> {
120 let overrides = overrides.and_then(|overrides| overrides.peripherals.as_ref());
121 let mut peripherals = HashMap::<String, &'a Peripheral>::new();
122 for peripheral in &device.peripherals {
123 peripherals.insert(peripheral.name.clone(), peripheral);
124 }
125 let defaults = device.default_register_properties;
126 let mut collected = Vec::new();
127 for peripheral in &device.peripherals {
128 collected.push(_Peripheral::build(
129 &peripheral,
130 &peripherals,
131 defaults,
132 overrides,
133 ));
134 }
135 _Peripherals(collected)
136 }
137}
138
139impl<'a> Display for _Peripherals<'a> {
140 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
141 for peripheral in &self.0 {
142 if let Some(packages_cfg) = features_cfg!(peripheral) {
143 write!(f, "{}", packages_cfg)?;
144 }
145 write!(f, "pub mod {};\n", peripheral.name)?;
146 }
147 Ok(())
148 }
149}
150
151impl<'a> IntoIterator for _Peripherals<'a> {
152 type Item = <Vec<_Peripheral<'a>> as IntoIterator>::Item;
153 type IntoIter = <Vec<_Peripheral<'a>> as IntoIterator>::IntoIter;
154
155 fn into_iter(self) -> Self::IntoIter {
156 self.0.into_iter()
157 }
158}
159
160trait DerivedPeripheral<'a> {
161 fn name(&self, overrides: Option<&'a PeripheralOverrides>) -> String;
162
163 fn description(&'a self, overrides: Option<&'a PeripheralOverrides>) -> Option<&'a String>;
164
165 fn default_register_properties(
166 &'a self,
167 peripherals: &HashMap<String, &'a Peripheral>,
168 ) -> RegisterProperties;
169
170 fn registers(
171 &'a self,
172 peripherals: &HashMap<String, &'a Peripheral>,
173 ) -> Option<&'a Vec<RegisterCluster>>;
174
175 fn overrides(
176 &'a self,
177 overrides: Option<&'a HashMap<String, PeripheralOverrides>>,
178 ) -> Option<&'a PeripheralOverrides>;
179}
180
181impl<'a> DerivedPeripheral<'a> for Peripheral {
182 fn name(&self, overrides: Option<&'a PeripheralOverrides>) -> String {
183 build_ident(
184 overrides
185 .and_then(|overrides| overrides.name.as_ref())
186 .unwrap_or(&self.name),
187 )
188 }
189
190 fn description(&'a self, overrides: Option<&'a PeripheralOverrides>) -> Option<&'a String> {
191 overrides
192 .and_then(|overrides| overrides.description.as_ref())
193 .or(self.description.as_ref())
194 }
195
196 fn default_register_properties(
197 &'a self,
198 peripherals: &HashMap<String, &'a Peripheral>,
199 ) -> RegisterProperties {
200 self.derived_from
201 .as_ref()
202 .and_then(|name| peripherals.get(name))
203 .map(|p| p.default_register_properties(peripherals))
204 .map(|derived| merge_defaults(self.default_register_properties, derived))
205 .unwrap_or(self.default_register_properties)
206 }
207
208 fn registers(
209 &'a self,
210 peripherals: &HashMap<String, &'a Peripheral>,
211 ) -> Option<&'a Vec<RegisterCluster>> {
212 let derived = self
213 .derived_from
214 .as_ref()
215 .and_then(|name| peripherals.get(name))
216 .and_then(|&p| p.registers(peripherals));
217 self.registers.as_ref().or(derived)
218 }
219
220 fn overrides(
221 &'a self,
222 overrides: Option<&'a HashMap<String, PeripheralOverrides>>,
223 ) -> Option<&'a PeripheralOverrides> {
224 overrides!(self, overrides)
225 }
226}