diff options
| author | nikvoid <[email protected]> | 2025-07-04 17:26:37 +0300 |
|---|---|---|
| committer | nikvoid <[email protected]> | 2025-07-16 12:35:50 +0300 |
| commit | 71ad56357925a3f2b98a20bcce3c1bdb0ac63be5 (patch) | |
| tree | 1513579878ec403bb4e419b491f42d1e1892c956 /embassy-stm32 | |
| parent | 38807ff5fd508ce1a1400c1589e029c0361d0ef0 (diff) | |
stm32: add `waveform_up` function for complementary PWM too
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index a450705a2..07d5ec826 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -134,6 +134,66 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 134 | self.inner.set_dead_time_clock_division(ckd); | 134 | self.inner.set_dead_time_clock_division(ckd); |
| 135 | self.inner.set_dead_time_value(value); | 135 | self.inner.set_dead_time_value(value); |
| 136 | } | 136 | } |
| 137 | |||
| 138 | /// Generate a sequence of PWM waveform | ||
| 139 | /// | ||
| 140 | /// Note: | ||
| 141 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. | ||
| 142 | pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) { | ||
| 143 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | ||
| 144 | let req = dma.request(); | ||
| 145 | |||
| 146 | let original_duty_state = self.inner.get_compare_value(channel); | ||
| 147 | let original_enable_state = self.inner.get_channel_enable_state(channel); | ||
| 148 | let original_update_dma_state = self.inner.get_update_dma_state(); | ||
| 149 | |||
| 150 | if !original_update_dma_state { | ||
| 151 | self.inner.enable_update_dma(true); | ||
| 152 | } | ||
| 153 | |||
| 154 | if !original_enable_state { | ||
| 155 | self.inner.enable_channel(channel, true); | ||
| 156 | } | ||
| 157 | |||
| 158 | unsafe { | ||
| 159 | #[cfg(not(any(bdma, gpdma)))] | ||
| 160 | use crate::dma::{Burst, FifoThreshold}; | ||
| 161 | use crate::dma::{Transfer, TransferOptions}; | ||
| 162 | |||
| 163 | let dma_transfer_option = TransferOptions { | ||
| 164 | #[cfg(not(any(bdma, gpdma)))] | ||
| 165 | fifo_threshold: Some(FifoThreshold::Full), | ||
| 166 | #[cfg(not(any(bdma, gpdma)))] | ||
| 167 | mburst: Burst::Incr8, | ||
| 168 | ..Default::default() | ||
| 169 | }; | ||
| 170 | |||
| 171 | Transfer::new_write( | ||
| 172 | dma, | ||
| 173 | req, | ||
| 174 | duty, | ||
| 175 | self.inner.regs_gp16().ccr(channel.index()).as_ptr() as *mut u16, | ||
| 176 | dma_transfer_option, | ||
| 177 | ) | ||
| 178 | .await | ||
| 179 | }; | ||
| 180 | |||
| 181 | // restore output compare state | ||
| 182 | if !original_enable_state { | ||
| 183 | self.inner.enable_channel(channel, false); | ||
| 184 | } | ||
| 185 | |||
| 186 | self.inner.set_compare_value(channel, original_duty_state); | ||
| 187 | |||
| 188 | // Since DMA is closed before timer update event trigger DMA is turn off, | ||
| 189 | // this can almost always trigger a DMA FIFO error. | ||
| 190 | // | ||
| 191 | // optional TODO: | ||
| 192 | // clean FEIF after disable UDE | ||
| 193 | if !original_update_dma_state { | ||
| 194 | self.inner.enable_update_dma(false); | ||
| 195 | } | ||
| 196 | } | ||
| 137 | } | 197 | } |
| 138 | 198 | ||
| 139 | impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { | 199 | impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { |
