Skip to content

Commit e3a1333

Browse files
authored
Merge pull request #258 from Crzyrndm/l47x-adc-temperature
L47x/L48x adc temperature
2 parents 1a56cfd + 857e731 commit e3a1333

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

examples/adc_dma.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const APP: () = {
6666
&mut delay,
6767
);
6868

69-
let mut temp_pin = adc.enable_temperature();
69+
let mut temp_pin = adc.enable_temperature(&mut delay);
7070

7171
let dma1_channel = dma_channels.1;
7272

src/adc.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,19 @@ impl ADC {
199199
}
200200

201201
/// Enable and get the `Temperature`
202-
pub fn enable_temperature(&mut self) -> Temperature {
202+
pub fn enable_temperature(&mut self, delay: &mut impl DelayUs<u32>) -> Temperature {
203203
self.common.ccr.modify(|_, w| w.ch17sel().set_bit());
204204

205+
// rm0351 section 18.4.32 pg580 (L47/L48/L49/L4A models)
206+
// Note:
207+
// The sensor has a startup time after waking from power-down mode before it can output VTS
208+
// at the correct level. The ADC also has a startup time after power-on, so to minimize the
209+
// delay, the ADEN and CH17SEL bits should be set at the same time.
210+
//
211+
// https://github.com/STMicroelectronics/STM32CubeL4/blob/master/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h#L1363
212+
// 120us is used in the ST HAL code
213+
delay.delay_us(150);
214+
205215
Temperature {}
206216
}
207217

@@ -267,9 +277,14 @@ impl ADC {
267277
}
268278

269279
/// Convert a raw sample from the `Temperature` to deg C
270-
pub fn to_degrees_centigrade(sample: u16) -> f32 {
271-
(130.0 - 30.0) / (VtempCal130::get().read() as f32 - VtempCal30::get().read() as f32)
272-
* (sample as f32 - VtempCal30::get().read() as f32)
280+
pub fn to_degrees_centigrade(&self, sample: u16) -> f32 {
281+
let sample = (u32::from(sample) * self.calibrated_vdda) / VDDA_CALIB_MV;
282+
(VtempCal130::TEMP_DEGREES - VtempCal30::TEMP_DEGREES) as f32
283+
// as signed because RM0351 doesn't specify against this being an
284+
// inverse relation (which would result in a negative differential)
285+
/ (VtempCal130::get().read() as i32 - VtempCal30::get().read() as i32) as f32
286+
// this can definitely be negative so must be done as a signed value
287+
* (sample as i32 - VtempCal30::get().read() as i32) as f32
273288
+ 30.0
274289
}
275290

src/signature.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,33 @@ impl VrefCal {
9393
}
9494

9595
/// A temperature reading taken at 30°C stored at the factory
96+
/// aka TS_CAL1 in reference manual
9697
#[derive(Debug)]
9798
#[repr(C)]
9899
pub struct VtempCal30(u16);
99100
define_ptr_type!(VtempCal30, 0x1FFF_75A8);
100101

101102
impl VtempCal30 {
103+
/// aka TS_CAL1_TEMP in reference manual
104+
pub const TEMP_DEGREES: u16 = 30;
102105
/// Read calibration value
103106
pub fn read(&self) -> u16 {
104107
self.0
105108
}
106109
}
107110

108111
/// A temperature reading taken at 130°C stored at the factory
112+
/// aka TS_CAL2 in reference manual
109113
#[derive(Debug)]
110114
#[repr(C)]
111115
pub struct VtempCal130(u16);
112116
define_ptr_type!(VtempCal130, 0x1FFF_75CA);
113117

114118
impl VtempCal130 {
119+
/// aka TS_CAL2_TEMP in reference manual
120+
/// Feature gate Required: this is 110 for L47x/L48x, 130 for other L4s according to
121+
/// https://github.com/STMicroelectronics/STM32CubeL4/blob/5e1553e07706491bd11f4edd304e093b6e4b83a4/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h#L352-L356
122+
pub const TEMP_DEGREES: u16 = 130;
115123
/// Read calibration value
116124
pub fn read(&self) -> u16 {
117125
self.0

0 commit comments

Comments
 (0)