aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-mspm0/build.rs55
-rw-r--r--embassy-mspm0/src/adc.rs53
-rw-r--r--examples/mspm0g3507/src/bin/adc.rs10
-rw-r--r--examples/mspm0l1306/src/bin/adc.rs10
4 files changed, 56 insertions, 72 deletions
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs
index ad90b5223..4bfeb5626 100644
--- a/embassy-mspm0/build.rs
+++ b/embassy-mspm0/build.rs
@@ -225,52 +225,15 @@ fn generate_adc_constants() -> TokenStream {
225 let vrsel = METADATA.adc_vrsel; 225 let vrsel = METADATA.adc_vrsel;
226 let memctl = METADATA.adc_memctl; 226 let memctl = METADATA.adc_memctl;
227 227
228 if vrsel == 3 { 228 println!("cargo::rustc-check-cfg=cfg(adc_neg_vref)");
229 quote! { 229 match vrsel {
230 pub const ADC_VRSEL: u8 = #vrsel; 230 3 => (),
231 pub const ADC_MEMCTL: u8 = #memctl; 231 5 => println!("cargo:rustc-cfg=adc_neg_vref"),
232 232 _ => panic!("Unsupported ADC VRSEL value: {vrsel}"),
233 #[derive(Clone, Copy, PartialEq, Eq, Debug)] 233 }
234 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 234 quote! {
235 /// Reference voltage (Vref) selection for the ADC channels. 235 pub const ADC_VRSEL: u8 = #vrsel;
236 pub enum Vrsel { 236 pub const ADC_MEMCTL: u8 = #memctl;
237 /// VDDA reference
238 VddaVssa = 0,
239
240 /// External reference from pin
241 ExtrefVrefm = 1,
242
243 /// Internal reference
244 IntrefVssa = 2,
245 }
246 }
247 } else if vrsel == 5 {
248 quote! {
249 pub const ADC_VRSEL: u8 = #vrsel;
250 pub const ADC_MEMCTL: u8 = #memctl;
251
252 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
253 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
254 /// Reference voltage (Vref) selection for the ADC channels.
255 pub enum Vrsel {
256 /// VDDA reference
257 VddaVssa = 0,
258
259 /// External reference from pin
260 ExtrefVrefm = 1,
261
262 /// Internal reference
263 IntrefVssa = 2,
264
265 /// VDDA and VREFM connected to VREF+ and VREF- of ADC
266 VddaVrefm = 3,
267
268 /// INTREF and VREFM connected to VREF+ and VREF- of ADC
269 IntrefVrefm = 4,
270 }
271 }
272 } else {
273 panic!("Unsupported ADC VRSEL value: {vrsel}");
274 } 237 }
275} 238}
276 239
diff --git a/embassy-mspm0/src/adc.rs b/embassy-mspm0/src/adc.rs
index e4ba81139..71569aef0 100644
--- a/embassy-mspm0/src/adc.rs
+++ b/embassy-mspm0/src/adc.rs
@@ -58,10 +58,32 @@ impl Resolution {
58 } 58 }
59} 59}
60 60
61pub use crate::_generated::Vrsel; 61#[derive(Clone, Copy, PartialEq, Eq, Debug)]
62#[cfg_attr(feature = "defmt", derive(defmt::Format))]
63/// Reference voltage (Vref) selection for the ADC channels.
64pub enum Vrsel {
65 /// VDDA reference
66 VddaVssa = 0,
67
68 /// External reference from pin
69 ExtrefVrefm = 1,
70
71 /// Internal reference
72 IntrefVssa = 2,
73
74 /// VDDA and VREFM connected to VREF+ and VREF- of ADC
75 #[cfg(adc_neg_vref)]
76 VddaVrefm = 3,
77
78 /// INTREF and VREFM connected to VREF+ and VREF- of ADC
79 #[cfg(adc_neg_vref)]
80 IntrefVrefm = 4,
81}
62 82
63/// ADC configuration. 83/// ADC configuration.
64pub struct AdcConfig { 84#[derive(Copy, Clone)]
85#[non_exhaustive]
86pub struct Config {
65 /// Resolution of the ADC conversion. The number of bits used to represent an ADC measurement. 87 /// Resolution of the ADC conversion. The number of bits used to represent an ADC measurement.
66 pub resolution: Resolution, 88 pub resolution: Resolution,
67 /// ADC voltage reference selection. 89 /// ADC voltage reference selection.
@@ -73,19 +95,29 @@ pub struct AdcConfig {
73 pub sample_time: u16, 95 pub sample_time: u16,
74} 96}
75 97
98impl Default for Config {
99 fn default() -> Self {
100 Self {
101 resolution: Resolution::BIT12,
102 vr_select: Vrsel::VddaVssa,
103 sample_time: 50,
104 }
105 }
106}
107
76/// ADC (Analog to Digial Converter) Driver. 108/// ADC (Analog to Digial Converter) Driver.
77pub struct Adc<'d, T: Instance, M: Mode> { 109pub struct Adc<'d, T: Instance, M: Mode> {
78 #[allow(unused)] 110 #[allow(unused)]
79 adc: crate::Peri<'d, T>, 111 adc: crate::Peri<'d, T>,
80 info: &'static Info, 112 info: &'static Info,
81 state: &'static State, 113 state: &'static State,
82 config: AdcConfig, 114 config: Config,
83 _phantom: PhantomData<M>, 115 _phantom: PhantomData<M>,
84} 116}
85 117
86impl<'d, T: Instance> Adc<'d, T, Blocking> { 118impl<'d, T: Instance> Adc<'d, T, Blocking> {
87 /// A new blocking ADC driver instance. 119 /// A new blocking ADC driver instance.
88 pub fn new_blocking(peri: Peri<'d, T>, config: AdcConfig) -> Self { 120 pub fn new_blocking(peri: Peri<'d, T>, config: Config) -> Self {
89 let mut this = Self { 121 let mut this = Self {
90 adc: peri, 122 adc: peri,
91 info: T::info(), 123 info: T::info(),
@@ -102,10 +134,8 @@ impl<'d, T: Instance> Adc<'d, T, Async> {
102 /// A new asynchronous ADC driver instance. 134 /// A new asynchronous ADC driver instance.
103 pub fn new_async( 135 pub fn new_async(
104 peri: Peri<'d, T>, 136 peri: Peri<'d, T>,
105 config: AdcConfig, 137 config: Config,
106 _irqs: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> 138 _irqs: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
107 + interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>>
108 + 'd,
109 ) -> Self { 139 ) -> Self {
110 let mut this = Self { 140 let mut this = Self {
111 adc: peri, 141 adc: peri,
@@ -244,6 +274,9 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
244} 274}
245 275
246impl<'d, T: Instance> Adc<'d, T, Async> { 276impl<'d, T: Instance> Adc<'d, T, Async> {
277 /// Maximum length allowed for [`Self::read_sequence`].
278 pub const MAX_SEQUENCE_LEN: usize = ADC_MEMCTL as usize;
279
247 async fn wait_for_conversion(&self) { 280 async fn wait_for_conversion(&self) {
248 let info = self.info; 281 let info = self.info;
249 let state = self.state; 282 let state = self.state;
@@ -337,9 +370,9 @@ impl<'d, T: Instance> Adc<'d, T, Async> {
337 "Sequence length must be equal to readings length" 370 "Sequence length must be equal to readings length"
338 ); 371 );
339 assert!( 372 assert!(
340 sequence.len() <= ADC_MEMCTL as usize, 373 sequence.len() <= Self::MAX_SEQUENCE_LEN,
341 "Asynchronous read sequence cannot be more than {} in length", 374 "Asynchronous read sequence cannot be more than {} in length",
342 ADC_MEMCTL 375 Self::MAX_SEQUENCE_LEN
343 ); 376 );
344 377
345 // CTL0.ENC must be 0 to write the MEMCTL register 378 // CTL0.ENC must be 0 to write the MEMCTL register
diff --git a/examples/mspm0g3507/src/bin/adc.rs b/examples/mspm0g3507/src/bin/adc.rs
index fed8b9dd3..73711c75c 100644
--- a/examples/mspm0g3507/src/bin/adc.rs
+++ b/examples/mspm0g3507/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_mspm0::adc::{self, Adc, AdcChannel, AdcConfig, Resolution, Vrsel}; 6use embassy_mspm0::adc::{self, Adc, AdcChannel, Vrsel};
7use embassy_mspm0::{bind_interrupts, peripherals, Config}; 7use embassy_mspm0::{bind_interrupts, peripherals, Config};
8use embassy_time::Timer; 8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _}; 9use {defmt_rtt as _, panic_halt as _};
@@ -17,14 +17,8 @@ async fn main(_spawner: Spawner) -> ! {
17 info!("Hello world!"); 17 info!("Hello world!");
18 let p = embassy_mspm0::init(Config::default()); 18 let p = embassy_mspm0::init(Config::default());
19 19
20 let adc_config = AdcConfig {
21 resolution: Resolution::BIT12,
22 vr_select: Vrsel::VddaVssa,
23 sample_time: 50,
24 };
25
26 // Configure adc with sequence 0 to 1 20 // Configure adc with sequence 0 to 1
27 let mut adc = Adc::new_async(p.ADC0, adc_config, Irqs); 21 let mut adc = Adc::new_async(p.ADC0, Default::default(), Irqs);
28 let pin1 = p.PA22.degrade_adc(); 22 let pin1 = p.PA22.degrade_adc();
29 let pin2 = p.PB20.degrade_adc(); 23 let pin2 = p.PB20.degrade_adc();
30 let sequence = [(&pin1, Vrsel::VddaVssa), (&pin2, Vrsel::VddaVssa)]; 24 let sequence = [(&pin1, Vrsel::VddaVssa), (&pin2, Vrsel::VddaVssa)];
diff --git a/examples/mspm0l1306/src/bin/adc.rs b/examples/mspm0l1306/src/bin/adc.rs
index 9ede31fed..a0c2c0cff 100644
--- a/examples/mspm0l1306/src/bin/adc.rs
+++ b/examples/mspm0l1306/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_mspm0::adc::{self, Adc, AdcChannel, AdcConfig, Resolution, Vrsel}; 6use embassy_mspm0::adc::{self, Adc, AdcChannel, Vrsel};
7use embassy_mspm0::{bind_interrupts, peripherals, Config}; 7use embassy_mspm0::{bind_interrupts, peripherals, Config};
8use embassy_time::Timer; 8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _}; 9use {defmt_rtt as _, panic_halt as _};
@@ -17,14 +17,8 @@ async fn main(_spawner: Spawner) -> ! {
17 info!("Hello world!"); 17 info!("Hello world!");
18 let p = embassy_mspm0::init(Config::default()); 18 let p = embassy_mspm0::init(Config::default());
19 19
20 let adc_config = AdcConfig {
21 resolution: Resolution::BIT12,
22 vr_select: Vrsel::VddaVssa,
23 sample_time: 50,
24 };
25
26 // Configure adc with sequence 0 to 1 20 // Configure adc with sequence 0 to 1
27 let mut adc = Adc::new_async(p.ADC0, adc_config, Irqs); 21 let mut adc = Adc::new_async(p.ADC0, Default::default(), Irqs);
28 let pin1 = p.PA22.degrade_adc(); 22 let pin1 = p.PA22.degrade_adc();
29 let pin2 = p.PA20.degrade_adc(); 23 let pin2 = p.PA20.degrade_adc();
30 let sequence = [(&pin1, Vrsel::VddaVssa), (&pin2, Vrsel::VddaVssa)]; 24 let sequence = [(&pin1, Vrsel::VddaVssa), (&pin2, Vrsel::VddaVssa)];