parent
14eecf2fc4
commit
c1eaad41f3
2 changed files with 106 additions and 61 deletions
|
@ -61,7 +61,7 @@ embedded-storage = { version = "0.3" }
|
|||
rand_core = "0.6.4"
|
||||
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-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"
|
||||
pio-proc = {version= "0.2" }
|
||||
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 crate::{pac, reset};
|
||||
use crate::{pac, reset, Peripheral};
|
||||
|
||||
// TODO fix terrible use of global here
|
||||
static mut XIN_HZ: u32 = 0;
|
||||
|
@ -543,53 +544,26 @@ pub fn clk_rtc_freq() -> u32 {
|
|||
base / int
|
||||
}
|
||||
|
||||
pub fn clk_gpout0_freq() -> u32 {
|
||||
pub fn clk_gpout_freq(num: usize) -> u32 {
|
||||
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 {
|
||||
ClkGpout0ctrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(),
|
||||
ClkGpout0ctrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(),
|
||||
ClkGpout0ctrlAuxsrc::XOSC_CLKSRC => xosc_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLK_SYS => clk_sys_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLK_USB => clk_usb_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLK_ADC => clk_adc_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLK_RTC => clk_rtc_freq(),
|
||||
ClkGpout0ctrlAuxsrc::CLK_REF => clk_ref_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLKSRC_PLL_SYS => pll_sys_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLKSRC_GPIN0 => gpin0_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLKSRC_GPIN1 => gpin1_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLKSRC_PLL_USB => pll_usb_freq(),
|
||||
ClkGpoutCtrlAuxsrc::ROSC_CLKSRC => estimate_rosc_freq(),
|
||||
ClkGpoutCtrlAuxsrc::XOSC_CLKSRC => xosc_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLK_SYS => clk_sys_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLK_USB => clk_usb_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLK_ADC => clk_adc_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLK_RTC => clk_rtc_freq(),
|
||||
ClkGpoutCtrlAuxsrc::CLK_REF => clk_ref_freq(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let div = unsafe { c.clk_gpout0_div().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 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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
pub trait GpoutPin {}
|
||||
pub trait GpinPin {
|
||||
fn gpin_number(&self) -> usize;
|
||||
fn pin_number(&self) -> usize;
|
||||
}
|
||||
|
||||
impl GpoutPin for crate::peripherals::PIN_21 {}
|
||||
impl GpoutPin for crate::peripherals::PIN_23 {}
|
||||
impl GpoutPin for crate::peripherals::PIN_24 {}
|
||||
impl GpoutPin for crate::peripherals::PIN_25 {}
|
||||
macro_rules! impl_gpinpin {
|
||||
($name:ident, $pin_num:expr, $gpin_num:expr) => {
|
||||
impl GpinPin for crate::peripherals::$name {
|
||||
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> {
|
||||
_pin: PeripheralRef<'d, T>,
|
||||
gpout: PeripheralRef<'d, T>,
|
||||
}
|
||||
|
||||
impl<'d, T: GpoutPin> Gpout<'d, T> {
|
||||
pub fn new(_pin: impl Peripheral<P = T> + 'd) -> Self {
|
||||
into_ref!(_pin);
|
||||
pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self {
|
||||
into_ref!(gpout);
|
||||
|
||||
unsafe {
|
||||
let p = pac::IO_BANK0.gpio(21).ctrl();
|
||||
p.write(|w| w.set_funcsel(pac::io::vals::Gpio21ctrlFuncsel::CLOCKS_GPOUT_0.0));
|
||||
let p = pac::IO_BANK0.gpio(gpout.pin_number()).ctrl();
|
||||
p.write(|w| w.set_funcsel(0x08));
|
||||
}
|
||||
|
||||
Self { _pin }
|
||||
Self { gpout }
|
||||
}
|
||||
|
||||
pub fn set_div(&self, int: u32, frac: u8) {
|
||||
unsafe {
|
||||
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_frac(frac);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_src(&self, src: ClkGpout0ctrlAuxsrc) {
|
||||
pub fn set_src(&self, src: ClkGpoutCtrlAuxsrc) {
|
||||
unsafe {
|
||||
let c = pac::CLOCKS;
|
||||
c.clk_gpout0_ctrl().modify(|w| {
|
||||
c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| {
|
||||
w.set_auxsrc(src);
|
||||
});
|
||||
}
|
||||
|
@ -716,7 +749,7 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
|
|||
pub fn enable(&self) {
|
||||
unsafe {
|
||||
let c = pac::CLOCKS;
|
||||
c.clk_gpout0_ctrl().modify(|w| {
|
||||
c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| {
|
||||
w.set_enable(true);
|
||||
});
|
||||
}
|
||||
|
@ -725,13 +758,22 @@ impl<'d, T: GpoutPin> Gpout<'d, T> {
|
|||
pub fn disable(&self) {
|
||||
unsafe {
|
||||
let c = pac::CLOCKS;
|
||||
c.clk_gpout0_ctrl().modify(|w| {
|
||||
c.clk_gpout_ctrl(self.gpout.gpout_number()).modify(|w| {
|
||||
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.
|
||||
///
|
||||
/// This will not produce random values if the ROSC is stopped or run at some
|
||||
|
|
Loading…
Reference in a new issue