aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-25 15:33:57 -0500
committerxoviat <[email protected]>2023-06-30 18:21:42 -0500
commitcdb3fb059f32a5669856390cfe379da71092d545 (patch)
tree54722ba00c8ad1000d2bdcb53398f5a53a2d3348
parent45561f1622c9d883c8a9fa990c22a8a373d6ce5e (diff)
stm32/hrtim: first draft
-rw-r--r--embassy-stm32/build.rs10
-rw-r--r--embassy-stm32/src/pwm/advanced_pwm.rs147
-rw-r--r--embassy-stm32/src/pwm/mod.rs60
-rw-r--r--embassy-stm32/src/timer/mod.rs39
4 files changed, 256 insertions, 0 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 40103d322..4856047ce 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -589,6 +589,16 @@ fn main() {
589 (("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)), 589 (("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)),
590 (("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)), 590 (("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)),
591 (("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)), 591 (("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)),
592 (("hrtim", "CHA1"), quote!(crate::pwm::ChannelAPin)),
593 (("hrtim", "CHA2"), quote!(crate::pwm::ChannelAComplementaryPin)),
594 (("hrtim", "CHB1"), quote!(crate::pwm::ChannelBPin)),
595 (("hrtim", "CHB2"), quote!(crate::pwm::ChannelBComplementaryPin)),
596 (("hrtim", "CHC1"), quote!(crate::pwm::ChannelCPin)),
597 (("hrtim", "CHC2"), quote!(crate::pwm::ChannelCComplementaryPin)),
598 (("hrtim", "CHD1"), quote!(crate::pwm::ChannelDPin)),
599 (("hrtim", "CHD2"), quote!(crate::pwm::ChannelDComplementaryPin)),
600 (("hrtim", "CHE1"), quote!(crate::pwm::ChannelEPin)),
601 (("hrtim", "CHE2"), quote!(crate::pwm::ChannelEComplementaryPin)),
592 (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)), 602 (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)),
593 (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)), 603 (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)),
594 (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)), 604 (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)),
diff --git a/embassy-stm32/src/pwm/advanced_pwm.rs b/embassy-stm32/src/pwm/advanced_pwm.rs
new file mode 100644
index 000000000..39d60c50c
--- /dev/null
+++ b/embassy-stm32/src/pwm/advanced_pwm.rs
@@ -0,0 +1,147 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::{into_ref, PeripheralRef};
4
5use super::simple_pwm::*;
6use super::*;
7#[allow(unused_imports)]
8use crate::gpio::sealed::{AFType, Pin};
9use crate::gpio::AnyPin;
10use crate::time::Hertz;
11use crate::Peripheral;
12
13// Re-implement the channels for hrtim
14pub struct ChA;
15pub struct ChB;
16pub struct ChC;
17pub struct ChD;
18pub struct ChE;
19
20pub struct PwmPin<'d, Perip, Channel> {
21 _pin: PeripheralRef<'d, AnyPin>,
22 phantom: PhantomData<(Perip, Channel)>,
23}
24
25pub struct ComplementaryPwmPin<'d, Perip, Channel> {
26 _pin: PeripheralRef<'d, AnyPin>,
27 phantom: PhantomData<(Perip, Channel)>,
28}
29
30macro_rules! advanced_channel_impl {
31 ($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => {
32 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> {
33 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
34 into_ref!(pin);
35 critical_section::with(|_| {
36 pin.set_low();
37 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
38 #[cfg(gpio_v2)]
39 pin.set_speed(crate::gpio::Speed::VeryHigh);
40 });
41 PwmPin {
42 _pin: pin.map_into(),
43 phantom: PhantomData,
44 }
45 }
46 }
47
48 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> {
49 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
50 into_ref!(pin);
51 critical_section::with(|_| {
52 pin.set_low();
53 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
54 #[cfg(gpio_v2)]
55 pin.set_speed(crate::gpio::Speed::VeryHigh);
56 });
57 ComplementaryPwmPin {
58 _pin: pin.map_into(),
59 phantom: PhantomData,
60 }
61 }
62 }
63 };
64}
65
66advanced_channel_impl!(new_cha, ChA, ChannelAPin, ChannelAComplementaryPin);
67advanced_channel_impl!(new_chb, ChB, ChannelBPin, ChannelBComplementaryPin);
68advanced_channel_impl!(new_chc, ChC, ChannelCPin, ChannelCComplementaryPin);
69advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin);
70advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin);
71
72pub struct AdvancedPwm<'d, T> {
73 inner: PeripheralRef<'d, T>,
74}
75
76impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
77 pub fn new(
78 tim: impl Peripheral<P = T> + 'd,
79 _ch1: Option<PwmPin<'d, T, Ch1>>,
80 _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>,
81 _ch2: Option<PwmPin<'d, T, Ch2>>,
82 _ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>,
83 _ch3: Option<PwmPin<'d, T, Ch3>>,
84 _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>,
85 _ch4: Option<PwmPin<'d, T, Ch4>>,
86 _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>,
87 freq: Hertz,
88 ) -> Self {
89 Self::new_inner(tim, freq)
90 }
91
92 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self {
93 into_ref!(tim);
94
95 T::enable();
96 <T as crate::rcc::sealed::RccPeripheral>::reset();
97
98 let mut this = Self { inner: tim };
99 //
100 // this.inner.set_frequency(freq);
101 // this.inner.start();
102 //
103 // this.inner.enable_outputs(true);
104 //
105 // this.inner
106 // .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1);
107 // this.inner
108 // .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1);
109 // this.inner
110 // .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1);
111 // this.inner
112 // .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1);
113 this
114 }
115
116 pub fn enable(&mut self, channel: AdvancedChannel) {
117 // self.inner.enable_channel(channel, true);
118 // self.inner.enable_complementary_channel(channel, true);
119 }
120
121 pub fn disable(&mut self, channel: AdvancedChannel) {
122 // self.inner.enable_complementary_channel(channel, false);
123 // self.inner.enable_channel(channel, false);
124 }
125
126 pub fn set_freq(&mut self, freq: Hertz) {
127 // self.inner.set_frequency(freq);
128 }
129
130 pub fn get_max_duty(&self) -> u16 {
131 todo!()
132 // self.inner.get_max_compare_value()
133 }
134
135 pub fn set_duty(&mut self, channel: AdvancedChannel, duty: u16) {
136 // assert!(duty < self.get_max_duty());
137 // self.inner.set_compare_value(channel, duty)
138 }
139
140 /// Set the dead time as a proportion of max_duty
141 pub fn set_dead_time(&mut self, value: u16) {
142 // let (ckd, value) = compute_dead_time_value(value);
143 //
144 // self.inner.set_dead_time_clock_division(ckd);
145 // self.inner.set_dead_time_value(value);
146 }
147}
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
index 5aba2663e..4c2031348 100644
--- a/embassy-stm32/src/pwm/mod.rs
+++ b/embassy-stm32/src/pwm/mod.rs
@@ -1,3 +1,5 @@
1#[cfg(hrtim_v1)]
2pub mod advanced_pwm;
1pub mod complementary_pwm; 3pub mod complementary_pwm;
2pub mod simple_pwm; 4pub mod simple_pwm;
3 5
@@ -27,6 +29,29 @@ impl Channel {
27 } 29 }
28} 30}
29 31
32#[cfg(hrtim_v1)]
33#[derive(Clone, Copy)]
34pub enum AdvancedChannel {
35 ChA,
36 ChB,
37 ChC,
38 ChD,
39 ChE,
40}
41
42#[cfg(hrtim_v1)]
43impl AdvancedChannel {
44 pub fn raw(&self) -> usize {
45 match self {
46 AdvancedChannel::ChA => 0,
47 AdvancedChannel::ChB => 1,
48 AdvancedChannel::ChC => 2,
49 AdvancedChannel::ChD => 3,
50 AdvancedChannel::ChE => 4,
51 }
52 }
53}
54
30#[derive(Clone, Copy)] 55#[derive(Clone, Copy)]
31pub enum OutputCompareMode { 56pub enum OutputCompareMode {
32 Frozen, 57 Frozen,
@@ -57,6 +82,14 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
57pub(crate) mod sealed { 82pub(crate) mod sealed {
58 use super::*; 83 use super::*;
59 84
85 pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
86 fn enable_outputs(&mut self, enable: bool);
87
88 fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode);
89
90 fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool);
91 }
92
60 pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance { 93 pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance {
61 /// Global output enable. Does not do anything on non-advanced timers. 94 /// Global output enable. Does not do anything on non-advanced timers.
62 fn enable_outputs(&mut self, enable: bool); 95 fn enable_outputs(&mut self, enable: bool);
@@ -89,6 +122,8 @@ pub(crate) mod sealed {
89 } 122 }
90} 123}
91 124
125pub trait AdvancedCaptureCompare16bitInstance: sealed::AdvancedCaptureCompare16bitInstance + 'static {}
126
92pub trait CaptureCompare16bitInstance: 127pub trait CaptureCompare16bitInstance:
93 sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static 128 sealed::CaptureCompare16bitInstance + crate::timer::GeneralPurpose16bitInstance + 'static
94{ 129{
@@ -250,6 +285,20 @@ foreach_interrupt! {
250 285
251 } 286 }
252 }; 287 };
288
289 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
290 impl crate::pwm::sealed::AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
291 fn enable_outputs(&mut self, enable: bool) { todo!() }
292
293 fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode) { todo!() }
294
295 fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool) { todo!() }
296 }
297
298 impl AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
299
300 }
301 };
253} 302}
254 303
255pin_trait!(Channel1Pin, CaptureCompare16bitInstance); 304pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
@@ -267,3 +316,14 @@ pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
267pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance); 316pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
268pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance); 317pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
269pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance); 318pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
319
320pin_trait!(ChannelAPin, AdvancedCaptureCompare16bitInstance);
321pin_trait!(ChannelAComplementaryPin, AdvancedCaptureCompare16bitInstance);
322pin_trait!(ChannelBPin, AdvancedCaptureCompare16bitInstance);
323pin_trait!(ChannelBComplementaryPin, AdvancedCaptureCompare16bitInstance);
324pin_trait!(ChannelCPin, AdvancedCaptureCompare16bitInstance);
325pin_trait!(ChannelCComplementaryPin, AdvancedCaptureCompare16bitInstance);
326pin_trait!(ChannelDPin, AdvancedCaptureCompare16bitInstance);
327pin_trait!(ChannelDComplementaryPin, AdvancedCaptureCompare16bitInstance);
328pin_trait!(ChannelEPin, AdvancedCaptureCompare16bitInstance);
329pin_trait!(ChannelEComplementaryPin, AdvancedCaptureCompare16bitInstance);
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 09b7a3776..34ad5db11 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -43,6 +43,21 @@ pub(crate) mod sealed {
43 pub trait AdvancedControlInstance: GeneralPurpose16bitInstance { 43 pub trait AdvancedControlInstance: GeneralPurpose16bitInstance {
44 fn regs_advanced() -> crate::pac::timer::TimAdv; 44 fn regs_advanced() -> crate::pac::timer::TimAdv;
45 } 45 }
46
47 #[cfg(hrtim_v1)]
48 pub trait HighResolutionControlInstance: RccPeripheral {
49 type Interrupt: interrupt::typelevel::Interrupt;
50
51 fn regs_highres() -> crate::pac::hrtim::Hrtim;
52
53 fn start(&mut self);
54
55 fn stop(&mut self);
56
57 fn reset(&mut self);
58
59 fn set_frequency(&mut self, frequency: Hertz);
60 }
46} 61}
47 62
48pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {} 63pub trait GeneralPurpose16bitInstance: sealed::GeneralPurpose16bitInstance + 'static {}
@@ -51,6 +66,9 @@ pub trait GeneralPurpose32bitInstance: sealed::GeneralPurpose32bitInstance + 'st
51 66
52pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {} 67pub trait AdvancedControlInstance: sealed::AdvancedControlInstance + 'static {}
53 68
69#[cfg(hrtim_v1)]
70pub trait HighResolutionControlInstance: sealed::HighResolutionControlInstance + 'static {}
71
54pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {} 72pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {}
55 73
56#[allow(unused)] 74#[allow(unused)]
@@ -208,4 +226,25 @@ foreach_interrupt! {
208 impl AdvancedControlInstance for crate::peripherals::$inst { 226 impl AdvancedControlInstance for crate::peripherals::$inst {
209 } 227 }
210 }; 228 };
229
230 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
231 impl sealed::HighResolutionControlInstance for crate::peripherals::$inst {
232 type Interrupt = crate::interrupt::typelevel::$irq;
233
234 fn regs_highres() -> crate::pac::hrtim::Hrtim {
235 crate::pac::$inst
236 }
237
238 fn start(&mut self) { todo!() }
239
240 fn stop(&mut self) { todo!() }
241
242 fn reset(&mut self) { todo!() }
243
244 fn set_frequency(&mut self, frequency: Hertz) { todo!() }
245 }
246
247 impl HighResolutionControlInstance for crate::peripherals::$inst {
248 }
249 };
211} 250}