1360: stm32/rcc: add i2s pll on some f4 micros r=Dirbaio a=xoviat

Adds the i2s pll on some f4 micros. 

1361: Executor: Replace unnecessary atomics in runqueue r=Dirbaio a=GrantM11235

Only the head pointer needs to be atomic. The `RunQueueItem` pointers are only loaded and stored, and never concurrently

Co-authored-by: xoviat <xoviat@users.noreply.github.com>
Co-authored-by: Grant Miller <GrantM11235@gmail.com>
This commit is contained in:
bors[bot]
2023-04-15 10:38:28 +00:00
committed by GitHub
3 changed files with 100 additions and 10 deletions

View File

@ -29,10 +29,66 @@ pub struct Config {
pub pclk1: Option<Hertz>,
pub pclk2: Option<Hertz>,
#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))]
pub plli2s: Option<Hertz>,
pub pll48: bool,
}
unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
#[cfg(stm32f410)]
unsafe fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
None
}
// Not currently implemented, but will be in the future
#[cfg(any(stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))]
unsafe fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> {
None
}
#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))]
unsafe fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> {
let min_div = 2;
let max_div = 7;
let target = match plli2s {
Some(target) => target,
None => return None,
};
// We loop through the possible divider values to find the best configuration. Looping
// through all possible "N" values would result in more iterations.
let (n, outdiv, output, _error) = (min_div..=max_div)
.filter_map(|outdiv| {
let target_vco_out = match target.checked_mul(outdiv) {
Some(x) => x,
None => return None,
};
let n = (target_vco_out + (vco_in >> 1)) / vco_in;
let vco_out = vco_in * n;
if !(100_000_000..=432_000_000).contains(&vco_out) {
return None;
}
let output = vco_out / outdiv;
let error = (output as i32 - target as i32).unsigned_abs();
Some((n, outdiv, output, error))
})
.min_by_key(|(_, _, _, error)| *error)?;
RCC.plli2scfgr().modify(|w| {
w.set_plli2sn(n as u16);
w.set_plli2sr(outdiv as u8);
});
Some(output)
}
unsafe fn setup_pll(
pllsrcclk: u32,
use_hse: bool,
pllsysclk: Option<u32>,
plli2s: Option<u32>,
pll48clk: bool,
) -> PllResults {
use crate::pac::rcc::vals::{Pllp, Pllsrc};
let sysclk = pllsysclk.unwrap_or(pllsrcclk);
@ -43,6 +99,7 @@ unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48
use_pll: false,
pllsysclk: None,
pll48clk: None,
plli2sclk: None,
};
}
// Input divisor from PLL source clock, must result to frequency in
@ -101,6 +158,7 @@ unsafe fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48
use_pll: true,
pllsysclk: Some(real_pllsysclk),
pll48clk: if pll48clk { Some(real_pll48clk) } else { None },
plli2sclk: setup_i2s_pll(vco_in, plli2s),
}
}
@ -286,6 +344,10 @@ pub(crate) unsafe fn init(config: Config) {
pllsrcclk,
config.hse.is_some(),
if sysclk_on_pll { Some(sysclk) } else { None },
#[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))]
config.plli2s.map(|i2s| i2s.0),
#[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))]
None,
config.pll48,
);
@ -376,6 +438,13 @@ pub(crate) unsafe fn init(config: Config) {
while !RCC.cr().read().pllrdy() {}
}
#[cfg(not(stm32f410))]
if plls.plli2sclk.is_some() {
RCC.cr().modify(|w| w.set_plli2son(true));
while !RCC.cr().read().plli2srdy() {}
}
RCC.cfgr().modify(|w| {
w.set_ppre2(Ppre(ppre2_bits));
w.set_ppre1(Ppre(ppre1_bits));
@ -409,6 +478,12 @@ pub(crate) unsafe fn init(config: Config) {
ahb3: Hertz(hclk),
pll48: plls.pll48clk.map(Hertz),
#[cfg(not(stm32f410))]
plli2s: plls.plli2sclk.map(Hertz),
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pllsai: None,
});
}
@ -416,6 +491,8 @@ struct PllResults {
use_pll: bool,
pllsysclk: Option<u32>,
pll48clk: Option<u32>,
#[allow(dead_code)]
plli2sclk: Option<u32>,
}
mod max {

View File

@ -60,6 +60,12 @@ pub struct Clocks {
#[cfg(any(rcc_f2, rcc_f4, rcc_f410, rcc_f7))]
pub pll48: Option<Hertz>,
#[cfg(all(rcc_f4, not(stm32f410)))]
pub plli2s: Option<Hertz>,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pub pllsai: Option<Hertz>,
#[cfg(stm32f1)]
pub adc: Hertz,