1use super::sealed::{Split, SplitCapture};
20use super::{
21 CPin, CaptureFilter, CaptureMode, CapturePolarity, CapturePrescaler, Instance, Timer,
22 WithCapture,
23};
24pub use super::{Ch, C1, C2, C3, C4};
25use crate::gpio::PushPull;
26use crate::rcc::Rcc;
27use core::ops::{Deref, DerefMut};
28use fugit::HertzU32 as Hertz;
29
30pub trait CaptureExt
31where
32 Self: Sized + Instance + WithCapture + SplitCapture,
33{
34 fn capture_hz(
35 self,
36 freq: Hertz,
37 rcc: &mut Rcc,
38 ) -> (CaptureHzManager<Self>, Self::CaptureChannels);
39}
40
41impl<TIM> CaptureExt for TIM
42where
43 Self: Sized + Instance + WithCapture + SplitCapture,
44{
45 fn capture_hz(
46 self,
47 time: Hertz,
48 rcc: &mut Rcc,
49 ) -> (CaptureHzManager<Self>, Self::CaptureChannels) {
50 Timer::new(self, rcc).capture_hz(time)
51 }
52}
53
54impl<TIM: Instance + WithCapture + SplitCapture> Timer<TIM> {
55 pub fn capture_hz(mut self, freq: Hertz) -> (CaptureHzManager<TIM>, TIM::CaptureChannels) {
59 self.tim.enable_preload(true);
63
64 let psc = self.clk.raw() / freq.raw();
65 assert!(self.clk.raw() % freq.raw() == 0);
66 assert!(
67 psc <= u16::MAX.into(),
68 "PSC value {} exceeds 16-bit limit (65535)",
69 psc
70 );
71
72 self.tim.set_prescaler(psc as u16 - 1);
73 self.tim.set_auto_reload(TIM::max_auto_reload()).unwrap();
74
75 self.tim.trigger_update();
77
78 self.tim.start_capture();
79
80 (CaptureHzManager { timer: self }, TIM::split_capture())
81 }
82}
83
84pub struct CaptureChannelDisabled<TIM, const C: u8> {
85 pub(super) tim: TIM,
86}
87
88impl<TIM: crate::Steal, const C: u8> CaptureChannelDisabled<TIM, C> {
89 pub(crate) fn new() -> Self {
90 Self {
91 tim: unsafe { TIM::steal() },
92 }
93 }
94}
95impl<TIM: Instance + WithCapture + crate::Steal, const C: u8> CaptureChannelDisabled<TIM, C>
96where
97 TIM: CPin<C>,
98{
99 pub fn with(
100 mut self,
101 pin: impl Into<TIM::Ch<PushPull>>,
102 ) -> CaptureChannel<TIM, C, false, PushPull> {
103 self.tim.preload_capture(C, CaptureMode::InputCapture);
104 CaptureChannel {
105 tim: self.tim,
106 pin: pin.into(),
107 }
108 }
109}
110
111pub struct CaptureChannel<TIM: CPin<C>, const C: u8, const COMP: bool = false, Otype = PushPull> {
112 pub(super) tim: TIM,
113 pin: TIM::Ch<Otype>,
114 }
116
117impl<TIM: Instance + WithCapture + CPin<C>, const C: u8, const COMP: bool, Otype>
118 CaptureChannel<TIM, C, COMP, Otype>
119{
120 pub const fn channel(&self) -> u8 {
121 C
122 }
123 pub fn release(mut self) -> (CaptureChannelDisabled<TIM, C>, TIM::Ch<Otype>) {
124 self.disable();
125 (CaptureChannelDisabled { tim: self.tim }, self.pin)
126 }
127 pub fn erase(self) -> CaptureErasedChannel<TIM> {
128 CaptureErasedChannel {
129 _tim: self.tim,
130 channel: C,
131 }
132 }
133
134 pub fn set_prescaler(&mut self, psc: CapturePrescaler) {
135 self.tim.prescaler_capture(C, psc);
136 }
137
138 pub fn set_filter(&mut self, filter: CaptureFilter) {
139 self.tim.filter_capture(C, filter);
140 }
141}
142
143pub struct CaptureErasedChannel<TIM> {
144 _tim: TIM,
145 channel: u8,
146}
147
148impl<TIM> CaptureErasedChannel<TIM> {
149 pub const fn channel(&self) -> u8 {
150 self.channel
151 }
152}
153
154macro_rules! ch_impl {
155 () => {
156 #[inline]
158 pub fn disable(&mut self) {
159 TIM::enable_channel(self.channel(), false);
160 }
161
162 #[inline]
164 pub fn enable(&mut self) {
165 TIM::enable_channel(self.channel(), true);
166 }
167
168 #[inline]
170 pub fn get_capture(&self) -> u32 {
171 TIM::read_cc_value(self.channel())
172 }
173
174 #[inline]
176 pub fn set_polarity(&mut self, p: CapturePolarity) {
177 TIM::set_capture_channel_polarity(self.channel(), p);
178 }
179 };
180}
181
182impl<TIM: Instance + WithCapture + CPin<C>, const C: u8, const COMP: bool, Otype>
183 CaptureChannel<TIM, C, COMP, Otype>
184{
185 ch_impl!();
186}
187
188impl<TIM: Instance + WithCapture> CaptureErasedChannel<TIM> {
189 ch_impl!();
190}
191
192pub struct CaptureHzManager<TIM>
193where
194 TIM: Instance + WithCapture,
195{
196 pub(super) timer: Timer<TIM>,
197}
198
199impl<TIM> CaptureHzManager<TIM>
200where
201 TIM: Instance + WithCapture + Split,
202{
203 pub fn release(mut self, _channels: TIM::Channels) -> Timer<TIM> {
204 self.tim.cr1_reset();
206 self.timer
207 }
208}
209
210impl<TIM> Deref for CaptureHzManager<TIM>
211where
212 TIM: Instance + WithCapture,
213{
214 type Target = Timer<TIM>;
215 fn deref(&self) -> &Self::Target {
216 &self.timer
217 }
218}
219
220impl<TIM> DerefMut for CaptureHzManager<TIM>
221where
222 TIM: Instance + WithCapture,
223{
224 fn deref_mut(&mut self) -> &mut Self::Target {
225 &mut self.timer
226 }
227}
228
229impl<TIM> CaptureHzManager<TIM>
230where
231 TIM: Instance + WithCapture,
232{
233 pub fn get_timer_clock(&self) -> u32 {
235 let clk = self.clk;
236 let psc = self.tim.read_prescaler() as u32;
237
238 (clk / (psc + 1)).raw()
240 }
241
242 pub fn set_timer_clock(&mut self, freq: Hertz) {
244 let clk = self.clk;
245 let psc = clk.raw() / freq.raw();
246 assert!(self.clk.raw() % freq.raw() == 0);
247 assert!(
248 psc <= u16::MAX.into(),
249 "PSC value {} exceeds 16-bit limit (65535)",
250 psc
251 );
252
253 self.tim.set_prescaler(psc as u16 - 1);
254 self.tim.set_auto_reload(TIM::max_auto_reload()).unwrap();
255 self.tim.cnt_reset();
256 }
257
258 pub fn get_max_auto_reload(&mut self) -> u32 {
259 TIM::max_auto_reload()
260 }
261}