diff options
| author | melvdl <[email protected]> | 2025-06-27 01:08:28 +0200 |
|---|---|---|
| committer | melvdl <[email protected]> | 2025-06-27 01:08:28 +0200 |
| commit | 6f88c2c73caa63a6e534130f4a064cb95d3e9d7d (patch) | |
| tree | fdddad93e4f48f32ff15a3b8ad6cd0ae12095fd4 /embassy-stm32/src/timer/simple_pwm.rs | |
| parent | cbd24bf2eece65a787fc085c255e9b2932ea73e3 (diff) | |
stm32: rename timer channel trait; replace impls via macro with impls generic over timer channels
Diffstat (limited to 'embassy-stm32/src/timer/simple_pwm.rs')
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 279 |
1 files changed, 128 insertions, 151 deletions
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 02835c379..c04b1ab97 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -4,7 +4,7 @@ use core::marker::PhantomData; | |||
| 4 | use core::mem::ManuallyDrop; | 4 | use core::mem::ManuallyDrop; |
| 5 | 5 | ||
| 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; | 6 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; |
| 7 | use super::{Ch1, Ch2, Ch3, Ch4, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; | 7 | use super::{Ch1, Ch2, Ch3, Ch4, Channel, GeneralInstance4Channel, TimerBits, TimerChannel, TimerPin}; |
| 8 | #[cfg(gpio_v2)] | 8 | #[cfg(gpio_v2)] |
| 9 | use crate::gpio::Pull; | 9 | use crate::gpio::Pull; |
| 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| @@ -34,46 +34,37 @@ pub struct PwmPinConfig { | |||
| 34 | pub pull: Pull, | 34 | pub pull: Pull, |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | macro_rules! channel_impl { | 37 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { |
| 38 | ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { | 38 | /// Create a new PWM pin instance. |
| 39 | impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { | 39 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, output_type: OutputType) -> Self { |
| 40 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] | 40 | critical_section::with(|_| { |
| 41 | pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T, $channel>>, output_type: OutputType) -> Self { | 41 | pin.set_low(); |
| 42 | critical_section::with(|_| { | 42 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); |
| 43 | pin.set_low(); | 43 | }); |
| 44 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); | 44 | PwmPin { |
| 45 | }); | 45 | _pin: pin.into(), |
| 46 | PwmPin { | 46 | phantom: PhantomData, |
| 47 | _pin: pin.into(), | ||
| 48 | phantom: PhantomData, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] | ||
| 53 | pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T, $channel>>, pin_config: PwmPinConfig) -> Self { | ||
| 54 | critical_section::with(|_| { | ||
| 55 | pin.set_low(); | ||
| 56 | pin.set_as_af( | ||
| 57 | pin.af_num(), | ||
| 58 | #[cfg(gpio_v1)] | ||
| 59 | AfType::output(pin_config.output_type, pin_config.speed), | ||
| 60 | #[cfg(gpio_v2)] | ||
| 61 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | ||
| 62 | ); | ||
| 63 | }); | ||
| 64 | PwmPin { | ||
| 65 | _pin: pin.into(), | ||
| 66 | phantom: PhantomData, | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | 47 | } |
| 70 | }; | 48 | } |
| 71 | } | ||
| 72 | 49 | ||
| 73 | channel_impl!(new_ch1, new_ch1_with_config, Ch1, TimerPin); | 50 | /// Create a new PWM pin instance with config. |
| 74 | channel_impl!(new_ch2, new_ch2_with_config, Ch2, TimerPin); | 51 | pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C>>, pin_config: PwmPinConfig) -> Self { |
| 75 | channel_impl!(new_ch3, new_ch3_with_config, Ch3, TimerPin); | 52 | critical_section::with(|_| { |
| 76 | channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin); | 53 | pin.set_low(); |
| 54 | pin.set_as_af( | ||
| 55 | pin.af_num(), | ||
| 56 | #[cfg(gpio_v1)] | ||
| 57 | AfType::output(pin_config.output_type, pin_config.speed), | ||
| 58 | #[cfg(gpio_v2)] | ||
| 59 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | ||
| 60 | ); | ||
| 61 | }); | ||
| 62 | PwmPin { | ||
| 63 | _pin: pin.into(), | ||
| 64 | phantom: PhantomData, | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 77 | 68 | ||
| 78 | /// A single channel of a pwm, obtained from [`SimplePwm::split`], | 69 | /// A single channel of a pwm, obtained from [`SimplePwm::split`], |
| 79 | /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. | 70 | /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. |
| @@ -82,7 +73,7 @@ channel_impl!(new_ch4, new_ch4_with_config, Ch4, TimerPin); | |||
| 82 | /// the frequency configuration is shared with all four channels. | 73 | /// the frequency configuration is shared with all four channels. |
| 83 | pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> { | 74 | pub struct SimplePwmChannel<'d, T: GeneralInstance4Channel> { |
| 84 | timer: ManuallyDrop<Timer<'d, T>>, | 75 | timer: ManuallyDrop<Timer<'d, T>>, |
| 85 | channel: TimerChannel, | 76 | channel: Channel, |
| 86 | } | 77 | } |
| 87 | 78 | ||
| 88 | // TODO: check for RMW races | 79 | // TODO: check for RMW races |
| @@ -207,18 +198,13 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 207 | this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details | 198 | this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details |
| 208 | this.inner.start(); | 199 | this.inner.start(); |
| 209 | 200 | ||
| 210 | [ | 201 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] |
| 211 | TimerChannel::Ch1, | 202 | .iter() |
| 212 | TimerChannel::Ch2, | 203 | .for_each(|&channel| { |
| 213 | TimerChannel::Ch3, | 204 | this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); |
| 214 | TimerChannel::Ch4, | 205 | |
| 215 | ] | 206 | this.inner.set_output_compare_preload(channel, true); |
| 216 | .iter() | 207 | }); |
| 217 | .for_each(|&channel| { | ||
| 218 | this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); | ||
| 219 | |||
| 220 | this.inner.set_output_compare_preload(channel, true); | ||
| 221 | }); | ||
| 222 | 208 | ||
| 223 | this | 209 | this |
| 224 | } | 210 | } |
| @@ -226,7 +212,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 226 | /// Get a single channel | 212 | /// Get a single channel |
| 227 | /// | 213 | /// |
| 228 | /// If you need to use multiple channels, use [`Self::split`]. | 214 | /// If you need to use multiple channels, use [`Self::split`]. |
| 229 | pub fn channel(&mut self, channel: TimerChannel) -> SimplePwmChannel<'_, T> { | 215 | pub fn channel(&mut self, channel: Channel) -> SimplePwmChannel<'_, T> { |
| 230 | SimplePwmChannel { | 216 | SimplePwmChannel { |
| 231 | timer: unsafe { self.inner.clone_unchecked() }, | 217 | timer: unsafe { self.inner.clone_unchecked() }, |
| 232 | channel, | 218 | channel, |
| @@ -239,7 +225,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 239 | /// | 225 | /// |
| 240 | /// If you need to use multiple channels, use [`Self::split`]. | 226 | /// If you need to use multiple channels, use [`Self::split`]. |
| 241 | pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { | 227 | pub fn ch1(&mut self) -> SimplePwmChannel<'_, T> { |
| 242 | self.channel(TimerChannel::Ch1) | 228 | self.channel(Channel::Ch1) |
| 243 | } | 229 | } |
| 244 | 230 | ||
| 245 | /// Channel 2 | 231 | /// Channel 2 |
| @@ -248,7 +234,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 248 | /// | 234 | /// |
| 249 | /// If you need to use multiple channels, use [`Self::split`]. | 235 | /// If you need to use multiple channels, use [`Self::split`]. |
| 250 | pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { | 236 | pub fn ch2(&mut self) -> SimplePwmChannel<'_, T> { |
| 251 | self.channel(TimerChannel::Ch2) | 237 | self.channel(Channel::Ch2) |
| 252 | } | 238 | } |
| 253 | 239 | ||
| 254 | /// Channel 3 | 240 | /// Channel 3 |
| @@ -257,7 +243,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 257 | /// | 243 | /// |
| 258 | /// If you need to use multiple channels, use [`Self::split`]. | 244 | /// If you need to use multiple channels, use [`Self::split`]. |
| 259 | pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { | 245 | pub fn ch3(&mut self) -> SimplePwmChannel<'_, T> { |
| 260 | self.channel(TimerChannel::Ch3) | 246 | self.channel(Channel::Ch3) |
| 261 | } | 247 | } |
| 262 | 248 | ||
| 263 | /// Channel 4 | 249 | /// Channel 4 |
| @@ -266,7 +252,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 266 | /// | 252 | /// |
| 267 | /// If you need to use multiple channels, use [`Self::split`]. | 253 | /// If you need to use multiple channels, use [`Self::split`]. |
| 268 | pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { | 254 | pub fn ch4(&mut self) -> SimplePwmChannel<'_, T> { |
| 269 | self.channel(TimerChannel::Ch4) | 255 | self.channel(Channel::Ch4) |
| 270 | } | 256 | } |
| 271 | 257 | ||
| 272 | /// Splits a [`SimplePwm`] into four pwm channels. | 258 | /// Splits a [`SimplePwm`] into four pwm channels. |
| @@ -288,10 +274,10 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 288 | }; | 274 | }; |
| 289 | 275 | ||
| 290 | SimplePwmChannels { | 276 | SimplePwmChannels { |
| 291 | ch1: ch(TimerChannel::Ch1), | 277 | ch1: ch(Channel::Ch1), |
| 292 | ch2: ch(TimerChannel::Ch2), | 278 | ch2: ch(Channel::Ch2), |
| 293 | ch3: ch(TimerChannel::Ch3), | 279 | ch3: ch(Channel::Ch3), |
| 294 | ch4: ch(TimerChannel::Ch4), | 280 | ch4: ch(Channel::Ch4), |
| 295 | } | 281 | } |
| 296 | } | 282 | } |
| 297 | 283 | ||
| @@ -322,7 +308,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 322 | /// | 308 | /// |
| 323 | /// Note: | 309 | /// Note: |
| 324 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. | 310 | /// you will need to provide corresponding TIMx_UP DMA channel to use this method. |
| 325 | pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: TimerChannel, duty: &[u16]) { | 311 | pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) { |
| 326 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 312 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| 327 | let req = dma.request(); | 313 | let req = dma.request(); |
| 328 | 314 | ||
| @@ -405,8 +391,8 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 405 | pub async fn waveform_up_multi_channel( | 391 | pub async fn waveform_up_multi_channel( |
| 406 | &mut self, | 392 | &mut self, |
| 407 | dma: Peri<'_, impl super::UpDma<T>>, | 393 | dma: Peri<'_, impl super::UpDma<T>>, |
| 408 | starting_channel: TimerChannel, | 394 | starting_channel: Channel, |
| 409 | ending_channel: TimerChannel, | 395 | ending_channel: Channel, |
| 410 | duty: &[u16], | 396 | duty: &[u16], |
| 411 | ) { | 397 | ) { |
| 412 | let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32; | 398 | let cr1_addr = self.inner.regs_gp16().cr1().as_ptr() as u32; |
| @@ -462,106 +448,97 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | |||
| 462 | } | 448 | } |
| 463 | } | 449 | } |
| 464 | 450 | ||
| 465 | macro_rules! impl_waveform_chx { | 451 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { |
| 466 | ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { | 452 | /// Generate a sequence of PWM waveform |
| 467 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | 453 | pub async fn waveform<C: TimerChannel>(&mut self, dma: Peri<'_, impl super::Dma<T, C>>, duty: &[u16]) { |
| 468 | /// Generate a sequence of PWM waveform | 454 | use crate::pac::timer::vals::Ccds; |
| 469 | pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch<T, $cc_ch>>, duty: &[u16]) { | ||
| 470 | use crate::pac::timer::vals::Ccds; | ||
| 471 | 455 | ||
| 472 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 456 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| 473 | let req = dma.request(); | 457 | let req = dma.request(); |
| 474 | 458 | ||
| 475 | let cc_channel = TimerChannel::$cc_ch; | 459 | let cc_channel = C::CHANNEL; |
| 476 | 460 | ||
| 477 | let original_duty_state = self.channel(cc_channel).current_duty_cycle(); | 461 | let original_duty_state = self.channel(cc_channel).current_duty_cycle(); |
| 478 | let original_enable_state = self.channel(cc_channel).is_enabled(); | 462 | let original_enable_state = self.channel(cc_channel).is_enabled(); |
| 479 | let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ON_UPDATE; | 463 | let original_cc_dma_on_update = self.inner.get_cc_dma_selection() == Ccds::ON_UPDATE; |
| 480 | let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); | 464 | let original_cc_dma_enabled = self.inner.get_cc_dma_enable_state(cc_channel); |
| 481 | 465 | ||
| 482 | // redirect CC DMA request onto Update Event | 466 | // redirect CC DMA request onto Update Event |
| 483 | if !original_cc_dma_on_update { | 467 | if !original_cc_dma_on_update { |
| 484 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE) | 468 | self.inner.set_cc_dma_selection(Ccds::ON_UPDATE) |
| 485 | } | 469 | } |
| 486 | 470 | ||
| 487 | if !original_cc_dma_enabled { | 471 | if !original_cc_dma_enabled { |
| 488 | self.inner.set_cc_dma_enable_state(cc_channel, true); | 472 | self.inner.set_cc_dma_enable_state(cc_channel, true); |
| 489 | } | 473 | } |
| 490 | 474 | ||
| 491 | if !original_enable_state { | 475 | if !original_enable_state { |
| 492 | self.channel(cc_channel).enable(); | 476 | self.channel(cc_channel).enable(); |
| 493 | } | 477 | } |
| 494 | 478 | ||
| 495 | unsafe { | 479 | unsafe { |
| 480 | #[cfg(not(any(bdma, gpdma)))] | ||
| 481 | use crate::dma::{Burst, FifoThreshold}; | ||
| 482 | use crate::dma::{Transfer, TransferOptions}; | ||
| 483 | |||
| 484 | let dma_transfer_option = TransferOptions { | ||
| 485 | #[cfg(not(any(bdma, gpdma)))] | ||
| 486 | fifo_threshold: Some(FifoThreshold::Full), | ||
| 487 | #[cfg(not(any(bdma, gpdma)))] | ||
| 488 | mburst: Burst::Incr8, | ||
| 489 | ..Default::default() | ||
| 490 | }; | ||
| 491 | |||
| 492 | match self.inner.bits() { | ||
| 493 | TimerBits::Bits16 => { | ||
| 494 | Transfer::new_write( | ||
| 495 | dma, | ||
| 496 | req, | ||
| 497 | duty, | ||
| 498 | self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, | ||
| 499 | dma_transfer_option, | ||
| 500 | ) | ||
| 501 | .await | ||
| 502 | } | ||
| 503 | #[cfg(not(any(stm32l0)))] | ||
| 504 | TimerBits::Bits32 => { | ||
| 496 | #[cfg(not(any(bdma, gpdma)))] | 505 | #[cfg(not(any(bdma, gpdma)))] |
| 497 | use crate::dma::{Burst, FifoThreshold}; | 506 | panic!("unsupported timer bits"); |
| 498 | use crate::dma::{Transfer, TransferOptions}; | 507 | |
| 499 | 508 | #[cfg(any(bdma, gpdma))] | |
| 500 | let dma_transfer_option = TransferOptions { | 509 | Transfer::new_write( |
| 501 | #[cfg(not(any(bdma, gpdma)))] | 510 | dma, |
| 502 | fifo_threshold: Some(FifoThreshold::Full), | 511 | req, |
| 503 | #[cfg(not(any(bdma, gpdma)))] | 512 | duty, |
| 504 | mburst: Burst::Incr8, | 513 | self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, |
| 505 | ..Default::default() | 514 | dma_transfer_option, |
| 506 | }; | 515 | ) |
| 507 | 516 | .await | |
| 508 | match self.inner.bits() { | ||
| 509 | TimerBits::Bits16 => { | ||
| 510 | Transfer::new_write( | ||
| 511 | dma, | ||
| 512 | req, | ||
| 513 | duty, | ||
| 514 | self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, | ||
| 515 | dma_transfer_option, | ||
| 516 | ) | ||
| 517 | .await | ||
| 518 | } | ||
| 519 | #[cfg(not(any(stm32l0)))] | ||
| 520 | TimerBits::Bits32 => { | ||
| 521 | #[cfg(not(any(bdma, gpdma)))] | ||
| 522 | panic!("unsupported timer bits"); | ||
| 523 | |||
| 524 | #[cfg(any(bdma, gpdma))] | ||
| 525 | Transfer::new_write( | ||
| 526 | dma, | ||
| 527 | req, | ||
| 528 | duty, | ||
| 529 | self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, | ||
| 530 | dma_transfer_option, | ||
| 531 | ) | ||
| 532 | .await | ||
| 533 | } | ||
| 534 | }; | ||
| 535 | }; | ||
| 536 | |||
| 537 | // restore output compare state | ||
| 538 | if !original_enable_state { | ||
| 539 | self.channel(cc_channel).disable(); | ||
| 540 | } | 517 | } |
| 518 | }; | ||
| 519 | }; | ||
| 541 | 520 | ||
| 542 | self.channel(cc_channel).set_duty_cycle(original_duty_state); | 521 | // restore output compare state |
| 522 | if !original_enable_state { | ||
| 523 | self.channel(cc_channel).disable(); | ||
| 524 | } | ||
| 543 | 525 | ||
| 544 | // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, | 526 | self.channel(cc_channel).set_duty_cycle(original_duty_state); |
| 545 | // this can almost always trigger a DMA FIFO error. | ||
| 546 | // | ||
| 547 | // optional TODO: | ||
| 548 | // clean FEIF after disable UDE | ||
| 549 | if !original_cc_dma_enabled { | ||
| 550 | self.inner.set_cc_dma_enable_state(cc_channel, false); | ||
| 551 | } | ||
| 552 | 527 | ||
| 553 | if !original_cc_dma_on_update { | 528 | // Since DMA is closed before timer Capture Compare Event trigger DMA is turn off, |
| 554 | self.inner.set_cc_dma_selection(Ccds::ON_COMPARE) | 529 | // this can almost always trigger a DMA FIFO error. |
| 555 | } | 530 | // |
| 556 | } | 531 | // optional TODO: |
| 532 | // clean FEIF after disable UDE | ||
| 533 | if !original_cc_dma_enabled { | ||
| 534 | self.inner.set_cc_dma_enable_state(cc_channel, false); | ||
| 557 | } | 535 | } |
| 558 | }; | ||
| 559 | } | ||
| 560 | 536 | ||
| 561 | impl_waveform_chx!(waveform_ch1, Dma, Ch1); | 537 | if !original_cc_dma_on_update { |
| 562 | impl_waveform_chx!(waveform_ch2, Dma, Ch2); | 538 | self.inner.set_cc_dma_selection(Ccds::ON_COMPARE) |
| 563 | impl_waveform_chx!(waveform_ch3, Dma, Ch3); | 539 | } |
| 564 | impl_waveform_chx!(waveform_ch4, Dma, Ch4); | 540 | } |
| 541 | } | ||
| 565 | 542 | ||
| 566 | impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { | 543 | impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::ErrorType for SimplePwmChannel<'d, T> { |
| 567 | type Error = core::convert::Infallible; | 544 | type Error = core::convert::Infallible; |
| @@ -599,7 +576,7 @@ impl<'d, T: GeneralInstance4Channel> embedded_hal_1::pwm::SetDutyCycle for Simpl | |||
| 599 | } | 576 | } |
| 600 | 577 | ||
| 601 | impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { | 578 | impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { |
| 602 | type Channel = TimerChannel; | 579 | type Channel = Channel; |
| 603 | type Time = Hertz; | 580 | type Time = Hertz; |
| 604 | type Duty = u32; | 581 | type Duty = u32; |
| 605 | 582 | ||
