From c1ca8c46c22ec27cdafa6a33d234687626979144 Mon Sep 17 00:00:00 2001 From: Richard Meadows <962920+richardeoin@users.noreply.github.com> Date: Sun, 24 May 2020 17:17:52 +0200 Subject: [PATCH] Beginning of DFSDM support --- examples/dfsdm.rs | 39 ++++++++++ src/dfsdm.rs | 180 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + src/prelude.rs | 1 + 4 files changed, 222 insertions(+) create mode 100644 examples/dfsdm.rs create mode 100644 src/dfsdm.rs diff --git a/examples/dfsdm.rs b/examples/dfsdm.rs new file mode 100644 index 00000000..2b461669 --- /dev/null +++ b/examples/dfsdm.rs @@ -0,0 +1,39 @@ +// #![deny(warnings)] +#![deny(unsafe_code)] +#![no_main] +#![no_std] + +extern crate panic_itm; + +use cortex_m; +use cortex_m_rt::entry; +use stm32h7xx_hal::{pac, prelude::*}; + +#[entry] +fn main() -> ! { + let dp = pac::Peripherals::take().unwrap(); + + // Constrain and Freeze power + let pwr = dp.PWR.constrain(); + let vos = pwr.freeze(); + + // Constrain and Freeze clock + let rcc = dp.RCC.constrain(); + let ccdr = rcc.sys_ck(100.mhz()).freeze(vos, &dp.SYSCFG); + + let mut dfsdm = dp.DFSDM.dfsdm(ccdr.peripheral.DFSDM1); + + let input_data = [4i16; 640]; + for d in input_data.iter() { + dfsdm.write(*d); + } + + loop { + match dfsdm.read() { + Ok(value) => { + assert!(value > 0); + } + Err(_) => {} + } + } +} diff --git a/src/dfsdm.rs b/src/dfsdm.rs new file mode 100644 index 00000000..6c376995 --- /dev/null +++ b/src/dfsdm.rs @@ -0,0 +1,180 @@ +//! # Digital filter for sigma delta modulators (DFSDM) +//! +//! + +use crate::rcc::{rec, CoreClocks, ResetEnable}; +use crate::stm32::DFSDM; + +use crate::gpio::gpiob::{ + PB1, PB10, PB11, PB12, PB13, PB14, PB15, PB2, PB6, PB7, PB8, PB9, +}; +use crate::gpio::gpioc::{PC0, PC1, PC10, PC11, PC2, PC3, PC4, PC5, PC6, PC7}; +use crate::gpio::gpiod::{PD0, PD1, PD6, PD7, PD8, PD9}; +use crate::gpio::gpioe::{PE10, PE11, PE12, PE13, PE4, PE5, PE7, PE8}; +use crate::gpio::gpiof::{PF13, PF14}; + +macro_rules! pins { + (DFSDM1: $($pin_ty:ident: [$($P:ty),*])+) => {}; +} + +pins! { + DFSDM1: + DATIN0: [ + PC1> + ] + DATIN1: [ + PB1>, + PB12>, + PC3>, + PD6> + ] + DATIN2: [ + PB14>, + PC5>, + PE7> + ] + DATIN3: [ + PC7>, + PD9>, + PE4> + ] + DATIN4: [ + PC0>, + PD7>, + PE10> + ] + DATIN5: [ + PB6>, + PC11>, + PE12> + ] + DATIN6: [ + PD1>, + PF13> + ] + DATIN7: [ + PB9>, + PB10> + ] + CKIN0: [ + PC0> + ] + CKIN1: [ + PB2>, + PB13>, + PC2>, + PD7> + ] + CKIN2: [ + PB15>, + PC4>, + PE8> + ] + CKIN3: [ + PC6>, + PD8>, + PE5> + ] + CKIN4: [ + PC1>, + PD6>, + PE11> + ] + CKIN5: [ + PB7>, + PC10>, + PE13> + ] + CKIN6: [ + PD0>, + PF14> + ] + CKIN7: [ + PB8>, + PB11> + ] +} + +pub struct Dfsdm { + dfsdm: DFSDM, +} + +/// Extension trait for DFSDM peripheral +pub trait DfsdmExt: Sized { + type Rec: ResetEnable; + + fn dfsdm(self, prec: Self::Rec) -> Dfsdm; +} +impl DfsdmExt for DFSDM { + type Rec = rec::Dfsdm1; + + fn dfsdm(self, prec: rec::Dfsdm1) -> Dfsdm { + Dfsdm::dfsdm(self, prec) + } +} + +impl Dfsdm { + pub fn dfsdm(dfsdm: DFSDM, prec: rec::Dfsdm1) -> Self { + // Enable and reset peripheral + prec.enable().reset(); + + unsafe { + // Set Channel Control Register 2 + dfsdm.dfsdm_chcfg0r2.modify(|_, w| w.offset().bits(2)); + + // Set Channel Control Register 1 + dfsdm.dfsdm_chcfg0r1.modify(|_, w| { + w.datmpx() + .bits(2) // Data input from register writes + .chen() + .set_bit() + }); + + // Set Filter Control Register + dfsdm.dfsdm0_fcr.modify(|_, w| { + w.ford().bits(3).fosr().bits(64 - 1).iosr().bits(0) + }); + + // Set Filter Control Register 1 + dfsdm.dfsdm0_cr1.modify(|_, w| { + w.rch() + .bits(0) // Channel 0 + .dfen() + .set_bit() + }); + } + + // Global enable + dfsdm.dfsdm_chcfg0r1.modify(|_, w| w.dfsdmen().set_bit()); + + Self { dfsdm } + } + + /// Listen for end of conversion interrupt + pub fn listen(&mut self) { + // Set REOC IE + self.dfsdm.dfsdm0_cr2.modify(|_, w| w.reocie().set_bit()); + } + + /// Write input data + pub fn write(&mut self, data: i16) { + unsafe { + self.dfsdm + .dfsdm_chdatin0r + .write(|w| w.indat0().bits(data as u16)); + + self.dfsdm.dfsdm0_cr1.modify(|_, w| w.rswstart().set_bit()); + } + } + + /// Return data + pub fn read(&mut self) -> Result { + let isr = self.dfsdm.dfsdm0_isr.read(); + + if isr.reocf().bit_is_set() { + Ok(self.dfsdm.dfsdm0_rdatar.read().rdata().bits() as i16) + } else { + Err(()) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index deacf8e8..38b68152 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,8 @@ pub mod adc; #[cfg(feature = "device-selected")] pub mod delay; #[cfg(feature = "device-selected")] +pub mod dfsdm; +#[cfg(feature = "device-selected")] pub mod exti; #[cfg(feature = "device-selected")] pub mod flash; diff --git a/src/prelude.rs b/src/prelude.rs index 2adcefed..bc095316 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -3,6 +3,7 @@ pub use embedded_hal::prelude::*; pub use crate::adc::AdcExt as _stm32h7xx_hal_adc_AdcExt; pub use crate::delay::DelayExt as _stm32h7xx_hal_delay_DelayExt; +pub use crate::dfsdm::DfsdmExt as _stm32h7xx_hal_dfsdm_DfsdmExt; pub use crate::exti::ExtiExt as _stm32h7xx_hal_delay_ExtiExt; pub use crate::flash::FlashExt as _stm32h7xx_hal_flash_FlashExt; pub use crate::gpio::GpioExt as _stm32h7xx_hal_gpio_GpioExt;