aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/adc/c0.rs32
-rw-r--r--embassy-stm32/src/adc/f1.rs24
-rw-r--r--embassy-stm32/src/adc/f3.rs26
-rw-r--r--embassy-stm32/src/adc/g4.rs85
-rw-r--r--embassy-stm32/src/adc/mod.rs41
-rw-r--r--embassy-stm32/src/adc/v1.rs40
-rw-r--r--embassy-stm32/src/adc/v2.rs47
-rw-r--r--embassy-stm32/src/adc/v3.rs101
-rw-r--r--embassy-stm32/src/adc/v4.rs61
9 files changed, 195 insertions, 262 deletions
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index 70302ef96..1869993a5 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -19,33 +19,17 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(25);
19 19
20const TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US: u32 = 20; 20const TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US: u32 = 20;
21 21
22const TEMP_CHANNEL: u8 = 9;
23const VREF_CHANNEL: u8 = 10;
24
25const NUM_HW_CHANNELS: u8 = 22; 22const NUM_HW_CHANNELS: u8 = 22;
26const CHSELR_SQ_SIZE: usize = 8; 23const CHSELR_SQ_SIZE: usize = 8;
27const CHSELR_SQ_MAX_CHANNEL: u8 = 14; 24const CHSELR_SQ_MAX_CHANNEL: u8 = 14;
28const CHSELR_SQ_SEQUENCE_END_MARKER: u8 = 0b1111; 25const CHSELR_SQ_SEQUENCE_END_MARKER: u8 = 0b1111;
29 26
30// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, 27impl<T: Instance> super::VrefConverter for T {
31// this currently cannot be modeled with stm32-data, 28 const CHANNEL: u8 = 10;
32// so these are available from the software on all ADCs.
33/// Internal voltage reference channel.
34pub struct VrefInt;
35impl<T: Instance> AdcChannel<T> for VrefInt {}
36impl<T: Instance> SealedAdcChannel<T> for VrefInt {
37 fn channel(&self) -> u8 {
38 VREF_CHANNEL
39 }
40} 29}
41 30
42/// Internal temperature channel. 31impl<T: Instance> super::TemperatureConverter for T {
43pub struct Temperature; 32 const CHANNEL: u8 = 9;
44impl<T: Instance> AdcChannel<T> for Temperature {}
45impl<T: Instance> SealedAdcChannel<T> for Temperature {
46 fn channel(&self) -> u8 {
47 TEMP_CHANNEL
48 }
49} 33}
50 34
51#[derive(Copy, Clone, Debug)] 35#[derive(Copy, Clone, Debug)]
@@ -232,22 +216,22 @@ impl<'d, T: Instance> Adc<'d, T> {
232 } 216 }
233 217
234 /// Enable reading the voltage reference internal channel. 218 /// Enable reading the voltage reference internal channel.
235 pub fn enable_vrefint(&self) -> VrefInt { 219 pub fn enable_vrefint(&self) -> super::VrefInt {
236 T::common_regs().ccr().modify(|reg| { 220 T::common_regs().ccr().modify(|reg| {
237 reg.set_vrefen(true); 221 reg.set_vrefen(true);
238 }); 222 });
239 223
240 VrefInt {} 224 super::VrefInt {}
241 } 225 }
242 226
243 /// Enable reading the temperature internal channel. 227 /// Enable reading the temperature internal channel.
244 pub fn enable_temperature(&self) -> Temperature { 228 pub fn enable_temperature(&self) -> super::Temperature {
245 debug!("Ensure that sample time is set to more than temperature sensor T_start from the datasheet!"); 229 debug!("Ensure that sample time is set to more than temperature sensor T_start from the datasheet!");
246 T::common_regs().ccr().modify(|reg| { 230 T::common_regs().ccr().modify(|reg| {
247 reg.set_tsen(true); 231 reg.set_tsen(true);
248 }); 232 });
249 233
250 Temperature {} 234 super::Temperature {}
251 } 235 }
252 236
253 /// Set the ADC sample time. 237 /// Set the ADC sample time.
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 32e330d76..835cc8c63 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -28,20 +28,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
28 } 28 }
29} 29}
30 30
31pub struct Vref; 31impl<T: Instance> super::VrefConverter for T {
32impl<T: Instance> AdcChannel<T> for Vref {} 32 const CHANNEL: u8 = 17;
33impl<T: Instance> super::SealedAdcChannel<T> for Vref {
34 fn channel(&self) -> u8 {
35 17
36 }
37} 33}
38 34
39pub struct Temperature; 35impl<T: Instance> super::TemperatureConverter for T {
40impl<T: Instance> AdcChannel<T> for Temperature {} 36 const CHANNEL: u8 = 16;
41impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
42 fn channel(&self) -> u8 {
43 16
44 }
45} 37}
46 38
47impl<'d, T: Instance> Adc<'d, T> { 39impl<'d, T: Instance> Adc<'d, T> {
@@ -91,18 +83,18 @@ impl<'d, T: Instance> Adc<'d, T> {
91 } 83 }
92 } 84 }
93 85
94 pub fn enable_vref(&self) -> Vref { 86 pub fn enable_vref(&self) -> super::VrefInt {
95 T::regs().cr2().modify(|reg| { 87 T::regs().cr2().modify(|reg| {
96 reg.set_tsvrefe(true); 88 reg.set_tsvrefe(true);
97 }); 89 });
98 Vref {} 90 super::VrefInt {}
99 } 91 }
100 92
101 pub fn enable_temperature(&self) -> Temperature { 93 pub fn enable_temperature(&self) -> super::Temperature {
102 T::regs().cr2().modify(|reg| { 94 T::regs().cr2().modify(|reg| {
103 reg.set_tsvrefe(true); 95 reg.set_tsvrefe(true);
104 }); 96 });
105 Temperature {} 97 super::Temperature {}
106 } 98 }
107 99
108 /// Perform a single conversion. 100 /// Perform a single conversion.
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index cf31aa81b..da185e875 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -29,27 +29,19 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
29 } 29 }
30} 30}
31 31
32pub struct Vref; 32impl<T: Instance> super::VrefConverter for T {
33impl<T: Instance> AdcChannel<T> for Vref {} 33 const CHANNEL: u8 = 18;
34impl<T: Instance> super::SealedAdcChannel<T> for Vref {
35 fn channel(&self) -> u8 {
36 18
37 }
38} 34}
39 35
40impl Vref { 36impl super::VrefInt {
41 /// The value that vref would be if vdda was at 3300mv 37 /// The value that vref would be if vdda was at 3300mv
42 pub fn value(&self) -> u16 { 38 pub fn value(&self) -> u16 {
43 crate::pac::VREFINTCAL.data().read() 39 crate::pac::VREFINTCAL.data().read()
44 } 40 }
45} 41}
46 42
47pub struct Temperature; 43impl<T: Instance> super::TemperatureConverter for T {
48impl<T: Instance> AdcChannel<T> for Temperature {} 44 const CHANNEL: u8 = 16;
49impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
50 fn channel(&self) -> u8 {
51 16
52 }
53} 45}
54 46
55impl<'d, T: Instance> Adc<'d, T> { 47impl<'d, T: Instance> Adc<'d, T> {
@@ -109,16 +101,16 @@ impl<'d, T: Instance> Adc<'d, T> {
109 } 101 }
110 } 102 }
111 103
112 pub fn enable_vref(&self) -> Vref { 104 pub fn enable_vref(&self) -> super::VrefInt {
113 T::common_regs().ccr().modify(|w| w.set_vrefen(true)); 105 T::common_regs().ccr().modify(|w| w.set_vrefen(true));
114 106
115 Vref {} 107 super::VrefInt {}
116 } 108 }
117 109
118 pub fn enable_temperature(&self) -> Temperature { 110 pub fn enable_temperature(&self) -> super::Temperature {
119 T::common_regs().ccr().modify(|w| w.set_tsen(true)); 111 T::common_regs().ccr().modify(|w| w.set_tsen(true));
120 112
121 Temperature {} 113 super::Temperature {}
122 } 114 }
123 115
124 /// Perform a single conversion. 116 /// Perform a single conversion.
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 5066aeec0..2138a82b4 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -35,34 +35,6 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60);
35#[cfg(stm32h7)] 35#[cfg(stm32h7)]
36const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); 36const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
37 37
38// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
39/// Internal voltage reference channel.
40pub struct VrefInt;
41impl<T: Instance + VrefChannel> AdcChannel<T> for VrefInt {}
42impl<T: Instance + VrefChannel> super::SealedAdcChannel<T> for VrefInt {
43 fn channel(&self) -> u8 {
44 T::CHANNEL
45 }
46}
47
48/// Internal temperature channel.
49pub struct Temperature;
50impl<T: Instance + TemperatureChannel> AdcChannel<T> for Temperature {}
51impl<T: Instance + TemperatureChannel> super::SealedAdcChannel<T> for Temperature {
52 fn channel(&self) -> u8 {
53 T::CHANNEL
54 }
55}
56
57/// Internal battery voltage channel.
58pub struct Vbat;
59impl<T: Instance + VBatChannel> AdcChannel<T> for Vbat {}
60impl<T: Instance + VBatChannel> super::SealedAdcChannel<T> for Vbat {
61 fn channel(&self) -> u8 {
62 T::CHANNEL
63 }
64}
65
66// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 38// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
67// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. 39// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
68#[allow(unused)] 40#[allow(unused)]
@@ -250,39 +222,39 @@ impl<'d, T: Instance> Adc<'d, T> {
250 } 222 }
251 223
252 /// Enable reading the voltage reference internal channel. 224 /// Enable reading the voltage reference internal channel.
253 pub fn enable_vrefint(&self) -> VrefInt 225 pub fn enable_vrefint(&self) -> super::VrefInt
254 where 226 where
255 T: VrefChannel, 227 T: super::VrefConverter,
256 { 228 {
257 T::common_regs().ccr().modify(|reg| { 229 T::common_regs().ccr().modify(|reg| {
258 reg.set_vrefen(true); 230 reg.set_vrefen(true);
259 }); 231 });
260 232
261 VrefInt {} 233 super::VrefInt {}
262 } 234 }
263 235
264 /// Enable reading the temperature internal channel. 236 /// Enable reading the temperature internal channel.
265 pub fn enable_temperature(&self) -> Temperature 237 pub fn enable_temperature(&self) -> super::Temperature
266 where 238 where
267 T: TemperatureChannel, 239 T: super::TemperatureConverter,
268 { 240 {
269 T::common_regs().ccr().modify(|reg| { 241 T::common_regs().ccr().modify(|reg| {
270 reg.set_vsenseen(true); 242 reg.set_vsenseen(true);
271 }); 243 });
272 244
273 Temperature {} 245 super::Temperature {}
274 } 246 }
275 247
276 /// Enable reading the vbat internal channel. 248 /// Enable reading the vbat internal channel.
277 pub fn enable_vbat(&self) -> Vbat 249 pub fn enable_vbat(&self) -> super::Vbat
278 where 250 where
279 T: VBatChannel, 251 T: super::VBatConverter,
280 { 252 {
281 T::common_regs().ccr().modify(|reg| { 253 T::common_regs().ccr().modify(|reg| {
282 reg.set_vbaten(true); 254 reg.set_vbaten(true);
283 }); 255 });
284 256
285 Vbat {} 257 super::Vbat {}
286 } 258 }
287 259
288 /// Enable differential channel. 260 /// Enable differential channel.
@@ -850,62 +822,49 @@ impl<T: Instance, const N: usize> InjectedAdc<T, N> {
850 } 822 }
851} 823}
852 824
853/// Implemented for ADCs that have a Temperature channel
854pub trait TemperatureChannel {
855 const CHANNEL: u8;
856}
857/// Implemented for ADCs that have a Vref channel
858pub trait VrefChannel {
859 const CHANNEL: u8;
860}
861/// Implemented for ADCs that have a VBat channel
862pub trait VBatChannel {
863 const CHANNEL: u8;
864}
865
866#[cfg(stm32g4)] 825#[cfg(stm32g4)]
867mod g4 { 826mod g4 {
868 pub use super::*; 827 use crate::adc::{TemperatureConverter, VBatConverter, VrefConverter};
869 828
870 impl TemperatureChannel for crate::peripherals::ADC1 { 829 impl TemperatureConverter for crate::peripherals::ADC1 {
871 const CHANNEL: u8 = 16; 830 const CHANNEL: u8 = 16;
872 } 831 }
873 832
874 impl VrefChannel for crate::peripherals::ADC1 { 833 impl VrefConverter for crate::peripherals::ADC1 {
875 const CHANNEL: u8 = 18; 834 const CHANNEL: u8 = 18;
876 } 835 }
877 836
878 impl VBatChannel for crate::peripherals::ADC1 { 837 impl VBatConverter for crate::peripherals::ADC1 {
879 const CHANNEL: u8 = 17; 838 const CHANNEL: u8 = 17;
880 } 839 }
881 840
882 #[cfg(peri_adc3_common)] 841 #[cfg(peri_adc3_common)]
883 impl VrefChannel for crate::peripherals::ADC3 { 842 impl VrefConverter for crate::peripherals::ADC3 {
884 const CHANNEL: u8 = 18; 843 const CHANNEL: u8 = 18;
885 } 844 }
886 845
887 #[cfg(peri_adc3_common)] 846 #[cfg(peri_adc3_common)]
888 impl VBatChannel for crate::peripherals::ADC3 { 847 impl VBatConverter for crate::peripherals::ADC3 {
889 const CHANNEL: u8 = 17; 848 const CHANNEL: u8 = 17;
890 } 849 }
891 850
892 #[cfg(not(stm32g4x1))] 851 #[cfg(not(stm32g4x1))]
893 impl VrefChannel for crate::peripherals::ADC4 { 852 impl VrefConverter for crate::peripherals::ADC4 {
894 const CHANNEL: u8 = 18; 853 const CHANNEL: u8 = 18;
895 } 854 }
896 855
897 #[cfg(not(stm32g4x1))] 856 #[cfg(not(stm32g4x1))]
898 impl TemperatureChannel for crate::peripherals::ADC5 { 857 impl TemperatureConverter for crate::peripherals::ADC5 {
899 const CHANNEL: u8 = 4; 858 const CHANNEL: u8 = 4;
900 } 859 }
901 860
902 #[cfg(not(stm32g4x1))] 861 #[cfg(not(stm32g4x1))]
903 impl VrefChannel for crate::peripherals::ADC5 { 862 impl VrefConverter for crate::peripherals::ADC5 {
904 const CHANNEL: u8 = 18; 863 const CHANNEL: u8 = 18;
905 } 864 }
906 865
907 #[cfg(not(stm32g4x1))] 866 #[cfg(not(stm32g4x1))]
908 impl VBatChannel for crate::peripherals::ADC5 { 867 impl VBatConverter for crate::peripherals::ADC5 {
909 const CHANNEL: u8 = 17; 868 const CHANNEL: u8 = 17;
910 } 869 }
911} 870}
@@ -913,13 +872,13 @@ mod g4 {
913// TODO this should look at each ADC individually and impl the correct channels 872// TODO this should look at each ADC individually and impl the correct channels
914#[cfg(stm32h7)] 873#[cfg(stm32h7)]
915mod h7 { 874mod h7 {
916 impl<T: Instance> TemperatureChannel for T { 875 impl<T: Instance> TemperatureConverter for T {
917 const CHANNEL: u8 = 18; 876 const CHANNEL: u8 = 18;
918 } 877 }
919 impl<T: Instance> VrefChannel for T { 878 impl<T: Instance> VrefConverter for T {
920 const CHANNEL: u8 = 19; 879 const CHANNEL: u8 = 19;
921 } 880 }
922 impl<T: Instance> VBatChannel for T { 881 impl<T: Instance> VBatConverter for T {
923 // TODO this should be 14 for H7a/b/35 882 // TODO this should be 14 for H7a/b/35
924 const CHANNEL: u8 = 17; 883 const CHANNEL: u8 = 17;
925 } 884 }
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index a6b796fb9..a5ca6277f 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -100,6 +100,47 @@ pub(crate) fn blocking_delay_us(us: u32) {
100 } 100 }
101} 101}
102 102
103/// Implemented for ADCs that have a Temperature channel
104pub trait TemperatureConverter {
105 const CHANNEL: u8;
106}
107/// Implemented for ADCs that have a Vref channel
108pub trait VrefConverter {
109 const CHANNEL: u8;
110}
111/// Implemented for ADCs that have a VBat channel
112pub trait VBatConverter {
113 const CHANNEL: u8;
114}
115
116// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
117/// Internal voltage reference channel.
118pub struct VrefInt;
119impl<T: Instance + VrefConverter> AdcChannel<T> for VrefInt {}
120impl<T: Instance + VrefConverter> SealedAdcChannel<T> for VrefInt {
121 fn channel(&self) -> u8 {
122 T::CHANNEL
123 }
124}
125
126/// Internal temperature channel.
127pub struct Temperature;
128impl<T: Instance + TemperatureConverter> AdcChannel<T> for Temperature {}
129impl<T: Instance + TemperatureConverter> SealedAdcChannel<T> for Temperature {
130 fn channel(&self) -> u8 {
131 T::CHANNEL
132 }
133}
134
135/// Internal battery voltage channel.
136pub struct Vbat;
137impl<T: Instance + VBatConverter> AdcChannel<T> for Vbat {}
138impl<T: Instance + VBatConverter> SealedAdcChannel<T> for Vbat {
139 fn channel(&self) -> u8 {
140 T::CHANNEL
141 }
142}
143
103/// ADC instance. 144/// ADC instance.
104#[cfg(not(any( 145#[cfg(not(any(
105 adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_g4, adc_f3v1, adc_f3v2, adc_g0, adc_u0, adc_h5, adc_h7rs, 146 adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_g4, adc_f3v1, adc_f3v2, adc_g0, adc_u0, adc_h5, adc_h7rs,
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 3838cc12a..97557ee8a 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -5,10 +5,11 @@ use core::task::Poll;
5#[cfg(adc_l0)] 5#[cfg(adc_l0)]
6use stm32_metapac::adc::vals::Ckmode; 6use stm32_metapac::adc::vals::Ckmode;
7 7
8use super::blocking_delay_us; 8#[cfg(not(adc_l0))]
9use super::Vbat;
10use super::{Temperature, VrefInt, blocking_delay_us};
9use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 11use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
10use crate::interrupt::typelevel::Interrupt; 12use crate::interrupt::typelevel::Interrupt;
11use crate::peripherals::ADC1;
12use crate::{Peri, interrupt, rcc}; 13use crate::{Peri, interrupt, rcc};
13 14
14mod watchdog_v1; 15mod watchdog_v1;
@@ -42,32 +43,23 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
42} 43}
43 44
44#[cfg(not(adc_l0))] 45#[cfg(not(adc_l0))]
45pub struct Vbat; 46impl super::VBatConverter for crate::peripherals::ADC1 {
46 47 const CHANNEL: u8 = 18;
47#[cfg(not(adc_l0))] 48}
48impl AdcChannel<ADC1> for Vbat {}
49 49
50#[cfg(not(adc_l0))] 50#[cfg(not(adc_l0))]
51impl super::SealedAdcChannel<ADC1> for Vbat { 51impl super::VrefConverter for crate::peripherals::ADC1 {
52 fn channel(&self) -> u8 { 52 const CHANNEL: u8 = 17;
53 18
54 }
55} 53}
56 54
57pub struct Vref; 55#[cfg(adc_l0)]
58impl AdcChannel<ADC1> for Vref {} 56impl super::VrefConverter for crate::peripherals::ADC1 {
59impl super::SealedAdcChannel<ADC1> for Vref { 57 const CHANNEL: u8 = 18;
60 fn channel(&self) -> u8 {
61 17
62 }
63} 58}
64 59
65pub struct Temperature; 60#[cfg(not(adc_l0))]
66impl AdcChannel<ADC1> for Temperature {} 61impl super::TemperatureConverter for crate::peripherals::ADC1 {
67impl super::SealedAdcChannel<ADC1> for Temperature { 62 const CHANNEL: u8 = 16;
68 fn channel(&self) -> u8 {
69 if cfg!(adc_l0) { 18 } else { 16 }
70 }
71} 63}
72 64
73impl<'d, T: Instance> Adc<'d, T> { 65impl<'d, T: Instance> Adc<'d, T> {
@@ -127,12 +119,12 @@ impl<'d, T: Instance> Adc<'d, T> {
127 Vbat 119 Vbat
128 } 120 }
129 121
130 pub fn enable_vref(&self) -> Vref { 122 pub fn enable_vref(&self) -> VrefInt {
131 // Table 28. Embedded internal reference voltage 123 // Table 28. Embedded internal reference voltage
132 // tstart = 10μs 124 // tstart = 10μs
133 T::regs().ccr().modify(|reg| reg.set_vrefen(true)); 125 T::regs().ccr().modify(|reg| reg.set_vrefen(true));
134 blocking_delay_us(10); 126 blocking_delay_us(10);
135 Vref 127 VrefInt
136 } 128 }
137 129
138 pub fn enable_temperature(&self) -> Temperature { 130 pub fn enable_temperature(&self) -> Temperature {
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 67721770a..af5d486d9 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,10 +1,9 @@
1use core::mem; 1use core::mem;
2use core::sync::atomic::{Ordering, compiler_fence}; 2use core::sync::atomic::{Ordering, compiler_fence};
3 3
4use super::blocking_delay_us; 4use super::{Temperature, Vbat, VrefInt, blocking_delay_us};
5use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel}; 5use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel};
6use crate::pac::adc::vals; 6use crate::pac::adc::vals;
7use crate::peripherals::ADC1;
8use crate::time::Hertz; 7use crate::time::Hertz;
9use crate::{Peri, rcc}; 8use crate::{Peri, rcc};
10 9
@@ -23,12 +22,22 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
23/// VREF voltage used for factory calibration of VREFINTCAL register. 22/// VREF voltage used for factory calibration of VREFINTCAL register.
24pub const VREF_CALIB_MV: u32 = 3300; 23pub const VREF_CALIB_MV: u32 = 3300;
25 24
26pub struct VrefInt; 25impl super::VrefConverter for crate::peripherals::ADC1 {
27impl AdcChannel<ADC1> for VrefInt {} 26 const CHANNEL: u8 = 17;
28impl super::SealedAdcChannel<ADC1> for VrefInt { 27}
29 fn channel(&self) -> u8 { 28
30 17 29#[cfg(any(stm32f2, stm32f40x, stm32f41x))]
31 } 30impl super::TemperatureConverter for crate::peripherals::ADC1 {
31 const CHANNEL: u8 = 16;
32}
33
34#[cfg(not(any(stm32f2, stm32f40x, stm32f41x)))]
35impl super::TemperatureConverter for crate::peripherals::ADC1 {
36 const CHANNEL: u8 = 18;
37}
38
39impl super::VBatConverter for crate::peripherals::ADC1 {
40 const CHANNEL: u8 = 18;
32} 41}
33 42
34impl VrefInt { 43impl VrefInt {
@@ -38,20 +47,6 @@ impl VrefInt {
38 } 47 }
39} 48}
40 49
41pub struct Temperature;
42impl AdcChannel<ADC1> for Temperature {}
43impl super::SealedAdcChannel<ADC1> for Temperature {
44 fn channel(&self) -> u8 {
45 cfg_if::cfg_if! {
46 if #[cfg(any(stm32f2, stm32f40x, stm32f41x))] {
47 16
48 } else {
49 18
50 }
51 }
52 }
53}
54
55impl Temperature { 50impl Temperature {
56 /// Time needed for temperature sensor readings to stabilize 51 /// Time needed for temperature sensor readings to stabilize
57 pub fn start_time_us() -> u32 { 52 pub fn start_time_us() -> u32 {
@@ -59,14 +54,6 @@ impl Temperature {
59 } 54 }
60} 55}
61 56
62pub struct Vbat;
63impl AdcChannel<ADC1> for Vbat {}
64impl super::SealedAdcChannel<ADC1> for Vbat {
65 fn channel(&self) -> u8 {
66 18
67 }
68}
69
70enum Prescaler { 57enum Prescaler {
71 Div2, 58 Div2,
72 Div4, 59 Div4,
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index bbbaf73c8..0822fbb69 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -9,8 +9,11 @@ use pac::adc::vals::{OversamplingRatio, OversamplingShift, Rovsm, Trovs};
9#[cfg(adc_g0)] 9#[cfg(adc_g0)]
10pub use pac::adc::vals::{Ovsr, Ovss, Presc}; 10pub use pac::adc::vals::{Ovsr, Ovss, Presc};
11 11
12#[allow(unused_imports)]
13use super::SealedAdcChannel;
12use super::{ 14use super::{
13 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, 15 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, Temperature, Vbat, VrefInt,
16 blocking_delay_us,
14}; 17};
15 18
16#[cfg(any(adc_v3, adc_g0, adc_u0))] 19#[cfg(any(adc_v3, adc_g0, adc_u0))]
@@ -32,61 +35,55 @@ pub const VREF_CALIB_MV: u32 = 3000;
32// TODO: Use [#![feature(variant_count)]](https://github.com/rust-lang/rust/issues/73662) when stable 35// TODO: Use [#![feature(variant_count)]](https://github.com/rust-lang/rust/issues/73662) when stable
33const SAMPLE_TIMES_CAPACITY: usize = 2; 36const SAMPLE_TIMES_CAPACITY: usize = 2;
34 37
35pub struct VrefInt; 38#[cfg(adc_g0)]
36impl<T: Instance> AdcChannel<T> for VrefInt {} 39impl<T: Instance> super::VrefConverter for T {
37impl<T: Instance> SealedAdcChannel<T> for VrefInt { 40 const CHANNEL: u8 = 13;
38 fn channel(&self) -> u8 { 41}
39 cfg_if! { 42#[cfg(any(adc_h5, adc_h7rs))]
40 if #[cfg(adc_g0)] { 43impl<T: Instance> super::VrefConverter for T {
41 let val = 13; 44 const CHANNEL: u8 = 17;
42 } else if #[cfg(any(adc_h5, adc_h7rs))] { 45}
43 let val = 17; 46#[cfg(adc_u0)]
44 } else if #[cfg(adc_u0)] { 47impl<T: Instance> super::VrefConverter for T {
45 let val = 12; 48 const CHANNEL: u8 = 12;
46 } else { 49}
47 let val = 0; 50#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
48 } 51impl<T: Instance> super::VrefConverter for T {
49 } 52 const CHANNEL: u8 = 0;
50 val
51 }
52} 53}
53 54
54pub struct Temperature; 55#[cfg(adc_g0)]
55impl<T: Instance> AdcChannel<T> for Temperature {} 56impl<T: Instance> super::TemperatureConverter for T {
56impl<T: Instance> SealedAdcChannel<T> for Temperature { 57 const CHANNEL: u8 = 12;
57 fn channel(&self) -> u8 { 58}
58 cfg_if! { 59#[cfg(any(adc_h5, adc_h7rs))]
59 if #[cfg(adc_g0)] { 60impl<T: Instance> super::TemperatureConverter for T {
60 let val = 12; 61 const CHANNEL: u8 = 16;
61 } else if #[cfg(any(adc_h5, adc_h7rs))] { 62}
62 let val = 16; 63#[cfg(adc_u0)]
63 } else if #[cfg(adc_u0)] { 64impl<T: Instance> super::TemperatureConverter for T {
64 let val = 11; 65 const CHANNEL: u8 = 11;
65 } else { 66}
66 let val = 17; 67#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
67 } 68impl<T: Instance> super::TemperatureConverter for T {
68 } 69 const CHANNEL: u8 = 17;
69 val
70 }
71} 70}
72 71
73pub struct Vbat; 72#[cfg(adc_g0)]
74impl<T: Instance> AdcChannel<T> for Vbat {} 73impl<T: Instance> super::VBatConverter for T {
75impl<T: Instance> SealedAdcChannel<T> for Vbat { 74 const CHANNEL: u8 = 14;
76 fn channel(&self) -> u8 { 75}
77 cfg_if! { 76#[cfg(any(adc_h5, adc_h7rs))]
78 if #[cfg(adc_g0)] { 77impl<T: Instance> super::VBatConverter for T {
79 let val = 14; 78 const CHANNEL: u8 = 2;
80 } else if #[cfg(any(adc_h5, adc_h7rs))] { 79}
81 let val = 2; 80#[cfg(adc_u0)]
82 } else if #[cfg(any(adc_h5, adc_h7rs))] { 81impl<T: Instance> super::VBatConverter for T {
83 let val = 13; 82 const CHANNEL: u8 = 13;
84 } else { 83}
85 let val = 18; 84#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))]
86 } 85impl<T: Instance> super::VBatConverter for T {
87 } 86 const CHANNEL: u8 = 18;
88 val
89 }
90} 87}
91 88
92cfg_if! { 89cfg_if! {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index cc3f8b34e..2f7baf3bf 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -5,7 +5,8 @@ use pac::adc::vals::{Adstp, Difsel, Dmngt, Exten, Pcsel};
5use pac::adccommon::vals::Presc; 5use pac::adccommon::vals::Presc;
6 6
7use super::{ 7use super::{
8 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, 8 Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, Temperature, Vbat,
9 VrefInt, blocking_delay_us,
9}; 10};
10use crate::dma::Transfer; 11use crate::dma::Transfer;
11use crate::time::Hertz; 12use crate::time::Hertz;
@@ -25,52 +26,40 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
25const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); 26const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);
26 27
27#[cfg(stm32g4)] 28#[cfg(stm32g4)]
28const VREF_CHANNEL: u8 = 18; 29impl<T: Instance> super::VrefConverter for T {
30 const CHANNEL: u8 = 18;
31}
29#[cfg(stm32g4)] 32#[cfg(stm32g4)]
30const TEMP_CHANNEL: u8 = 16; 33impl<T: Instance> super::TemperatureConverter for T {
34 const CHANNEL: u8 = 16;
35}
31 36
32#[cfg(stm32h7)] 37#[cfg(stm32h7)]
33const VREF_CHANNEL: u8 = 19; 38impl<T: Instance> super::VrefConverter for T {
39 const CHANNEL: u8 = 19;
40}
34#[cfg(stm32h7)] 41#[cfg(stm32h7)]
35const TEMP_CHANNEL: u8 = 18; 42impl<T: Instance> super::TemperatureConverter for T {
43 const CHANNEL: u8 = 18;
44}
36 45
37// TODO this should be 14 for H7a/b/35 46// TODO this should be 14 for H7a/b/35
38#[cfg(not(stm32u5))] 47#[cfg(not(stm32u5))]
39const VBAT_CHANNEL: u8 = 17; 48impl<T: Instance> super::VBatConverter for T {
49 const CHANNEL: u8 = 17;
50}
40 51
41#[cfg(stm32u5)] 52#[cfg(stm32u5)]
42const VREF_CHANNEL: u8 = 0; 53impl<T: Instance> super::VrefConverter for T {
43#[cfg(stm32u5)] 54 const CHANNEL: u8 = 0;
44const TEMP_CHANNEL: u8 = 19;
45#[cfg(stm32u5)]
46const VBAT_CHANNEL: u8 = 18;
47
48// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
49/// Internal voltage reference channel.
50pub struct VrefInt;
51impl<T: Instance> AdcChannel<T> for VrefInt {}
52impl<T: Instance> SealedAdcChannel<T> for VrefInt {
53 fn channel(&self) -> u8 {
54 VREF_CHANNEL
55 }
56} 55}
57 56#[cfg(stm32u5)]
58/// Internal temperature channel. 57impl<T: Instance> super::TemperatureConverter for T {
59pub struct Temperature; 58 const CHANNEL: u8 = 19;
60impl<T: Instance> AdcChannel<T> for Temperature {}
61impl<T: Instance> SealedAdcChannel<T> for Temperature {
62 fn channel(&self) -> u8 {
63 TEMP_CHANNEL
64 }
65} 59}
66 60#[cfg(stm32u5)]
67/// Internal battery voltage channel. 61impl<T: Instance> super::VBatConverter for T {
68pub struct Vbat; 62 const CHANNEL: u8 = 18;
69impl<T: Instance> AdcChannel<T> for Vbat {}
70impl<T: Instance> SealedAdcChannel<T> for Vbat {
71 fn channel(&self) -> u8 {
72 VBAT_CHANNEL
73 }
74} 63}
75 64
76// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 65// NOTE (unused): The prescaler enum closely copies the hardware capabilities,