Skip to content

Commit 83dd084

Browse files
authored
External clocks for timers (#128)
* timers external clock * disable tim15 for stm32g081
1 parent ea8bee6 commit 83dd084

File tree

3 files changed

+152
-13
lines changed

3 files changed

+152
-13
lines changed

src/rcc/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ impl Rcc {
185185
}
186186
}
187187

188+
pub fn trim_hsi_clocks(&mut self, value: u8) {
189+
self.icscr.modify(|_, w| unsafe { w.hsitrim().bits(value) });
190+
}
191+
188192
pub fn set_reset_mode(&mut self, mode: ResetMode) {
189193
unsafe {
190194
let flash = &(*FLASH::ptr());

src/timer/mod.rs

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use crate::rcc::*;
33
use crate::stm32::*;
44
use crate::time::{Hertz, MicroSecond};
5+
use core::marker::PhantomData;
56
use cortex_m::peripheral::syst::SystClkSource;
67
use cortex_m::peripheral::SYST;
78
use hal::timer::{CountDown, Periodic};
@@ -151,19 +152,6 @@ macro_rules! timers {
151152
low | (_high << 16)
152153
}
153154

154-
/// Releases the TIM peripheral
155-
pub fn release(self) -> $TIM {
156-
self.tim
157-
}
158-
}
159-
160-
impl TimerExt<$TIM> for $TIM {
161-
fn timer(self, rcc: &mut Rcc) -> Timer<$TIM> {
162-
Timer::$tim(self, rcc)
163-
}
164-
}
165-
166-
impl Timer<$TIM> {
167155
pub fn start(&mut self, timeout: MicroSecond) {
168156
// Pause the counter. Also set URS so that when we set UG below, it will
169157
// generate an update event *without* triggering an interrupt.
@@ -196,6 +184,17 @@ macro_rules! timers {
196184
Ok(())
197185
}
198186
}
187+
188+
/// Releases the TIM peripheral
189+
pub fn release(self) -> $TIM {
190+
self.tim
191+
}
192+
}
193+
194+
impl TimerExt<$TIM> for $TIM {
195+
fn timer(self, rcc: &mut Rcc) -> Timer<$TIM> {
196+
Timer::$tim(self, rcc)
197+
}
199198
}
200199

201200
impl CountDown for Timer<$TIM> {
@@ -218,6 +217,56 @@ macro_rules! timers {
218217
}
219218
}
220219

220+
pub enum ExternalClockMode {
221+
Mode1,
222+
Mode2,
223+
}
224+
225+
pub trait ExternalClock {
226+
fn mode(&self) -> ExternalClockMode;
227+
}
228+
229+
macro_rules! timers_external_clocks {
230+
($($TIM:ident: ($tim:ident, $sms:ident $(,$ece:ident)*),)+) => {
231+
$(
232+
impl Timer<$TIM> {
233+
pub fn use_external_clock<C: ExternalClock>(&mut self, clk: C, freq: Hertz) {
234+
self.clk = freq;
235+
match clk.mode() {
236+
ExternalClockMode::Mode1 => {
237+
self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b111) });
238+
$(
239+
self.tim.smcr.modify(|_, w| w.$ece().clear_bit());
240+
)*
241+
},
242+
ExternalClockMode::Mode2 => {
243+
self.tim.smcr.modify(|_, w| unsafe { w.$sms().bits(0b0) });
244+
$(
245+
self.tim.smcr.modify(|_, w| w.$ece().set_bit());
246+
)*
247+
},
248+
}
249+
}
250+
}
251+
)+
252+
}
253+
}
254+
255+
timers_external_clocks! {
256+
TIM1: (tim1, sms, ece),
257+
TIM3: (tim3, sms, ece),
258+
}
259+
260+
#[cfg(feature = "stm32g0x1")]
261+
timers_external_clocks! {
262+
TIM2: (tim2, sms, ece),
263+
}
264+
265+
#[cfg(any(feature = "stm32g070", feature = "stm32g071"))]
266+
timers_external_clocks! {
267+
TIM15: (tim15, sms1),
268+
}
269+
221270
timers! {
222271
TIM1: (tim1, cnt),
223272
TIM3: (tim3, cnt_l, cnt_h),

src/timer/pins.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ pub trait TimerPin<TIM> {
1010
fn release(self) -> Self;
1111
}
1212

13+
pub struct TriggerPin<TIM, PIN: TimerPin<TIM>> {
14+
pin: PIN,
15+
tim: PhantomData<TIM>,
16+
}
17+
18+
impl<TIM, PIN: TimerPin<TIM>> ExternalClock for TriggerPin<TIM, PIN> {
19+
fn mode(&self) -> ExternalClockMode {
20+
ExternalClockMode::Mode1
21+
}
22+
}
23+
24+
impl<TIM, PIN: TimerPin<TIM>> TriggerPin<TIM, PIN> {
25+
pub fn release(self) -> PIN {
26+
self.pin
27+
}
28+
}
29+
1330
macro_rules! timer_pins {
1431
($TIMX:ident, [ $(($ch:ty, $pin:ty, $af_mode:expr),)+ ]) => {
1532
$(
@@ -28,6 +45,75 @@ macro_rules! timer_pins {
2845
};
2946
}
3047

48+
macro_rules! trigger_pins {
49+
($TIMX:ident, [ $(($pin:ty, $ccp:ident $(,$icf:ident)*),)+ ]) => {
50+
$(
51+
impl TriggerPin<$TIMX, $pin> {
52+
pub fn new(pin: $pin, edge: SignalEdge) -> Self {
53+
TimerPin::<$TIMX>::setup(&pin);
54+
let tim = unsafe { &(*$TIMX::ptr()) };
55+
let ts = match edge {
56+
SignalEdge::All => 0b100,
57+
SignalEdge::Falling => {
58+
tim.ccer.modify(|_, w| w.$ccp().set_bit());
59+
0b101
60+
},
61+
SignalEdge::Rising => {
62+
tim.ccer.modify(|_, w| w.$ccp().clear_bit());
63+
0b101
64+
}
65+
};
66+
67+
tim.smcr.modify(|_, w| unsafe { w.ts().bits(ts) });
68+
69+
Self {
70+
pin,
71+
tim: PhantomData,
72+
}
73+
}
74+
75+
$(
76+
pub fn with_filter(pin: $pin, edge: SignalEdge, capture_filter: u8) -> Self {
77+
unsafe {
78+
let tim = &(*$TIMX::ptr()) ;
79+
tim.ccmr1_input().modify(|_, w| w.$icf().bits(capture_filter));
80+
}
81+
Self::new(pin, edge)
82+
}
83+
)*
84+
}
85+
)+
86+
};
87+
}
88+
89+
trigger_pins!(TIM1, [
90+
(PA8<DefaultMode>, cc1p),
91+
(PC8<DefaultMode>, cc1p),
92+
(PA9<DefaultMode>, cc2p),
93+
(PB3<DefaultMode>, cc2p),
94+
(PC9<DefaultMode>, cc2p),
95+
]);
96+
97+
#[cfg(feature = "stm32g0x1")]
98+
trigger_pins!(TIM2, [
99+
(PA0<DefaultMode>, cc1p, ic1f),
100+
(PA5<DefaultMode>, cc1p, ic1f),
101+
(PA15<DefaultMode>, cc1p, ic1f),
102+
(PC4<DefaultMode>, cc1p, ic1f),
103+
(PA1<DefaultMode>, cc2p, ic2f),
104+
(PB3<DefaultMode>, cc2p, ic2f),
105+
(PC5<DefaultMode>, cc2p, ic2f),
106+
]);
107+
108+
trigger_pins!(TIM3, [
109+
(PA6<DefaultMode>, cc1p, ic1f),
110+
(PB4<DefaultMode>, cc1p, ic1f),
111+
(PC6<DefaultMode>, cc1p, ic1f),
112+
(PA7<DefaultMode>, cc2p, ic2f),
113+
(PB5<DefaultMode>, cc2p, ic2f),
114+
(PC7<DefaultMode>, cc2p, ic2f),
115+
]);
116+
31117
timer_pins!(TIM1, [
32118
(Channel1, PA8<DefaultMode>, AltFunction::AF2),
33119
(Channel1, PC8<DefaultMode>, AltFunction::AF2),

0 commit comments

Comments
 (0)