diff options
| author | Grant Miller <[email protected]> | 2024-09-06 10:25:29 -0500 |
|---|---|---|
| committer | Grant Miller <[email protected]> | 2024-09-06 10:25:29 -0500 |
| commit | f7f062e0a3f303dfc4f976907b2555f2cfb48621 (patch) | |
| tree | 1a9e4a8cc312f29847d8c67fe4c75f78a36fa0d1 /embassy-stm32/src/timer | |
| parent | 8ac758bdee793496f842f4c267bda2b6f935a0bb (diff) | |
Deduplicate SimplePwm's channel methods
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 119 |
1 files changed, 63 insertions, 56 deletions
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index f94ed1be5..7179a7a59 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -51,7 +51,8 @@ channel_impl!(new_ch2, Ch2, Channel2Pin); | |||
| 51 | channel_impl!(new_ch3, Ch3, Channel3Pin); | 51 | channel_impl!(new_ch3, Ch3, Channel3Pin); |
| 52 | channel_impl!(new_ch4, Ch4, Channel4Pin); | 52 | channel_impl!(new_ch4, Ch4, Channel4Pin); |
| 53 | 53 | ||
| 54 | /// A single channel of a pwm, obtained from [`SimplePwm::split`]. | 54 | /// A single channel of a pwm, obtained from [`SimplePwm::split`], |
| 55 | /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. | ||
| 55 | /// | 56 | /// |
| 56 | /// It is not possible to change the pwm frequency because | 57 | /// It is not possible to change the pwm frequency because |
| 57 | /// the frequency configuration is shared with all four channels. | 58 | /// the frequency configuration is shared with all four channels. |
| @@ -179,13 +180,52 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 179 | this | 180 | this |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | fn channel(&self, channel: Channel) -> SimplePwmChannel<'_, T> { | 183 | /// Get a single channel |
| 184 | /// | ||
| 185 | /// If you need to use multiple channels, use [`Self::split`]. | ||
| 186 | pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> { | ||
| 183 | SimplePwmChannel { | 187 | SimplePwmChannel { |
| 184 | timer: &self.inner, | 188 | timer: &self.inner, |
| 185 | channel, | 189 | channel, |
| 186 | } | 190 | } |
| 187 | } | 191 | } |
| 188 | 192 | ||
| 193 | /// Channel 1 | ||
| 194 | /// | ||
| 195 | /// This is just a convenience wrapper around [`Self::channel`]. | ||
| 196 | /// | ||
| 197 | /// If you need to use multiple channels, use [`Self::split`]. | ||
| 198 | pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { | ||
| 199 | self.channel(Channel::Ch1) | ||
| 200 | } | ||
| 201 | |||
| 202 | /// Channel 2 | ||
| 203 | /// | ||
| 204 | /// This is just a convenience wrapper around [`Self::channel`]. | ||
| 205 | /// | ||
| 206 | /// If you need to use multiple channels, use [`Self::split`]. | ||
| 207 | pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { | ||
| 208 | self.channel(Channel::Ch2) | ||
| 209 | } | ||
| 210 | |||
| 211 | /// Channel 3 | ||
| 212 | /// | ||
| 213 | /// This is just a convenience wrapper around [`Self::channel`]. | ||
| 214 | /// | ||
| 215 | /// If you need to use multiple channels, use [`Self::split`]. | ||
| 216 | pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { | ||
| 217 | self.channel(Channel::Ch3) | ||
| 218 | } | ||
| 219 | |||
| 220 | /// Channel 4 | ||
| 221 | /// | ||
| 222 | /// This is just a convenience wrapper around [`Self::channel`]. | ||
| 223 | /// | ||
| 224 | /// If you need to use multiple channels, use [`Self::split`]. | ||
| 225 | pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { | ||
| 226 | self.channel(Channel::Ch4) | ||
| 227 | } | ||
| 228 | |||
| 189 | /// Splits a [`SimplePwm`] into four pwm channels. | 229 | /// Splits a [`SimplePwm`] into four pwm channels. |
| 190 | /// | 230 | /// |
| 191 | /// This returns all four channels, including channels that | 231 | /// This returns all four channels, including channels that |
| @@ -193,27 +233,19 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 193 | // TODO: I hate the name "split" | 233 | // TODO: I hate the name "split" |
| 194 | pub fn split(&mut self) -> SimplePwmChannels<'_, T> { | 234 | pub fn split(&mut self) -> SimplePwmChannels<'_, T> { |
| 195 | // TODO: pre-enable channels? | 235 | // TODO: pre-enable channels? |
| 196 | SimplePwmChannels { | ||
| 197 | ch1: self.channel(Channel::Ch1), | ||
| 198 | ch2: self.channel(Channel::Ch2), | ||
| 199 | ch3: self.channel(Channel::Ch3), | ||
| 200 | ch4: self.channel(Channel::Ch4), | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | /// Enable the given channel. | ||
| 205 | pub fn enable(&mut self, channel: Channel) { | ||
| 206 | self.inner.enable_channel(channel, true); | ||
| 207 | } | ||
| 208 | 236 | ||
| 209 | /// Disable the given channel. | 237 | // we can't use self.channel() because that takes &mut self |
| 210 | pub fn disable(&mut self, channel: Channel) { | 238 | let ch = |channel| SimplePwmChannel { |
| 211 | self.inner.enable_channel(channel, false); | 239 | timer: &self.inner, |
| 212 | } | 240 | channel, |
| 241 | }; | ||
| 213 | 242 | ||
| 214 | /// Check whether given channel is enabled | 243 | SimplePwmChannels { |
| 215 | pub fn is_enabled(&self, channel: Channel) -> bool { | 244 | ch1: ch(Channel::Ch1), |
| 216 | self.inner.get_channel_enable_state(channel) | 245 | ch2: ch(Channel::Ch2), |
| 246 | ch3: ch(Channel::Ch3), | ||
| 247 | ch4: ch(Channel::Ch4), | ||
| 248 | } | ||
| 217 | } | 249 | } |
| 218 | 250 | ||
| 219 | /// Set PWM frequency. | 251 | /// Set PWM frequency. |
| @@ -236,31 +268,6 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 236 | self.inner.get_max_compare_value() + 1 | 268 | self.inner.get_max_compare_value() + 1 |
| 237 | } | 269 | } |
| 238 | 270 | ||
| 239 | /// Set the duty for a given channel. | ||
| 240 | /// | ||
| 241 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. | ||
| 242 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | ||
| 243 | assert!(duty <= self.get_max_duty()); | ||
| 244 | self.inner.set_compare_value(channel, duty) | ||
| 245 | } | ||
| 246 | |||
| 247 | /// Get the duty for a given channel. | ||
| 248 | /// | ||
| 249 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. | ||
| 250 | pub fn get_duty(&self, channel: Channel) -> u32 { | ||
| 251 | self.inner.get_compare_value(channel) | ||
| 252 | } | ||
| 253 | |||
| 254 | /// Set the output polarity for a given channel. | ||
| 255 | pub fn set_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { | ||
| 256 | self.inner.set_output_polarity(channel, polarity); | ||
| 257 | } | ||
| 258 | |||
| 259 | /// Set the output compare mode for a given channel. | ||
| 260 | pub fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { | ||
| 261 | self.inner.set_output_compare_mode(channel, mode); | ||
| 262 | } | ||
| 263 | |||
| 264 | /// Generate a sequence of PWM waveform | 271 | /// Generate a sequence of PWM waveform |
| 265 | /// | 272 | /// |
| 266 | /// Note: | 273 | /// Note: |
| @@ -276,8 +283,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 276 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 283 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| 277 | let req = dma.request(); | 284 | let req = dma.request(); |
| 278 | 285 | ||
| 279 | let original_duty_state = self.get_duty(channel); | 286 | let original_duty_state = self.channel(channel).get_duty(); |
| 280 | let original_enable_state = self.is_enabled(channel); | 287 | let original_enable_state = self.channel(channel).is_enabled(); |
| 281 | let original_update_dma_state = self.inner.get_update_dma_state(); | 288 | let original_update_dma_state = self.inner.get_update_dma_state(); |
| 282 | 289 | ||
| 283 | if !original_update_dma_state { | 290 | if !original_update_dma_state { |
| @@ -285,7 +292,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 285 | } | 292 | } |
| 286 | 293 | ||
| 287 | if !original_enable_state { | 294 | if !original_enable_state { |
| 288 | self.enable(channel); | 295 | self.channel(channel).enable(); |
| 289 | } | 296 | } |
| 290 | 297 | ||
| 291 | unsafe { | 298 | unsafe { |
| @@ -313,10 +320,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 313 | 320 | ||
| 314 | // restore output compare state | 321 | // restore output compare state |
| 315 | if !original_enable_state { | 322 | if !original_enable_state { |
| 316 | self.disable(channel); | 323 | self.channel(channel).disable(); |
| 317 | } | 324 | } |
| 318 | 325 | ||
| 319 | self.set_duty(channel, original_duty_state); | 326 | self.channel(channel).set_duty(original_duty_state); |
| 320 | 327 | ||
| 321 | // Since DMA is closed before timer update event trigger DMA is turn off, | 328 | // Since DMA is closed before timer update event trigger DMA is turn off, |
| 322 | // this can almost always trigger a DMA FIFO error. | 329 | // this can almost always trigger a DMA FIFO error. |
| @@ -346,8 +353,8 @@ macro_rules! impl_waveform_chx { | |||
| 346 | 353 | ||
| 347 | let cc_channel = Channel::$cc_ch; | 354 | let cc_channel = Channel::$cc_ch; |
| 348 | 355 | ||
| 349 | let original_duty_state = self.get_duty(cc_channel); | 356 | let original_duty_state = self.channel(cc_channel).get_duty(); |
| 350 | let original_enable_state = self.is_enabled(cc_channel); | 357 | let original_enable_state = self.channel(cc_channel).is_enabled(); |
| 351 | let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ONUPDATE; | 358 | let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ONUPDATE; |
| 352 | let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); | 359 | let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); |
| 353 | 360 | ||
| @@ -361,7 +368,7 @@ macro_rules! impl_waveform_chx { | |||
| 361 | } | 368 | } |
| 362 | 369 | ||
| 363 | if !original_enable_state { | 370 | if !original_enable_state { |
| 364 | self.enable(cc_channel); | 371 | self.channel(cc_channel).enable(); |
| 365 | } | 372 | } |
| 366 | 373 | ||
| 367 | unsafe { | 374 | unsafe { |
| @@ -389,10 +396,10 @@ macro_rules! impl_waveform_chx { | |||
| 389 | 396 | ||
| 390 | // restore output compare state | 397 | // restore output compare state |
| 391 | if !original_enable_state { | 398 | if !original_enable_state { |
| 392 | self.disable(cc_channel); | 399 | self.channel(cc_channel).disable(); |
| 393 | } | 400 | } |
| 394 | 401 | ||
| 395 | self.set_duty(cc_channel, original_duty_state); | 402 | self.channel(cc_channel).set_duty(original_duty_state); |
| 396 | 403 | ||
| 397 | // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, | 404 | // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, |
| 398 | // this can almost always trigger a DMA FIFO error. | 405 | // this can almost always trigger a DMA FIFO error. |
