Merge pull request #2625 from OroArmor/add-pll1_p_mul_2-clock

Add `PLL1_P_MUL_2` clock.
This commit is contained in:
Dario Nieuwenhuis 2024-02-26 02:16:41 +00:00 committed by GitHub
commit 1ad28581c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 246 additions and 377 deletions

View file

@ -70,7 +70,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0"
critical-section = "1.1"
#stm32-metapac = { version = "15" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6097928f720646c73d6483a3245f922bd5faee2f" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7c8b53413499acc3273b706318777a60f932d77a" }
vcell = "0.1.3"
bxcan = "0.7.0"
nb = "1.0.0"
@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] }
proc-macro2 = "1.0.36"
quote = "1.0.15"
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6097928f720646c73d6483a3245f922bd5faee2f", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7c8b53413499acc3273b706318777a60f932d77a", default-features = false, features = ["metadata"]}
[features]

View file

@ -74,7 +74,7 @@ impl<'d, T: Instance> Adc<'d, T> {
Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
}
}
@ -84,14 +84,14 @@ impl<'d, T: Instance> Adc<'d, T> {
pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
match us * Self::freq().0 / 1_000_000 {
0..=1 => SampleTime::Cycles1_5,
2..=7 => SampleTime::Cycles7_5,
8..=13 => SampleTime::Cycles13_5,
14..=28 => SampleTime::Cycles28_5,
29..=41 => SampleTime::Cycles41_5,
42..=55 => SampleTime::Cycles55_5,
56..=71 => SampleTime::Cycles71_5,
_ => SampleTime::Cycles239_5,
0..=1 => SampleTime::CYCLES1_5,
2..=7 => SampleTime::CYCLES7_5,
8..=13 => SampleTime::CYCLES13_5,
14..=28 => SampleTime::CYCLES28_5,
29..=41 => SampleTime::CYCLES41_5,
42..=55 => SampleTime::CYCLES55_5,
56..=71 => SampleTime::CYCLES71_5,
_ => SampleTime::CYCLES239_5,
}
}

View file

@ -97,7 +97,7 @@ impl<'d, T: Instance> Adc<'d, T> {
Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
}
}
@ -107,13 +107,13 @@ impl<'d, T: Instance> Adc<'d, T> {
pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
match us * Self::freq().0 / 1_000_000 {
0..=1 => SampleTime::Cycles1_5,
2..=4 => SampleTime::Cycles4_5,
5..=7 => SampleTime::Cycles7_5,
8..=19 => SampleTime::Cycles19_5,
20..=61 => SampleTime::Cycles61_5,
62..=181 => SampleTime::Cycles181_5,
_ => SampleTime::Cycles601_5,
0..=1 => SampleTime::CYCLES1_5,
2..=4 => SampleTime::CYCLES4_5,
5..=7 => SampleTime::CYCLES7_5,
8..=19 => SampleTime::CYCLES19_5,
20..=61 => SampleTime::CYCLES61_5,
62..=181 => SampleTime::CYCLES181_5,
_ => SampleTime::CYCLES601_5,
}
}

View file

@ -107,12 +107,12 @@ impl Calibration {
/// Returns a calibrated voltage value as in microvolts (uV)
pub fn cal_uv(&self, raw: u16, resolution: super::Resolution) -> u32 {
(self.vdda_uv() / resolution.to_max_count()) * raw as u32
(self.vdda_uv() / super::resolution_to_max_count(resolution)) * raw as u32
}
/// Returns a calibrated voltage value as an f32
pub fn cal_f32(&self, raw: u16, resolution: super::Resolution) -> f32 {
raw as f32 * self.vdda_f32() / resolution.to_max_count() as f32
raw as f32 * self.vdda_f32() / super::resolution_to_max_count(resolution) as f32
}
}
@ -175,12 +175,7 @@ impl<'d, T: Instance> Adc<'d, T> {
}
pub fn resolution(&self) -> Resolution {
match T::regs().cr1().read().res() {
crate::pac::adc::vals::Res::TWELVEBIT => Resolution::TwelveBit,
crate::pac::adc::vals::Res::TENBIT => Resolution::TenBit,
crate::pac::adc::vals::Res::EIGHTBIT => Resolution::EightBit,
crate::pac::adc::vals::Res::SIXBIT => Resolution::SixBit,
}
T::regs().cr1().read().res()
}
pub fn enable_vref(&self) -> Vref<T> {
@ -359,23 +354,23 @@ impl<'d, T: Instance> Adc<'d, T> {
fn get_res_clks(res: Resolution) -> u32 {
match res {
Resolution::TwelveBit => 12,
Resolution::TenBit => 11,
Resolution::EightBit => 9,
Resolution::SixBit => 7,
Resolution::BITS12 => 12,
Resolution::BITS10 => 11,
Resolution::BITS8 => 9,
Resolution::BITS6 => 7,
}
}
fn get_sample_time_clks(sample_time: SampleTime) -> u32 {
match sample_time {
SampleTime::Cycles4 => 4,
SampleTime::Cycles9 => 9,
SampleTime::Cycles16 => 16,
SampleTime::Cycles24 => 24,
SampleTime::Cycles48 => 48,
SampleTime::Cycles96 => 96,
SampleTime::Cycles192 => 192,
SampleTime::Cycles384 => 384,
SampleTime::CYCLES4 => 4,
SampleTime::CYCLES9 => 9,
SampleTime::CYCLES16 => 16,
SampleTime::CYCLES24 => 24,
SampleTime::CYCLES48 => 48,
SampleTime::CYCLES96 => 96,
SampleTime::CYCLES192 => 192,
SampleTime::CYCLES384 => 384,
}
}
@ -384,14 +379,14 @@ impl<'d, T: Instance> Adc<'d, T> {
let us_clks = us * Self::freq().0 / 1_000_000;
let clks = us_clks.saturating_sub(res_clks);
match clks {
0..=4 => SampleTime::Cycles4,
5..=9 => SampleTime::Cycles9,
10..=16 => SampleTime::Cycles16,
17..=24 => SampleTime::Cycles24,
25..=48 => SampleTime::Cycles48,
49..=96 => SampleTime::Cycles96,
97..=192 => SampleTime::Cycles192,
193.. => SampleTime::Cycles384,
0..=4 => SampleTime::CYCLES4,
5..=9 => SampleTime::CYCLES9,
10..=16 => SampleTime::CYCLES16,
17..=24 => SampleTime::CYCLES24,
25..=48 => SampleTime::CYCLES48,
49..=96 => SampleTime::CYCLES96,
97..=192 => SampleTime::CYCLES192,
193.. => SampleTime::CYCLES384,
}
}

View file

@ -10,22 +10,17 @@
#[cfg_attr(adc_v1, path = "v1.rs")]
#[cfg_attr(adc_l0, path = "v1.rs")]
#[cfg_attr(adc_v2, path = "v2.rs")]
#[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")]
#[cfg_attr(any(adc_v3, adc_g0, adc_h5), path = "v3.rs")]
#[cfg_attr(adc_v4, path = "v4.rs")]
mod _version;
#[cfg(not(any(adc_f1, adc_f3_v2)))]
mod resolution;
mod sample_time;
#[allow(unused)]
#[cfg(not(adc_f3_v2))]
pub use _version::*;
#[cfg(not(any(adc_f1, adc_f3, adc_f3_v2)))]
pub use resolution::Resolution;
#[cfg(not(adc_f3_v2))]
pub use sample_time::SampleTime;
#[cfg(not(any(adc_f1, adc_f3_v2)))]
pub use crate::pac::adc::vals::Res as Resolution;
pub use crate::pac::adc::vals::SampleTime;
use crate::peripherals;
/// Analog to Digital driver.
@ -79,10 +74,10 @@ pub(crate) mod sealed {
}
/// ADC instance.
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0)))]
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
/// ADC instance.
#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0))]
#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))]
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
/// ADC pin.
@ -137,3 +132,27 @@ macro_rules! impl_adc_pin {
}
};
}
/// Get the maximum reading value for this resolution.
///
/// This is `2**n - 1`.
#[cfg(not(any(adc_f1, adc_f3_v2)))]
pub const fn resolution_to_max_count(res: Resolution) -> u32 {
match res {
#[cfg(adc_v4)]
Resolution::BITS16 => (1 << 16) - 1,
#[cfg(adc_v4)]
Resolution::BITS14 => (1 << 14) - 1,
#[cfg(adc_v4)]
Resolution::BITS14V => (1 << 14) - 1,
#[cfg(adc_v4)]
Resolution::BITS12V => (1 << 12) - 1,
Resolution::BITS12 => (1 << 12) - 1,
Resolution::BITS10 => (1 << 10) - 1,
Resolution::BITS8 => (1 << 8) - 1,
#[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1, adc_h5))]
Resolution::BITS6 => (1 << 6) - 1,
#[allow(unreachable_patterns)]
_ => core::unreachable!(),
}
}

View file

@ -1,72 +0,0 @@
/// ADC resolution
#[allow(missing_docs)]
#[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Resolution {
TwelveBit,
TenBit,
EightBit,
SixBit,
}
/// ADC resolution
#[allow(missing_docs)]
#[cfg(adc_v4)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Resolution {
SixteenBit,
FourteenBit,
TwelveBit,
TenBit,
EightBit,
}
impl Default for Resolution {
fn default() -> Self {
#[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))]
{
Self::TwelveBit
}
#[cfg(adc_v4)]
{
Self::SixteenBit
}
}
}
impl From<Resolution> for crate::pac::adc::vals::Res {
fn from(res: Resolution) -> crate::pac::adc::vals::Res {
match res {
#[cfg(adc_v4)]
Resolution::SixteenBit => crate::pac::adc::vals::Res::SIXTEENBIT,
#[cfg(adc_v4)]
Resolution::FourteenBit => crate::pac::adc::vals::Res::FOURTEENBITV,
Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
#[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))]
Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
}
}
}
impl Resolution {
/// Get the maximum reading value for this resolution.
///
/// This is `2**n - 1`.
pub const fn to_max_count(&self) -> u32 {
match self {
#[cfg(adc_v4)]
Resolution::SixteenBit => (1 << 16) - 1,
#[cfg(adc_v4)]
Resolution::FourteenBit => (1 << 14) - 1,
Resolution::TwelveBit => (1 << 12) - 1,
Resolution::TenBit => (1 << 10) - 1,
Resolution::EightBit => (1 << 8) - 1,
#[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))]
Resolution::SixBit => (1 << 6) - 1,
}
}
}

View file

@ -1,148 +0,0 @@
#[cfg(not(adc_f3_v2))]
macro_rules! impl_sample_time {
($default_doc:expr, $default:ident, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => {
#[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SampleTime {
$(
#[doc = concat!($doc, " ADC clock cycles.")]
$variant,
)*
}
impl From<SampleTime> for crate::pac::adc::vals::SampleTime {
fn from(sample_time: SampleTime) -> crate::pac::adc::vals::SampleTime {
match sample_time {
$(SampleTime::$variant => crate::pac::adc::vals::SampleTime::$pac_variant),*
}
}
}
impl From<crate::pac::adc::vals::SampleTime> for SampleTime {
fn from(sample_time: crate::pac::adc::vals::SampleTime) -> SampleTime {
match sample_time {
$(crate::pac::adc::vals::SampleTime::$pac_variant => SampleTime::$variant),*
}
}
}
impl Default for SampleTime {
fn default() -> Self {
Self::$default
}
}
};
}
#[cfg(any(adc_f1, adc_v1))]
impl_sample_time!(
"1.5",
Cycles1_5,
(
("1.5", Cycles1_5, CYCLES1_5),
("7.5", Cycles7_5, CYCLES7_5),
("13.5", Cycles13_5, CYCLES13_5),
("28.5", Cycles28_5, CYCLES28_5),
("41.5", Cycles41_5, CYCLES41_5),
("55.5", Cycles55_5, CYCLES55_5),
("71.5", Cycles71_5, CYCLES71_5),
("239.5", Cycles239_5, CYCLES239_5)
)
);
#[cfg(adc_v2)]
impl_sample_time!(
"3",
Cycles3,
(
("3", Cycles3, CYCLES3),
("15", Cycles15, CYCLES15),
("28", Cycles28, CYCLES28),
("56", Cycles56, CYCLES56),
("84", Cycles84, CYCLES84),
("112", Cycles112, CYCLES112),
("144", Cycles144, CYCLES144),
("480", Cycles480, CYCLES480)
)
);
#[cfg(adc_v3)]
impl_sample_time!(
"2.5",
Cycles2_5,
(
("2.5", Cycles2_5, CYCLES2_5),
("6.5", Cycles6_5, CYCLES6_5),
("12.5", Cycles12_5, CYCLES12_5),
("24.5", Cycles24_5, CYCLES24_5),
("47.5", Cycles47_5, CYCLES47_5),
("92.5", Cycles92_5, CYCLES92_5),
("247.5", Cycles247_5, CYCLES247_5),
("640.5", Cycles640_5, CYCLES640_5)
)
);
#[cfg(any(adc_l0, adc_g0))]
impl_sample_time!(
"1.5",
Cycles1_5,
(
("1.5", Cycles1_5, CYCLES1_5),
("3.5", Cycles3_5, CYCLES3_5),
("7.5", Cycles7_5, CYCLES7_5),
("12.5", Cycles12_5, CYCLES12_5),
("19.5", Cycles19_5, CYCLES19_5),
("39.5", Cycles39_5, CYCLES39_5),
("79.5", Cycles79_5, CYCLES79_5),
("160.5", Cycles160_5, CYCLES160_5)
)
);
#[cfg(adc_v4)]
impl_sample_time!(
"1.5",
Cycles1_5,
(
("1.5", Cycles1_5, CYCLES1_5),
("2.5", Cycles2_5, CYCLES2_5),
("8.5", Cycles8_5, CYCLES8_5),
("16.5", Cycles16_5, CYCLES16_5),
("32.5", Cycles32_5, CYCLES32_5),
("64.5", Cycles64_5, CYCLES64_5),
("387.5", Cycles387_5, CYCLES387_5),
("810.5", Cycles810_5, CYCLES810_5)
)
);
#[cfg(adc_f3)]
impl_sample_time!(
"1.5",
Cycles1_5,
(
("1.5", Cycles1_5, CYCLES1_5),
("2.5", Cycles2_5, CYCLES2_5),
("4.5", Cycles4_5, CYCLES4_5),
("7.5", Cycles7_5, CYCLES7_5),
("19.5", Cycles19_5, CYCLES19_5),
("61.5", Cycles61_5, CYCLES61_5),
("181.5", Cycles181_5, CYCLES181_5),
("601.5", Cycles601_5, CYCLES601_5)
)
);
#[cfg(any(adc_f3_v1_1))]
impl_sample_time!(
"4",
Cycles4,
(
("4", Cycles4, CYCLES4),
("9", Cycles9, CYCLES9),
("16", Cycles16, CYCLES16),
("24", Cycles24, CYCLES24),
("48", Cycles48, CYCLES48),
("96", Cycles96, CYCLES96),
("192", Cycles192, CYCLES192),
("384", Cycles384, CYCLES384)
)
);

View file

@ -109,7 +109,7 @@ impl<'d, T: Instance> Adc<'d, T> {
Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
}
}

View file

@ -111,7 +111,7 @@ where
Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
}
}

View file

@ -1,3 +1,4 @@
use cfg_if::cfg_if;
use embassy_hal_internal::into_ref;
use embedded_hal_02::blocking::delay::DelayUs;
@ -13,10 +14,15 @@ pub struct VrefInt;
impl<T: Instance> AdcPin<T> for VrefInt {}
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
fn channel(&self) -> u8 {
#[cfg(not(adc_g0))]
let val = 0;
#[cfg(adc_g0)]
cfg_if! {
if #[cfg(adc_g0)] {
let val = 13;
} else if #[cfg(adc_h5)] {
let val = 17;
} else {
let val = 0;
}
}
val
}
}
@ -25,10 +31,15 @@ pub struct Temperature;
impl<T: Instance> AdcPin<T> for Temperature {}
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
fn channel(&self) -> u8 {
#[cfg(not(adc_g0))]
let val = 17;
#[cfg(adc_g0)]
cfg_if! {
if #[cfg(adc_g0)] {
let val = 12;
} else if #[cfg(adc_h5)] {
let val = 16;
} else {
let val = 17;
}
}
val
}
}
@ -37,14 +48,31 @@ pub struct Vbat;
impl<T: Instance> AdcPin<T> for Vbat {}
impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
fn channel(&self) -> u8 {
#[cfg(not(adc_g0))]
let val = 18;
#[cfg(adc_g0)]
cfg_if! {
if #[cfg(adc_g0)] {
let val = 14;
} else if #[cfg(adc_h5)] {
let val = 2;
} else {
let val = 18;
}
}
val
}
}
cfg_if! {
if #[cfg(adc_h5)] {
pub struct VddCore;
impl<T: Instance> AdcPin<T> for VddCore {}
impl<T: Instance> super::sealed::AdcPin<T> for VddCore {
fn channel(&self) -> u8 {
6
}
}
}
}
impl<'d, T: Instance> Adc<'d, T> {
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
into_ref!(adc);
@ -74,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
}
}
@ -98,27 +126,41 @@ impl<'d, T: Instance> Adc<'d, T> {
}
pub fn enable_temperature(&self) -> Temperature {
#[cfg(not(adc_g0))]
T::common_regs().ccr().modify(|reg| {
reg.set_ch17sel(true);
});
#[cfg(adc_g0)]
cfg_if! {
if #[cfg(adc_g0)] {
T::regs().ccr().modify(|reg| {
reg.set_tsen(true);
});
} else if #[cfg(adc_h5)] {
T::common_regs().ccr().modify(|reg| {
reg.set_tsen(true);
});
} else {
T::common_regs().ccr().modify(|reg| {
reg.set_ch17sel(true);
});
}
}
Temperature {}
}
pub fn enable_vbat(&self) -> Vbat {
#[cfg(not(adc_g0))]
T::common_regs().ccr().modify(|reg| {
reg.set_ch18sel(true);
});
#[cfg(adc_g0)]
cfg_if! {
if #[cfg(adc_g0)] {
T::regs().ccr().modify(|reg| {
reg.set_vbaten(true);
});
} else if #[cfg(adc_h5)] {
T::common_regs().ccr().modify(|reg| {
reg.set_vbaten(true);
});
} else {
T::common_regs().ccr().modify(|reg| {
reg.set_ch18sel(true);
});
}
}
Vbat {}
}
@ -205,16 +247,21 @@ impl<'d, T: Instance> Adc<'d, T> {
val
}
#[cfg(adc_g0)]
fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
cfg_if! {
if #[cfg(adc_g0)] {
T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into()));
} else if #[cfg(adc_h5)] {
match _ch {
0..=9 => T::regs().smpr1().modify(|w| w.set_smp(_ch as usize % 10, sample_time.into())),
_ => T::regs().smpr2().modify(|w| w.set_smp(_ch as usize % 10, sample_time.into())),
}
#[cfg(not(adc_g0))]
fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
} else {
let sample_time = sample_time.into();
T::regs()
.smpr(ch as usize / 10)
.modify(|reg| reg.set_smp(ch as usize % 10, sample_time));
.smpr(_ch as usize / 10)
.modify(|reg| reg.set_smp(_ch as usize % 10, sample_time));
}
}
}
}

View file

@ -159,7 +159,7 @@ impl<'d, T: Instance> Adc<'d, T> {
}
let mut s = Self {
adc,
sample_time: Default::default(),
sample_time: SampleTime::from_bits(0),
};
s.power_up(delay);
s.configure_differential_inputs();

View file

@ -36,8 +36,10 @@ where
// fmc v1 and v2 does not have the fmcen bit
// fsmc v1, v2 and v3 does not have the fmcen bit
// This is a "not" because it is expected that all future versions have this bit
#[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1)))]
#[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))]
T::REGS.bcr1().modify(|r| r.set_fmcen(true));
#[cfg(any(fmc_v4))]
T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
}
/// Get the kernel clock currently in use for this FMC instance.
@ -60,8 +62,10 @@ where
// fmc v1 and v2 does not have the fmcen bit
// fsmc v1, v2 and v3 does not have the fmcen bit
// This is a "not" because it is expected that all future versions have this bit
#[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1)))]
#[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))]
T::REGS.bcr1().modify(|r| r.set_fmcen(true));
#[cfg(any(fmc_v4))]
T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
}
fn source_clock_hz(&self) -> u32 {

View file

@ -79,20 +79,20 @@ impl Format {
#[cfg(any(spi_v1, spi_f1))]
const fn datlen(&self) -> vals::Datlen {
match self {
Format::Data16Channel16 => vals::Datlen::SIXTEENBIT,
Format::Data16Channel32 => vals::Datlen::SIXTEENBIT,
Format::Data24Channel32 => vals::Datlen::TWENTYFOURBIT,
Format::Data32Channel32 => vals::Datlen::THIRTYTWOBIT,
Format::Data16Channel16 => vals::Datlen::BITS16,
Format::Data16Channel32 => vals::Datlen::BITS16,
Format::Data24Channel32 => vals::Datlen::BITS24,
Format::Data32Channel32 => vals::Datlen::BITS32,
}
}
#[cfg(any(spi_v1, spi_f1))]
const fn chlen(&self) -> vals::Chlen {
match self {
Format::Data16Channel16 => vals::Chlen::SIXTEENBIT,
Format::Data16Channel32 => vals::Chlen::THIRTYTWOBIT,
Format::Data24Channel32 => vals::Chlen::THIRTYTWOBIT,
Format::Data32Channel32 => vals::Chlen::THIRTYTWOBIT,
Format::Data16Channel16 => vals::Chlen::BITS16,
Format::Data16Channel32 => vals::Chlen::BITS32,
Format::Data24Channel32 => vals::Chlen::BITS32,
Format::Data32Channel32 => vals::Chlen::BITS32,
}
}
}

View file

@ -216,6 +216,11 @@ pub fn init(config: Config) -> Peripherals {
#[cfg(dbgmcu)]
crate::pac::DBGMCU.cr().modify(|cr| {
#[cfg(any(dbgmcu_h5))]
{
cr.set_stop(config.enable_debug_during_sleep);
cr.set_standby(config.enable_debug_during_sleep);
}
#[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba, dbgmcu_l5))]
{
cr.set_dbg_stop(config.enable_debug_during_sleep);

View file

@ -209,6 +209,9 @@ pub(crate) unsafe fn init(config: Config) {
out_freq
});
#[cfg(stm32f3)]
let pll_mul_2 = pll.map(|pll| pll * 2u32);
#[cfg(any(rcc_f1, rcc_f1cl, stm32f3))]
let usb = match pll {
Some(Hertz(72_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1_5),
@ -374,6 +377,9 @@ pub(crate) unsafe fn init(config: Config) {
hsi: hsi,
hse: hse,
pll1_p: pll,
#[cfg(stm32f3)]
pll1_p_mul_2: pll_mul_2,
hsi_div_244: hsi.map(|h| h / 244u32),
sys: Some(sys),
pclk1: Some(pclk1),
pclk2: Some(pclk2),

View file

@ -288,6 +288,7 @@ pub(crate) unsafe fn init(config: Config) {
clk48: pll.q,
hsi_div488: hsi.map(|hsi| hsi/488u32),
hsi_hse: None,
afif: None,
);

View file

@ -365,5 +365,6 @@ pub(crate) unsafe fn init(config: Config) {
pll1_q: pll1_q_freq,
pll1_p: pll1_p_freq,
rtc: rtc,
hsi_div_488: None,
);
}

View file

@ -617,6 +617,7 @@ pub(crate) unsafe fn init(config: Config) {
hsi: hsi,
hsi48: hsi48,
csi: csi,
csi_div_122: csi.map(|c| c / 122u32),
hse: hse,
lse: None,

View file

@ -290,6 +290,8 @@ pub(crate) unsafe fn init(config: Config) {
lsi: None,
msik: None,
iclk: None,
shsi: None,
shsi_div_2: None,
);
}

View file

@ -1,5 +1,6 @@
//! Serial Audio Interface (SAI)
#![macro_use]
#![cfg_attr(gpdma, allow(unused))]
use core::marker::PhantomData;
@ -7,6 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use self::sealed::WhichSubBlock;
pub use crate::dma::word;
#[cfg(not(gpdma))]
use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
use crate::gpio::sealed::{AFType, Pin as _};
use crate::gpio::AnyPin;
@ -26,6 +28,7 @@ pub enum Error {
Overrun,
}
#[cfg(not(gpdma))]
impl From<ringbuffer::OverrunError> for Error {
fn from(_: ringbuffer::OverrunError) -> Self {
Self::Overrun
@ -41,7 +44,7 @@ pub enum Mode {
}
impl Mode {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn mode(&self, tx_rx: TxRx) -> vals::Mode {
match tx_rx {
TxRx::Transmitter => match self {
@ -76,7 +79,7 @@ pub enum SlotSize {
}
impl SlotSize {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn slotsz(&self) -> vals::Slotsz {
match self {
SlotSize::DataSize => vals::Slotsz::DATASIZE,
@ -99,7 +102,7 @@ pub enum DataSize {
}
impl DataSize {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn ds(&self) -> vals::Ds {
match self {
DataSize::Data8 => vals::Ds::BIT8,
@ -124,7 +127,7 @@ pub enum FifoThreshold {
}
impl FifoThreshold {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn fth(&self) -> vals::Fth {
match self {
FifoThreshold::Empty => vals::Fth::EMPTY,
@ -145,7 +148,7 @@ pub enum MuteValue {
}
impl MuteValue {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn muteval(&self) -> vals::Muteval {
match self {
MuteValue::Zero => vals::Muteval::SENDZERO,
@ -164,7 +167,7 @@ pub enum Protocol {
}
impl Protocol {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn prtcfg(&self) -> vals::Prtcfg {
match self {
Protocol::Free => vals::Prtcfg::FREE,
@ -183,7 +186,7 @@ pub enum SyncInput {
/// Syncs with the other A/B sub-block within the SAI unit
Internal,
/// Syncs with a sub-block in the other SAI unit
#[cfg(sai_v4)]
#[cfg(any(sai_v4_2pdm, sai_v4_4pdm))]
External(SyncInputInstance),
}
@ -192,14 +195,14 @@ impl SyncInput {
match self {
SyncInput::None => vals::Syncen::ASYNCHRONOUS,
SyncInput::Internal => vals::Syncen::INTERNAL,
#[cfg(any(sai_v4))]
#[cfg(any(sai_v4_2pdm, sai_v4_4pdm))]
SyncInput::External(_) => vals::Syncen::EXTERNAL,
}
}
}
/// SAI instance to sync from.
#[cfg(sai_v4)]
#[cfg(any(sai_v4_2pdm, sai_v4_4pdm))]
#[derive(Copy, Clone, PartialEq)]
#[allow(missing_docs)]
pub enum SyncInputInstance {
@ -222,7 +225,7 @@ pub enum StereoMono {
}
impl StereoMono {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn mono(&self) -> vals::Mono {
match self {
StereoMono::Stereo => vals::Mono::STEREO,
@ -241,7 +244,7 @@ pub enum BitOrder {
}
impl BitOrder {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn lsbfirst(&self) -> vals::Lsbfirst {
match self {
BitOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
@ -260,7 +263,7 @@ pub enum FrameSyncOffset {
}
impl FrameSyncOffset {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn fsoff(&self) -> vals::Fsoff {
match self {
FrameSyncOffset::OnFirstBit => vals::Fsoff::ONFIRST,
@ -279,7 +282,7 @@ pub enum FrameSyncPolarity {
}
impl FrameSyncPolarity {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn fspol(&self) -> vals::Fspol {
match self {
FrameSyncPolarity::ActiveLow => vals::Fspol::FALLINGEDGE,
@ -297,7 +300,7 @@ pub enum FrameSyncDefinition {
}
impl FrameSyncDefinition {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn fsdef(&self) -> bool {
match self {
FrameSyncDefinition::StartOfFrame => false,
@ -315,7 +318,7 @@ pub enum ClockStrobe {
}
impl ClockStrobe {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn ckstr(&self) -> vals::Ckstr {
match self {
ClockStrobe::Falling => vals::Ckstr::FALLINGEDGE,
@ -333,7 +336,7 @@ pub enum ComplementFormat {
}
impl ComplementFormat {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn cpl(&self) -> vals::Cpl {
match self {
ComplementFormat::OnesComplement => vals::Cpl::ONESCOMPLEMENT,
@ -352,7 +355,7 @@ pub enum Companding {
}
impl Companding {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn comp(&self) -> vals::Comp {
match self {
Companding::None => vals::Comp::NOCOMPANDING,
@ -371,7 +374,7 @@ pub enum OutputDrive {
}
impl OutputDrive {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn outdriv(&self) -> vals::Outdriv {
match self {
OutputDrive::OnStart => vals::Outdriv::ONSTART,
@ -404,7 +407,7 @@ pub enum MasterClockDivider {
}
impl MasterClockDivider {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
const fn mckdiv(&self) -> u8 {
match self {
MasterClockDivider::MasterClockDisabled => 0,
@ -501,12 +504,12 @@ impl Config {
}
}
#[cfg(not(gpdma))]
enum RingBuffer<'d, W: word::Word> {
Writable(WritableRingBuffer<'d, W>),
Readable(ReadableRingBuffer<'d, W>),
}
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut W {
let ch = w.ch(sub_block as usize);
ch.dr().as_ptr() as _
@ -528,6 +531,7 @@ fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) {
)
}
#[cfg(not(gpdma))]
fn get_ring_buffer<'d, T: Instance, W: word::Word>(
dma: impl Peripheral<P = impl Channel> + 'd,
dma_buf: &'d mut [W],
@ -554,12 +558,12 @@ fn update_synchronous_config(config: &mut Config) {
config.mode = Mode::Slave;
config.sync_output = false;
#[cfg(any(sai_v1, sai_v2, sai_v3))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm))]
{
config.sync_input = SyncInput::Internal;
}
#[cfg(any(sai_v4))]
#[cfg(any(sai_v4_2pdm, sai_v4_4pdm))]
{
//this must either be Internal or External
//The asynchronous sub-block on the same SAI needs to enable sync_output
@ -599,10 +603,14 @@ pub struct Sai<'d, T: Instance, W: word::Word> {
fs: Option<PeripheralRef<'d, AnyPin>>,
sck: Option<PeripheralRef<'d, AnyPin>>,
mclk: Option<PeripheralRef<'d, AnyPin>>,
#[cfg(gpdma)]
ring_buffer: PhantomData<W>,
#[cfg(not(gpdma))]
ring_buffer: RingBuffer<'d, W>,
sub_block: WhichSubBlock,
}
#[cfg(not(gpdma))]
impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
/// Create a new SAI driver in asynchronous mode with MCLK.
///
@ -715,13 +723,13 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
ring_buffer: RingBuffer<'d, W>,
config: Config,
) -> Self {
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
{
let ch = T::REGS.ch(sub_block as usize);
ch.cr1().modify(|w| w.set_saien(false));
}
#[cfg(any(sai_v4))]
#[cfg(any(sai_v4_2pdm, sai_v4_4pdm))]
{
if let SyncInput::External(i) = config.sync_input {
T::REGS.gcr().modify(|w| {
@ -740,7 +748,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
}
}
#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
#[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))]
{
let ch = T::REGS.ch(sub_block as usize);
ch.cr1().modify(|w| {

View file

@ -1005,8 +1005,8 @@ mod word_impl {
pub type Config = vals::Dff;
impl_word!(u8, vals::Dff::EIGHTBIT);
impl_word!(u16, vals::Dff::SIXTEENBIT);
impl_word!(u8, vals::Dff::BITS8);
impl_word!(u16, vals::Dff::BITS16);
}
#[cfg(spi_v2)]
@ -1015,19 +1015,19 @@ mod word_impl {
pub type Config = (vals::Ds, vals::Frxth);
impl_word!(word::U4, (vals::Ds::FOURBIT, vals::Frxth::QUARTER));
impl_word!(word::U5, (vals::Ds::FIVEBIT, vals::Frxth::QUARTER));
impl_word!(word::U6, (vals::Ds::SIXBIT, vals::Frxth::QUARTER));
impl_word!(word::U7, (vals::Ds::SEVENBIT, vals::Frxth::QUARTER));
impl_word!(u8, (vals::Ds::EIGHTBIT, vals::Frxth::QUARTER));
impl_word!(word::U9, (vals::Ds::NINEBIT, vals::Frxth::HALF));
impl_word!(word::U10, (vals::Ds::TENBIT, vals::Frxth::HALF));
impl_word!(word::U11, (vals::Ds::ELEVENBIT, vals::Frxth::HALF));
impl_word!(word::U12, (vals::Ds::TWELVEBIT, vals::Frxth::HALF));
impl_word!(word::U13, (vals::Ds::THIRTEENBIT, vals::Frxth::HALF));
impl_word!(word::U14, (vals::Ds::FOURTEENBIT, vals::Frxth::HALF));
impl_word!(word::U15, (vals::Ds::FIFTEENBIT, vals::Frxth::HALF));
impl_word!(u16, (vals::Ds::SIXTEENBIT, vals::Frxth::HALF));
impl_word!(word::U4, (vals::Ds::BITS4, vals::Frxth::QUARTER));
impl_word!(word::U5, (vals::Ds::BITS5, vals::Frxth::QUARTER));
impl_word!(word::U6, (vals::Ds::BITS6, vals::Frxth::QUARTER));
impl_word!(word::U7, (vals::Ds::BITS7, vals::Frxth::QUARTER));
impl_word!(u8, (vals::Ds::BITS8, vals::Frxth::QUARTER));
impl_word!(word::U9, (vals::Ds::BITS9, vals::Frxth::HALF));
impl_word!(word::U10, (vals::Ds::BITS10, vals::Frxth::HALF));
impl_word!(word::U11, (vals::Ds::BITS11, vals::Frxth::HALF));
impl_word!(word::U12, (vals::Ds::BITS12, vals::Frxth::HALF));
impl_word!(word::U13, (vals::Ds::BITS13, vals::Frxth::HALF));
impl_word!(word::U14, (vals::Ds::BITS14, vals::Frxth::HALF));
impl_word!(word::U15, (vals::Ds::BITS15, vals::Frxth::HALF));
impl_word!(u16, (vals::Ds::BITS16, vals::Frxth::HALF));
}
#[cfg(any(spi_v3, spi_v4, spi_v5))]

View file

@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut adc = Adc::new(p.ADC, Irqs, &mut Delay);
adc.set_sample_time(SampleTime::Cycles71_5);
adc.set_sample_time(SampleTime::CYCLES71_5);
let mut pin = p.PA1;
let mut vrefint = adc.enable_vref(&mut Delay);

View file

@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) -> ! {
let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay);
adc.set_sample_time(SampleTime::Cycles601_5);
adc.set_sample_time(SampleTime::CYCLES601_5);
info!("enable vrefint...");

View file

@ -42,7 +42,7 @@ async fn main(_spawner: Spawner) -> ! {
let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay);
let mut opamp = OpAmp::new(p.OPAMP2);
adc.set_sample_time(SampleTime::Cycles601_5);
adc.set_sample_time(SampleTime::CYCLES601_5);
info!("enable vrefint...");

View file

@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut adc = Adc::new(p.ADC2, &mut Delay);
adc.set_sample_time(SampleTime::Cycles32_5);
adc.set_sample_time(SampleTime::CYCLES32_5);
loop {
let measured = adc.read(&mut p.PA7);

View file

@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
let mut adc = Adc::new(p.ADC3, &mut Delay);
adc.set_sample_time(SampleTime::Cycles32_5);
adc.set_sample_time(SampleTime::CYCLES32_5);
let mut vrefint_channel = adc.enable_vrefint();

View file

@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) {
info!("Hello World!");
let mut adc = Adc::new(p.ADC, Irqs, &mut Delay);
adc.set_sample_time(SampleTime::Cycles79_5);
adc.set_sample_time(SampleTime::CYCLES79_5);
let mut pin = p.PA1;
let mut vrefint = adc.enable_vref(&mut Delay);

View file

@ -20,7 +20,7 @@ fn main() -> ! {
let mut adc = Adc::new(p.ADC1, &mut Delay);
//adc.enable_vref();
adc.set_resolution(Resolution::EightBit);
adc.set_resolution(Resolution::BITS8);
let mut channel = p.PC0;
loop {