lpc8xx_hal/clock.rs
1//! Common types for system clocks
2//!
3//! This module defines types that are helpful for working with system clocks.
4
5/// Represents a number of ticks of a given clock
6///
7/// This struct is used to represent an amount of time, a duration, but in a
8/// low-level way that hardware peripherals can understand and handle. It is
9/// meant to be a common denominator that higher-level time APIs can be built on
10/// top of.
11pub struct Ticks<'clock, C: 'clock> {
12 /// The number of ticks
13 pub value: u32,
14
15 /// Reference to the clock
16 ///
17 /// For many clocks, it's possible to change their frequency. If this were
18 /// to be done after an instance of `Ticks` had been created, that would
19 /// invalidate the `Ticks` instance, as the same number of ticks would
20 /// suddenly represent a different duration of time.
21 ///
22 /// This reference exists to prevent this. Any change to the configuration
23 /// of a clock would presumably require a mutable reference, which means as
24 /// long as this shared reference to the clock exists, the compiler will
25 /// prevent the clock frequency from being changed.
26 pub clock: &'clock C,
27}
28
29impl<'clock, Clock> Clone for Ticks<'clock, Clock> {
30 fn clone(&self) -> Self {
31 Ticks {
32 value: self.value,
33 clock: self.clock,
34 }
35 }
36}
37
38impl<'clock, Clock> Copy for Ticks<'clock, Clock> {}
39
40/// Implemented by clocks that can return a frequency
41///
42/// Implementations of this trait might be very simple, for clocks that run at
43/// one specific frequency. Or they might be more complex, for clocks whose
44/// frequency can be configured.
45///
46/// Some clocks might not have an implementation of this trait at all. An
47/// example of this might be a type that represents an external clock that is
48/// fed into the microcontroller via a pin.
49pub trait Frequency {
50 /// The frequency of the clock in Hz
51 ///
52 /// This method must never return `0`.
53 fn hz(&self) -> u32;
54}
55
56/// Marker trait that identifies a clock as currently being enabled
57///
58/// A clock that is always enabled can just implement this trait
59/// unconditionally. Clocks that can be disabled can use a different type or a
60/// type parameter to implement this trait conditionally.
61///
62/// HAL users will typically use this trait to ensure that a clock that is
63/// passed as a parameter is enabled.
64///
65/// # Examples
66///
67/// This is a function that takes a clock. The function uses this trait to
68/// ensure the passed clock is enabled.
69///
70/// ``` rust
71/// use lpc8xx_hal::clock;
72///
73/// fn use_clock<C>(clock: C) where C: clock::Frequency + clock::Enabled {
74/// // do something with the clock
75/// }
76/// ```
77///
78/// The following example shows how to use a type parameter to track whether a
79/// clock is enabled, and implement the `Enabled` trait conditionally.
80///
81/// ``` rust
82/// use lpc8xx_hal::{
83/// clock,
84/// init_state,
85/// };
86///
87///
88/// struct MyClock<State> {
89/// _state: State,
90/// }
91///
92/// impl MyClock<init_state::Disabled> {
93/// /// Consume the instance with disabled state, return one with enabled
94/// /// state.
95/// pub fn enable(self) -> MyClock<init_state::Enabled> {
96/// // Enable the clock
97/// // ...
98///
99/// MyClock {
100/// _state: init_state::Enabled(()),
101/// }
102/// }
103/// }
104///
105/// impl clock::Enabled for MyClock<init_state::Enabled> {}
106/// ```
107pub trait Enabled {}