aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/clocks.rs214
-rw-r--r--examples/rp/src/bin/gpout.rs4
2 files changed, 148 insertions, 70 deletions
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index dc8505987..6d389cace 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -6,11 +6,18 @@ use crate::{pac, reset, Peripheral};
6// TODO fix terrible use of global here 6// TODO fix terrible use of global here
7static mut XIN_HZ: u32 = 0; 7static mut XIN_HZ: u32 = 0;
8 8
9pub use rp_pac::clocks::vals::{ 9#[repr(u8)]
10 ClkAdcCtrlAuxsrc as AdcAuxsrc, ClkGpoutCtrlAuxsrc as GpoutSrc, ClkPeriCtrlAuxsrc as PeriClkAuxsrc, 10#[non_exhaustive]
11 ClkRefCtrlAuxsrc as RefAuxsrc, ClkRtcCtrlAuxsrc as RtcAuxsrc, ClkSysCtrlAuxsrc as SysAuxsrc, 11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12 ClkUsbCtrlAuxsrc as UsbAuxsrc, 12pub enum PeriClkSrc {
13}; 13 Sys = ClkPeriCtrlAuxsrc::CLK_SYS.0,
14 PllSys = ClkPeriCtrlAuxsrc::CLKSRC_PLL_SYS.0,
15 PllUsb = ClkPeriCtrlAuxsrc::CLKSRC_PLL_USB.0,
16 Rosc = ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH.0,
17 Xosc = ClkPeriCtrlAuxsrc::XOSC_CLKSRC.0,
18 Gpin0 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN0.0,
19 Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1.0,
20}
14 21
15#[non_exhaustive] 22#[non_exhaustive]
16pub struct ClockConfig { 23pub struct ClockConfig {
@@ -18,7 +25,7 @@ pub struct ClockConfig {
18 pub xosc: Option<XoscConfig>, 25 pub xosc: Option<XoscConfig>,
19 pub ref_clk: RefClkConfig, 26 pub ref_clk: RefClkConfig,
20 pub sys_clk: SysClkConfig, 27 pub sys_clk: SysClkConfig,
21 pub peri_clk_src: Option<ClkPeriCtrlAuxsrc>, 28 pub peri_clk_src: Option<PeriClkSrc>,
22 pub usb_clk: Option<UsbClkConfig>, 29 pub usb_clk: Option<UsbClkConfig>,
23 pub adc_clk: Option<AdcClkConfig>, 30 pub adc_clk: Option<AdcClkConfig>,
24 pub rtc_clk: Option<RtcClkConfig>, 31 pub rtc_clk: Option<RtcClkConfig>,
@@ -28,7 +35,7 @@ impl ClockConfig {
28 pub fn crystal(crystal_hz: u32) -> Self { 35 pub fn crystal(crystal_hz: u32) -> Self {
29 Self { 36 Self {
30 rosc: Some(RoscConfig { 37 rosc: Some(RoscConfig {
31 range: pac::rosc::vals::FreqRange::MEDIUM, 38 range: RoscRange::Medium,
32 drive_strength: [0; 8], 39 drive_strength: [0; 8],
33 div: 16, 40 div: 16,
34 }), 41 }),
@@ -52,23 +59,23 @@ impl ClockConfig {
52 div: 1, 59 div: 1,
53 }, 60 },
54 sys_clk: SysClkConfig { 61 sys_clk: SysClkConfig {
55 src: SysClkSrc::Aux(ClkSysCtrlAuxsrc::CLKSRC_PLL_SYS), 62 src: SysClkSrc::PllSys,
56 div_int: 1, 63 div_int: 1,
57 div_frac: 0, 64 div_frac: 0,
58 }, 65 },
59 peri_clk_src: Some(ClkPeriCtrlAuxsrc::CLK_SYS), 66 peri_clk_src: Some(PeriClkSrc::Sys),
60 usb_clk: Some(UsbClkConfig { 67 usb_clk: Some(UsbClkConfig {
61 src: ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB, 68 src: UsbClkSrc::PllUsb,
62 div: 1, 69 div: 1,
63 phase: 0, 70 phase: 0,
64 }), 71 }),
65 adc_clk: Some(AdcClkConfig { 72 adc_clk: Some(AdcClkConfig {
66 src: ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB, 73 src: AdcClkSrc::PllUsb,
67 div: 1, 74 div: 1,
68 phase: 0, 75 phase: 0,
69 }), 76 }),
70 rtc_clk: Some(RtcClkConfig { 77 rtc_clk: Some(RtcClkConfig {
71 src: ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB, 78 src: RtcClkSrc::PllUsb,
72 div_int: 1024, 79 div_int: 1024,
73 div_frac: 0, 80 div_frac: 0,
74 phase: 0, 81 phase: 0,
@@ -79,7 +86,7 @@ impl ClockConfig {
79 pub fn rosc() -> Self { 86 pub fn rosc() -> Self {
80 Self { 87 Self {
81 rosc: Some(RoscConfig { 88 rosc: Some(RoscConfig {
82 range: pac::rosc::vals::FreqRange::HIGH, 89 range: RoscRange::High,
83 drive_strength: [0; 8], 90 drive_strength: [0; 8],
84 div: 1, 91 div: 1,
85 }), 92 }),
@@ -89,19 +96,19 @@ impl ClockConfig {
89 div: 1, 96 div: 1,
90 }, 97 },
91 sys_clk: SysClkConfig { 98 sys_clk: SysClkConfig {
92 src: SysClkSrc::Aux(ClkSysCtrlAuxsrc::ROSC_CLKSRC), 99 src: SysClkSrc::Rosc,
93 div_int: 1, 100 div_int: 1,
94 div_frac: 0, 101 div_frac: 0,
95 }, 102 },
96 peri_clk_src: Some(ClkPeriCtrlAuxsrc::ROSC_CLKSRC_PH), 103 peri_clk_src: Some(PeriClkSrc::Rosc),
97 usb_clk: None, 104 usb_clk: None,
98 adc_clk: Some(AdcClkConfig { 105 adc_clk: Some(AdcClkConfig {
99 src: ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH, 106 src: AdcClkSrc::Rosc,
100 div: 1, 107 div: 1,
101 phase: 0, 108 phase: 0,
102 }), 109 }),
103 rtc_clk: Some(RtcClkConfig { 110 rtc_clk: Some(RtcClkConfig {
104 src: ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH, 111 src: RtcClkSrc::Rosc,
105 div_int: 1024, 112 div_int: 1024,
106 div_frac: 0, 113 div_frac: 0,
107 phase: 0, 114 phase: 0,
@@ -110,8 +117,18 @@ impl ClockConfig {
110 } 117 }
111} 118}
112 119
120#[repr(u16)]
121#[non_exhaustive]
122#[derive(Clone, Copy, Debug, PartialEq, Eq)]
123pub enum RoscRange {
124 Low = pac::rosc::vals::FreqRange::LOW.0,
125 Medium = pac::rosc::vals::FreqRange::MEDIUM.0,
126 High = pac::rosc::vals::FreqRange::HIGH.0,
127 TooHigh = pac::rosc::vals::FreqRange::TOOHIGH.0,
128}
129
113pub struct RoscConfig { 130pub struct RoscConfig {
114 pub range: pac::rosc::vals::FreqRange, 131 pub range: RoscRange,
115 pub drive_strength: [u8; 8], 132 pub drive_strength: [u8; 8],
116 pub div: u16, 133 pub div: u16,
117} 134}
@@ -134,15 +151,30 @@ pub struct RefClkConfig {
134 pub div: u8, 151 pub div: u8,
135} 152}
136 153
154#[non_exhaustive]
155#[derive(Clone, Copy, Debug, PartialEq, Eq)]
137pub enum RefClkSrc { 156pub enum RefClkSrc {
157 // main sources
138 Xosc, 158 Xosc,
139 Rosc, 159 Rosc,
140 Aux(ClkRefCtrlAuxsrc), 160 // aux sources
161 PllUsb,
162 Gpin0,
163 Gpin1,
141} 164}
142 165
166#[non_exhaustive]
167#[derive(Clone, Copy, Debug, PartialEq, Eq)]
143pub enum SysClkSrc { 168pub enum SysClkSrc {
169 // main sources
144 Ref, 170 Ref,
145 Aux(ClkSysCtrlAuxsrc), 171 // aux sources
172 PllSys,
173 PllUsb,
174 Rosc,
175 Xosc,
176 Gpin0,
177 Gpin1,
146} 178}
147 179
148pub struct SysClkConfig { 180pub struct SysClkConfig {
@@ -151,20 +183,56 @@ pub struct SysClkConfig {
151 pub div_frac: u8, 183 pub div_frac: u8,
152} 184}
153 185
186#[repr(u8)]
187#[non_exhaustive]
188#[derive(Clone, Copy, Debug, PartialEq, Eq)]
189pub enum UsbClkSrc {
190 PllUsb = ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB.0,
191 PllSys = ClkUsbCtrlAuxsrc::CLKSRC_PLL_SYS.0,
192 Rosc = ClkUsbCtrlAuxsrc::ROSC_CLKSRC_PH.0,
193 Xosc = ClkUsbCtrlAuxsrc::XOSC_CLKSRC.0,
194 Gpin0 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN0.0,
195 Gpin1 = ClkUsbCtrlAuxsrc::CLKSRC_GPIN1.0,
196}
197
154pub struct UsbClkConfig { 198pub struct UsbClkConfig {
155 pub src: ClkUsbCtrlAuxsrc, 199 pub src: UsbClkSrc,
156 pub div: u8, 200 pub div: u8,
157 pub phase: u8, 201 pub phase: u8,
158} 202}
159 203
204#[repr(u8)]
205#[non_exhaustive]
206#[derive(Clone, Copy, Debug, PartialEq, Eq)]
207pub enum AdcClkSrc {
208 PllUsb = ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB.0,
209 PllSys = ClkAdcCtrlAuxsrc::CLKSRC_PLL_SYS.0,
210 Rosc = ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH.0,
211 Xosc = ClkAdcCtrlAuxsrc::XOSC_CLKSRC.0,
212 Gpin0 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN0.0,
213 Gpin1 = ClkAdcCtrlAuxsrc::CLKSRC_GPIN1.0,
214}
215
160pub struct AdcClkConfig { 216pub struct AdcClkConfig {
161 pub src: ClkAdcCtrlAuxsrc, 217 pub src: AdcClkSrc,
162 pub div: u8, 218 pub div: u8,
163 pub phase: u8, 219 pub phase: u8,
164} 220}
165 221
222#[repr(u8)]
223#[non_exhaustive]
224#[derive(Clone, Copy, Debug, PartialEq, Eq)]
225pub enum RtcClkSrc {
226 PllUsb = ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB.0,
227 PllSys = ClkRtcCtrlAuxsrc::CLKSRC_PLL_SYS.0,
228 Rosc = ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH.0,
229 Xosc = ClkRtcCtrlAuxsrc::XOSC_CLKSRC.0,
230 Gpin0 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN0.0,
231 Gpin1 = ClkRtcCtrlAuxsrc::CLKSRC_GPIN1.0,
232}
233
166pub struct RtcClkConfig { 234pub struct RtcClkConfig {
167 pub src: ClkRtcCtrlAuxsrc, 235 pub src: RtcClkSrc,
168 pub div_int: u32, 236 pub div_int: u32,
169 pub div_frac: u8, 237 pub div_frac: u8,
170 pub phase: u8, 238 pub phase: u8,
@@ -229,27 +297,21 @@ pub(crate) unsafe fn init(config: ClockConfig) {
229 } 297 }
230 } 298 }
231 299
232 match config.ref_clk.src { 300 let (ref_src, ref_aux) = {
233 RefClkSrc::Xosc => { 301 use {ClkRefCtrlAuxsrc as Aux, ClkRefCtrlSrc as Src};
234 c.clk_ref_ctrl().write(|w| { 302 match config.ref_clk.src {
235 w.set_src(ClkRefCtrlSrc::XOSC_CLKSRC); 303 RefClkSrc::Xosc => (Src::XOSC_CLKSRC, Aux::CLKSRC_PLL_USB),
236 }); 304 RefClkSrc::Rosc => (Src::ROSC_CLKSRC_PH, Aux::CLKSRC_PLL_USB),
237 while c.clk_ref_selected().read() != 1 << ClkRefCtrlSrc::XOSC_CLKSRC.0 {} 305 RefClkSrc::PllUsb => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_PLL_USB),
238 } 306 RefClkSrc::Gpin0 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN0),
239 RefClkSrc::Rosc => { 307 RefClkSrc::Gpin1 => (Src::CLKSRC_CLK_REF_AUX, Aux::CLKSRC_GPIN1),
240 c.clk_ref_ctrl().write(|w| {
241 w.set_src(ClkRefCtrlSrc::ROSC_CLKSRC_PH);
242 });
243 while c.clk_ref_selected().read() != 1 << ClkRefCtrlSrc::ROSC_CLKSRC_PH.0 {}
244 }
245 RefClkSrc::Aux(src) => {
246 c.clk_ref_ctrl().write(|w| {
247 w.set_auxsrc(src);
248 w.set_src(ClkRefCtrlSrc::CLKSRC_CLK_REF_AUX);
249 });
250 while c.clk_ref_selected().read() != 1 << ClkRefCtrlSrc::CLKSRC_CLK_REF_AUX.0 {}
251 } 308 }
252 } 309 };
310 c.clk_ref_ctrl().write(|w| {
311 w.set_src(ref_src);
312 w.set_auxsrc(ref_aux);
313 });
314 while c.clk_ref_selected().read() != 1 << ref_src.0 {}
253 c.clk_ref_div().write(|w| { 315 c.clk_ref_div().write(|w| {
254 w.set_int(config.ref_clk.div); 316 w.set_int(config.ref_clk.div);
255 }); 317 });
@@ -259,26 +321,27 @@ pub(crate) unsafe fn init(config: ClockConfig) {
259 w.set_enable(true); 321 w.set_enable(true);
260 }); 322 });
261 323
262 match config.sys_clk.src { 324 let (sys_src, sys_aux) = {
263 SysClkSrc::Ref => { 325 use {ClkSysCtrlAuxsrc as Aux, ClkSysCtrlSrc as Src};
264 c.clk_sys_ctrl().write(|w| { 326 match config.sys_clk.src {
265 w.set_src(ClkSysCtrlSrc::CLK_REF); 327 SysClkSrc::Ref => (Src::CLK_REF, Aux::CLKSRC_PLL_SYS),
266 }); 328 SysClkSrc::PllSys => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_PLL_SYS),
267 while c.clk_sys_selected().read() != 1 << ClkSysCtrlSrc::CLK_REF.0 {} 329 SysClkSrc::PllUsb => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_PLL_USB),
268 } 330 SysClkSrc::Rosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::ROSC_CLKSRC),
269 SysClkSrc::Aux(src) => { 331 SysClkSrc::Xosc => (Src::CLKSRC_CLK_SYS_AUX, Aux::XOSC_CLKSRC),
270 c.clk_sys_ctrl().write(|w| { 332 SysClkSrc::Gpin0 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN0),
271 w.set_src(ClkSysCtrlSrc::CLK_REF); 333 SysClkSrc::Gpin1 => (Src::CLKSRC_CLK_SYS_AUX, Aux::CLKSRC_GPIN1),
272 });
273 while c.clk_sys_selected().read() != 1 << ClkSysCtrlSrc::CLK_REF.0 {}
274
275 c.clk_sys_ctrl().write(|w| {
276 w.set_auxsrc(src);
277 w.set_src(ClkSysCtrlSrc::CLKSRC_CLK_SYS_AUX);
278 });
279 while c.clk_sys_selected().read() != 1 << ClkSysCtrlSrc::CLKSRC_CLK_SYS_AUX.0 {}
280 } 334 }
335 };
336 if sys_src != ClkSysCtrlSrc::CLK_REF {
337 c.clk_sys_ctrl().write(|w| w.set_src(ClkSysCtrlSrc::CLK_REF));
338 while c.clk_sys_selected().read() != 1 << ClkSysCtrlSrc::CLK_REF.0 {}
281 } 339 }
340 c.clk_sys_ctrl().write(|w| {
341 w.set_auxsrc(sys_aux);
342 w.set_src(sys_src);
343 });
344 while c.clk_sys_selected().read() != 1 << sys_src.0 {}
282 c.clk_sys_div().write(|w| { 345 c.clk_sys_div().write(|w| {
283 w.set_int(config.sys_clk.div_int); 346 w.set_int(config.sys_clk.div_int);
284 w.set_frac(config.sys_clk.div_frac); 347 w.set_frac(config.sys_clk.div_frac);
@@ -289,7 +352,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
289 if let Some(src) = config.peri_clk_src { 352 if let Some(src) = config.peri_clk_src {
290 c.clk_peri_ctrl().write(|w| { 353 c.clk_peri_ctrl().write(|w| {
291 w.set_enable(true); 354 w.set_enable(true);
292 w.set_auxsrc(src); 355 w.set_auxsrc(ClkPeriCtrlAuxsrc(src as _));
293 }); 356 });
294 } else { 357 } else {
295 peris.set_spi0(false); 358 peris.set_spi0(false);
@@ -304,7 +367,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
304 c.clk_usb_ctrl().write(|w| { 367 c.clk_usb_ctrl().write(|w| {
305 w.set_phase(conf.phase); 368 w.set_phase(conf.phase);
306 w.set_enable(true); 369 w.set_enable(true);
307 w.set_auxsrc(conf.src); 370 w.set_auxsrc(ClkUsbCtrlAuxsrc(conf.src as _));
308 }); 371 });
309 } else { 372 } else {
310 peris.set_usbctrl(false); 373 peris.set_usbctrl(false);
@@ -316,7 +379,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
316 c.clk_adc_ctrl().write(|w| { 379 c.clk_adc_ctrl().write(|w| {
317 w.set_phase(conf.phase); 380 w.set_phase(conf.phase);
318 w.set_enable(true); 381 w.set_enable(true);
319 w.set_auxsrc(conf.src); 382 w.set_auxsrc(ClkAdcCtrlAuxsrc(conf.src as _));
320 }); 383 });
321 } else { 384 } else {
322 peris.set_adc(false); 385 peris.set_adc(false);
@@ -334,7 +397,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
334 c.clk_rtc_ctrl().write(|w| { 397 c.clk_rtc_ctrl().write(|w| {
335 w.set_phase(conf.phase); 398 w.set_phase(conf.phase);
336 w.set_enable(true); 399 w.set_enable(true);
337 w.set_auxsrc(conf.src); 400 w.set_auxsrc(ClkRtcCtrlAuxsrc(conf.src as _));
338 }); 401 });
339 } else { 402 } else {
340 peris.set_rtc(false); 403 peris.set_rtc(false);
@@ -369,7 +432,7 @@ unsafe fn configure_rosc(config: RoscConfig) {
369 432
370 p.ctrl().write(|w| { 433 p.ctrl().write(|w| {
371 w.set_enable(pac::rosc::vals::Enable::ENABLE); 434 w.set_enable(pac::rosc::vals::Enable::ENABLE);
372 w.set_freq_range(config.range); 435 w.set_freq_range(pac::rosc::vals::FreqRange(config.range as u16));
373 }); 436 });
374} 437}
375 438
@@ -671,6 +734,21 @@ impl_gpoutpin!(PIN_23, 1);
671impl_gpoutpin!(PIN_24, 2); 734impl_gpoutpin!(PIN_24, 2);
672impl_gpoutpin!(PIN_25, 3); 735impl_gpoutpin!(PIN_25, 3);
673 736
737#[repr(u8)]
738pub enum GpoutSrc {
739 PllSys = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS.0,
740 Gpin0 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0.0,
741 Gpin1 = ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1.0,
742 PllUsb = ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB.0,
743 Rosc = ClkGpoutCtrlAuxsrc::ROSC_CLKSRC.0,
744 Xosc = ClkGpoutCtrlAuxsrc::XOSC_CLKSRC.0,
745 Sys = ClkGpoutCtrlAuxsrc::CLK_SYS.0,
746 Usb = ClkGpoutCtrlAuxsrc::CLK_USB.0,
747 Adc = ClkGpoutCtrlAuxsrc::CLK_ADC.0,
748 Rtc = ClkGpoutCtrlAuxsrc::CLK_RTC.0,
749 Ref = ClkGpoutCtrlAuxsrc::CLK_REF.0,
750}
751
674pub struct Gpout<'d, T: GpoutPin> { 752pub struct Gpout<'d, T: GpoutPin> {
675 gpout: PeripheralRef<'d, T>, 753 gpout: PeripheralRef<'d, T>,
676} 754}
@@ -696,11 +774,11 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
696 } 774 }
697 } 775 }
698 776
699 pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) { 777 pub fn set_src(&self, src: GpoutSrc) {
700 unsafe { 778 unsafe {
701 let c = pac::CLOCKS; 779 let c = pac::CLOCKS;
702 c.clk_gpout_ctrl(self.gpout.number()).modify(|w| { 780 c.clk_gpout_ctrl(self.gpout.number()).modify(|w| {
703 w.set_auxsrc(src); 781 w.set_auxsrc(ClkGpoutCtrlAuxsrc(src as _));
704 }); 782 });
705 } 783 }
706 } 784 }
diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs
index 236a653ac..64461fc5f 100644
--- a/examples/rp/src/bin/gpout.rs
+++ b/examples/rp/src/bin/gpout.rs
@@ -17,14 +17,14 @@ async fn main(_spawner: Spawner) {
17 gpout3.enable(); 17 gpout3.enable();
18 18
19 loop { 19 loop {
20 gpout3.set_src(clocks::GpoutSrc::CLK_SYS); 20 gpout3.set_src(clocks::GpoutSrc::Sys);
21 info!( 21 info!(
22 "Pin 25 is now outputing CLK_SYS/1000, should be toggling at {}", 22 "Pin 25 is now outputing CLK_SYS/1000, should be toggling at {}",
23 gpout3.get_freq() 23 gpout3.get_freq()
24 ); 24 );
25 Timer::after(Duration::from_secs(2)).await; 25 Timer::after(Duration::from_secs(2)).await;
26 26
27 gpout3.set_src(clocks::GpoutSrc::CLK_REF); 27 gpout3.set_src(clocks::GpoutSrc::Ref);
28 info!( 28 info!(
29 "Pin 25 is now outputing CLK_REF/1000, should be toggling at {}", 29 "Pin 25 is now outputing CLK_REF/1000, should be toggling at {}",
30 gpout3.get_freq() 30 gpout3.get_freq()