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