@@ -339,6 +339,12 @@ macro_rules! adc_hal {
339
339
this_adc
340
340
}
341
341
342
+ /// Releases the ADC peripheral and associated pins
343
+ pub fn free( mut self ) -> $ADC {
344
+ self . disable( ) ;
345
+ self . rb
346
+ }
347
+
342
348
/// Software can use CkMode::SYNCDIV1 only if
343
349
/// hclk and sysclk are the same. (see reference manual 15.3.3)
344
350
fn clocks_welldefined( & self , clocks: Clocks ) -> bool {
@@ -373,16 +379,47 @@ macro_rules! adc_hal {
373
379
self . rb. cfgr. modify( |_, w| w. align( ) . variant( align. into( ) ) ) ;
374
380
}
375
381
382
+ /// Software procedure to enable the ADC
383
+ /// According to RM0316 15.3.9
376
384
fn enable( & mut self ) {
377
- self . rb. cr. modify( |_, w| w. aden( ) . enable( ) ) ;
378
- while self . rb. isr. read( ) . adrdy( ) . is_not_ready( ) { }
385
+ // This check assumes, that the ADC was enabled before and it was waited until
386
+ // ADRDY=1 was set.
387
+ // This assumption is true, if the peripheral was initially enabled through
388
+ // this method.
389
+ if !self . rb. cr. read( ) . aden( ) . is_enable( ) {
390
+ // Set ADEN=1
391
+ self . rb. cr. modify( |_, w| w. aden( ) . enable( ) ) ;
392
+ // Wait until ADRDY=1 (ADRDY is set after the ADC startup time). This can be
393
+ // done using the associated interrupt (setting ADRDYIE=1).
394
+ while self . rb. isr. read( ) . adrdy( ) . is_not_ready( ) { }
395
+ }
379
396
}
380
397
398
+ /// Disable according to RM0316 15.3.9
381
399
fn disable( & mut self ) {
382
- self . rb. cr. modify( |_, w| w. addis( ) . disable( ) ) ;
400
+ // NOTE: Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0
401
+ // (ADC is enabled and eventually converting a regular conversion and there is no
402
+ // pending request to disable the ADC)
403
+ if self . rb. cr. read( ) . addis( ) . bit( ) == false
404
+ && ( self . rb. cr. read( ) . adstart( ) . bit( ) || self . rb. cr. read( ) . jadstart( ) . bit( ) ) {
405
+ self . rb. cr. modify( |_, w| w. adstp( ) . stop( ) ) ;
406
+ // NOTE: In auto-injection mode (JAUTO=1), setting ADSTP bit aborts both
407
+ // regular and injected conversions (do not use JADSTP)
408
+ if !self . rb. cfgr. read( ) . jauto( ) . is_enabled( ) {
409
+ self . rb. cr. modify( |_, w| w. jadstp( ) . stop( ) ) ;
410
+ }
411
+ while self . rb. cr. read( ) . adstp( ) . bit( ) || self . rb. cr. read( ) . jadstp( ) . bit( ) { }
412
+ }
413
+
414
+ // NOTE: Software is allowed to set ADDIS only when ADEN=1 and both ADSTART=0
415
+ // and JADSTART=0 (which ensures that no conversion is ongoing)
416
+ if self . rb. cr. read( ) . aden( ) . is_enable( ) {
417
+ self . rb. cr. modify( |_, w| w. addis( ) . disable( ) ) ;
418
+ while self . rb. cr. read( ) . addis( ) . bit( ) { }
419
+ }
383
420
}
384
421
385
- /// Calibrate according to 15.3.8 in the Reference Manual
422
+ /// Calibrate according to RM0316 15.3.8
386
423
fn calibrate( & mut self ) {
387
424
if !self . rb. cr. read( ) . advregen( ) . is_enabled( ) {
388
425
self . advregen_enable( ) ;
@@ -425,7 +462,9 @@ macro_rules! adc_hal {
425
462
426
463
/// busy ADC read
427
464
fn convert_one( & mut self , chan: u8 ) -> u16 {
428
- self . ensure_oneshot( ) ;
465
+ if self . operation_mode != Some ( OperationMode :: OneShot ) {
466
+ self . setup_oneshot( ) ;
467
+ }
429
468
self . set_chan_smps( chan, SampleTime :: default ( ) ) ;
430
469
self . select_single_chan( chan) ;
431
470
@@ -435,12 +474,6 @@ macro_rules! adc_hal {
435
474
return self . rb. dr. read( ) . rdata( ) . bits( ) ;
436
475
}
437
476
438
- fn ensure_oneshot( & mut self ) {
439
- if self . operation_mode != Some ( OperationMode :: OneShot ) {
440
- self . setup_oneshot( ) ;
441
- }
442
- }
443
-
444
477
/// This should only be invoked with the defined channels for the particular
445
478
/// device. (See Pin/Channel mapping above)
446
479
fn select_single_chan( & self , chan: u8 ) {
@@ -477,15 +510,16 @@ macro_rules! adc_hal {
477
510
478
511
}
479
512
480
- impl <WORD , PIN > OneShot <$ADC, WORD , PIN > for Adc <$ADC>
513
+ impl <Word , Pin > OneShot <$ADC, Word , Pin > for Adc <$ADC>
481
514
where
482
- WORD : From <u16 >,
483
- PIN : Channel <$ADC, ID = u8 >,
515
+ Word : From <u16 >,
516
+ Pin : Channel <$ADC, ID = u8 >,
484
517
{
485
518
type Error = ( ) ;
486
519
487
- fn read( & mut self , _pin: & mut PIN ) -> nb:: Result <WORD , Self :: Error > {
488
- let res = self . convert_one( PIN :: channel( ) ) ;
520
+ fn read( & mut self , _pin: & mut Pin ) -> nb:: Result <Word , Self :: Error > {
521
+ // TODO: Convert back to previous mode after use.
522
+ let res = self . convert_one( Pin :: channel( ) ) ;
489
523
return Ok ( res. into( ) ) ;
490
524
}
491
525
}
0 commit comments