@@ -54,6 +54,10 @@ pub struct Adc {
54
54
precision : Precision ,
55
55
}
56
56
57
+ /// Contains the calibration factors for the ADC which can be reused with [`Adc::set_calibration()`]
58
+ #[ derive( Clone , Copy , PartialEq , Eq , Debug ) ]
59
+ pub struct CalibrationFactor ( pub u8 ) ;
60
+
57
61
impl Adc {
58
62
pub fn new ( adc : ADC , rcc : & mut Rcc ) -> Self {
59
63
// Enable ADC clocks
@@ -68,6 +72,41 @@ impl Adc {
68
72
}
69
73
}
70
74
75
+ /// Runs the calibration routine on the ADC
76
+ ///
77
+ /// Wait for tADCVREG_SETUP (20us on STM32G071x8) after calling [`Self::new()`] before calibrating, to wait for the
78
+ /// ADC voltage regulator to stabilize.
79
+ ///
80
+ /// Do not call if an ADC reading is ongoing.
81
+ pub fn calibrate ( & mut self ) {
82
+ self . rb . cr . modify ( |_, w| w. adcal ( ) . set_bit ( ) ) ;
83
+ while self . rb . cr . read ( ) . adcal ( ) . bit_is_set ( ) { }
84
+ }
85
+
86
+ /// Returns the calibration factors used by the ADC
87
+ ///
88
+ /// The ADC does not have a factory-stored calibration, [`Self::calibrate()`] must be run before calling this
89
+ /// for the returned value to be useful.
90
+ ///
91
+ /// The ADC loses its calibration factors when Standby or Vbat mode is entered. Saving and restoring the calibration
92
+ /// factors can be used to recalibrate the ADC after waking up from sleep more quickly than re-running calibraiton.
93
+ /// Note that VDDA changes and to a lesser extent temperature changes affect the ADC operating conditions and
94
+ /// calibration should be run again for the best accuracy.
95
+ pub fn get_calibration ( & self ) -> CalibrationFactor {
96
+ CalibrationFactor ( self . rb . calfact . read ( ) . calfact ( ) . bits ( ) )
97
+ }
98
+
99
+ /// Writes the calibration factors used by the ADC
100
+ ///
101
+ /// See [`Self::get_calibration()`].
102
+ ///
103
+ /// Do not call if an ADC reading is ongoing.
104
+ pub fn set_calibration ( & mut self , calfact : CalibrationFactor ) {
105
+ self . rb
106
+ . calfact
107
+ . write ( |w| unsafe { w. calfact ( ) . bits ( calfact. 0 ) } ) ;
108
+ }
109
+
71
110
/// Set the Adc sampling time
72
111
pub fn set_sample_time ( & mut self , t_samp : SampleTime ) {
73
112
self . sample_time = t_samp;
0 commit comments