@@ -60,12 +60,76 @@ pub struct Vbat;
60
60
/// Core temperature internal signal
61
61
pub struct Temperature ;
62
62
impl Temperature {
63
+ /// Precompute the inverse of `VTEMP_CAL_VREFANALOG`, in volts,
64
+ /// for floating point calculations
65
+ const INV_VREFANALOG_VOLTS : f32 = 1000. / VDDA_CALIB as f32 ;
66
+ /// Temperature at which temperature sensor has been calibrated in production
67
+ /// for data into [`VtempCal30`] (tolerance: +-5 DegC) (unit: DegC).
68
+ const VTEMP_CAL_T30 : u16 = 30 ;
69
+ /// Temperature at which temperature sensor has been calibrated in production
70
+ /// for data into [`VtempCal130`] (tolerance: +-5 DegC) (unit: DegC).
71
+ const VTEMP_CAL_T130 : u16 = 130 ;
72
+
73
+ /// Convert a sample to 12 bits. Reference voltages were captured at 12 bits.
74
+ const fn to_12b ( sample : u16 , resolution : config:: Resolution ) -> u16 {
75
+ match resolution {
76
+ config:: Resolution :: Six => sample << 6 ,
77
+ config:: Resolution :: Eight => sample << 4 ,
78
+ config:: Resolution :: Ten => sample << 2 ,
79
+ config:: Resolution :: Twelve => sample,
80
+ }
81
+ }
82
+
83
+ /// Convert a raw sample from `Temperature` to deg C.
84
+ ///
85
+ /// ## Arguments
86
+ /// * `sample`: ADC sample taken on the [`Temperature`] channel.
87
+ /// * `vdda`: Analog reference voltage (vref+) when the temperature
88
+ /// sample was taken, in volts.
89
+ /// * `resolution`: Configured ADC resolution.
90
+ #[ inline( always) ]
91
+ pub fn temperature_to_degrees_centigrade (
92
+ sample : u16 ,
93
+ vdda : f32 ,
94
+ resolution : config:: Resolution ,
95
+ ) -> f32 {
96
+ // Reference measurements were taken at 12 bits
97
+ let sample_12b = Self :: to_12b ( sample, resolution) ;
98
+
99
+ // Normalize for the difference in VDDA
100
+ let sample_normalized = sample_12b as f32 * ( vdda * Self :: INV_VREFANALOG_VOLTS ) ;
101
+
102
+ ( ( sample_normalized - VtempCal30 :: get ( ) . read ( ) as f32 )
103
+ * ( ( Self :: VTEMP_CAL_T130 - Self :: VTEMP_CAL_T30 ) as f32 ) )
104
+ / ( ( VtempCal130 :: get ( ) . read ( ) - VtempCal30 :: get ( ) . read ( ) ) as f32 )
105
+ + Self :: VTEMP_CAL_T30 as f32
106
+ }
107
+
63
108
/// Convert a raw sample from `Temperature` to deg C
109
+ ///
110
+ /// ## Arguments
111
+ /// * `sample`: ADC sample taken on the [`Temperature`] channel.
112
+ /// * `vdda`: Analog reference voltage (vref+) when the temperature
113
+ /// sample was taken, in millivolts.
114
+ /// * `resolution`: Configured ADC resolution.
64
115
#[ inline( always) ]
65
- pub fn temperature_to_degrees_centigrade ( sample : u16 ) -> f32 {
66
- ( ( 130.0 - 30.0 ) / ( VtempCal130 :: get ( ) . read ( ) as f32 - VtempCal30 :: get ( ) . read ( ) as f32 )
67
- * ( sample as f32 - VtempCal30 :: get ( ) . read ( ) as f32 ) )
68
- + 30.0
116
+ pub fn temperature_to_degrees_centigrade_coarse (
117
+ sample : u16 ,
118
+ vdda : u32 ,
119
+ resolution : config:: Resolution ,
120
+ ) -> i16 {
121
+ // Reference measurements were taken at 12 bits
122
+ let sample_12b = Self :: to_12b ( sample, resolution) ;
123
+
124
+ // Normalize for the difference in VDDA
125
+ let sample_normalized = ( ( sample_12b as u32 * vdda) / VDDA_CALIB ) as u16 ;
126
+
127
+ let t = ( ( sample_normalized as i32 - VtempCal30 :: get ( ) . read ( ) as i32 )
128
+ * ( ( Self :: VTEMP_CAL_T130 - Self :: VTEMP_CAL_T30 ) as i32 ) )
129
+ / ( ( VtempCal130 :: get ( ) . read ( ) - VtempCal30 :: get ( ) . read ( ) ) as i32 )
130
+ + Self :: VTEMP_CAL_T30 as i32 ;
131
+
132
+ t as i16
69
133
}
70
134
}
71
135
0 commit comments