embassy_stm32/timer/
pwm_input.rs1use embassy_hal_internal::into_ref;
4
5use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource};
6use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel};
7use crate::gpio::{AfType, Pull};
8use crate::time::Hertz;
9use crate::Peripheral;
10
11pub struct PwmInput<'d, T: GeneralInstance4Channel> {
13 channel: Channel,
14 inner: Timer<'d, T>,
15}
16
17impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
18 pub fn new(
20 tim: impl Peripheral<P = T> + 'd,
21 pin: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
22 pull: Pull,
23 freq: Hertz,
24 ) -> Self {
25 into_ref!(pin);
26
27 pin.set_as_af(pin.af_num(), AfType::input(pull));
28
29 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2)
30 }
31
32 pub fn new_alt(
34 tim: impl Peripheral<P = T> + 'd,
35 pin: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
36 pull: Pull,
37 freq: Hertz,
38 ) -> Self {
39 into_ref!(pin);
40
41 pin.set_as_af(pin.af_num(), AfType::input(pull));
42
43 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1)
44 }
45
46 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, ch1: Channel, ch2: Channel) -> Self {
47 let mut inner = Timer::new(tim);
48
49 inner.set_counting_mode(CountingMode::EdgeAlignedUp);
50 inner.set_tick_freq(freq);
51 inner.enable_outputs(); inner.start();
53
54 inner.set_input_ti_selection(ch1, InputTISelection::Normal);
57 inner.set_input_capture_mode(ch1, InputCaptureMode::Rising);
58
59 inner.set_input_ti_selection(ch2, InputTISelection::Alternate);
60 inner.set_input_capture_mode(ch2, InputCaptureMode::Falling);
61
62 inner.set_trigger_source(match ch1 {
63 Channel::Ch1 => TriggerSource::TI1FP1,
64 Channel::Ch2 => TriggerSource::TI2FP2,
65 _ => panic!("Invalid channel for PWM input"),
66 });
67
68 inner.set_slave_mode(SlaveMode::RESET_MODE);
69
70 Self { channel: ch1, inner }
73 }
74
75 pub fn enable(&mut self) {
77 self.inner.enable_channel(Channel::Ch1, true);
78 self.inner.enable_channel(Channel::Ch2, true);
79 }
80
81 pub fn disable(&mut self) {
83 self.inner.enable_channel(Channel::Ch1, false);
84 self.inner.enable_channel(Channel::Ch2, false);
85 }
86
87 pub fn is_enabled(&self) -> bool {
89 self.inner.get_channel_enable_state(Channel::Ch1)
90 }
91
92 pub fn get_period_ticks(&self) -> u32 {
94 self.inner.get_capture_value(self.channel)
95 }
96
97 pub fn get_width_ticks(&self) -> u32 {
99 self.inner.get_capture_value(match self.channel {
100 Channel::Ch1 => Channel::Ch2,
101 Channel::Ch2 => Channel::Ch1,
102 _ => panic!("Invalid channel for PWM input"),
103 })
104 }
105
106 pub fn get_duty_cycle(&self) -> f32 {
108 let period = self.get_period_ticks();
109 if period == 0 {
110 return 0.;
111 }
112 100. * (self.get_width_ticks() as f32) / (period as f32)
113 }
114}