From ac19c4ef1f65ec598ec1eef2a87b112063777e83 Mon Sep 17 00:00:00 2001 From: Andrey Sverdlichenko Date: Sun, 19 Jan 2025 19:29:21 -0500 Subject: [PATCH] Cleanup device initialization --- src/adc.rs | 20 +++++++++++++------- src/i2c.rs | 4 ++-- src/lib.rs | 5 ----- src/timer.rs | 6 ++++-- src/timer/lptim.rs | 14 +++++++++++--- src/timer/timers.rs | 14 +++++++++++--- 6 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/adc.rs b/src/adc.rs index 7a11755..a10e162 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -4,18 +4,22 @@ use crate::pac::adc::chselr1; use crate::pac::ADC; use crate::rcc::{Rcc, ResetEnable}; +pub trait AdcExt { + fn constrain(self, rcc: &Rcc) -> Adc; +} + pub struct Adc { adc: ADC, vref_cache: Option, } -impl Adc { - pub fn new(adc: ADC, rcc: &Rcc) -> Self { +impl AdcExt for ADC { + fn constrain(self, rcc: &Rcc) -> Adc { ADC::enable(rcc); ADC::reset(rcc); // Enable ADC voltage regulator. - adc.cr().modify(|_, w| w.advregen().enabled()); + self.cr().modify(|_, w| w.advregen().enabled()); // RM0444 15.3.3 Calibration can only be initiated when the ADC voltage regulator is // enabled (ADVREGEN = 1 and tADCVREG_SETUP has elapsed) and the ADC is disabled @@ -24,18 +28,20 @@ impl Adc { // Round up for a safety margin. cortex_m::asm::delay(2000); - adc.cfgr1().modify(|_, w| w.chselrmod().sequence()); + self.cfgr1().modify(|_, w| w.chselrmod().sequence()); // Set clock to PCLK/2. // TODO: make this configurable. - adc.cfgr2().modify(|_, w| w.ckmode().pclk_div2()); + self.cfgr2().modify(|_, w| w.ckmode().pclk_div2()); - Self { - adc, + Adc { + adc: self, vref_cache: None, } } +} +impl Adc { pub fn calibrate(&mut self) { self.adc.isr().write(|w| w.eocal().clear()); self.adc.cr().modify(|_, w| w.adcal().start_calibration()); diff --git a/src/i2c.rs b/src/i2c.rs index c2cd7c7..ca150c7 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -68,7 +68,7 @@ impl Config { /// Extension trait to create I2C bus from a raw device pub trait I2cExt { - fn i2c(self, sda: SDA, scl: SCL, config: &Config, rcc: &Rcc) -> I2c + fn constrain(self, sda: SDA, scl: SCL, config: &Config, rcc: &Rcc) -> I2c where SDA: SdaPin, SCL: SclPin; @@ -132,7 +132,7 @@ macro_rules! i2c { )+ impl I2cExt<$I2C> for $I2C { - fn i2c(self, sda: SDA, scl: SCL, config: &Config, rcc: &Rcc) -> I2c<$I2C> + fn constrain(self, sda: SDA, scl: SCL, config: &Config, rcc: &Rcc) -> I2c<$I2C> where SDA: SdaPin<$I2C>, SCL: SclPin<$I2C>, diff --git a/src/lib.rs b/src/lib.rs index c16f03f..fff5f36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,6 @@ #![no_std] #![deny(unsafe_code)] -// TODO: cleanup HAL modules -// 1. use constrain() for creating peripherals via extension traits -// 2. except for GPIO, which is canonically split() -// 3. and except for timers, which can be turned into counter, pwm, etc - pub mod adc; pub mod exti; pub mod gpio; diff --git a/src/timer.rs b/src/timer.rs index 5bc1a93..b7b2552 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -2,5 +2,7 @@ mod lptim; mod timers; -pub use lptim::{Disabled, Enabled, LowPowerTimer, LptimCounter, LptimEvent, LptimPrescaler}; -pub use timers::{Pwm, PwmPin, Timer}; +pub use lptim::{ + Disabled, Enabled, LowPowerTimer, LptimCounter, LptimEvent, LptimExt, LptimPrescaler, +}; +pub use timers::{Pwm, PwmPin, Timer, TimerExt}; diff --git a/src/timer/lptim.rs b/src/timer/lptim.rs index 29a32ce..5efe37c 100644 --- a/src/timer/lptim.rs +++ b/src/timer/lptim.rs @@ -5,6 +5,12 @@ use crate::pac::{LPTIM1, LPTIM2}; use crate::rcc::lptim::{LptimClock, LptimClockExt}; use crate::rcc::{Rcc, ResetEnable}; +pub trait LptimExt { + fn constrain(self) -> LowPowerTimer + where + Self: Sized; +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum LptimPrescaler { Div1 = 0b000, @@ -50,11 +56,13 @@ pub struct LptimCounter { macro_rules! low_power_timer { ($TIM:ident) => { - impl LowPowerTimer<$TIM> { - pub fn new(timer: $TIM) -> Self { - Self { timer } + impl LptimExt for $TIM { + fn constrain(self) -> LowPowerTimer { + LowPowerTimer { timer: self } } + } + impl LowPowerTimer<$TIM> { pub fn upcounter( self, clock: LptimClock, diff --git a/src/timer/timers.rs b/src/timer/timers.rs index 4e84955..c2a1b6a 100644 --- a/src/timer/timers.rs +++ b/src/timer/timers.rs @@ -14,6 +14,12 @@ use crate::gpio::gpioe::{PE3, PE4, PE5, PE6}; #[cfg(feature = "stm32g0b1")] use crate::pac::TIM4; +pub trait TimerExt { + fn constrain(self) -> Timer + where + Self: Sized; +} + /// Wrapper for timer peripheral. #[derive(Debug)] pub struct Timer { @@ -34,11 +40,13 @@ pub struct Pwm { macro_rules! general_purpose_timer { ($TIM:ident, $REG:tt) => { - impl Timer<$TIM> { - pub fn new(timer: $TIM) -> Self { - Self { timer } + impl TimerExt for $TIM { + fn constrain(self) -> Timer { + Timer { timer: self } } + } + impl Timer<$TIM> { pub fn upcounter(self, prescaler: u16, limit: $REG, rcc: &Rcc) -> Counter<$TIM> { $TIM::enable(rcc); $TIM::reset(rcc);