diff options
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/time_driver.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/mod.rs | 514 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/qei.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 6 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/dac_dma.rs | 14 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/dac_dma.rs | 14 |
8 files changed, 427 insertions, 137 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 61d70b732..c6bc27f89 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -68,7 +68,7 @@ rand_core = "0.6.3" | |||
| 68 | sdio-host = "0.5.0" | 68 | sdio-host = "0.5.0" |
| 69 | critical-section = "1.1" | 69 | critical-section = "1.1" |
| 70 | #stm32-metapac = { version = "15" } | 70 | #stm32-metapac = { version = "15" } |
| 71 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786" } | 71 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", rev = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df" } |
| 72 | vcell = "0.1.3" | 72 | vcell = "0.1.3" |
| 73 | bxcan = "0.7.0" | 73 | bxcan = "0.7.0" |
| 74 | nb = "1.0.0" | 74 | nb = "1.0.0" |
| @@ -89,7 +89,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 89 | proc-macro2 = "1.0.36" | 89 | proc-macro2 = "1.0.36" |
| 90 | quote = "1.0.15" | 90 | quote = "1.0.15" |
| 91 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 91 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 92 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786", default-features = false, features = ["metadata"]} | 92 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-028efe4e6e0719b661cbdf8ffda3341e4d63d0df", default-features = false, features = ["metadata"]} |
| 93 | 93 | ||
| 94 | 94 | ||
| 95 | [features] | 95 | [features] |
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 320b29ddb..29ff4a736 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -14,7 +14,7 @@ use crate::pac::timer::vals; | |||
| 14 | use crate::rcc::sealed::RccPeripheral; | 14 | use crate::rcc::sealed::RccPeripheral; |
| 15 | #[cfg(feature = "low-power")] | 15 | #[cfg(feature = "low-power")] |
| 16 | use crate::rtc::Rtc; | 16 | use crate::rtc::Rtc; |
| 17 | use crate::timer::sealed::{Basic16bitInstance as BasicInstance, GeneralPurpose16bitInstance as Instance}; | 17 | use crate::timer::sealed::{CoreInstance, GeneralPurpose16bitInstance as Instance}; |
| 18 | use crate::{interrupt, peripherals}; | 18 | use crate::{interrupt, peripherals}; |
| 19 | 19 | ||
| 20 | // NOTE regarding ALARM_COUNT: | 20 | // NOTE regarding ALARM_COUNT: |
| @@ -234,8 +234,8 @@ impl RtcDriver { | |||
| 234 | w.set_ccie(0, true); | 234 | w.set_ccie(0, true); |
| 235 | }); | 235 | }); |
| 236 | 236 | ||
| 237 | <T as BasicInstance>::Interrupt::unpend(); | 237 | <T as CoreInstance>::Interrupt::unpend(); |
| 238 | unsafe { <T as BasicInstance>::Interrupt::enable() }; | 238 | unsafe { <T as CoreInstance>::Interrupt::enable() }; |
| 239 | 239 | ||
| 240 | r.cr1().modify(|w| w.set_cen(true)); | 240 | r.cr1().modify(|w| w.set_cen(true)); |
| 241 | } | 241 | } |
| @@ -251,7 +251,7 @@ impl RtcDriver { | |||
| 251 | // Clear all interrupt flags. Bits in SR are "write 0 to clear", so write the bitwise NOT. | 251 | // Clear all interrupt flags. Bits in SR are "write 0 to clear", so write the bitwise NOT. |
| 252 | // Other approaches such as writing all zeros, or RMWing won't work, they can | 252 | // Other approaches such as writing all zeros, or RMWing won't work, they can |
| 253 | // miss interrupts. | 253 | // miss interrupts. |
| 254 | r.sr().write_value(regs::SrGp(!sr.0)); | 254 | r.sr().write_value(regs::SrGp16(!sr.0)); |
| 255 | 255 | ||
| 256 | // Overflow | 256 | // Overflow |
| 257 | if sr.uif() { | 257 | if sr.uif() { |
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index eddce0404..0470e3048 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -52,7 +52,7 @@ pub struct ComplementaryPwm<'d, T> { | |||
| 52 | inner: PeripheralRef<'d, T>, | 52 | inner: PeripheralRef<'d, T>, |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | 55 | impl<'d, T: GeneralPurpose16bitInstance + ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { |
| 56 | /// Create a new complementary PWM driver. | 56 | /// Create a new complementary PWM driver. |
| 57 | #[allow(clippy::too_many_arguments)] | 57 | #[allow(clippy::too_many_arguments)] |
| 58 | pub fn new( | 58 | pub fn new( |
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 210bf7153..f66b4d094 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -1,5 +1,19 @@ | |||
| 1 | //! Timers, PWM, quadrature decoder. | 1 | //! Timers, PWM, quadrature decoder. |
| 2 | 2 | ||
| 3 | // Timer inheritance | ||
| 4 | // | ||
| 5 | // CaptureCompare16bitInstance ComplementaryCaptureCompare16bitInstance | ||
| 6 | // v v | ||
| 7 | // Core -------------------------> 1CH -------------------------> 1CH_CMP | ||
| 8 | // | | ^ | | ||
| 9 | // +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV | ||
| 10 | // | | | ^ | | ^ ^ | ||
| 11 | // | | +------|--|--------------|-----------+ | | ||
| 12 | // | +--------------------+ +--------------|-----------|---------+ | ||
| 13 | // | | | | | ||
| 14 | // | +--------------------------------------|-----------+ | ||
| 15 | // +----------------------------------------------------+ | ||
| 16 | |||
| 3 | pub mod complementary_pwm; | 17 | pub mod complementary_pwm; |
| 4 | pub mod qei; | 18 | pub mod qei; |
| 5 | pub mod simple_pwm; | 19 | pub mod simple_pwm; |
| @@ -19,32 +33,32 @@ pub mod low_level { | |||
| 19 | pub(crate) mod sealed { | 33 | pub(crate) mod sealed { |
| 20 | use super::*; | 34 | use super::*; |
| 21 | 35 | ||
| 22 | /// Basic 16-bit timer instance. | 36 | /// Virtual Core 16-bit timer instance. |
| 23 | pub trait Basic16bitInstance: RccPeripheral { | 37 | pub trait CoreInstance: RccPeripheral { |
| 24 | /// Interrupt for this timer. | 38 | /// Interrupt for this timer. |
| 25 | type Interrupt: interrupt::typelevel::Interrupt; | 39 | type Interrupt: interrupt::typelevel::Interrupt; |
| 26 | 40 | ||
| 27 | /// Get access to the basic 16bit timer registers. | 41 | /// Get access to the virutal core 16bit timer registers. |
| 28 | /// | 42 | /// |
| 29 | /// Note: This works even if the timer is more capable, because registers | 43 | /// 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 | 44 | /// 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 | 45 | /// for a given set of capabilities, and having it transparently work with |
| 32 | /// more capable timers. | 46 | /// more capable timers. |
| 33 | fn regs() -> crate::pac::timer::TimBasic; | 47 | fn regs_core() -> crate::pac::timer::TimCore; |
| 34 | 48 | ||
| 35 | /// Start the timer. | 49 | /// Start the timer. |
| 36 | fn start(&mut self) { | 50 | fn start(&mut self) { |
| 37 | Self::regs().cr1().modify(|r| r.set_cen(true)); | 51 | Self::regs_core().cr1().modify(|r| r.set_cen(true)); |
| 38 | } | 52 | } |
| 39 | 53 | ||
| 40 | /// Stop the timer. | 54 | /// Stop the timer. |
| 41 | fn stop(&mut self) { | 55 | fn stop(&mut self) { |
| 42 | Self::regs().cr1().modify(|r| r.set_cen(false)); | 56 | Self::regs_core().cr1().modify(|r| r.set_cen(false)); |
| 43 | } | 57 | } |
| 44 | 58 | ||
| 45 | /// Reset the counter value to 0 | 59 | /// Reset the counter value to 0 |
| 46 | fn reset(&mut self) { | 60 | fn reset(&mut self) { |
| 47 | Self::regs().cnt().write(|r| r.set_cnt(0)); | 61 | Self::regs_core().cnt().write(|r| r.set_cnt(0)); |
| 48 | } | 62 | } |
| 49 | 63 | ||
| 50 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. | 64 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. |
| @@ -64,7 +78,7 @@ pub(crate) mod sealed { | |||
| 64 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | 78 | // the timer counts `0..=arr`, we want it to count `0..divide_by` |
| 65 | let arr = unwrap!(u16::try_from(divide_by - 1)); | 79 | let arr = unwrap!(u16::try_from(divide_by - 1)); |
| 66 | 80 | ||
| 67 | let regs = Self::regs(); | 81 | let regs = Self::regs_core(); |
| 68 | regs.psc().write(|r| r.set_psc(psc)); | 82 | regs.psc().write(|r| r.set_psc(psc)); |
| 69 | regs.arr().write(|r| r.set_arr(arr)); | 83 | regs.arr().write(|r| r.set_arr(arr)); |
| 70 | 84 | ||
| @@ -77,7 +91,7 @@ pub(crate) mod sealed { | |||
| 77 | /// | 91 | /// |
| 78 | /// Returns whether the update interrupt flag was set. | 92 | /// Returns whether the update interrupt flag was set. |
| 79 | fn clear_update_interrupt(&mut self) -> bool { | 93 | fn clear_update_interrupt(&mut self) -> bool { |
| 80 | let regs = Self::regs(); | 94 | let regs = Self::regs_core(); |
| 81 | let sr = regs.sr().read(); | 95 | let sr = regs.sr().read(); |
| 82 | if sr.uif() { | 96 | if sr.uif() { |
| 83 | regs.sr().modify(|r| { | 97 | regs.sr().modify(|r| { |
| @@ -91,29 +105,19 @@ pub(crate) mod sealed { | |||
| 91 | 105 | ||
| 92 | /// Enable/disable the update interrupt. | 106 | /// Enable/disable the update interrupt. |
| 93 | fn enable_update_interrupt(&mut self, enable: bool) { | 107 | fn enable_update_interrupt(&mut self, enable: bool) { |
| 94 | Self::regs().dier().modify(|r| r.set_uie(enable)); | 108 | 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 | } | 109 | } |
| 106 | 110 | ||
| 107 | /// Enable/disable autoreload preload. | 111 | /// Enable/disable autoreload preload. |
| 108 | fn set_autoreload_preload(&mut self, enable: bool) { | 112 | fn set_autoreload_preload(&mut self, enable: bool) { |
| 109 | Self::regs().cr1().modify(|r| r.set_arpe(enable)); | 113 | Self::regs_core().cr1().modify(|r| r.set_arpe(enable)); |
| 110 | } | 114 | } |
| 111 | 115 | ||
| 112 | /// Get the timer frequency. | 116 | /// Get the timer frequency. |
| 113 | fn get_frequency(&self) -> Hertz { | 117 | fn get_frequency(&self) -> Hertz { |
| 114 | let timer_f = Self::frequency(); | 118 | let timer_f = Self::frequency(); |
| 115 | 119 | ||
| 116 | let regs = Self::regs(); | 120 | let regs = Self::regs_core(); |
| 117 | let arr = regs.arr().read().arr(); | 121 | let arr = regs.arr().read().arr(); |
| 118 | let psc = regs.psc().read().psc(); | 122 | let psc = regs.psc().read().psc(); |
| 119 | 123 | ||
| @@ -121,8 +125,67 @@ pub(crate) mod sealed { | |||
| 121 | } | 125 | } |
| 122 | } | 126 | } |
| 123 | 127 | ||
| 128 | /// Virtual Basic without CR2 16-bit timer instance. | ||
| 129 | pub trait BasicNoCr2Instance: CoreInstance { | ||
| 130 | /// Get access to the Baisc 16bit timer registers. | ||
| 131 | /// | ||
| 132 | /// Note: This works even if the timer is more capable, because registers | ||
| 133 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 134 | /// for a given set of capabilities, and having it transparently work with | ||
| 135 | /// more capable timers. | ||
| 136 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2; | ||
| 137 | |||
| 138 | /// Enable/disable the update dma. | ||
| 139 | fn enable_update_dma(&mut self, enable: bool) { | ||
| 140 | Self::regs_basic_no_cr2().dier().modify(|r| r.set_ude(enable)); | ||
| 141 | } | ||
| 142 | |||
| 143 | /// Get the update dma enable/disable state. | ||
| 144 | fn get_update_dma_state(&self) -> bool { | ||
| 145 | Self::regs_basic_no_cr2().dier().read().ude() | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | /// Basic 16-bit timer instance. | ||
| 150 | pub trait BasicInstance: BasicNoCr2Instance { | ||
| 151 | /// Get access to the Baisc 16bit timer registers. | ||
| 152 | /// | ||
| 153 | /// Note: This works even if the timer is more capable, because registers | ||
| 154 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 155 | /// for a given set of capabilities, and having it transparently work with | ||
| 156 | /// more capable timers. | ||
| 157 | fn regs_basic() -> crate::pac::timer::TimBasic; | ||
| 158 | } | ||
| 159 | |||
| 160 | /// Gneral-purpose 1 channel 16-bit timer instance. | ||
| 161 | pub trait GeneralPurpose1ChannelInstance: CoreInstance { | ||
| 162 | /// Get access to the general purpose 1 channel 16bit timer registers. | ||
| 163 | /// | ||
| 164 | /// Note: This works even if the timer is more capable, because registers | ||
| 165 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 166 | /// for a given set of capabilities, and having it transparently work with | ||
| 167 | /// more capable timers. | ||
| 168 | fn regs_1ch() -> crate::pac::timer::Tim1ch; | ||
| 169 | |||
| 170 | /// Set clock divider. | ||
| 171 | fn set_clock_division(&mut self, ckd: vals::Ckd) { | ||
| 172 | Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | /// Gneral-purpose 1 channel 16-bit timer instance. | ||
| 177 | pub trait GeneralPurpose2ChannelInstance: GeneralPurpose1ChannelInstance { | ||
| 178 | /// Get access to the general purpose 2 channel 16bit timer registers. | ||
| 179 | /// | ||
| 180 | /// Note: This works even if the timer is more capable, because registers | ||
| 181 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 182 | /// for a given set of capabilities, and having it transparently work with | ||
| 183 | /// more capable timers. | ||
| 184 | fn regs_2ch() -> crate::pac::timer::Tim2ch; | ||
| 185 | } | ||
| 186 | |||
| 124 | /// Gneral-purpose 16-bit timer instance. | 187 | /// Gneral-purpose 16-bit timer instance. |
| 125 | pub trait GeneralPurpose16bitInstance: Basic16bitInstance { | 188 | pub trait GeneralPurpose16bitInstance: BasicInstance + GeneralPurpose2ChannelInstance { |
| 126 | /// Get access to the general purpose 16bit timer registers. | 189 | /// Get access to the general purpose 16bit timer registers. |
| 127 | /// | 190 | /// |
| 128 | /// Note: This works even if the timer is more capable, because registers | 191 | /// Note: This works even if the timer is more capable, because registers |
| @@ -135,7 +198,7 @@ pub(crate) mod sealed { | |||
| 135 | fn set_counting_mode(&mut self, mode: CountingMode) { | 198 | fn set_counting_mode(&mut self, mode: CountingMode) { |
| 136 | let (cms, dir) = mode.into(); | 199 | let (cms, dir) = mode.into(); |
| 137 | 200 | ||
| 138 | let timer_enabled = Self::regs().cr1().read().cen(); | 201 | let timer_enabled = Self::regs_core().cr1().read().cen(); |
| 139 | // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. | 202 | // 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. | 203 | // Changing direction is discouraged while the timer is running. |
| 141 | assert!(!timer_enabled); | 204 | assert!(!timer_enabled); |
| @@ -149,11 +212,6 @@ pub(crate) mod sealed { | |||
| 149 | let cr1 = Self::regs_gp16().cr1().read(); | 212 | let cr1 = Self::regs_gp16().cr1().read(); |
| 150 | (cr1.cms(), cr1.dir()).into() | 213 | (cr1.cms(), cr1.dir()).into() |
| 151 | } | 214 | } |
| 152 | |||
| 153 | /// Set clock divider. | ||
| 154 | fn set_clock_division(&mut self, ckd: vals::Ckd) { | ||
| 155 | Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd)); | ||
| 156 | } | ||
| 157 | } | 215 | } |
| 158 | 216 | ||
| 159 | /// Gneral-purpose 32-bit timer instance. | 217 | /// Gneral-purpose 32-bit timer instance. |
| @@ -196,36 +254,67 @@ pub(crate) mod sealed { | |||
| 196 | } | 254 | } |
| 197 | } | 255 | } |
| 198 | 256 | ||
| 257 | /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. | ||
| 258 | pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance { | ||
| 259 | /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. | ||
| 260 | /// | ||
| 261 | /// Note: This works even if the timer is more capable, because registers | ||
| 262 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 263 | /// for a given set of capabilities, and having it transparently work with | ||
| 264 | /// more capable timers. | ||
| 265 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; | ||
| 266 | |||
| 267 | /// Enable timer outputs. | ||
| 268 | fn enable_outputs(&mut self) { | ||
| 269 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(true)); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. | ||
| 274 | pub trait GeneralPurpose2ChannelComplementaryInstance: | ||
| 275 | BasicInstance + GeneralPurpose1ChannelComplementaryInstance | ||
| 276 | { | ||
| 277 | /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. | ||
| 278 | /// | ||
| 279 | /// Note: This works even if the timer is more capable, because registers | ||
| 280 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 281 | /// for a given set of capabilities, and having it transparently work with | ||
| 282 | /// more capable timers. | ||
| 283 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; | ||
| 284 | } | ||
| 285 | |||
| 199 | /// Advanced control timer instance. | 286 | /// Advanced control timer instance. |
| 200 | pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { | 287 | pub trait AdvancedControlInstance: |
| 288 | GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance | ||
| 289 | { | ||
| 201 | /// Get access to the advanced timer registers. | 290 | /// Get access to the advanced timer registers. |
| 202 | fn regs_advanced() -> crate::pac::timer::TimAdv; | 291 | fn regs_advanced() -> crate::pac::timer::TimAdv; |
| 203 | } | 292 | } |
| 204 | 293 | ||
| 205 | /// Capture/Compare 16-bit timer instance. | 294 | /// Capture/Compare 16-bit timer instance. |
| 206 | pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { | 295 | pub trait CaptureCompare16bitInstance: GeneralPurpose1ChannelInstance { |
| 207 | /// Set input capture filter. | 296 | /// Set input capture filter. |
| 208 | fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::Icf) { | 297 | fn set_input_capture_filter(&mut self, channel: Channel, icf: vals::FilterValue) { |
| 209 | let raw_channel = channel.index(); | 298 | let raw_channel = channel.index(); |
| 210 | Self::regs_gp16() | 299 | Self::regs_1ch() |
| 211 | .ccmr_input(raw_channel / 2) | 300 | .ccmr_input(raw_channel / 2) |
| 212 | .modify(|r| r.set_icf(raw_channel % 2, icf)); | 301 | .modify(|r| r.set_icf(raw_channel % 2, icf)); |
| 213 | } | 302 | } |
| 214 | 303 | ||
| 215 | /// Clear input interrupt. | 304 | /// Clear input interrupt. |
| 216 | fn clear_input_interrupt(&mut self, channel: Channel) { | 305 | fn clear_input_interrupt(&mut self, channel: Channel) { |
| 217 | Self::regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); | 306 | Self::regs_1ch().sr().modify(|r| r.set_ccif(channel.index(), false)); |
| 218 | } | 307 | } |
| 219 | 308 | ||
| 220 | /// Enable input interrupt. | 309 | /// Enable input interrupt. |
| 221 | fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) { | 310 | fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) { |
| 222 | Self::regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); | 311 | Self::regs_1ch().dier().modify(|r| r.set_ccie(channel.index(), enable)); |
| 223 | } | 312 | } |
| 224 | 313 | ||
| 225 | /// Set input capture prescaler. | 314 | /// Set input capture prescaler. |
| 226 | fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) { | 315 | fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) { |
| 227 | let raw_channel = channel.index(); | 316 | let raw_channel = channel.index(); |
| 228 | Self::regs_gp16() | 317 | Self::regs_1ch() |
| 229 | .ccmr_input(raw_channel / 2) | 318 | .ccmr_input(raw_channel / 2) |
| 230 | .modify(|r| r.set_icpsc(raw_channel % 2, factor)); | 319 | .modify(|r| r.set_icpsc(raw_channel % 2, factor)); |
| 231 | } | 320 | } |
| @@ -233,14 +322,14 @@ pub(crate) mod sealed { | |||
| 233 | /// Set input TI selection. | 322 | /// Set input TI selection. |
| 234 | fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { | 323 | fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) { |
| 235 | let raw_channel = channel.index(); | 324 | let raw_channel = channel.index(); |
| 236 | Self::regs_gp16() | 325 | Self::regs_1ch() |
| 237 | .ccmr_input(raw_channel / 2) | 326 | .ccmr_input(raw_channel / 2) |
| 238 | .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); | 327 | .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); |
| 239 | } | 328 | } |
| 240 | 329 | ||
| 241 | /// Set input capture mode. | 330 | /// Set input capture mode. |
| 242 | fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { | 331 | fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) { |
| 243 | Self::regs_gp16().ccer().modify(|r| match mode { | 332 | Self::regs_1ch().ccer().modify(|r| match mode { |
| 244 | InputCaptureMode::Rising => { | 333 | InputCaptureMode::Rising => { |
| 245 | r.set_ccnp(channel.index(), false); | 334 | r.set_ccnp(channel.index(), false); |
| 246 | r.set_ccp(channel.index(), false); | 335 | r.set_ccp(channel.index(), false); |
| @@ -256,12 +345,9 @@ pub(crate) mod sealed { | |||
| 256 | }); | 345 | }); |
| 257 | } | 346 | } |
| 258 | 347 | ||
| 259 | /// Enable timer outputs. | ||
| 260 | fn enable_outputs(&mut self); | ||
| 261 | |||
| 262 | /// Set output compare mode. | 348 | /// Set output compare mode. |
| 263 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { | 349 | fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { |
| 264 | let r = Self::regs_gp16(); | 350 | let r = Self::regs_1ch(); |
| 265 | let raw_channel: usize = channel.index(); | 351 | let raw_channel: usize = channel.index(); |
| 266 | r.ccmr_output(raw_channel / 2) | 352 | r.ccmr_output(raw_channel / 2) |
| 267 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | 353 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); |
| @@ -269,45 +355,45 @@ pub(crate) mod sealed { | |||
| 269 | 355 | ||
| 270 | /// Set output polarity. | 356 | /// Set output polarity. |
| 271 | fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { | 357 | fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { |
| 272 | Self::regs_gp16() | 358 | Self::regs_1ch() |
| 273 | .ccer() | 359 | .ccer() |
| 274 | .modify(|w| w.set_ccp(channel.index(), polarity.into())); | 360 | .modify(|w| w.set_ccp(channel.index(), polarity.into())); |
| 275 | } | 361 | } |
| 276 | 362 | ||
| 277 | /// Enable/disable a channel. | 363 | /// Enable/disable a channel. |
| 278 | fn enable_channel(&mut self, channel: Channel, enable: bool) { | 364 | fn enable_channel(&mut self, channel: Channel, enable: bool) { |
| 279 | Self::regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); | 365 | Self::regs_1ch().ccer().modify(|w| w.set_cce(channel.index(), enable)); |
| 280 | } | 366 | } |
| 281 | 367 | ||
| 282 | /// Get enable/disable state of a channel | 368 | /// Get enable/disable state of a channel |
| 283 | fn get_channel_enable_state(&self, channel: Channel) -> bool { | 369 | fn get_channel_enable_state(&self, channel: Channel) -> bool { |
| 284 | Self::regs_gp16().ccer().read().cce(channel.index()) | 370 | Self::regs_1ch().ccer().read().cce(channel.index()) |
| 285 | } | 371 | } |
| 286 | 372 | ||
| 287 | /// Set compare value for a channel. | 373 | /// Set compare value for a channel. |
| 288 | fn set_compare_value(&mut self, channel: Channel, value: u16) { | 374 | fn set_compare_value(&mut self, channel: Channel, value: u16) { |
| 289 | Self::regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value)); | 375 | Self::regs_1ch().ccr(channel.index()).modify(|w| w.set_ccr(value)); |
| 290 | } | 376 | } |
| 291 | 377 | ||
| 292 | /// Get capture value for a channel. | 378 | /// Get capture value for a channel. |
| 293 | fn get_capture_value(&mut self, channel: Channel) -> u16 { | 379 | fn get_capture_value(&mut self, channel: Channel) -> u16 { |
| 294 | Self::regs_gp16().ccr(channel.index()).read().ccr() | 380 | Self::regs_1ch().ccr(channel.index()).read().ccr() |
| 295 | } | 381 | } |
| 296 | 382 | ||
| 297 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | 383 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. |
| 298 | fn get_max_compare_value(&self) -> u16 { | 384 | fn get_max_compare_value(&self) -> u16 { |
| 299 | Self::regs_gp16().arr().read().arr() | 385 | Self::regs_1ch().arr().read().arr() |
| 300 | } | 386 | } |
| 301 | 387 | ||
| 302 | /// Get compare value for a channel. | 388 | /// Get compare value for a channel. |
| 303 | fn get_compare_value(&self, channel: Channel) -> u16 { | 389 | fn get_compare_value(&self, channel: Channel) -> u16 { |
| 304 | Self::regs_gp16().ccr(channel.index()).read().ccr() | 390 | Self::regs_1ch().ccr(channel.index()).read().ccr() |
| 305 | } | 391 | } |
| 306 | 392 | ||
| 307 | /// Set output compare preload. | 393 | /// Set output compare preload. |
| 308 | fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) { | 394 | fn set_output_compare_preload(&mut self, channel: Channel, preload: bool) { |
| 309 | let channel_index = channel.index(); | 395 | let channel_index = channel.index(); |
| 310 | Self::regs_gp16() | 396 | Self::regs_1ch() |
| 311 | .ccmr_output(channel_index / 2) | 397 | .ccmr_output(channel_index / 2) |
| 312 | .modify(|w| w.set_ocpe(channel_index % 2, preload)); | 398 | .modify(|w| w.set_ocpe(channel_index % 2, preload)); |
| 313 | } | 399 | } |
| @@ -334,27 +420,29 @@ pub(crate) mod sealed { | |||
| 334 | } | 420 | } |
| 335 | 421 | ||
| 336 | /// Capture/Compare 16-bit timer instance with complementary pin support. | 422 | /// Capture/Compare 16-bit timer instance with complementary pin support. |
| 337 | pub trait ComplementaryCaptureCompare16bitInstance: CaptureCompare16bitInstance + AdvancedControlInstance { | 423 | pub trait ComplementaryCaptureCompare16bitInstance: |
| 424 | CaptureCompare16bitInstance + GeneralPurpose1ChannelComplementaryInstance | ||
| 425 | { | ||
| 338 | /// Set complementary output polarity. | 426 | /// Set complementary output polarity. |
| 339 | fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { | 427 | fn set_complementary_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity) { |
| 340 | Self::regs_advanced() | 428 | Self::regs_1ch_cmp() |
| 341 | .ccer() | 429 | .ccer() |
| 342 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); | 430 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); |
| 343 | } | 431 | } |
| 344 | 432 | ||
| 345 | /// Set clock divider for the dead time. | 433 | /// Set clock divider for the dead time. |
| 346 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { | 434 | fn set_dead_time_clock_division(&mut self, value: vals::Ckd) { |
| 347 | Self::regs_advanced().cr1().modify(|w| w.set_ckd(value)); | 435 | Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); |
| 348 | } | 436 | } |
| 349 | 437 | ||
| 350 | /// Set dead time, as a fraction of the max duty value. | 438 | /// Set dead time, as a fraction of the max duty value. |
| 351 | fn set_dead_time_value(&mut self, value: u8) { | 439 | fn set_dead_time_value(&mut self, value: u8) { |
| 352 | Self::regs_advanced().bdtr().modify(|w| w.set_dtg(value)); | 440 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); |
| 353 | } | 441 | } |
| 354 | 442 | ||
| 355 | /// Enable/disable a complementary channel. | 443 | /// Enable/disable a complementary channel. |
| 356 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { | 444 | fn enable_complementary_channel(&mut self, channel: Channel, enable: bool) { |
| 357 | Self::regs_advanced() | 445 | Self::regs_1ch_cmp() |
| 358 | .ccer() | 446 | .ccer() |
| 359 | .modify(|w| w.set_ccne(channel.index(), enable)); | 447 | .modify(|w| w.set_ccne(channel.index(), enable)); |
| 360 | } | 448 | } |
| @@ -571,11 +659,29 @@ impl From<OutputPolarity> for bool { | |||
| 571 | } | 659 | } |
| 572 | } | 660 | } |
| 573 | 661 | ||
| 662 | /// Virtual Core 16-bit timer instance. | ||
| 663 | pub trait CoreInstance: sealed::CoreInstance + 'static {} | ||
| 664 | |||
| 665 | /// Virtual Basic 16-bit timer without CR2 register instance. | ||
| 666 | pub trait BasicNoCr2Instance: sealed::BasicNoCr2Instance + CoreInstance + 'static {} | ||
| 667 | |||
| 574 | /// Basic 16-bit timer instance. | 668 | /// Basic 16-bit timer instance. |
| 575 | pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} | 669 | pub trait BasicInstance: sealed::BasicInstance + BasicNoCr2Instance + 'static {} |
| 670 | |||
| 671 | /// 1 channel 16-bit instance. | ||
| 672 | pub trait GeneralPurpose1ChannelInstance: sealed::GeneralPurpose1ChannelInstance + CoreInstance + 'static {} | ||
| 673 | |||
| 674 | /// 2 channel 16-bit instance. | ||
| 675 | pub trait GeneralPurpose2ChannelInstance: | ||
| 676 | sealed::GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelInstance + 'static | ||
| 677 | { | ||
| 678 | } | ||
| 576 | 679 | ||
| 577 | /// Gneral-purpose 16-bit timer instance. | 680 | /// General-purpose 16-bit timer instance. |
| 578 | pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + Basic16bitInstance + 'static {} | 681 | pub trait GeneralPurpose16bitInstance: |
| 682 | sealed::GeneralPurpose16bitInstance + BasicInstance + GeneralPurpose2ChannelInstance + 'static | ||
| 683 | { | ||
| 684 | } | ||
| 579 | 685 | ||
| 580 | /// Gneral-purpose 32-bit timer instance. | 686 | /// Gneral-purpose 32-bit timer instance. |
| 581 | pub trait GeneralPurpose32bitInstance: | 687 | pub trait GeneralPurpose32bitInstance: |
| @@ -583,18 +689,39 @@ pub trait GeneralPurpose32bitInstance: | |||
| 583 | { | 689 | { |
| 584 | } | 690 | } |
| 585 | 691 | ||
| 692 | /// General-purpose 1 channel with one complementary 16-bit timer instance. | ||
| 693 | pub trait GeneralPurpose1ChannelComplementaryInstance: | ||
| 694 | sealed::GeneralPurpose1ChannelComplementaryInstance + GeneralPurpose1ChannelInstance + 'static | ||
| 695 | { | ||
| 696 | } | ||
| 697 | |||
| 698 | /// General-purpose 2 channel with one complementary 16-bit timer instance. | ||
| 699 | pub trait GeneralPurpose2ChannelComplementaryInstance: | ||
| 700 | sealed::GeneralPurpose2ChannelComplementaryInstance | ||
| 701 | + BasicInstance | ||
| 702 | + GeneralPurpose1ChannelComplementaryInstance | ||
| 703 | + 'static | ||
| 704 | { | ||
| 705 | } | ||
| 706 | |||
| 586 | /// Advanced control timer instance. | 707 | /// Advanced control timer instance. |
| 587 | pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + GeneralPurpose16bitInstance + 'static {} | 708 | pub trait AdvancedControlInstance: |
| 709 | sealed::AdvancedControlInstance + GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance + 'static | ||
| 710 | { | ||
| 711 | } | ||
| 588 | 712 | ||
| 589 | /// Capture/Compare 16-bit timer instance. | 713 | /// Capture/Compare 16-bit timer instance. |
| 590 | pub trait CaptureCompare16bitInstance: | 714 | pub trait CaptureCompare16bitInstance: |
| 591 | sealed::CaptureCompare16bitInstance + GeneralPurpose16bitInstance + 'static | 715 | sealed::CaptureCompare16bitInstance + GeneralPurpose1ChannelInstance + 'static |
| 592 | { | 716 | { |
| 593 | } | 717 | } |
| 594 | 718 | ||
| 595 | /// Capture/Compare 16-bit timer instance with complementary pin support. | 719 | /// Capture/Compare 16-bit timer instance with complementary pin support. |
| 596 | pub trait ComplementaryCaptureCompare16bitInstance: | 720 | pub trait ComplementaryCaptureCompare16bitInstance: |
| 597 | sealed::ComplementaryCaptureCompare16bitInstance + CaptureCompare16bitInstance + AdvancedControlInstance + 'static | 721 | sealed::ComplementaryCaptureCompare16bitInstance |
| 722 | + CaptureCompare16bitInstance | ||
| 723 | + GeneralPurpose1ChannelComplementaryInstance | ||
| 724 | + 'static | ||
| 598 | { | 725 | { |
| 599 | } | 726 | } |
| 600 | 727 | ||
| @@ -621,12 +748,34 @@ pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); | |||
| 621 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); | 748 | pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); |
| 622 | 749 | ||
| 623 | #[allow(unused)] | 750 | #[allow(unused)] |
| 624 | macro_rules! impl_basic_16bit_timer { | 751 | macro_rules! impl_core_timer { |
| 625 | ($inst:ident, $irq:ident) => { | 752 | ($inst:ident, $irq:ident) => { |
| 626 | impl sealed::Basic16bitInstance for crate::peripherals::$inst { | 753 | impl sealed::CoreInstance for crate::peripherals::$inst { |
| 627 | type Interrupt = crate::interrupt::typelevel::$irq; | 754 | type Interrupt = crate::interrupt::typelevel::$irq; |
| 628 | 755 | ||
| 629 | fn regs() -> crate::pac::timer::TimBasic { | 756 | fn regs_core() -> crate::pac::timer::TimCore { |
| 757 | unsafe { crate::pac::timer::TimCore::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 758 | } | ||
| 759 | } | ||
| 760 | }; | ||
| 761 | } | ||
| 762 | |||
| 763 | #[allow(unused)] | ||
| 764 | macro_rules! impl_basic_no_cr2_timer { | ||
| 765 | ($inst:ident) => { | ||
| 766 | impl sealed::BasicNoCr2Instance for crate::peripherals::$inst { | ||
| 767 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2 { | ||
| 768 | unsafe { crate::pac::timer::TimBasicNoCr2::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 769 | } | ||
| 770 | } | ||
| 771 | }; | ||
| 772 | } | ||
| 773 | |||
| 774 | #[allow(unused)] | ||
| 775 | macro_rules! impl_basic_timer { | ||
| 776 | ($inst:ident) => { | ||
| 777 | impl sealed::BasicInstance for crate::peripherals::$inst { | ||
| 778 | fn regs_basic() -> crate::pac::timer::TimBasic { | ||
| 630 | unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } | 779 | unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } |
| 631 | } | 780 | } |
| 632 | } | 781 | } |
| @@ -634,7 +783,40 @@ macro_rules! impl_basic_16bit_timer { | |||
| 634 | } | 783 | } |
| 635 | 784 | ||
| 636 | #[allow(unused)] | 785 | #[allow(unused)] |
| 637 | macro_rules! impl_32bit_timer { | 786 | macro_rules! impl_1ch_timer { |
| 787 | ($inst:ident) => { | ||
| 788 | impl sealed::GeneralPurpose1ChannelInstance for crate::peripherals::$inst { | ||
| 789 | fn regs_1ch() -> crate::pac::timer::Tim1ch { | ||
| 790 | unsafe { crate::pac::timer::Tim1ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 791 | } | ||
| 792 | } | ||
| 793 | }; | ||
| 794 | } | ||
| 795 | |||
| 796 | #[allow(unused)] | ||
| 797 | macro_rules! impl_2ch_timer { | ||
| 798 | ($inst:ident) => { | ||
| 799 | impl sealed::GeneralPurpose2ChannelInstance for crate::peripherals::$inst { | ||
| 800 | fn regs_2ch() -> crate::pac::timer::Tim2ch { | ||
| 801 | unsafe { crate::pac::timer::Tim2ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 802 | } | ||
| 803 | } | ||
| 804 | }; | ||
| 805 | } | ||
| 806 | |||
| 807 | #[allow(unused)] | ||
| 808 | macro_rules! impl_gp_16bit_timer { | ||
| 809 | ($inst:ident) => { | ||
| 810 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 811 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | ||
| 812 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 813 | } | ||
| 814 | } | ||
| 815 | }; | ||
| 816 | } | ||
| 817 | |||
| 818 | #[allow(unused)] | ||
| 819 | macro_rules! impl_gp_32bit_timer { | ||
| 638 | ($inst:ident) => { | 820 | ($inst:ident) => { |
| 639 | impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { | 821 | impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { |
| 640 | fn regs_gp32() -> crate::pac::timer::TimGp32 { | 822 | fn regs_gp32() -> crate::pac::timer::TimGp32 { |
| @@ -645,83 +827,193 @@ macro_rules! impl_32bit_timer { | |||
| 645 | } | 827 | } |
| 646 | 828 | ||
| 647 | #[allow(unused)] | 829 | #[allow(unused)] |
| 648 | macro_rules! impl_compare_capable_16bit { | 830 | macro_rules! impl_1ch_cmp_timer { |
| 831 | ($inst:ident) => { | ||
| 832 | impl sealed::GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst { | ||
| 833 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp { | ||
| 834 | unsafe { crate::pac::timer::Tim1chCmp::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 835 | } | ||
| 836 | } | ||
| 837 | }; | ||
| 838 | } | ||
| 839 | |||
| 840 | #[allow(unused)] | ||
| 841 | macro_rules! impl_2ch_cmp_timer { | ||
| 842 | ($inst:ident) => { | ||
| 843 | impl sealed::GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst { | ||
| 844 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp { | ||
| 845 | unsafe { crate::pac::timer::Tim2chCmp::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 846 | } | ||
| 847 | } | ||
| 848 | }; | ||
| 849 | } | ||
| 850 | |||
| 851 | #[allow(unused)] | ||
| 852 | macro_rules! impl_adv_timer { | ||
| 649 | ($inst:ident) => { | 853 | ($inst:ident) => { |
| 650 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | 854 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { |
| 651 | fn enable_outputs(&mut self) {} | 855 | fn regs_advanced() -> crate::pac::timer::TimAdv { |
| 856 | unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 857 | } | ||
| 652 | } | 858 | } |
| 653 | }; | 859 | }; |
| 654 | } | 860 | } |
| 655 | 861 | ||
| 862 | #[allow(unused)] | ||
| 863 | macro_rules! impl_compare_capable_16bit { | ||
| 864 | ($inst:ident) => { | ||
| 865 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 866 | }; | ||
| 867 | } | ||
| 868 | |||
| 869 | #[allow(unused)] | ||
| 870 | macro_rules! impl_compare_capable_32bit { | ||
| 871 | ($inst:ident) => { | ||
| 872 | impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} | ||
| 873 | }; | ||
| 874 | } | ||
| 875 | |||
| 876 | #[allow(unused)] | ||
| 877 | macro_rules! impl_compare_capable_complementary_16bit { | ||
| 878 | ($inst:ident) => { | ||
| 879 | impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 880 | }; | ||
| 881 | } | ||
| 882 | |||
| 656 | foreach_interrupt! { | 883 | foreach_interrupt! { |
| 884 | |||
| 657 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | 885 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { |
| 658 | impl_basic_16bit_timer!($inst, $irq); | 886 | impl_core_timer!($inst, $irq); |
| 659 | impl Basic16bitInstance for crate::peripherals::$inst {} | 887 | impl_basic_no_cr2_timer!($inst); |
| 888 | impl_basic_timer!($inst); | ||
| 889 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 890 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 891 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 660 | }; | 892 | }; |
| 661 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | 893 | |
| 662 | impl_basic_16bit_timer!($inst, $irq); | 894 | ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { |
| 895 | impl_core_timer!($inst, $irq); | ||
| 896 | impl_1ch_timer!($inst); | ||
| 663 | impl_compare_capable_16bit!($inst); | 897 | impl_compare_capable_16bit!($inst); |
| 664 | impl Basic16bitInstance for crate::peripherals::$inst {} | 898 | impl CoreInstance for crate::peripherals::$inst {} |
| 665 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | 899 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} |
| 666 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 900 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} |
| 901 | }; | ||
| 667 | 902 | ||
| 668 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 903 | |
| 669 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 904 | ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { |
| 670 | crate::pac::$inst | 905 | impl_core_timer!($inst, $irq); |
| 671 | } | 906 | impl_1ch_timer!($inst); |
| 672 | } | 907 | impl_compare_capable_16bit!($inst); |
| 908 | impl_2ch_timer!($inst); | ||
| 909 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 910 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 911 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 912 | impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} | ||
| 913 | }; | ||
| 914 | |||
| 915 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | ||
| 916 | impl_core_timer!($inst, $irq); | ||
| 917 | impl_basic_no_cr2_timer!($inst); | ||
| 918 | impl_basic_timer!($inst); | ||
| 919 | impl_1ch_timer!($inst); | ||
| 920 | impl_compare_capable_16bit!($inst); | ||
| 921 | impl_2ch_timer!($inst); | ||
| 922 | impl_gp_16bit_timer!($inst); | ||
| 923 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 924 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 925 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 926 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 927 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 928 | impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} | ||
| 929 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | ||
| 673 | }; | 930 | }; |
| 674 | 931 | ||
| 675 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | 932 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { |
| 676 | impl_basic_16bit_timer!($inst, $irq); | 933 | impl_core_timer!($inst, $irq); |
| 677 | impl_32bit_timer!($inst); | 934 | impl_basic_no_cr2_timer!($inst); |
| 935 | impl_basic_timer!($inst); | ||
| 936 | impl_1ch_timer!($inst); | ||
| 678 | impl_compare_capable_16bit!($inst); | 937 | impl_compare_capable_16bit!($inst); |
| 679 | impl Basic16bitInstance for crate::peripherals::$inst {} | 938 | impl_compare_capable_32bit!($inst); |
| 939 | impl_2ch_timer!($inst); | ||
| 940 | impl_gp_16bit_timer!($inst); | ||
| 941 | impl_gp_32bit_timer!($inst); | ||
| 942 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 943 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 944 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 945 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 680 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 946 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} |
| 681 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} | 947 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} |
| 948 | impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} | ||
| 682 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | 949 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} |
| 683 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} | 950 | impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} |
| 684 | impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {} | 951 | }; |
| 685 | 952 | ||
| 686 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | 953 | ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { |
| 687 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | 954 | impl_core_timer!($inst, $irq); |
| 688 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | 955 | impl_basic_no_cr2_timer!($inst); |
| 689 | } | 956 | impl_1ch_timer!($inst); |
| 690 | } | 957 | impl_compare_capable_16bit!($inst); |
| 958 | impl_1ch_cmp_timer!($inst); | ||
| 959 | impl_compare_capable_complementary_16bit!($inst); | ||
| 960 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 961 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 962 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 963 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 964 | impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} | ||
| 965 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 966 | }; | ||
| 967 | |||
| 968 | |||
| 969 | ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { | ||
| 970 | impl_core_timer!($inst, $irq); | ||
| 971 | impl_basic_no_cr2_timer!($inst); | ||
| 972 | impl_basic_timer!($inst); | ||
| 973 | impl_1ch_timer!($inst); | ||
| 974 | impl_compare_capable_16bit!($inst); | ||
| 975 | impl_1ch_cmp_timer!($inst); | ||
| 976 | impl_compare_capable_complementary_16bit!($inst); | ||
| 977 | impl_2ch_cmp_timer!($inst); | ||
| 978 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 979 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 980 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 981 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 982 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 983 | impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} | ||
| 984 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 985 | impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} | ||
| 691 | }; | 986 | }; |
| 692 | 987 | ||
| 693 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | ||
| 694 | impl_basic_16bit_timer!($inst, $irq); | ||
| 695 | 988 | ||
| 696 | impl Basic16bitInstance for crate::peripherals::$inst {} | 989 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { |
| 990 | impl_core_timer!($inst, $irq); | ||
| 991 | impl_basic_no_cr2_timer!($inst); | ||
| 992 | impl_basic_timer!($inst); | ||
| 993 | impl_1ch_timer!($inst); | ||
| 994 | impl_2ch_timer!($inst); | ||
| 995 | impl_compare_capable_16bit!($inst); | ||
| 996 | impl_1ch_cmp_timer!($inst); | ||
| 997 | impl_gp_16bit_timer!($inst); | ||
| 998 | impl_compare_capable_complementary_16bit!($inst); | ||
| 999 | impl_2ch_cmp_timer!($inst); | ||
| 1000 | impl_adv_timer!($inst); | ||
| 1001 | impl CoreInstance for crate::peripherals::$inst {} | ||
| 1002 | impl BasicNoCr2Instance for crate::peripherals::$inst{} | ||
| 1003 | impl BasicInstance for crate::peripherals::$inst {} | ||
| 1004 | impl GeneralPurpose1ChannelInstance for crate::peripherals::$inst {} | ||
| 1005 | impl GeneralPurpose2ChannelInstance for crate::peripherals::$inst {} | ||
| 697 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} | 1006 | impl GeneralPurpose16bitInstance for crate::peripherals::$inst {} |
| 698 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 1007 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} |
| 1008 | impl GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst {} | ||
| 699 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | 1009 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} |
| 1010 | impl GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst {} | ||
| 700 | impl AdvancedControlInstance for crate::peripherals::$inst {} | 1011 | impl AdvancedControlInstance for crate::peripherals::$inst {} |
| 701 | impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 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 | } | ||
| 707 | } | ||
| 708 | impl sealed::ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 709 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 710 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | ||
| 711 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 712 | } | ||
| 713 | } | ||
| 714 | |||
| 715 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { | ||
| 716 | fn regs_advanced() -> crate::pac::timer::TimAdv { | ||
| 717 | crate::pac::$inst | ||
| 718 | } | ||
| 719 | } | ||
| 720 | }; | 1012 | }; |
| 721 | } | 1013 | } |
| 722 | 1014 | ||
| 723 | // Update Event trigger DMA for every timer | 1015 | // Update Event trigger DMA for every timer |
| 724 | dma_trait!(UpDma, Basic16bitInstance); | 1016 | dma_trait!(UpDma, BasicNoCr2Instance); |
| 725 | 1017 | ||
| 726 | dma_trait!(Ch1Dma, CaptureCompare16bitInstance); | 1018 | dma_trait!(Ch1Dma, CaptureCompare16bitInstance); |
| 727 | dma_trait!(Ch2Dma, CaptureCompare16bitInstance); | 1019 | dma_trait!(Ch2Dma, CaptureCompare16bitInstance); |
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 59efb72ba..75e5ab12a 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs | |||
| @@ -57,7 +57,7 @@ pub struct Qei<'d, T> { | |||
| 57 | _inner: PeripheralRef<'d, T>, | 57 | _inner: PeripheralRef<'d, T>, |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { | 60 | impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> Qei<'d, T> { |
| 61 | /// Create a new quadrature decoder driver. | 61 | /// Create a new quadrature decoder driver. |
| 62 | pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { | 62 | pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { |
| 63 | Self::new_inner(tim) | 63 | Self::new_inner(tim) |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 0b4c1225f..1c665d456 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -59,7 +59,7 @@ pub struct SimplePwm<'d, T> { | |||
| 59 | inner: PeripheralRef<'d, T>, | 59 | inner: PeripheralRef<'d, T>, |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | 62 | impl<'d, T: GeneralPurpose16bitInstance + CaptureCompare16bitInstance> SimplePwm<'d, T> { |
| 63 | /// Create a new simple PWM driver. | 63 | /// Create a new simple PWM driver. |
| 64 | pub fn new( | 64 | pub fn new( |
| 65 | tim: impl Peripheral<P = T> + 'd, | 65 | tim: impl Peripheral<P = T> + 'd, |
| @@ -84,8 +84,6 @@ 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| { |
| @@ -202,7 +200,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 202 | &mut dma, | 200 | &mut dma, |
| 203 | req, | 201 | req, |
| 204 | duty, | 202 | duty, |
| 205 | T::regs_gp16().ccr(channel.index()).as_ptr() as *mut _, | 203 | T::regs_1ch().ccr(channel.index()).as_ptr() as *mut _, |
| 206 | dma_transfer_option, | 204 | dma_transfer_option, |
| 207 | ) | 205 | ) |
| 208 | .await | 206 | .await |
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 8e5c41a43..d88bd838f 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; | |||
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::low_level::RccPeripheral; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::Basic16bitInstance; | 11 | use embassy_stm32::timer::low_level::BasicInstance; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -75,9 +75,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 75 | dac.enable(); | 75 | dac.enable(); |
| 76 | 76 | ||
| 77 | TIM6::enable_and_reset(); | 77 | TIM6::enable_and_reset(); |
| 78 | TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 78 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 79 | TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 79 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 80 | TIM6::regs().cr1().modify(|w| { | 80 | TIM6::regs_basic().cr1().modify(|w| { |
| 81 | w.set_opm(false); | 81 | w.set_opm(false); |
| 82 | w.set_cen(true); | 82 | w.set_cen(true); |
| 83 | }); | 83 | }); |
| @@ -112,9 +112,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | TIM7::enable_and_reset(); | 114 | TIM7::enable_and_reset(); |
| 115 | TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 115 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 116 | TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 116 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 117 | TIM7::regs().cr1().modify(|w| { | 117 | TIM7::regs_basic().cr1().modify(|w| { |
| 118 | w.set_opm(false); | 118 | w.set_opm(false); |
| 119 | w.set_cen(true); | 119 | w.set_cen(true); |
| 120 | }); | 120 | }); |
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 8e5098557..f227812cd 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; | |||
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::low_level::RccPeripheral; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::Basic16bitInstance; | 11 | use embassy_stm32::timer::low_level::BasicInstance; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -46,9 +46,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 46 | dac.enable(); | 46 | dac.enable(); |
| 47 | 47 | ||
| 48 | TIM6::enable_and_reset(); | 48 | TIM6::enable_and_reset(); |
| 49 | TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 49 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 50 | TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 50 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 51 | TIM6::regs().cr1().modify(|w| { | 51 | TIM6::regs_basic().cr1().modify(|w| { |
| 52 | w.set_opm(false); | 52 | w.set_opm(false); |
| 53 | w.set_cen(true); | 53 | w.set_cen(true); |
| 54 | }); | 54 | }); |
| @@ -83,9 +83,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | TIM7::enable_and_reset(); | 85 | TIM7::enable_and_reset(); |
| 86 | TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 86 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 87 | TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 87 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 88 | TIM7::regs().cr1().modify(|w| { | 88 | TIM7::regs_basic().cr1().modify(|w| { |
| 89 | w.set_opm(false); | 89 | w.set_opm(false); |
| 90 | w.set_cen(true); | 90 | w.set_cen(true); |
| 91 | }); | 91 | }); |
