diff options
| author | xoviat <[email protected]> | 2023-06-26 20:23:26 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-06-30 18:21:57 -0500 |
| commit | b9eb3dfad7b601a7819377c2c94369ca74efc824 (patch) | |
| tree | 3413356af57549bc416fcec97475c253ac2547b2 | |
| parent | 71513ccb3905965aef2ae29a841dfdf4dfffe69a (diff) | |
stm32/hrtim: add api concept
| -rw-r--r-- | embassy-stm32/src/pwm/advanced_pwm.rs | 125 |
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; | |||
| 11 | use crate::Peripheral; | 11 | use crate::Peripheral; |
| 12 | 12 | ||
| 13 | // Re-implement the channels for hrtim | 13 | // Re-implement the channels for hrtim |
| 14 | pub struct ChA; | 14 | pub struct Master { |
| 15 | pub struct ChB; | 15 | phantom: PhantomData<bool>, |
| 16 | pub struct ChC; | 16 | } |
| 17 | pub struct ChD; | 17 | pub struct ChA { |
| 18 | pub struct ChE; | 18 | phantom: PhantomData<bool>, |
| 19 | } | ||
| 20 | pub struct ChB { | ||
| 21 | phantom: PhantomData<bool>, | ||
| 22 | } | ||
| 23 | pub struct ChC { | ||
| 24 | phantom: PhantomData<bool>, | ||
| 25 | } | ||
| 26 | pub struct ChD { | ||
| 27 | phantom: PhantomData<bool>, | ||
| 28 | } | ||
| 29 | pub struct ChE { | ||
| 30 | phantom: PhantomData<bool>, | ||
| 31 | } | ||
| 32 | |||
| 33 | mod sealed { | ||
| 34 | pub trait AdvancedChannel {} | ||
| 35 | } | ||
| 36 | |||
| 37 | pub trait AdvancedChannel: sealed::AdvancedChannel {} | ||
| 19 | 38 | ||
| 20 | pub struct PwmPin<'d, Perip, Channel> { | 39 | pub 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); | |||
| 69 | advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin); | 91 | advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin); |
| 70 | advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin); | 92 | advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin); |
| 71 | 93 | ||
| 94 | /// Struct used to divide a high resolution timer into multiple channels | ||
| 72 | pub struct AdvancedPwm<'d, T> { | 95 | pub 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 | ||
| 76 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> { | 105 | impl<'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 | ||
| 185 | pub struct BridgeConverter<T: AdvancedChannel> { | ||
| 186 | pub ch: T, | ||
| 187 | } | ||
| 125 | 188 | ||
| 126 | pub fn set_freq(&mut self, freq: Hertz) { | 189 | impl<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 | ||
| 200 | pub struct ResonantConverter<T: AdvancedChannel> { | ||
| 201 | pub ch: T, | ||
| 202 | } | ||
| 134 | 203 | ||
| 135 | pub fn set_duty(&mut self, channel: AdvancedChannel, duty: u16) { | 204 | impl<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 | } |
