diff options
| author | James Munns <[email protected]> | 2025-12-03 20:08:44 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-03 20:08:44 +0100 |
| commit | b75a6222e892cc58543b30f231b60dedaa0a5f5d (patch) | |
| tree | 8cccb88b8e61e3eac4bd0715a5370171ecb05ccd /src/clocks/periph_helpers.rs | |
| parent | 8798306fb2c124efc06443c2913c3d7a4919dd83 (diff) | |
Misc minor cleanups (#85)
Diffstat (limited to 'src/clocks/periph_helpers.rs')
| -rw-r--r-- | src/clocks/periph_helpers.rs | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/src/clocks/periph_helpers.rs b/src/clocks/periph_helpers.rs index 24d074e8a..1ea7a99ed 100644 --- a/src/clocks/periph_helpers.rs +++ b/src/clocks/periph_helpers.rs | |||
| @@ -41,6 +41,50 @@ pub trait SPConfHelper { | |||
| 41 | fn post_enable_config(&self, clocks: &Clocks) -> Result<u32, ClockError>; | 41 | fn post_enable_config(&self, clocks: &Clocks) -> Result<u32, ClockError>; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | /// Copy and paste macro that: | ||
| 45 | /// | ||
| 46 | /// * Sets the clocksel mux to `$selvar` | ||
| 47 | /// * Resets and halts the div, and applies the calculated div4 bits | ||
| 48 | /// * Releases reset + halt | ||
| 49 | /// * Waits for the div to stabilize | ||
| 50 | /// * Returns `Ok($freq / $conf.div.into_divisor())` | ||
| 51 | /// | ||
| 52 | /// Assumes: | ||
| 53 | /// | ||
| 54 | /// * self is a configuration struct that has a field called `div`, which | ||
| 55 | /// is a `Div4` | ||
| 56 | /// | ||
| 57 | /// usage: | ||
| 58 | /// | ||
| 59 | /// ```rust | ||
| 60 | /// apply_div4!(self, clksel, clkdiv, variant, freq) | ||
| 61 | /// ``` | ||
| 62 | /// | ||
| 63 | /// In the future if we make all the clksel+clkdiv pairs into commonly derivedFrom | ||
| 64 | /// registers, or if we put some kind of simple trait around those regs, we could | ||
| 65 | /// do this with something other than a macro, but for now, this is harm-reduction | ||
| 66 | /// to avoid incorrect copy + paste | ||
| 67 | macro_rules! apply_div4 { | ||
| 68 | ($conf:ident, $selreg:ident, $divreg:ident, $selvar:ident, $freq:ident) => {{ | ||
| 69 | // set clksel | ||
| 70 | $selreg.modify(|_r, w| w.mux().variant($selvar)); | ||
| 71 | |||
| 72 | // Set up clkdiv | ||
| 73 | $divreg.modify(|_r, w| { | ||
| 74 | unsafe { w.div().bits($conf.div.into_bits()) } | ||
| 75 | .halt() | ||
| 76 | .asserted() | ||
| 77 | .reset() | ||
| 78 | .asserted() | ||
| 79 | }); | ||
| 80 | $divreg.modify(|_r, w| w.halt().deasserted().reset().deasserted()); | ||
| 81 | |||
| 82 | while $divreg.read().unstab().is_unstable() {} | ||
| 83 | |||
| 84 | Ok($freq / $conf.div.into_divisor()) | ||
| 85 | }}; | ||
| 86 | } | ||
| 87 | |||
| 44 | // config types | 88 | // config types |
| 45 | 89 | ||
| 46 | /// This type represents a divider in the range 1..=16. | 90 | /// This type represents a divider in the range 1..=16. |
| @@ -217,22 +261,7 @@ impl SPConfHelper for Lpi2cConfig { | |||
| 217 | }, | 261 | }, |
| 218 | }; | 262 | }; |
| 219 | 263 | ||
| 220 | // set clksel | 264 | apply_div4!(self, clksel, clkdiv, variant, freq) |
| 221 | clksel.modify(|_r, w| w.mux().variant(variant)); | ||
| 222 | |||
| 223 | // Set up clkdiv | ||
| 224 | clkdiv.modify(|_r, w| { | ||
| 225 | unsafe { w.div().bits(self.div.into_bits()) } | ||
| 226 | .halt() | ||
| 227 | .asserted() | ||
| 228 | .reset() | ||
| 229 | .asserted() | ||
| 230 | }); | ||
| 231 | clkdiv.modify(|_r, w| w.halt().deasserted().reset().deasserted()); | ||
| 232 | |||
| 233 | while clkdiv.read().unstab().is_unstable() {} | ||
| 234 | |||
| 235 | Ok(freq / self.div.into_divisor()) | ||
| 236 | } | 265 | } |
| 237 | } | 266 | } |
| 238 | 267 | ||
| @@ -347,24 +376,7 @@ impl SPConfHelper for LpuartConfig { | |||
| 347 | }; | 376 | }; |
| 348 | 377 | ||
| 349 | // set clksel | 378 | // set clksel |
| 350 | clksel.modify(|_r, w| w.mux().variant(variant)); | 379 | apply_div4!(self, clksel, clkdiv, variant, freq) |
| 351 | |||
| 352 | // Set up clkdiv | ||
| 353 | clkdiv.modify(|_r, w| { | ||
| 354 | w.halt().asserted(); | ||
| 355 | w.reset().asserted(); | ||
| 356 | unsafe { w.div().bits(self.div.into_bits()) }; | ||
| 357 | w | ||
| 358 | }); | ||
| 359 | clkdiv.modify(|_r, w| { | ||
| 360 | w.halt().deasserted(); | ||
| 361 | w.reset().deasserted(); | ||
| 362 | w | ||
| 363 | }); | ||
| 364 | |||
| 365 | while clkdiv.read().unstab().is_unstable() {} | ||
| 366 | |||
| 367 | Ok(freq / self.div.into_divisor()) | ||
| 368 | } | 380 | } |
| 369 | } | 381 | } |
| 370 | 382 | ||
| @@ -482,25 +494,9 @@ impl SPConfHelper for AdcConfig { | |||
| 482 | return Ok(0); | 494 | return Ok(0); |
| 483 | } | 495 | } |
| 484 | }; | 496 | }; |
| 497 | let clksel = mrcc0.mrcc_adc_clksel(); | ||
| 498 | let clkdiv = mrcc0.mrcc_adc_clkdiv(); | ||
| 485 | 499 | ||
| 486 | // set clksel | 500 | apply_div4!(self, clksel, clkdiv, variant, freq) |
| 487 | mrcc0.mrcc_adc_clksel().modify(|_r, w| w.mux().variant(variant)); | ||
| 488 | |||
| 489 | // Set up clkdiv | ||
| 490 | mrcc0.mrcc_adc_clkdiv().modify(|_r, w| { | ||
| 491 | w.halt().asserted(); | ||
| 492 | w.reset().asserted(); | ||
| 493 | unsafe { w.div().bits(self.div.into_bits()) }; | ||
| 494 | w | ||
| 495 | }); | ||
| 496 | mrcc0.mrcc_adc_clkdiv().modify(|_r, w| { | ||
| 497 | w.halt().deasserted(); | ||
| 498 | w.reset().deasserted(); | ||
| 499 | w | ||
| 500 | }); | ||
| 501 | |||
| 502 | while mrcc0.mrcc_adc_clkdiv().read().unstab().is_unstable() {} | ||
| 503 | |||
| 504 | Ok(freq / self.div.into_divisor()) | ||
| 505 | } | 501 | } |
| 506 | } | 502 | } |
