@@ -34,6 +34,7 @@ use crate::gpio::{
3434use crate :: gpio:: gpioc:: { PC0 , PC1 } ;
3535use crate :: gpio:: gpioe:: { PE7 , PE8 } ;
3636use crate :: gpio:: gpiof:: PF1 ;
37+ use crate :: observable:: IntoObservationToken ;
3738use crate :: rcc:: { Clocks , Rcc } ;
3839use crate :: stm32:: { COMP , EXTI } ;
3940
@@ -140,7 +141,7 @@ pub enum Hysteresis {
140141
141142/// Comparator positive input
142143pub trait PositiveInput < C > {
143- fn setup ( & self , comp : & C ) ;
144+ fn setup ( comp : & mut C ) ;
144145}
145146
146147/// Comparator negative input
@@ -153,21 +154,21 @@ pub trait NegativeInput<C> {
153154 /// Does this input rely on dividing Vrefint using an internal resistor divider
154155 ///
155156 /// This is only relevant for `RefintInput` other than `RefintInput::VRefint`
156- fn use_resistor_divider ( & self ) -> bool ;
157+ const USE_RESISTOR_DIVIDER : bool = false ;
157158
158- fn setup ( & self , comp : & C ) ;
159+ fn setup ( comp : & mut C ) ;
159160}
160161
161162macro_rules! positive_input_pin {
162163 ( $COMP: ident, $pin_0: ident, $pin_1: ident) => {
163- impl PositiveInput <$COMP> for & $pin_0<Analog > {
164- fn setup( & self , comp: & $COMP) {
164+ impl PositiveInput <$COMP> for $pin_0<Analog > {
165+ fn setup( comp: & mut $COMP) {
165166 comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( false ) ) ;
166167 }
167168 }
168169
169- impl PositiveInput <$COMP> for & $pin_1<Analog > {
170- fn setup( & self , comp: & $COMP) {
170+ impl PositiveInput <$COMP> for $pin_1<Analog > {
171+ fn setup( comp: & mut $COMP) {
171172 comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( true ) ) ;
172173 }
173174 }
@@ -208,11 +209,7 @@ macro_rules! negative_input_pin_helper {
208209 impl NegativeInput <$COMP> for $input {
209210 const USE_VREFINT : bool = false ;
210211
211- fn use_resistor_divider( & self ) -> bool {
212- false
213- }
214-
215- fn setup( & self , comp: & $COMP) {
212+ fn setup( comp: & mut $COMP) {
216213 comp. csr( ) . modify( |_, w| unsafe { w. inmsel( ) . bits( $bits) } ) ;
217214 }
218215 }
@@ -245,30 +242,54 @@ negative_input_pin! {
245242 COMP7 : PD15 <Analog >, PB12 <Analog >,
246243}
247244
248- #[ derive( Copy , Clone , Eq , PartialEq ) ]
249- pub enum RefintInput {
245+ pub mod refint_input {
250246 /// VRefint * 1/4
251- VRefintM14 = 0b000 ,
247+ #[ derive( Copy , Clone ) ]
248+ pub struct VRefintM14 ;
249+
252250 /// VRefint * 1/2
253- VRefintM12 = 0b001 ,
251+ #[ derive( Copy , Clone ) ]
252+ pub struct VRefintM12 ;
253+
254254 /// VRefint * 3/4
255- VRefintM34 = 0b010 ,
255+ #[ derive( Copy , Clone ) ]
256+ pub struct VRefintM34 ;
257+
256258 /// VRefint
257- VRefint = 0b011 ,
259+ #[ derive( Copy , Clone ) ]
260+ pub struct VRefint ;
261+ macro_rules! impl_vrefint {
262+ ( $t: ty, $bits: expr, $use_r_div: expr) => {
263+ impl super :: RefintInput for $t {
264+ const BITS : u8 = $bits;
265+ const USE_RESISTOR_DIVIDER : bool = $use_r_div;
266+ }
267+
268+ impl crate :: observable:: Observable for $t { }
269+ impl crate :: Sealed for $t { }
270+ } ;
271+ }
272+
273+ impl_vrefint ! ( VRefintM14 , 0b000 , true ) ;
274+ impl_vrefint ! ( VRefintM12 , 0b001 , true ) ;
275+ impl_vrefint ! ( VRefintM34 , 0b010 , true ) ;
276+ impl_vrefint ! ( VRefint , 0b011 , false ) ;
277+ }
278+
279+ pub trait RefintInput {
280+ const BITS : u8 ;
281+ const USE_RESISTOR_DIVIDER : bool ;
258282}
259283
260284macro_rules! refint_input {
261285 ( $( $COMP: ident, ) +) => { $(
262- impl NegativeInput <$COMP> for RefintInput {
286+ impl < REF : RefintInput > NegativeInput <$COMP> for REF {
263287 const USE_VREFINT : bool = true ;
288+ const USE_RESISTOR_DIVIDER : bool = <REF as RefintInput >:: USE_RESISTOR_DIVIDER ;
264289
265- fn use_resistor_divider( & self ) -> bool {
266- * self != RefintInput :: VRefint
267- }
268-
269- fn setup( & self , comp: & $COMP) {
290+ fn setup( comp: & mut $COMP) {
270291 comp. csr( )
271- . modify( |_, w| unsafe { w. inmsel( ) . bits( * self as u8 ) } ) ;
292+ . modify( |_, w| unsafe { w. inmsel( ) . bits( < REF as RefintInput > :: BITS ) } ) ;
272293 }
273294 }
274295 ) +} ;
@@ -289,11 +310,7 @@ macro_rules! dac_input_helper {
289310 impl <ED > NegativeInput <$COMP> for & dac:: $channel<{ dac:: $MODE } , ED > {
290311 const USE_VREFINT : bool = false ;
291312
292- fn use_resistor_divider( & self ) -> bool {
293- false
294- }
295-
296- fn setup( & self , comp: & $COMP) {
313+ fn setup( comp: & mut $COMP) {
297314 comp. csr( ) . modify( |_, w| unsafe { w. inmsel( ) . bits( $bits) } ) ;
298315 }
299316 }
@@ -371,37 +388,48 @@ pub struct Comparator<C, ED> {
371388
372389pub trait ComparatorExt < COMP > {
373390 /// Initializes a comparator
374- fn comparator < P : PositiveInput < COMP > , N : NegativeInput < COMP > > (
391+ fn comparator < P , N , PP , NP > (
375392 self ,
376393 positive_input : P ,
377394 negative_input : N ,
378395 config : Config ,
379396 clocks : & Clocks ,
380- ) -> Comparator < COMP , Disabled > ;
397+ ) -> Comparator < COMP , Disabled >
398+ where
399+ PP : PositiveInput < COMP > ,
400+ NP : NegativeInput < COMP > ,
401+ P : IntoObservationToken < Peripheral = PP > ,
402+ N : IntoObservationToken < Peripheral = NP > ;
381403}
382404
383405macro_rules! impl_comparator {
384406 ( $COMP: ty, $comp: ident, $Event: expr) => {
385407 impl ComparatorExt <$COMP> for $COMP {
386- fn comparator<P : PositiveInput <$COMP> , N : NegativeInput <$COMP> >(
387- self ,
388- positive_input : P ,
389- negative_input : N ,
408+ fn comparator<P , N , PP , NP >(
409+ mut self ,
410+ _positive_input : P , // TODO: Store these
411+ _negative_input : N , // TODO: Store these
390412 config: Config ,
391413 clocks: & Clocks ,
392- ) -> Comparator <$COMP, Disabled > {
393- positive_input. setup( & self ) ;
394- negative_input. setup( & self ) ;
414+ ) -> Comparator <$COMP, Disabled >
415+ where
416+ PP : PositiveInput <$COMP>,
417+ NP : NegativeInput <$COMP>,
418+ P : IntoObservationToken <Peripheral = PP >,
419+ N : IntoObservationToken <Peripheral = NP >,
420+ {
421+ PP :: setup( & mut self ) ;
422+ PP :: setup( & mut self ) ;
395423 // Delay for scaler voltage bridge initialization for certain negative inputs
396424 let voltage_scaler_delay = clocks. sys_clk. raw( ) / ( 1_000_000 / 200 ) ; // 200us
397425 cortex_m:: asm:: delay( voltage_scaler_delay) ;
398426 self . csr( ) . modify( |_, w| unsafe {
399427 w. hyst( )
400428 . bits( config. hysteresis as u8 )
401429 . scalen( )
402- . bit( N :: USE_VREFINT )
430+ . bit( NP :: USE_VREFINT )
403431 . brgen( )
404- . bit( negative_input . use_resistor_divider ( ) )
432+ . bit( NP :: USE_RESISTOR_DIVIDER )
405433 . pol( )
406434 . bit( config. inverted)
407435 } ) ;
@@ -415,13 +443,19 @@ macro_rules! impl_comparator {
415443
416444 impl Comparator <$COMP, Disabled > {
417445 /// Initializes a comparator
418- pub fn $comp<P : PositiveInput <$COMP> , N : NegativeInput <$COMP> >(
446+ pub fn $comp<P , N , PP , NP >(
419447 comp: $COMP,
420448 positive_input: P ,
421449 negative_input: N ,
422450 config: Config ,
423451 clocks: & Clocks ,
424- ) -> Self {
452+ ) -> Self
453+ where
454+ PP : PositiveInput <$COMP>,
455+ NP : NegativeInput <$COMP>,
456+ P : IntoObservationToken <Peripheral = PP >,
457+ N : IntoObservationToken <Peripheral = NP >,
458+ {
425459 comp. comparator( positive_input, negative_input, config, clocks)
426460 }
427461
0 commit comments