parent
14eecf2fc4
commit
c1eaad41f3
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user