stm32/f3: add high res for hrtim and misc.
This commit is contained in:
		@@ -60,7 +60,7 @@ impl<'d, T: Instance> Adc<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn freq() -> Hertz {
 | 
					    fn freq() -> Hertz {
 | 
				
			||||||
        unsafe { get_freqs() }.adc
 | 
					        unsafe { get_freqs() }.adc.unwrap()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
 | 
					    pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,8 @@ pub use traits::Instance;
 | 
				
			|||||||
#[allow(unused_imports)]
 | 
					#[allow(unused_imports)]
 | 
				
			||||||
use crate::gpio::sealed::{AFType, Pin};
 | 
					use crate::gpio::sealed::{AFType, Pin};
 | 
				
			||||||
use crate::gpio::AnyPin;
 | 
					use crate::gpio::AnyPin;
 | 
				
			||||||
 | 
					#[cfg(stm32f334)]
 | 
				
			||||||
 | 
					use crate::rcc::get_freqs;
 | 
				
			||||||
use crate::time::Hertz;
 | 
					use crate::time::Hertz;
 | 
				
			||||||
use crate::Peripheral;
 | 
					use crate::Peripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -158,17 +160,29 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
 | 
				
			|||||||
        T::enable();
 | 
					        T::enable();
 | 
				
			||||||
        <T as crate::rcc::sealed::RccPeripheral>::reset();
 | 
					        <T as crate::rcc::sealed::RccPeripheral>::reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //        // Enable and and stabilize the DLL
 | 
					        #[cfg(stm32f334)]
 | 
				
			||||||
        //        T::regs().dllcr().modify(|w| {
 | 
					        if unsafe { get_freqs() }.hrtim.is_some() {
 | 
				
			||||||
        //            // w.set_calen(true);
 | 
					            // Enable and and stabilize the DLL
 | 
				
			||||||
        //            // w.set_calrte(11);
 | 
					            T::regs().dllcr().modify(|w| {
 | 
				
			||||||
        //            w.set_cal(true);
 | 
					                w.set_cal(true);
 | 
				
			||||||
        //        });
 | 
					            });
 | 
				
			||||||
        //
 | 
					
 | 
				
			||||||
        //        debug!("wait for dll calibration");
 | 
					            trace!("hrtim: wait for dll calibration");
 | 
				
			||||||
        //        while !T::regs().isr().read().dllrdy() {}
 | 
					            while !T::regs().isr().read().dllrdy() {}
 | 
				
			||||||
        //
 | 
					
 | 
				
			||||||
        //        debug!("dll calibration complete");
 | 
					            trace!("hrtim: dll calibration complete");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Enable periodic calibration
 | 
				
			||||||
 | 
					            // Cal must be disabled before we can enable it
 | 
				
			||||||
 | 
					            T::regs().dllcr().modify(|w| {
 | 
				
			||||||
 | 
					                w.set_cal(false);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            T::regs().dllcr().modify(|w| {
 | 
				
			||||||
 | 
					                w.set_calen(true);
 | 
				
			||||||
 | 
					                w.set_calrte(11);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            _inner: tim,
 | 
					            _inner: tim,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,7 +104,13 @@ foreach_interrupt! {
 | 
				
			|||||||
                use crate::rcc::sealed::RccPeripheral;
 | 
					                use crate::rcc::sealed::RccPeripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let f = frequency.0;
 | 
					                let f = frequency.0;
 | 
				
			||||||
 | 
					                #[cfg(not(stm32f334))]
 | 
				
			||||||
                let timer_f = Self::frequency().0;
 | 
					                let timer_f = Self::frequency().0;
 | 
				
			||||||
 | 
					                #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					                let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(
 | 
				
			||||||
 | 
					                    Self::frequency()
 | 
				
			||||||
 | 
					                ).0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
 | 
					                let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
 | 
				
			||||||
                let psc = if Self::regs().isr().read().dllrdy() {
 | 
					                let psc = if Self::regs().isr().read().dllrdy() {
 | 
				
			||||||
                    Prescaler::compute_min_high_res(psc_min)
 | 
					                    Prescaler::compute_min_high_res(psc_min)
 | 
				
			||||||
@@ -125,7 +131,13 @@ foreach_interrupt! {
 | 
				
			|||||||
                use crate::rcc::sealed::RccPeripheral;
 | 
					                use crate::rcc::sealed::RccPeripheral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let f = frequency.0;
 | 
					                let f = frequency.0;
 | 
				
			||||||
 | 
					                #[cfg(not(stm32f334))]
 | 
				
			||||||
                let timer_f = Self::frequency().0;
 | 
					                let timer_f = Self::frequency().0;
 | 
				
			||||||
 | 
					                #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					                let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(
 | 
				
			||||||
 | 
					                    Self::frequency()
 | 
				
			||||||
 | 
					                ).0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
 | 
					                let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
 | 
				
			||||||
                let psc = if Self::regs().isr().read().dllrdy() {
 | 
					                let psc = if Self::regs().isr().read().dllrdy() {
 | 
				
			||||||
                    Prescaler::compute_min_high_res(psc_min)
 | 
					                    Prescaler::compute_min_high_res(psc_min)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,6 +184,6 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        apb1_tim: Hertz(pclk1 * timer_mul1),
 | 
					        apb1_tim: Hertz(pclk1 * timer_mul1),
 | 
				
			||||||
        apb2_tim: Hertz(pclk2 * timer_mul2),
 | 
					        apb2_tim: Hertz(pclk2 * timer_mul2),
 | 
				
			||||||
        ahb1: Hertz(hclk),
 | 
					        ahb1: Hertz(hclk),
 | 
				
			||||||
        adc: Hertz(adcclk),
 | 
					        adc: Some(Hertz(adcclk)),
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					#[cfg(rcc_f3)]
 | 
				
			||||||
 | 
					use crate::pac::adccommon::vals::Ckmode;
 | 
				
			||||||
use crate::pac::flash::vals::Latency;
 | 
					use crate::pac::flash::vals::Latency;
 | 
				
			||||||
use crate::pac::rcc::vals::{Adcpres, Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre};
 | 
					use crate::pac::rcc::vals::{Adcpres, Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre};
 | 
				
			||||||
use crate::pac::{FLASH, RCC};
 | 
					use crate::pac::{FLASH, RCC};
 | 
				
			||||||
@@ -10,44 +12,80 @@ pub const HSI_FREQ: Hertz = Hertz(8_000_000);
 | 
				
			|||||||
/// LSI speed
 | 
					/// LSI speed
 | 
				
			||||||
pub const LSI_FREQ: Hertz = Hertz(40_000);
 | 
					pub const LSI_FREQ: Hertz = Hertz(40_000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[repr(u16)]
 | 
					impl From<AdcClockSource> for Adcpres {
 | 
				
			||||||
#[derive(Clone, Copy)]
 | 
					    fn from(value: AdcClockSource) -> Self {
 | 
				
			||||||
pub enum ADCPrescaler {
 | 
					 | 
				
			||||||
    Div1 = 1,
 | 
					 | 
				
			||||||
    Div2 = 2,
 | 
					 | 
				
			||||||
    Div4 = 4,
 | 
					 | 
				
			||||||
    Div6 = 6,
 | 
					 | 
				
			||||||
    Div8 = 8,
 | 
					 | 
				
			||||||
    Div12 = 12,
 | 
					 | 
				
			||||||
    Div16 = 16,
 | 
					 | 
				
			||||||
    Div32 = 32,
 | 
					 | 
				
			||||||
    Div64 = 64,
 | 
					 | 
				
			||||||
    Div128 = 128,
 | 
					 | 
				
			||||||
    Div256 = 256,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl From<ADCPrescaler> for Adcpres {
 | 
					 | 
				
			||||||
    fn from(value: ADCPrescaler) -> Self {
 | 
					 | 
				
			||||||
        match value {
 | 
					        match value {
 | 
				
			||||||
            ADCPrescaler::Div1 => Adcpres::DIV1,
 | 
					            AdcClockSource::PllDiv1 => Adcpres::DIV1,
 | 
				
			||||||
            ADCPrescaler::Div2 => Adcpres::DIV2,
 | 
					            AdcClockSource::PllDiv2 => Adcpres::DIV2,
 | 
				
			||||||
            ADCPrescaler::Div4 => Adcpres::DIV4,
 | 
					            AdcClockSource::PllDiv4 => Adcpres::DIV4,
 | 
				
			||||||
            ADCPrescaler::Div6 => Adcpres::DIV6,
 | 
					            AdcClockSource::PllDiv6 => Adcpres::DIV6,
 | 
				
			||||||
            ADCPrescaler::Div8 => Adcpres::DIV8,
 | 
					            AdcClockSource::PllDiv8 => Adcpres::DIV8,
 | 
				
			||||||
            ADCPrescaler::Div12 => Adcpres::DIV12,
 | 
					            AdcClockSource::PllDiv12 => Adcpres::DIV12,
 | 
				
			||||||
            ADCPrescaler::Div16 => Adcpres::DIV16,
 | 
					            AdcClockSource::PllDiv16 => Adcpres::DIV16,
 | 
				
			||||||
            ADCPrescaler::Div32 => Adcpres::DIV32,
 | 
					            AdcClockSource::PllDiv32 => Adcpres::DIV32,
 | 
				
			||||||
            ADCPrescaler::Div64 => Adcpres::DIV64,
 | 
					            AdcClockSource::PllDiv64 => Adcpres::DIV64,
 | 
				
			||||||
            ADCPrescaler::Div128 => Adcpres::DIV128,
 | 
					            AdcClockSource::PllDiv128 => Adcpres::DIV128,
 | 
				
			||||||
            ADCPrescaler::Div256 => Adcpres::DIV256,
 | 
					            AdcClockSource::PllDiv256 => Adcpres::DIV256,
 | 
				
			||||||
 | 
					            _ => unreachable!(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(rcc_f3)]
 | 
				
			||||||
 | 
					impl From<AdcClockSource> for Ckmode {
 | 
				
			||||||
 | 
					    fn from(value: AdcClockSource) -> Self {
 | 
				
			||||||
 | 
					        match value {
 | 
				
			||||||
 | 
					            AdcClockSource::BusDiv1 => Ckmode::SYNCDIV1,
 | 
				
			||||||
 | 
					            AdcClockSource::BusDiv2 => Ckmode::SYNCDIV2,
 | 
				
			||||||
 | 
					            AdcClockSource::BusDiv4 => Ckmode::SYNCDIV4,
 | 
				
			||||||
 | 
					            _ => unreachable!(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Copy)]
 | 
					#[derive(Clone, Copy)]
 | 
				
			||||||
pub enum ADCClock {
 | 
					pub enum AdcClockSource {
 | 
				
			||||||
    AHB(ADCPrescaler),
 | 
					    PllDiv1 = 1,
 | 
				
			||||||
    PLL(ADCPrescaler),
 | 
					    PllDiv2 = 2,
 | 
				
			||||||
 | 
					    PllDiv4 = 4,
 | 
				
			||||||
 | 
					    PllDiv6 = 6,
 | 
				
			||||||
 | 
					    PllDiv8 = 8,
 | 
				
			||||||
 | 
					    PllDiv12 = 12,
 | 
				
			||||||
 | 
					    PllDiv16 = 16,
 | 
				
			||||||
 | 
					    PllDiv32 = 32,
 | 
				
			||||||
 | 
					    PllDiv64 = 64,
 | 
				
			||||||
 | 
					    PllDiv128 = 128,
 | 
				
			||||||
 | 
					    PllDiv256 = 256,
 | 
				
			||||||
 | 
					    BusDiv1,
 | 
				
			||||||
 | 
					    BusDiv2,
 | 
				
			||||||
 | 
					    BusDiv4,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl AdcClockSource {
 | 
				
			||||||
 | 
					    pub fn is_bus(&self) -> bool {
 | 
				
			||||||
 | 
					        match self {
 | 
				
			||||||
 | 
					            Self::BusDiv1 => true,
 | 
				
			||||||
 | 
					            Self::BusDiv2 => true,
 | 
				
			||||||
 | 
					            Self::BusDiv4 => true,
 | 
				
			||||||
 | 
					            _ => false,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn bus_div(&self) -> u32 {
 | 
				
			||||||
 | 
					        match self {
 | 
				
			||||||
 | 
					            Self::BusDiv1 => 1,
 | 
				
			||||||
 | 
					            Self::BusDiv2 => 2,
 | 
				
			||||||
 | 
					            Self::BusDiv4 => 4,
 | 
				
			||||||
 | 
					            _ => unreachable!(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Default)]
 | 
				
			||||||
 | 
					pub enum HrtimClockSource {
 | 
				
			||||||
 | 
					    #[default]
 | 
				
			||||||
 | 
					    BusClk,
 | 
				
			||||||
 | 
					    PllClk,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Clocks configutation
 | 
					/// Clocks configutation
 | 
				
			||||||
@@ -79,11 +117,13 @@ pub struct Config {
 | 
				
			|||||||
    #[cfg(rcc_f3)]
 | 
					    #[cfg(rcc_f3)]
 | 
				
			||||||
    /// ADC clock setup
 | 
					    /// ADC clock setup
 | 
				
			||||||
    /// - For AHB, a psc of 4 or less must be used
 | 
					    /// - For AHB, a psc of 4 or less must be used
 | 
				
			||||||
    pub adc: Option<ADCClock>,
 | 
					    pub adc: Option<AdcClockSource>,
 | 
				
			||||||
    #[cfg(rcc_f3)]
 | 
					    #[cfg(rcc_f3)]
 | 
				
			||||||
    /// ADC clock setup
 | 
					    /// ADC clock setup
 | 
				
			||||||
    /// - For AHB, a psc of 4 or less must be used
 | 
					    /// - For AHB, a psc of 4 or less must be used
 | 
				
			||||||
    pub adc34: Option<ADCClock>,
 | 
					    pub adc34: Option<AdcClockSource>,
 | 
				
			||||||
 | 
					    #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					    pub hrtim: HrtimClockSource,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Information required to setup the PLL clock
 | 
					// Information required to setup the PLL clock
 | 
				
			||||||
@@ -197,44 +237,6 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(rcc_f3)]
 | 
					 | 
				
			||||||
    let adc = config.adc.map(|adc| match adc {
 | 
					 | 
				
			||||||
        ADCClock::PLL(psc) => RCC.cfgr2().modify(|w| {
 | 
					 | 
				
			||||||
            // Make sure that we're using the PLL
 | 
					 | 
				
			||||||
            pll_config.unwrap();
 | 
					 | 
				
			||||||
            w.set_adc12pres(psc.into());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Hertz(sysclk / psc as u32)
 | 
					 | 
				
			||||||
        }),
 | 
					 | 
				
			||||||
        ADCClock::AHB(psc) => {
 | 
					 | 
				
			||||||
            assert!(psc as u16 <= 4);
 | 
					 | 
				
			||||||
            assert!(!(psc as u16 == 1 && hpre_bits != Hpre::DIV1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // To select this scheme, bits CKMODE[1:0] of the ADCx_CCR register must be
 | 
					 | 
				
			||||||
            // different from “00”.
 | 
					 | 
				
			||||||
            todo!();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(rcc_f3)]
 | 
					 | 
				
			||||||
    let adc34 = config.adc34.map(|adc| match adc {
 | 
					 | 
				
			||||||
        ADCClock::PLL(psc) => RCC.cfgr2().modify(|w| {
 | 
					 | 
				
			||||||
            // Make sure that we're using the PLL
 | 
					 | 
				
			||||||
            pll_config.unwrap();
 | 
					 | 
				
			||||||
            w.set_adc34pres(psc.into());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Hertz(sysclk / psc as u32)
 | 
					 | 
				
			||||||
        }),
 | 
					 | 
				
			||||||
        ADCClock::AHB(psc) => {
 | 
					 | 
				
			||||||
            assert!(psc as u16 <= 4);
 | 
					 | 
				
			||||||
            assert!(!(psc as u16 == 1 && hpre_bits != Hpre::DIV1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // To select this scheme, bits CKMODE[1:0] of the ADCx_CCR register must be
 | 
					 | 
				
			||||||
            // different from “00”.
 | 
					 | 
				
			||||||
            todo!();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Set prescalers
 | 
					    // Set prescalers
 | 
				
			||||||
    // CFGR has been written before (PLL, PLL48) don't overwrite these settings
 | 
					    // CFGR has been written before (PLL, PLL48) don't overwrite these settings
 | 
				
			||||||
    RCC.cfgr().modify(|w| {
 | 
					    RCC.cfgr().modify(|w| {
 | 
				
			||||||
@@ -257,6 +259,61 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(rcc_f3)]
 | 
				
			||||||
 | 
					    let adc = config.adc.map(|adc| {
 | 
				
			||||||
 | 
					        if !adc.is_bus() {
 | 
				
			||||||
 | 
					            RCC.cfgr2().modify(|w| {
 | 
				
			||||||
 | 
					                // Make sure that we're using the PLL
 | 
				
			||||||
 | 
					                pll_config.unwrap();
 | 
				
			||||||
 | 
					                w.set_adc12pres(adc.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Hertz(sysclk / adc as u32)
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            crate::pac::ADC_COMMON.ccr().modify(|w| {
 | 
				
			||||||
 | 
					                assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                w.set_ckmode(adc.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Hertz(sysclk / adc.bus_div() as u32)
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(rcc_f3)]
 | 
				
			||||||
 | 
					    let adc34 = config.adc.map(|adc| {
 | 
				
			||||||
 | 
					        if !adc.is_bus() {
 | 
				
			||||||
 | 
					            RCC.cfgr2().modify(|w| {
 | 
				
			||||||
 | 
					                // Make sure that we're using the PLL
 | 
				
			||||||
 | 
					                pll_config.unwrap();
 | 
				
			||||||
 | 
					                w.set_adc12pres(adc.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Hertz(sysclk / adc as u32)
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // TODO: need to use only if adc32_common is present
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            todo!()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					    let hrtim = match config.hrtim {
 | 
				
			||||||
 | 
					        // Must be configured after the bus is ready, otherwise it won't work
 | 
				
			||||||
 | 
					        HrtimClockSource::BusClk => None,
 | 
				
			||||||
 | 
					        HrtimClockSource::PllClk => {
 | 
				
			||||||
 | 
					            use crate::pac::rcc::vals::Timsw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Make sure that we're using the PLL
 | 
				
			||||||
 | 
					            pll_config.unwrap();
 | 
				
			||||||
 | 
					            assert!((pclk2 == sysclk) || (pclk2 * 2 == sysclk));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RCC.cfgr3().modify(|w| w.set_hrtim1sw(Timsw::PLL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Some(Hertz(sysclk * 2))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_freqs(Clocks {
 | 
					    set_freqs(Clocks {
 | 
				
			||||||
        sys: Hertz(sysclk),
 | 
					        sys: Hertz(sysclk),
 | 
				
			||||||
        apb1: Hertz(pclk1),
 | 
					        apb1: Hertz(pclk1),
 | 
				
			||||||
@@ -268,6 +325,8 @@ pub(crate) unsafe fn init(config: Config) {
 | 
				
			|||||||
        adc: adc,
 | 
					        adc: adc,
 | 
				
			||||||
        #[cfg(rcc_f3)]
 | 
					        #[cfg(rcc_f3)]
 | 
				
			||||||
        adc34: adc34,
 | 
					        adc34: adc34,
 | 
				
			||||||
 | 
					        #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					        hrtim: hrtim,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,15 +71,15 @@ pub struct Clocks {
 | 
				
			|||||||
    #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
 | 
					    #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
 | 
				
			||||||
    pub pllsai: Option<Hertz>,
 | 
					    pub pllsai: Option<Hertz>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(stm32f1)]
 | 
					    #[cfg(any(rcc_f1, rcc_f100, rcc_f1cl, rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_f3, rcc_g4))]
 | 
				
			||||||
    pub adc: Hertz,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7ab, rcc_f3, rcc_g4))]
 | 
					 | 
				
			||||||
    pub adc: Option<Hertz>,
 | 
					    pub adc: Option<Hertz>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(any(rcc_f3, rcc_g4))]
 | 
					    #[cfg(any(rcc_f3, rcc_g4))]
 | 
				
			||||||
    pub adc34: Option<Hertz>,
 | 
					    pub adc34: Option<Hertz>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(stm32f334)]
 | 
				
			||||||
 | 
					    pub hrtim: Option<Hertz>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
 | 
					    #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
 | 
				
			||||||
    /// Set only if the lsi or lse is configured, indicates stop is supported
 | 
					    /// Set only if the lsi or lse is configured, indicates stop is supported
 | 
				
			||||||
    pub rtc: Option<Hertz>,
 | 
					    pub rtc: Option<Hertz>,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use defmt::info;
 | 
					use defmt::info;
 | 
				
			||||||
use embassy_executor::Spawner;
 | 
					use embassy_executor::Spawner;
 | 
				
			||||||
use embassy_stm32::adc::{Adc, VREF_INT};
 | 
					use embassy_stm32::adc::{Adc, SampleTime, VREF_INT};
 | 
				
			||||||
use embassy_stm32::rcc::{ADCClock, ADCPrescaler};
 | 
					use embassy_stm32::rcc::AdcClockSource;
 | 
				
			||||||
use embassy_stm32::time::Hertz;
 | 
					use embassy_stm32::time::mhz;
 | 
				
			||||||
use embassy_stm32::Config;
 | 
					use embassy_stm32::Config;
 | 
				
			||||||
use embassy_time::{Delay, Duration, Timer};
 | 
					use embassy_time::{Delay, Duration, Timer};
 | 
				
			||||||
use {defmt_rtt as _, panic_probe as _};
 | 
					use {defmt_rtt as _, panic_probe as _};
 | 
				
			||||||
@@ -14,9 +14,11 @@ use {defmt_rtt as _, panic_probe as _};
 | 
				
			|||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) -> ! {
 | 
					async fn main(_spawner: Spawner) -> ! {
 | 
				
			||||||
    let mut config = Config::default();
 | 
					    let mut config = Config::default();
 | 
				
			||||||
    config.rcc.hse = Some(Hertz(8_000_000));
 | 
					    config.rcc.sysclk = Some(mhz(64));
 | 
				
			||||||
    config.rcc.sysclk = Some(Hertz(16_000_000));
 | 
					    config.rcc.hclk = Some(mhz(64));
 | 
				
			||||||
    config.rcc.adc = Some(ADCClock::PLL(ADCPrescaler::Div1));
 | 
					    config.rcc.pclk1 = Some(mhz(32));
 | 
				
			||||||
 | 
					    config.rcc.pclk2 = Some(mhz(64));
 | 
				
			||||||
 | 
					    config.rcc.adc = Some(AdcClockSource::PllDiv1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut p = embassy_stm32::init(config);
 | 
					    let mut p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,6 +26,8 @@ async fn main(_spawner: Spawner) -> ! {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let mut adc = Adc::new(p.ADC1, &mut Delay);
 | 
					    let mut adc = Adc::new(p.ADC1, &mut Delay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    adc.set_sample_time(SampleTime::Cycles601_5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info!("enable vrefint...");
 | 
					    info!("enable vrefint...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut vrefint = adc.enable_vref(&mut Delay);
 | 
					    let mut vrefint = adc.enable_vref(&mut Delay);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
use defmt::*;
 | 
					use defmt::*;
 | 
				
			||||||
use embassy_executor::Spawner;
 | 
					use embassy_executor::Spawner;
 | 
				
			||||||
use embassy_stm32::hrtim::*;
 | 
					use embassy_stm32::hrtim::*;
 | 
				
			||||||
 | 
					use embassy_stm32::rcc::HrtimClockSource;
 | 
				
			||||||
use embassy_stm32::time::{khz, mhz};
 | 
					use embassy_stm32::time::{khz, mhz};
 | 
				
			||||||
use embassy_stm32::Config;
 | 
					use embassy_stm32::Config;
 | 
				
			||||||
use embassy_time::{Duration, Timer};
 | 
					use embassy_time::{Duration, Timer};
 | 
				
			||||||
@@ -17,6 +18,7 @@ async fn main(_spawner: Spawner) {
 | 
				
			|||||||
    config.rcc.hclk = Some(mhz(64));
 | 
					    config.rcc.hclk = Some(mhz(64));
 | 
				
			||||||
    config.rcc.pclk1 = Some(mhz(32));
 | 
					    config.rcc.pclk1 = Some(mhz(32));
 | 
				
			||||||
    config.rcc.pclk2 = Some(mhz(64));
 | 
					    config.rcc.pclk2 = Some(mhz(64));
 | 
				
			||||||
 | 
					    config.rcc.hrtim = HrtimClockSource::PllClk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user