diff options
| author | Caleb Jamison <[email protected]> | 2023-05-09 17:45:24 -0400 |
|---|---|---|
| committer | Caleb Jamison <[email protected]> | 2023-05-09 17:45:24 -0400 |
| commit | 5cfe1a1fb40470dfaf256fc87989fd67884113f1 (patch) | |
| tree | 25f36348ebb5826b0e314a9e8f01fb25508aef3d | |
| parent | 6bea07848717857659c737a3bb3eab7c2cd8abdb (diff) | |
Dirbaio comments round 2
| -rw-r--r-- | embassy-rp/src/clocks.rs | 191 | ||||
| -rw-r--r-- | examples/rp/src/bin/gpout.rs | 10 |
2 files changed, 107 insertions, 94 deletions
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index b919b98a9..1354ccd27 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs | |||
| @@ -6,15 +6,22 @@ use crate::{pac, reset, Peripheral}; | |||
| 6 | // TODO fix terrible use of global here | 6 | // TODO fix terrible use of global here |
| 7 | static mut XIN_HZ: u32 = 0; | 7 | static mut XIN_HZ: u32 = 0; |
| 8 | 8 | ||
| 9 | pub use rp_pac::clocks::vals::{ | ||
| 10 | ClkAdcCtrlAuxsrc as AdcAuxsrc, ClkGpoutCtrlAuxsrc as GpoutSrc, ClkPeriCtrlAuxsrc as PeriClkAuxsrc, | ||
| 11 | ClkRefCtrlAuxsrc as RefAuxsrc, ClkRtcCtrlAuxsrc as RtcAuxsrc, ClkSysCtrlAuxsrc as SysAuxsrc, | ||
| 12 | ClkUsbCtrlAuxsrc as UsbAuxsrc, | ||
| 13 | }; | ||
| 14 | |||
| 15 | #[non_exhaustive] | ||
| 9 | pub struct ClockConfig { | 16 | pub struct ClockConfig { |
| 10 | rosc: Option<RoscConfig>, | 17 | pub rosc: Option<RoscConfig>, |
| 11 | xosc: Option<XoscConfig>, | 18 | pub xosc: Option<XoscConfig>, |
| 12 | ref_clk: RefClkConfig, | 19 | pub ref_clk: RefClkConfig, |
| 13 | sys_clk: SysClkConfig, | 20 | pub sys_clk: SysClkConfig, |
| 14 | peri_clk_src: Option<ClkPeriCtrlAuxsrc>, | 21 | pub peri_clk_src: Option<ClkPeriCtrlAuxsrc>, |
| 15 | usb_clk: Option<UsbClkConfig>, | 22 | pub usb_clk: Option<UsbClkConfig>, |
| 16 | adc_clk: Option<AdcClkConfig>, | 23 | pub adc_clk: Option<AdcClkConfig>, |
| 17 | rtc_clk: Option<RtcClkConfig>, | 24 | pub rtc_clk: Option<RtcClkConfig>, |
| 18 | } | 25 | } |
| 19 | 26 | ||
| 20 | impl ClockConfig { | 27 | impl ClockConfig { |
| @@ -54,15 +61,18 @@ impl ClockConfig { | |||
| 54 | usb_clk: Some(UsbClkConfig { | 61 | usb_clk: Some(UsbClkConfig { |
| 55 | src: ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB, | 62 | src: ClkUsbCtrlAuxsrc::CLKSRC_PLL_USB, |
| 56 | div: 1, | 63 | div: 1, |
| 64 | phase: 0, | ||
| 57 | }), | 65 | }), |
| 58 | adc_clk: Some(AdcClkConfig { | 66 | adc_clk: Some(AdcClkConfig { |
| 59 | src: ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB, | 67 | src: ClkAdcCtrlAuxsrc::CLKSRC_PLL_USB, |
| 60 | div: 1, | 68 | div: 1, |
| 69 | phase: 0, | ||
| 61 | }), | 70 | }), |
| 62 | rtc_clk: Some(RtcClkConfig { | 71 | rtc_clk: Some(RtcClkConfig { |
| 63 | src: ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB, | 72 | src: ClkRtcCtrlAuxsrc::CLKSRC_PLL_USB, |
| 64 | div_int: 1024, | 73 | div_int: 1024, |
| 65 | div_frac: 0, | 74 | div_frac: 0, |
| 75 | phase: 0, | ||
| 66 | }), | 76 | }), |
| 67 | } | 77 | } |
| 68 | } | 78 | } |
| @@ -89,27 +99,29 @@ impl ClockConfig { | |||
| 89 | adc_clk: Some(AdcClkConfig { | 99 | adc_clk: Some(AdcClkConfig { |
| 90 | src: ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH, | 100 | src: ClkAdcCtrlAuxsrc::ROSC_CLKSRC_PH, |
| 91 | div: 1, | 101 | div: 1, |
| 102 | phase: 0, | ||
| 92 | }), | 103 | }), |
| 93 | rtc_clk: Some(RtcClkConfig { | 104 | rtc_clk: Some(RtcClkConfig { |
| 94 | src: ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH, | 105 | src: ClkRtcCtrlAuxsrc::ROSC_CLKSRC_PH, |
| 95 | div_int: 1024, | 106 | div_int: 1024, |
| 96 | div_frac: 0, | 107 | div_frac: 0, |
| 108 | phase: 0, | ||
| 97 | }), | 109 | }), |
| 98 | } | 110 | } |
| 99 | } | 111 | } |
| 100 | } | 112 | } |
| 101 | 113 | ||
| 102 | pub struct RoscConfig { | 114 | pub struct RoscConfig { |
| 103 | range: pac::rosc::vals::FreqRange, | 115 | pub range: pac::rosc::vals::FreqRange, |
| 104 | drive_strength: [u8; 8], | 116 | pub drive_strength: [u8; 8], |
| 105 | div: u16, | 117 | pub div: u16, |
| 106 | } | 118 | } |
| 107 | 119 | ||
| 108 | pub struct XoscConfig { | 120 | pub struct XoscConfig { |
| 109 | hz: u32, | 121 | pub hz: u32, |
| 110 | clock_type: ExternalClock, | 122 | pub clock_type: ExternalClock, |
| 111 | sys_pll: Option<PllConfig>, | 123 | pub sys_pll: Option<PllConfig>, |
| 112 | usb_pll: Option<PllConfig>, | 124 | pub usb_pll: Option<PllConfig>, |
| 113 | } | 125 | } |
| 114 | 126 | ||
| 115 | pub struct PllConfig { | 127 | pub struct PllConfig { |
| @@ -124,8 +136,8 @@ pub enum ExternalClock { | |||
| 124 | Clock, | 136 | Clock, |
| 125 | } | 137 | } |
| 126 | pub struct RefClkConfig { | 138 | pub struct RefClkConfig { |
| 127 | src: RefClkSrc, | 139 | pub src: RefClkSrc, |
| 128 | div: u8, | 140 | pub div: u8, |
| 129 | } | 141 | } |
| 130 | 142 | ||
| 131 | pub enum RefClkSrc { | 143 | pub enum RefClkSrc { |
| @@ -140,25 +152,28 @@ pub enum SysClkSrc { | |||
| 140 | } | 152 | } |
| 141 | 153 | ||
| 142 | pub struct SysClkConfig { | 154 | pub struct SysClkConfig { |
| 143 | src: SysClkSrc, | 155 | pub src: SysClkSrc, |
| 144 | div_int: u32, | 156 | pub div_int: u32, |
| 145 | div_frac: u8, | 157 | pub div_frac: u8, |
| 146 | } | 158 | } |
| 147 | 159 | ||
| 148 | pub struct UsbClkConfig { | 160 | pub struct UsbClkConfig { |
| 149 | src: ClkUsbCtrlAuxsrc, | 161 | pub src: ClkUsbCtrlAuxsrc, |
| 150 | div: u8, | 162 | pub div: u8, |
| 163 | pub phase: u8, | ||
| 151 | } | 164 | } |
| 152 | 165 | ||
| 153 | pub struct AdcClkConfig { | 166 | pub struct AdcClkConfig { |
| 154 | src: ClkAdcCtrlAuxsrc, | 167 | pub src: ClkAdcCtrlAuxsrc, |
| 155 | div: u8, | 168 | pub div: u8, |
| 169 | pub phase: u8, | ||
| 156 | } | 170 | } |
| 157 | 171 | ||
| 158 | pub struct RtcClkConfig { | 172 | pub struct RtcClkConfig { |
| 159 | src: ClkRtcCtrlAuxsrc, | 173 | pub src: ClkRtcCtrlAuxsrc, |
| 160 | div_int: u32, | 174 | pub div_int: u32, |
| 161 | div_frac: u8, | 175 | pub div_frac: u8, |
| 176 | pub phase: u8, | ||
| 162 | } | 177 | } |
| 163 | 178 | ||
| 164 | /// safety: must be called exactly once at bootup | 179 | /// safety: must be called exactly once at bootup |
| @@ -289,6 +304,7 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 289 | // CLK USB = PLL USB (48MHz) / 1 = 48MHz | 304 | // CLK USB = PLL USB (48MHz) / 1 = 48MHz |
| 290 | c.clk_usb_div().write(|w| w.set_int(conf.div)); | 305 | c.clk_usb_div().write(|w| w.set_int(conf.div)); |
| 291 | c.clk_usb_ctrl().write(|w| { | 306 | c.clk_usb_ctrl().write(|w| { |
| 307 | w.set_phase(conf.phase); | ||
| 292 | w.set_enable(true); | 308 | w.set_enable(true); |
| 293 | w.set_auxsrc(conf.src); | 309 | w.set_auxsrc(conf.src); |
| 294 | }); | 310 | }); |
| @@ -300,6 +316,7 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 300 | // CLK ADC = PLL USB (48MHZ) / 1 = 48MHz | 316 | // CLK ADC = PLL USB (48MHZ) / 1 = 48MHz |
| 301 | c.clk_adc_div().write(|w| w.set_int(conf.div)); | 317 | c.clk_adc_div().write(|w| w.set_int(conf.div)); |
| 302 | c.clk_adc_ctrl().write(|w| { | 318 | c.clk_adc_ctrl().write(|w| { |
| 319 | w.set_phase(conf.phase); | ||
| 303 | w.set_enable(true); | 320 | w.set_enable(true); |
| 304 | w.set_auxsrc(conf.src); | 321 | w.set_auxsrc(conf.src); |
| 305 | }); | 322 | }); |
| @@ -317,6 +334,7 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 317 | w.set_frac(conf.div_frac); | 334 | w.set_frac(conf.div_frac); |
| 318 | }); | 335 | }); |
| 319 | c.clk_rtc_ctrl().write(|w| { | 336 | c.clk_rtc_ctrl().write(|w| { |
| 337 | w.set_phase(conf.phase); | ||
| 320 | w.set_enable(true); | 338 | w.set_enable(true); |
| 321 | w.set_auxsrc(conf.src); | 339 | w.set_auxsrc(conf.src); |
| 322 | }); | 340 | }); |
| @@ -544,33 +562,6 @@ pub fn clk_rtc_freq() -> u32 { | |||
| 544 | base / int | 562 | base / int |
| 545 | } | 563 | } |
| 546 | 564 | ||
| 547 | pub fn clk_gpout_freq<T: GpoutPin>(gpout: &Gpout<T>) -> u32 { | ||
| 548 | let c = pac::CLOCKS; | ||
| 549 | let src = unsafe { c.clk_gpout_ctrl(gpout.gpout.gpout_number()).read().auxsrc() }; | ||
| 550 | |||
| 551 | let base = match src { | ||
| 552 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), | ||
| 553 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), | ||
| 554 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), | ||
| 555 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), | ||
| 556 | ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), | ||
| 557 | ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(), | ||
| 558 | ClkGpoutCtrlAuxsrc::CLK_SYS => clk_sys_freq(), | ||
| 559 | ClkGpoutCtrlAuxsrc::CLK_USB => clk_usb_freq(), | ||
| 560 | ClkGpoutCtrlAuxsrc::CLK_ADC => clk_adc_freq(), | ||
| 561 | ClkGpoutCtrlAuxsrc::CLK_RTC => clk_rtc_freq(), | ||
| 562 | ClkGpoutCtrlAuxsrc::CLK_REF => clk_ref_freq(), | ||
| 563 | _ => unreachable!(), | ||
| 564 | }; | ||
| 565 | |||
| 566 | let div = unsafe { c.clk_gpout_div(gpout.gpout.gpout_number()).read() }; | ||
| 567 | let int = if div.int() == 0 { 65536 } else { div.int() }; | ||
| 568 | // TODO handle fractional clock div | ||
| 569 | let _frac = div.frac(); | ||
| 570 | |||
| 571 | base / int | ||
| 572 | } | ||
| 573 | |||
| 574 | unsafe fn start_xosc(crystal_hz: u32) { | 565 | unsafe fn start_xosc(crystal_hz: u32) { |
| 575 | pac::XOSC | 566 | pac::XOSC |
| 576 | .ctrl() | 567 | .ctrl() |
| @@ -641,20 +632,16 @@ unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) { | |||
| 641 | p.pwr().modify(|w| w.set_postdivpd(false)); | 632 | p.pwr().modify(|w| w.set_postdivpd(false)); |
| 642 | } | 633 | } |
| 643 | 634 | ||
| 644 | pub trait GpinPin { | 635 | pub trait GpinPin: crate::gpio::Pin { |
| 645 | fn gpin_number(&self) -> usize; | 636 | fn number(&self) -> usize; |
| 646 | fn pin_number(&self) -> usize; | ||
| 647 | } | 637 | } |
| 648 | 638 | ||
| 649 | macro_rules! impl_gpinpin { | 639 | macro_rules! impl_gpinpin { |
| 650 | ($name:ident, $pin_num:expr, $gpin_num:expr) => { | 640 | ($name:ident, $pin_num:expr, $gpin_num:expr) => { |
| 651 | impl GpinPin for crate::peripherals::$name { | 641 | impl GpinPin for crate::peripherals::$name { |
| 652 | fn gpin_number(&self) -> usize { | 642 | fn number(&self) -> usize { |
| 653 | $gpin_num | 643 | $gpin_num |
| 654 | } | 644 | } |
| 655 | fn pin_number(&self) -> usize { | ||
| 656 | $pin_num | ||
| 657 | } | ||
| 658 | } | 645 | } |
| 659 | }; | 646 | }; |
| 660 | } | 647 | } |
| @@ -663,53 +650,50 @@ impl_gpinpin!(PIN_20, 20, 0); | |||
| 663 | impl_gpinpin!(PIN_22, 22, 1); | 650 | impl_gpinpin!(PIN_22, 22, 1); |
| 664 | 651 | ||
| 665 | pub struct Gpin<'d, T: GpinPin> { | 652 | pub struct Gpin<'d, T: GpinPin> { |
| 666 | gpout: PeripheralRef<'d, T>, | 653 | gpin: PeripheralRef<'d, T>, |
| 667 | } | 654 | } |
| 668 | 655 | ||
| 669 | impl<'d, T: GpinPin> Gpin<'d, T> { | 656 | impl<'d, T: GpinPin> Gpin<'d, T> { |
| 670 | pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { | 657 | pub fn new(gpin: impl Peripheral<P = T> + 'd) -> Self { |
| 671 | into_ref!(gpout); | 658 | into_ref!(gpin); |
| 672 | 659 | ||
| 673 | unsafe { | 660 | unsafe { |
| 674 | let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); | 661 | gpin.io().ctrl().write(|w| w.set_funcsel(0x08)); |
| 675 | p.write(|w| w.set_funcsel(0x08)); | ||
| 676 | } | 662 | } |
| 677 | 663 | ||
| 678 | Self { gpout } | 664 | Self { gpin } |
| 679 | } | 665 | } |
| 680 | } | 666 | } |
| 681 | 667 | ||
| 682 | impl<'d, T: GpinPin> Drop for Gpin<'d, T> { | 668 | impl<'d, T: GpinPin> Drop for Gpin<'d, T> { |
| 683 | fn drop(&mut self) { | 669 | fn drop(&mut self) { |
| 684 | unsafe { | 670 | unsafe { |
| 685 | let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | 671 | self.gpin |
| 686 | p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | 672 | .io() |
| 673 | .ctrl() | ||
| 674 | .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||
| 687 | } | 675 | } |
| 688 | } | 676 | } |
| 689 | } | 677 | } |
| 690 | 678 | ||
| 691 | pub trait GpoutPin { | 679 | pub trait GpoutPin: crate::gpio::Pin { |
| 692 | fn gpout_number(&self) -> usize; | 680 | fn number(&self) -> usize; |
| 693 | fn pin_number(&self) -> usize; | ||
| 694 | } | 681 | } |
| 695 | 682 | ||
| 696 | macro_rules! impl_gpoutpin { | 683 | macro_rules! impl_gpoutpin { |
| 697 | ($name:ident, $pin_num:expr, $gpout_num:expr) => { | 684 | ($name:ident, $gpout_num:expr) => { |
| 698 | impl GpoutPin for crate::peripherals::$name { | 685 | impl GpoutPin for crate::peripherals::$name { |
| 699 | fn gpout_number(&self) -> usize { | 686 | fn number(&self) -> usize { |
| 700 | $gpout_num | 687 | $gpout_num |
| 701 | } | 688 | } |
| 702 | fn pin_number(&self) -> usize { | ||
| 703 | $pin_num | ||
| 704 | } | ||
| 705 | } | 689 | } |
| 706 | }; | 690 | }; |
| 707 | } | 691 | } |
| 708 | 692 | ||
| 709 | impl_gpoutpin!(PIN_21, 21, 0); | 693 | impl_gpoutpin!(PIN_21, 0); |
| 710 | impl_gpoutpin!(PIN_23, 23, 1); | 694 | impl_gpoutpin!(PIN_23, 1); |
| 711 | impl_gpoutpin!(PIN_24, 24, 2); | 695 | impl_gpoutpin!(PIN_24, 2); |
| 712 | impl_gpoutpin!(PIN_25, 25, 3); | 696 | impl_gpoutpin!(PIN_25, 3); |
| 713 | 697 | ||
| 714 | pub struct Gpout<'d, T: GpoutPin> { | 698 | pub struct Gpout<'d, T: GpoutPin> { |
| 715 | gpout: PeripheralRef<'d, T>, | 699 | gpout: PeripheralRef<'d, T>, |
| @@ -720,8 +704,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 720 | into_ref!(gpout); | 704 | into_ref!(gpout); |
| 721 | 705 | ||
| 722 | unsafe { | 706 | unsafe { |
| 723 | let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); | 707 | gpout.io().ctrl().write(|w| w.set_funcsel(0x08)); |
| 724 | p.write(|w| w.set_funcsel(0x08)); | ||
| 725 | } | 708 | } |
| 726 | 709 | ||
| 727 | Self { gpout } | 710 | Self { gpout } |
| @@ -730,7 +713,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 730 | pub fn set_div(&self, int: u32, frac: u8) { | 713 | pub fn set_div(&self, int: u32, frac: u8) { |
| 731 | unsafe { | 714 | unsafe { |
| 732 | let c = pac::CLOCKS; | 715 | let c = pac::CLOCKS; |
| 733 | c.clk_gpout_div(self.gpout.gpout_number()).write(|w| { | 716 | c.clk_gpout_div(self.gpout.number()).write(|w| { |
| 734 | w.set_int(int); | 717 | w.set_int(int); |
| 735 | w.set_frac(frac); | 718 | w.set_frac(frac); |
| 736 | }); | 719 | }); |
| @@ -740,7 +723,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 740 | pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) { | 723 | pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) { |
| 741 | unsafe { | 724 | unsafe { |
| 742 | let c = pac::CLOCKS; | 725 | let c = pac::CLOCKS; |
| 743 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | 726 | c.clk_gpout_ctrl(self.gpout.number()).modify(|w| { |
| 744 | w.set_auxsrc(src); | 727 | w.set_auxsrc(src); |
| 745 | }); | 728 | }); |
| 746 | } | 729 | } |
| @@ -749,7 +732,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 749 | pub fn enable(&self) { | 732 | pub fn enable(&self) { |
| 750 | unsafe { | 733 | unsafe { |
| 751 | let c = pac::CLOCKS; | 734 | let c = pac::CLOCKS; |
| 752 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | 735 | c.clk_gpout_ctrl(self.gpout.number()).modify(|w| { |
| 753 | w.set_enable(true); | 736 | w.set_enable(true); |
| 754 | }); | 737 | }); |
| 755 | } | 738 | } |
| @@ -758,18 +741,48 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 758 | pub fn disable(&self) { | 741 | pub fn disable(&self) { |
| 759 | unsafe { | 742 | unsafe { |
| 760 | let c = pac::CLOCKS; | 743 | let c = pac::CLOCKS; |
| 761 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | 744 | c.clk_gpout_ctrl(self.gpout.number()).modify(|w| { |
| 762 | w.set_enable(false); | 745 | w.set_enable(false); |
| 763 | }); | 746 | }); |
| 764 | } | 747 | } |
| 765 | } | 748 | } |
| 749 | |||
| 750 | pub fn get_freq(&self) -> u32 { | ||
| 751 | let c = pac::CLOCKS; | ||
| 752 | let src = unsafe { c.clk_gpout_ctrl(self.gpout.number()).read().auxsrc() }; | ||
| 753 | |||
| 754 | let base = match src { | ||
| 755 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), | ||
| 756 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), | ||
| 757 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), | ||
| 758 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), | ||
| 759 | ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), | ||
| 760 | ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(), | ||
| 761 | ClkGpoutCtrlAuxsrc::CLK_SYS => clk_sys_freq(), | ||
| 762 | ClkGpoutCtrlAuxsrc::CLK_USB => clk_usb_freq(), | ||
| 763 | ClkGpoutCtrlAuxsrc::CLK_ADC => clk_adc_freq(), | ||
| 764 | ClkGpoutCtrlAuxsrc::CLK_RTC => clk_rtc_freq(), | ||
| 765 | ClkGpoutCtrlAuxsrc::CLK_REF => clk_ref_freq(), | ||
| 766 | _ => unreachable!(), | ||
| 767 | }; | ||
| 768 | |||
| 769 | let div = unsafe { c.clk_gpout_div(self.gpout.number()).read() }; | ||
| 770 | let int = if div.int() == 0 { 65536 } else { div.int() }; | ||
| 771 | // TODO handle fractional clock div | ||
| 772 | let _frac = div.frac(); | ||
| 773 | |||
| 774 | base / int | ||
| 775 | } | ||
| 766 | } | 776 | } |
| 767 | 777 | ||
| 768 | impl<'d, T: GpoutPin> Drop for Gpout<'d, T> { | 778 | impl<'d, T: GpoutPin> Drop for Gpout<'d, T> { |
| 769 | fn drop(&mut self) { | 779 | fn drop(&mut self) { |
| 780 | self.disable(); | ||
| 770 | unsafe { | 781 | unsafe { |
| 771 | let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | 782 | self.gpout |
| 772 | p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | 783 | .io() |
| 784 | .ctrl() | ||
| 785 | .write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||
| 773 | } | 786 | } |
| 774 | } | 787 | } |
| 775 | } | 788 | } |
diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs index ea0efb859..236a653ac 100644 --- a/examples/rp/src/bin/gpout.rs +++ b/examples/rp/src/bin/gpout.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::{clocks, pac}; | 7 | use embassy_rp::clocks; |
| 8 | use embassy_time::{Duration, Timer}; | 8 | use embassy_time::{Duration, Timer}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -17,17 +17,17 @@ async fn main(_spawner: Spawner) { | |||
| 17 | gpout3.enable(); | 17 | gpout3.enable(); |
| 18 | 18 | ||
| 19 | loop { | 19 | loop { |
| 20 | gpout3.set_src(pac::clocks::vals::ClkGpoutCtrlAuxsrc::CLK_SYS); | 20 | gpout3.set_src(clocks::GpoutSrc::CLK_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 | clocks::clk_gpout_freq(&gpout3) | 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(pac::clocks::vals::ClkGpoutCtrlAuxsrc::CLK_REF); | 27 | gpout3.set_src(clocks::GpoutSrc::CLK_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 | clocks::clk_gpout_freq(&gpout3) | 30 | gpout3.get_freq() |
| 31 | ); | 31 | ); |
| 32 | Timer::after(Duration::from_secs(2)).await; | 32 | Timer::after(Duration::from_secs(2)).await; |
| 33 | } | 33 | } |
