stm32f1_hal/timer/
timer8.rs

1type TimerX = pac::TIM8;
2type Width = u16;
3
4// Do NOT manually modify the code between begin and end!
5// It's synced by scripts/sync_code.py.
6// sync begin
7
8use super::*;
9use crate::{Mcu, pac};
10
11impl Instance for TimerX {}
12
13impl TimerInit<TimerX> for TimerX {
14    fn constrain(self, mcu: &mut Mcu) -> Timer<TimerX> {
15        Timer::new(self, mcu)
16    }
17}
18
19impl GeneralTimer for TimerX {
20    #[inline(always)]
21    fn reset_config(&mut self) {
22        self.cr1().reset();
23    }
24
25    #[inline(always)]
26    fn enable_counter(&mut self) {
27        self.cr1().modify(|_, w| w.cen().set_bit());
28    }
29
30    #[inline(always)]
31    fn disable_counter(&mut self) {
32        self.cr1().modify(|_, w| w.cen().clear_bit());
33    }
34
35    #[inline(always)]
36    fn is_counter_enabled(&self) -> bool {
37        self.cr1().read().cen().is_enabled()
38    }
39
40    #[inline(always)]
41    fn reset_counter(&mut self) {
42        self.cnt().reset();
43    }
44
45    #[inline(always)]
46    fn max_auto_reload() -> u32 {
47        Width::MAX as u32
48    }
49
50    #[inline(always)]
51    unsafe fn set_auto_reload_unchecked(&mut self, arr: u32) {
52        unsafe {
53            self.arr().write(|w| w.bits(arr));
54        }
55    }
56
57    #[inline(always)]
58    fn set_auto_reload(&mut self, arr: u32) -> Result<(), Error> {
59        // Note: Make it impossible to set the ARR value to 0, since this
60        // would cause an infinite loop.
61        if arr > 0 && arr <= Self::max_auto_reload() {
62            unsafe { self.set_auto_reload_unchecked(arr) }
63            Ok(())
64        } else {
65            Err(Error::WrongAutoReload)
66        }
67    }
68
69    #[inline(always)]
70    fn read_auto_reload(&self) -> u32 {
71        self.arr().read().bits()
72    }
73
74    #[inline(always)]
75    fn set_prescaler(&mut self, psc: u16) {
76        self.psc().write(|w| w.psc().set(psc));
77    }
78
79    #[inline(always)]
80    fn read_prescaler(&self) -> u16 {
81        self.psc().read().psc().bits()
82    }
83
84    #[inline(always)]
85    fn read_count(&self) -> u32 {
86        self.cnt().read().bits()
87    }
88
89    #[inline(always)]
90    fn trigger_update(&mut self) {
91        // Sets the URS bit to prevent an interrupt from being triggered by
92        // the UG bit
93        self.cr1().modify(|_, w| w.urs().set_bit());
94        self.egr().write(|w| w.ug().set_bit());
95        self.cr1().modify(|_, w| w.urs().clear_bit());
96    }
97
98    #[inline]
99    fn config_freq(&mut self, clock: Hertz, update_freq: Hertz) {
100        let (prescaler, arr) = compute_prescaler_arr(clock.raw(), update_freq.raw());
101        self.set_prescaler(prescaler as u16);
102        self.set_auto_reload(arr).unwrap();
103        // Trigger update event to load the registers
104        self.trigger_update();
105    }
106
107    #[inline(always)]
108    fn clear_interrupt_flag(&mut self, event: Event) {
109        self.sr()
110            .write(|w| unsafe { w.bits(0xffff & !event.bits()) });
111    }
112
113    #[inline(always)]
114    fn listen_interrupt(&mut self, event: Event, b: bool) {
115        self.dier().modify(|r, w| unsafe {
116            w.bits(if b {
117                r.bits() | event.bits()
118            } else {
119                r.bits() & !event.bits()
120            })
121        });
122    }
123
124    #[inline(always)]
125    fn get_interrupt_flag(&self) -> Event {
126        Event::from_bits_truncate(self.sr().read().bits())
127    }
128
129    #[inline(always)]
130    fn start_one_pulse(&mut self) {
131        self.cr1().modify(|_, w| w.opm().set_bit().cen().set_bit());
132    }
133
134    #[inline(always)]
135    fn stop_in_debug(&mut self, state: bool) {
136        let dbg = unsafe { DBG::steal() };
137        // sync dbg_t8
138        dbg.cr().modify(|_, w| w.dbg_tim8_stop().bit(state));
139        // sync dbg_end
140    }
141
142    #[inline(always)]
143    fn enable_preload(&mut self, b: bool) {
144        self.cr1().modify(|_, w| w.arpe().bit(b));
145    }
146}
147
148// sync pwm
149// PWM ------------------------------------------------------------------------
150
151impl TimerWithPwm for TimerX {
152    fn stop_pwm(&mut self) {
153        self.disable_counter();
154    }
155
156    // sync start_pwm_aoe
157
158    #[inline(always)]
159    fn start_pwm(&mut self) {
160        // self.bdtr().modify(|_, w| w.moe().set_bit());
161        self.bdtr().modify(|_, w| w.aoe().set_bit());
162        self.reset_counter();
163        self.enable_counter();
164    }
165
166    // sync pwm_cfg_4
167
168    #[inline(always)]
169    fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: PwmMode) {
170        let mode = Ocm::from(mode);
171        match channel {
172            Channel::C1 => {
173                self.ccmr1_output()
174                    .modify(|_, w| w.oc1pe().set_bit().oc1m().set(mode as _));
175            }
176            Channel::C2 => {
177                self.ccmr1_output()
178                    .modify(|_, w| w.oc2pe().set_bit().oc2m().set(mode as _));
179            }
180            Channel::C3 => {
181                self.ccmr2_output()
182                    .modify(|_, w| w.oc3pe().set_bit().oc3m().set(mode as _));
183            }
184            Channel::C4 => {
185                self.ccmr2_output()
186                    .modify(|_, w| w.oc4pe().set_bit().oc4m().set(mode as _));
187            }
188        }
189    }
190
191    fn set_polarity(&mut self, channel: Channel, polarity: PwmPolarity) {
192        match channel {
193            Channel::C1 => {
194                self.ccer()
195                    .modify(|_, w| w.cc1p().bit(polarity == PwmPolarity::ActiveLow));
196            }
197            Channel::C2 => {
198                self.ccer()
199                    .modify(|_, w| w.cc2p().bit(polarity == PwmPolarity::ActiveLow));
200            }
201            Channel::C3 => {
202                self.ccer()
203                    .modify(|_, w| w.cc3p().bit(polarity == PwmPolarity::ActiveLow));
204            }
205            Channel::C4 => {
206                self.ccer()
207                    .modify(|_, w| w.cc4p().bit(polarity == PwmPolarity::ActiveLow));
208            }
209        }
210    }
211}
212
213// sync pwm_ch1
214// PWM Channels ---------------------------------------------------------------
215
216impl TimerWithPwm1Ch for TimerX {
217    #[inline(always)]
218    fn enable_ch1(&mut self, en: bool) {
219        self.ccer().modify(|_, w| w.cc1e().bit(en));
220    }
221
222    #[inline(always)]
223    fn set_ch1_cc_value(&mut self, value: u32) {
224        unsafe { self.ccr1().write(|w| w.bits(value)) };
225    }
226
227    #[inline(always)]
228    fn get_ch1_cc_value(&self) -> u32 {
229        self.ccr1().read().bits()
230    }
231}
232
233// sync pwm_ch2
234
235impl TimerWithPwm2Ch for TimerX {
236    #[inline(always)]
237    fn enable_ch2(&mut self, en: bool) {
238        self.ccer().modify(|_, w| w.cc2e().bit(en));
239    }
240
241    #[inline(always)]
242    fn set_ch2_cc_value(&mut self, value: u32) {
243        unsafe { self.ccr2().write(|w| w.bits(value)) };
244    }
245
246    #[inline(always)]
247    fn get_ch2_cc_value(&self) -> u32 {
248        self.ccr2().read().bits()
249    }
250}
251
252// sync pwm_ch4
253
254impl TimerWithPwm3Ch for TimerX {
255    #[inline(always)]
256    fn enable_ch3(&mut self, en: bool) {
257        self.ccer().modify(|_, w| w.cc3e().bit(en));
258    }
259
260    #[inline(always)]
261    fn set_ch3_cc_value(&mut self, value: u32) {
262        unsafe { self.ccr3().write(|w| w.bits(value)) };
263    }
264
265    #[inline(always)]
266    fn get_ch3_cc_value(&self) -> u32 {
267        self.ccr3().read().bits()
268    }
269}
270
271impl TimerWithPwm4Ch for TimerX {
272    #[inline(always)]
273    fn enable_ch4(&mut self, en: bool) {
274        self.ccer().modify(|_, w| w.cc4e().bit(en));
275    }
276
277    #[inline(always)]
278    fn set_ch4_cc_value(&mut self, value: u32) {
279        unsafe { self.ccr4().write(|w| w.bits(value)) };
280    }
281
282    #[inline(always)]
283    fn get_ch4_cc_value(&self) -> u32 {
284        self.ccr4().read().bits()
285    }
286}
287
288// Other ----------------------------------------------------------------------
289
290// sync master
291impl MasterTimer for TimerX {
292    #[inline(always)]
293    fn master_mode(&mut self, mode: MasterMode) {
294        self.cr2().modify(|_, w| w.mms().variant(mode.into()));
295    }
296}
297
298// sync dir
299
300impl TimerDirection for TimerX {
301    #[inline(always)]
302    fn set_count_direction(&mut self, dir: CountDirection) {
303        self.cr1()
304            .modify(|_, w| w.dir().bit(dir == CountDirection::Down));
305    }
306}
307
308// sync RTIC
309#[cfg(feature = "rtic")]
310mod timer_rtic {
311    use super::*;
312    use crate::Mcu;
313    use rtic_monotonic::Monotonic;
314
315    impl MonoTimerExt for TimerX {
316        fn monotonic<const FREQ: u32>(self, mcu: &mut Mcu) -> MonoTimer<Self, FREQ> {
317            mcu.rcc.enable(&self);
318            mcu.rcc.reset(&self);
319            let clk = mcu.rcc.get_timer_clock(&self);
320            FTimer::new(self, clk).monotonic()
321        }
322    }
323
324    impl<const FREQ: u32> FTimer<TimerX, FREQ> {
325        pub fn monotonic(self) -> MonoTimer<TimerX, FREQ> {
326            MonoTimer::<TimerX, FREQ>::_new(self)
327        }
328    }
329
330    impl<const FREQ: u32> MonoTimer<TimerX, FREQ> {
331        fn _new(timer: FTimer<TimerX, FREQ>) -> Self {
332            // Set auto-reload value.
333            timer.tim.arr().write(|w| w.arr().set(u16::MAX));
334            // Generate interrupt on overflow.
335            timer.tim.egr().write(|w| w.ug().set_bit());
336
337            // Start timer.
338            // Clear interrupt flag.
339            timer.tim.sr().modify(|_, w| w.uif().clear_bit());
340            timer.tim.cr1().modify(|_, w| {
341                // Enable counter.
342                w.cen().set_bit();
343                // Overflow should trigger update event.
344                w.udis().clear_bit();
345                // Only overflow triggers interrupt.
346                w.urs().set_bit()
347            });
348
349            Self { timer, ovf: 0 }
350        }
351    }
352
353    impl<const FREQ: u32> Monotonic for MonoTimer<TimerX, FREQ> {
354        type Instant = fugit::TimerInstantU32<FREQ>;
355        type Duration = fugit::TimerDurationU32<FREQ>;
356
357        unsafe fn reset(&mut self) {
358            self.tim.dier().modify(|_, w| w.cc1ie().set_bit());
359        }
360
361        #[inline(always)]
362        fn now(&mut self) -> Self::Instant {
363            let cnt = self.tim.cnt().read().cnt().bits() as u32;
364
365            // If the overflow bit is set, we add this to the timer value. It means the `on_interrupt`
366            // has not yet happened, and we need to compensate here.
367            let ovf = if self.tim.sr().read().uif().bit_is_set() {
368                0x10000
369            } else {
370                0
371            };
372
373            Self::Instant::from_ticks(cnt.wrapping_add(ovf).wrapping_add(self.ovf))
374        }
375
376        fn set_compare(&mut self, instant: Self::Instant) {
377            let now = self.now();
378            let cnt = self.tim.cnt().read().cnt().bits();
379
380            // Since the timer may or may not overflow based on the requested compare val, we check
381            // how many ticks are left.
382            let val = match instant.checked_duration_since(now) {
383                None => cnt.wrapping_add(0xffff), // In the past, RTIC will handle this
384                Some(x) if x.ticks() <= 0xffff => instant.duration_since_epoch().ticks() as u16, // Will not overflow
385                Some(_) => cnt.wrapping_add(0xffff), // Will overflow, run for as long as possible
386            };
387
388            self.tim.ccr1().write(|w| w.ccr().set(val));
389        }
390
391        fn clear_compare_flag(&mut self) {
392            self.tim.sr().modify(|_, w| w.cc1if().clear_bit());
393        }
394
395        fn on_interrupt(&mut self) {
396            // If there was an overflow, increment the overflow counter.
397            if self.tim.sr().read().uif().bit_is_set() {
398                self.tim.sr().modify(|_, w| w.uif().clear_bit());
399
400                self.ovf += 0x10000;
401            }
402        }
403
404        #[inline(always)]
405        fn zero() -> Self::Instant {
406            Self::Instant::from_ticks(0)
407        }
408    }
409}
410
411// sync end