aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/pwm/mod.rs32
-rw-r--r--embassy-stm32/src/timer/mod.rs138
2 files changed, 155 insertions, 15 deletions
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
index 4c2031348..1838bfdfe 100644
--- a/embassy-stm32/src/pwm/mod.rs
+++ b/embassy-stm32/src/pwm/mod.rs
@@ -29,7 +29,6 @@ impl Channel {
29 } 29 }
30} 30}
31 31
32#[cfg(hrtim_v1)]
33#[derive(Clone, Copy)] 32#[derive(Clone, Copy)]
34pub enum AdvancedChannel { 33pub enum AdvancedChannel {
35 ChA, 34 ChA,
@@ -39,7 +38,6 @@ pub enum AdvancedChannel {
39 ChE, 38 ChE,
40} 39}
41 40
42#[cfg(hrtim_v1)]
43impl AdvancedChannel { 41impl AdvancedChannel {
44 pub fn raw(&self) -> usize { 42 pub fn raw(&self) -> usize {
45 match self { 43 match self {
@@ -82,6 +80,7 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
82pub(crate) mod sealed { 80pub(crate) mod sealed {
83 use super::*; 81 use super::*;
84 82
83 #[cfg(hrtim_v1)]
85 pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance { 84 pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
86 fn enable_outputs(&mut self, enable: bool); 85 fn enable_outputs(&mut self, enable: bool);
87 86
@@ -122,6 +121,7 @@ pub(crate) mod sealed {
122 } 121 }
123} 122}
124 123
124#[cfg(hrtim_v1)]
125pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {} 125pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {}
126 126
127pub trait CaptureCompare16bitInstance: 127pub trait CaptureCompare16bitInstance:
@@ -317,13 +317,21 @@ pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
317pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); 317pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
318pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); 318pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
319 319
320pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance); 320#[cfg(hrtim_v1)]
321pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance); 321mod hrtim_pins {
322pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance); 322 use super::*;
323pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance); 323
324pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance); 324 pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance);
325pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance); 325 pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance);
326pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance); 326 pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance);
327pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance); 327 pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance);
328pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance); 328 pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance);
329pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance); 329 pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance);
330 pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance);
331 pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance);
332 pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance);
333 pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance);
334}
335
336#[cfg(hrtim_v1)]
337pub use hrtim_pins::*;
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 34ad5db11..03b9b3cf8 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -1,3 +1,6 @@
1#[cfg(hrtim_v1)]
2use core::ops;
3
1use stm32_metapac::timer::vals; 4use stm32_metapac::timer::vals;
2 5
3use crate::interrupt; 6use crate::interrupt;
@@ -50,13 +53,64 @@ pub(crate) mod sealed {
50 53
51 fn regs_highres() -> crate::pac::hrtim::Hrtim; 54 fn regs_highres() -> crate::pac::hrtim::Hrtim;
52 55
56 fn set_master_frequency(&mut self, frequency: Hertz);
57
58 fn set_channel_frequency(&mut self, channel: usize, frequency: Hertz);
59
53 fn start(&mut self); 60 fn start(&mut self);
54 61
55 fn stop(&mut self); 62 fn stop(&mut self);
56 63
57 fn reset(&mut self); 64 fn reset(&mut self);
65 }
66}
58 67
59 fn set_frequency(&mut self, frequency: Hertz); 68#[cfg(hrtim_v1)]
69#[derive(Clone, Copy)]
70pub(crate) enum HighResolutionControlPrescaler {
71 Div1,
72 Div2,
73 Div4,
74 Div8,
75 Div16,
76 Div32,
77 Div64,
78 Div128,
79}
80
81#[cfg(hrtim_v1)]
82impl ops::Div<HighResolutionControlPrescaler> for Hertz {
83 type Output = Hertz;
84
85 fn div(self, rhs: HighResolutionControlPrescaler) -> Self::Output {
86 let divisor = match rhs {
87 HighResolutionControlPrescaler::Div1 => 1,
88 HighResolutionControlPrescaler::Div2 => 2,
89 HighResolutionControlPrescaler::Div4 => 4,
90 HighResolutionControlPrescaler::Div8 => 8,
91 HighResolutionControlPrescaler::Div16 => 16,
92 HighResolutionControlPrescaler::Div32 => 32,
93 HighResolutionControlPrescaler::Div64 => 64,
94 HighResolutionControlPrescaler::Div128 => 128,
95 };
96
97 Hertz(self.0 / divisor)
98 }
99}
100
101#[cfg(hrtim_v1)]
102impl From<HighResolutionControlPrescaler> for u8 {
103 fn from(val: HighResolutionControlPrescaler) -> Self {
104 match val {
105 HighResolutionControlPrescaler::Div1 => 0b000,
106 HighResolutionControlPrescaler::Div2 => 0b001,
107 HighResolutionControlPrescaler::Div4 => 0b010,
108 HighResolutionControlPrescaler::Div8 => 0b011,
109 HighResolutionControlPrescaler::Div16 => 0b100,
110 HighResolutionControlPrescaler::Div32 => 0b101,
111 HighResolutionControlPrescaler::Div64 => 0b110,
112 HighResolutionControlPrescaler::Div128 => 0b111,
113 }
60 } 114 }
61} 115}
62 116
@@ -235,13 +289,91 @@ foreach_interrupt! {
235 crate::pac::$inst 289 crate::pac::$inst
236 } 290 }
237 291
292 fn set_master_frequency(&mut self, frequency: Hertz) {
293 use crate::rcc::sealed::RccPeripheral;
294
295 // TODO: fix frequency source
296 let f = frequency.0;
297 let timer_f = Self::frequency().0;
298 // Ratio taken from RM0364 Table 81
299 let base_f = Hertz(timer_f * (70_300 / 144_000_000));
300
301 /*
302 Find the smallest prescaler that allows us to acheive our frequency
303 */
304 let psc = [
305 HighResolutionControlPrescaler::Div1,
306 HighResolutionControlPrescaler::Div2,
307 HighResolutionControlPrescaler::Div4,
308 HighResolutionControlPrescaler::Div8,
309 HighResolutionControlPrescaler::Div16,
310 HighResolutionControlPrescaler::Div32,
311 HighResolutionControlPrescaler::Div64,
312 HighResolutionControlPrescaler::Div128,
313 ]
314 .iter()
315 .skip_while(|psc| frequency < base_f / **psc)
316 .next()
317 .unwrap();
318
319 let psc_timer_f = Hertz(timer_f) / *psc;
320 let per: u16 = (psc_timer_f / f).0 as u16;
321
322 let regs = Self::regs_highres();
323
324 regs.mcr().modify(|w| w.set_ckpsc(((*psc).into())));
325 regs.mper().modify(|w| w.set_mper(per));
326
327 // regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY));
328 // regs.egr().write(|r| r.set_ug(true));
329 // regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT));
330 }
331
332 fn set_channel_frequency(&mut self, channel: usize, frequency: Hertz) {
333 use crate::rcc::sealed::RccPeripheral;
334
335 // TODO: fix frequency source
336 let f = frequency.0;
337 let timer_f = Self::frequency().0;
338 // Ratio taken from RM0364 Table 81
339 let base_f = Hertz(timer_f * (70_300 / 144_000_000));
340
341 /*
342 Find the smallest prescaler that allows us to acheive our frequency
343 */
344 let psc = [
345 HighResolutionControlPrescaler::Div1,
346 HighResolutionControlPrescaler::Div2,
347 HighResolutionControlPrescaler::Div4,
348 HighResolutionControlPrescaler::Div8,
349 HighResolutionControlPrescaler::Div16,
350 HighResolutionControlPrescaler::Div32,
351 HighResolutionControlPrescaler::Div64,
352 HighResolutionControlPrescaler::Div128,
353 ]
354 .iter()
355 .skip_while(|psc| frequency < base_f / **psc)
356 .next()
357 .unwrap();
358
359 let psc_timer_f = Hertz(timer_f) / *psc;
360 let per: u16 = (psc_timer_f / f).0 as u16;
361
362 let regs = Self::regs_highres();
363
364 regs.tim(channel).cr().modify(|w| w.set_ckpsc(((*psc).into())));
365 regs.tim(channel).per().modify(|w| w.set_per(per));
366
367 // regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY));
368 // regs.egr().write(|r| r.set_ug(true));
369 // regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT));
370 }
371
238 fn start(&mut self) { todo!() } 372 fn start(&mut self) { todo!() }
239 373
240 fn stop(&mut self) { todo!() } 374 fn stop(&mut self) { todo!() }
241 375
242 fn reset(&mut self) { todo!() } 376 fn reset(&mut self) { todo!() }
243
244 fn set_frequency(&mut self, frequency: Hertz) { todo!() }
245 } 377 }
246 378
247 impl HighResolutionControlInstance for crate::peripherals::$inst { 379 impl HighResolutionControlInstance for crate::peripherals::$inst {