diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-10 00:24:02 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-10 00:24:02 +0100 |
| commit | e7d0b8db88fa032b5d825901092aca78b0b424ce (patch) | |
| tree | 162a4cd6e75b47fe9a7c885c68ea4d7aae34e8c6 /embassy-stm32/src/timer | |
| parent | 04147b4147741bb711d6cc769aa7a4a88eed8e76 (diff) | |
| parent | 8fd803a5fe0af8cc9d648ba2efba755b502f08e9 (diff) | |
Merge pull request #2499 from eZioPan/update-metapac8
Update embassy-stm32 after stm32-metapac timer_v2
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 17 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/mod.rs | 610 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 7 |
3 files changed, 425 insertions, 209 deletions
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index eddce0404..72f1ec864 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -23,7 +23,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { | |||
| 23 | 23 | ||
| 24 | macro_rules! complementary_channel_impl { | 24 | macro_rules! complementary_channel_impl { |
| 25 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 25 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 26 | impl<'d, T: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { | 26 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { |
| 27 | #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] | 27 | #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] |
| 28 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { | 28 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { |
| 29 | into_ref!(pin); | 29 | into_ref!(pin); |
| @@ -84,14 +84,13 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | |||
| 84 | 84 | ||
| 85 | this.inner.enable_outputs(); | 85 | this.inner.enable_outputs(); |
| 86 | 86 | ||
| 87 | this.inner | 87 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] |
| 88 | .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1); | 88 | .iter() |
| 89 | this.inner | 89 | .for_each(|&channel| { |
| 90 | .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1); | 90 | this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); |
| 91 | this.inner | 91 | this.inner.set_output_compare_preload(channel, true); |
| 92 | .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1); | 92 | }); |
| 93 | this.inner | 93 | |
| 94 | .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1); | ||
| 95 | this | 94 | this |
| 96 | } | 95 | } |
| 97 | 96 | ||
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 210bf7153..0118395a7 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -1,5 +1,31 @@ | |||
| 1 | //! Timers, PWM, quadrature decoder. | 1 | //! Timers, PWM, quadrature decoder. |
| 2 | 2 | ||
| 3 | //! Timer inheritance | ||
| 4 | |||
| 5 | // sealed: | ||
| 6 | // | ||
| 7 | // Core -------------------------> 1CH -------------------------> 1CH_CMP | ||
| 8 | // | | ^ | | ||
| 9 | // +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV | ||
| 10 | // | | | ^ | | ^ ^ | ||
| 11 | // | | +------|--|--------------|-----------+ | | ||
| 12 | // | +--------------------+ +--------------|-----------|---------+ | ||
| 13 | // | | | | | ||
| 14 | // | +--------------------------------------|-----------+ | ||
| 15 | // +----------------------------------------------------+ | ||
| 16 | |||
| 17 | //! BasicInstance --> CaptureCompare16bitInstance --+--> ComplementaryCaptureCompare16bitInstance | ||
| 18 | //! | | ||
| 19 | //! +--> CaptureCompare32bitInstance | ||
| 20 | //! | ||
| 21 | //! mapping: | ||
| 22 | //! | ||
| 23 | //! BasicInstance --> Basic Timer | ||
| 24 | //! CaptureCompare16bitInstance --> 1-channel Timer, 2-channel Timer, General Purpose 16-bit Timer | ||
| 25 | //! CaptureCompare32bitInstance --> General Purpose 32-bit Timer | ||
| 26 | //! ComplementaryCaptureCompare16bitInstance --> 1-channel with one complentary Timer, 2-channel with one complentary Timer, Advance Control Timer | ||
| 27 | |||
| 28 | #[cfg(not(stm32l0))] | ||
| 3 | pub mod complementary_pwm; | 29 | pub mod complementary_pwm; |
| 4 | pub mod qei; | 30 | pub mod qei; |
| 5 | pub mod simple_pwm; | 31 | pub mod simple_pwm; |
| @@ -19,32 +45,32 @@ pub mod low_level { | |||
| 19 | pub(crate) mod sealed { | 45 | pub(crate) mod sealed { |
| 20 | use super::*; | 46 | use super::*; |
| 21 | 47 | ||
| 22 | /// Basic 16-bit timer instance. | 48 | /// Virtual Core 16-bit timer instance. |
| 23 | pub trait Basic16bitInstance: RccPeripheral { | 49 | pub trait CoreInstance: RccPeripheral { |
| 24 | /// Interrupt for this timer. | 50 | /// Interrupt for this timer. |
| 25 | type Interrupt: interrupt::typelevel::Interrupt; | 51 | type Interrupt: interrupt::typelevel::Interrupt; |
| 26 | 52 | ||
| 27 | /// Get access to the basic 16bit timer registers. | 53 | /// Get access to the virutal core 16bit timer registers. |
| 28 | /// | 54 | /// |
| 29 | /// Note: This works even if the timer is more capable, because registers | 55 | /// Note: This works even if the timer is more capable, because registers |
| 30 | /// for the less capable timers are a subset. This allows writing a driver | 56 | /// for the less capable timers are a subset. This allows writing a driver |
| 31 | /// for a given set of capabilities, and having it transparently work with | 57 | /// for a given set of capabilities, and having it transparently work with |
| 32 | /// more capable timers. | 58 | /// more capable timers. |
| 33 | fn regs() -> crate::pac::timer::TimBasic; | 59 | fn regs_core() -> crate::pac::timer::TimCore; |
| 34 | 60 | ||
| 35 | /// Start the timer. | 61 | /// Start the timer. |
| 36 | fn start(&mut self) { | 62 | fn start(&mut self) { |
| 37 | Self::regs().cr1().modify(|r| r.set_cen(true)); | 63 | Self::regs_core().cr1().modify(|r| r.set_cen(true)); |
| 38 | } | 64 | } |
| 39 | 65 | ||
| 40 | /// Stop the timer. | 66 | /// Stop the timer. |
| 41 | fn stop(&mut self) { | 67 | fn stop(&mut self) { |
| 42 | Self::regs().cr1().modify(|r| r.set_cen(false)); | 68 | Self::regs_core().cr1().modify(|r| r.set_cen(false)); |
| 43 | } | 69 | } |
| 44 | 70 | ||
| 45 | /// Reset the counter value to 0 | 71 | /// Reset the counter value to 0 |
| 46 | fn reset(&mut self) { | 72 | fn reset(&mut self) { |
| 47 | Self::regs().cnt().write(|r| r.set_cnt(0)); | 73 | Self::regs_core().cnt().write(|r| r.set_cnt(0)); |
| 48 | } | 74 | } |
| 49 | 75 | ||
| 50 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. | 76 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. |
| @@ -64,7 +90,7 @@ pub(crate) mod sealed { | |||
| 64 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | 90 | // the timer counts `0..=arr`, we want it to count `0..divide_by` |
| 65 | let arr = unwrap!(u16::try_from(divide_by - 1)); | 91 | let arr = unwrap!(u16::try_from(divide_by - 1)); |
| 66 | 92 | ||
| 67 | let regs = Self::regs(); | 93 | let regs = Self::regs_core(); |
| 68 | regs.psc().write(|r| r.set_psc(psc)); | 94 | regs.psc().write(|r| r.set_psc(psc)); |
| 69 | regs.arr().write(|r| r.set_arr(arr)); | 95 | regs.arr().write(|r| r.set_arr(arr)); |
| 70 | 96 | ||
| @@ -77,7 +103,7 @@ pub(crate) mod sealed { | |||
| 77 | /// | 103 | /// |
| 78 | /// Returns whether the update interrupt flag was set. | 104 | /// Returns whether the update interrupt flag was set. |
| 79 | fn clear_update_interrupt(&mut self) -> bool { | 105 | fn clear_update_interrupt(&mut self) -> bool { |
| 80 | let regs = Self::regs(); | 106 | let regs = Self::regs_core(); |
| 81 | let sr = regs.sr().read(); | 107 | let sr = regs.sr().read(); |
| 82 | if sr.uif() { | 108 | if sr.uif() { |
| 83 | regs.sr().modify(|r| { | 109 | regs.sr().modify(|r| { |
| @@ -91,29 +117,19 @@ pub(crate) mod sealed { | |||
| 91 | 117 | ||
| 92 | /// Enable/disable the update interrupt. | 118 | /// Enable/disable the update interrupt. |
| 93 | fn enable_update_interrupt(&mut self, enable: bool) { | 119 | fn enable_update_interrupt(&mut self, enable: bool) { |
| 94 | Self::regs().dier().modify(|r| r.set_uie(enable)); | 120 | Self::regs_core().dier().modify(|r| r.set_uie(enable)); |
| 95 | } | ||
| 96 | |||
| 97 | /// Enable/disable the update dma. | ||
| 98 | fn enable_update_dma(&mut self, enable: bool) { | ||
| 99 | Self::regs().dier().modify(|r| r.set_ude(enable)); | ||
| 100 | } | ||
| 101 | |||
| 102 | /// Get the update dma enable/disable state. | ||
| 103 | fn get_update_dma_state(&self) -> bool { | ||
| 104 | Self::regs().dier().read().ude() | ||
| 105 | } | 121 | } |
| 106 | 122 | ||
| 107 | /// Enable/disable autoreload preload. | 123 | /// Enable/disable autoreload preload. |
| 108 | fn set_autoreload_preload(&mut self, enable: bool) { | 124 | fn set_autoreload_preload(&mut self, enable: bool) { |
| 109 | Self::regs().cr1().modify(|r| r.set_arpe(enable)); | 125 | Self::regs_core().cr1().modify(|r| r.set_arpe(enable)); |
| 110 | } | 126 | } |
| 111 | 127 | ||
| 112 | /// Get the timer frequency. | 128 | /// Get the timer frequency. |
| 113 | fn get_frequency(&self) -> Hertz { | 129 | fn get_frequency(&self) -> Hertz { |
| 114 | let timer_f = Self::frequency(); | 130 | let timer_f = Self::frequency(); |
| 115 | 131 | ||
| 116 | let regs = Self::regs(); | 132 | let regs = Self::regs_core(); |
| 117 | let arr = regs.arr().read().arr(); | 133 | let arr = regs.arr().read().arr(); |
| 118 | let psc = regs.psc().read().psc(); | 134 | let psc = regs.psc().read().psc(); |
| 119 | 135 | ||
| @@ -121,91 +137,101 @@ pub(crate) mod sealed { | |||
| 121 | } | 137 | } |
| 122 | } | 138 | } |
| 123 | 139 | ||
| 124 | /// Gneral-purpose 16-bit timer instance. | 140 | /// Virtual Basic without CR2 16-bit timer instance. |
| 125 | pub trait GeneralPurpose16bitInstance: Basic16bitInstance { | 141 | pub trait BasicNoCr2Instance: CoreInstance { |
| 126 | /// Get access to the general purpose 16bit timer registers. | 142 | /// Get access to the Baisc 16bit timer registers. |
| 127 | /// | 143 | /// |
| 128 | /// Note: This works even if the timer is more capable, because registers | 144 | /// Note: This works even if the timer is more capable, because registers |
| 129 | /// for the less capable timers are a subset. This allows writing a driver | 145 | /// for the less capable timers are a subset. This allows writing a driver |
| 130 | /// for a given set of capabilities, and having it transparently work with | 146 | /// for a given set of capabilities, and having it transparently work with |
| 131 | /// more capable timers. | 147 | /// more capable timers. |
| 132 | fn regs_gp16() -> crate::pac::timer::TimGp16; | 148 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2; |
| 133 | |||
| 134 | /// Set counting mode. | ||
| 135 | fn set_counting_mode(&mut self, mode: CountingMode) { | ||
| 136 | let (cms, dir) = mode.into(); | ||
| 137 | |||
| 138 | let timer_enabled = Self::regs().cr1().read().cen(); | ||
| 139 | // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. | ||
| 140 | // Changing direction is discouraged while the timer is running. | ||
| 141 | assert!(!timer_enabled); | ||
| 142 | 149 | ||
| 143 | Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); | 150 | /// Enable/disable the update dma. |
| 144 | Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) | 151 | fn enable_update_dma(&mut self, enable: bool) { |
| 152 | Self::regs_basic_no_cr2().dier().modify(|r| r.set_ude(enable)); | ||
| 145 | } | 153 | } |
| 146 | 154 | ||
| 147 | /// Get counting mode. | 155 | /// Get the update dma enable/disable state. |
| 148 | fn get_counting_mode(&self) -> CountingMode { | 156 | fn get_update_dma_state(&self) -> bool { |
| 149 | let cr1 = Self::regs_gp16().cr1().read(); | 157 | Self::regs_basic_no_cr2().dier().read().ude() |
| 150 | (cr1.cms(), cr1.dir()).into() | ||
| 151 | } | 158 | } |
| 159 | } | ||
| 160 | |||
| 161 | /// Basic 16-bit timer instance. | ||
| 162 | pub trait BasicInstance: BasicNoCr2Instance { | ||
| 163 | /// Get access to the Baisc 16bit timer registers. | ||
| 164 | /// | ||
| 165 | /// Note: This works even if the timer is more capable, because registers | ||
| 166 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 167 | /// for a given set of capabilities, and having it transparently work with | ||
| 168 | /// more capable timers. | ||
| 169 | fn regs_basic() -> crate::pac::timer::TimBasic; | ||
| 170 | } | ||
| 171 | |||
| 172 | /// Gneral-purpose 1 channel 16-bit timer instance. | ||
| 173 | pub trait GeneralPurpose1ChannelInstance: CoreInstance { | ||
| 174 | /// Get access to the general purpose 1 channel 16bit timer registers. | ||
| 175 | /// | ||
| 176 | /// Note: This works even if the timer is more capable, because registers | ||
| 177 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 178 | /// for a given set of capabilities, and having it transparently work with | ||
| 179 | /// more capable timers. | ||
| 180 | fn regs_1ch() -> crate::pac::timer::Tim1ch; | ||
| 152 | 181 | ||
| 153 | /// Set clock divider. | 182 | /// Set clock divider. |
| 154 | fn set_clock_division(&mut self, ckd: vals::Ckd) { | 183 | fn set_clock_division(&mut self, ckd: vals::Ckd) { |
| 155 | Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd)); | 184 | Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); |
| 185 | } | ||
| 186 | |||
| 187 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | ||
| 188 | fn get_max_compare_value(&self) -> u16 { | ||
| 189 | Self::regs_1ch().arr().read().arr() | ||
| 156 | } | 190 | } |
| 157 | } | 191 | } |
| 158 | 192 | ||
| 159 | /// Gneral-purpose 32-bit timer instance. | 193 | /// Gneral-purpose 1 channel 16-bit timer instance. |
| 160 | pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { | 194 | pub trait GeneralPurpose2ChannelInstance: GeneralPurpose1ChannelInstance { |
| 161 | /// Get access to the general purpose 32bit timer registers. | 195 | /// Get access to the general purpose 2 channel 16bit timer registers. |
| 162 | /// | 196 | /// |
| 163 | /// Note: This works even if the timer is more capable, because registers | 197 | /// Note: This works even if the timer is more capable, because registers |
| 164 | /// for the less capable timers are a subset. This allows writing a driver | 198 | /// for the less capable timers are a subset. This allows writing a driver |
| 165 | /// for a given set of capabilities, and having it transparently work with | 199 | /// for a given set of capabilities, and having it transparently work with |
| 166 | /// more capable timers. | 200 | /// more capable timers. |
| 167 | fn regs_gp32() -> crate::pac::timer::TimGp32; | 201 | fn regs_2ch() -> crate::pac::timer::Tim2ch; |
| 168 | 202 | } | |
| 169 | /// Set timer frequency. | ||
| 170 | fn set_frequency(&mut self, frequency: Hertz) { | ||
| 171 | let f = frequency.0; | ||
| 172 | assert!(f > 0); | ||
| 173 | let timer_f = Self::frequency().0; | ||
| 174 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 175 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); | ||
| 176 | let arr: u32 = unwrap!((pclk_ticks_per_timer_period / (psc as u64 + 1)).try_into()); | ||
| 177 | |||
| 178 | let regs = Self::regs_gp32(); | ||
| 179 | regs.psc().write(|r| r.set_psc(psc)); | ||
| 180 | regs.arr().write(|r| r.set_arr(arr)); | ||
| 181 | 203 | ||
| 182 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | 204 | /// Gneral-purpose 16-bit timer instance. |
| 183 | regs.egr().write(|r| r.set_ug(true)); | 205 | pub trait GeneralPurpose16bitInstance: BasicInstance + GeneralPurpose2ChannelInstance { |
| 184 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | 206 | /// Get access to the general purpose 16bit timer registers. |
| 185 | } | 207 | /// |
| 208 | /// Note: This works even if the timer is more capable, because registers | ||
| 209 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 210 | /// for a given set of capabilities, and having it transparently work with | ||
| 211 | /// more capable timers. | ||
| 212 | fn regs_gp16() -> crate::pac::timer::TimGp16; | ||
| 186 | 213 | ||
| 187 | /// Get timer frequency. | 214 | /// Set counting mode. |
| 188 | fn get_frequency(&self) -> Hertz { | 215 | fn set_counting_mode(&mut self, mode: CountingMode) { |
| 189 | let timer_f = Self::frequency(); | 216 | let (cms, dir) = mode.into(); |
| 190 | 217 | ||
| 191 | let regs = Self::regs_gp32(); | 218 | let timer_enabled = Self::regs_core().cr1().read().cen(); |
| 192 | let arr = regs.arr().read().arr(); | 219 | // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. |
| 193 | let psc = regs.psc().read().psc(); | 220 | // Changing direction is discouraged while the timer is running. |
| 221 | assert!(!timer_enabled); | ||
| 194 | 222 | ||
| 195 | timer_f / arr / (psc + 1) | 223 | Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); |
| 224 | Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) | ||
| 196 | } | 225 | } |
| 197 | } | ||
| 198 | 226 | ||
| 199 | /// Advanced control timer instance. | 227 | /// Get counting mode. |
| 200 | pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { | 228 | fn get_counting_mode(&self) -> CountingMode { |
| 201 | /// Get access to the advanced timer registers. | 229 | let cr1 = Self::regs_gp16().cr1().read(); |
| 202 | fn regs_advanced() -> crate::pac::timer::TimAdv; | 230 | (cr1.cms(), cr1.dir()).into() |
| 203 | } | 231 | } |
| 204 | 232 | ||
| 205 | /// Capture/Compare 16-bit timer instance. | ||
| 206 | pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { | ||
| 207 | /// Set input capture filter. | 233 | /// Set input capture filter. |
| 208 | fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::Icf) { | 234 | fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { |
| 209 | let raw_channel = channel.index(); | 235 | let raw_channel = channel.index(); |
| 210 | Self::regs_gp16() | 236 | Self::regs_gp16() |
| 211 | .ccmr_input(raw_channel / 2) | 237 | .ccmr_input(raw_channel / 2) |
| @@ -256,14 +282,11 @@ pub(crate) mod sealed { | |||
| 256 | }); | 282 | }); |
| 257 | } | 283 | } |
| 258 | 284 | ||
| 259 | /// Enable timer outputs. | ||
| 260 | fn enable_outputs(&mut self); | ||
| 261 | |||
| 262 | /// Set output compare mode. | 285 | /// Set output compare mode. |
| 263 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { | 286 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { |
| 264 | let r = Self::regs_gp16(); | ||
| 265 | let raw_channel: usize = channel.index(); | 287 | let raw_channel: usize = channel.index(); |
| 266 | r.ccmr_output(raw_channel / 2) | 288 | Self::regs_gp16() |
| 289 | .ccmr_output(raw_channel / 2) | ||
| 267 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | 290 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); |
| 268 | } | 291 | } |
| 269 | 292 | ||
| @@ -294,11 +317,6 @@ pub(crate) mod sealed { | |||
| 294 | Self::regs_gp16().ccr(channel.index()).read().ccr() | 317 | Self::regs_gp16().ccr(channel.index()).read().ccr() |
| 295 | } | 318 | } |
| 296 | 319 | ||
| 297 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | ||
| 298 | fn get_max_compare_value(&self) -> u16 { | ||
| 299 | Self::regs_gp16().arr().read().arr() | ||
| 300 | } | ||
| 301 | |||
| 302 | /// Get compare value for a channel. | 320 | /// Get compare value for a channel. |
| 303 | fn get_compare_value(&self, channel: Channel) -> u16 { | 321 | fn get_compare_value(&self, channel: Channel) -> u16 { |
| 304 | Self::regs_gp16().ccr(channel.index()).read().ccr() | 322 | Self::regs_gp16().ccr(channel.index()).read().ccr() |
| @@ -333,35 +351,46 @@ pub(crate) mod sealed { | |||
| 333 | } | 351 | } |
| 334 | } | 352 | } |
| 335 | 353 | ||
| 336 | /// Capture/Compare 16-bit timer instance with complementary pin support. | 354 | #[cfg(not(stm32l0))] |
| 337 | pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + AdvancedControlInstance { | 355 | /// Gneral-purpose 32-bit timer instance. |
| 338 | /// Set complementary output polarity. | 356 | pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { |
| 339 | fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { | 357 | /// Get access to the general purpose 32bit timer registers. |
| 340 | Self::regs_advanced() | 358 | /// |
| 341 | .ccer() | 359 | /// Note: This works even if the timer is more capable, because registers |
| 342 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); | 360 | /// for the less capable timers are a subset. This allows writing a driver |
| 343 | } | 361 | /// for a given set of capabilities, and having it transparently work with |
| 362 | /// more capable timers. | ||
| 363 | fn regs_gp32() -> crate::pac::timer::TimGp32; | ||
| 344 | 364 | ||
| 345 | /// Set clock divider for the dead time. | 365 | /// Set timer frequency. |
| 346 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { | 366 | fn set_frequency(&mut self, frequency: Hertz) { |
| 347 | Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); | 367 | let f = frequency.0; |
| 348 | } | 368 | assert!(f > 0); |
| 369 | let timer_f = Self::frequency().0; | ||
| 370 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 371 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); | ||
| 372 | let arr: u32 = unwrap!((pclk_ticks_per_timer_period / (psc as u64 + 1)).try_into()); | ||
| 349 | 373 | ||
| 350 | /// Set dead time, as a fraction of the max duty value. | 374 | let regs = Self::regs_gp32(); |
| 351 | fn set_dead_time_value(&mut self, value: u8) { | 375 | regs.psc().write(|r| r.set_psc(psc)); |
| 352 | Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value)); | 376 | regs.arr().write(|r| r.set_arr(arr)); |
| 377 | |||
| 378 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | ||
| 379 | regs.egr().write(|r| r.set_ug(true)); | ||
| 380 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | ||
| 353 | } | 381 | } |
| 354 | 382 | ||
| 355 | /// Enable/disable a complementary channel. | 383 | /// Get timer frequency. |
| 356 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { | 384 | fn get_frequency(&self) -> Hertz { |
| 357 | Self::regs_advanced() | 385 | let timer_f = Self::frequency(); |
| 358 | .ccer() | 386 | |
| 359 | .modify(|w| w.set_ccne(channel.index(), enable)); | 387 | let regs = Self::regs_gp32(); |
| 388 | let arr = regs.arr().read().arr(); | ||
| 389 | let psc = regs.psc().read().psc(); | ||
| 390 | |||
| 391 | timer_f / arr / (psc + 1) | ||
| 360 | } | 392 | } |
| 361 | } | ||
| 362 | 393 | ||
| 363 | /// Capture/Compare 32-bit timer instance. | ||
| 364 | pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance + CaptureCompare16bitInstance { | ||
| 365 | /// Set comapre value for a channel. | 394 | /// Set comapre value for a channel. |
| 366 | fn set_compare_value(&mut self, channel: Channel, value: u32) { | 395 | fn set_compare_value(&mut self, channel: Channel, value: u32) { |
| 367 | Self::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(value)); | 396 | Self::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(value)); |
| @@ -382,6 +411,70 @@ pub(crate) mod sealed { | |||
| 382 | Self::regs_gp32().ccr(channel.index()).read().ccr() | 411 | Self::regs_gp32().ccr(channel.index()).read().ccr() |
| 383 | } | 412 | } |
| 384 | } | 413 | } |
| 414 | |||
| 415 | #[cfg(not(stm32l0))] | ||
| 416 | /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. | ||
| 417 | pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance { | ||
| 418 | /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. | ||
| 419 | /// | ||
| 420 | /// Note: This works even if the timer is more capable, because registers | ||
| 421 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 422 | /// for a given set of capabilities, and having it transparently work with | ||
| 423 | /// more capable timers. | ||
| 424 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; | ||
| 425 | |||
| 426 | /// Set clock divider for the dead time. | ||
| 427 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { | ||
| 428 | Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); | ||
| 429 | } | ||
| 430 | |||
| 431 | /// Set dead time, as a fraction of the max duty value. | ||
| 432 | fn set_dead_time_value(&mut self, value: u8) { | ||
| 433 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); | ||
| 434 | } | ||
| 435 | |||
| 436 | /// Enable timer outputs. | ||
| 437 | fn enable_outputs(&mut self) { | ||
| 438 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 442 | #[cfg(not(stm32l0))] | ||
| 443 | /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. | ||
| 444 | pub trait GeneralPurpose2ChannelComplementaryInstance: | ||
| 445 | BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance | ||
| 446 | { | ||
| 447 | /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. | ||
| 448 | /// | ||
| 449 | /// Note: This works even if the timer is more capable, because registers | ||
| 450 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 451 | /// for a given set of capabilities, and having it transparently work with | ||
| 452 | /// more capable timers. | ||
| 453 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; | ||
| 454 | } | ||
| 455 | |||
| 456 | #[cfg(not(stm32l0))] | ||
| 457 | /// Advanced control timer instance. | ||
| 458 | pub trait AdvancedControlInstance: | ||
| 459 | GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance | ||
| 460 | { | ||
| 461 | /// Get access to the advanced timer registers. | ||
| 462 | fn regs_advanced() -> crate::pac::timer::TimAdv; | ||
| 463 | |||
| 464 | /// Set complementary output polarity. | ||
| 465 | fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { | ||
| 466 | Self::regs_advanced() | ||
| 467 | .ccer() | ||
| 468 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); | ||
| 469 | } | ||
| 470 | |||
| 471 | /// Enable/disable a complementary channel. | ||
| 472 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { | ||
| 473 | Self::regs_advanced() | ||
| 474 | .ccer() | ||
| 475 | .modify(|w| w.set_ccne(channel.index(), enable)); | ||
| 476 | } | ||
| 477 | } | ||
| 385 | } | 478 | } |
| 386 | 479 | ||
| 387 | /// Timer channel. | 480 | /// Timer channel. |
| @@ -572,156 +665,281 @@ impl From<OutputPolarity> for bool { | |||
| 572 | } | 665 | } |
| 573 | 666 | ||
| 574 | /// Basic 16-bit timer instance. | 667 | /// Basic 16-bit timer instance. |
| 575 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | 668 | pub trait BasicInstance: sealed::BasicInstance + sealed::BasicNoCr2Instance + sealed::CoreInstance + 'static {} |
| 576 | 669 | ||
| 577 | /// Gneral-purpose 16-bit timer instance. | 670 | // It's just a General-purpose 16-bit timer instance. |
| 578 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + Basic16bitInstance + 'static {} | 671 | /// Capture Compare timer instance. |
| 579 | |||
| 580 | /// Gneral-purpose 32-bit timer instance. | ||
| 581 | pub trait GeneralPurpose32bitInstance: | ||
| 582 | sealed::GeneralPurpose32bitInstance + GeneralPurpose16bitInstance + 'static | ||
| 583 | { | ||
| 584 | } | ||
| 585 | |||
| 586 | /// Advanced control timer instance. | ||
| 587 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + GeneralPurpose16bitInstance + 'static {} | ||
| 588 | |||
| 589 | /// Capture/Compare 16-bit timer instance. | ||
| 590 | pub trait CaptureCompare16bitInstance: | 672 | pub trait CaptureCompare16bitInstance: |
| 591 | sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static | 673 | BasicInstance |
| 674 | + sealed::GeneralPurpose2ChannelInstance | ||
| 675 | + sealed::GeneralPurpose1ChannelInstance | ||
| 676 | + sealed::GeneralPurpose16bitInstance | ||
| 677 | + 'static | ||
| 592 | { | 678 | { |
| 593 | } | 679 | } |
| 594 | 680 | ||
| 595 | /// Capture/Compare 16-bit timer instance with complementary pin support. | 681 | #[cfg(not(stm32l0))] |
| 596 | pub trait ComplementaryCaptureCompare16bitInstance: | 682 | // It's just a General-purpose 32-bit timer instance. |
| 597 | sealed::ComplementaryCaptureCompare16bitInstance + CaptureCompare16bitInstance + AdvancedControlInstance + 'static | 683 | /// Capture Compare 32-bit timer instance. |
| 684 | pub trait CaptureCompare32bitInstance: | ||
| 685 | CaptureCompare16bitInstance + sealed::GeneralPurpose32bitInstance + 'static | ||
| 598 | { | 686 | { |
| 599 | } | 687 | } |
| 600 | 688 | ||
| 601 | /// Capture/Compare 32-bit timer instance. | 689 | #[cfg(not(stm32l0))] |
| 602 | pub trait CaptureCompare32bitInstance: | 690 | // It's just a Advanced Control timer instance. |
| 603 | sealed::CaptureCompare32bitInstance + CaptureCompare16bitInstance + GeneralPurpose32bitInstance + 'static | 691 | /// Complementary Capture Compare 32-bit timer instance. |
| 692 | pub trait ComplementaryCaptureCompare16bitInstance: | ||
| 693 | CaptureCompare16bitInstance | ||
| 694 | + sealed::GeneralPurpose1ChannelComplementaryInstance | ||
| 695 | + sealed::GeneralPurpose2ChannelComplementaryInstance | ||
| 696 | + sealed::AdvancedControlInstance | ||
| 697 | + 'static | ||
| 604 | { | 698 | { |
| 605 | } | 699 | } |
| 606 | 700 | ||
| 607 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | 701 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); |
| 608 | pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance); | ||
| 609 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | 702 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); |
| 610 | pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance); | ||
| 611 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | 703 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); |
| 612 | pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance); | ||
| 613 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | 704 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); |
| 614 | pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance); | ||
| 615 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | 705 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); |
| 616 | pin_trait!(BreakInputPin, CaptureCompare16bitInstance); | 706 | |
| 617 | pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance); | 707 | cfg_if::cfg_if! { |
| 618 | pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance); | 708 | if #[cfg(not(stm32l0))] { |
| 619 | pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); | 709 | pin_trait!(Channel1ComplementaryPin, ComplementaryCaptureCompare16bitInstance); |
| 620 | pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | 710 | pin_trait!(Channel2ComplementaryPin, ComplementaryCaptureCompare16bitInstance); |
| 621 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); | 711 | pin_trait!(Channel3ComplementaryPin, ComplementaryCaptureCompare16bitInstance); |
| 712 | pin_trait!(Channel4ComplementaryPin, ComplementaryCaptureCompare16bitInstance); | ||
| 713 | |||
| 714 | pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance); | ||
| 715 | pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 716 | |||
| 717 | pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 718 | pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 719 | |||
| 720 | pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 721 | pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 722 | } | ||
| 723 | } | ||
| 622 | 724 | ||
| 623 | #[allow(unused)] | 725 | #[allow(unused)] |
| 624 | macro_rules! impl_basic_16bit_timer { | 726 | macro_rules! impl_core_timer { |
| 625 | ($inst:ident, $irq:ident) => { | 727 | ($inst:ident, $irq:ident) => { |
| 626 | impl sealed::Basic16bitInstance for crate::peripherals::$inst { | 728 | impl sealed::CoreInstance for crate::peripherals::$inst { |
| 627 | type Interrupt = crate::interrupt::typelevel::$irq; | 729 | type Interrupt = crate::interrupt::typelevel::$irq; |
| 628 | 730 | ||
| 629 | fn regs() -> crate::pac::timer::TimBasic { | 731 | fn regs_core() -> crate::pac::timer::TimCore { |
| 630 | unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } | 732 | unsafe { crate::pac::timer::TimCore::from_ptr(crate::pac::$inst.as_ptr()) } |
| 631 | } | 733 | } |
| 632 | } | 734 | } |
| 633 | }; | 735 | }; |
| 634 | } | 736 | } |
| 635 | 737 | ||
| 636 | #[allow(unused)] | 738 | #[allow(unused)] |
| 637 | macro_rules! impl_32bit_timer { | 739 | macro_rules! impl_basic_no_cr2_timer { |
| 638 | ($inst:ident) => { | 740 | ($inst:ident) => { |
| 639 | impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { | 741 | impl sealed::BasicNoCr2Instance for crate::peripherals::$inst { |
| 640 | fn regs_gp32() -> crate::pac::timer::TimGp32 { | 742 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2 { |
| 641 | crate::pac::$inst | 743 | unsafe { crate::pac::timer::TimBasicNoCr2::from_ptr(crate::pac::$inst.as_ptr()) } |
| 642 | } | 744 | } |
| 643 | } | 745 | } |
| 644 | }; | 746 | }; |
| 645 | } | 747 | } |
| 646 | 748 | ||
| 647 | #[allow(unused)] | 749 | #[allow(unused)] |
| 648 | macro_rules! impl_compare_capable_16bit { | 750 | macro_rules! impl_basic_timer { |
| 649 | ($inst:ident) => { | 751 | ($inst:ident) => { |
| 650 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | 752 | impl sealed::BasicInstance for crate::peripherals::$inst { |
| 651 | fn enable_outputs(&mut self) {} | 753 | fn regs_basic() -> crate::pac::timer::TimBasic { |
| 754 | unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 755 | } | ||
| 652 | } | 756 | } |
| 653 | }; | 757 | }; |
| 654 | } | 758 | } |
| 655 | 759 | ||
| 656 | foreach_interrupt! { | 760 | #[allow(unused)] |
| 657 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | 761 | macro_rules! impl_1ch_timer { |
| 658 | impl_basic_16bit_timer!($inst, $irq); | 762 | ($inst:ident) => { |
| 659 | impl Basic16bitInstance for crate::peripherals::$inst {} | 763 | impl sealed::GeneralPurpose1ChannelInstance for crate::peripherals::$inst { |
| 764 | fn regs_1ch() -> crate::pac::timer::Tim1ch { | ||
| 765 | unsafe { crate::pac::timer::Tim1ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 766 | } | ||
| 767 | } | ||
| 660 | }; | 768 | }; |
| 661 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | 769 | } |
| 662 | impl_basic_16bit_timer!($inst, $irq); | ||
| 663 | impl_compare_capable_16bit!($inst); | ||
| 664 | impl Basic16bitInstance for crate::peripherals::$inst {} | ||
| 665 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | ||
| 666 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 667 | 770 | ||
| 668 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 771 | #[allow(unused)] |
| 669 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 772 | macro_rules! impl_2ch_timer { |
| 670 | crate::pac::$inst | 773 | ($inst:ident) => { |
| 774 | impl sealed::GeneralPurpose2ChannelInstance for crate::peripherals::$inst { | ||
| 775 | fn regs_2ch() -> crate::pac::timer::Tim2ch { | ||
| 776 | unsafe { crate::pac::timer::Tim2ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 671 | } | 777 | } |
| 672 | } | 778 | } |
| 673 | }; | 779 | }; |
| 780 | } | ||
| 674 | 781 | ||
| 675 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | 782 | #[allow(unused)] |
| 676 | impl_basic_16bit_timer!($inst, $irq); | 783 | macro_rules! impl_gp16_timer { |
| 677 | impl_32bit_timer!($inst); | 784 | ($inst:ident) => { |
| 678 | impl_compare_capable_16bit!($inst); | ||
| 679 | impl Basic16bitInstance for crate::peripherals::$inst {} | ||
| 680 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 681 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} | ||
| 682 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | ||
| 683 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} | ||
| 684 | impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} | ||
| 685 | |||
| 686 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 785 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { |
| 687 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 786 | fn regs_gp16() -> crate::pac::timer::TimGp16 { |
| 688 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | 787 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } |
| 689 | } | 788 | } |
| 690 | } | 789 | } |
| 691 | }; | 790 | }; |
| 791 | } | ||
| 692 | 792 | ||
| 693 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | 793 | #[allow(unused)] |
| 694 | impl_basic_16bit_timer!($inst, $irq); | 794 | macro_rules! impl_gp32_timer { |
| 795 | ($inst:ident) => { | ||
| 796 | impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { | ||
| 797 | fn regs_gp32() -> crate::pac::timer::TimGp32 { | ||
| 798 | crate::pac::$inst | ||
| 799 | } | ||
| 800 | } | ||
| 801 | }; | ||
| 802 | } | ||
| 695 | 803 | ||
| 696 | impl Basic16bitInstance for crate::peripherals::$inst {} | 804 | #[allow(unused)] |
| 697 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | 805 | macro_rules! impl_1ch_cmp_timer { |
| 698 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 806 | ($inst:ident) => { |
| 699 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | 807 | impl sealed::GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst { |
| 700 | impl AdvancedControlInstance for crate::peripherals::$inst {} | 808 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp { |
| 701 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | 809 | unsafe { crate::pac::timer::Tim1chCmp::from_ptr(crate::pac::$inst.as_ptr()) } |
| 702 | fn enable_outputs(&mut self) { | ||
| 703 | use crate::timer::sealed::AdvancedControlInstance; | ||
| 704 | let r = Self::regs_advanced(); | ||
| 705 | r.bdtr().modify(|w| w.set_moe(true)); | ||
| 706 | } | 810 | } |
| 707 | } | 811 | } |
| 708 | impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | 812 | }; |
| 709 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 813 | } |
| 710 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 814 | |
| 711 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | 815 | #[allow(unused)] |
| 816 | macro_rules! impl_2ch_cmp_timer { | ||
| 817 | ($inst:ident) => { | ||
| 818 | impl sealed::GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst { | ||
| 819 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp { | ||
| 820 | unsafe { crate::pac::timer::Tim2chCmp::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 712 | } | 821 | } |
| 713 | } | 822 | } |
| 823 | }; | ||
| 824 | } | ||
| 714 | 825 | ||
| 826 | #[allow(unused)] | ||
| 827 | macro_rules! impl_adv_timer { | ||
| 828 | ($inst:ident) => { | ||
| 715 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { | 829 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { |
| 716 | fn regs_advanced() -> crate::pac::timer::TimAdv { | 830 | fn regs_advanced() -> crate::pac::timer::TimAdv { |
| 717 | crate::pac::$inst | 831 | unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) } |
| 718 | } | 832 | } |
| 719 | } | 833 | } |
| 720 | }; | 834 | }; |
| 721 | } | 835 | } |
| 722 | 836 | ||
| 837 | foreach_interrupt! { | ||
| 838 | |||
| 839 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | ||
| 840 | impl_core_timer!($inst, $irq); | ||
| 841 | impl_basic_no_cr2_timer!($inst); | ||
| 842 | impl_basic_timer!($inst); | ||
| 843 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 844 | }; | ||
| 845 | |||
| 846 | ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { | ||
| 847 | impl_core_timer!($inst, $irq); | ||
| 848 | impl_basic_no_cr2_timer!($inst); | ||
| 849 | impl_basic_timer!($inst); | ||
| 850 | impl_1ch_timer!($inst); | ||
| 851 | impl_2ch_timer!($inst); | ||
| 852 | impl_gp16_timer!($inst); | ||
| 853 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 854 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 855 | }; | ||
| 856 | |||
| 857 | |||
| 858 | ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { | ||
| 859 | impl_core_timer!($inst, $irq); | ||
| 860 | impl_basic_no_cr2_timer!($inst); | ||
| 861 | impl_basic_timer!($inst); | ||
| 862 | impl_1ch_timer!($inst); | ||
| 863 | impl_2ch_timer!($inst); | ||
| 864 | impl_gp16_timer!($inst); | ||
| 865 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 866 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 867 | }; | ||
| 868 | |||
| 869 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | ||
| 870 | impl_core_timer!($inst, $irq); | ||
| 871 | impl_basic_no_cr2_timer!($inst); | ||
| 872 | impl_basic_timer!($inst); | ||
| 873 | impl_1ch_timer!($inst); | ||
| 874 | impl_2ch_timer!($inst); | ||
| 875 | impl_gp16_timer!($inst); | ||
| 876 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 877 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 878 | }; | ||
| 879 | |||
| 880 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | ||
| 881 | impl_core_timer!($inst, $irq); | ||
| 882 | impl_basic_no_cr2_timer!($inst); | ||
| 883 | impl_basic_timer!($inst); | ||
| 884 | impl_1ch_timer!($inst); | ||
| 885 | impl_2ch_timer!($inst); | ||
| 886 | impl_gp16_timer!($inst); | ||
| 887 | impl_gp32_timer!($inst); | ||
| 888 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 889 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 890 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} | ||
| 891 | }; | ||
| 892 | |||
| 893 | ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { | ||
| 894 | impl_core_timer!($inst, $irq); | ||
| 895 | impl_basic_no_cr2_timer!($inst); | ||
| 896 | impl_basic_timer!($inst); | ||
| 897 | impl_1ch_timer!($inst); | ||
| 898 | impl_2ch_timer!($inst); | ||
| 899 | impl_gp16_timer!($inst); | ||
| 900 | impl_1ch_cmp_timer!($inst); | ||
| 901 | impl_2ch_cmp_timer!($inst); | ||
| 902 | impl_adv_timer!($inst); | ||
| 903 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 904 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 905 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 906 | }; | ||
| 907 | |||
| 908 | |||
| 909 | ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { | ||
| 910 | impl_core_timer!($inst, $irq); | ||
| 911 | impl_basic_no_cr2_timer!($inst); | ||
| 912 | impl_basic_timer!($inst); | ||
| 913 | impl_1ch_timer!($inst); | ||
| 914 | impl_2ch_timer!($inst); | ||
| 915 | impl_gp16_timer!($inst); | ||
| 916 | impl_1ch_cmp_timer!($inst); | ||
| 917 | impl_2ch_cmp_timer!($inst); | ||
| 918 | impl_adv_timer!($inst); | ||
| 919 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 920 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 921 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 922 | }; | ||
| 923 | |||
| 924 | |||
| 925 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | ||
| 926 | impl_core_timer!($inst, $irq); | ||
| 927 | impl_basic_no_cr2_timer!($inst); | ||
| 928 | impl_basic_timer!($inst); | ||
| 929 | impl_1ch_timer!($inst); | ||
| 930 | impl_2ch_timer!($inst); | ||
| 931 | impl_gp16_timer!($inst); | ||
| 932 | impl_1ch_cmp_timer!($inst); | ||
| 933 | impl_2ch_cmp_timer!($inst); | ||
| 934 | impl_adv_timer!($inst); | ||
| 935 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 936 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 937 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 938 | }; | ||
| 939 | } | ||
| 940 | |||
| 723 | // Update Event trigger DMA for every timer | 941 | // Update Event trigger DMA for every timer |
| 724 | dma_trait!(UpDma, Basic16bitInstance); | 942 | dma_trait!(UpDma, BasicInstance); |
| 725 | 943 | ||
| 726 | dma_trait!(Ch1Dma, CaptureCompare16bitInstance); | 944 | dma_trait!(Ch1Dma, CaptureCompare16bitInstance); |
| 727 | dma_trait!(Ch2Dma, CaptureCompare16bitInstance); | 945 | dma_trait!(Ch2Dma, CaptureCompare16bitInstance); |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 0b4c1225f..1acba504e 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -84,13 +84,12 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 84 | this.set_frequency(freq); | 84 | this.set_frequency(freq); |
| 85 | this.inner.start(); | 85 | this.inner.start(); |
| 86 | 86 | ||
| 87 | this.inner.enable_outputs(); | ||
| 88 | |||
| 89 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] | 87 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] |
| 90 | .iter() | 88 | .iter() |
| 91 | .for_each(|&channel| { | 89 | .for_each(|&channel| { |
| 92 | this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); | 90 | this.inner.set_output_compare_mode(channel, OutputCompareMode::PwmMode1); |
| 93 | this.inner.set_output_compare_preload(channel, true) | 91 | |
| 92 | this.inner.set_output_compare_preload(channel, true); | ||
| 94 | }); | 93 | }); |
| 95 | 94 | ||
| 96 | this | 95 | this |
| @@ -202,7 +201,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 202 | &mut dma, | 201 | &mut dma, |
| 203 | req, | 202 | req, |
| 204 | duty, | 203 | duty, |
| 205 | T::regs_gp16().ccr(channel.index()).as_ptr() as *mut _, | 204 | T::regs_1ch().ccr(channel.index()).as_ptr() as *mut _, |
| 206 | dma_transfer_option, | 205 | dma_transfer_option, |
| 207 | ) | 206 | ) |
| 208 | .await | 207 | .await |
