aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-06-09 23:09:00 +0200
committerGitHub <[email protected]>2021-06-09 23:09:00 +0200
commit3d16e922d5fc87453f9c8eb43c6414b959e3da80 (patch)
tree31a39d194e10ea5b728d8a0046a9530c67590ea4
parent9d2f95c82f0b312760f4c95e5da035f164789b85 (diff)
parent9a2adec5843894e6e25c3f671e4a852821345429 (diff)
Merge pull request #237 from lulf/enable-clock-for-peris
Infer enable and reset registers based on RCC registry file
-rw-r--r--embassy-stm32/src/rng.rs4
-rw-r--r--stm32-metapac/build.rs91
2 files changed, 72 insertions, 23 deletions
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 704f1a97b..c2248c84d 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -24,6 +24,8 @@ pub struct Random<T: Instance> {
24 24
25impl<T: Instance> Random<T> { 25impl<T: Instance> Random<T> {
26 pub fn new(inner: impl Unborrow<Target = T>) -> Self { 26 pub fn new(inner: impl Unborrow<Target = T>) -> Self {
27 T::enable();
28 T::reset();
27 unborrow!(inner); 29 unborrow!(inner);
28 let mut random = Self { _inner: inner }; 30 let mut random = Self { _inner: inner };
29 random.reset(); 31 random.reset();
@@ -133,7 +135,7 @@ pub(crate) mod sealed {
133 } 135 }
134} 136}
135 137
136pub trait Instance: sealed::Instance {} 138pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral {}
137 139
138crate::pac::peripherals!( 140crate::pac::peripherals!(
139 (rng, $inst:ident) => { 141 (rng, $inst:ident) => {
diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs
index 008c9eb37..8118d8072 100644
--- a/stm32-metapac/build.rs
+++ b/stm32-metapac/build.rs
@@ -105,6 +105,30 @@ macro_rules! {} {{
105 .unwrap(); 105 .unwrap();
106} 106}
107 107
108fn find_reg_for_field<'c>(
109 rcc: &'c ir::IR,
110 reg_prefix: &str,
111 field_name: &str,
112) -> Option<(&'c str, &'c str)> {
113 rcc.fieldsets.iter().find_map(|(name, fieldset)| {
114 if name.starts_with(reg_prefix) {
115 fieldset
116 .fields
117 .iter()
118 .find_map(|field| {
119 if field_name == field.name {
120 return Some(field.name.as_str());
121 } else {
122 None
123 }
124 })
125 .map(|n| (name.as_str(), n))
126 } else {
127 None
128 }
129 })
130}
131
108fn main() { 132fn main() {
109 let dir = "../stm32-data/data"; 133 let dir = "../stm32-data/data";
110 134
@@ -131,6 +155,21 @@ fn main() {
131 peripherals: Vec::new(), 155 peripherals: Vec::new(),
132 }; 156 };
133 157
158 // Load RCC register for chip
159 let rcc = chip.peripherals.iter().find_map(|(name, p)| {
160 if name == "RCC" {
161 p.block.as_ref().map(|block| {
162 let bi = BlockInfo::parse(block);
163 let rcc_reg_path = Path::new(&dir)
164 .join("registers")
165 .join(&format!("{}_{}.yaml", bi.module, bi.version));
166 serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap()
167 })
168 } else {
169 None
170 }
171 });
172
134 let mut peripheral_versions: HashMap<String, String> = HashMap::new(); 173 let mut peripheral_versions: HashMap<String, String> = HashMap::new();
135 let mut pin_table: Vec<Vec<String>> = Vec::new(); 174 let mut pin_table: Vec<Vec<String>> = Vec::new();
136 let mut interrupt_table: Vec<Vec<String>> = Vec::new(); 175 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
@@ -217,30 +256,38 @@ fn main() {
217 }; 256 };
218 assert_eq!(p.address, dma_base + dma_stride * dma_num); 257 assert_eq!(p.address, dma_base + dma_stride * dma_num);
219 } 258 }
220 "spi" => { 259
221 if let Some(clock) = &p.clock { 260 _ => {}
222 // Workaround for APB1 register being split on some chip families. Assume 261 }
223 // first register until we can find a way to hint which register is used 262
224 let reg = clock.to_ascii_lowercase(); 263 if let Some(clock) = &p.clock {
225 let (enable_reg, reset_reg) = if chip.family == "STM32H7" && clock == "APB1" 264 if let Some(rcc) = &rcc {
226 { 265 // Workaround for clock registers being split on some chip families. Assume fields are
227 (format!("{}lenr", reg), format!("{}lrstr", reg)) 266 // named after peripheral and look for first field matching and use that register.
228 } else if chip.family.starts_with("STM32L4") && clock == "APB1" { 267 let en = find_reg_for_field(&rcc, clock, &format!("{}EN", name));
229 (format!("{}enr1", reg), format!("{}rstr1", reg)) 268 let rst = find_reg_for_field(&rcc, clock, &format!("{}RST", name));
230 } else { 269
231 (format!("{}enr", reg), format!("{}rstr", reg)) 270 match (en, rst) {
232 }; 271 (Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => {
233 let field = name.to_ascii_lowercase(); 272 peripheral_rcc_table.push(vec![
234 peripheral_rcc_table.push(vec![ 273 name.clone(),
235 name.clone(), 274 enable_reg.to_ascii_lowercase(),
236 enable_reg, 275 reset_reg.to_ascii_lowercase(),
237 reset_reg, 276 format!("set_{}", enable_field.to_ascii_lowercase()),
238 format!("set_{}en", field), 277 format!("set_{}", reset_field.to_ascii_lowercase()),
239 format!("set_{}rst", field), 278 ]);
240 ]); 279 }
280 (None, Some(_)) => {
281 println!("Unable to find enable register for {}", name)
282 }
283 (Some(_), None) => {
284 println!("Unable to find reset register for {}", name)
285 }
286 (None, None) => {
287 println!("Unable to find enable and reset register for {}", name)
288 }
241 } 289 }
242 } 290 }
243 _ => {}
244 } 291 }
245 } 292 }
246 293