aboutsummaryrefslogtreecommitdiff
path: root/embassy-mspm0
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mspm0')
-rw-r--r--embassy-mspm0/build.rs55
-rw-r--r--embassy-mspm0/src/adc.rs53
2 files changed, 52 insertions, 56 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