aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/clocks.rs137
1 files changed, 71 insertions, 66 deletions
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index c70436695..67439fda3 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -8,6 +8,10 @@ use crate::gpio::sealed::Pin;
8use crate::gpio::AnyPin; 8use crate::gpio::AnyPin;
9use crate::{pac, reset, Peripheral}; 9use crate::{pac, reset, Peripheral};
10 10
11// NOTE: all gpin handling is commented out for future reference.
12// gpin is not usually safe to use during the boot init() call, so it won't
13// be very useful until we have runtime clock reconfiguration. once this
14// happens we can resurrect the commented-out gpin bits.
11struct Clocks { 15struct Clocks {
12 xosc: AtomicU32, 16 xosc: AtomicU32,
13 sys: AtomicU32, 17 sys: AtomicU32,
@@ -16,8 +20,8 @@ struct Clocks {
16 pll_usb: AtomicU32, 20 pll_usb: AtomicU32,
17 usb: AtomicU32, 21 usb: AtomicU32,
18 adc: AtomicU32, 22 adc: AtomicU32,
19 gpin0: AtomicU32, 23 // gpin0: AtomicU32,
20 gpin1: AtomicU32, 24 // gpin1: AtomicU32,
21 rosc: AtomicU32, 25 rosc: AtomicU32,
22 peri: AtomicU32, 26 peri: AtomicU32,
23 rtc: AtomicU16, 27 rtc: AtomicU16,
@@ -31,8 +35,8 @@ static CLOCKS: Clocks = Clocks {
31 pll_usb: AtomicU32::new(0), 35 pll_usb: AtomicU32::new(0),
32 usb: AtomicU32::new(0), 36 usb: AtomicU32::new(0),
33 adc: AtomicU32::new(0), 37 adc: AtomicU32::new(0),
34 gpin0: AtomicU32::new(0), 38 // gpin0: AtomicU32::new(0),
35 gpin1: AtomicU32::new(0), 39 // gpin1: AtomicU32::new(0),
36 rosc: AtomicU32::new(0), 40 rosc: AtomicU32::new(0),
37 peri: AtomicU32::new(0), 41 peri: AtomicU32::new(0),
38 rtc: AtomicU16::new(0), 42 rtc: AtomicU16::new(0),
@@ -47,8 +51,8 @@ pub enum PeriClkSrc {
47 PllUsb = ClkPeriCtrlAuxsrc::CLKSRC_PLL_USB.0, 51 PllUsb = ClkPeriCtrlAuxsrc::CLKSRC_PLL_USB.0,
48 Rosc = ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH.0, 52 Rosc = ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH.0,
49 Xosc = ClkPeriCtrlAuxsrc::XOSC_CLKSRC.0, 53 Xosc = ClkPeriCtrlAuxsrc::XOSC_CLKSRC.0,
50 Gpin0 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN0.0, 54 // Gpin0 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN0.0,
51 Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1.0, 55 // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1.0,
52} 56}
53 57
54#[non_exhaustive] 58#[non_exhaustive]
@@ -61,8 +65,8 @@ pub struct ClockConfig {
61 pub usb_clk: Option<UsbClkConfig>, 65 pub usb_clk: Option<UsbClkConfig>,
62 pub adc_clk: Option<AdcClkConfig>, 66 pub adc_clk: Option<AdcClkConfig>,
63 pub rtc_clk: Option<RtcClkConfig>, 67 pub rtc_clk: Option<RtcClkConfig>,
64 gpin0: Option<(u32, Gpin<'static, AnyPin>)>, 68 // gpin0: Option<(u32, Gpin<'static, AnyPin>)>,
65 gpin1: Option<(u32, Gpin<'static, AnyPin>)>, 69 // gpin1: Option<(u32, Gpin<'static, AnyPin>)>,
66} 70}
67 71
68impl ClockConfig { 72impl ClockConfig {
@@ -118,8 +122,8 @@ impl ClockConfig {
118 div_frac: 0, 122 div_frac: 0,
119 phase: 0, 123 phase: 0,
120 }), 124 }),
121 gpin0: None, 125 // gpin0: None,
122 gpin1: None, 126 // gpin1: None,
123 } 127 }
124 } 128 }
125 129
@@ -156,20 +160,20 @@ impl ClockConfig {
156 div_frac: 171, 160 div_frac: 171,
157 phase: 0, 161 phase: 0,
158 }), 162 }),
159 gpin0: None, 163 // gpin0: None,
160 gpin1: None, 164 // gpin1: None,
161 } 165 }
162 } 166 }
163 167
164 pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) { 168 // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) {
165 match P::NR { 169 // match P::NR {
166 0 => self.gpin0 = Some((hz, gpin.map_into())), 170 // 0 => self.gpin0 = Some((hz, gpin.map_into())),
167 1 => self.gpin1 = Some((hz, gpin.map_into())), 171 // 1 => self.gpin1 = Some((hz, gpin.map_into())),
168 _ => unreachable!(), 172 // _ => unreachable!(),
169 } 173 // }
170 // pin is now provisionally bound. if the config is applied it must be forgotten, 174 // // pin is now provisionally bound. if the config is applied it must be forgotten,
171 // or Gpin::drop will deconfigure the clock input. 175 // // or Gpin::drop will deconfigure the clock input.
172 } 176 // }
173} 177}
174 178
175#[repr(u16)] 179#[repr(u16)]
@@ -219,8 +223,8 @@ pub enum RefClkSrc {
219 Rosc, 223 Rosc,
220 // aux sources 224 // aux sources
221 PllUsb, 225 PllUsb,
222 Gpin0, 226 // Gpin0,
223 Gpin1, 227 // Gpin1,
224} 228}
225 229
226#[non_exhaustive] 230#[non_exhaustive]
@@ -233,8 +237,8 @@ pub enum SysClkSrc {
233 PllUsb, 237 PllUsb,
234 Rosc, 238 Rosc,
235 Xosc, 239 Xosc,
236 Gpin0, 240 // Gpin0,
237 Gpin1, 241 // Gpin1,
238} 242}
239 243
240pub struct SysClkConfig { 244pub struct SysClkConfig {
@@ -251,8 +255,8 @@ pub enum UsbClkSrc {
251 PllSys = ClkUsbCtrlAuxsrc::CLKSRC_PLL_SYS.0, 255 PllSys = ClkUsbCtrlAuxsrc::CLKSRC_PLL_SYS.0,
252 Rosc = ClkUsbCtrlAuxsrc::ROSC_CLKSRC_PH.0, 256 Rosc = ClkUsbCtrlAuxsrc::ROSC_CLKSRC_PH.0,
253 Xosc = ClkUsbCtrlAuxsrc::XOSC_CLKSRC.0, 257 Xosc = ClkUsbCtrlAuxsrc::XOSC_CLKSRC.0,
254 Gpin0 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN0.0, 258 // Gpin0 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN0.0,
255 Gpin1 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN1.0, 259 // Gpin1 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN1.0,
256} 260}
257 261
258pub struct UsbClkConfig { 262pub struct UsbClkConfig {
@@ -269,8 +273,8 @@ pub enum AdcClkSrc {
269 PllSys = ClkAdcCtrlAuxsrc::CLKSRC_PLL_SYS.0, 273 PllSys = ClkAdcCtrlAuxsrc::CLKSRC_PLL_SYS.0,
270 Rosc = ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH.0, 274 Rosc = ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH.0,
271 Xosc = ClkAdcCtrlAuxsrc::XOSC_CLKSRC.0, 275 Xosc = ClkAdcCtrlAuxsrc::XOSC_CLKSRC.0,
272 Gpin0 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN0.0, 276 // Gpin0 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN0.0,
273 Gpin1 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN1.0, 277 // Gpin1 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN1.0,
274} 278}
275 279
276pub struct AdcClkConfig { 280pub struct AdcClkConfig {
@@ -287,8 +291,8 @@ pub enum RtcClkSrc {
287 PllSys = ClkRtcCtrlAuxsrc::CLKSRC_PLL_SYS.0, 291 PllSys = ClkRtcCtrlAuxsrc::CLKSRC_PLL_SYS.0,
288 Rosc = ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH.0, 292 Rosc = ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH.0,
289 Xosc = ClkRtcCtrlAuxsrc::XOSC_CLKSRC.0, 293 Xosc = ClkRtcCtrlAuxsrc::XOSC_CLKSRC.0,
290 Gpin0 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN0.0, 294 // Gpin0 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN0.0,
291 Gpin1 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN1.0, 295 // Gpin1 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN1.0,
292} 296}
293 297
294pub struct RtcClkConfig { 298pub struct RtcClkConfig {
@@ -306,6 +310,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
306 // - USB, SYSCFG (breaks usb-to-swd on core1) 310 // - USB, SYSCFG (breaks usb-to-swd on core1)
307 let mut peris = reset::ALL_PERIPHERALS; 311 let mut peris = reset::ALL_PERIPHERALS;
308 peris.set_io_qspi(false); 312 peris.set_io_qspi(false);
313 // peris.set_io_bank0(false); // might be suicide if we're clocked from gpin
309 peris.set_pads_qspi(false); 314 peris.set_pads_qspi(false);
310 peris.set_pll_sys(false); 315 peris.set_pll_sys(false);
311 peris.set_pll_usb(false); 316 peris.set_pll_usb(false);
@@ -332,16 +337,16 @@ pub(crate) unsafe fn init(config: ClockConfig) {
332 reset::reset(peris); 337 reset::reset(peris);
333 reset::unreset_wait(peris); 338 reset::unreset_wait(peris);
334 339
335 let gpin0_freq = config.gpin0.map_or(0, |p| { 340 // let gpin0_freq = config.gpin0.map_or(0, |p| {
336 core::mem::forget(p.1); 341 // core::mem::forget(p.1);
337 p.0 342 // p.0
338 }); 343 // });
339 CLOCKS.gpin0.store(gpin0_freq, Ordering::Relaxed); 344 // CLOCKS.gpin0.store(gpin0_freq, Ordering::Relaxed);
340 let gpin1_freq = config.gpin1.map_or(0, |p| { 345 // let gpin1_freq = config.gpin1.map_or(0, |p| {
341 core::mem::forget(p.1); 346 // core::mem::forget(p.1);
342 p.0 347 // p.0
343 }); 348 // });
344 CLOCKS.gpin1.store(gpin1_freq, Ordering::Relaxed); 349 // CLOCKS.gpin1.store(gpin1_freq, Ordering::Relaxed);
345 350
346 let rosc_freq = match config.rosc { 351 let rosc_freq = match config.rosc {
347 Some(config) => configure_rosc(config), 352 Some(config) => configure_rosc(config),
@@ -381,8 +386,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
381 RefClkSrc::Xosc => (Src::XOSC_CLKSRC, Aux::CLKSRC_PLL_USB, xosc_freq / div), 386 RefClkSrc::Xosc => (Src::XOSC_CLKSRC, Aux::CLKSRC_PLL_USB, xosc_freq / div),
382 RefClkSrc::Rosc => (Src::ROSC_CLKSRC_PH, Aux::CLKSRC_PLL_USB, rosc_freq / div), 387 RefClkSrc::Rosc => (Src::ROSC_CLKSRC_PH, Aux::CLKSRC_PLL_USB, rosc_freq / div),
383 RefClkSrc::PllUsb => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_PLL_USB, pll_usb_freq / div), 388 RefClkSrc::PllUsb => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_PLL_USB, pll_usb_freq / div),
384 RefClkSrc::Gpin0 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN0, gpin0_freq / div), 389 // RefClkSrc::Gpin0 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN0, gpin0_freq / div),
385 RefClkSrc::Gpin1 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN1, gpin1_freq / div), 390 // RefClkSrc::Gpin1 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN1, gpin1_freq / div),
386 } 391 }
387 }; 392 };
388 assert!(clk_ref_freq != 0); 393 assert!(clk_ref_freq != 0);
@@ -409,8 +414,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
409 SysClkSrc::PllUsb => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_PLL_USB, pll_usb_freq), 414 SysClkSrc::PllUsb => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_PLL_USB, pll_usb_freq),
410 SysClkSrc::Rosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::ROSC_CLKSRC, rosc_freq), 415 SysClkSrc::Rosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::ROSC_CLKSRC, rosc_freq),
411 SysClkSrc::Xosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::XOSC_CLKSRC, xosc_freq), 416 SysClkSrc::Xosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::XOSC_CLKSRC, xosc_freq),
412 SysClkSrc::Gpin0 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN0, gpin0_freq), 417 // SysClkSrc::Gpin0 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN0, gpin0_freq),
413 SysClkSrc::Gpin1 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN1, gpin1_freq), 418 // SysClkSrc::Gpin1 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN1, gpin1_freq),
414 }; 419 };
415 assert!(config.sys_clk.div_int <= 0x1000000); 420 assert!(config.sys_clk.div_int <= 0x1000000);
416 let div = config.sys_clk.div_int as u64 * 256 + config.sys_clk.div_frac as u64; 421 let div = config.sys_clk.div_int as u64 * 256 + config.sys_clk.div_frac as u64;
@@ -445,8 +450,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
445 PeriClkSrc::PllUsb => pll_usb_freq, 450 PeriClkSrc::PllUsb => pll_usb_freq,
446 PeriClkSrc::Rosc => rosc_freq, 451 PeriClkSrc::Rosc => rosc_freq,
447 PeriClkSrc::Xosc => xosc_freq, 452 PeriClkSrc::Xosc => xosc_freq,
448 PeriClkSrc::Gpin0 => gpin0_freq, 453 // PeriClkSrc::Gpin0 => gpin0_freq,
449 PeriClkSrc::Gpin1 => gpin1_freq, 454 // PeriClkSrc::Gpin1 => gpin1_freq,
450 }; 455 };
451 assert!(peri_freq != 0); 456 assert!(peri_freq != 0);
452 CLOCKS.peri.store(peri_freq, Ordering::Relaxed); 457 CLOCKS.peri.store(peri_freq, Ordering::Relaxed);
@@ -470,8 +475,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
470 UsbClkSrc::PllSys => pll_sys_freq, 475 UsbClkSrc::PllSys => pll_sys_freq,
471 UsbClkSrc::Rosc => rosc_freq, 476 UsbClkSrc::Rosc => rosc_freq,
472 UsbClkSrc::Xosc => xosc_freq, 477 UsbClkSrc::Xosc => xosc_freq,
473 UsbClkSrc::Gpin0 => gpin0_freq, 478 // UsbClkSrc::Gpin0 => gpin0_freq,
474 UsbClkSrc::Gpin1 => gpin1_freq, 479 // UsbClkSrc::Gpin1 => gpin1_freq,
475 }; 480 };
476 assert!(usb_freq != 0); 481 assert!(usb_freq != 0);
477 assert!(conf.div >= 1 && conf.div <= 4); 482 assert!(conf.div >= 1 && conf.div <= 4);
@@ -493,8 +498,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
493 AdcClkSrc::PllSys => pll_sys_freq, 498 AdcClkSrc::PllSys => pll_sys_freq,
494 AdcClkSrc::Rosc => rosc_freq, 499 AdcClkSrc::Rosc => rosc_freq,
495 AdcClkSrc::Xosc => xosc_freq, 500 AdcClkSrc::Xosc => xosc_freq,
496 AdcClkSrc::Gpin0 => gpin0_freq, 501 // AdcClkSrc::Gpin0 => gpin0_freq,
497 AdcClkSrc::Gpin1 => gpin1_freq, 502 // AdcClkSrc::Gpin1 => gpin1_freq,
498 }; 503 };
499 assert!(adc_in_freq != 0); 504 assert!(adc_in_freq != 0);
500 assert!(conf.div >= 1 && conf.div <= 4); 505 assert!(conf.div >= 1 && conf.div <= 4);
@@ -519,8 +524,8 @@ pub(crate) unsafe fn init(config: ClockConfig) {
519 RtcClkSrc::PllSys => pll_sys_freq, 524 RtcClkSrc::PllSys => pll_sys_freq,
520 RtcClkSrc::Rosc => rosc_freq, 525 RtcClkSrc::Rosc => rosc_freq,
521 RtcClkSrc::Xosc => xosc_freq, 526 RtcClkSrc::Xosc => xosc_freq,
522 RtcClkSrc::Gpin0 => gpin0_freq, 527 // RtcClkSrc::Gpin0 => gpin0_freq,
523 RtcClkSrc::Gpin1 => gpin1_freq, 528 // RtcClkSrc::Gpin1 => gpin1_freq,
524 }; 529 };
525 assert!(rtc_in_freq != 0); 530 assert!(rtc_in_freq != 0);
526 assert!(config.sys_clk.div_int <= 0x1000000); 531 assert!(config.sys_clk.div_int <= 0x1000000);
@@ -576,12 +581,12 @@ pub fn xosc_freq() -> u32 {
576 CLOCKS.xosc.load(Ordering::Relaxed) 581 CLOCKS.xosc.load(Ordering::Relaxed)
577} 582}
578 583
579pub fn gpin0_freq() -> u32 { 584// pub fn gpin0_freq() -> u32 {
580 CLOCKS.gpin0.load(Ordering::Relaxed) 585// CLOCKS.gpin0.load(Ordering::Relaxed)
581} 586// }
582pub fn gpin1_freq() -> u32 { 587// pub fn gpin1_freq() -> u32 {
583 CLOCKS.gpin1.load(Ordering::Relaxed) 588// CLOCKS.gpin1.load(Ordering::Relaxed)
584} 589// }
585 590
586pub fn pll_sys_freq() -> u32 { 591pub fn pll_sys_freq() -> u32 {
587 CLOCKS.pll_sys.load(Ordering::Relaxed) 592 CLOCKS.pll_sys.load(Ordering::Relaxed)
@@ -705,9 +710,9 @@ impl<'d, T: Pin> Gpin<'d, T> {
705 } 710 }
706 } 711 }
707 712
708 fn map_into(self) -> Gpin<'d, AnyPin> { 713 // fn map_into(self) -> Gpin<'d, AnyPin> {
709 unsafe { core::mem::transmute(self) } 714 // unsafe { core::mem::transmute(self) }
710 } 715 // }
711} 716}
712 717
713impl<'d, T: Pin> Drop for Gpin<'d, T> { 718impl<'d, T: Pin> Drop for Gpin<'d, T> {
@@ -743,8 +748,8 @@ impl_gpoutpin!(PIN_25, 3);
743#[repr(u8)] 748#[repr(u8)]
744pub enum GpoutSrc { 749pub enum GpoutSrc {
745 PllSys = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS.0, 750 PllSys = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS.0,
746 Gpin0 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0.0, 751 // Gpin0 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0.0,
747 Gpin1 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1.0, 752 // Gpin1 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1.0,
748 PllUsb = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB.0, 753 PllUsb = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB.0,
749 Rosc = ClkGpoutCtrlAuxsrc::ROSC_CLKSRC.0, 754 Rosc = ClkGpoutCtrlAuxsrc::ROSC_CLKSRC.0,
750 Xosc = ClkGpoutCtrlAuxsrc::XOSC_CLKSRC.0, 755 Xosc = ClkGpoutCtrlAuxsrc::XOSC_CLKSRC.0,
@@ -813,8 +818,8 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
813 818
814 let base = match src { 819 let base = match src {
815 ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), 820 ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(),
816 ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), 821 // ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(),
817 ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), 822 // ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(),
818 ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), 823 ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(),
819 ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => rosc_freq(), 824 ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => rosc_freq(),
820 ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(), 825 ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(),