aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authornikvoid <[email protected]>2025-07-04 17:26:37 +0300
committernikvoid <[email protected]>2025-07-16 12:35:50 +0300
commit71ad56357925a3f2b98a20bcce3c1bdb0ac63be5 (patch)
tree1513579878ec403bb4e419b491f42d1e1892c956 /embassy-stm32
parent38807ff5fd508ce1a1400c1589e029c0361d0ef0 (diff)
stm32: add `waveform_up` function for complementary PWM too
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs60
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
139impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { 199impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> {