5
5
//! This code has been taken from the stm32g0xx-hal project and modified slightly to support
6
6
//! STM32G4xx MCUs.
7
7
8
+ use core:: borrow:: Borrow ;
8
9
use core:: marker:: PhantomData ;
9
10
10
11
use crate :: dac;
11
12
use crate :: exti:: { Event as ExtiEvent , ExtiExt } ;
13
+ use crate :: gpio:: { FrozenPin , IsFrozen } ;
12
14
use crate :: gpio:: {
13
15
gpioa:: { PA0 , PA1 , PA11 , PA12 , PA2 , PA3 , PA4 , PA5 , PA6 , PA7 } ,
14
16
gpiob:: { PB0 , PB1 , PB14 , PB15 , PB2 , PB6 , PB7 , PB8 , PB9 } ,
15
17
gpioc:: PC2 ,
16
18
gpiof:: PF4 ,
17
- Analog , Alternate , AlternateOD , SignalEdge , AF2 , AF3 , AF8 ,
19
+ Alternate , AlternateOD , Analog , SignalEdge , AF2 , AF3 , AF8 ,
18
20
} ;
19
21
20
22
#[ cfg( any(
@@ -139,12 +141,17 @@ pub enum Hysteresis {
139
141
}
140
142
141
143
/// Comparator positive input
142
- pub trait PositiveInput < C > {
143
- fn setup ( & self , comp : & C ) ;
144
+ pub trait PositiveInput < C > : crate :: Sealed {
145
+ /// Setup comaprator to use this as its positive input
146
+ ///
147
+ /// # Safety
148
+ ///
149
+ /// Internal use only
150
+ unsafe fn setup ( & self , comp : & mut C ) ;
144
151
}
145
152
146
153
/// Comparator negative input
147
- pub trait NegativeInput < C > {
154
+ pub trait NegativeInput < C > : crate :: Sealed {
148
155
/// Does this input use the internal reference Vrefint
149
156
///
150
157
/// This only true for RefintInput
@@ -155,19 +162,36 @@ pub trait NegativeInput<C> {
155
162
/// This is only relevant for `RefintInput` other than `RefintInput::VRefint`
156
163
fn use_resistor_divider ( & self ) -> bool ;
157
164
158
- fn setup ( & self , comp : & C ) ;
165
+ /// Setup comaprator to use this as its negative input
166
+ ///
167
+ /// # Safety
168
+ ///
169
+ /// Internal use only
170
+ unsafe fn setup ( & self , comp : & mut C ) ;
159
171
}
160
172
161
173
macro_rules! positive_input_pin {
162
174
( $COMP: ident, $pin_0: ident, $pin_1: ident) => {
163
- impl PositiveInput <$COMP> for & $pin_0<Analog > {
164
- fn setup( & self , comp: & $COMP) {
175
+ impl PositiveInput <$COMP> for & $pin_0<Analog , IsFrozen > {
176
+ unsafe fn setup( & self , comp: & mut $COMP) {
177
+ comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( false ) )
178
+ }
179
+ }
180
+
181
+ impl PositiveInput <$COMP> for $pin_0<Analog > {
182
+ unsafe fn setup( & self , comp: & mut $COMP) {
165
183
comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( false ) )
166
184
}
167
185
}
168
186
169
- impl PositiveInput <$COMP> for & $pin_1<Analog > {
170
- fn setup( & self , comp: & $COMP) {
187
+ impl PositiveInput <$COMP> for & $pin_1<Analog , IsFrozen > {
188
+ unsafe fn setup( & self , comp: & mut $COMP) {
189
+ comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( true ) )
190
+ }
191
+ }
192
+
193
+ impl PositiveInput <$COMP> for $pin_1<Analog > {
194
+ unsafe fn setup( & self , comp: & mut $COMP) {
171
195
comp. csr( ) . modify( |_, w| w. inpsel( ) . bit( true ) )
172
196
}
173
197
}
@@ -212,7 +236,7 @@ macro_rules! negative_input_pin_helper {
212
236
false
213
237
}
214
238
215
- fn setup( & self , comp: & $COMP) {
239
+ unsafe fn setup( & self , comp: & mut $COMP) {
216
240
comp. csr( ) . modify( |_, w| unsafe { w. inmsel( ) . bits( $bits) } )
217
241
}
218
242
}
@@ -257,6 +281,9 @@ pub enum RefintInput {
257
281
VRefint = 0b011 ,
258
282
}
259
283
284
+ impl FrozenPin < RefintInput > for RefintInput { }
285
+ impl crate :: Sealed for RefintInput { }
286
+
260
287
macro_rules! refint_input {
261
288
( $( $COMP: ident, ) +) => { $(
262
289
impl NegativeInput <$COMP> for RefintInput {
@@ -266,7 +293,7 @@ macro_rules! refint_input {
266
293
* self != RefintInput :: VRefint
267
294
}
268
295
269
- fn setup( & self , comp: & $COMP) {
296
+ unsafe fn setup( & self , comp: & mut $COMP) {
270
297
comp. csr( )
271
298
. modify( |_, w| unsafe { w. inmsel( ) . bits( * self as u8 ) } )
272
299
}
@@ -285,15 +312,27 @@ refint_input!(COMP1, COMP2, COMP3, COMP4,);
285
312
refint_input ! ( COMP5 , COMP6 , COMP7 , ) ;
286
313
287
314
macro_rules! dac_input_helper {
288
- ( $COMP: ident: $channel: ident, $MODE: ident, $bits: expr) => {
289
- impl < ED > NegativeInput <$COMP> for & dac:: $channel<{ dac:: $MODE } , ED > {
315
+ ( $COMP: ident: $channel: ident, $MODE: ident, $ED : ty , $ bits: expr) => {
316
+ impl NegativeInput <$COMP> for & dac:: $channel<{ dac:: $MODE } , $ED , IsFrozen > {
290
317
const USE_VREFINT : bool = false ;
291
318
292
319
fn use_resistor_divider( & self ) -> bool {
293
320
false
294
321
}
295
322
296
- fn setup( & self , comp: & $COMP) {
323
+ unsafe fn setup( & self , comp: & mut $COMP) {
324
+ comp. csr( ) . modify( |_, w| unsafe { w. inmsel( ) . bits( $bits) } )
325
+ }
326
+ }
327
+
328
+ impl NegativeInput <$COMP> for dac:: $channel<{ dac:: $MODE } , $ED> {
329
+ const USE_VREFINT : bool = false ;
330
+
331
+ fn use_resistor_divider( & self ) -> bool {
332
+ false
333
+ }
334
+
335
+ unsafe fn setup( & self , comp: & mut $COMP) {
297
336
comp. csr( ) . modify( |_, w| unsafe { w. inmsel( ) . bits( $bits) } )
298
337
}
299
338
}
@@ -302,8 +341,10 @@ macro_rules! dac_input_helper {
302
341
303
342
macro_rules! dac_input {
304
343
( $COMP: ident: $channel: ident, $bits: expr) => {
305
- dac_input_helper!( $COMP: $channel, M_MIX_SIG , $bits) ;
306
- dac_input_helper!( $COMP: $channel, M_INT_SIG , $bits) ;
344
+ dac_input_helper!( $COMP: $channel, M_MIX_SIG , dac:: Enabled , $bits) ;
345
+ dac_input_helper!( $COMP: $channel, M_MIX_SIG , dac:: WaveGenerator , $bits) ;
346
+ dac_input_helper!( $COMP: $channel, M_INT_SIG , dac:: Enabled , $bits) ;
347
+ dac_input_helper!( $COMP: $channel, M_INT_SIG , dac:: WaveGenerator , $bits) ;
307
348
} ;
308
349
}
309
350
@@ -371,37 +412,46 @@ pub struct Comparator<C, ED> {
371
412
372
413
pub trait ComparatorExt < COMP > {
373
414
/// Initializes a comparator
374
- fn comparator < P : PositiveInput < COMP > , N : NegativeInput < COMP > > (
415
+ fn comparator < PP , NP , P , N > (
375
416
self ,
376
- positive_input : P ,
377
- negative_input : N ,
417
+ positive_input : PP ,
418
+ negative_input : NP ,
378
419
config : Config ,
379
420
clocks : & Clocks ,
380
- ) -> Comparator < COMP , Disabled > ;
421
+ ) -> Comparator < COMP , Disabled >
422
+ where
423
+ PP : FrozenPin < P > + PositiveInput < COMP > ,
424
+ NP : FrozenPin < N > + NegativeInput < COMP > ;
381
425
}
382
426
383
427
macro_rules! impl_comparator {
384
428
( $COMP: ty, $comp: ident, $Event: expr) => {
385
429
impl ComparatorExt <$COMP> for $COMP {
386
- fn comparator<P : PositiveInput <$COMP> , N : NegativeInput <$COMP> >(
387
- self ,
388
- positive_input: P ,
389
- negative_input: N ,
430
+ fn comparator<PP , NP , P , N >(
431
+ mut self ,
432
+ positive_input: PP ,
433
+ negative_input: NP ,
390
434
config: Config ,
391
435
clocks: & Clocks ,
392
- ) -> Comparator <$COMP, Disabled > {
393
- positive_input. setup( & self ) ;
394
- negative_input. setup( & self ) ;
436
+ ) -> Comparator <$COMP, Disabled >
437
+ where
438
+ PP : FrozenPin <P > + PositiveInput <$COMP>,
439
+ NP : FrozenPin <N > + NegativeInput <$COMP>
440
+ {
441
+ unsafe {
442
+ positive_input. borrow( ) . setup( & mut self ) ;
443
+ negative_input. borrow( ) . setup( & mut self ) ;
444
+ }
395
445
// Delay for scaler voltage bridge initialization for certain negative inputs
396
446
let voltage_scaler_delay = clocks. sys_clk. raw( ) / ( 1_000_000 / 200 ) ; // 200us
397
447
cortex_m:: asm:: delay( voltage_scaler_delay) ;
398
448
self . csr( ) . modify( |_, w| unsafe {
399
449
w. hyst( )
400
450
. bits( config. hysteresis as u8 )
401
451
. scalen( )
402
- . bit( N :: USE_VREFINT )
452
+ . bit( NP :: USE_VREFINT )
403
453
. brgen( )
404
- . bit( negative_input. use_resistor_divider( ) )
454
+ . bit( negative_input. borrow ( ) . use_resistor_divider( ) )
405
455
. pol( )
406
456
. bit( config. inverted)
407
457
} ) ;
@@ -415,13 +465,17 @@ macro_rules! impl_comparator {
415
465
416
466
impl Comparator <$COMP, Disabled > {
417
467
/// Initializes a comparator
418
- pub fn $comp<P : PositiveInput <$COMP> , N : NegativeInput <$COMP> >(
468
+ pub fn $comp<PP , NP , P , N >(
419
469
comp: $COMP,
420
- positive_input: P ,
421
- negative_input: N ,
470
+ positive_input: PP ,
471
+ negative_input: NP ,
422
472
config: Config ,
423
473
clocks: & Clocks ,
424
- ) -> Self {
474
+ ) -> Self
475
+ where
476
+ PP : FrozenPin <P > + PositiveInput <$COMP>,
477
+ NP : FrozenPin <N > + NegativeInput <$COMP>
478
+ {
425
479
comp. comparator( positive_input, negative_input, config, clocks)
426
480
}
427
481
0 commit comments