Skip to content

Commit 97fd4e4

Browse files
committed
Add rough doc of Observable::observe
1 parent fa03e3b commit 97fd4e4

File tree

1 file changed

+81
-1
lines changed

1 file changed

+81
-1
lines changed

src/observable.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,88 @@ pub struct ObservationToken<P: Observable> {
3535

3636
/// A trait providing an interface to make peripherals observed
3737
///
38-
/// See [`Observed`] and [`ObservationToken`]
38+
/// See [`Observable::observe`], [`Observed`] and [`ObservationToken`]
3939
pub trait Observable: Sized {
40+
/// Observe this peripheral to split it into a [`Observed<Self>`] and a set of [`ObservationToken`]'s
41+
///
42+
/// This is useful when you need the same peripherals for multiple things at the same time.
43+
///
44+
/// For example let's say you want to keep track of the voltage of a pin. You want to log it
45+
/// every second but if it rises above a threshold then you need to react really fast.
46+
///
47+
/// This can be solved by connecting the pin to a comparator that compares the pins
48+
/// voltage to a reference. If the voltage rises above the reference then the comparator
49+
/// will quickly detect this and an interrupt can be generated or similar (not shown here).
50+
///
51+
/// ```
52+
/// let dp = stm32::Peripherals::take().unwrap();
53+
/// let mut rcc = dp.RCC.constrain();
54+
///
55+
/// let gpioa = dp.GPIOA.split(&mut rcc);
56+
///
57+
/// let (comp1, comp2, ..) = dp.COMP.split(&mut rcc);
58+
///
59+
/// let pa1 = gpioa.pa1.into_analog(); // <- The pin to keep track of
60+
/// let pa0 = gpioa.pa0.into_analog(); // <- Reference voltage
61+
///
62+
/// // Pins consumed here
63+
/// let comp1 = comp1.comparator(pa1, pa0, Config::default(), &rcc.clocks);
64+
/// let comp1 = comp1.enable();
65+
///
66+
/// // Can not use pa0 and pa1 for AD readings
67+
/// ```
68+
///
69+
/// However we still want to perform AD readings every second. Since the pins are consumed
70+
/// by the comparator this is impossible.
71+
///
72+
/// It turns ut that to construct the comparator we do not actually need a pin. We
73+
/// just need proof that there is a pin that is setup in the correct mode and which
74+
/// will stay in that mode as long as the comparator lives.
75+
///
76+
/// This is where [`Observable::observe`] comes in. It splits the peripheral, in this case
77+
/// a pin, into an [`Observed<Self>`] and a set of [`ObservationToken`]'s. The `Observed`
78+
/// type can be used just like the peripheral would normally be used. For our pin we can
79+
/// use it to perform AD readings etc. There is however one vital difference, we can not
80+
/// reconfigure the observed peripheral. The `ObservationToken`'s on the other hand
81+
/// are tokens that proove that the peripheral will not be reconfigured. These can then
82+
/// be used instead of the peripheral to pass as arguments to other peripherals.
83+
///
84+
/// ```
85+
/// let dp = stm32::Peripherals::take().unwrap();
86+
/// let mut rcc = dp.RCC.constrain();
87+
///
88+
/// let gpioa = dp.GPIOA.split(&mut rcc);
89+
///
90+
/// let (comp1, comp2, ..) = dp.COMP.split(&mut rcc);
91+
///
92+
/// let (pa1, [pa1_token]) = gpioa // <- The pin to keep track of
93+
/// .pa1
94+
/// .into_analog()
95+
/// .observe();
96+
/// let pa0 = gpioa.pa0.into_analog(); // <- Reference voltage
97+
///
98+
/// // Only pa1_token and pa0 consumed here
99+
/// let comp1 = comp1.comparator(pa1_token, pa0, Config::default(), &rcc.clocks);
100+
/// let comp1 = comp1.enable();
101+
///
102+
/// let mut delay = cp.SYST.delay(&rcc.clocks);
103+
/// let mut adc = dp.ADC2.claim_and_configure(
104+
/// stm32g4xx_hal::adc::ClockSource::SystemClock,
105+
/// &rcc,
106+
/// stm32g4xx_hal::adc::config::AdcConfig::default(),
107+
/// &mut delay,
108+
/// false,
109+
/// );
110+
///
111+
/// // Can not reconfigure pa1 here
112+
///
113+
/// loop {
114+
/// // Can still use pa1 here
115+
/// let sample = adc.convert(&pa1, SampleTime::Cycles_640_5);
116+
/// defmt::info!("Reading: {}", sample);
117+
/// delay.delay(1000.millis());
118+
/// }
119+
/// ```
40120
fn observe<const N: usize>(self) -> (Observed<Self, N>, [ObservationToken<Self>; N]) {
41121
(
42122
Observed { peripheral: self },

0 commit comments

Comments
 (0)