time.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. //! Time units
  2. //!
  3. //! See [`Hertz`], [`KiloHertz`] and [`MegaHertz`] for creating increasingly higher frequencies.
  4. //!
  5. //! The [`U32Ext`] trait adds various methods like `.hz()`, `.mhz()`, etc to the `u32` primitive type,
  6. //! allowing it to be converted into frequencies.
  7. //!
  8. //! # Examples
  9. //!
  10. //! ## Create a 2 MHz frequency
  11. //!
  12. //! This example demonstrates various ways of creating a 2 MHz (2_000_000 Hz) frequency. They are
  13. //! all equivalent, however the `2.mhz()` variant should be preferred for readability.
  14. //!
  15. //! ```rust
  16. //! use stm32f1xx_hal::{
  17. //! time::Hertz,
  18. //! // Imports U32Ext trait
  19. //! prelude::*,
  20. //! };
  21. //!
  22. //! let freq_hz = 2_000_000.hz();
  23. //! let freq_khz = 2_000.khz();
  24. //! let freq_mhz = 2.mhz();
  25. //!
  26. //! assert_eq!(freq_hz, freq_khz);
  27. //! assert_eq!(freq_khz, freq_mhz);
  28. //! ```
  29. use core::ops;
  30. use cortex_m::peripheral::{DCB, DWT};
  31. use crate::rcc::Clocks;
  32. /// Bits per second
  33. #[derive(Clone, Copy, PartialEq, Debug)]
  34. pub struct Bps(pub u32);
  35. /// Hertz
  36. ///
  37. /// Create a frequency specified in [Hertz](https://en.wikipedia.org/wiki/Hertz).
  38. ///
  39. /// See also [`KiloHertz`] and [`MegaHertz`] for semantically correct ways of creating higher
  40. /// frequencies.
  41. ///
  42. /// # Examples
  43. ///
  44. /// ## Create an 60 Hz frequency
  45. ///
  46. /// ```rust
  47. /// use stm32f1xx_hal::time::Hertz;
  48. ///
  49. /// let freq = 60.hz();
  50. /// ```
  51. #[derive(Clone, Copy, PartialEq, Debug)]
  52. pub struct Hertz(pub u32);
  53. /// Kilohertz
  54. ///
  55. /// Create a frequency specified in kilohertz.
  56. ///
  57. /// See also [`Hertz`] and [`MegaHertz`] for semantically correct ways of creating lower or higher
  58. /// frequencies.
  59. ///
  60. /// # Examples
  61. ///
  62. /// ## Create a 100 Khz frequency
  63. ///
  64. /// This example creates a 100 KHz frequency. This could be used to set an I2C data rate or PWM
  65. /// frequency, etc.
  66. ///
  67. /// ```rust
  68. /// use stm32f1xx_hal::time::Hertz;
  69. ///
  70. /// let freq = 100.khz();
  71. /// ```
  72. #[derive(Clone, Copy, PartialEq, Debug)]
  73. pub struct KiloHertz(pub u32);
  74. /// Megahertz
  75. ///
  76. /// Create a frequency specified in megahertz.
  77. ///
  78. /// See also [`Hertz`] and [`KiloHertz`] for semantically correct ways of creating lower
  79. /// frequencies.
  80. ///
  81. /// # Examples
  82. ///
  83. /// ## Create a an 8 MHz frequency
  84. ///
  85. /// This example creates an 8 MHz frequency that could be used to configure an SPI peripheral, etc.
  86. ///
  87. /// ```rust
  88. /// use stm32f1xx_hal::time::Hertz;
  89. ///
  90. /// let freq = 8.mhz();
  91. /// ```
  92. #[derive(Clone, Copy, PartialEq, Debug)]
  93. pub struct MegaHertz(pub u32);
  94. /// Time unit
  95. #[derive(PartialEq, PartialOrd, Clone, Copy)]
  96. pub struct MilliSeconds(pub u32);
  97. #[derive(PartialEq, PartialOrd, Clone, Copy)]
  98. pub struct MicroSeconds(pub u32);
  99. /// Extension trait that adds convenience methods to the `u32` type
  100. pub trait U32Ext {
  101. /// Wrap in `Bps`
  102. fn bps(self) -> Bps;
  103. /// Wrap in `Hertz`
  104. fn hz(self) -> Hertz;
  105. /// Wrap in `KiloHertz`
  106. fn khz(self) -> KiloHertz;
  107. /// Wrap in `MegaHertz`
  108. fn mhz(self) -> MegaHertz;
  109. /// Wrap in `MilliSeconds`
  110. fn ms(self) -> MilliSeconds;
  111. /// Wrap in `MicroSeconds`
  112. fn us(self) -> MicroSeconds;
  113. }
  114. impl U32Ext for u32 {
  115. fn bps(self) -> Bps {
  116. Bps(self)
  117. }
  118. fn hz(self) -> Hertz {
  119. Hertz(self)
  120. }
  121. fn khz(self) -> KiloHertz {
  122. KiloHertz(self)
  123. }
  124. fn mhz(self) -> MegaHertz {
  125. MegaHertz(self)
  126. }
  127. fn ms(self) -> MilliSeconds {
  128. MilliSeconds(self)
  129. }
  130. fn us(self) -> MicroSeconds {
  131. MicroSeconds(self)
  132. }
  133. }
  134. impl From<KiloHertz> for Hertz {
  135. fn from(val: KiloHertz) -> Self {
  136. Self(val.0 * 1_000)
  137. }
  138. }
  139. impl From<MegaHertz> for Hertz {
  140. fn from(val: MegaHertz) -> Self {
  141. Self(val.0 * 1_000_000)
  142. }
  143. }
  144. impl From<MegaHertz> for KiloHertz {
  145. fn from(val: MegaHertz) -> Self {
  146. Self(val.0 * 1_000)
  147. }
  148. }
  149. impl Into<Hertz> for MilliSeconds {
  150. fn into(self) -> Hertz {
  151. Hertz(1_000 / self.0)
  152. }
  153. }
  154. impl Into<Hertz> for MicroSeconds {
  155. fn into(self) -> Hertz {
  156. Hertz(1_000_000 / self.0)
  157. }
  158. }
  159. /// Macro to implement arithmetic operations (e.g. multiplication, division)
  160. /// for wrapper types.
  161. macro_rules! impl_arithmetic {
  162. ($wrapper:ty, $wrapped:ty) => {
  163. impl ops::Mul<$wrapped> for $wrapper {
  164. type Output = Self;
  165. fn mul(self, rhs: $wrapped) -> Self {
  166. Self(self.0 * rhs)
  167. }
  168. }
  169. impl ops::MulAssign<$wrapped> for $wrapper {
  170. fn mul_assign(&mut self, rhs: $wrapped) {
  171. self.0 *= rhs;
  172. }
  173. }
  174. impl ops::Div<$wrapped> for $wrapper {
  175. type Output = Self;
  176. fn div(self, rhs: $wrapped) -> Self {
  177. Self(self.0 / rhs)
  178. }
  179. }
  180. impl ops::Div<$wrapper> for $wrapper {
  181. type Output = $wrapped;
  182. fn div(self, rhs: $wrapper) -> $wrapped {
  183. self.0 / rhs.0
  184. }
  185. }
  186. impl ops::DivAssign<$wrapped> for $wrapper {
  187. fn div_assign(&mut self, rhs: $wrapped) {
  188. self.0 /= rhs;
  189. }
  190. }
  191. };
  192. }
  193. impl_arithmetic!(Hertz, u32);
  194. impl_arithmetic!(KiloHertz, u32);
  195. impl_arithmetic!(MegaHertz, u32);
  196. impl_arithmetic!(Bps, u32);
  197. /// A monotonic non-decreasing timer
  198. ///
  199. /// This uses the timer in the debug watch trace peripheral. This means, that if the
  200. /// core is stopped, the timer does not count up. This may be relevant if you are using
  201. /// cortex_m_semihosting::hprintln for debugging in which case the timer will be stopped
  202. /// while printing
  203. #[derive(Clone, Copy)]
  204. pub struct MonoTimer {
  205. frequency: Hertz,
  206. }
  207. impl MonoTimer {
  208. /// Creates a new `Monotonic` timer
  209. pub fn new(mut dwt: DWT, mut dcb: DCB, clocks: Clocks) -> Self {
  210. dcb.enable_trace();
  211. dwt.enable_cycle_counter();
  212. // now the CYCCNT counter can't be stopped or reset
  213. drop(dwt);
  214. MonoTimer {
  215. frequency: clocks.hclk(),
  216. }
  217. }
  218. /// Returns the frequency at which the monotonic timer is operating at
  219. pub fn frequency(self) -> Hertz {
  220. self.frequency
  221. }
  222. /// Returns an `Instant` corresponding to "now"
  223. pub fn now(self) -> Instant {
  224. Instant {
  225. now: DWT::get_cycle_count(),
  226. }
  227. }
  228. }
  229. /// A measurement of a monotonically non-decreasing clock
  230. #[derive(Clone, Copy)]
  231. pub struct Instant {
  232. now: u32,
  233. }
  234. impl Instant {
  235. /// Ticks elapsed since the `Instant` was created
  236. pub fn elapsed(self) -> u32 {
  237. DWT::get_cycle_count().wrapping_sub(self.now)
  238. }
  239. }