commit
901d31e8f8
@ -1,16 +1,37 @@
|
|||||||
|
use core::future::poll_fn;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use crate::adc::{Adc, AdcPin, Instance, SampleTime};
|
use crate::adc::{Adc, AdcPin, Instance, SampleTime};
|
||||||
use crate::rcc::get_freqs;
|
use crate::rcc::get_freqs;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::{interrupt, Peripheral};
|
||||||
|
|
||||||
pub const VDDA_CALIB_MV: u32 = 3300;
|
pub const VDDA_CALIB_MV: u32 = 3300;
|
||||||
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
||||||
// No calibration data for F103, voltage should be 1.2v
|
// No calibration data for F103, voltage should be 1.2v
|
||||||
pub const VREF_INT: u32 = 1200;
|
pub const VREF_INT: u32 = 1200;
|
||||||
|
|
||||||
|
/// Interrupt handler.
|
||||||
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
if T::regs().sr().read().eoc() {
|
||||||
|
T::regs().cr1().modify(|w| w.set_eocie(false));
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
T::state().waker.wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl<T: Instance> AdcPin<T> for Vref {}
|
impl<T: Instance> AdcPin<T> for Vref {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
||||||
@ -95,18 +116,28 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a single conversion.
|
/// Perform a single conversion.
|
||||||
fn convert(&mut self) -> u16 {
|
async fn convert(&mut self) -> u16 {
|
||||||
T::regs().cr2().modify(|reg| {
|
T::regs().cr2().modify(|reg| {
|
||||||
reg.set_adon(true);
|
reg.set_adon(true);
|
||||||
reg.set_swstart(true);
|
reg.set_swstart(true);
|
||||||
});
|
});
|
||||||
while T::regs().cr2().read().swstart() {}
|
T::regs().cr1().modify(|w| w.set_eocie(true));
|
||||||
while !T::regs().sr().read().eoc() {}
|
|
||||||
|
poll_fn(|cx| {
|
||||||
|
T::state().waker.register(cx.waker());
|
||||||
|
|
||||||
|
if !T::regs().cr2().read().swstart() && T::regs().sr().read().eoc() {
|
||||||
|
Poll::Ready(())
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
T::regs().dr().read().0 as u16
|
T::regs().dr().read().0 as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
||||||
Self::set_channel_sample_time(pin.channel(), self.sample_time);
|
Self::set_channel_sample_time(pin.channel(), self.sample_time);
|
||||||
T::regs().cr1().modify(|reg| {
|
T::regs().cr1().modify(|reg| {
|
||||||
reg.set_scan(false);
|
reg.set_scan(false);
|
||||||
@ -123,7 +154,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
|
|
||||||
// Configure the channel to sample
|
// Configure the channel to sample
|
||||||
T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel()));
|
T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel()));
|
||||||
self.convert()
|
self.convert().await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
@ -135,3 +166,11 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
T::regs().cr2().modify(|reg| reg.set_adon(false));
|
||||||
|
|
||||||
|
T::disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -173,3 +173,23 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
use crate::pac::adc::vals;
|
||||||
|
|
||||||
|
T::regs().cr().modify(|w| w.set_adstp(true));
|
||||||
|
|
||||||
|
while T::regs().cr().read().adstp() {}
|
||||||
|
|
||||||
|
T::regs().cr().modify(|w| w.set_addis(true));
|
||||||
|
|
||||||
|
while T::regs().cr().read().aden() {}
|
||||||
|
|
||||||
|
// Disable the adc regulator
|
||||||
|
T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE));
|
||||||
|
T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::DISABLED));
|
||||||
|
|
||||||
|
T::disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,15 +31,15 @@ pub struct Adc<'d, T: Instance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
#[cfg(any(adc_f3, adc_v1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1))]
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
#[cfg(any(adc_f3, adc_v1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1))]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub waker: AtomicWaker,
|
pub waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(adc_f3, adc_v1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1))]
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -58,11 +58,14 @@ pub(crate) mod sealed {
|
|||||||
fn common_regs() -> crate::pac::adccommon::AdcCommon;
|
fn common_regs() -> crate::pac::adccommon::AdcCommon;
|
||||||
#[cfg(adc_f3)]
|
#[cfg(adc_f3)]
|
||||||
fn frequency() -> crate::time::Hertz;
|
fn frequency() -> crate::time::Hertz;
|
||||||
#[cfg(any(adc_f3, adc_v1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1))]
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AdcPin<T: Instance> {
|
pub trait AdcPin<T: Instance> {
|
||||||
|
#[cfg(any(adc_v1, adc_v2))]
|
||||||
|
fn set_as_analog(&mut self) {}
|
||||||
|
|
||||||
fn channel(&self) -> u8;
|
fn channel(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +99,7 @@ foreach_adc!(
|
|||||||
unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
|
unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(adc_f3, adc_v1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1))]
|
||||||
fn state() -> &'static sealed::State {
|
fn state() -> &'static sealed::State {
|
||||||
static STATE: sealed::State = sealed::State::new();
|
static STATE: sealed::State = sealed::State::new();
|
||||||
&STATE
|
&STATE
|
||||||
@ -120,6 +123,11 @@ macro_rules! impl_adc_pin {
|
|||||||
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
|
|
||||||
impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin {
|
impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin {
|
||||||
|
#[cfg(any(adc_v1, adc_v2))]
|
||||||
|
fn set_as_analog(&mut self) {
|
||||||
|
<Self as crate::gpio::sealed::Pin>::set_as_analog(self);
|
||||||
|
}
|
||||||
|
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
$ch
|
$ch
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use core::task::Poll;
|
|||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
|
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::peripherals::ADC;
|
use crate::peripherals::ADC;
|
||||||
use crate::{interrupt, Peripheral};
|
use crate::{interrupt, Peripheral};
|
||||||
@ -31,24 +31,24 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
impl InternalChannel<ADC> for Vbat {}
|
impl AdcPin<ADC> for Vbat {}
|
||||||
impl super::sealed::InternalChannel<ADC> for Vbat {
|
impl super::sealed::AdcPin<ADC> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl InternalChannel<ADC> for Vref {}
|
impl AdcPin<ADC> for Vref {}
|
||||||
impl super::sealed::InternalChannel<ADC> for Vref {
|
impl super::sealed::AdcPin<ADC> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl InternalChannel<ADC> for Temperature {}
|
impl AdcPin<ADC> for Temperature {}
|
||||||
impl super::sealed::InternalChannel<ADC> for Temperature {
|
impl super::sealed::AdcPin<ADC> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
@ -134,18 +134,14 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
|
T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read<P>(&mut self, pin: &mut P) -> u16
|
pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
||||||
where
|
|
||||||
P: AdcPin<T> + crate::gpio::sealed::Pin,
|
|
||||||
{
|
|
||||||
let channel = pin.channel();
|
let channel = pin.channel();
|
||||||
pin.set_as_analog();
|
pin.set_as_analog();
|
||||||
self.read_channel(channel).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
|
// A.7.5 Single conversion sequence code example - Software trigger
|
||||||
let channel = channel.channel();
|
T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
|
||||||
self.read_channel(channel).await
|
|
||||||
|
self.convert().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn convert(&mut self) -> u16 {
|
async fn convert(&mut self) -> u16 {
|
||||||
@ -171,13 +167,6 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
|
|
||||||
T::regs().dr().read().data()
|
T::regs().dr().read().data()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_channel(&mut self, channel: u8) -> u16 {
|
|
||||||
// A.7.5 Single conversion sequence code example - Software trigger
|
|
||||||
T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
|
|
||||||
|
|
||||||
self.convert().await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use super::InternalChannel;
|
|
||||||
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||||
use crate::peripherals::ADC1;
|
use crate::peripherals::ADC1;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
@ -16,8 +15,8 @@ pub const VREF_CALIB_MV: u32 = 3300;
|
|||||||
pub const ADC_POWERUP_TIME_US: u32 = 3;
|
pub const ADC_POWERUP_TIME_US: u32 = 3;
|
||||||
|
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl InternalChannel<ADC1> for VrefInt {}
|
impl AdcPin<ADC1> for VrefInt {}
|
||||||
impl super::sealed::InternalChannel<ADC1> for VrefInt {
|
impl super::sealed::AdcPin<ADC1> for VrefInt {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
@ -31,8 +30,8 @@ impl VrefInt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl InternalChannel<ADC1> for Temperature {}
|
impl AdcPin<ADC1> for Temperature {}
|
||||||
impl super::sealed::InternalChannel<ADC1> for Temperature {
|
impl super::sealed::AdcPin<ADC1> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(stm32f40, stm32f41))] {
|
if #[cfg(any(stm32f40, stm32f41))] {
|
||||||
@ -52,8 +51,8 @@ impl Temperature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
impl InternalChannel<ADC1> for Vbat {}
|
impl AdcPin<ADC1> for Vbat {}
|
||||||
impl super::sealed::InternalChannel<ADC1> for Vbat {
|
impl super::sealed::AdcPin<ADC1> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
@ -176,22 +175,11 @@ where
|
|||||||
T::regs().dr().read().0 as u16
|
T::regs().dr().read().0 as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read<P>(&mut self, pin: &mut P) -> u16
|
pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
|
||||||
where
|
|
||||||
P: AdcPin<T>,
|
|
||||||
P: crate::gpio::sealed::Pin,
|
|
||||||
{
|
|
||||||
pin.set_as_analog();
|
pin.set_as_analog();
|
||||||
|
|
||||||
self.read_channel(pin.channel())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
|
|
||||||
self.read_channel(channel.channel())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_channel(&mut self, channel: u8) -> u16 {
|
|
||||||
// Configure ADC
|
// Configure ADC
|
||||||
|
let channel = pin.channel();
|
||||||
|
|
||||||
// Select channel
|
// Select channel
|
||||||
T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
|
T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
|
||||||
@ -199,9 +187,7 @@ where
|
|||||||
// Configure channel
|
// Configure channel
|
||||||
Self::set_channel_sample_time(channel, self.sample_time);
|
Self::set_channel_sample_time(channel, self.sample_time);
|
||||||
|
|
||||||
let val = self.convert();
|
self.convert()
|
||||||
|
|
||||||
val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
@ -216,6 +202,10 @@ where
|
|||||||
|
|
||||||
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
impl<'d, T: Instance> Drop for Adc<'d, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
T::regs().cr2().modify(|reg| {
|
||||||
|
reg.set_adon(false);
|
||||||
|
});
|
||||||
|
|
||||||
T::disable();
|
T::disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut pin = p.PA1;
|
let mut pin = p.PA1;
|
||||||
|
|
||||||
let mut vrefint = adc.enable_vref(&mut Delay);
|
let mut vrefint = adc.enable_vref(&mut Delay);
|
||||||
let vrefint_sample = adc.read_internal(&mut vrefint).await;
|
let vrefint_sample = adc.read(&mut vrefint).await;
|
||||||
let convert_to_millivolts = |sample| {
|
let convert_to_millivolts = |sample| {
|
||||||
// From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf
|
// From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf
|
||||||
// 6.3.4 Embedded reference voltage
|
// 6.3.4 Embedded reference voltage
|
||||||
|
@ -5,9 +5,15 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::adc::Adc;
|
use embassy_stm32::adc::Adc;
|
||||||
|
use embassy_stm32::peripherals::ADC1;
|
||||||
|
use embassy_stm32::{adc, bind_interrupts};
|
||||||
use embassy_time::{Delay, Duration, Timer};
|
use embassy_time::{Delay, Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
ADC1_2 => adc::InterruptHandler<ADC1>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
@ -17,7 +23,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut pin = p.PB1;
|
let mut pin = p.PB1;
|
||||||
|
|
||||||
let mut vrefint = adc.enable_vref(&mut Delay);
|
let mut vrefint = adc.enable_vref(&mut Delay);
|
||||||
let vrefint_sample = adc.read(&mut vrefint);
|
let vrefint_sample = adc.read(&mut vrefint).await;
|
||||||
let convert_to_millivolts = |sample| {
|
let convert_to_millivolts = |sample| {
|
||||||
// From http://www.st.com/resource/en/datasheet/CD00161566.pdf
|
// From http://www.st.com/resource/en/datasheet/CD00161566.pdf
|
||||||
// 5.3.4 Embedded reference voltage
|
// 5.3.4 Embedded reference voltage
|
||||||
@ -27,7 +33,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let v = adc.read(&mut pin);
|
let v = adc.read(&mut pin).await;
|
||||||
info!("--> {} - {} mV", v, convert_to_millivolts(v));
|
info!("--> {} - {} mV", v, convert_to_millivolts(v));
|
||||||
Timer::after(Duration::from_millis(100)).await;
|
Timer::after(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
// Startup delay can be combined to the maximum of either
|
// Startup delay can be combined to the maximum of either
|
||||||
delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
|
delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
|
||||||
|
|
||||||
let vrefint_sample = adc.read_internal(&mut vrefint);
|
let vrefint_sample = adc.read(&mut vrefint);
|
||||||
|
|
||||||
let convert_to_millivolts = |sample| {
|
let convert_to_millivolts = |sample| {
|
||||||
// From http://www.st.com/resource/en/datasheet/DM00071990.pdf
|
// From http://www.st.com/resource/en/datasheet/DM00071990.pdf
|
||||||
@ -55,12 +55,12 @@ async fn main(_spawner: Spawner) {
|
|||||||
info!("PC1: {} ({} mV)", v, convert_to_millivolts(v));
|
info!("PC1: {} ({} mV)", v, convert_to_millivolts(v));
|
||||||
|
|
||||||
// Read internal temperature
|
// Read internal temperature
|
||||||
let v = adc.read_internal(&mut temp);
|
let v = adc.read(&mut temp);
|
||||||
let celcius = convert_to_celcius(v);
|
let celcius = convert_to_celcius(v);
|
||||||
info!("Internal temp: {} ({} C)", v, celcius);
|
info!("Internal temp: {} ({} C)", v, celcius);
|
||||||
|
|
||||||
// Read internal voltage reference
|
// Read internal voltage reference
|
||||||
let v = adc.read_internal(&mut vrefint);
|
let v = adc.read(&mut vrefint);
|
||||||
info!("VrefInt: {}", v);
|
info!("VrefInt: {}", v);
|
||||||
|
|
||||||
Timer::after(Duration::from_millis(100)).await;
|
Timer::after(Duration::from_millis(100)).await;
|
||||||
|
@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut pin = p.PA3;
|
let mut pin = p.PA3;
|
||||||
|
|
||||||
let mut vrefint = adc.enable_vrefint();
|
let mut vrefint = adc.enable_vrefint();
|
||||||
let vrefint_sample = adc.read_internal(&mut vrefint);
|
let vrefint_sample = adc.read(&mut vrefint);
|
||||||
let convert_to_millivolts = |sample| {
|
let convert_to_millivolts = |sample| {
|
||||||
// From http://www.st.com/resource/en/datasheet/DM00273119.pdf
|
// From http://www.st.com/resource/en/datasheet/DM00273119.pdf
|
||||||
// 6.3.27 Reference voltage
|
// 6.3.27 Reference voltage
|
||||||
|
Loading…
Reference in New Issue
Block a user