diff options
| -rw-r--r-- | embassy-stm32/src/hrtim/mod.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/hrtim/traits.rs | 196 | ||||
| -rw-r--r-- | embassy-stm32/src/pwm/mod.rs | 199 |
3 files changed, 200 insertions, 201 deletions
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index 7e3a8f144..ddf8cc2a8 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | mod traits; | ||
| 2 | |||
| 1 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 2 | 4 | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 5 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| @@ -5,7 +7,7 @@ use embassy_hal_common::{into_ref, PeripheralRef}; | |||
| 5 | #[allow(unused_imports)] | 7 | #[allow(unused_imports)] |
| 6 | use crate::gpio::sealed::{AFType, Pin}; | 8 | use crate::gpio::sealed::{AFType, Pin}; |
| 7 | use crate::gpio::AnyPin; | 9 | use crate::gpio::AnyPin; |
| 8 | use crate::pwm::HighResolutionCaptureCompare16bitInstance; | 10 | use crate::hrtim::traits::HighResolutionCaptureCompare16bitInstance; |
| 9 | use crate::time::Hertz; | 11 | use crate::time::Hertz; |
| 10 | use crate::Peripheral; | 12 | use crate::Peripheral; |
| 11 | 13 | ||
| @@ -41,7 +43,7 @@ pub struct ChE<T: HighResolutionCaptureCompare16bitInstance> { | |||
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | mod sealed { | 45 | mod sealed { |
| 44 | use crate::pwm::HighResolutionCaptureCompare16bitInstance; | 46 | use super::HighResolutionCaptureCompare16bitInstance; |
| 45 | 47 | ||
| 46 | pub trait AdvancedChannel<T: HighResolutionCaptureCompare16bitInstance> { | 48 | pub trait AdvancedChannel<T: HighResolutionCaptureCompare16bitInstance> { |
| 47 | fn raw() -> usize; | 49 | fn raw() -> usize; |
diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs new file mode 100644 index 000000000..16193a450 --- /dev/null +++ b/embassy-stm32/src/hrtim/traits.rs | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | use crate::time::Hertz; | ||
| 2 | |||
| 3 | #[derive(Clone, Copy)] | ||
| 4 | pub(crate) enum HighResolutionControlPrescaler { | ||
| 5 | Div1, | ||
| 6 | Div2, | ||
| 7 | Div4, | ||
| 8 | Div8, | ||
| 9 | Div16, | ||
| 10 | Div32, | ||
| 11 | Div64, | ||
| 12 | Div128, | ||
| 13 | } | ||
| 14 | |||
| 15 | impl From<HighResolutionControlPrescaler> for u32 { | ||
| 16 | fn from(val: HighResolutionControlPrescaler) -> Self { | ||
| 17 | match val { | ||
| 18 | HighResolutionControlPrescaler::Div1 => 1, | ||
| 19 | HighResolutionControlPrescaler::Div2 => 2, | ||
| 20 | HighResolutionControlPrescaler::Div4 => 4, | ||
| 21 | HighResolutionControlPrescaler::Div8 => 8, | ||
| 22 | HighResolutionControlPrescaler::Div16 => 16, | ||
| 23 | HighResolutionControlPrescaler::Div32 => 32, | ||
| 24 | HighResolutionControlPrescaler::Div64 => 64, | ||
| 25 | HighResolutionControlPrescaler::Div128 => 128, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | impl From<HighResolutionControlPrescaler> for u8 { | ||
| 31 | fn from(val: HighResolutionControlPrescaler) -> Self { | ||
| 32 | match val { | ||
| 33 | HighResolutionControlPrescaler::Div1 => 0b000, | ||
| 34 | HighResolutionControlPrescaler::Div2 => 0b001, | ||
| 35 | HighResolutionControlPrescaler::Div4 => 0b010, | ||
| 36 | HighResolutionControlPrescaler::Div8 => 0b011, | ||
| 37 | HighResolutionControlPrescaler::Div16 => 0b100, | ||
| 38 | HighResolutionControlPrescaler::Div32 => 0b101, | ||
| 39 | HighResolutionControlPrescaler::Div64 => 0b110, | ||
| 40 | HighResolutionControlPrescaler::Div128 => 0b111, | ||
| 41 | } | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | impl From<u8> for HighResolutionControlPrescaler { | ||
| 46 | fn from(val: u8) -> Self { | ||
| 47 | match val { | ||
| 48 | 0b000 => HighResolutionControlPrescaler::Div1, | ||
| 49 | 0b001 => HighResolutionControlPrescaler::Div2, | ||
| 50 | 0b010 => HighResolutionControlPrescaler::Div4, | ||
| 51 | 0b011 => HighResolutionControlPrescaler::Div8, | ||
| 52 | 0b100 => HighResolutionControlPrescaler::Div16, | ||
| 53 | 0b101 => HighResolutionControlPrescaler::Div32, | ||
| 54 | 0b110 => HighResolutionControlPrescaler::Div64, | ||
| 55 | 0b111 => HighResolutionControlPrescaler::Div128, | ||
| 56 | _ => unreachable!(), | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | impl HighResolutionControlPrescaler { | ||
| 62 | pub fn compute_min_high_res(val: u32) -> Self { | ||
| 63 | *[ | ||
| 64 | HighResolutionControlPrescaler::Div1, | ||
| 65 | HighResolutionControlPrescaler::Div2, | ||
| 66 | HighResolutionControlPrescaler::Div4, | ||
| 67 | HighResolutionControlPrescaler::Div8, | ||
| 68 | HighResolutionControlPrescaler::Div16, | ||
| 69 | HighResolutionControlPrescaler::Div32, | ||
| 70 | HighResolutionControlPrescaler::Div64, | ||
| 71 | HighResolutionControlPrescaler::Div128, | ||
| 72 | ] | ||
| 73 | .iter() | ||
| 74 | .skip_while(|psc| <HighResolutionControlPrescaler as Into<u32>>::into(**psc) <= val) | ||
| 75 | .next() | ||
| 76 | .unwrap() | ||
| 77 | } | ||
| 78 | |||
| 79 | pub fn compute_min_low_res(val: u32) -> Self { | ||
| 80 | *[ | ||
| 81 | HighResolutionControlPrescaler::Div32, | ||
| 82 | HighResolutionControlPrescaler::Div64, | ||
| 83 | HighResolutionControlPrescaler::Div128, | ||
| 84 | ] | ||
| 85 | .iter() | ||
| 86 | .skip_while(|psc| <HighResolutionControlPrescaler as Into<u32>>::into(**psc) <= val) | ||
| 87 | .next() | ||
| 88 | .unwrap() | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | pub(crate) mod sealed { | ||
| 93 | use super::*; | ||
| 94 | |||
| 95 | pub trait HighResolutionCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance { | ||
| 96 | fn set_master_frequency(frequency: Hertz); | ||
| 97 | |||
| 98 | fn set_channel_frequency(channnel: usize, frequency: Hertz); | ||
| 99 | |||
| 100 | /// Set the dead time as a proportion of max_duty | ||
| 101 | fn set_channel_dead_time(channnel: usize, dead_time: u16); | ||
| 102 | |||
| 103 | // fn enable_outputs(enable: bool); | ||
| 104 | // | ||
| 105 | // fn enable_channel(&mut self, channel: usize, enable: bool); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | pub trait HighResolutionCaptureCompare16bitInstance: | ||
| 110 | sealed::HighResolutionCaptureCompare16bitInstance + 'static | ||
| 111 | { | ||
| 112 | } | ||
| 113 | |||
| 114 | foreach_interrupt! { | ||
| 115 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { | ||
| 116 | impl sealed::HighResolutionCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 117 | fn set_master_frequency(frequency: Hertz) { | ||
| 118 | use crate::rcc::sealed::RccPeripheral; | ||
| 119 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 120 | |||
| 121 | let f = frequency.0; | ||
| 122 | let timer_f = Self::frequency().0; | ||
| 123 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 124 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 125 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 126 | } else { | ||
| 127 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 128 | }; | ||
| 129 | |||
| 130 | let psc_val: u32 = psc.into(); | ||
| 131 | let timer_f = 32 * (timer_f / psc_val); | ||
| 132 | let per: u16 = (timer_f / f) as u16; | ||
| 133 | |||
| 134 | let regs = Self::regs(); | ||
| 135 | |||
| 136 | regs.mcr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 137 | regs.mper().modify(|w| w.set_mper(per)); | ||
| 138 | } | ||
| 139 | |||
| 140 | fn set_channel_frequency(channel: usize, frequency: Hertz) { | ||
| 141 | use crate::rcc::sealed::RccPeripheral; | ||
| 142 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 143 | |||
| 144 | let f = frequency.0; | ||
| 145 | let timer_f = Self::frequency().0; | ||
| 146 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 147 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 148 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 149 | } else { | ||
| 150 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 151 | }; | ||
| 152 | |||
| 153 | let psc_val: u32 = psc.into(); | ||
| 154 | let timer_f = 32 * (timer_f / psc_val); | ||
| 155 | let per: u16 = (timer_f / f) as u16; | ||
| 156 | |||
| 157 | let regs = Self::regs(); | ||
| 158 | |||
| 159 | regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 160 | regs.tim(channel).per().modify(|w| w.set_per(per)); | ||
| 161 | } | ||
| 162 | |||
| 163 | fn set_channel_dead_time(channel: usize, dead_time: u16) { | ||
| 164 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 165 | |||
| 166 | let regs = Self::regs(); | ||
| 167 | |||
| 168 | let channel_psc: HighResolutionControlPrescaler = regs.tim(channel).cr().read().ckpsc().into(); | ||
| 169 | let psc_val: u32 = channel_psc.into(); | ||
| 170 | |||
| 171 | |||
| 172 | // The dead-time base clock runs 4 times slower than the hrtim base clock | ||
| 173 | // u9::MAX = 511 | ||
| 174 | let psc_min = (psc_val * dead_time as u32) / (4 * 511); | ||
| 175 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 176 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 177 | } else { | ||
| 178 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 179 | }; | ||
| 180 | |||
| 181 | let dt_psc_val: u32 = psc.into(); | ||
| 182 | let dt_val = (dt_psc_val * dead_time as u32) / (4 * psc_val); | ||
| 183 | |||
| 184 | regs.tim(channel).dt().modify(|w| { | ||
| 185 | w.set_dtprsc(psc.into()); | ||
| 186 | w.set_dtf(dt_val as u16); | ||
| 187 | w.set_dtr(dt_val as u16); | ||
| 188 | }); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | impl HighResolutionCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 193 | |||
| 194 | } | ||
| 195 | }; | ||
| 196 | } | ||
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs index c4b38ebdb..5aba2663e 100644 --- a/embassy-stm32/src/pwm/mod.rs +++ b/embassy-stm32/src/pwm/mod.rs | |||
| @@ -3,9 +3,6 @@ pub mod simple_pwm; | |||
| 3 | 3 | ||
| 4 | use stm32_metapac::timer::vals::Ckd; | 4 | use stm32_metapac::timer::vals::Ckd; |
| 5 | 5 | ||
| 6 | #[cfg(hrtim_v1)] | ||
| 7 | use crate::time::Hertz; | ||
| 8 | |||
| 9 | #[cfg(feature = "unstable-pac")] | 6 | #[cfg(feature = "unstable-pac")] |
| 10 | pub mod low_level { | 7 | pub mod low_level { |
| 11 | pub use super::sealed::*; | 8 | pub use super::sealed::*; |
| @@ -57,117 +54,9 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { | |||
| 57 | } | 54 | } |
| 58 | } | 55 | } |
| 59 | 56 | ||
| 60 | #[cfg(hrtim_v1)] | ||
| 61 | #[derive(Clone, Copy)] | ||
| 62 | pub(crate) enum HighResolutionControlPrescaler { | ||
| 63 | Div1, | ||
| 64 | Div2, | ||
| 65 | Div4, | ||
| 66 | Div8, | ||
| 67 | Div16, | ||
| 68 | Div32, | ||
| 69 | Div64, | ||
| 70 | Div128, | ||
| 71 | } | ||
| 72 | |||
| 73 | #[cfg(hrtim_v1)] | ||
| 74 | impl From<HighResolutionControlPrescaler> for u32 { | ||
| 75 | fn from(val: HighResolutionControlPrescaler) -> Self { | ||
| 76 | match val { | ||
| 77 | HighResolutionControlPrescaler::Div1 => 1, | ||
| 78 | HighResolutionControlPrescaler::Div2 => 2, | ||
| 79 | HighResolutionControlPrescaler::Div4 => 4, | ||
| 80 | HighResolutionControlPrescaler::Div8 => 8, | ||
| 81 | HighResolutionControlPrescaler::Div16 => 16, | ||
| 82 | HighResolutionControlPrescaler::Div32 => 32, | ||
| 83 | HighResolutionControlPrescaler::Div64 => 64, | ||
| 84 | HighResolutionControlPrescaler::Div128 => 128, | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | #[cfg(hrtim_v1)] | ||
| 90 | impl From<HighResolutionControlPrescaler> for u8 { | ||
| 91 | fn from(val: HighResolutionControlPrescaler) -> Self { | ||
| 92 | match val { | ||
| 93 | HighResolutionControlPrescaler::Div1 => 0b000, | ||
| 94 | HighResolutionControlPrescaler::Div2 => 0b001, | ||
| 95 | HighResolutionControlPrescaler::Div4 => 0b010, | ||
| 96 | HighResolutionControlPrescaler::Div8 => 0b011, | ||
| 97 | HighResolutionControlPrescaler::Div16 => 0b100, | ||
| 98 | HighResolutionControlPrescaler::Div32 => 0b101, | ||
| 99 | HighResolutionControlPrescaler::Div64 => 0b110, | ||
| 100 | HighResolutionControlPrescaler::Div128 => 0b111, | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | #[cfg(hrtim_v1)] | ||
| 106 | impl From<u8> for HighResolutionControlPrescaler { | ||
| 107 | fn from(val: u8) -> Self { | ||
| 108 | match val { | ||
| 109 | 0b000 => HighResolutionControlPrescaler::Div1, | ||
| 110 | 0b001 => HighResolutionControlPrescaler::Div2, | ||
| 111 | 0b010 => HighResolutionControlPrescaler::Div4, | ||
| 112 | 0b011 => HighResolutionControlPrescaler::Div8, | ||
| 113 | 0b100 => HighResolutionControlPrescaler::Div16, | ||
| 114 | 0b101 => HighResolutionControlPrescaler::Div32, | ||
| 115 | 0b110 => HighResolutionControlPrescaler::Div64, | ||
| 116 | 0b111 => HighResolutionControlPrescaler::Div128, | ||
| 117 | _ => unreachable!(), | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | #[cfg(hrtim_v1)] | ||
| 123 | impl HighResolutionControlPrescaler { | ||
| 124 | pub fn compute_min_high_res(val: u32) -> Self { | ||
| 125 | *[ | ||
| 126 | HighResolutionControlPrescaler::Div1, | ||
| 127 | HighResolutionControlPrescaler::Div2, | ||
| 128 | HighResolutionControlPrescaler::Div4, | ||
| 129 | HighResolutionControlPrescaler::Div8, | ||
| 130 | HighResolutionControlPrescaler::Div16, | ||
| 131 | HighResolutionControlPrescaler::Div32, | ||
| 132 | HighResolutionControlPrescaler::Div64, | ||
| 133 | HighResolutionControlPrescaler::Div128, | ||
| 134 | ] | ||
| 135 | .iter() | ||
| 136 | .skip_while(|psc| <HighResolutionControlPrescaler as Into<u32>>::into(**psc) <= val) | ||
| 137 | .next() | ||
| 138 | .unwrap() | ||
| 139 | } | ||
| 140 | |||
| 141 | pub fn compute_min_low_res(val: u32) -> Self { | ||
| 142 | *[ | ||
| 143 | HighResolutionControlPrescaler::Div32, | ||
| 144 | HighResolutionControlPrescaler::Div64, | ||
| 145 | HighResolutionControlPrescaler::Div128, | ||
| 146 | ] | ||
| 147 | .iter() | ||
| 148 | .skip_while(|psc| <HighResolutionControlPrescaler as Into<u32>>::into(**psc) <= val) | ||
| 149 | .next() | ||
| 150 | .unwrap() | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | pub(crate) mod sealed { | 57 | pub(crate) mod sealed { |
| 155 | use super::*; | 58 | use super::*; |
| 156 | 59 | ||
| 157 | #[cfg(hrtim_v1)] | ||
| 158 | pub trait HighResolutionCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance { | ||
| 159 | fn set_master_frequency(frequency: Hertz); | ||
| 160 | |||
| 161 | fn set_channel_frequency(channnel: usize, frequency: Hertz); | ||
| 162 | |||
| 163 | /// Set the dead time as a proportion of max_duty | ||
| 164 | fn set_channel_dead_time(channnel: usize, dead_time: u16); | ||
| 165 | |||
| 166 | // fn enable_outputs(enable: bool); | ||
| 167 | // | ||
| 168 | // fn enable_channel(&mut self, channel: usize, enable: bool); | ||
| 169 | } | ||
| 170 | |||
| 171 | pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance { | 60 | pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance { |
| 172 | /// Global output enable. Does not do anything on non-advanced timers. | 61 | /// Global output enable. Does not do anything on non-advanced timers. |
| 173 | fn enable_outputs(&mut self, enable: bool); | 62 | fn enable_outputs(&mut self, enable: bool); |
| @@ -200,12 +89,6 @@ pub(crate) mod sealed { | |||
| 200 | } | 89 | } |
| 201 | } | 90 | } |
| 202 | 91 | ||
| 203 | #[cfg(hrtim_v1)] | ||
| 204 | pub trait HighResolutionCaptureCompare16bitInstance: | ||
| 205 | sealed::HighResolutionCaptureCompare16bitInstance + 'static | ||
| 206 | { | ||
| 207 | } | ||
| 208 | |||
| 209 | pub trait CaptureCompare16bitInstance: | 92 | pub trait CaptureCompare16bitInstance: |
| 210 | sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static | 93 | sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static |
| 211 | { | 94 | { |
| @@ -367,88 +250,6 @@ foreach_interrupt! { | |||
| 367 | 250 | ||
| 368 | } | 251 | } |
| 369 | }; | 252 | }; |
| 370 | |||
| 371 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { | ||
| 372 | impl crate::pwm::sealed::HighResolutionCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 373 | fn set_master_frequency(frequency: Hertz) { | ||
| 374 | use crate::rcc::sealed::RccPeripheral; | ||
| 375 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 376 | |||
| 377 | let f = frequency.0; | ||
| 378 | let timer_f = Self::frequency().0; | ||
| 379 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 380 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 381 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 382 | } else { | ||
| 383 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 384 | }; | ||
| 385 | |||
| 386 | let psc_val: u32 = psc.into(); | ||
| 387 | let timer_f = 32 * (timer_f / psc_val); | ||
| 388 | let per: u16 = (timer_f / f) as u16; | ||
| 389 | |||
| 390 | let regs = Self::regs(); | ||
| 391 | |||
| 392 | regs.mcr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 393 | regs.mper().modify(|w| w.set_mper(per)); | ||
| 394 | } | ||
| 395 | |||
| 396 | fn set_channel_frequency(channel: usize, frequency: Hertz) { | ||
| 397 | use crate::rcc::sealed::RccPeripheral; | ||
| 398 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 399 | |||
| 400 | let f = frequency.0; | ||
| 401 | let timer_f = Self::frequency().0; | ||
| 402 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | ||
| 403 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 404 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 405 | } else { | ||
| 406 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 407 | }; | ||
| 408 | |||
| 409 | let psc_val: u32 = psc.into(); | ||
| 410 | let timer_f = 32 * (timer_f / psc_val); | ||
| 411 | let per: u16 = (timer_f / f) as u16; | ||
| 412 | |||
| 413 | let regs = Self::regs(); | ||
| 414 | |||
| 415 | regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); | ||
| 416 | regs.tim(channel).per().modify(|w| w.set_per(per)); | ||
| 417 | } | ||
| 418 | |||
| 419 | fn set_channel_dead_time(channel: usize, dead_time: u16) { | ||
| 420 | use crate::timer::sealed::HighResolutionControlInstance; | ||
| 421 | |||
| 422 | let regs = Self::regs(); | ||
| 423 | |||
| 424 | let channel_psc: HighResolutionControlPrescaler = regs.tim(channel).cr().read().ckpsc().into(); | ||
| 425 | let psc_val: u32 = channel_psc.into(); | ||
| 426 | |||
| 427 | |||
| 428 | // The dead-time base clock runs 4 times slower than the hrtim base clock | ||
| 429 | // u9::MAX = 511 | ||
| 430 | let psc_min = (psc_val * dead_time as u32) / (4 * 511); | ||
| 431 | let psc = if Self::regs().isr().read().dllrdy() { | ||
| 432 | HighResolutionControlPrescaler::compute_min_high_res(psc_min) | ||
| 433 | } else { | ||
| 434 | HighResolutionControlPrescaler::compute_min_low_res(psc_min) | ||
| 435 | }; | ||
| 436 | |||
| 437 | let dt_psc_val: u32 = psc.into(); | ||
| 438 | let dt_val = (dt_psc_val * dead_time as u32) / (4 * psc_val); | ||
| 439 | |||
| 440 | regs.tim(channel).dt().modify(|w| { | ||
| 441 | w.set_dtprsc(psc.into()); | ||
| 442 | w.set_dtf(dt_val as u16); | ||
| 443 | w.set_dtr(dt_val as u16); | ||
| 444 | }); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | impl HighResolutionCaptureCompare16bitInstance for crate::peripherals::$inst { | ||
| 449 | |||
| 450 | } | ||
| 451 | }; | ||
| 452 | } | 253 | } |
| 453 | 254 | ||
| 454 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | 255 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); |
