Merge #1032
1032: stm32/adc: Misc refactoring r=Dirbaio a=GrantM11235 Noteworthy changes: - Fixed a few typos in the `SampleTime`s - `set_resolution` now writes directly to the configuration register. This also fixed a bug in v3 where the resolution was changed while `ADEN` is enabled, which the datasheet says isn't allowed. Co-authored-by: Grant Miller <GrantM11235@gmail.com>
This commit is contained in:
commit
4e61d83555
@ -1,9 +1,7 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use embassy_hal_common::into_ref;
|
use embassy_hal_common::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use crate::adc::{AdcPin, Instance};
|
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::Peripheral;
|
||||||
@ -29,69 +27,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod sample_time {
|
|
||||||
/// ADC sample time
|
|
||||||
///
|
|
||||||
/// The default setting is 1.5 ADC clock cycles.
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum SampleTime {
|
|
||||||
/// 1.5 ADC clock cycles
|
|
||||||
Cycles1_5 = 0b000,
|
|
||||||
|
|
||||||
/// 7.5 ADC clock cycles
|
|
||||||
Cycles7_5 = 0b001,
|
|
||||||
|
|
||||||
/// 13.5 ADC clock cycles
|
|
||||||
Cycles13_5 = 0b010,
|
|
||||||
|
|
||||||
/// 28.5 ADC clock cycles
|
|
||||||
Cycles28_5 = 0b011,
|
|
||||||
|
|
||||||
/// 41.5 ADC clock cycles
|
|
||||||
Cycles41_5 = 0b100,
|
|
||||||
|
|
||||||
/// 55.5 ADC clock cycles
|
|
||||||
Cycles55_5 = 0b101,
|
|
||||||
|
|
||||||
/// 71.5 ADC clock cycles
|
|
||||||
Cycles71_5 = 0b110,
|
|
||||||
|
|
||||||
/// 239.5 ADC clock cycles
|
|
||||||
Cycles239_5 = 0b111,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SampleTime {
|
|
||||||
pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
|
|
||||||
match self {
|
|
||||||
SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5,
|
|
||||||
SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5,
|
|
||||||
SampleTime::Cycles13_5 => crate::pac::adc::vals::SampleTime::CYCLES13_5,
|
|
||||||
SampleTime::Cycles28_5 => crate::pac::adc::vals::SampleTime::CYCLES28_5,
|
|
||||||
SampleTime::Cycles41_5 => crate::pac::adc::vals::SampleTime::CYCLES41_5,
|
|
||||||
SampleTime::Cycles55_5 => crate::pac::adc::vals::SampleTime::CYCLES55_5,
|
|
||||||
SampleTime::Cycles71_5 => crate::pac::adc::vals::SampleTime::CYCLES71_5,
|
|
||||||
SampleTime::Cycles239_5 => crate::pac::adc::vals::SampleTime::CYCLES239_5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SampleTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Cycles28_5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use sample_time::SampleTime;
|
|
||||||
|
|
||||||
pub struct Adc<'d, T: Instance> {
|
|
||||||
sample_time: SampleTime,
|
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> Adc<'d, T> {
|
impl<'d, T: Instance> Adc<'d, T> {
|
||||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||||
into_ref!(_peri);
|
into_ref!(adc);
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -120,8 +58,8 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
delay.delay_us((1_000_000) / Self::freq().0 + 1);
|
delay.delay_us((1_000_000) / Self::freq().0 + 1);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
adc,
|
||||||
sample_time: Default::default(),
|
sample_time: Default::default(),
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,14 +139,11 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
|
let sample_time = sample_time.into();
|
||||||
if ch <= 9 {
|
if ch <= 9 {
|
||||||
T::regs()
|
T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time));
|
||||||
.smpr2()
|
|
||||||
.modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
|
|
||||||
} else {
|
} else {
|
||||||
T::regs()
|
T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
|
||||||
.smpr1()
|
|
||||||
.modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,38 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
#[cfg_attr(adc_v4, path = "v4.rs")]
|
|
||||||
#[cfg_attr(adc_v3, path = "v3.rs")]
|
|
||||||
#[cfg_attr(adc_v2, path = "v2.rs")]
|
|
||||||
#[cfg_attr(adc_g0, path = "v3.rs")]
|
|
||||||
#[cfg_attr(adc_f1, path = "f1.rs")]
|
#[cfg_attr(adc_f1, path = "f1.rs")]
|
||||||
#[cfg_attr(adc_v1, path = "v1.rs")]
|
#[cfg_attr(adc_v1, path = "v1.rs")]
|
||||||
|
#[cfg_attr(adc_v2, path = "v2.rs")]
|
||||||
|
#[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")]
|
||||||
|
#[cfg_attr(adc_v4, path = "v4.rs")]
|
||||||
mod _version;
|
mod _version;
|
||||||
|
|
||||||
|
#[cfg(not(any(adc_f1, adc_v1)))]
|
||||||
|
mod resolution;
|
||||||
|
#[cfg(not(adc_v1))]
|
||||||
|
mod sample_time;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub use _version::*;
|
pub use _version::*;
|
||||||
|
#[cfg(not(any(adc_f1, adc_v1)))]
|
||||||
|
pub use resolution::Resolution;
|
||||||
|
#[cfg(not(adc_v1))]
|
||||||
|
pub use sample_time::SampleTime;
|
||||||
|
|
||||||
use crate::peripherals;
|
use crate::peripherals;
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
#[cfg(not(adc_v1))]
|
||||||
pub trait Instance {
|
pub struct Adc<'d, T: Instance> {
|
||||||
fn regs() -> &'static crate::pac::adc::Adc;
|
#[allow(unused)]
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
adc: crate::PeripheralRef<'d, T>,
|
||||||
fn common_regs() -> &'static crate::pac::adccommon::AdcCommon;
|
sample_time: SampleTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) mod sealed {
|
||||||
|
pub trait Instance {
|
||||||
|
fn regs() -> crate::pac::adc::Adc;
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
||||||
pub trait Common {
|
fn common_regs() -> crate::pac::adccommon::AdcCommon;
|
||||||
fn regs() -> &'static crate::pac::adccommon::AdcCommon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AdcPin<T: Instance> {
|
pub trait AdcPin<T: Instance> {
|
||||||
@ -34,12 +44,11 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(adc_f1, adc_v2)))]
|
#[cfg(not(any(adc_f1, adc_v2, adc_v4)))]
|
||||||
pub trait Instance: sealed::Instance + 'static {}
|
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
|
||||||
#[cfg(any(adc_f1, adc_v2))]
|
#[cfg(any(adc_f1, adc_v2, adc_v4))]
|
||||||
pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral + 'static {}
|
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
|
||||||
pub trait Common: sealed::Common + 'static {}
|
|
||||||
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
|
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
|
||||||
pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
|
pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
|
||||||
|
|
||||||
@ -47,14 +56,14 @@ pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
|
|||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(adc, $inst:ident) => {
|
(adc, $inst:ident) => {
|
||||||
impl crate::adc::sealed::Instance for peripherals::$inst {
|
impl crate::adc::sealed::Instance for peripherals::$inst {
|
||||||
fn regs() -> &'static crate::pac::adc::Adc {
|
fn regs() -> crate::pac::adc::Adc {
|
||||||
&crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
||||||
fn common_regs() -> &'static crate::pac::adccommon::AdcCommon {
|
fn common_regs() -> crate::pac::adccommon::AdcCommon {
|
||||||
foreach_peripheral!{
|
foreach_peripheral!{
|
||||||
(adccommon, $common_inst:ident) => {
|
(adccommon, $common_inst:ident) => {
|
||||||
return &crate::pac::$common_inst
|
return crate::pac::$common_inst
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,14 +77,14 @@ foreach_peripheral!(
|
|||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(adc, ADC3) => {
|
(adc, ADC3) => {
|
||||||
impl crate::adc::sealed::Instance for peripherals::ADC3 {
|
impl crate::adc::sealed::Instance for peripherals::ADC3 {
|
||||||
fn regs() -> &'static crate::pac::adc::Adc {
|
fn regs() -> crate::pac::adc::Adc {
|
||||||
&crate::pac::ADC3
|
crate::pac::ADC3
|
||||||
}
|
}
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
||||||
fn common_regs() -> &'static crate::pac::adccommon::AdcCommon {
|
fn common_regs() -> crate::pac::adccommon::AdcCommon {
|
||||||
foreach_peripheral!{
|
foreach_peripheral!{
|
||||||
(adccommon, ADC3_COMMON) => {
|
(adccommon, ADC3_COMMON) => {
|
||||||
return &crate::pac::ADC3_COMMON
|
return crate::pac::ADC3_COMMON
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,14 +94,14 @@ foreach_peripheral!(
|
|||||||
};
|
};
|
||||||
(adc, $inst:ident) => {
|
(adc, $inst:ident) => {
|
||||||
impl crate::adc::sealed::Instance for peripherals::$inst {
|
impl crate::adc::sealed::Instance for peripherals::$inst {
|
||||||
fn regs() -> &'static crate::pac::adc::Adc {
|
fn regs() -> crate::pac::adc::Adc {
|
||||||
&crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
||||||
fn common_regs() -> &'static crate::pac::adccommon::AdcCommon {
|
fn common_regs() -> crate::pac::adccommon::AdcCommon {
|
||||||
foreach_peripheral!{
|
foreach_peripheral!{
|
||||||
(adccommon, ADC_COMMON) => {
|
(adccommon, ADC_COMMON) => {
|
||||||
return &crate::pac::ADC_COMMON
|
return crate::pac::ADC_COMMON
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,19 +111,6 @@ foreach_peripheral!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(all(not(adc_f1), not(adc_v1)))]
|
|
||||||
foreach_peripheral!(
|
|
||||||
(adccommon, $inst:ident) => {
|
|
||||||
impl sealed::Common for peripherals::$inst {
|
|
||||||
fn regs() -> &'static crate::pac::adccommon::AdcCommon {
|
|
||||||
&crate::pac::$inst
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl crate::adc::Common for peripherals::$inst {}
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
macro_rules! impl_adc_pin {
|
macro_rules! impl_adc_pin {
|
||||||
($inst:ident, $pin:ident, $ch:expr) => {
|
($inst:ident, $pin:ident, $ch:expr) => {
|
||||||
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
|
63
embassy-stm32/src/adc/resolution.rs
Normal file
63
embassy-stm32/src/adc/resolution.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#[cfg(any(adc_v2, adc_v3, adc_g0))]
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Resolution {
|
||||||
|
TwelveBit,
|
||||||
|
TenBit,
|
||||||
|
EightBit,
|
||||||
|
SixBit,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Resolution {
|
||||||
|
SixteenBit,
|
||||||
|
FourteenBit,
|
||||||
|
TwelveBit,
|
||||||
|
TenBit,
|
||||||
|
EightBit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Resolution {
|
||||||
|
fn default() -> Self {
|
||||||
|
#[cfg(any(adc_v2, adc_v3, adc_g0))]
|
||||||
|
{
|
||||||
|
Self::TwelveBit
|
||||||
|
}
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
{
|
||||||
|
Self::SixteenBit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Resolution> for crate::pac::adc::vals::Res {
|
||||||
|
fn from(res: Resolution) -> crate::pac::adc::vals::Res {
|
||||||
|
match res {
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
Resolution::SixteenBit => crate::pac::adc::vals::Res::SIXTEENBIT,
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
Resolution::FourteenBit => crate::pac::adc::vals::Res::FOURTEENBITV,
|
||||||
|
Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
|
||||||
|
Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
|
||||||
|
Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
|
||||||
|
#[cfg(any(adc_v2, adc_v3, adc_g0))]
|
||||||
|
Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Resolution {
|
||||||
|
pub fn to_max_count(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
Resolution::SixteenBit => (1 << 16) - 1,
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
Resolution::FourteenBit => (1 << 14) - 1,
|
||||||
|
Resolution::TwelveBit => (1 << 12) - 1,
|
||||||
|
Resolution::TenBit => (1 << 10) - 1,
|
||||||
|
Resolution::EightBit => (1 << 8) - 1,
|
||||||
|
#[cfg(any(adc_v2, adc_v3, adc_g0))]
|
||||||
|
Resolution::SixBit => (1 << 6) - 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
embassy-stm32/src/adc/sample_time.rs
Normal file
111
embassy-stm32/src/adc/sample_time.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
macro_rules! impl_sample_time {
|
||||||
|
($default_doc:expr, $default:ident, $pac:ty, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => {
|
||||||
|
#[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")]
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
pub enum SampleTime {
|
||||||
|
$(
|
||||||
|
#[doc = concat!($doc, " ADC clock cycles.")]
|
||||||
|
$variant,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SampleTime> for $pac {
|
||||||
|
fn from(sample_time: SampleTime) -> $pac {
|
||||||
|
match sample_time {
|
||||||
|
$(SampleTime::$variant => <$pac>::$pac_variant),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SampleTime {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::$default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(adc_f1)]
|
||||||
|
impl_sample_time!(
|
||||||
|
"1.5",
|
||||||
|
Cycles1_5,
|
||||||
|
crate::pac::adc::vals::SampleTime,
|
||||||
|
(
|
||||||
|
("1.5", Cycles1_5, CYCLES1_5),
|
||||||
|
("7.5", Cycles7_5, CYCLES7_5),
|
||||||
|
("13.5", Cycles13_5, CYCLES13_5),
|
||||||
|
("28.5", Cycles28_5, CYCLES28_5),
|
||||||
|
("41.5", Cycles41_5, CYCLES41_5),
|
||||||
|
("55.5", Cycles55_5, CYCLES55_5),
|
||||||
|
("71.5", Cycles71_5, CYCLES71_5),
|
||||||
|
("239.5", Cycles239_5, CYCLES239_5)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(adc_v2)]
|
||||||
|
impl_sample_time!(
|
||||||
|
"3",
|
||||||
|
Cycles3,
|
||||||
|
crate::pac::adc::vals::Smp,
|
||||||
|
(
|
||||||
|
("3", Cycles3, CYCLES3),
|
||||||
|
("15", Cycles15, CYCLES15),
|
||||||
|
("28", Cycles28, CYCLES28),
|
||||||
|
("56", Cycles56, CYCLES56),
|
||||||
|
("84", Cycles84, CYCLES84),
|
||||||
|
("112", Cycles112, CYCLES112),
|
||||||
|
("144", Cycles144, CYCLES144),
|
||||||
|
("480", Cycles480, CYCLES480)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(adc_v3)]
|
||||||
|
impl_sample_time!(
|
||||||
|
"2.5",
|
||||||
|
Cycles2_5,
|
||||||
|
crate::pac::adc::vals::SampleTime,
|
||||||
|
(
|
||||||
|
("2.5", Cycles2_5, CYCLES2_5),
|
||||||
|
("6.5", Cycles6_5, CYCLES6_5),
|
||||||
|
("12.5", Cycles12_5, CYCLES12_5),
|
||||||
|
("24.5", Cycles24_5, CYCLES24_5),
|
||||||
|
("47.5", Cycles47_5, CYCLES47_5),
|
||||||
|
("92.5", Cycles92_5, CYCLES92_5),
|
||||||
|
("247.5", Cycles247_5, CYCLES247_5),
|
||||||
|
("640.5", Cycles640_5, CYCLES640_5)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(adc_g0)]
|
||||||
|
impl_sample_time!(
|
||||||
|
"1.5",
|
||||||
|
Cycles1_5,
|
||||||
|
crate::pac::adc::vals::SampleTime,
|
||||||
|
(
|
||||||
|
("1.5", Cycles1_5, CYCLES1_5),
|
||||||
|
("3.5", Cycles3_5, CYCLES3_5),
|
||||||
|
("7.5", Cycles7_5, CYCLES7_5),
|
||||||
|
("12.5", Cycles12_5, CYCLES12_5),
|
||||||
|
("19.5", Cycles19_5, CYCLES19_5),
|
||||||
|
("39.5", Cycles39_5, CYCLES39_5),
|
||||||
|
("79.5", Cycles79_5, CYCLES79_5),
|
||||||
|
("160.5", Cycles160_5, CYCLES160_5)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(adc_v4)]
|
||||||
|
impl_sample_time!(
|
||||||
|
"1.5",
|
||||||
|
Cycles1_5,
|
||||||
|
crate::pac::adc::vals::Smp,
|
||||||
|
(
|
||||||
|
("1.5", Cycles1_5, CYCLES1_5),
|
||||||
|
("2.5", Cycles2_5, CYCLES2_5),
|
||||||
|
("8.5", Cycles8_5, CYCLES8_5),
|
||||||
|
("16.5", Cycles16_5, CYCLES16_5),
|
||||||
|
("32.5", Cycles32_5, CYCLES32_5),
|
||||||
|
("64.5", Cycles64_5, CYCLES64_5),
|
||||||
|
("387.5", Cycles387_5, CYCLES387_5),
|
||||||
|
("810.5", Cycles810_5, CYCLES810_5)
|
||||||
|
)
|
||||||
|
);
|
@ -1,10 +1,8 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use embassy_hal_common::into_ref;
|
use embassy_hal_common::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use super::InternalChannel;
|
use super::InternalChannel;
|
||||||
use crate::adc::{AdcPin, Instance};
|
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||||
use crate::peripherals::ADC1;
|
use crate::peripherals::ADC1;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
@ -17,39 +15,6 @@ pub const VREF_CALIB_MV: u32 = 3300;
|
|||||||
/// ADC turn-on time
|
/// ADC turn-on time
|
||||||
pub const ADC_POWERUP_TIME_US: u32 = 3;
|
pub const ADC_POWERUP_TIME_US: u32 = 3;
|
||||||
|
|
||||||
pub enum Resolution {
|
|
||||||
TwelveBit,
|
|
||||||
TenBit,
|
|
||||||
EightBit,
|
|
||||||
SixBit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Resolution {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::TwelveBit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Resolution {
|
|
||||||
fn res(&self) -> crate::pac::adc::vals::Res {
|
|
||||||
match self {
|
|
||||||
Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
|
|
||||||
Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
|
|
||||||
Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
|
|
||||||
Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_max_count(&self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Resolution::TwelveBit => (1 << 12) - 1,
|
|
||||||
Resolution::TenBit => (1 << 10) - 1,
|
|
||||||
Resolution::EightBit => (1 << 8) - 1,
|
|
||||||
Resolution::SixBit => (1 << 6) - 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl InternalChannel<ADC1> for VrefInt {}
|
impl InternalChannel<ADC1> for VrefInt {}
|
||||||
impl super::sealed::InternalChannel<ADC1> for VrefInt {
|
impl super::sealed::InternalChannel<ADC1> for VrefInt {
|
||||||
@ -94,42 +59,6 @@ impl super::sealed::InternalChannel<ADC1> for Vbat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ADC sample time
|
|
||||||
///
|
|
||||||
/// The default setting is 3 ADC clock cycles.
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum SampleTime {
|
|
||||||
Cycles3 = 0b000,
|
|
||||||
Cycles15 = 0b001,
|
|
||||||
Cycles28 = 0b010,
|
|
||||||
Cycles56 = 0b011,
|
|
||||||
Cycles85 = 0b100,
|
|
||||||
Cycles112 = 0b101,
|
|
||||||
Cycles144 = 0b110,
|
|
||||||
Cycles480 = 0b111,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SampleTime {
|
|
||||||
pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::Smp {
|
|
||||||
match self {
|
|
||||||
SampleTime::Cycles3 => crate::pac::adc::vals::Smp::CYCLES3,
|
|
||||||
SampleTime::Cycles15 => crate::pac::adc::vals::Smp::CYCLES15,
|
|
||||||
SampleTime::Cycles28 => crate::pac::adc::vals::Smp::CYCLES28,
|
|
||||||
SampleTime::Cycles56 => crate::pac::adc::vals::Smp::CYCLES56,
|
|
||||||
SampleTime::Cycles85 => crate::pac::adc::vals::Smp::CYCLES84,
|
|
||||||
SampleTime::Cycles112 => crate::pac::adc::vals::Smp::CYCLES112,
|
|
||||||
SampleTime::Cycles144 => crate::pac::adc::vals::Smp::CYCLES144,
|
|
||||||
SampleTime::Cycles480 => crate::pac::adc::vals::Smp::CYCLES480,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SampleTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Cycles3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Prescaler {
|
enum Prescaler {
|
||||||
Div2,
|
Div2,
|
||||||
Div4,
|
Div4,
|
||||||
@ -161,18 +90,12 @@ impl Prescaler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Adc<'d, T: Instance> {
|
|
||||||
sample_time: SampleTime,
|
|
||||||
resolution: Resolution,
|
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T> Adc<'d, T>
|
impl<'d, T> Adc<'d, T>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||||
into_ref!(_peri);
|
into_ref!(adc);
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
|
|
||||||
@ -188,9 +111,8 @@ where
|
|||||||
delay.delay_us(ADC_POWERUP_TIME_US);
|
delay.delay_us(ADC_POWERUP_TIME_US);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
adc,
|
||||||
sample_time: Default::default(),
|
sample_time: Default::default(),
|
||||||
resolution: Resolution::default(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +121,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_resolution(&mut self, resolution: Resolution) {
|
pub fn set_resolution(&mut self, resolution: Resolution) {
|
||||||
self.resolution = resolution;
|
unsafe {
|
||||||
|
T::regs().cr1().modify(|reg| reg.set_res(resolution.into()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables internal voltage reference and returns [VrefInt], which can be used in
|
/// Enables internal voltage reference and returns [VrefInt], which can be used in
|
||||||
@ -283,7 +207,6 @@ where
|
|||||||
|
|
||||||
unsafe fn read_channel(&mut self, channel: u8) -> u16 {
|
unsafe fn read_channel(&mut self, channel: u8) -> u16 {
|
||||||
// Configure ADC
|
// Configure ADC
|
||||||
T::regs().cr1().modify(|reg| reg.set_res(self.resolution.res()));
|
|
||||||
|
|
||||||
// Select channel
|
// Select channel
|
||||||
T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
|
T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
|
||||||
@ -297,14 +220,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
|
let sample_time = sample_time.into();
|
||||||
if ch <= 9 {
|
if ch <= 9 {
|
||||||
T::regs()
|
T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time));
|
||||||
.smpr2()
|
|
||||||
.modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
|
|
||||||
} else {
|
} else {
|
||||||
T::regs()
|
T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
|
||||||
.smpr1()
|
|
||||||
.modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use embassy_hal_common::into_ref;
|
use embassy_hal_common::into_ref;
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
|
|
||||||
use crate::adc::{AdcPin, Instance};
|
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
/// Default VREF voltage used for sample conversion to millivolts.
|
/// Default VREF voltage used for sample conversion to millivolts.
|
||||||
@ -24,39 +22,6 @@ fn enable() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Resolution {
|
|
||||||
TwelveBit,
|
|
||||||
TenBit,
|
|
||||||
EightBit,
|
|
||||||
SixBit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Resolution {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::TwelveBit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Resolution {
|
|
||||||
fn res(&self) -> crate::pac::adc::vals::Res {
|
|
||||||
match self {
|
|
||||||
Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
|
|
||||||
Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
|
|
||||||
Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
|
|
||||||
Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_max_count(&self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Resolution::TwelveBit => (1 << 12) - 1,
|
|
||||||
Resolution::TenBit => (1 << 10) - 1,
|
|
||||||
Resolution::EightBit => (1 << 8) - 1,
|
|
||||||
Resolution::SixBit => (1 << 6) - 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl<T: Instance> AdcPin<T> for VrefInt {}
|
impl<T: Instance> AdcPin<T> for VrefInt {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
|
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
|
||||||
@ -93,125 +58,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(adc_g0))]
|
|
||||||
mod sample_time {
|
|
||||||
/// ADC sample time
|
|
||||||
///
|
|
||||||
/// The default setting is 2.5 ADC clock cycles.
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum SampleTime {
|
|
||||||
/// 2.5 ADC clock cycles
|
|
||||||
Cycles2_5 = 0b000,
|
|
||||||
|
|
||||||
/// 6.5 ADC clock cycles
|
|
||||||
Cycles6_5 = 0b001,
|
|
||||||
|
|
||||||
/// 12.5 ADC clock cycles
|
|
||||||
Cycles12_5 = 0b010,
|
|
||||||
|
|
||||||
/// 24.5 ADC clock cycles
|
|
||||||
Cycles24_5 = 0b011,
|
|
||||||
|
|
||||||
/// 47.5 ADC clock cycles
|
|
||||||
Cycles47_5 = 0b100,
|
|
||||||
|
|
||||||
/// 92.5 ADC clock cycles
|
|
||||||
Cycles92_5 = 0b101,
|
|
||||||
|
|
||||||
/// 247.5 ADC clock cycles
|
|
||||||
Cycles247_5 = 0b110,
|
|
||||||
|
|
||||||
/// 640.5 ADC clock cycles
|
|
||||||
Cycles640_5 = 0b111,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SampleTime {
|
|
||||||
pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
|
|
||||||
match self {
|
|
||||||
SampleTime::Cycles2_5 => crate::pac::adc::vals::SampleTime::CYCLES2_5,
|
|
||||||
SampleTime::Cycles6_5 => crate::pac::adc::vals::SampleTime::CYCLES6_5,
|
|
||||||
SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5,
|
|
||||||
SampleTime::Cycles24_5 => crate::pac::adc::vals::SampleTime::CYCLES24_5,
|
|
||||||
SampleTime::Cycles47_5 => crate::pac::adc::vals::SampleTime::CYCLES47_5,
|
|
||||||
SampleTime::Cycles92_5 => crate::pac::adc::vals::SampleTime::CYCLES92_5,
|
|
||||||
SampleTime::Cycles247_5 => crate::pac::adc::vals::SampleTime::CYCLES247_5,
|
|
||||||
SampleTime::Cycles640_5 => crate::pac::adc::vals::SampleTime::CYCLES640_5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SampleTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Cycles2_5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(adc_g0)]
|
|
||||||
mod sample_time {
|
|
||||||
/// ADC sample time
|
|
||||||
///
|
|
||||||
/// The default setting is 1.5 ADC clock cycles.
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum SampleTime {
|
|
||||||
/// 1.5 ADC clock cycles
|
|
||||||
Cycles1_5 = 0b000,
|
|
||||||
|
|
||||||
/// 3.5 ADC clock cycles
|
|
||||||
Cycles3_5 = 0b001,
|
|
||||||
|
|
||||||
/// 7.5 ADC clock cycles
|
|
||||||
Cycles7_5 = 0b010,
|
|
||||||
|
|
||||||
/// 12.5 ADC clock cycles
|
|
||||||
Cycles12_5 = 0b011,
|
|
||||||
|
|
||||||
/// 19.5 ADC clock cycles
|
|
||||||
Cycles19_5 = 0b100,
|
|
||||||
|
|
||||||
/// 39.5 ADC clock cycles
|
|
||||||
Cycles39_5 = 0b101,
|
|
||||||
|
|
||||||
/// 79.5 ADC clock cycles
|
|
||||||
Cycles79_5 = 0b110,
|
|
||||||
|
|
||||||
/// 160.5 ADC clock cycles
|
|
||||||
Cycles160_5 = 0b111,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SampleTime {
|
|
||||||
pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
|
|
||||||
match self {
|
|
||||||
SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5,
|
|
||||||
SampleTime::Cycles3_5 => crate::pac::adc::vals::SampleTime::CYCLES3_5,
|
|
||||||
SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5,
|
|
||||||
SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5,
|
|
||||||
SampleTime::Cycles19_5 => crate::pac::adc::vals::SampleTime::CYCLES19_5,
|
|
||||||
SampleTime::Cycles39_5 => crate::pac::adc::vals::SampleTime::CYCLES39_5,
|
|
||||||
SampleTime::Cycles79_5 => crate::pac::adc::vals::SampleTime::CYCLES79_5,
|
|
||||||
SampleTime::Cycles160_5 => crate::pac::adc::vals::SampleTime::CYCLES160_5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SampleTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Cycles1_5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use sample_time::SampleTime;
|
|
||||||
|
|
||||||
pub struct Adc<'d, T: Instance> {
|
|
||||||
sample_time: SampleTime,
|
|
||||||
resolution: Resolution,
|
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance> Adc<'d, T> {
|
impl<'d, T: Instance> Adc<'d, T> {
|
||||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
|
||||||
into_ref!(_peri);
|
into_ref!(adc);
|
||||||
enable();
|
enable();
|
||||||
unsafe {
|
unsafe {
|
||||||
T::regs().cr().modify(|reg| {
|
T::regs().cr().modify(|reg| {
|
||||||
@ -241,9 +90,8 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
delay.delay_us(1);
|
delay.delay_us(1);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
adc,
|
||||||
sample_time: Default::default(),
|
sample_time: Default::default(),
|
||||||
resolution: Resolution::default(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +136,12 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_resolution(&mut self, resolution: Resolution) {
|
pub fn set_resolution(&mut self, resolution: Resolution) {
|
||||||
self.resolution = resolution;
|
unsafe {
|
||||||
|
#[cfg(not(stm32g0))]
|
||||||
|
T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
|
||||||
|
#[cfg(stm32g0)]
|
||||||
|
T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -340,12 +193,6 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
// spin
|
// spin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure ADC
|
|
||||||
#[cfg(not(stm32g0))]
|
|
||||||
T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res()));
|
|
||||||
#[cfg(stm32g0)]
|
|
||||||
T::regs().cfgr1().modify(|reg| reg.set_res(self.resolution.res()));
|
|
||||||
|
|
||||||
// Configure channel
|
// Configure channel
|
||||||
Self::set_channel_sample_time(pin.channel(), self.sample_time);
|
Self::set_channel_sample_time(pin.channel(), self.sample_time);
|
||||||
|
|
||||||
@ -374,19 +221,16 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
|
|
||||||
#[cfg(stm32g0)]
|
#[cfg(stm32g0)]
|
||||||
unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
|
unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
|
||||||
T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.sample_time()));
|
T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stm32g0))]
|
#[cfg(not(stm32g0))]
|
||||||
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
|
let sample_time = sample_time.into();
|
||||||
if ch <= 9 {
|
if ch <= 9 {
|
||||||
T::regs()
|
T::regs().smpr1().modify(|reg| reg.set_smp(ch as _, sample_time));
|
||||||
.smpr1()
|
|
||||||
.modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
|
|
||||||
} else {
|
} else {
|
||||||
T::regs()
|
T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
|
||||||
.smpr2()
|
|
||||||
.modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use atomic_polyfill::{AtomicU8, Ordering};
|
use atomic_polyfill::{AtomicU8, Ordering};
|
||||||
use embedded_hal_02::blocking::delay::DelayUs;
|
use embedded_hal_02::blocking::delay::DelayUs;
|
||||||
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
|
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
|
||||||
use pac::adccommon::vals::Presc;
|
use pac::adccommon::vals::Presc;
|
||||||
|
|
||||||
use super::{AdcPin, Instance, InternalChannel};
|
use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::{pac, Peripheral};
|
use crate::{pac, Peripheral};
|
||||||
|
|
||||||
@ -14,42 +12,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
|
|||||||
/// VREF voltage used for factory calibration of VREFINTCAL register.
|
/// VREF voltage used for factory calibration of VREFINTCAL register.
|
||||||
pub const VREF_CALIB_MV: u32 = 3300;
|
pub const VREF_CALIB_MV: u32 = 3300;
|
||||||
|
|
||||||
pub enum Resolution {
|
|
||||||
SixteenBit,
|
|
||||||
FourteenBit,
|
|
||||||
TwelveBit,
|
|
||||||
TenBit,
|
|
||||||
EightBit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Resolution {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::SixteenBit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Resolution {
|
|
||||||
fn res(&self) -> pac::adc::vals::Res {
|
|
||||||
match self {
|
|
||||||
Resolution::SixteenBit => pac::adc::vals::Res::SIXTEENBIT,
|
|
||||||
Resolution::FourteenBit => pac::adc::vals::Res::FOURTEENBITV,
|
|
||||||
Resolution::TwelveBit => pac::adc::vals::Res::TWELVEBITV,
|
|
||||||
Resolution::TenBit => pac::adc::vals::Res::TENBIT,
|
|
||||||
Resolution::EightBit => pac::adc::vals::Res::EIGHTBIT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_max_count(&self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Resolution::SixteenBit => (1 << 16) - 1,
|
|
||||||
Resolution::FourteenBit => (1 << 14) - 1,
|
|
||||||
Resolution::TwelveBit => (1 << 12) - 1,
|
|
||||||
Resolution::TenBit => (1 << 10) - 1,
|
|
||||||
Resolution::EightBit => (1 << 8) - 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Vrefint/Temperature/Vbat are only available on ADC3 on H7, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
|
// NOTE: Vrefint/Temperature/Vbat are only available on ADC3 on H7, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl<T: Instance> InternalChannel<T> for VrefInt {}
|
impl<T: Instance> InternalChannel<T> for VrefInt {}
|
||||||
@ -193,57 +155,6 @@ foreach_peripheral!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
/// ADC sample time
|
|
||||||
///
|
|
||||||
/// The default setting is 2.5 ADC clock cycles.
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum SampleTime {
|
|
||||||
/// 1.5 ADC clock cycles
|
|
||||||
Cycles1_5,
|
|
||||||
|
|
||||||
/// 2.5 ADC clock cycles
|
|
||||||
Cycles2_5,
|
|
||||||
|
|
||||||
/// 8.5 ADC clock cycles
|
|
||||||
Cycles8_5,
|
|
||||||
|
|
||||||
/// 16.5 ADC clock cycles
|
|
||||||
Cycles16_5,
|
|
||||||
|
|
||||||
/// 32.5 ADC clock cycles
|
|
||||||
Cycles32_5,
|
|
||||||
|
|
||||||
/// 64.5 ADC clock cycles
|
|
||||||
Cycles64_5,
|
|
||||||
|
|
||||||
/// 387.5 ADC clock cycles
|
|
||||||
Cycles387_5,
|
|
||||||
|
|
||||||
/// 810.5 ADC clock cycles
|
|
||||||
Cycles810_5,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SampleTime {
|
|
||||||
pub(crate) fn sample_time(&self) -> pac::adc::vals::Smp {
|
|
||||||
match self {
|
|
||||||
SampleTime::Cycles1_5 => pac::adc::vals::Smp::CYCLES1_5,
|
|
||||||
SampleTime::Cycles2_5 => pac::adc::vals::Smp::CYCLES2_5,
|
|
||||||
SampleTime::Cycles8_5 => pac::adc::vals::Smp::CYCLES8_5,
|
|
||||||
SampleTime::Cycles16_5 => pac::adc::vals::Smp::CYCLES16_5,
|
|
||||||
SampleTime::Cycles32_5 => pac::adc::vals::Smp::CYCLES32_5,
|
|
||||||
SampleTime::Cycles64_5 => pac::adc::vals::Smp::CYCLES64_5,
|
|
||||||
SampleTime::Cycles387_5 => pac::adc::vals::Smp::CYCLES387_5,
|
|
||||||
SampleTime::Cycles810_5 => pac::adc::vals::Smp::CYCLES810_5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SampleTime {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Cycles1_5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
|
// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
|
||||||
// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
|
// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -312,15 +223,9 @@ impl Prescaler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Adc<'d, T: Instance> {
|
impl<'d, T: Instance> Adc<'d, T> {
|
||||||
sample_time: SampleTime,
|
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
|
||||||
resolution: Resolution,
|
embassy_hal_common::into_ref!(adc);
|
||||||
phantom: PhantomData<&'d mut T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
|
||||||
pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
|
|
||||||
embassy_hal_common::into_ref!(_peri);
|
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
|
|
||||||
@ -350,9 +255,8 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
|
adc,
|
||||||
sample_time: Default::default(),
|
sample_time: Default::default(),
|
||||||
resolution: Resolution::default(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
};
|
};
|
||||||
s.power_up(delay);
|
s.power_up(delay);
|
||||||
s.configure_differential_inputs();
|
s.configure_differential_inputs();
|
||||||
@ -454,7 +358,9 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_resolution(&mut self, resolution: Resolution) {
|
pub fn set_resolution(&mut self, resolution: Resolution) {
|
||||||
self.resolution = resolution;
|
unsafe {
|
||||||
|
T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a single conversion.
|
/// Perform a single conversion.
|
||||||
@ -495,9 +401,6 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn read_channel(&mut self, channel: u8) -> u16 {
|
unsafe fn read_channel(&mut self, channel: u8) -> u16 {
|
||||||
// Configure ADC
|
|
||||||
T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res()));
|
|
||||||
|
|
||||||
// Configure channel
|
// Configure channel
|
||||||
Self::set_channel_sample_time(channel, self.sample_time);
|
Self::set_channel_sample_time(channel, self.sample_time);
|
||||||
|
|
||||||
@ -514,14 +417,11 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
|
let sample_time = sample_time.into();
|
||||||
if ch <= 9 {
|
if ch <= 9 {
|
||||||
T::regs()
|
T::regs().smpr(0).modify(|reg| reg.set_smp(ch as _, sample_time));
|
||||||
.smpr(0)
|
|
||||||
.modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
|
|
||||||
} else {
|
} else {
|
||||||
T::regs()
|
T::regs().smpr(1).modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
|
||||||
.smpr(1)
|
|
||||||
.modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user