aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/adc/f1.rs79
-rw-r--r--embassy-stm32/src/adc/mod.rs80
-rw-r--r--embassy-stm32/src/adc/resolution.rs63
-rw-r--r--embassy-stm32/src/adc/sample_time.rs111
-rw-r--r--embassy-stm32/src/adc/v2.rs100
-rw-r--r--embassy-stm32/src/adc/v3.rs184
-rw-r--r--embassy-stm32/src/adc/v4.rs122
7 files changed, 254 insertions, 485 deletions
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index c5b317ce9..d30ec001d 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -1,9 +1,7 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::into_ref; 1use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
5 3
6use crate::adc::{AdcPin, Instance}; 4use crate::adc::{Adc, AdcPin, Instance, SampleTime};
7use crate::rcc::get_freqs; 5use crate::rcc::get_freqs;
8use crate::time::Hertz; 6use crate::time::Hertz;
9use crate::Peripheral; 7use crate::Peripheral;
@@ -29,69 +27,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
29 } 27 }
30} 28}
31 29
32mod sample_time {
33 /// ADC sample time
34 ///
35 /// The default setting is 1.5 ADC clock cycles.
36 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
37 pub enum SampleTime {
38 /// 1.5 ADC clock cycles
39 Cycles1_5 = 0b000,
40
41 /// 7.5 ADC clock cycles
42 Cycles7_5 = 0b001,
43
44 /// 13.5 ADC clock cycles
45 Cycles13_5 = 0b010,
46
47 /// 28.5 ADC clock cycles
48 Cycles28_5 = 0b011,
49
50 /// 41.5 ADC clock cycles
51 Cycles41_5 = 0b100,
52
53 /// 55.5 ADC clock cycles
54 Cycles55_5 = 0b101,
55
56 /// 71.5 ADC clock cycles
57 Cycles71_5 = 0b110,
58
59 /// 239.5 ADC clock cycles
60 Cycles239_5 = 0b111,
61 }
62
63 impl SampleTime {
64 pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
65 match self {
66 SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5,
67 SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5,
68 SampleTime::Cycles13_5 => crate::pac::adc::vals::SampleTime::CYCLES13_5,
69 SampleTime::Cycles28_5 => crate::pac::adc::vals::SampleTime::CYCLES28_5,
70 SampleTime::Cycles41_5 => crate::pac::adc::vals::SampleTime::CYCLES41_5,
71 SampleTime::Cycles55_5 => crate::pac::adc::vals::SampleTime::CYCLES55_5,
72 SampleTime::Cycles71_5 => crate::pac::adc::vals::SampleTime::CYCLES71_5,
73 SampleTime::Cycles239_5 => crate::pac::adc::vals::SampleTime::CYCLES239_5,
74 }
75 }
76 }
77
78 impl Default for SampleTime {
79 fn default() -> Self {
80 Self::Cycles28_5
81 }
82 }
83}
84
85pub use sample_time::SampleTime;
86
87pub struct Adc<'d, T: Instance> {
88 sample_time: SampleTime,
89 phantom: PhantomData<&'d mut T>,
90}
91
92impl<'d, T: Instance> Adc<'d, T> { 30impl<'d, T: Instance> Adc<'d, T> {
93 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 31 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
94 into_ref!(_peri); 32 into_ref!(adc);
95 T::enable(); 33 T::enable();
96 T::reset(); 34 T::reset();
97 unsafe { 35 unsafe {
@@ -120,8 +58,8 @@ impl<'d, T: Instance> Adc<'d, T> {
120 delay.delay_us((1_000_000) / Self::freq().0 + 1); 58 delay.delay_us((1_000_000) / Self::freq().0 + 1);
121 59
122 Self { 60 Self {
61 adc,
123 sample_time: Default::default(), 62 sample_time: Default::default(),
124 phantom: PhantomData,
125 } 63 }
126 } 64 }
127 65
@@ -201,14 +139,11 @@ impl<'d, T: Instance> Adc<'d, T> {
201 } 139 }
202 140
203 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 141 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
142 let sample_time = sample_time.into();
204 if ch <= 9 { 143 if ch <= 9 {
205 T::regs() 144 T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time));
206 .smpr2()
207 .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
208 } else { 145 } else {
209 T::regs() 146 T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
210 .smpr1()
211 .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
212 } 147 }
213 } 148 }
214} 149}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 0eb4eba73..ec49dace7 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -1,28 +1,38 @@
1#![macro_use] 1#![macro_use]
2 2
3#[cfg_attr(adc_v4, path = "v4.rs")]
4#[cfg_attr(adc_v3, path = "v3.rs")]
5#[cfg_attr(adc_v2, path = "v2.rs")]
6#[cfg_attr(adc_g0, path = "v3.rs")]
7#[cfg_attr(adc_f1, path = "f1.rs")] 3#[cfg_attr(adc_f1, path = "f1.rs")]
8#[cfg_attr(adc_v1, path = "v1.rs")] 4#[cfg_attr(adc_v1, path = "v1.rs")]
5#[cfg_attr(adc_v2, path = "v2.rs")]
6#[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")]
7#[cfg_attr(adc_v4, path = "v4.rs")]
9mod _version; 8mod _version;
10 9
10#[cfg(not(any(adc_f1, adc_v1)))]
11mod resolution;
12#[cfg(not(adc_v1))]
13mod sample_time;
14
11#[allow(unused)] 15#[allow(unused)]
12pub use _version::*; 16pub use _version::*;
17#[cfg(not(any(adc_f1, adc_v1)))]
18pub use resolution::Resolution;
19#[cfg(not(adc_v1))]
20pub use sample_time::SampleTime;
13 21
14use crate::peripherals; 22use crate::peripherals;
15 23
24#[cfg(not(adc_v1))]
25pub struct Adc<'d, T: Instance> {
26 #[allow(unused)]
27 adc: crate::PeripheralRef<'d, T>,
28 sample_time: SampleTime,
29}
30
16pub(crate) mod sealed { 31pub(crate) mod sealed {
17 pub trait Instance { 32 pub trait Instance {
18 fn regs() -> &'static crate::pac::adc::Adc; 33 fn regs() -> crate::pac::adc::Adc;
19 #[cfg(all(not(adc_f1), not(adc_v1)))] 34 #[cfg(all(not(adc_f1), not(adc_v1)))]
20 fn common_regs() -> &'static crate::pac::adccommon::AdcCommon; 35 fn common_regs() -> crate::pac::adccommon::AdcCommon;
21 }
22
23 #[cfg(all(not(adc_f1), not(adc_v1)))]
24 pub trait Common {
25 fn regs() -> &'static crate::pac::adccommon::AdcCommon;
26 } 36 }
27 37
28 pub trait AdcPin<T: Instance> { 38 pub trait AdcPin<T: Instance> {
@@ -34,12 +44,11 @@ pub(crate) mod sealed {
34 } 44 }
35} 45}
36 46
37#[cfg(not(any(adc_f1, adc_v2)))] 47#[cfg(not(any(adc_f1, adc_v2, adc_v4)))]
38pub trait Instance: sealed::Instance + 'static {} 48pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
39#[cfg(any(adc_f1, adc_v2))] 49#[cfg(any(adc_f1, adc_v2, adc_v4))]
40pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral + 'static {} 50pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
41#[cfg(all(not(adc_f1), not(adc_v1)))] 51
42pub trait Common: sealed::Common + 'static {}
43pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 52pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
44pub trait InternalChannel<T>: sealed::InternalChannel<T> {} 53pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
45 54
@@ -47,14 +56,14 @@ pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
47foreach_peripheral!( 56foreach_peripheral!(
48 (adc, $inst:ident) => { 57 (adc, $inst:ident) => {
49 impl crate::adc::sealed::Instance for peripherals::$inst { 58 impl crate::adc::sealed::Instance for peripherals::$inst {
50 fn regs() -> &'static crate::pac::adc::Adc { 59 fn regs() -> crate::pac::adc::Adc {
51 &crate::pac::$inst 60 crate::pac::$inst
52 } 61 }
53 #[cfg(all(not(adc_f1), not(adc_v1)))] 62 #[cfg(all(not(adc_f1), not(adc_v1)))]
54 fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { 63 fn common_regs() -> crate::pac::adccommon::AdcCommon {
55 foreach_peripheral!{ 64 foreach_peripheral!{
56 (adccommon, $common_inst:ident) => { 65 (adccommon, $common_inst:ident) => {
57 return &crate::pac::$common_inst 66 return crate::pac::$common_inst
58 }; 67 };
59 } 68 }
60 } 69 }
@@ -68,14 +77,14 @@ foreach_peripheral!(
68foreach_peripheral!( 77foreach_peripheral!(
69 (adc, ADC3) => { 78 (adc, ADC3) => {
70 impl crate::adc::sealed::Instance for peripherals::ADC3 { 79 impl crate::adc::sealed::Instance for peripherals::ADC3 {
71 fn regs() -> &'static crate::pac::adc::Adc { 80 fn regs() -> crate::pac::adc::Adc {
72 &crate::pac::ADC3 81 crate::pac::ADC3
73 } 82 }
74 #[cfg(all(not(adc_f1), not(adc_v1)))] 83 #[cfg(all(not(adc_f1), not(adc_v1)))]
75 fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { 84 fn common_regs() -> crate::pac::adccommon::AdcCommon {
76 foreach_peripheral!{ 85 foreach_peripheral!{
77 (adccommon, ADC3_COMMON) => { 86 (adccommon, ADC3_COMMON) => {
78 return &crate::pac::ADC3_COMMON 87 return crate::pac::ADC3_COMMON
79 }; 88 };
80 } 89 }
81 } 90 }
@@ -85,14 +94,14 @@ foreach_peripheral!(
85 }; 94 };
86 (adc, $inst:ident) => { 95 (adc, $inst:ident) => {
87 impl crate::adc::sealed::Instance for peripherals::$inst { 96 impl crate::adc::sealed::Instance for peripherals::$inst {
88 fn regs() -> &'static crate::pac::adc::Adc { 97 fn regs() -> crate::pac::adc::Adc {
89 &crate::pac::$inst 98 crate::pac::$inst
90 } 99 }
91 #[cfg(all(not(adc_f1), not(adc_v1)))] 100 #[cfg(all(not(adc_f1), not(adc_v1)))]
92 fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { 101 fn common_regs() -> crate::pac::adccommon::AdcCommon {
93 foreach_peripheral!{ 102 foreach_peripheral!{
94 (adccommon, ADC_COMMON) => { 103 (adccommon, ADC_COMMON) => {
95 return &crate::pac::ADC_COMMON 104 return crate::pac::ADC_COMMON
96 }; 105 };
97 } 106 }
98 } 107 }
@@ -102,19 +111,6 @@ foreach_peripheral!(
102 }; 111 };
103); 112);
104 113
105#[cfg(all(not(adc_f1), not(adc_v1)))]
106foreach_peripheral!(
107 (adccommon, $inst:ident) => {
108 impl sealed::Common for peripherals::$inst {
109 fn regs() -> &'static crate::pac::adccommon::AdcCommon {
110 &crate::pac::$inst
111 }
112 }
113
114 impl crate::adc::Common for peripherals::$inst {}
115 };
116);
117
118macro_rules! impl_adc_pin { 114macro_rules! impl_adc_pin {
119 ($inst:ident, $pin:ident, $ch:expr) => { 115 ($inst:ident, $pin:ident, $ch:expr) => {
120 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} 116 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs
new file mode 100644
index 000000000..62b52a46c
--- /dev/null
+++ b/embassy-stm32/src/adc/resolution.rs
@@ -0,0 +1,63 @@
1#[cfg(any(adc_v2, adc_v3, adc_g0))]
2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3pub enum Resolution {
4 TwelveBit,
5 TenBit,
6 EightBit,
7 SixBit,
8}
9
10#[cfg(adc_v4)]
11#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub enum Resolution {
13 SixteenBit,
14 FourteenBit,
15 TwelveBit,
16 TenBit,
17 EightBit,
18}
19
20impl Default for Resolution {
21 fn default() -> Self {
22 #[cfg(any(adc_v2, adc_v3, adc_g0))]
23 {
24 Self::TwelveBit
25 }
26 #[cfg(adc_v4)]
27 {
28 Self::SixteenBit
29 }
30 }
31}
32
33impl From<Resolution> for crate::pac::adc::vals::Res {
34 fn from(res: Resolution) -> crate::pac::adc::vals::Res {
35 match res {
36 #[cfg(adc_v4)]
37 Resolution::SixteenBit => crate::pac::adc::vals::Res::SIXTEENBIT,
38 #[cfg(adc_v4)]
39 Resolution::FourteenBit => crate::pac::adc::vals::Res::FOURTEENBITV,
40 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
41 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
42 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
43 #[cfg(any(adc_v2, adc_v3, adc_g0))]
44 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
45 }
46 }
47}
48
49impl Resolution {
50 pub fn to_max_count(&self) -> u32 {
51 match self {
52 #[cfg(adc_v4)]
53 Resolution::SixteenBit => (1 << 16) - 1,
54 #[cfg(adc_v4)]
55 Resolution::FourteenBit => (1 << 14) - 1,
56 Resolution::TwelveBit => (1 << 12) - 1,
57 Resolution::TenBit => (1 << 10) - 1,
58 Resolution::EightBit => (1 << 8) - 1,
59 #[cfg(any(adc_v2, adc_v3, adc_g0))]
60 Resolution::SixBit => (1 << 6) - 1,
61 }
62 }
63}
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs
new file mode 100644
index 000000000..60ba80048
--- /dev/null
+++ b/embassy-stm32/src/adc/sample_time.rs
@@ -0,0 +1,111 @@
1macro_rules! impl_sample_time {
2 ($default_doc:expr, $default:ident, $pac:ty, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => {
3 #[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")]
4 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
5 pub enum SampleTime {
6 $(
7 #[doc = concat!($doc, " ADC clock cycles.")]
8 $variant,
9 )*
10 }
11
12 impl From<SampleTime> for $pac {
13 fn from(sample_time: SampleTime) -> $pac {
14 match sample_time {
15 $(SampleTime::$variant => <$pac>::$pac_variant),*
16 }
17 }
18 }
19
20 impl Default for SampleTime {
21 fn default() -> Self {
22 Self::$default
23 }
24 }
25 };
26}
27
28#[cfg(adc_f1)]
29impl_sample_time!(
30 "1.5",
31 Cycles1_5,
32 crate::pac::adc::vals::SampleTime,
33 (
34 ("1.5", Cycles1_5, CYCLES1_5),
35 ("7.5", Cycles7_5, CYCLES7_5),
36 ("13.5", Cycles13_5, CYCLES13_5),
37 ("28.5", Cycles28_5, CYCLES28_5),
38 ("41.5", Cycles41_5, CYCLES41_5),
39 ("55.5", Cycles55_5, CYCLES55_5),
40 ("71.5", Cycles71_5, CYCLES71_5),
41 ("239.5", Cycles239_5, CYCLES239_5)
42 )
43);
44
45#[cfg(adc_v2)]
46impl_sample_time!(
47 "3",
48 Cycles3,
49 crate::pac::adc::vals::Smp,
50 (
51 ("3", Cycles3, CYCLES3),
52 ("15", Cycles15, CYCLES15),
53 ("28", Cycles28, CYCLES28),
54 ("56", Cycles56, CYCLES56),
55 ("84", Cycles84, CYCLES84),
56 ("112", Cycles112, CYCLES112),
57 ("144", Cycles144, CYCLES144),
58 ("480", Cycles480, CYCLES480)
59 )
60);
61
62#[cfg(adc_v3)]
63impl_sample_time!(
64 "2.5",
65 Cycles2_5,
66 crate::pac::adc::vals::SampleTime,
67 (
68 ("2.5", Cycles2_5, CYCLES2_5),
69 ("6.5", Cycles6_5, CYCLES6_5),
70 ("12.5", Cycles12_5, CYCLES12_5),
71 ("24.5", Cycles24_5, CYCLES24_5),
72 ("47.5", Cycles47_5, CYCLES47_5),
73 ("92.5", Cycles92_5, CYCLES92_5),
74 ("247.5", Cycles247_5, CYCLES247_5),
75 ("640.5", Cycles640_5, CYCLES640_5)
76 )
77);
78
79#[cfg(adc_g0)]
80impl_sample_time!(
81 "1.5",
82 Cycles1_5,
83 crate::pac::adc::vals::SampleTime,
84 (
85 ("1.5", Cycles1_5, CYCLES1_5),
86 ("3.5", Cycles3_5, CYCLES3_5),
87 ("7.5", Cycles7_5, CYCLES7_5),
88 ("12.5", Cycles12_5, CYCLES12_5),
89 ("19.5", Cycles19_5, CYCLES19_5),
90 ("39.5", Cycles39_5, CYCLES39_5),
91 ("79.5", Cycles79_5, CYCLES79_5),
92 ("160.5", Cycles160_5, CYCLES160_5)
93 )
94);
95
96#[cfg(adc_v4)]
97impl_sample_time!(
98 "1.5",
99 Cycles1_5,
100 crate::pac::adc::vals::Smp,
101 (
102 ("1.5", Cycles1_5, CYCLES1_5),
103 ("2.5", Cycles2_5, CYCLES2_5),
104 ("8.5", Cycles8_5, CYCLES8_5),
105 ("16.5", Cycles16_5, CYCLES16_5),
106 ("32.5", Cycles32_5, CYCLES32_5),
107 ("64.5", Cycles64_5, CYCLES64_5),
108 ("387.5", Cycles387_5, CYCLES387_5),
109 ("810.5", Cycles810_5, CYCLES810_5)
110 )
111);
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 53419c7f2..11a51f993 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,10 +1,8 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::into_ref; 1use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
5 3
6use super::InternalChannel; 4use super::InternalChannel;
7use crate::adc::{AdcPin, Instance}; 5use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
8use crate::peripherals::ADC1; 6use crate::peripherals::ADC1;
9use crate::time::Hertz; 7use crate::time::Hertz;
10use crate::Peripheral; 8use crate::Peripheral;
@@ -17,39 +15,6 @@ pub const VREF_CALIB_MV: u32 = 3300;
17/// ADC turn-on time 15/// ADC turn-on time
18pub const ADC_POWERUP_TIME_US: u32 = 3; 16pub const ADC_POWERUP_TIME_US: u32 = 3;
19 17
20pub enum Resolution {
21 TwelveBit,
22 TenBit,
23 EightBit,
24 SixBit,
25}
26
27impl Default for Resolution {
28 fn default() -> Self {
29 Self::TwelveBit
30 }
31}
32
33impl Resolution {
34 fn res(&self) -> crate::pac::adc::vals::Res {
35 match self {
36 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
37 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
38 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
39 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
40 }
41 }
42
43 pub fn to_max_count(&self) -> u32 {
44 match self {
45 Resolution::TwelveBit => (1 << 12) - 1,
46 Resolution::TenBit => (1 << 10) - 1,
47 Resolution::EightBit => (1 << 8) - 1,
48 Resolution::SixBit => (1 << 6) - 1,
49 }
50 }
51}
52
53pub struct VrefInt; 18pub struct VrefInt;
54impl InternalChannel<ADC1> for VrefInt {} 19impl InternalChannel<ADC1> for VrefInt {}
55impl super::sealed::InternalChannel<ADC1> for VrefInt { 20impl super::sealed::InternalChannel<ADC1> for VrefInt {
@@ -94,42 +59,6 @@ impl super::sealed::InternalChannel<ADC1> for Vbat {
94 } 59 }
95} 60}
96 61
97/// ADC sample time
98///
99/// The default setting is 3 ADC clock cycles.
100#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
101pub enum SampleTime {
102 Cycles3 = 0b000,
103 Cycles15 = 0b001,
104 Cycles28 = 0b010,
105 Cycles56 = 0b011,
106 Cycles85 = 0b100,
107 Cycles112 = 0b101,
108 Cycles144 = 0b110,
109 Cycles480 = 0b111,
110}
111
112impl SampleTime {
113 pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::Smp {
114 match self {
115 SampleTime::Cycles3 => crate::pac::adc::vals::Smp::CYCLES3,
116 SampleTime::Cycles15 => crate::pac::adc::vals::Smp::CYCLES15,
117 SampleTime::Cycles28 => crate::pac::adc::vals::Smp::CYCLES28,
118 SampleTime::Cycles56 => crate::pac::adc::vals::Smp::CYCLES56,
119 SampleTime::Cycles85 => crate::pac::adc::vals::Smp::CYCLES84,
120 SampleTime::Cycles112 => crate::pac::adc::vals::Smp::CYCLES112,
121 SampleTime::Cycles144 => crate::pac::adc::vals::Smp::CYCLES144,
122 SampleTime::Cycles480 => crate::pac::adc::vals::Smp::CYCLES480,
123 }
124 }
125}
126
127impl Default for SampleTime {
128 fn default() -> Self {
129 Self::Cycles3
130 }
131}
132
133enum Prescaler { 62enum Prescaler {
134 Div2, 63 Div2,
135 Div4, 64 Div4,
@@ -161,18 +90,12 @@ impl Prescaler {
161 } 90 }
162} 91}
163 92
164pub struct Adc<'d, T: Instance> {
165 sample_time: SampleTime,
166 resolution: Resolution,
167 phantom: PhantomData<&'d mut T>,
168}
169
170impl<'d, T> Adc<'d, T> 93impl<'d, T> Adc<'d, T>
171where 94where
172 T: Instance, 95 T: Instance,
173{ 96{
174 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 97 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
175 into_ref!(_peri); 98 into_ref!(adc);
176 T::enable(); 99 T::enable();
177 T::reset(); 100 T::reset();
178 101
@@ -188,9 +111,8 @@ where
188 delay.delay_us(ADC_POWERUP_TIME_US); 111 delay.delay_us(ADC_POWERUP_TIME_US);
189 112
190 Self { 113 Self {
114 adc,
191 sample_time: Default::default(), 115 sample_time: Default::default(),
192 resolution: Resolution::default(),
193 phantom: PhantomData,
194 } 116 }
195 } 117 }
196 118
@@ -199,7 +121,9 @@ where
199 } 121 }
200 122
201 pub fn set_resolution(&mut self, resolution: Resolution) { 123 pub fn set_resolution(&mut self, resolution: Resolution) {
202 self.resolution = resolution; 124 unsafe {
125 T::regs().cr1().modify(|reg| reg.set_res(resolution.into()));
126 }
203 } 127 }
204 128
205 /// Enables internal voltage reference and returns [VrefInt], which can be used in 129 /// Enables internal voltage reference and returns [VrefInt], which can be used in
@@ -283,7 +207,6 @@ where
283 207
284 unsafe fn read_channel(&mut self, channel: u8) -> u16 { 208 unsafe fn read_channel(&mut self, channel: u8) -> u16 {
285 // Configure ADC 209 // Configure ADC
286 T::regs().cr1().modify(|reg| reg.set_res(self.resolution.res()));
287 210
288 // Select channel 211 // Select channel
289 T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); 212 T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
@@ -297,14 +220,11 @@ where
297 } 220 }
298 221
299 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 222 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
223 let sample_time = sample_time.into();
300 if ch <= 9 { 224 if ch <= 9 {
301 T::regs() 225 T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time));
302 .smpr2()
303 .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
304 } else { 226 } else {
305 T::regs() 227 T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
306 .smpr1()
307 .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
308 } 228 }
309 } 229 }
310} 230}
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 816feeac7..8f81cb7a3 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,9 +1,7 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::into_ref; 1use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
5 3
6use crate::adc::{AdcPin, Instance}; 4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
7use crate::Peripheral; 5use crate::Peripheral;
8 6
9/// Default VREF voltage used for sample conversion to millivolts. 7/// Default VREF voltage used for sample conversion to millivolts.
@@ -24,39 +22,6 @@ fn enable() {
24 }); 22 });
25} 23}
26 24
27pub enum Resolution {
28 TwelveBit,
29 TenBit,
30 EightBit,
31 SixBit,
32}
33
34impl Default for Resolution {
35 fn default() -> Self {
36 Self::TwelveBit
37 }
38}
39
40impl Resolution {
41 fn res(&self) -> crate::pac::adc::vals::Res {
42 match self {
43 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
44 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
45 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
46 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
47 }
48 }
49
50 pub fn to_max_count(&self) -> u32 {
51 match self {
52 Resolution::TwelveBit => (1 << 12) - 1,
53 Resolution::TenBit => (1 << 10) - 1,
54 Resolution::EightBit => (1 << 8) - 1,
55 Resolution::SixBit => (1 << 6) - 1,
56 }
57 }
58}
59
60pub struct VrefInt; 25pub struct VrefInt;
61impl<T: Instance> AdcPin<T> for VrefInt {} 26impl<T: Instance> AdcPin<T> for VrefInt {}
62impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { 27impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
@@ -93,125 +58,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
93 } 58 }
94} 59}
95 60
96#[cfg(not(adc_g0))]
97mod sample_time {
98 /// ADC sample time
99 ///
100 /// The default setting is 2.5 ADC clock cycles.
101 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
102 pub enum SampleTime {
103 /// 2.5 ADC clock cycles
104 Cycles2_5 = 0b000,
105
106 /// 6.5 ADC clock cycles
107 Cycles6_5 = 0b001,
108
109 /// 12.5 ADC clock cycles
110 Cycles12_5 = 0b010,
111
112 /// 24.5 ADC clock cycles
113 Cycles24_5 = 0b011,
114
115 /// 47.5 ADC clock cycles
116 Cycles47_5 = 0b100,
117
118 /// 92.5 ADC clock cycles
119 Cycles92_5 = 0b101,
120
121 /// 247.5 ADC clock cycles
122 Cycles247_5 = 0b110,
123
124 /// 640.5 ADC clock cycles
125 Cycles640_5 = 0b111,
126 }
127
128 impl SampleTime {
129 pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
130 match self {
131 SampleTime::Cycles2_5 => crate::pac::adc::vals::SampleTime::CYCLES2_5,
132 SampleTime::Cycles6_5 => crate::pac::adc::vals::SampleTime::CYCLES6_5,
133 SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5,
134 SampleTime::Cycles24_5 => crate::pac::adc::vals::SampleTime::CYCLES24_5,
135 SampleTime::Cycles47_5 => crate::pac::adc::vals::SampleTime::CYCLES47_5,
136 SampleTime::Cycles92_5 => crate::pac::adc::vals::SampleTime::CYCLES92_5,
137 SampleTime::Cycles247_5 => crate::pac::adc::vals::SampleTime::CYCLES247_5,
138 SampleTime::Cycles640_5 => crate::pac::adc::vals::SampleTime::CYCLES640_5,
139 }
140 }
141 }
142
143 impl Default for SampleTime {
144 fn default() -> Self {
145 Self::Cycles2_5
146 }
147 }
148}
149
150#[cfg(adc_g0)]
151mod sample_time {
152 /// ADC sample time
153 ///
154 /// The default setting is 1.5 ADC clock cycles.
155 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
156 pub enum SampleTime {
157 /// 1.5 ADC clock cycles
158 Cycles1_5 = 0b000,
159
160 /// 3.5 ADC clock cycles
161 Cycles3_5 = 0b001,
162
163 /// 7.5 ADC clock cycles
164 Cycles7_5 = 0b010,
165
166 /// 12.5 ADC clock cycles
167 Cycles12_5 = 0b011,
168
169 /// 19.5 ADC clock cycles
170 Cycles19_5 = 0b100,
171
172 /// 39.5 ADC clock cycles
173 Cycles39_5 = 0b101,
174
175 /// 79.5 ADC clock cycles
176 Cycles79_5 = 0b110,
177
178 /// 160.5 ADC clock cycles
179 Cycles160_5 = 0b111,
180 }
181
182 impl SampleTime {
183 pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime {
184 match self {
185 SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5,
186 SampleTime::Cycles3_5 => crate::pac::adc::vals::SampleTime::CYCLES3_5,
187 SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5,
188 SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5,
189 SampleTime::Cycles19_5 => crate::pac::adc::vals::SampleTime::CYCLES19_5,
190 SampleTime::Cycles39_5 => crate::pac::adc::vals::SampleTime::CYCLES39_5,
191 SampleTime::Cycles79_5 => crate::pac::adc::vals::SampleTime::CYCLES79_5,
192 SampleTime::Cycles160_5 => crate::pac::adc::vals::SampleTime::CYCLES160_5,
193 }
194 }
195 }
196
197 impl Default for SampleTime {
198 fn default() -> Self {
199 Self::Cycles1_5
200 }
201 }
202}
203
204pub use sample_time::SampleTime;
205
206pub struct Adc<'d, T: Instance> {
207 sample_time: SampleTime,
208 resolution: Resolution,
209 phantom: PhantomData<&'d mut T>,
210}
211
212impl<'d, T: Instance> Adc<'d, T> { 61impl<'d, T: Instance> Adc<'d, T> {
213 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 62 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
214 into_ref!(_peri); 63 into_ref!(adc);
215 enable(); 64 enable();
216 unsafe { 65 unsafe {
217 T::regs().cr().modify(|reg| { 66 T::regs().cr().modify(|reg| {
@@ -241,9 +90,8 @@ impl<'d, T: Instance> Adc<'d, T> {
241 delay.delay_us(1); 90 delay.delay_us(1);
242 91
243 Self { 92 Self {
93 adc,
244 sample_time: Default::default(), 94 sample_time: Default::default(),
245 resolution: Resolution::default(),
246 phantom: PhantomData,
247 } 95 }
248 } 96 }
249 97
@@ -288,7 +136,12 @@ impl<'d, T: Instance> Adc<'d, T> {
288 } 136 }
289 137
290 pub fn set_resolution(&mut self, resolution: Resolution) { 138 pub fn set_resolution(&mut self, resolution: Resolution) {
291 self.resolution = resolution; 139 unsafe {
140 #[cfg(not(stm32g0))]
141 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
142 #[cfg(stm32g0)]
143 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
144 }
292 } 145 }
293 146
294 /* 147 /*
@@ -340,12 +193,6 @@ impl<'d, T: Instance> Adc<'d, T> {
340 // spin 193 // spin
341 } 194 }
342 195
343 // Configure ADC
344 #[cfg(not(stm32g0))]
345 T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res()));
346 #[cfg(stm32g0)]
347 T::regs().cfgr1().modify(|reg| reg.set_res(self.resolution.res()));
348
349 // Configure channel 196 // Configure channel
350 Self::set_channel_sample_time(pin.channel(), self.sample_time); 197 Self::set_channel_sample_time(pin.channel(), self.sample_time);
351 198
@@ -374,19 +221,16 @@ impl<'d, T: Instance> Adc<'d, T> {
374 221
375 #[cfg(stm32g0)] 222 #[cfg(stm32g0)]
376 unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { 223 unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
377 T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.sample_time())); 224 T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into()));
378 } 225 }
379 226
380 #[cfg(not(stm32g0))] 227 #[cfg(not(stm32g0))]
381 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 228 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
229 let sample_time = sample_time.into();
382 if ch <= 9 { 230 if ch <= 9 {
383 T::regs() 231 T::regs().smpr1().modify(|reg| reg.set_smp(ch as _, sample_time));
384 .smpr1()
385 .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
386 } else { 232 } else {
387 T::regs() 233 T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
388 .smpr2()
389 .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
390 } 234 }
391 } 235 }
392} 236}
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 2b8f10533..f5aa0e63d 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -1,11 +1,9 @@
1use core::marker::PhantomData;
2
3use atomic_polyfill::{AtomicU8, Ordering}; 1use atomic_polyfill::{AtomicU8, Ordering};
4use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
5use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; 3use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
6use pac::adccommon::vals::Presc; 4use pac::adccommon::vals::Presc;
7 5
8use super::{AdcPin, Instance, InternalChannel}; 6use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
9use crate::time::Hertz; 7use crate::time::Hertz;
10use crate::{pac, Peripheral}; 8use crate::{pac, Peripheral};
11 9
@@ -14,42 +12,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
14/// VREF voltage used for factory calibration of VREFINTCAL register. 12/// VREF voltage used for factory calibration of VREFINTCAL register.
15pub const VREF_CALIB_MV: u32 = 3300; 13pub const VREF_CALIB_MV: u32 = 3300;
16 14
17pub enum Resolution {
18 SixteenBit,
19 FourteenBit,
20 TwelveBit,
21 TenBit,
22 EightBit,
23}
24
25impl Default for Resolution {
26 fn default() -> Self {
27 Self::SixteenBit
28 }
29}
30
31impl Resolution {
32 fn res(&self) -> pac::adc::vals::Res {
33 match self {
34 Resolution::SixteenBit => pac::adc::vals::Res::SIXTEENBIT,
35 Resolution::FourteenBit => pac::adc::vals::Res::FOURTEENBITV,
36 Resolution::TwelveBit => pac::adc::vals::Res::TWELVEBITV,
37 Resolution::TenBit => pac::adc::vals::Res::TENBIT,
38 Resolution::EightBit => pac::adc::vals::Res::EIGHTBIT,
39 }
40 }
41
42 pub fn to_max_count(&self) -> u32 {
43 match self {
44 Resolution::SixteenBit => (1 << 16) - 1,
45 Resolution::FourteenBit => (1 << 14) - 1,
46 Resolution::TwelveBit => (1 << 12) - 1,
47 Resolution::TenBit => (1 << 10) - 1,
48 Resolution::EightBit => (1 << 8) - 1,
49 }
50 }
51}
52
53// 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 15// 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
54pub struct VrefInt; 16pub struct VrefInt;
55impl<T: Instance> InternalChannel<T> for VrefInt {} 17impl<T: Instance> InternalChannel<T> for VrefInt {}
@@ -193,57 +155,6 @@ foreach_peripheral!(
193 }; 155 };
194); 156);
195 157
196/// ADC sample time
197///
198/// The default setting is 2.5 ADC clock cycles.
199#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
200pub enum SampleTime {
201 /// 1.5 ADC clock cycles
202 Cycles1_5,
203
204 /// 2.5 ADC clock cycles
205 Cycles2_5,
206
207 /// 8.5 ADC clock cycles
208 Cycles8_5,
209
210 /// 16.5 ADC clock cycles
211 Cycles16_5,
212
213 /// 32.5 ADC clock cycles
214 Cycles32_5,
215
216 /// 64.5 ADC clock cycles
217 Cycles64_5,
218
219 /// 387.5 ADC clock cycles
220 Cycles387_5,
221
222 /// 810.5 ADC clock cycles
223 Cycles810_5,
224}
225
226impl SampleTime {
227 pub(crate) fn sample_time(&self) -> pac::adc::vals::Smp {
228 match self {
229 SampleTime::Cycles1_5 => pac::adc::vals::Smp::CYCLES1_5,
230 SampleTime::Cycles2_5 => pac::adc::vals::Smp::CYCLES2_5,
231 SampleTime::Cycles8_5 => pac::adc::vals::Smp::CYCLES8_5,
232 SampleTime::Cycles16_5 => pac::adc::vals::Smp::CYCLES16_5,
233 SampleTime::Cycles32_5 => pac::adc::vals::Smp::CYCLES32_5,
234 SampleTime::Cycles64_5 => pac::adc::vals::Smp::CYCLES64_5,
235 SampleTime::Cycles387_5 => pac::adc::vals::Smp::CYCLES387_5,
236 SampleTime::Cycles810_5 => pac::adc::vals::Smp::CYCLES810_5,
237 }
238 }
239}
240
241impl Default for SampleTime {
242 fn default() -> Self {
243 Self::Cycles1_5
244 }
245}
246
247// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 158// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
248// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. 159// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
249#[allow(unused)] 160#[allow(unused)]
@@ -312,15 +223,9 @@ impl Prescaler {
312 } 223 }
313} 224}
314 225
315pub struct Adc<'d, T: Instance> { 226impl<'d, T: Instance> Adc<'d, T> {
316 sample_time: SampleTime, 227 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
317 resolution: Resolution, 228 embassy_hal_common::into_ref!(adc);
318 phantom: PhantomData<&'d mut T>,
319}
320
321impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
322 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
323 embassy_hal_common::into_ref!(_peri);
324 T::enable(); 229 T::enable();
325 T::reset(); 230 T::reset();
326 231
@@ -350,9 +255,8 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
350 } 255 }
351 256
352 let mut s = Self { 257 let mut s = Self {
258 adc,
353 sample_time: Default::default(), 259 sample_time: Default::default(),
354 resolution: Resolution::default(),
355 phantom: PhantomData,
356 }; 260 };
357 s.power_up(delay); 261 s.power_up(delay);
358 s.configure_differential_inputs(); 262 s.configure_differential_inputs();
@@ -454,7 +358,9 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
454 } 358 }
455 359
456 pub fn set_resolution(&mut self, resolution: Resolution) { 360 pub fn set_resolution(&mut self, resolution: Resolution) {
457 self.resolution = resolution; 361 unsafe {
362 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
363 }
458 } 364 }
459 365
460 /// Perform a single conversion. 366 /// Perform a single conversion.
@@ -495,9 +401,6 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
495 } 401 }
496 402
497 unsafe fn read_channel(&mut self, channel: u8) -> u16 { 403 unsafe fn read_channel(&mut self, channel: u8) -> u16 {
498 // Configure ADC
499 T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res()));
500
501 // Configure channel 404 // Configure channel
502 Self::set_channel_sample_time(channel, self.sample_time); 405 Self::set_channel_sample_time(channel, self.sample_time);
503 406
@@ -514,14 +417,11 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
514 } 417 }
515 418
516 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 419 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
420 let sample_time = sample_time.into();
517 if ch <= 9 { 421 if ch <= 9 {
518 T::regs() 422 T::regs().smpr(0).modify(|reg| reg.set_smp(ch as _, sample_time));
519 .smpr(0)
520 .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time()));
521 } else { 423 } else {
522 T::regs() 424 T::regs().smpr(1).modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
523 .smpr(1)
524 .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time()));
525 } 425 }
526 } 426 }
527} 427}