timer.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*!
  2. # Timer
  3. ## Alternate function remapping
  4. This is a list of the remap settings you can use to assign pins to PWM channels
  5. and the QEI peripherals
  6. ### TIM1
  7. Not available on STM32F101.
  8. | Channel | Tim1NoRemap | Tim1FullRemap |
  9. |:---:|:-----------:|:-------------:|
  10. | CH1 | PA8 | PE9 |
  11. | CH2 | PA9 | PE11 |
  12. | CH3 | PA10 | PE13 |
  13. | CH4 | PA11 | PE14 |
  14. ### TIM2
  15. | Channel | Tim2NoRemap | Tim2PartialRemap1 | Tim2PartialRemap2 | Tim2FullRemap |
  16. |:---:|:-----------:|:-----------------:|:-----------------:|:-------------:|
  17. | CH1 | PA0 | PA15 | PA0 | PA15 |
  18. | CH2 | PA1 | PB3 | PA1 | PB3 |
  19. | CH3 | PA2 | PA2 | PB10 | PB10 |
  20. | CH4 | PA3 | PA3 | PB11 | PB11 |
  21. ### TIM3
  22. | Channel | Tim3NoRemap | Tim3PartialRemap | Tim3FullRemap |
  23. |:---:|:-----------:|:----------------:|:-------------:|
  24. | CH1 | PA6 | PB4 | PC6 |
  25. | CH2 | PA7 | PB5 | PC7 |
  26. | CH3 | PB0 | PB0 | PC8 |
  27. | CH4 | PB1 | PB1 | PC9 |
  28. ### TIM4
  29. Not available on low density devices.
  30. | Channel | Tim4NoRemap | Tim4Remap |
  31. |:---:|:-----------:|:---------:|
  32. | CH1 | PB6 | PD12 |
  33. | CH2 | PB7 | PD13 |
  34. | CH3 | PB8 | PD14 |
  35. | CH4 | PB9 | PD15 |
  36. */
  37. use crate::hal::timer::{Cancel, CountDown, Periodic};
  38. #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
  39. use crate::pac::TIM1;
  40. #[cfg(feature = "medium")]
  41. use crate::pac::TIM4;
  42. #[cfg(any(feature = "high", feature = "connectivity"))]
  43. use crate::pac::TIM5;
  44. #[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity",))]
  45. use crate::pac::TIM6;
  46. #[cfg(any(
  47. all(feature = "high", any(feature = "stm32f101", feature = "stm32f103",),),
  48. any(feature = "stm32f100", feature = "connectivity",)
  49. ))]
  50. use crate::pac::TIM7;
  51. #[cfg(all(feature = "stm32f103", feature = "high",))]
  52. use crate::pac::TIM8;
  53. use crate::pac::{DBGMCU as DBG, TIM2, TIM3};
  54. #[cfg(feature = "stm32f100")]
  55. use crate::pac::{TIM15, TIM16, TIM17};
  56. #[cfg(not(feature = "stm32f101"))]
  57. use crate::rcc::APB2;
  58. use crate::rcc::{sealed::RccBus, Clocks, Enable, GetBusFreq, Reset, APB1};
  59. use cast::{u16, u32, u64};
  60. use cortex_m::peripheral::syst::SystClkSource;
  61. use cortex_m::peripheral::SYST;
  62. use void::Void;
  63. use crate::time::Hertz;
  64. /// Interrupt events
  65. pub enum Event {
  66. /// Timer timed out / count down ended
  67. Update,
  68. }
  69. #[derive(Debug, PartialEq)]
  70. pub enum Error {
  71. /// Timer is canceled
  72. Canceled,
  73. }
  74. pub struct Timer<TIM> {
  75. pub(crate) tim: TIM,
  76. pub(crate) clk: Hertz,
  77. }
  78. pub struct CountDownTimer<TIM> {
  79. tim: TIM,
  80. clk: Hertz,
  81. }
  82. pub(crate) mod sealed {
  83. pub trait Remap {
  84. type Periph;
  85. const REMAP: u8;
  86. }
  87. pub trait Ch1<REMAP> {}
  88. pub trait Ch2<REMAP> {}
  89. pub trait Ch3<REMAP> {}
  90. pub trait Ch4<REMAP> {}
  91. }
  92. macro_rules! remap {
  93. ($($name:ident: ($TIMX:ident, $state:literal, $P1:ident, $P2:ident, $P3:ident, $P4:ident),)+) => {
  94. $(
  95. pub struct $name;
  96. impl sealed::Remap for $name {
  97. type Periph = $TIMX;
  98. const REMAP: u8 = $state;
  99. }
  100. impl<MODE> sealed::Ch1<$name> for $P1<MODE> {}
  101. impl<MODE> sealed::Ch2<$name> for $P2<MODE> {}
  102. impl<MODE> sealed::Ch3<$name> for $P3<MODE> {}
  103. impl<MODE> sealed::Ch4<$name> for $P4<MODE> {}
  104. )+
  105. }
  106. }
  107. use crate::gpio::gpioa::{PA0, PA1, PA15, PA2, PA3, PA6, PA7};
  108. use crate::gpio::gpiob::{PB0, PB1, PB10, PB11, PB3, PB4, PB5};
  109. use crate::gpio::gpioc::{PC6, PC7, PC8, PC9};
  110. #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
  111. use crate::gpio::{
  112. gpioa::{PA10, PA11, PA8, PA9},
  113. gpioe::{PE11, PE13, PE14, PE9},
  114. };
  115. #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
  116. remap!(
  117. Tim1NoRemap: (TIM1, 0b00, PA8, PA9, PA10, PA11),
  118. //Tim1PartialRemap: (TIM1, 0b01, PA8, PA9, PA10, PA11),
  119. Tim1FullRemap: (TIM1, 0b11, PE9, PE11, PE13, PE14),
  120. );
  121. remap!(
  122. Tim2NoRemap: (TIM2, 0b00, PA0, PA1, PA2, PA3),
  123. Tim2PartialRemap1: (TIM2, 0b01, PA15, PB3, PA2, PA3),
  124. Tim2PartialRemap2: (TIM2, 0b10, PA0, PA1, PB10, PB11),
  125. Tim2FullRemap: (TIM2, 0b11, PA15, PB3, PB10, PB11),
  126. Tim3NoRemap: (TIM3, 0b00, PA6, PA7, PB0, PB1),
  127. Tim3PartialRemap: (TIM3, 0b10, PB4, PB5, PB0, PB1),
  128. Tim3FullRemap: (TIM3, 0b11, PC6, PC7, PC8, PC9),
  129. );
  130. #[cfg(feature = "medium")]
  131. use crate::gpio::{
  132. gpiob::{PB6, PB7, PB8, PB9},
  133. gpiod::{PD12, PD13, PD14, PD15},
  134. };
  135. #[cfg(feature = "medium")]
  136. remap!(
  137. Tim4NoRemap: (TIM4, 0b00, PB6, PB7, PB8, PB9),
  138. Tim4Remap: (TIM4, 0b01, PD12, PD13, PD14, PD15),
  139. );
  140. impl Timer<SYST> {
  141. pub fn syst(mut syst: SYST, clocks: &Clocks) -> Self {
  142. syst.set_clock_source(SystClkSource::Core);
  143. Self {
  144. tim: syst,
  145. clk: clocks.hclk(),
  146. }
  147. }
  148. pub fn start_count_down<T>(self, timeout: T) -> CountDownTimer<SYST>
  149. where
  150. T: Into<Hertz>,
  151. {
  152. let Self { tim, clk } = self;
  153. let mut timer = CountDownTimer { tim, clk };
  154. timer.start(timeout);
  155. timer
  156. }
  157. pub fn release(self) -> SYST {
  158. self.tim
  159. }
  160. }
  161. impl CountDownTimer<SYST> {
  162. /// Starts listening for an `event`
  163. pub fn listen(&mut self, event: Event) {
  164. match event {
  165. Event::Update => self.tim.enable_interrupt(),
  166. }
  167. }
  168. /// Stops listening for an `event`
  169. pub fn unlisten(&mut self, event: Event) {
  170. match event {
  171. Event::Update => self.tim.disable_interrupt(),
  172. }
  173. }
  174. /// Resets the counter
  175. pub fn reset(&mut self) {
  176. // According to the Cortex-M3 Generic User Guide, the interrupt request is only generated
  177. // when the counter goes from 1 to 0, so writing zero should not trigger an interrupt
  178. self.tim.clear_current();
  179. }
  180. /// Returns the number of microseconds since the last update event.
  181. /// *NOTE:* This method is not a very good candidate to keep track of time, because
  182. /// it is very easy to lose an update event.
  183. pub fn micros_since(&self) -> u32 {
  184. let reload_value = SYST::get_reload();
  185. let timer_clock = u64(self.clk.0);
  186. let ticks = u64(reload_value - SYST::get_current());
  187. // It is safe to make this cast since the maximum ticks is (2^24 - 1) and the minimum sysclk
  188. // is 4Mhz, which gives a maximum period of ~4.2 seconds which is < (2^32 - 1) microseconds
  189. u32(1_000_000 * ticks / timer_clock).unwrap()
  190. }
  191. /// Stops the timer
  192. pub fn stop(mut self) -> Timer<SYST> {
  193. self.tim.disable_counter();
  194. let Self { tim, clk } = self;
  195. Timer { tim, clk }
  196. }
  197. /// Releases the SYST
  198. pub fn release(self) -> SYST {
  199. self.stop().release()
  200. }
  201. }
  202. impl CountDown for CountDownTimer<SYST> {
  203. type Time = Hertz;
  204. fn start<T>(&mut self, timeout: T)
  205. where
  206. T: Into<Hertz>,
  207. {
  208. let rvr = self.clk.0 / timeout.into().0 - 1;
  209. assert!(rvr < (1 << 24));
  210. self.tim.set_reload(rvr);
  211. self.tim.clear_current();
  212. self.tim.enable_counter();
  213. }
  214. fn wait(&mut self) -> nb::Result<(), Void> {
  215. if self.tim.has_wrapped() {
  216. Ok(())
  217. } else {
  218. Err(nb::Error::WouldBlock)
  219. }
  220. }
  221. }
  222. impl Cancel for CountDownTimer<SYST> {
  223. type Error = Error;
  224. fn cancel(&mut self) -> Result<(), Self::Error> {
  225. if !self.tim.is_counter_enabled() {
  226. return Err(Self::Error::Canceled);
  227. }
  228. self.tim.disable_counter();
  229. Ok(())
  230. }
  231. }
  232. impl Periodic for CountDownTimer<SYST> {}
  233. macro_rules! hal {
  234. ($($TIMX:ident: ($timX:ident, $APBx:ident, $dbg_timX_stop:ident$(,$master_timbase:ident)*),)+) => {
  235. $(
  236. impl Timer<$TIMX> {
  237. /// Initialize timer
  238. pub fn $timX(tim: $TIMX, clocks: &Clocks, apb: &mut $APBx) -> Self {
  239. // enable and reset peripheral to a clean slate state
  240. $TIMX::enable(apb);
  241. $TIMX::reset(apb);
  242. Self { tim, clk: <$TIMX as RccBus>::Bus::get_timer_frequency(&clocks) }
  243. }
  244. /// Starts timer in count down mode at a given frequency
  245. pub fn start_count_down<T>(self, timeout: T) -> CountDownTimer<$TIMX>
  246. where
  247. T: Into<Hertz>,
  248. {
  249. let Self { tim, clk } = self;
  250. let mut timer = CountDownTimer { tim, clk };
  251. timer.start(timeout);
  252. timer
  253. }
  254. $(
  255. /// Starts timer in count down mode at a given frequency and additionally configures the timers master mode
  256. pub fn start_master<T>(self, timeout: T, mode: crate::pac::$master_timbase::cr2::MMS_A) -> CountDownTimer<$TIMX>
  257. where
  258. T: Into<Hertz>,
  259. {
  260. let Self { tim, clk } = self;
  261. let mut timer = CountDownTimer { tim, clk };
  262. timer.tim.cr2.modify(|_,w| w.mms().variant(mode));
  263. timer.start(timeout);
  264. timer
  265. }
  266. )?
  267. /// Resets timer peripheral
  268. #[inline(always)]
  269. pub fn clocking_reset(&mut self, apb: &mut <$TIMX as RccBus>::Bus) {
  270. $TIMX::reset(apb);
  271. }
  272. /// Stopping timer in debug mode can cause troubles when sampling the signal
  273. #[inline(always)]
  274. pub fn stop_in_debug(&mut self, dbg: &mut DBG, state: bool) {
  275. dbg.cr.modify(|_, w| w.$dbg_timX_stop().bit(state));
  276. }
  277. /// Releases the TIM Peripheral
  278. pub fn release(self) -> $TIMX {
  279. self.tim
  280. }
  281. }
  282. impl CountDownTimer<$TIMX> {
  283. /// Starts listening for an `event`
  284. pub fn listen(&mut self, event: Event) {
  285. match event {
  286. Event::Update => self.tim.dier.write(|w| w.uie().set_bit()),
  287. }
  288. }
  289. /// Stops listening for an `event`
  290. pub fn unlisten(&mut self, event: Event) {
  291. match event {
  292. Event::Update => self.tim.dier.write(|w| w.uie().clear_bit()),
  293. }
  294. }
  295. /// Stops the timer
  296. pub fn stop(self) -> Timer<$TIMX> {
  297. self.tim.cr1.modify(|_, w| w.cen().clear_bit());
  298. let Self { tim, clk } = self;
  299. Timer { tim, clk }
  300. }
  301. /// Clears Update Interrupt Flag
  302. pub fn clear_update_interrupt_flag(&mut self) {
  303. self.tim.sr.modify(|_, w| w.uif().clear_bit());
  304. }
  305. /// Releases the TIM Peripheral
  306. pub fn release(self) -> $TIMX {
  307. self.stop().release()
  308. }
  309. /// Returns the number of microseconds since the last update event.
  310. /// *NOTE:* This method is not a very good candidate to keep track of time, because
  311. /// it is very easy to lose an update event.
  312. pub fn micros_since(&self) -> u32 {
  313. let timer_clock = self.clk.0;
  314. let psc = u32(self.tim.psc.read().psc().bits());
  315. // freq_divider is always bigger than 0, since (psc + 1) is always less than
  316. // timer_clock
  317. let freq_divider = u64(timer_clock / (psc + 1));
  318. let cnt = u64(self.tim.cnt.read().cnt().bits());
  319. // It is safe to make this cast, because the maximum timer period in this HAL is
  320. // 1s (1Hz), then 1 second < (2^32 - 1) microseconds
  321. u32(1_000_000 * cnt / freq_divider).unwrap()
  322. }
  323. /// Resets the counter
  324. pub fn reset(&mut self) {
  325. // Sets the URS bit to prevent an interrupt from being triggered by
  326. // the UG bit
  327. self.tim.cr1.modify(|_, w| w.urs().set_bit());
  328. self.tim.egr.write(|w| w.ug().set_bit());
  329. self.tim.cr1.modify(|_, w| w.urs().clear_bit());
  330. }
  331. }
  332. impl CountDown for CountDownTimer<$TIMX> {
  333. type Time = Hertz;
  334. fn start<T>(&mut self, timeout: T)
  335. where
  336. T: Into<Hertz>,
  337. {
  338. // pause
  339. self.tim.cr1.modify(|_, w| w.cen().clear_bit());
  340. let (psc, arr) = compute_arr_presc(timeout.into().0, self.clk.0);
  341. self.tim.psc.write(|w| w.psc().bits(psc) );
  342. // TODO: Remove this `allow` once this field is made safe for stm32f100
  343. #[allow(unused_unsafe)]
  344. self.tim.arr.write(|w| unsafe { w.arr().bits(arr) });
  345. // Trigger an update event to load the prescaler value to the clock
  346. self.reset();
  347. // start counter
  348. self.tim.cr1.modify(|_, w| w.cen().set_bit());
  349. }
  350. fn wait(&mut self) -> nb::Result<(), Void> {
  351. if self.tim.sr.read().uif().bit_is_clear() {
  352. Err(nb::Error::WouldBlock)
  353. } else {
  354. self.clear_update_interrupt_flag();
  355. Ok(())
  356. }
  357. }
  358. }
  359. impl Cancel for CountDownTimer<$TIMX>
  360. {
  361. type Error = Error;
  362. fn cancel(&mut self) -> Result<(), Self::Error> {
  363. let is_counter_enabled = self.tim.cr1.read().cen().is_enabled();
  364. if !is_counter_enabled {
  365. return Err(Self::Error::Canceled);
  366. }
  367. // disable counter
  368. self.tim.cr1.modify(|_, w| w.cen().clear_bit());
  369. Ok(())
  370. }
  371. }
  372. impl Periodic for CountDownTimer<$TIMX> {}
  373. )+
  374. }
  375. }
  376. #[inline(always)]
  377. fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u16) {
  378. let ticks = clock / freq;
  379. let psc = u16((ticks - 1) / (1 << 16)).unwrap();
  380. let arr = u16(ticks / u32(psc + 1)).unwrap();
  381. (psc, arr)
  382. }
  383. hal! {
  384. TIM2: (tim2, APB1, dbg_tim2_stop, tim2),
  385. TIM3: (tim3, APB1, dbg_tim3_stop, tim2),
  386. }
  387. #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))]
  388. hal! {
  389. TIM1: (tim1, APB2, dbg_tim1_stop, tim1),
  390. }
  391. #[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity",))]
  392. hal! {
  393. TIM6: (tim6, APB1, dbg_tim6_stop, tim6),
  394. }
  395. #[cfg(any(
  396. all(feature = "high", any(feature = "stm32f101", feature = "stm32f103",),),
  397. any(feature = "stm32f100", feature = "connectivity",)
  398. ))]
  399. hal! {
  400. TIM7: (tim7, APB1, dbg_tim7_stop, tim6),
  401. }
  402. #[cfg(feature = "stm32f100")]
  403. hal! {
  404. TIM15: (tim15, APB2, dbg_tim15_stop),
  405. TIM16: (tim16, APB2, dbg_tim16_stop),
  406. TIM17: (tim17, APB2, dbg_tim17_stop),
  407. }
  408. #[cfg(feature = "medium")]
  409. hal! {
  410. TIM4: (tim4, APB1, dbg_tim4_stop, tim2),
  411. }
  412. #[cfg(any(feature = "high", feature = "connectivity"))]
  413. hal! {
  414. TIM5: (tim5, APB1, dbg_tim5_stop, tim2),
  415. }
  416. #[cfg(all(feature = "stm32f103", feature = "high",))]
  417. hal! {
  418. TIM8: (tim8, APB2, dbg_tim8_stop, tim1),
  419. }
  420. //TODO: restore these timers once stm32-rs has been updated
  421. /*
  422. * dbg_tim(12-13)_stop fields missing from 103 xl in stm32-rs
  423. * dbg_tim(9-10)_stop fields missing from 101 xl in stm32-rs
  424. #[cfg(any(
  425. feature = "xl",
  426. all(
  427. feature = "stm32f100",
  428. feature = "high",
  429. )))]
  430. hal! {
  431. TIM12: (tim12, dbg_tim12_stop),
  432. TIM13: (tim13, dbg_tim13_stop),
  433. TIM14: (tim14, dbg_tim14_stop),
  434. }
  435. #[cfg(feature = "xl")]
  436. hal! {
  437. TIM9: (tim9, dbg_tim9_stop),
  438. TIM10: (tim10, dbg_tim10_stop),
  439. TIM11: (tim11, dbg_tim11_stop),
  440. }
  441. */