aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp
diff options
context:
space:
mode:
authorCaleb Jamison <[email protected]>2023-05-09 11:46:25 -0400
committerCaleb Jamison <[email protected]>2023-05-09 11:46:25 -0400
commitc1eaad41f30d0b712b94e05f62dc7bb90fe8cc6d (patch)
tree3fcf179477a6fa5af19b7c5b8dfaeeea2b7c0610 /embassy-rp
parent14eecf2fc44d9894e7e053280f771a0e98c255ef (diff)
Gpout cleanup, basic Gpin support
Requires rp-pac #3
Diffstat (limited to 'embassy-rp')
-rw-r--r--embassy-rp/Cargo.toml5
-rw-r--r--embassy-rp/src/clocks.rs162
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" }
61rand_core = "0.6.4" 61rand_core = "0.6.4"
62fixed = "1.23.1" 62fixed = "1.23.1"
63 63
64rp-pac = { version = "2", features = ["rt"] } 64rp-pac = { version = "3", features = ["rt"] }
65 65
66embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 66embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
67embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true} 67embedded-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}
71paste = "1.0" 71paste = "1.0"
72pio-proc = {version= "0.2" } 72pio-proc = {version= "0.2" }
73pio = {version= "0.2.1" } 73pio = {version= "0.2.1" }
74
75[patch.crates-io]
76rp-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 @@
1use embassy_hal_common::{into_ref, PeripheralRef};
1use pac::clocks::vals::*; 2use pac::clocks::vals::*;
2 3
3use crate::{pac, reset}; 4use crate::{pac, reset, Peripheral};
4 5
5// TODO fix terrible use of global here 6// TODO fix terrible use of global here
6static mut XIN_HZ: u32 = 0; 7static 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
546pub fn clk_gpout0_freq() -> u32 { 547pub 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
573pub 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
670pub trait GpoutPin {} 644pub trait GpinPin {
645 fn gpin_number(&self) -> usize;
646 fn pin_number(&self) -> usize;
647}
671 648
672impl GpoutPin for crate::peripherals::PIN_21 {} 649macro_rules! impl_gpinpin {
673impl GpoutPin for crate::peripherals::PIN_23 {} 650 ($name:ident, $pin_num:expr, $gpin_num:expr) => {
674impl GpoutPin for crate::peripherals::PIN_24 {} 651 impl GpinPin for crate::peripherals::$name {
675impl 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
677use embassy_hal_common::{into_ref, PeripheralRef}; 662impl_gpinpin!(PIN_20, 20, 0);
663impl_gpinpin!(PIN_22, 22, 1);
664
665pub struct Gpin<'d, T: GpinPin> {
666 gpout: PeripheralRef<'d, T>,
667}
668
669impl<'d, T: GpinPin> Gpin<'d, T> {
670 pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self {
671 into_ref!(gpout);
678 672
679use 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
682impl<'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
691pub trait GpoutPin {
692 fn gpout_number(&self) -> usize;
693 fn pin_number(&self) -> usize;
694}
695
696macro_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
709impl_gpoutpin!(PIN_21, 21, 0);
710impl_gpoutpin!(PIN_23, 23, 1);
711impl_gpoutpin!(PIN_24, 24, 2);
712impl_gpoutpin!(PIN_25, 25, 3);
680 713
681pub struct Gpout<'d, T: GpoutPin> { 714pub struct Gpout<'d, T: GpoutPin> {
682 _pin: PeripheralRef<'d, T>, 715 gpout: PeripheralRef<'d, T>,
683} 716}
684 717
685impl<'d, T: GpoutPin> Gpout<'d, T> { 718impl<'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
768impl<'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