@@ -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
@@ -70,15 +74,39 @@ impl Adc {
70
74
71
75
/// Runs the calibration routine on the ADC
72
76
///
73
- /// Wait for tADCVREG_SETUP (20us on STM32G071x8) after calling ` new()`
74
- /// before calibrating, to wait for the ADC voltage regulator to stabilize.
77
+ /// Wait for tADCVREG_SETUP (20us on STM32G071x8) after calling [`Self:: new()`] before calibrating, to wait for the
78
+ /// ADC voltage regulator to stabilize.
75
79
///
76
80
/// Do not call if an ADC reading is ongoing.
77
81
pub fn calibrate ( & mut self ) {
78
82
self . rb . cr . modify ( |_, w| w. adcal ( ) . set_bit ( ) ) ;
79
83
while self . rb . cr . read ( ) . adcal ( ) . bit_is_set ( ) { }
80
84
}
81
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
+
82
110
/// Set the Adc sampling time
83
111
pub fn set_sample_time ( & mut self , t_samp : SampleTime ) {
84
112
self . sample_time = t_samp;
0 commit comments