diff options
| author | Caleb Jamison <[email protected]> | 2023-05-09 11:46:25 -0400 |
|---|---|---|
| committer | Caleb Jamison <[email protected]> | 2023-05-09 11:46:25 -0400 |
| commit | c1eaad41f30d0b712b94e05f62dc7bb90fe8cc6d (patch) | |
| tree | 3fcf179477a6fa5af19b7c5b8dfaeeea2b7c0610 /embassy-rp | |
| parent | 14eecf2fc44d9894e7e053280f771a0e98c255ef (diff) | |
Gpout cleanup, basic Gpin support
Requires rp-pac #3
Diffstat (limited to 'embassy-rp')
| -rw-r--r-- | embassy-rp/Cargo.toml | 5 | ||||
| -rw-r--r-- | embassy-rp/src/clocks.rs | 162 |
2 files changed, 106 insertions, 61 deletions
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 59d0bf338..0d0e6fff0 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -61,7 +61,7 @@ embedded-storage = { version = "0.3" } | |||
| 61 | rand_core = "0.6.4" | 61 | rand_core = "0.6.4" |
| 62 | fixed = "1.23.1" | 62 | fixed = "1.23.1" |
| 63 | 63 | ||
| 64 | rp-pac = { version = "2", features = ["rt"] } | 64 | rp-pac = { version = "3", features = ["rt"] } |
| 65 | 65 | ||
| 66 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | 66 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } |
| 67 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true} | 67 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true} |
| @@ -71,3 +71,6 @@ embedded-hal-nb = { version = "=1.0.0-alpha.2", optional = true} | |||
| 71 | paste = "1.0" | 71 | paste = "1.0" |
| 72 | pio-proc = {version= "0.2" } | 72 | pio-proc = {version= "0.2" } |
| 73 | pio = {version= "0.2.1" } | 73 | pio = {version= "0.2.1" } |
| 74 | |||
| 75 | [patch.crates-io] | ||
| 76 | rp-pac = {git = "https://github.com/CBJamo/rp-pac.git"} | ||
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index def34fc70..743a3fd53 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | ||
| 1 | use pac::clocks::vals::*; | 2 | use pac::clocks::vals::*; |
| 2 | 3 | ||
| 3 | use crate::{pac, reset}; | 4 | use crate::{pac, reset, Peripheral}; |
| 4 | 5 | ||
| 5 | // TODO fix terrible use of global here | 6 | // TODO fix terrible use of global here |
| 6 | static mut XIN_HZ: u32 = 0; | 7 | static mut XIN_HZ: u32 = 0; |
| @@ -543,53 +544,26 @@ pub fn clk_rtc_freq() -> u32 { | |||
| 543 | base / int | 544 | base / int |
| 544 | } | 545 | } |
| 545 | 546 | ||
| 546 | pub fn clk_gpout0_freq() -> u32 { | 547 | pub fn clk_gpout_freq(num: usize) -> u32 { |
| 547 | let c = pac::CLOCKS; | ||
| 548 | let src = unsafe { c.clk_gpout0_ctrl().read().auxsrc() }; | ||
| 549 | |||
| 550 | let base = match src { | ||
| 551 | ClkGpout0ctrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), | ||
| 552 | ClkGpout0ctrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), | ||
| 553 | ClkGpout0ctrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), | ||
| 554 | ClkGpout0ctrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), | ||
| 555 | ClkGpout0ctrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), | ||
| 556 | ClkGpout0ctrlAuxsrc::XOSC_CLKSRC => xosc_freq(), | ||
| 557 | ClkGpout0ctrlAuxsrc::CLK_SYS => clk_sys_freq(), | ||
| 558 | ClkGpout0ctrlAuxsrc::CLK_USB => clk_usb_freq(), | ||
| 559 | ClkGpout0ctrlAuxsrc::CLK_ADC => clk_adc_freq(), | ||
| 560 | ClkGpout0ctrlAuxsrc::CLK_RTC => clk_rtc_freq(), | ||
| 561 | ClkGpout0ctrlAuxsrc::CLK_REF => clk_ref_freq(), | ||
| 562 | _ => unreachable!(), | ||
| 563 | }; | ||
| 564 | |||
| 565 | let div = unsafe { c.clk_gpout0_div().read() }; | ||
| 566 | let int = if div.int() == 0 { 65536 } else { div.int() }; | ||
| 567 | // TODO handle fractional clock div | ||
| 568 | let _frac = div.frac(); | ||
| 569 | |||
| 570 | base / int | ||
| 571 | } | ||
| 572 | |||
| 573 | pub fn clk_gpout1_freq() -> u32 { | ||
| 574 | let c = pac::CLOCKS; | 548 | let c = pac::CLOCKS; |
| 575 | let src = unsafe { c.clk_gpout1_ctrl().read().auxsrc() }; | 549 | let src = unsafe { c.clk_gpout_ctrl(num).read().auxsrc() }; |
| 576 | 550 | ||
| 577 | let base = match src { | 551 | let base = match src { |
| 578 | ClkGpout1ctrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), | 552 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), |
| 579 | ClkGpout1ctrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), | 553 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), |
| 580 | ClkGpout1ctrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), | 554 | ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), |
| 581 | ClkGpout1ctrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), | 555 | ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), |
| 582 | ClkGpout1ctrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), | 556 | ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), |
| 583 | ClkGpout1ctrlAuxsrc::XOSC_CLKSRC => xosc_freq(), | 557 | ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(), |
| 584 | ClkGpout1ctrlAuxsrc::CLK_SYS => clk_sys_freq(), | 558 | ClkGpoutCtrlAuxsrc::CLK_SYS => clk_sys_freq(), |
| 585 | ClkGpout1ctrlAuxsrc::CLK_USB => clk_usb_freq(), | 559 | ClkGpoutCtrlAuxsrc::CLK_USB => clk_usb_freq(), |
| 586 | ClkGpout1ctrlAuxsrc::CLK_ADC => clk_adc_freq(), | 560 | ClkGpoutCtrlAuxsrc::CLK_ADC => clk_adc_freq(), |
| 587 | ClkGpout1ctrlAuxsrc::CLK_RTC => clk_rtc_freq(), | 561 | ClkGpoutCtrlAuxsrc::CLK_RTC => clk_rtc_freq(), |
| 588 | ClkGpout1ctrlAuxsrc::CLK_REF => clk_ref_freq(), | 562 | ClkGpoutCtrlAuxsrc::CLK_REF => clk_ref_freq(), |
| 589 | _ => unreachable!(), | 563 | _ => unreachable!(), |
| 590 | }; | 564 | }; |
| 591 | 565 | ||
| 592 | let div = unsafe { c.clk_gpout1_div().read() }; | 566 | let div = unsafe { c.clk_gpout_div(num).read() }; |
| 593 | let int = if div.int() == 0 { 65536 } else { div.int() }; | 567 | let int = if div.int() == 0 { 65536 } else { div.int() }; |
| 594 | // TODO handle fractional clock div | 568 | // TODO handle fractional clock div |
| 595 | let _frac = div.frac(); | 569 | let _frac = div.frac(); |
| @@ -667,47 +641,106 @@ unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) { | |||
| 667 | p.pwr().modify(|w| w.set_postdivpd(false)); | 641 | p.pwr().modify(|w| w.set_postdivpd(false)); |
| 668 | } | 642 | } |
| 669 | 643 | ||
| 670 | pub trait GpoutPin {} | 644 | pub trait GpinPin { |
| 645 | fn gpin_number(&self) -> usize; | ||
| 646 | fn pin_number(&self) -> usize; | ||
| 647 | } | ||
| 671 | 648 | ||
| 672 | impl GpoutPin for crate::peripherals::PIN_21 {} | 649 | macro_rules! impl_gpinpin { |
| 673 | impl GpoutPin for crate::peripherals::PIN_23 {} | 650 | ($name:ident, $pin_num:expr, $gpin_num:expr) => { |
| 674 | impl GpoutPin for crate::peripherals::PIN_24 {} | 651 | impl GpinPin for crate::peripherals::$name { |
| 675 | impl GpoutPin for crate::peripherals::PIN_25 {} | 652 | fn gpin_number(&self) -> usize { |
| 653 | $gpin_num | ||
| 654 | } | ||
| 655 | fn pin_number(&self) -> usize { | ||
| 656 | $pin_num | ||
| 657 | } | ||
| 658 | } | ||
| 659 | }; | ||
| 660 | } | ||
| 676 | 661 | ||
| 677 | use embassy_hal_common::{into_ref, PeripheralRef}; | 662 | impl_gpinpin!(PIN_20, 20, 0); |
| 663 | impl_gpinpin!(PIN_22, 22, 1); | ||
| 664 | |||
| 665 | pub struct Gpin<'d, T: GpinPin> { | ||
| 666 | gpout: PeripheralRef<'d, T>, | ||
| 667 | } | ||
| 668 | |||
| 669 | impl<'d, T: GpinPin> Gpin<'d, T> { | ||
| 670 | pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { | ||
| 671 | into_ref!(gpout); | ||
| 678 | 672 | ||
| 679 | use crate::Peripheral; | 673 | unsafe { |
| 674 | let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); | ||
| 675 | p.write(|w| w.set_funcsel(0x08)); | ||
| 676 | } | ||
| 677 | |||
| 678 | Self { gpout } | ||
| 679 | } | ||
| 680 | } | ||
| 681 | |||
| 682 | impl<'d, T: GpinPin> Drop for Gpin<'d, T> { | ||
| 683 | fn drop(&mut self) { | ||
| 684 | unsafe { | ||
| 685 | let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | ||
| 686 | p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||
| 687 | } | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | pub trait GpoutPin { | ||
| 692 | fn gpout_number(&self) -> usize; | ||
| 693 | fn pin_number(&self) -> usize; | ||
| 694 | } | ||
| 695 | |||
| 696 | macro_rules! impl_gpoutpin { | ||
| 697 | ($name:ident, $pin_num:expr, $gpout_num:expr) => { | ||
| 698 | impl GpoutPin for crate::peripherals::$name { | ||
| 699 | fn gpout_number(&self) -> usize { | ||
| 700 | $gpout_num | ||
| 701 | } | ||
| 702 | fn pin_number(&self) -> usize { | ||
| 703 | $pin_num | ||
| 704 | } | ||
| 705 | } | ||
| 706 | }; | ||
| 707 | } | ||
| 708 | |||
| 709 | impl_gpoutpin!(PIN_21, 21, 0); | ||
| 710 | impl_gpoutpin!(PIN_23, 23, 1); | ||
| 711 | impl_gpoutpin!(PIN_24, 24, 2); | ||
| 712 | impl_gpoutpin!(PIN_25, 25, 3); | ||
| 680 | 713 | ||
| 681 | pub struct Gpout<'d, T: GpoutPin> { | 714 | pub struct Gpout<'d, T: GpoutPin> { |
| 682 | _pin: PeripheralRef<'d, T>, | 715 | gpout: PeripheralRef<'d, T>, |
| 683 | } | 716 | } |
| 684 | 717 | ||
| 685 | impl<'d, T: GpoutPin> Gpout<'d, T> { | 718 | impl<'d, T: GpoutPin> Gpout<'d, T> { |
| 686 | pub fn new(_pin: impl Peripheral<P = T> + 'd) -> Self { | 719 | pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { |
| 687 | into_ref!(_pin); | 720 | into_ref!(gpout); |
| 688 | 721 | ||
| 689 | unsafe { | 722 | unsafe { |
| 690 | let p = pac::IO_BANK0.gpio(21).ctrl(); | 723 | let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); |
| 691 | p.write(|w| w.set_funcsel(pac::io::vals::Gpio21ctrlFuncsel::CLOCKS_GPOUT_0.0)); | 724 | p.write(|w| w.set_funcsel(0x08)); |
| 692 | } | 725 | } |
| 693 | 726 | ||
| 694 | Self { _pin } | 727 | Self { gpout } |
| 695 | } | 728 | } |
| 696 | 729 | ||
| 697 | pub fn set_div(&self, int: u32, frac: u8) { | 730 | pub fn set_div(&self, int: u32, frac: u8) { |
| 698 | unsafe { | 731 | unsafe { |
| 699 | let c = pac::CLOCKS; | 732 | let c = pac::CLOCKS; |
| 700 | c.clk_gpout0_div().write(|w| { | 733 | c.clk_gpout_div(self.gpout.gpout_number()).write(|w| { |
| 701 | w.set_int(int); | 734 | w.set_int(int); |
| 702 | w.set_frac(frac); | 735 | w.set_frac(frac); |
| 703 | }); | 736 | }); |
| 704 | } | 737 | } |
| 705 | } | 738 | } |
| 706 | 739 | ||
| 707 | pub fn set_src(&self, src: ClkGpout0ctrlAuxsrc) { | 740 | pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) { |
| 708 | unsafe { | 741 | unsafe { |
| 709 | let c = pac::CLOCKS; | 742 | let c = pac::CLOCKS; |
| 710 | c.clk_gpout0_ctrl().modify(|w| { | 743 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { |
| 711 | w.set_auxsrc(src); | 744 | w.set_auxsrc(src); |
| 712 | }); | 745 | }); |
| 713 | } | 746 | } |
| @@ -716,7 +749,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 716 | pub fn enable(&self) { | 749 | pub fn enable(&self) { |
| 717 | unsafe { | 750 | unsafe { |
| 718 | let c = pac::CLOCKS; | 751 | let c = pac::CLOCKS; |
| 719 | c.clk_gpout0_ctrl().modify(|w| { | 752 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { |
| 720 | w.set_enable(true); | 753 | w.set_enable(true); |
| 721 | }); | 754 | }); |
| 722 | } | 755 | } |
| @@ -725,13 +758,22 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||
| 725 | pub fn disable(&self) { | 758 | pub fn disable(&self) { |
| 726 | unsafe { | 759 | unsafe { |
| 727 | let c = pac::CLOCKS; | 760 | let c = pac::CLOCKS; |
| 728 | c.clk_gpout0_ctrl().modify(|w| { | 761 | c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { |
| 729 | w.set_enable(true); | 762 | w.set_enable(true); |
| 730 | }); | 763 | }); |
| 731 | } | 764 | } |
| 732 | } | 765 | } |
| 733 | } | 766 | } |
| 734 | 767 | ||
| 768 | impl<'d, T: GpoutPin> Drop for Gpout<'d, T> { | ||
| 769 | fn drop(&mut self) { | ||
| 770 | unsafe { | ||
| 771 | let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | ||
| 772 | p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||
| 773 | } | ||
| 774 | } | ||
| 775 | } | ||
| 776 | |||
| 735 | /// Random number generator based on the ROSC RANDOMBIT register. | 777 | /// Random number generator based on the ROSC RANDOMBIT register. |
| 736 | /// | 778 | /// |
| 737 | /// This will not produce random values if the ROSC is stopped or run at some | 779 | /// This will not produce random values if the ROSC is stopped or run at some |
