ral_gen/
peripheral.rs

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            &registers,
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}