Skip to content

Commit

Permalink
rcc_shared_m & rcc_i2s_apb features
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 18, 2024
1 parent 4f1caae commit ddc96c5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 72 deletions.
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ gpio-f401 = [
"tim9",
"tim10",
"tim11",
"rcc_shared_m"
]
gpio-f410 = [
"dac",
Expand Down Expand Up @@ -230,6 +231,7 @@ gpio-f412 = [
"tim13",
"tim14",
"usart3",
"rcc_i2s_apb",
]
gpio-f413 = [
"gpiod",
Expand Down Expand Up @@ -275,6 +277,7 @@ gpio-f413 = [
"uart8",
"uart9",
"uart10",
"rcc_i2s_apb",
]
gpio-f417 = [
"gpiod",
Expand Down Expand Up @@ -313,6 +316,7 @@ gpio-f417 = [
"usart3",
"uart4",
"uart5",
"rcc_shared_m"
]
gpio-f427 = [
"gpiod",
Expand Down Expand Up @@ -360,6 +364,7 @@ gpio-f427 = [
"uart5",
"uart7",
"uart8",
"rcc_shared_m"
]
gpio-f446 = [
"gpiod",
Expand Down Expand Up @@ -401,6 +406,7 @@ gpio-f446 = [
"usart3",
"uart4",
"uart5",
"rcc_i2s_apb",
]
gpio-f469 = [
"gpiod",
Expand Down Expand Up @@ -451,6 +457,7 @@ gpio-f469 = [
"uart5",
"uart7",
"uart8",
"rcc_shared_m"
]

## Support monotonic timers and other stuff that can be used by [RTICv1 framework](https://crates.io/crates/cortex-m-rtic)
Expand Down Expand Up @@ -490,8 +497,12 @@ fsmc_lcd = ["dep:display-interface", "dep:display-interface-04"]
## SDIO peripheral support. See [sdio-host](https://crates.io/crates/sdio-host)
sdio-host = ["dep:sdio-host"]

## Next features are for internal use only!!!

dfsdm = []
sai = []
rcc_shared_m = []
rcc_i2s_apb = []

adc2 = []
adc3 = []
Expand Down
8 changes: 4 additions & 4 deletions src/i2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ where

impl I2sFreq for rcc::APB1 {
fn try_i2s_freq(clocks: &Clocks) -> Option<Hertz> {
#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
{
clocks.i2s_clk()
}
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
{
clocks.i2s_apb1_clk()
}
Expand All @@ -69,11 +69,11 @@ impl I2sFreq for rcc::APB1 {

impl I2sFreq for rcc::APB2 {
fn try_i2s_freq(clocks: &Clocks) -> Option<Hertz> {
#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
{
clocks.i2s_clk()
}
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
{
clocks.i2s_apb2_clk()
}
Expand Down
66 changes: 29 additions & 37 deletions src/rcc/f4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,11 @@ impl RccExt for RCC {
pll48clk: false,
i2s_ckin: None,

#[cfg(not(any(
feature = "gpio-f412",
feature = "gpio-f413",
feature = "gpio-f446"
)))]
#[cfg(not(feature = "rcc_i2s_apb"))]
i2s_clk: None,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb1_clk: None,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb2_clk: None,

#[cfg(feature = "sai")]
Expand Down Expand Up @@ -317,11 +313,11 @@ pub struct CFGR {

i2s_ckin: Option<u32>,

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
i2s_clk: Option<u32>,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb1_clk: Option<u32>,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb2_clk: Option<u32>,

#[cfg(feature = "sai")]
Expand Down Expand Up @@ -387,7 +383,7 @@ impl CFGR {
}
}

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
impl CFGR {
/// Selects an I2S clock frequency and enables the I2S clock.
pub fn i2s_clk(mut self, freq: Hertz) -> Self {
Expand All @@ -396,7 +392,7 @@ impl CFGR {
}
}

#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
impl CFGR {
/// Selects an I2S clock frequency for the first set of I2S instancesand enables the I2S clock.
pub fn i2s_apb1_clk(mut self, freq: Hertz) -> Self {
Expand Down Expand Up @@ -468,7 +464,7 @@ impl CFGR {
}

impl CFGR {
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
fn i2s_clocks(&self) -> I2sClocks {
let i2s_apb1_ext = self.i2s_apb1_clk.is_some() && self.i2s_apb1_clk == self.i2s_ckin;
let i2s_apb2_ext = self.i2s_apb2_clk.is_some() && self.i2s_apb2_clk == self.i2s_ckin;
Expand All @@ -492,7 +488,7 @@ impl CFGR {
}
}

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
fn i2s_clocks(&self) -> I2sClocks {
let i2s_ext = self.i2s_clk.is_some() && self.i2s_clk == self.i2s_ckin;
let pll_i2s_clk = if i2s_ext { None } else { self.i2s_clk };
Expand Down Expand Up @@ -716,11 +712,11 @@ impl CFGR {
sysclk: sysclk.Hz(),
pll48clk: plls.pll48clk.map(Hertz::from_raw),

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
i2s_clk: plls.i2s.i2s_clk.map(Hertz::from_raw),
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb1_clk: plls.i2s.apb1.i2s_clk.map(Hertz::from_raw),
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb2_clk: plls.i2s.apb2.i2s_clk.map(Hertz::from_raw),

#[cfg(feature = "sai")]
Expand All @@ -747,21 +743,21 @@ impl CFGR {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct I2sClocks {
/// True if the clock for the APB1 I2S instances is identical to I2S_CKIN.
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb1_ext: bool,
/// True if the clock for the APB2 I2S instances is identical to I2S_CKIN.
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb2_ext: bool,
/// True if the clock for I2S is identical to I2S_CKIN.
#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
i2s_ext: bool,
/// Target for the I2S PLL output.
pll_i2s_clk: Option<u32>,
}

impl I2sClocks {
fn real(&self, pll_i2s_clk: Option<u32>, i2s_ckin: Option<u32>) -> RealI2sClocks {
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
let clk = RealI2sClocks {
apb1: RealI2sClock {
i2s_ext: self.i2s_apb1_ext,
Expand All @@ -780,7 +776,7 @@ impl I2sClocks {
},
},
};
#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
let clk = RealI2sClocks {
i2s_ext: self.i2s_ext,
i2s_clk: if self.i2s_ext { i2s_ckin } else { pll_i2s_clk },
Expand All @@ -796,27 +792,23 @@ struct RealI2sClock {
i2s_clk: Option<u32>,
}

#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct RealI2sClocks {
apb1: RealI2sClock,
apb2: RealI2sClock,
}

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
use RealI2sClock as RealI2sClocks;

impl RealI2sClocks {
fn config_clocksel(&self) {
let rcc = unsafe { &*RCC::ptr() };

#[cfg(not(any(
feature = "gpio-f410",
feature = "gpio-f412",
feature = "gpio-f413",
feature = "gpio-f446",
)))]
#[cfg(not(feature = "gpio-f410"))]
#[cfg(not(feature = "rcc_i2s_apb"))]
rcc.cfgr().modify(|_, w| {
if self.i2s_ext {
w.i2ssrc().ckin()
Expand All @@ -832,7 +824,7 @@ impl RealI2sClocks {
w.i2ssrc().pllclkr()
}
});
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
rcc.dckcfgr().modify(|_, w| {
if self.apb1.i2s_ext {
w.i2s1src().i2s_ckin()
Expand Down Expand Up @@ -933,11 +925,11 @@ pub struct Clocks {
sysclk: Hertz,
pll48clk: Option<Hertz>,

#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
i2s_clk: Option<Hertz>,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb1_clk: Option<Hertz>,
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
i2s_apb2_clk: Option<Hertz>,

#[cfg(feature = "sai")]
Expand Down Expand Up @@ -998,17 +990,17 @@ impl Clocks {
}

/// Returns the frequency of the I2S clock.
#[cfg(not(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446")))]
#[cfg(not(feature = "rcc_i2s_apb"))]
pub fn i2s_clk(&self) -> Option<Hertz> {
self.i2s_clk
}
/// Returns the frequency of the first I2S clock (for the I2S peripherals on APB1).
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
pub fn i2s_apb1_clk(&self) -> Option<Hertz> {
self.i2s_apb1_clk
}
/// Returns the frequency of the second I2S clock (for the I2S peripherals on APB2).
#[cfg(any(feature = "gpio-f412", feature = "gpio-f413", feature = "gpio-f446"))]
#[cfg(feature = "rcc_i2s_apb")]
pub fn i2s_apb2_clk(&self) -> Option<Hertz> {
self.i2s_apb2_clk
}
Expand Down
44 changes: 13 additions & 31 deletions src/rcc/f4/pll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,17 @@ impl PllSetup {
// All PLLs are completely independent.
let main_pll = MainPll::fast_setup(pllsrcclk, cfgr.hse.is_some(), pllsysclk, cfgr.pll48clk);

#[cfg(any(feature = "gpio-f411", feature = "gpio-f412", feature = "gpio-f446"))]
#[cfg(not(feature = "rcc_shared_m"))]
let i2s_pll = I2sPll::setup(pllsrcclk, i2s_clocks.pll_i2s_clk);
#[cfg(any(
feature = "gpio-f401",
feature = "gpio-f417",
feature = "gpio-f427",
feature = "gpio-f469",
))]
#[cfg(feature = "rcc_shared_m")]
// We have separate PLLs, but they share the "M" divider.
let i2s_pll = I2sPll::setup_shared_m(pllsrcclk, main_pll.m(), i2s_clocks.pll_i2s_clk);

#[cfg(any(feature = "gpio-f446"))]
#[cfg(feature = "sai")]
#[cfg(not(feature = "rcc_shared_m"))]
let sai_pll = SaiPll::setup(pllsrcclk, sai_clocks.pll_sai_clk);
#[cfg(any(feature = "gpio-f427", feature = "gpio-f469"))]
#[cfg(feature = "sai")]
#[cfg(feature = "rcc_shared_m")]
let sai_pll = SaiPll::setup_shared_m(
pllsrcclk,
main_pll.m().or(i2s_pll.m()),
Expand Down Expand Up @@ -391,7 +388,7 @@ impl MainPll {
}
let div = crate::min_u32(crate::max_u32(div, min_div), max_div);
let output = vco_out / div;
let error = (output as i32 - target as i32).abs() as u32;
let error = (output as i32 - target as i32).unsigned_abs();
Some((div, output, error))
}
}
Expand Down Expand Up @@ -447,12 +444,7 @@ impl I2sPll {
pll
}

#[cfg(any(
feature = "gpio-f401",
feature = "gpio-f417",
feature = "gpio-f427",
feature = "gpio-f469",
))]
#[cfg(feature = "rcc_shared_m")]
fn setup_shared_m(pllsrcclk: u32, m: Option<u32>, plli2sclk: Option<u32>) -> Self {
// "m" is None if the main PLL is not in use.
let Some(m) = m else {
Expand Down Expand Up @@ -483,21 +475,11 @@ impl I2sPll {
fn apply_config(config: SingleOutputPll) {
let rcc = unsafe { &*RCC::ptr() };
// "M" may have been written before, but the value is identical.
#[cfg(any(
feature = "gpio-f401",
feature = "gpio-f417",
feature = "gpio-f427",
feature = "gpio-f469",
))]
#[cfg(feature = "rcc_shared_m")]
rcc.pllcfgr()
.modify(|_, w| unsafe { w.pllm().bits(config.m) });
rcc.plli2scfgr().modify(|_, w| unsafe {
#[cfg(any(
feature = "gpio-f411",
feature = "gpio-f412",
feature = "gpio-f413",
feature = "gpio-f446",
))]
#[cfg(not(feature = "rcc_shared_m"))]
w.plli2sm().bits(config.m);
w.plli2sn().bits(config.n);
w.plli2sr().bits(config.outdiv)
Expand Down Expand Up @@ -547,7 +529,7 @@ impl SaiPll {
pll
}

#[cfg(any(feature = "gpio-f427", feature = "gpio-f469"))]
#[cfg(feature = "rcc_shared_m")]
fn setup_shared_m(pllsrcclk: u32, m: Option<u32>, sai_clk: Option<u32>) -> Self {
// "m" is None if both other PLLs are not in use.
let Some(m) = m else {
Expand Down Expand Up @@ -592,11 +574,11 @@ impl SaiPll {
rcc.dckcfgr()
.modify(|_, w| w.pllsaidivq().set(saidiv as u8 - 1));
// "M" may have been written before, but the value is identical.
#[cfg(any(feature = "gpio-f427", feature = "gpio-f469"))]
#[cfg(feature = "rcc_shared_m")]
rcc.pllcfgr()
.modify(|_, w| unsafe { w.pllm().bits(config.m) });
rcc.pllsaicfgr().modify(|_, w| unsafe {
#[cfg(feature = "gpio-f446")]
#[cfg(not(feature = "rcc_shared_m"))]
w.pllsaim().bits(config.m);
w.pllsain().bits(config.n);
w.pllsaiq().bits(config.outdiv)
Expand Down

0 comments on commit ddc96c5

Please sign in to comment.