diff --git a/CHANGELOG.md b/CHANGELOG.md index 832d370c..1b12b8d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + - Add `rcc::Instance` trait + ## [v0.23.0] - 2025-09-22 - Implement `embedded_hal::i2c::I2c` for `I2cMasterDma` [#838] diff --git a/src/adc.rs b/src/adc.rs index b8eef7df..241c98ae 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -138,7 +138,6 @@ use crate::{ signature::VDDA_CALIB, }; use core::fmt; -use core::ops::Deref; pub mod config; mod f4; @@ -153,10 +152,7 @@ pub struct Vbat; pub struct Temperature; /// Marker trait for all ADC peripherals -pub trait Instance: - crate::Sealed + Deref + rcc::Enable + rcc::Reset -{ -} +pub trait Instance: rcc::Instance + crate::Ptr {} #[doc(hidden)] pub trait Calibrate { diff --git a/src/can.rs b/src/can.rs index 7d099d22..d83e07e4 100644 --- a/src/can.rs +++ b/src/can.rs @@ -5,7 +5,7 @@ use crate::gpio; use crate::pac::{self, RCC}; use crate::rcc; -pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset + gpio::alt::CanCommon {} +pub trait Instance: rcc::Instance + gpio::alt::CanCommon {} macro_rules! can { ($CAN:ty: $Can:ident) => { diff --git a/src/dma/traits.rs b/src/dma/traits.rs index a6b461a7..1bf06495 100644 --- a/src/dma/traits.rs +++ b/src/dma/traits.rs @@ -3,7 +3,6 @@ use crate::{ pac::{self, DMA1, DMA2}, timer, }; -use core::ops::Deref; use enumflags2::BitFlags; pub(crate) mod sealed { @@ -302,10 +301,7 @@ use address; pub type DMARegisterBlock = pac::dma1::RegisterBlock; /// Trait that represents an instance of a DMA peripheral. -pub trait Instance: - crate::Sealed + crate::Ptr + Deref -{ -} +pub trait Instance: rcc::Instance + crate::Ptr {} impl Instance for DMA1 {} impl Instance for DMA2 {} diff --git a/src/fmc.rs b/src/fmc.rs index 93c9bdea..a99ba17e 100644 --- a/src/fmc.rs +++ b/src/fmc.rs @@ -7,7 +7,7 @@ use stm32_fmc::FmcPeripheral; use stm32_fmc::{AddressPinSet, PinsSdram, Sdram, SdramChip, SdramPinSet, SdramTargetBank}; -use crate::rcc::{BusClock, Clocks, Enable, Reset}; +use crate::rcc::{BusClock, Clocks, Enable, RccBus, Reset}; use fugit::HertzU32 as Hertz; use crate::gpio::alt::fmc as alt; @@ -60,7 +60,7 @@ impl FmcExt for FMC_PER { fn fmc(self, clocks: &Clocks) -> FMC { FMC { fmc: self, - hclk: FMC_PER::clock(clocks), + hclk: ::Bus::clock(clocks), } } } diff --git a/src/fmpi2c.rs b/src/fmpi2c.rs index 2fa9f65b..ccc0e542 100644 --- a/src/fmpi2c.rs +++ b/src/fmpi2c.rs @@ -1,10 +1,8 @@ -use core::ops::Deref; - use crate::gpio; use crate::pac::fmpi2c1 as i2c1; use crate::pac::{self, rcc}; -use crate::rcc::{BusClock, Enable, Rcc, Reset}; +use crate::rcc::{BusClock, Rcc}; use fugit::{HertzU32 as Hertz, RateExtU32}; use micromath::F32Ext; @@ -25,13 +23,7 @@ mod hal_1; type I2cSel = rcc::dckcfgr2::FMPI2C1SEL; pub trait Instance: - crate::Sealed - + crate::Ptr - + Deref - + Enable - + Reset - + BusClock - + gpio::alt::I2cCommon + crate::rcc::Instance + crate::Ptr + gpio::alt::I2cCommon { fn set_clock_source(rcc: &rcc::RegisterBlock, source: I2cSel); } @@ -291,7 +283,7 @@ impl I2c { let i2c_timingr = match clocks { ClockSource::Apb => { I2C::set_clock_source(rcc, I2cSel::Apb); - let pclk = I2C::clock(&rcc.clocks); + let pclk = I2C::Bus::clock(&rcc.clocks); match mode { Mode::Standard { frequency } => { calculate_timing(I2C_STANDARD_MODE_SPEC, pclk, frequency, an_filter, dnf) diff --git a/src/i2c.rs b/src/i2c.rs index 16bee1d6..68f6adbd 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -1,7 +1,4 @@ -use core::ops::Deref; - use crate::pac::{self, i2c1}; -use crate::rcc::{Enable, Reset}; use crate::gpio; @@ -75,12 +72,7 @@ pub struct I2c { } pub trait Instance: - crate::Sealed - + crate::Ptr - + Deref - + Enable - + Reset - + gpio::alt::I2cCommon + crate::rcc::Instance + crate::Ptr + gpio::alt::I2cCommon { } diff --git a/src/i2s.rs b/src/i2s.rs index 1a92a3c0..af531182 100644 --- a/src/i2s.rs +++ b/src/i2s.rs @@ -23,7 +23,11 @@ pub extern crate stm32_i2s_v12x; /// Trait for SPI peripheral with i2s capability. pub trait Instance: - I2sFreq + rcc::Enable + rcc::Reset + gpio::alt::I2sCommon + gpio::alt::I2sMaster + rcc::Instance + + crate::Ptr + + rcc::RccBus + + gpio::alt::I2sCommon + + gpio::alt::I2sMaster { } @@ -41,16 +45,6 @@ pub trait I2sFreq { } } -impl I2sFreq for T -where - T: rcc::RccBus, - T::Bus: I2sFreq, -{ - fn try_i2s_freq(clocks: &Clocks) -> Option { - T::Bus::try_i2s_freq(clocks) - } -} - impl I2sFreq for rcc::APB1 { fn try_i2s_freq(clocks: &Clocks) -> Option { #[cfg(not(feature = "rcc_i2s_apb"))] @@ -173,7 +167,7 @@ impl I2s { ), rcc: &mut Rcc, ) -> Self { - let input_clock = SPI::i2s_freq(&rcc.clocks); + let input_clock = SPI::Bus::i2s_freq(&rcc.clocks); // Enable clock, enable reset, clear, reset SPI::enable(rcc); SPI::reset(rcc); @@ -319,7 +313,7 @@ impl DualI2s { ), rcc: &mut Rcc, ) -> Self { - let input_clock = SPI::i2s_freq(&rcc.clocks); + let input_clock = SPI::Bus::i2s_freq(&rcc.clocks); // Enable clock, enable reset, clear, reset // Note: this also affect the I2SEXT peripheral SPI::enable(rcc); @@ -458,7 +452,6 @@ mod dma { use crate::dma::traits::{DMASet, PeriAddress}; use crate::pac::spi1::RegisterBlock; use core::marker::PhantomData; - use core::ops::Deref; use stm32_i2s_v12x::driver::{I2sCore, I2sDriver}; use stm32_i2s_v12x::transfer::{Ext, Main}; use stm32_i2s_v12x::DualI2sPeripheral; @@ -467,7 +460,6 @@ mod dma { unsafe impl PeriAddress for I2sDriver, MS, TR, STD> where I2s: stm32_i2s_v12x::I2sPeripheral, - SPI: Deref, { /// SPI_DR is only 16 bits. Multiple transfers are needed for a 24-bit or 32-bit sample, /// as explained in the reference manual. diff --git a/src/qei.rs b/src/qei.rs index bee63deb..29bc6a44 100644 --- a/src/qei.rs +++ b/src/qei.rs @@ -97,7 +97,7 @@ impl embedded_hal_02::Qei for Qei { } } -pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset + General + CPin<0> + CPin<1> { +pub trait Instance: rcc::Instance + General + CPin<0> + CPin<1> { fn setup_qei(&mut self); fn read_direction(&self) -> bool; diff --git a/src/rcc/f4/enable.rs b/src/rcc/f4/enable.rs index 80251083..482498c4 100644 --- a/src/rcc/f4/enable.rs +++ b/src/rcc/f4/enable.rs @@ -69,6 +69,7 @@ macro_rules! bus_reset { macro_rules! bus { ($($PER:ident => ($busX:ty, $bit:literal),)+) => { $( + impl crate::rcc::Instance for crate::pac::$PER {} impl RccBus for crate::pac::$PER { type Bus = $busX; } @@ -79,6 +80,8 @@ macro_rules! bus { } } +#[cfg(feature = "quadspi")] +impl crate::rcc::Instance for crate::pac::QUADSPI {} #[cfg(feature = "quadspi")] impl RccBus for crate::pac::QUADSPI { type Bus = AHB3; @@ -144,6 +147,8 @@ bus! { FMC => (AHB3, 0), } +#[cfg(feature = "fsmc")] +impl crate::rcc::Instance for crate::pac::FSMC {} // TODO: fix absent ahb3lpenr #[cfg(feature = "fsmc")] impl RccBus for crate::pac::FSMC { @@ -246,6 +251,8 @@ bus! { ADC1 => (APB2, 8), } +#[cfg(feature = "adc2")] +impl crate::rcc::Instance for crate::pac::ADC2 {} #[cfg(feature = "adc2")] impl RccBus for crate::pac::ADC2 { type Bus = APB2; @@ -257,6 +264,8 @@ bus_lpenable!(ADC2 => 9); #[cfg(feature = "adc2")] bus_reset!(ADC2 => 8); +#[cfg(feature = "adc3")] +impl crate::rcc::Instance for crate::pac::ADC3 {} #[cfg(feature = "adc3")] impl RccBus for crate::pac::ADC3 { type Bus = APB2; diff --git a/src/rcc/mod.rs b/src/rcc/mod.rs index 8a5690eb..11f44386 100644 --- a/src/rcc/mod.rs +++ b/src/rcc/mod.rs @@ -88,6 +88,12 @@ impl RccExt for RCC { } } +/// Common trait for most of peripherals +pub trait Instance: + crate::Ptr + crate::Steal + Enable + Reset + RccBus + Deref +{ +} + /// Bus associated to peripheral pub trait RccBus: crate::Sealed { /// Bus type; @@ -106,26 +112,6 @@ pub trait BusTimerClock { fn timer_clock(clocks: &Clocks) -> Hertz; } -impl BusClock for T -where - T: RccBus, - T::Bus: BusClock, -{ - fn clock(clocks: &Clocks) -> Hertz { - T::Bus::clock(clocks) - } -} - -impl BusTimerClock for T -where - T: RccBus, - T::Bus: BusTimerClock, -{ - fn timer_clock(clocks: &Clocks) -> Hertz { - T::Bus::timer_clock(clocks) - } -} - /// Enable/disable peripheral pub trait Enable: RccBus { /// Enables peripheral diff --git a/src/sai.rs b/src/sai.rs index 9b8f9066..3894acb5 100644 --- a/src/sai.rs +++ b/src/sai.rs @@ -220,16 +220,7 @@ pub struct Receive; /// SAI sub-block which has been configured as a transmitter. pub struct Transmit; -pub trait Instance: - crate::Sealed - + crate::Ptr - + crate::Steal - + Deref - + rcc::Enable - + rcc::Reset - + rcc::BusClock -{ -} +pub trait Instance: rcc::Instance + crate::Ptr {} impl SAICH { fn new(sai: SAI) -> Self { diff --git a/src/serial.rs b/src/serial.rs index 4d8f4517..408d1fc8 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -14,6 +14,7 @@ //! the embedded-hal read and write traits with `u16` as the word type. You can use these //! implementations for 9-bit words. +use crate::rcc::BusClock; use core::fmt; use core::marker::PhantomData; use enumflags2::BitFlags; @@ -126,16 +127,7 @@ pub use config::Config; pub use gpio::alt::SerialAsync as CommonPins; // Implemented by all USART/UART instances -pub trait Instance: - crate::Sealed - + crate::Ptr - + crate::Steal - + core::ops::Deref - + rcc::Enable - + rcc::Reset - + rcc::BusClock - + CommonPins -{ +pub trait Instance: rcc::Instance + crate::Ptr + CommonPins { #[doc(hidden)] #[inline(always)] fn peri_address() -> u32 { @@ -265,7 +257,7 @@ impl Serial { USART::enable(rcc); USART::reset(rcc); - let pclk_freq = USART::clock(&rcc.clocks).raw(); + let pclk_freq = USART::Bus::clock(&rcc.clocks).raw(); let baud = config.baudrate.0; if !USART::RB::IRDA && config.irda != IrdaMode::None { diff --git a/src/spi.rs b/src/spi.rs index 83d28f98..a451457e 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -1,3 +1,4 @@ +use crate::rcc::BusClock; use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; @@ -210,13 +211,7 @@ impl DerefMut for SpiSlave { // Implemented by all SPI instances pub trait Instance: - crate::Sealed - + crate::Ptr - + Deref - + rcc::Enable - + rcc::Reset - + rcc::BusClock - + gpio::alt::SpiCommon + rcc::Instance + crate::Ptr + gpio::alt::SpiCommon { } @@ -488,7 +483,7 @@ impl Spi { ); Self::_new(spi, pins) - .pre_init(mode.into(), freq, SPI::clock(&rcc.clocks)) + .pre_init(mode.into(), freq, SPI::Bus::clock(&rcc.clocks)) .init() } } @@ -512,7 +507,7 @@ impl Spi { let pins = (pins.0, SPI::NoMiso, pins.1); Self::_new(spi, pins) - .pre_init(mode.into(), freq, SPI::clock(&rcc.clocks)) + .pre_init(mode.into(), freq, SPI::Bus::clock(&rcc.clocks)) .init() } } diff --git a/src/timer.rs b/src/timer.rs index 752286e0..8d2ac0bf 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -4,6 +4,7 @@ //! (`AlternateOD`). #![allow(non_upper_case_globals)] +use crate::rcc::BusTimerClock; use core::convert::TryFrom; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::SYST; @@ -485,10 +486,7 @@ mod sealed { } pub(crate) use sealed::{Advanced, General, MasterTimer, WithCapture, WithChannel, WithPwm}; -pub trait Instance: - crate::Sealed + rcc::Enable + rcc::Reset + rcc::BusTimerClock + General -{ -} +pub trait Instance: rcc::Instance + rcc::RccBus + General {} #[allow(unused)] use sealed::{Split, SplitCapture}; @@ -901,13 +899,13 @@ impl Timer { TIM::reset(rcc); Self { - clk: TIM::timer_clock(&rcc.clocks), + clk: TIM::Bus::timer_clock(&rcc.clocks), tim, } } pub fn configure(&mut self, clocks: &Clocks) { - self.clk = TIM::timer_clock(clocks); + self.clk = TIM::Bus::timer_clock(clocks); } pub fn counter_hz(self) -> CounterHz { @@ -954,7 +952,7 @@ impl FTimer { /// Calculate prescaler depending on `Clocks` state pub fn configure(&mut self, clocks: &Clocks) { - let clk = TIM::timer_clock(clocks); + let clk = TIM::Bus::timer_clock(clocks); assert!(clk.raw() % FREQ == 0); let psc = clk.raw() / FREQ; self.tim.set_prescaler(u16::try_from(psc - 1).unwrap());