aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-26 20:23:26 -0500
committerxoviat <[email protected]>2023-06-30 18:21:57 -0500
commitb9eb3dfad7b601a7819377c2c94369ca74efc824 (patch)
tree3413356af57549bc416fcec97475c253ac2547b2
parent71513ccb3905965aef2ae29a841dfdf4dfffe69a (diff)
stm32/hrtim: add api concept
-rw-r--r--embassy-stm32/src/pwm/advanced_pwm.rs125
1 files changed, 95 insertions, 30 deletions
diff --git a/embassy-stm32/src/pwm/advanced_pwm.rs b/embassy-stm32/src/pwm/advanced_pwm.rs
index 39d60c50c..a08952248 100644
--- a/embassy-stm32/src/pwm/advanced_pwm.rs
+++ b/embassy-stm32/src/pwm/advanced_pwm.rs
@@ -11,11 +11,30 @@ use crate::time::Hertz;
11use crate::Peripheral; 11use crate::Peripheral;
12 12
13// Re-implement the channels for hrtim 13// Re-implement the channels for hrtim
14pub struct ChA; 14pub struct Master {
15pub struct ChB; 15 phantom: PhantomData<bool>,
16pub struct ChC; 16}
17pub struct ChD; 17pub struct ChA {
18pub struct ChE; 18 phantom: PhantomData<bool>,
19}
20pub struct ChB {
21 phantom: PhantomData<bool>,
22}
23pub struct ChC {
24 phantom: PhantomData<bool>,
25}
26pub struct ChD {
27 phantom: PhantomData<bool>,
28}
29pub struct ChE {
30 phantom: PhantomData<bool>,
31}
32
33mod sealed {
34 pub trait AdvancedChannel {}
35}
36
37pub trait AdvancedChannel: sealed::AdvancedChannel {}
19 38
20pub struct PwmPin<'d, Perip, Channel> { 39pub struct PwmPin<'d, Perip, Channel> {
21 _pin: PeripheralRef<'d, AnyPin>, 40 _pin: PeripheralRef<'d, AnyPin>,
@@ -60,6 +79,9 @@ macro_rules! advanced_channel_impl {
60 } 79 }
61 } 80 }
62 } 81 }
82
83 impl sealed::AdvancedChannel for $channel {}
84 impl AdvancedChannel for $channel {}
63 }; 85 };
64} 86}
65 87
@@ -69,8 +91,15 @@ advanced_channel_impl!(new_chc, ChC, ChannelCPin, ChannelCComplementaryPin);
69advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin); 91advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin);
70advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin); 92advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin);
71 93
94/// Struct used to divide a high resolution timer into multiple channels
72pub struct AdvancedPwm<'d, T> { 95pub struct AdvancedPwm<'d, T> {
73 inner: PeripheralRef<'d, T>, 96 inner: PeripheralRef<'d, T>,
97 pub master: Master,
98 pub ch_a: ChA,
99 pub ch_b: ChB,
100 pub ch_c: ChC,
101 pub ch_d: ChD,
102 pub ch_e: ChE,
74} 103}
75 104
76impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> { 105impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
@@ -84,18 +113,25 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
84 _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>, 113 _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>,
85 _ch4: Option<PwmPin<'d, T, Ch4>>, 114 _ch4: Option<PwmPin<'d, T, Ch4>>,
86 _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>, 115 _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>,
87 freq: Hertz,
88 ) -> Self { 116 ) -> Self {
89 Self::new_inner(tim, freq) 117 Self::new_inner(tim)
90 } 118 }
91 119
92 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self { 120 fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self {
93 into_ref!(tim); 121 into_ref!(tim);
94 122
95 T::enable(); 123 T::enable();
96 <T as crate::rcc::sealed::RccPeripheral>::reset(); 124 <T as crate::rcc::sealed::RccPeripheral>::reset();
97 125
98 let mut this = Self { inner: tim }; 126 Self {
127 inner: tim,
128 master: Master { phantom: PhantomData },
129 ch_a: ChA { phantom: PhantomData },
130 ch_b: ChB { phantom: PhantomData },
131 ch_c: ChC { phantom: PhantomData },
132 ch_d: ChD { phantom: PhantomData },
133 ch_e: ChE { phantom: PhantomData },
134 }
99 // 135 //
100 // this.inner.set_frequency(freq); 136 // this.inner.set_frequency(freq);
101 // this.inner.start(); 137 // this.inner.start();
@@ -110,38 +146,67 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
110 // .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1); 146 // .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1);
111 // this.inner 147 // this.inner
112 // .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1); 148 // .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1);
113 this
114 } 149 }
115 150
116 pub fn enable(&mut self, channel: AdvancedChannel) { 151 // pub fn enable(&mut self, channel: AdvancedChannel) {
117 // self.inner.enable_channel(channel, true); 152 // // self.inner.enable_channel(channel, true);
118 // self.inner.enable_complementary_channel(channel, true); 153 // // self.inner.enable_complementary_channel(channel, true);
119 } 154 // }
155 //
156 // pub fn disable(&mut self, channel: AdvancedChannel) {
157 // // self.inner.enable_complementary_channel(channel, false);
158 // // self.inner.enable_channel(channel, false);
159 // }
160 //
161 // pub fn set_freq(&mut self, freq: Hertz) {
162 // // self.inner.set_frequency(freq);
163 // }
164 //
165 // pub fn get_max_duty(&self) -> u16 {
166 // todo!()
167 // // self.inner.get_max_compare_value()
168 // }
169 //
170 // pub fn set_duty(&mut self, channel: AdvancedChannel, duty: u16) {
171 // // assert!(duty < self.get_max_duty());
172 // // self.inner.set_compare_value(channel, duty)
173 // }
120 174
121 pub fn disable(&mut self, channel: AdvancedChannel) { 175 /// Set the dead time as a proportion of max_duty
122 // self.inner.enable_complementary_channel(channel, false); 176 pub fn set_dead_time(&mut self, value: u16) {
123 // self.inner.enable_channel(channel, false); 177 // let (ckd, value) = compute_dead_time_value(value);
178 //
179 // self.inner.set_dead_time_clock_division(ckd);
180 // self.inner.set_dead_time_value(value);
124 } 181 }
182}
183
184// Represents a fixed-frequency bridge converter
185pub struct BridgeConverter<T: AdvancedChannel> {
186 pub ch: T,
187}
125 188
126 pub fn set_freq(&mut self, freq: Hertz) { 189impl<T: AdvancedChannel> BridgeConverter<T> {
127 // self.inner.set_frequency(freq); 190 pub fn new(channel: T, frequency: Hertz) -> Self {
191 Self { ch: channel }
128 } 192 }
129 193
130 pub fn get_max_duty(&self) -> u16 { 194 pub fn set_duty(&mut self, primary: u16, secondary: u16) {
131 todo!() 195 todo!()
132 // self.inner.get_max_compare_value()
133 } 196 }
197}
198
199// Represents a variable-frequency resonant converter
200pub struct ResonantConverter<T: AdvancedChannel> {
201 pub ch: T,
202}
134 203
135 pub fn set_duty(&mut self, channel: AdvancedChannel, duty: u16) { 204impl<T: AdvancedChannel> ResonantConverter<T> {
136 // assert!(duty < self.get_max_duty()); 205 pub fn new(channel: T, min_frequency: Hertz) -> Self {
137 // self.inner.set_compare_value(channel, duty) 206 Self { ch: channel }
138 } 207 }
139 208
140 /// Set the dead time as a proportion of max_duty 209 pub fn set_frequency(&mut self, frequency: Hertz) {
141 pub fn set_dead_time(&mut self, value: u16) { 210 todo!()
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 } 211 }
147} 212}