aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-27 18:24:32 -0500
committerxoviat <[email protected]>2023-06-30 18:21:58 -0500
commit348019e37f0ff5716d80199e33244c0a1a59b360 (patch)
tree64cee936aacbc8b93883c4edf60aedf661228666
parentb9eb3dfad7b601a7819377c2c94369ca74efc824 (diff)
stm32/hrtim: impl channel alloc type system
-rw-r--r--embassy-stm32/src/pwm/advanced_pwm.rs167
-rw-r--r--embassy-stm32/src/pwm/mod.rs144
-rw-r--r--embassy-stm32/src/timer/mod.rs149
3 files changed, 194 insertions, 266 deletions
diff --git a/embassy-stm32/src/pwm/advanced_pwm.rs b/embassy-stm32/src/pwm/advanced_pwm.rs
index a08952248..c7b5f7482 100644
--- a/embassy-stm32/src/pwm/advanced_pwm.rs
+++ b/embassy-stm32/src/pwm/advanced_pwm.rs
@@ -2,7 +2,6 @@ use core::marker::PhantomData;
2 2
3use embassy_hal_common::{into_ref, PeripheralRef}; 3use embassy_hal_common::{into_ref, PeripheralRef};
4 4
5use super::simple_pwm::*;
6use super::*; 5use super::*;
7#[allow(unused_imports)] 6#[allow(unused_imports)]
8use crate::gpio::sealed::{AFType, Pin}; 7use crate::gpio::sealed::{AFType, Pin};
@@ -11,30 +10,34 @@ use crate::time::Hertz;
11use crate::Peripheral; 10use crate::Peripheral;
12 11
13// Re-implement the channels for hrtim 12// Re-implement the channels for hrtim
14pub struct Master { 13pub struct Master<T: AdvancedCaptureCompare16bitInstance> {
15 phantom: PhantomData<bool>, 14 phantom: PhantomData<T>,
16} 15}
17pub struct ChA { 16pub struct ChA<T: AdvancedCaptureCompare16bitInstance> {
18 phantom: PhantomData<bool>, 17 phantom: PhantomData<T>,
19} 18}
20pub struct ChB { 19pub struct ChB<T: AdvancedCaptureCompare16bitInstance> {
21 phantom: PhantomData<bool>, 20 phantom: PhantomData<T>,
22} 21}
23pub struct ChC { 22pub struct ChC<T: AdvancedCaptureCompare16bitInstance> {
24 phantom: PhantomData<bool>, 23 phantom: PhantomData<T>,
25} 24}
26pub struct ChD { 25pub struct ChD<T: AdvancedCaptureCompare16bitInstance> {
27 phantom: PhantomData<bool>, 26 phantom: PhantomData<T>,
28} 27}
29pub struct ChE { 28pub struct ChE<T: AdvancedCaptureCompare16bitInstance> {
30 phantom: PhantomData<bool>, 29 phantom: PhantomData<T>,
31} 30}
32 31
33mod sealed { 32mod sealed {
34 pub trait AdvancedChannel {} 33 use crate::pwm::AdvancedCaptureCompare16bitInstance;
34
35 pub trait AdvancedChannel<T: AdvancedCaptureCompare16bitInstance> {}
35} 36}
36 37
37pub trait AdvancedChannel: sealed::AdvancedChannel {} 38pub trait AdvancedChannel<T: AdvancedCaptureCompare16bitInstance>: sealed::AdvancedChannel<T> {
39 fn raw() -> usize;
40}
38 41
39pub struct PwmPin<'d, Perip, Channel> { 42pub struct PwmPin<'d, Perip, Channel> {
40 _pin: PeripheralRef<'d, AnyPin>, 43 _pin: PeripheralRef<'d, AnyPin>,
@@ -47,8 +50,8 @@ pub struct ComplementaryPwmPin<'d, Perip, Channel> {
47} 50}
48 51
49macro_rules! advanced_channel_impl { 52macro_rules! advanced_channel_impl {
50 ($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => { 53 ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => {
51 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> { 54 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> PwmPin<'d, Perip, $channel<Perip>> {
52 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self { 55 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
53 into_ref!(pin); 56 into_ref!(pin);
54 critical_section::with(|_| { 57 critical_section::with(|_| {
@@ -64,7 +67,7 @@ macro_rules! advanced_channel_impl {
64 } 67 }
65 } 68 }
66 69
67 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> { 70 impl<'d, Perip: AdvancedCaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel<Perip>> {
68 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self { 71 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self {
69 into_ref!(pin); 72 into_ref!(pin);
70 critical_section::with(|_| { 73 critical_section::with(|_| {
@@ -80,39 +83,45 @@ macro_rules! advanced_channel_impl {
80 } 83 }
81 } 84 }
82 85
83 impl sealed::AdvancedChannel for $channel {} 86 impl<T: AdvancedCaptureCompare16bitInstance> sealed::AdvancedChannel<T> for $channel<T> {}
84 impl AdvancedChannel for $channel {} 87 impl<T: AdvancedCaptureCompare16bitInstance> AdvancedChannel<T> for $channel<T> {
88 fn raw() -> usize {
89 $ch_num
90 }
91 }
85 }; 92 };
86} 93}
87 94
88advanced_channel_impl!(new_cha, ChA, ChannelAPin, ChannelAComplementaryPin); 95advanced_channel_impl!(new_cha, ChA, 0, ChannelAPin, ChannelAComplementaryPin);
89advanced_channel_impl!(new_chb, ChB, ChannelBPin, ChannelBComplementaryPin); 96advanced_channel_impl!(new_chb, ChB, 1, ChannelBPin, ChannelBComplementaryPin);
90advanced_channel_impl!(new_chc, ChC, ChannelCPin, ChannelCComplementaryPin); 97advanced_channel_impl!(new_chc, ChC, 2, ChannelCPin, ChannelCComplementaryPin);
91advanced_channel_impl!(new_chd, ChD, ChannelDPin, ChannelDComplementaryPin); 98advanced_channel_impl!(new_chd, ChD, 3, ChannelDPin, ChannelDComplementaryPin);
92advanced_channel_impl!(new_che, ChE, ChannelEPin, ChannelEComplementaryPin); 99advanced_channel_impl!(new_che, ChE, 4, ChannelEPin, ChannelEComplementaryPin);
93 100
94/// Struct used to divide a high resolution timer into multiple channels 101/// Struct used to divide a high resolution timer into multiple channels
95pub struct AdvancedPwm<'d, T> { 102pub struct AdvancedPwm<'d, T: AdvancedCaptureCompare16bitInstance> {
96 inner: PeripheralRef<'d, T>, 103 _inner: PeripheralRef<'d, T>,
97 pub master: Master, 104 pub master: Master<T>,
98 pub ch_a: ChA, 105 pub ch_a: ChA<T>,
99 pub ch_b: ChB, 106 pub ch_b: ChB<T>,
100 pub ch_c: ChC, 107 pub ch_c: ChC<T>,
101 pub ch_d: ChD, 108 pub ch_d: ChD<T>,
102 pub ch_e: ChE, 109 pub ch_e: ChE<T>,
103} 110}
104 111
105impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> { 112impl<'d, T: AdvancedCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
106 pub fn new( 113 pub fn new(
107 tim: impl Peripheral<P = T> + 'd, 114 tim: impl Peripheral<P = T> + 'd,
108 _ch1: Option<PwmPin<'d, T, Ch1>>, 115 _cha: Option<PwmPin<'d, T, ChA<T>>>,
109 _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>, 116 _chan: Option<ComplementaryPwmPin<'d, T, ChA<T>>>,
110 _ch2: Option<PwmPin<'d, T, Ch2>>, 117 _chb: Option<PwmPin<'d, T, ChB<T>>>,
111 _ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>, 118 _chbn: Option<ComplementaryPwmPin<'d, T, ChB<T>>>,
112 _ch3: Option<PwmPin<'d, T, Ch3>>, 119 _chc: Option<PwmPin<'d, T, ChC<T>>>,
113 _ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>, 120 _chcn: Option<ComplementaryPwmPin<'d, T, ChC<T>>>,
114 _ch4: Option<PwmPin<'d, T, Ch4>>, 121 _chd: Option<PwmPin<'d, T, ChD<T>>>,
115 _ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>, 122 _chdn: Option<ComplementaryPwmPin<'d, T, ChD<T>>>,
123 _che: Option<PwmPin<'d, T, ChE<T>>>,
124 _chen: Option<ComplementaryPwmPin<'d, T, ChE<T>>>,
116 ) -> Self { 125 ) -> Self {
117 Self::new_inner(tim) 126 Self::new_inner(tim)
118 } 127 }
@@ -124,7 +133,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
124 <T as crate::rcc::sealed::RccPeripheral>::reset(); 133 <T as crate::rcc::sealed::RccPeripheral>::reset();
125 134
126 Self { 135 Self {
127 inner: tim, 136 _inner: tim,
128 master: Master { phantom: PhantomData }, 137 master: Master { phantom: PhantomData },
129 ch_a: ChA { phantom: PhantomData }, 138 ch_a: ChA { phantom: PhantomData },
130 ch_b: ChB { phantom: PhantomData }, 139 ch_b: ChB { phantom: PhantomData },
@@ -132,48 +141,11 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
132 ch_d: ChD { phantom: PhantomData }, 141 ch_d: ChD { phantom: PhantomData },
133 ch_e: ChE { phantom: PhantomData }, 142 ch_e: ChE { phantom: PhantomData },
134 } 143 }
135 //
136 // this.inner.set_frequency(freq);
137 // this.inner.start();
138 //
139 // this.inner.enable_outputs(true);
140 //
141 // this.inner
142 // .set_output_compare_mode(Channel::Ch1, OutputCompareMode::PwmMode1);
143 // this.inner
144 // .set_output_compare_mode(Channel::Ch2, OutputCompareMode::PwmMode1);
145 // this.inner
146 // .set_output_compare_mode(Channel::Ch3, OutputCompareMode::PwmMode1);
147 // this.inner
148 // .set_output_compare_mode(Channel::Ch4, OutputCompareMode::PwmMode1);
149 } 144 }
150 145
151 // pub fn enable(&mut self, channel: AdvancedChannel) {
152 // // self.inner.enable_channel(channel, true);
153 // // self.inner.enable_complementary_channel(channel, true);
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 // }
174
175 /// Set the dead time as a proportion of max_duty 146 /// Set the dead time as a proportion of max_duty
176 pub fn set_dead_time(&mut self, value: u16) { 147 pub fn set_dead_time(&mut self, _value: u16) {
148 todo!()
177 // let (ckd, value) = compute_dead_time_value(value); 149 // let (ckd, value) = compute_dead_time_value(value);
178 // 150 //
179 // self.inner.set_dead_time_clock_division(ckd); 151 // self.inner.set_dead_time_clock_division(ckd);
@@ -182,28 +154,39 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> AdvancedPwm<'d, T> {
182} 154}
183 155
184// Represents a fixed-frequency bridge converter 156// Represents a fixed-frequency bridge converter
185pub struct BridgeConverter<T: AdvancedChannel> { 157pub struct BridgeConverter<T: AdvancedCaptureCompare16bitInstance, C: AdvancedChannel<T>> {
186 pub ch: T, 158 phantom: PhantomData<T>,
159 pub ch: C,
187} 160}
188 161
189impl<T: AdvancedChannel> BridgeConverter<T> { 162impl<T: AdvancedCaptureCompare16bitInstance, C: AdvancedChannel<T>> BridgeConverter<T, C> {
190 pub fn new(channel: T, frequency: Hertz) -> Self { 163 pub fn new(channel: C, frequency: Hertz) -> Self {
191 Self { ch: channel } 164 Self {
165 phantom: PhantomData,
166 ch: channel,
167 }
192 } 168 }
193 169
194 pub fn set_duty(&mut self, primary: u16, secondary: u16) { 170 pub fn set_duty(&mut self, primary: u16, secondary: u16) {
171 let _ = T::regs();
172 let _ = C::raw();
173
195 todo!() 174 todo!()
196 } 175 }
197} 176}
198 177
199// Represents a variable-frequency resonant converter 178// Represents a variable-frequency resonant converter
200pub struct ResonantConverter<T: AdvancedChannel> { 179pub struct ResonantConverter<T: AdvancedCaptureCompare16bitInstance, C: AdvancedChannel<T>> {
201 pub ch: T, 180 phantom: PhantomData<T>,
181 pub ch: C,
202} 182}
203 183
204impl<T: AdvancedChannel> ResonantConverter<T> { 184impl<T: AdvancedCaptureCompare16bitInstance, C: AdvancedChannel<T>> ResonantConverter<T, C> {
205 pub fn new(channel: T, min_frequency: Hertz) -> Self { 185 pub fn new(channel: C, min_frequency: Hertz) -> Self {
206 Self { ch: channel } 186 Self {
187 phantom: PhantomData,
188 ch: channel,
189 }
207 } 190 }
208 191
209 pub fn set_frequency(&mut self, frequency: Hertz) { 192 pub fn set_frequency(&mut self, frequency: Hertz) {
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
index 1838bfdfe..67009e788 100644
--- a/embassy-stm32/src/pwm/mod.rs
+++ b/embassy-stm32/src/pwm/mod.rs
@@ -3,8 +3,14 @@ pub mod advanced_pwm;
3pub mod complementary_pwm; 3pub mod complementary_pwm;
4pub mod simple_pwm; 4pub mod simple_pwm;
5 5
6#[cfg(hrtim_v1)]
7use core::ops;
8
6use stm32_metapac::timer::vals::Ckd; 9use stm32_metapac::timer::vals::Ckd;
7 10
11#[cfg(hrtim_v1)]
12use crate::time::Hertz;
13
8#[cfg(feature = "unstable-pac")] 14#[cfg(feature = "unstable-pac")]
9pub mod low_level { 15pub mod low_level {
10 pub use super::sealed::*; 16 pub use super::sealed::*;
@@ -30,27 +36,6 @@ impl Channel {
30} 36}
31 37
32#[derive(Clone, Copy)] 38#[derive(Clone, Copy)]
33pub enum AdvancedChannel {
34 ChA,
35 ChB,
36 ChC,
37 ChD,
38 ChE,
39}
40
41impl AdvancedChannel {
42 pub fn raw(&self) -> usize {
43 match self {
44 AdvancedChannel::ChA => 0,
45 AdvancedChannel::ChB => 1,
46 AdvancedChannel::ChC => 2,
47 AdvancedChannel::ChD => 3,
48 AdvancedChannel::ChE => 4,
49 }
50 }
51}
52
53#[derive(Clone, Copy)]
54pub enum OutputCompareMode { 39pub enum OutputCompareMode {
55 Frozen, 40 Frozen,
56 ActiveOnMatch, 41 ActiveOnMatch,
@@ -77,16 +62,87 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
77 } 62 }
78} 63}
79 64
65#[cfg(hrtim_v1)]
66#[derive(Clone, Copy)]
67pub(crate) enum HighResolutionControlPrescaler {
68 Div1,
69 Div2,
70 Div4,
71 Div8,
72 Div16,
73 Div32,
74 Div64,
75 Div128,
76}
77
78#[cfg(hrtim_v1)]
79impl ops::Div<HighResolutionControlPrescaler> for Hertz {
80 type Output = Hertz;
81
82 fn div(self, rhs: HighResolutionControlPrescaler) -> Self::Output {
83 let divisor = match rhs {
84 HighResolutionControlPrescaler::Div1 => 1,
85 HighResolutionControlPrescaler::Div2 => 2,
86 HighResolutionControlPrescaler::Div4 => 4,
87 HighResolutionControlPrescaler::Div8 => 8,
88 HighResolutionControlPrescaler::Div16 => 16,
89 HighResolutionControlPrescaler::Div32 => 32,
90 HighResolutionControlPrescaler::Div64 => 64,
91 HighResolutionControlPrescaler::Div128 => 128,
92 };
93
94 Hertz(self.0 / divisor)
95 }
96}
97
98#[cfg(hrtim_v1)]
99impl From<HighResolutionControlPrescaler> for u8 {
100 fn from(val: HighResolutionControlPrescaler) -> Self {
101 match val {
102 HighResolutionControlPrescaler::Div1 => 0b000,
103 HighResolutionControlPrescaler::Div2 => 0b001,
104 HighResolutionControlPrescaler::Div4 => 0b010,
105 HighResolutionControlPrescaler::Div8 => 0b011,
106 HighResolutionControlPrescaler::Div16 => 0b100,
107 HighResolutionControlPrescaler::Div32 => 0b101,
108 HighResolutionControlPrescaler::Div64 => 0b110,
109 HighResolutionControlPrescaler::Div128 => 0b111,
110 }
111 }
112}
113
114#[cfg(hrtim_v1)]
115impl HighResolutionControlPrescaler {
116 pub fn compute_min(base_f: Hertz, frequency: Hertz) -> Self {
117 *[
118 HighResolutionControlPrescaler::Div1,
119 HighResolutionControlPrescaler::Div2,
120 HighResolutionControlPrescaler::Div4,
121 HighResolutionControlPrescaler::Div8,
122 HighResolutionControlPrescaler::Div16,
123 HighResolutionControlPrescaler::Div32,
124 HighResolutionControlPrescaler::Div64,
125 HighResolutionControlPrescaler::Div128,
126 ]
127 .iter()
128 .skip_while(|psc| frequency <= base_f / **psc)
129 .next()
130 .unwrap()
131 }
132}
133
80pub(crate) mod sealed { 134pub(crate) mod sealed {
81 use super::*; 135 use super::*;
82 136
83 #[cfg(hrtim_v1)] 137 #[cfg(hrtim_v1)]
84 pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance { 138 pub trait AdvancedCaptureCompare16bitInstance: crate::timer::sealed::HighResolutionControlInstance {
85 fn enable_outputs(&mut self, enable: bool); 139 fn set_master_frequency(frequency: Hertz);
86 140
87 fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode); 141 fn set_channel_frequency(channnel: usize, frequency: Hertz);
88 142
89 fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool); 143 // fn enable_outputs(enable: bool);
144 //
145 // fn enable_channel(&mut self, channel: usize, enable: bool);
90 } 146 }
91 147
92 pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance { 148 pub trait CaptureCompare16bitInstance: crate::timer::sealed::GeneralPurpose16bitInstance {
@@ -288,11 +344,45 @@ foreach_interrupt! {
288 344
289 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { 345 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
290 impl crate::pwm::sealed::AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst { 346 impl crate::pwm::sealed::AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
291 fn enable_outputs(&mut self, enable: bool) { todo!() } 347 fn set_master_frequency(frequency: Hertz) {
348 use crate::rcc::sealed::RccPeripheral;
349 use crate::timer::sealed::HighResolutionControlInstance;
350
351 let f = frequency.0;
352 // TODO: fix frequency source
353 // let timer_f = Self::frequency().0;
354 let timer_f = Hertz(144_000_000).0;
355 let base_f = Hertz((32 * timer_f as u64 / u16::MAX as u64) as u32);
356 let psc = HighResolutionControlPrescaler::compute_min(base_f, frequency);
357
358 let psc_timer_f = Hertz(timer_f) / psc;
359 let per: u16 = (psc_timer_f / f).0 as u16;
360
361 let regs = Self::regs();
362
363 regs.mcr().modify(|w| w.set_ckpsc(psc.into()));
364 regs.mper().modify(|w| w.set_mper(per));
365 }
366
367 fn set_channel_frequency(channel: usize, frequency: Hertz) {
368 use crate::rcc::sealed::RccPeripheral;
369 use crate::timer::sealed::HighResolutionControlInstance;
370
371 let f = frequency.0;
372 // TODO: fix frequency source
373 // let timer_f = Self::frequency().0;
374 let timer_f = Hertz(144_000_000).0;
375 let base_f = Hertz((32 * timer_f as u64 / u16::MAX as u64) as u32);
376 let psc = HighResolutionControlPrescaler::compute_min(base_f, frequency);
292 377
293 fn set_output_compare_mode(&mut self, channel: AdvancedChannel, mode: OutputCompareMode) { todo!() } 378 let psc_timer_f = Hertz(timer_f) / psc;
379 let per: u16 = (psc_timer_f / f).0 as u16;
294 380
295 fn enable_channel(&mut self, channel: AdvancedChannel, enable: bool) { todo!() } 381 let regs = Self::regs();
382
383 regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into()));
384 regs.tim(channel).per().modify(|w| w.set_per(per));
385 }
296 } 386 }
297 387
298 impl AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst { 388 impl AdvancedCaptureCompare16bitInstance for crate::peripherals::$inst {
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 03b9b3cf8..89cb16668 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -51,66 +51,7 @@ pub(crate) mod sealed {
51 pub trait HighResolutionControlInstance: RccPeripheral { 51 pub trait HighResolutionControlInstance: RccPeripheral {
52 type Interrupt: interrupt::typelevel::Interrupt; 52 type Interrupt: interrupt::typelevel::Interrupt;
53 53
54 fn regs_highres() -> crate::pac::hrtim::Hrtim; 54 fn regs() -> crate::pac::hrtim::Hrtim;
55
56 fn set_master_frequency(&mut self, frequency: Hertz);
57
58 fn set_channel_frequency(&mut self, channel: usize, frequency: Hertz);
59
60 fn start(&mut self);
61
62 fn stop(&mut self);
63
64 fn reset(&mut self);
65 }
66}
67
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 }
114 } 55 }
115} 56}
116 57
@@ -285,95 +226,9 @@ foreach_interrupt! {
285 impl sealed::HighResolutionControlInstance for crate::peripherals::$inst { 226 impl sealed::HighResolutionControlInstance for crate::peripherals::$inst {
286 type Interrupt = crate::interrupt::typelevel::$irq; 227 type Interrupt = crate::interrupt::typelevel::$irq;
287 228
288 fn regs_highres() -> crate::pac::hrtim::Hrtim { 229 fn regs() -> crate::pac::hrtim::Hrtim {
289 crate::pac::$inst 230 crate::pac::$inst
290 } 231 }
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
372 fn start(&mut self) { todo!() }
373
374 fn stop(&mut self) { todo!() }
375
376 fn reset(&mut self) { todo!() }
377 } 232 }
378 233
379 impl HighResolutionControlInstance for crate::peripherals::$inst { 234 impl HighResolutionControlInstance for crate::peripherals::$inst {