From 31fc337e2f988720b7909575501e95af8707c1be Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Sun, 19 Nov 2023 04:30:28 +0000 Subject: [PATCH] STM32 DAC: Swap to new TSEL enum entirely in-HAL --- embassy-stm32/src/dac/mod.rs | 140 +++----------- embassy-stm32/src/dac/tsel.rs | 282 ++++++++++++++++++++++++++++ examples/stm32h7/src/bin/dac_dma.rs | 4 +- examples/stm32l4/src/bin/dac_dma.rs | 4 +- 4 files changed, 310 insertions(+), 120 deletions(-) create mode 100644 embassy-stm32/src/dac/tsel.rs diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index b87d6e49..6d51c1e9 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -10,6 +10,9 @@ use crate::pac::dac; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; +mod tsel; +pub use tsel::TriggerSel; + #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -51,7 +54,6 @@ impl Mode { } } - #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Custom Errors @@ -77,100 +79,6 @@ impl Channel { } } -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Trigger sources for CH1 -pub enum Ch1Trigger { - #[cfg(dac_v3)] - Tim1, - Tim2, - #[cfg(not(dac_v3))] - Tim3, - #[cfg(dac_v3)] - Tim4, - #[cfg(dac_v3)] - Tim5, - Tim6, - Tim7, - #[cfg(dac_v3)] - Tim8, - Tim15, - #[cfg(dac_v3)] - Hrtim1Dactrg1, - #[cfg(dac_v3)] - Hrtim1Dactrg2, - #[cfg(dac_v3)] - Lptim1, - #[cfg(dac_v3)] - Lptim2, - #[cfg(dac_v3)] - Lptim3, - Exti9, - Software, -} - -impl Ch1Trigger { - fn tsel(&self) -> dac::vals::Tsel1 { - match self { - #[cfg(dac_v3)] - Ch1Trigger::Tim1 => dac::vals::Tsel1::TIM1_TRGO, - Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO, - #[cfg(not(dac_v3))] - Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim4 => dac::vals::Tsel1::TIM4_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim5 => dac::vals::Tsel1::TIM5_TRGO, - Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO, - Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Tim8 => dac::vals::Tsel1::TIM8_TRGO, - Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO, - #[cfg(dac_v3)] - Ch1Trigger::Hrtim1Dactrg1 => dac::vals::Tsel1::HRTIM1_DACTRG1, - #[cfg(dac_v3)] - Ch1Trigger::Hrtim1Dactrg2 => dac::vals::Tsel1::HRTIM1_DACTRG2, - #[cfg(dac_v3)] - Ch1Trigger::Lptim1 => dac::vals::Tsel1::LPTIM1_OUT, - #[cfg(dac_v3)] - Ch1Trigger::Lptim2 => dac::vals::Tsel1::LPTIM2_OUT, - #[cfg(dac_v3)] - Ch1Trigger::Lptim3 => dac::vals::Tsel1::LPTIM3_OUT, - Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9, - Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE, - } - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -/// Trigger sources for CH2 -pub enum Ch2Trigger { - Tim6, - Tim8, - Tim7, - Tim5, - Tim2, - Tim4, - Exti9, - Software, -} - -impl Ch2Trigger { - fn tsel(&self) -> dac::vals::Tsel2 { - match self { - Ch2Trigger::Tim6 => dac::vals::Tsel2::TIM6_TRGO, - Ch2Trigger::Tim8 => dac::vals::Tsel2::TIM8_TRGO, - Ch2Trigger::Tim7 => dac::vals::Tsel2::TIM7_TRGO, - Ch2Trigger::Tim5 => dac::vals::Tsel2::TIM5_TRGO, - Ch2Trigger::Tim2 => dac::vals::Tsel2::TIM2_TRGO, - Ch2Trigger::Tim4 => dac::vals::Tsel2::TIM4_TRGO, - Ch2Trigger::Exti9 => dac::vals::Tsel2::EXTI9, - Ch2Trigger::Software => dac::vals::Tsel2::SOFTWARE, - } - } -} - #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] /// Single 8 or 12 bit value that can be output by the DAC @@ -315,10 +223,10 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> { /// Select a new trigger for this channel /// /// **Important**: This disables the channel! - pub fn select_trigger(&mut self, trigger: Ch1Trigger) -> Result<(), Error> { + pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { unwrap!(self.disable_channel()); T::regs().cr().modify(|reg| { - reg.set_tsel1(trigger.tsel()); + reg.set_tsel(0, trigger.tsel()); }); Ok(()) } @@ -426,10 +334,10 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> { } /// Select a new trigger for this channel - pub fn select_trigger(&mut self, trigger: Ch2Trigger) -> Result<(), Error> { + pub fn select_trigger(&mut self, trigger: TriggerSel) -> Result<(), Error> { unwrap!(self.disable_channel()); T::regs().cr().modify(|reg| { - reg.set_tsel2(trigger.tsel()); + reg.set_tsel(1, trigger.tsel()); }); Ok(()) } @@ -603,26 +511,26 @@ pub trait DacPin: crate::gpio::Pin + 'static {} foreach_peripheral!( (dac, $inst:ident) => { - // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented - #[cfg(any(rcc_h7, rcc_h7rm0433))] - impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { - fn frequency() -> crate::time::Hertz { - critical_section::with(|_| unsafe { crate::rcc::get_freqs().pclk1 }) - } + // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented + #[cfg(any(rcc_h7, rcc_h7rm0433))] + impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { + fn frequency() -> crate::time::Hertz { + critical_section::with(|_| unsafe { crate::rcc::get_freqs().pclk1 }) + } - fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); - crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); - } + fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); + crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); + } - fn disable_with_cs(_cs: critical_section::CriticalSection) { - crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) - } - } + fn disable_with_cs(_cs: critical_section::CriticalSection) { + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)) + } + } - #[cfg(any(rcc_h7, rcc_h7rm0433))] - impl crate::rcc::RccPeripheral for peripherals::$inst {} + #[cfg(any(rcc_h7, rcc_h7rm0433))] + impl crate::rcc::RccPeripheral for peripherals::$inst {} impl crate::dac::sealed::Instance for peripherals::$inst { fn regs() -> &'static crate::pac::dac::Dac { diff --git a/embassy-stm32/src/dac/tsel.rs b/embassy-stm32/src/dac/tsel.rs new file mode 100644 index 00000000..f38dd8fd --- /dev/null +++ b/embassy-stm32/src/dac/tsel.rs @@ -0,0 +1,282 @@ +/// Trigger selection for STM32F0. +#[cfg(stm32f0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F1. +#[cfg(stm32f1)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + #[cfg(any(stm32f100, stm32f105, stm32f107))] + Tim3 = 1, + #[cfg(any(stm32f101, stm32f103))] + Tim8 = 1, + Tim7 = 2, + #[cfg(any(stm32f101, stm32f103, stm32f105, stm32f107))] + Tim5 = 3, + #[cfg(all(stm32f100, any(flashsize_4, flashsize_6, flashsize_8, flashsize_b)))] + Tim15 = 3, + #[cfg(all(stm32f100, any(flashsize_c, flashsize_d, flashsize_e)))] + /// Can be remapped to TIM15 with MISC_REMAP in AFIO_MAPR2. + Tim5Or15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F2/F4/F7/L4, except F410 or L4+. +#[cfg(all(any(stm32f2, stm32f4, stm32f7, stm32l4_nonplus), not(stm32f410)))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim8 = 1, + #[cfg(not(any(stm32l45x, stm32l46x)))] + Tim7 = 2, + Tim5 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F410. +#[cfg(stm32f410)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim5 = 3, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F301/2 and 318. +#[cfg(any(stm32f301, stm32f302, stm32f318))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + #[cfg(stm32f302)] + /// Requires DAC_TRIG_RMP set in SYSCFG_CFGR1. + Tim3 = 1, + Tim15 = 3, + Tim2 = 4, + #[cfg(all(stm32f302, any(flashsize_6, flashsize_8)))] + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F303/3x8 (excluding 318 which is like 301, and 378 which is 37x). +#[cfg(any(stm32f303, stm32f328, stm32f358, stm32f398))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + /// * DAC1: defaults to TIM8 but can be remapped to TIM3 with DAC_TRIG_RMP in SYSCFG_CFGR1 + /// * DAC2: always TIM3 + Tim8Or3 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F37x. +#[cfg(any(stm32f373, stm32f378))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim7 = 2, + /// TIM5 on DAC1, TIM18 on DAC2 + Dac1Tim5Dac2Tim18 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32F334. +#[cfg(stm32f334)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + /// Requires DAC_TRIG_RMP set in SYSCFG_CFGR1. + Tim3 = 1, + Tim7 = 2, + /// Can be remapped to HRTIM_DACTRG1 using DAC1_TRIG3_RMP in SYSCFG_CFGR3. + Tim15OrHrtimDacTrg1 = 3, + Tim2 = 4, + /// Requires DAC_TRIG5_RMP set in SYSCFG_CFGR3. + HrtimDacTrg2 = 5, +} + +/// Trigger selection for STM32L0. +#[cfg(stm32l0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim3 = 1, + Tim3Ch3 = 2, + Tim21 = 3, + Tim2 = 4, + Tim7 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for STM32L1. +#[cfg(stm32l1)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Tim6 = 0, + Tim7 = 2, + Tim9 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Software = 7, +} + +/// Trigger selection for L4+, L5, U5, H7. +#[cfg(any(stm32l4_plus, stm32l5, stm32u5, stm32h7))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Tim4 = 3, + Tim5 = 4, + Tim6 = 5, + Tim7 = 6, + Tim8 = 7, + Tim15 = 8, + #[cfg(all(stm32h7, hrtim))] + Hrtim1DacTrg1 = 9, + #[cfg(all(stm32h7, hrtim))] + Hrtim1DacTrg2 = 10, + Lptim1 = 11, + #[cfg(not(stm32u5))] + Lptim2 = 12, + #[cfg(stm32u5)] + Lptim3 = 12, + Exti9 = 13, + #[cfg(any(stm32h7ax, stm32h7bx))] + /// RM0455 suggests this might be LPTIM2 on DAC1 and LPTIM3 on DAC2, + /// but it's probably wrong. Please let us know if you find out. + Lptim3 = 14, + #[cfg(any(stm32h72x, stm32h73x))] + Tim23 = 14, + #[cfg(any(stm32h72x, stm32h73x))] + Tim24 = 15, +} + +/// Trigger selection for H5. +#[cfg(stm32h5)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + #[cfg(any(stm32h56x, stm32h57x))] + Tim4 = 3, + #[cfg(stm32h503)] + Tim3 = 3, + #[cfg(any(stm32h56x, stm32h57x))] + Tim5 = 4, + Tim6 = 5, + Tim7 = 6, + #[cfg(any(stm32h56x, stm32h57x))] + Tim8 = 7, + #[cfg(any(stm32h56x, stm32h57x))] + Tim15 = 8, + Lptim1 = 11, + Lptim2 = 12, + Exti9 = 13, +} + +/// Trigger selection for G0. +#[cfg(stm32g0)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Tim3 = 3, + Tim6 = 5, + Tim7 = 6, + Tim15 = 8, + Lptim1 = 11, + Lptim2 = 12, + Exti9 = 13, +} + +/// Trigger selection for G4. +#[cfg(stm32g4)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + /// * DAC1, DAC2, DAC4: TIM8 + /// * DAC3: TIM1 + Dac124Tim8Dac3Tim1 = 1, + Tim7 = 2, + Tim15 = 3, + Tim2 = 4, + Tim4 = 5, + Exti9 = 6, + Tim6 = 7, + Tim3 = 8, + HrtimDacRstTrg1 = 9, + HrtimDacRstTrg2 = 10, + HrtimDacRstTrg3 = 11, + HrtimDacRstTrg4 = 12, + HrtimDacRstTrg5 = 13, + HrtimDacRstTrg6 = 14, + /// * DAC1, DAC4: HRTIM_DAC_TRG1 + /// * DAC2: HRTIM_DAC_TRG2 + /// * DAC3: HRTIM_DAC_TRG3 + HrtimDacTrg123 = 15, +} + +/// Trigger selection for WL. +#[cfg(stm32wl)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum TriggerSel { + Software = 0, + Tim1 = 1, + Tim2 = 2, + Lptim1 = 11, + Lptim2 = 12, + Lptim3 = 13, + Exti9 = 14, +} + +impl TriggerSel { + pub fn tsel(&self) -> u8 { + *self as u8 + } +} diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index e141fc48..12783464 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs @@ -77,7 +77,7 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); dac.enable_channel().unwrap(); TIM6::enable_and_reset(); @@ -127,7 +127,7 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 98f37f90..c9f0a4cf 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs @@ -48,7 +48,7 @@ async fn dac_task1(mut dac: Dac1Type) { error!("Reload value {} below threshold!", reload); } - dac.select_trigger(embassy_stm32::dac::Ch1Trigger::Tim6).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim6).unwrap(); dac.enable_channel().unwrap(); TIM6::enable_and_reset(); @@ -98,7 +98,7 @@ async fn dac_task2(mut dac: Dac2Type) { w.set_cen(true); }); - dac.select_trigger(embassy_stm32::dac::Ch2Trigger::Tim7).unwrap(); + dac.select_trigger(embassy_stm32::dac::TriggerSel::Tim7).unwrap(); debug!( "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",