| @@ -61,7 +61,7 @@ embedded-storage = { version = "0.3" } | |||||||
| rand_core = "0.6.4" | rand_core = "0.6.4" | ||||||
| fixed = "1.23.1" | fixed = "1.23.1" | ||||||
|  |  | ||||||
| rp-pac = { version = "2", features = ["rt"] } | rp-pac = { version = "3", features = ["rt"] } | ||||||
|  |  | ||||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | ||||||
| embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10", optional = true} | 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} | |||||||
| paste = "1.0" | paste = "1.0" | ||||||
| pio-proc = {version= "0.2" } | pio-proc = {version= "0.2" } | ||||||
| pio = {version= "0.2.1" } | pio = {version= "0.2.1" } | ||||||
|  |  | ||||||
|  | [patch.crates-io] | ||||||
|  | rp-pac = {git = "https://github.com/CBJamo/rp-pac.git"} | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
|  | use embassy_hal_common::{into_ref, PeripheralRef}; | ||||||
| use pac::clocks::vals::*; | use pac::clocks::vals::*; | ||||||
|  |  | ||||||
| use crate::{pac, reset}; | use crate::{pac, reset, Peripheral}; | ||||||
|  |  | ||||||
| // TODO fix terrible use of global here | // TODO fix terrible use of global here | ||||||
| static mut XIN_HZ: u32 = 0; | static mut XIN_HZ: u32 = 0; | ||||||
| @@ -543,53 +544,26 @@ pub fn clk_rtc_freq() -> u32 { | |||||||
|     base / int |     base / int | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn clk_gpout0_freq() -> u32 { | pub fn clk_gpout_freq(num: usize) -> u32 { | ||||||
|     let c = pac::CLOCKS; |     let c = pac::CLOCKS; | ||||||
|     let src = unsafe { c.clk_gpout0_ctrl().read().auxsrc() }; |     let src = unsafe { c.clk_gpout_ctrl(num).read().auxsrc() }; | ||||||
|  |  | ||||||
|     let base = match src { |     let base = match src { | ||||||
|         ClkGpout0ctrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), |         ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), |         ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), |         ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), |         ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), |         ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::XOSC_CLKSRC => xosc_freq(), |         ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLK_SYS => clk_sys_freq(), |         ClkGpoutCtrlAuxsrc::CLK_SYS => clk_sys_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLK_USB => clk_usb_freq(), |         ClkGpoutCtrlAuxsrc::CLK_USB => clk_usb_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLK_ADC => clk_adc_freq(), |         ClkGpoutCtrlAuxsrc::CLK_ADC => clk_adc_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLK_RTC => clk_rtc_freq(), |         ClkGpoutCtrlAuxsrc::CLK_RTC => clk_rtc_freq(), | ||||||
|         ClkGpout0ctrlAuxsrc::CLK_REF => clk_ref_freq(), |         ClkGpoutCtrlAuxsrc::CLK_REF => clk_ref_freq(), | ||||||
|         _ => unreachable!(), |         _ => unreachable!(), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let div = unsafe { c.clk_gpout0_div().read() }; |     let div = unsafe { c.clk_gpout_div(num).read() }; | ||||||
|     let int = if div.int() == 0 { 65536 } else { div.int() }; |  | ||||||
|     // TODO handle fractional clock div |  | ||||||
|     let _frac = div.frac(); |  | ||||||
|  |  | ||||||
|     base / int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn clk_gpout1_freq() -> u32 { |  | ||||||
|     let c = pac::CLOCKS; |  | ||||||
|     let src = unsafe { c.clk_gpout1_ctrl().read().auxsrc() }; |  | ||||||
|  |  | ||||||
|     let base = match src { |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::XOSC_CLKSRC => xosc_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLK_SYS => clk_sys_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLK_USB => clk_usb_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLK_ADC => clk_adc_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLK_RTC => clk_rtc_freq(), |  | ||||||
|         ClkGpout1ctrlAuxsrc::CLK_REF => clk_ref_freq(), |  | ||||||
|         _ => unreachable!(), |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     let div = unsafe { c.clk_gpout1_div().read() }; |  | ||||||
|     let int = if div.int() == 0 { 65536 } else { div.int() }; |     let int = if div.int() == 0 { 65536 } else { div.int() }; | ||||||
|     // TODO handle fractional clock div |     // TODO handle fractional clock div | ||||||
|     let _frac = div.frac(); |     let _frac = div.frac(); | ||||||
| @@ -667,47 +641,106 @@ unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) { | |||||||
|     p.pwr().modify(|w| w.set_postdivpd(false)); |     p.pwr().modify(|w| w.set_postdivpd(false)); | ||||||
| } | } | ||||||
|  |  | ||||||
| pub trait GpoutPin {} | pub trait GpinPin { | ||||||
|  |     fn gpin_number(&self) -> usize; | ||||||
|  |     fn pin_number(&self) -> usize; | ||||||
|  | } | ||||||
|  |  | ||||||
| impl GpoutPin for crate::peripherals::PIN_21 {} | macro_rules! impl_gpinpin { | ||||||
| impl GpoutPin for crate::peripherals::PIN_23 {} |     ($name:ident, $pin_num:expr, $gpin_num:expr) => { | ||||||
| impl GpoutPin for crate::peripherals::PIN_24 {} |         impl GpinPin for crate::peripherals::$name { | ||||||
| impl GpoutPin for crate::peripherals::PIN_25 {} |             fn gpin_number(&self) -> usize { | ||||||
|  |                 $gpin_num | ||||||
|  |             } | ||||||
|  |             fn pin_number(&self) -> usize { | ||||||
|  |                 $pin_num | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
| use embassy_hal_common::{into_ref, PeripheralRef}; | impl_gpinpin!(PIN_20, 20, 0); | ||||||
|  | impl_gpinpin!(PIN_22, 22, 1); | ||||||
|  |  | ||||||
| use crate::Peripheral; | pub struct Gpin<'d, T: GpinPin> { | ||||||
|  |     gpout: PeripheralRef<'d, T>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<'d, T: GpinPin> Gpin<'d, T> { | ||||||
|  |     pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { | ||||||
|  |         into_ref!(gpout); | ||||||
|  |  | ||||||
|  |         unsafe { | ||||||
|  |             let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); | ||||||
|  |             p.write(|w| w.set_funcsel(0x08)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Self { gpout } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<'d, T: GpinPin> Drop for Gpin<'d, T> { | ||||||
|  |     fn drop(&mut self) { | ||||||
|  |         unsafe { | ||||||
|  |             let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | ||||||
|  |             p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub trait GpoutPin { | ||||||
|  |     fn gpout_number(&self) -> usize; | ||||||
|  |     fn pin_number(&self) -> usize; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | macro_rules! impl_gpoutpin { | ||||||
|  |     ($name:ident, $pin_num:expr, $gpout_num:expr) => { | ||||||
|  |         impl GpoutPin for crate::peripherals::$name { | ||||||
|  |             fn gpout_number(&self) -> usize { | ||||||
|  |                 $gpout_num | ||||||
|  |             } | ||||||
|  |             fn pin_number(&self) -> usize { | ||||||
|  |                 $pin_num | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl_gpoutpin!(PIN_21, 21, 0); | ||||||
|  | impl_gpoutpin!(PIN_23, 23, 1); | ||||||
|  | impl_gpoutpin!(PIN_24, 24, 2); | ||||||
|  | impl_gpoutpin!(PIN_25, 25, 3); | ||||||
|  |  | ||||||
| pub struct Gpout<'d, T: GpoutPin> { | pub struct Gpout<'d, T: GpoutPin> { | ||||||
|     _pin: PeripheralRef<'d, T>, |     gpout: PeripheralRef<'d, T>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, T: GpoutPin> Gpout<'d, T> { | impl<'d, T: GpoutPin> Gpout<'d, T> { | ||||||
|     pub fn new(_pin: impl Peripheral<P = T> + 'd) -> Self { |     pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { | ||||||
|         into_ref!(_pin); |         into_ref!(gpout); | ||||||
|  |  | ||||||
|         unsafe { |         unsafe { | ||||||
|             let p = pac::IO_BANK0.gpio(21).ctrl(); |             let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl(); | ||||||
|             p.write(|w| w.set_funcsel(pac::io::vals::Gpio21ctrlFuncsel::CLOCKS_GPOUT_0.0)); |             p.write(|w| w.set_funcsel(0x08)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Self { _pin } |         Self { gpout } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn set_div(&self, int: u32, frac: u8) { |     pub fn set_div(&self, int: u32, frac: u8) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let c = pac::CLOCKS; |             let c = pac::CLOCKS; | ||||||
|             c.clk_gpout0_div().write(|w| { |             c.clk_gpout_div(self.gpout.gpout_number()).write(|w| { | ||||||
|                 w.set_int(int); |                 w.set_int(int); | ||||||
|                 w.set_frac(frac); |                 w.set_frac(frac); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn set_src(&self, src: ClkGpout0ctrlAuxsrc) { |     pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let c = pac::CLOCKS; |             let c = pac::CLOCKS; | ||||||
|             c.clk_gpout0_ctrl().modify(|w| { |             c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | ||||||
|                 w.set_auxsrc(src); |                 w.set_auxsrc(src); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| @@ -716,7 +749,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||||||
|     pub fn enable(&self) { |     pub fn enable(&self) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let c = pac::CLOCKS; |             let c = pac::CLOCKS; | ||||||
|             c.clk_gpout0_ctrl().modify(|w| { |             c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | ||||||
|                 w.set_enable(true); |                 w.set_enable(true); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| @@ -725,13 +758,22 @@ impl<'d, T: GpoutPin> Gpout<'d, T> { | |||||||
|     pub fn disable(&self) { |     pub fn disable(&self) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let c = pac::CLOCKS; |             let c = pac::CLOCKS; | ||||||
|             c.clk_gpout0_ctrl().modify(|w| { |             c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| { | ||||||
|                 w.set_enable(true); |                 w.set_enable(true); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl<'d, T: GpoutPin> Drop for Gpout<'d, T> { | ||||||
|  |     fn drop(&mut self) { | ||||||
|  |         unsafe { | ||||||
|  |             let p = pac::IO_BANK0.gpio(self.gpout.pin_number()).ctrl(); | ||||||
|  |             p.write(|w| w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::NULL.0)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| /// Random number generator based on the ROSC RANDOMBIT register. | /// Random number generator based on the ROSC RANDOMBIT register. | ||||||
| /// | /// | ||||||
| /// This will not produce random values if the ROSC is stopped or run at some | /// This will not produce random values if the ROSC is stopped or run at some | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user