Skip to content

Commit b3361a2

Browse files
committed
WIP: Fix ADC support for STM32L47x/L48x
1 parent 1c803af commit b3361a2

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

src/adc.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ use crate::{
2222
use pac::{ADC1, ADC_COMMON};
2323
use stable_deref_trait::StableDeref;
2424

25+
#[cfg(any(
26+
feature = "stm32l471",
27+
feature = "stm32l475",
28+
feature = "stm32l476",
29+
feature = "stm32l486"
30+
))]
31+
use crate::gpio::AnalogPin;
32+
2533
/// Vref internal signal, used for calibration
2634
pub struct Vref;
2735

@@ -31,6 +39,42 @@ pub struct Vbat;
3139
/// Core temperature internal signal
3240
pub struct Temperature;
3341

42+
// TODO: Avoid this hack
43+
#[cfg(any(
44+
feature = "stm32l471",
45+
feature = "stm32l475",
46+
feature = "stm32l476",
47+
feature = "stm32l486"
48+
))]
49+
impl AnalogPin for Vref {
50+
fn connect_adc(&mut self) {}
51+
fn disconnect_adc(&mut self) {}
52+
}
53+
54+
// TODO: Avoid this hack
55+
#[cfg(any(
56+
feature = "stm32l471",
57+
feature = "stm32l475",
58+
feature = "stm32l476",
59+
feature = "stm32l486"
60+
))]
61+
impl AnalogPin for Vbat {
62+
fn connect_adc(&mut self) {}
63+
fn disconnect_adc(&mut self) {}
64+
}
65+
66+
// TODO: Avoid this hack
67+
#[cfg(any(
68+
feature = "stm32l471",
69+
feature = "stm32l475",
70+
feature = "stm32l476",
71+
feature = "stm32l486"
72+
))]
73+
impl AnalogPin for Temperature {
74+
fn connect_adc(&mut self) {}
75+
fn disconnect_adc(&mut self) {}
76+
}
77+
3478
/// Analog to Digital converter interface
3579
pub struct ADC {
3680
pub(crate) adc: ADC1,
@@ -447,6 +491,15 @@ where
447491
self.start_conversion();
448492
while !self.has_completed_sequence() {}
449493

494+
#[cfg(any(
495+
feature = "stm32l471",
496+
feature = "stm32l475",
497+
feature = "stm32l476",
498+
feature = "stm32l486"
499+
))]
500+
// Connect the pin to the ADC
501+
channel.connect_adc();
502+
450503
// Read ADC value first time and discard it, as per errata sheet.
451504
// The errata states that if we do conversions slower than 1 kHz, the
452505
// first read ADC value can be corrupted, so we discard it and measure again.
@@ -458,6 +511,15 @@ where
458511
// Read ADC value
459512
let val = self.get_data();
460513

514+
#[cfg(any(
515+
feature = "stm32l471",
516+
feature = "stm32l475",
517+
feature = "stm32l476",
518+
feature = "stm32l486"
519+
))]
520+
// Disconnect the pin from the ADC
521+
channel.disconnect_adc();
522+
461523
// Disable ADC
462524
self.disable();
463525

@@ -638,11 +700,28 @@ impl Default for SampleTime {
638700
}
639701
}
640702

703+
#[cfg(not(any(
704+
feature = "stm32l471",
705+
feature = "stm32l475",
706+
feature = "stm32l476",
707+
feature = "stm32l486"
708+
)))]
641709
/// Implemented for all types that represent ADC channels
642710
pub trait Channel: EmbeddedHalChannel<ADC, ID = u8> {
643711
fn set_sample_time(&mut self, adc: &ADC1, sample_time: SampleTime);
644712
}
645713

714+
#[cfg(any(
715+
feature = "stm32l471",
716+
feature = "stm32l475",
717+
feature = "stm32l476",
718+
feature = "stm32l486"
719+
))]
720+
/// Implemented for all types that represent ADC channels
721+
pub trait Channel: EmbeddedHalChannel<ADC, ID = u8> + AnalogPin {
722+
fn set_sample_time(&mut self, adc: &ADC1, sample_time: SampleTime);
723+
}
724+
646725
macro_rules! adc_pins {
647726
(
648727
$(

src/gpio.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,44 @@ where
205205
}
206206
}
207207

208+
#[cfg(any(
209+
feature = "stm32l471",
210+
feature = "stm32l475",
211+
feature = "stm32l476",
212+
feature = "stm32l486"
213+
))]
214+
/// Analog Pin
215+
pub trait AnalogPin {
216+
fn connect_adc(&mut self);
217+
fn disconnect_adc(&mut self);
218+
}
219+
220+
#[cfg(any(
221+
feature = "stm32l471",
222+
feature = "stm32l475",
223+
feature = "stm32l476",
224+
feature = "stm32l486"
225+
))]
226+
impl<MODE, HL, const P: char, const N: u8> AnalogPin for Pin<MODE, HL, P, N> {
227+
#[inline(always)]
228+
fn connect_adc(&mut self) {
229+
unsafe {
230+
(*Gpio::<P>::ptr())
231+
.ascr
232+
.modify(|r, w| w.bits(r.bits() | (1 << N)));
233+
}
234+
}
235+
236+
#[inline(always)]
237+
fn disconnect_adc(&mut self) {
238+
unsafe {
239+
(*Gpio::<P>::ptr())
240+
.ascr
241+
.modify(|r, w| w.bits(r.bits() & !(1 << N)));
242+
}
243+
}
244+
}
245+
208246
/// Opaque MODER register
209247
pub struct MODER<const P: char> {
210248
_0: (),

0 commit comments

Comments
 (0)