diff options
| -rw-r--r-- | embassy-mspm0/build.rs | 55 | ||||
| -rw-r--r-- | embassy-mspm0/src/adc.rs | 53 | ||||
| -rw-r--r-- | examples/mspm0g3507/src/bin/adc.rs | 10 | ||||
| -rw-r--r-- | examples/mspm0l1306/src/bin/adc.rs | 10 |
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 | ||
| 61 | pub 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. | ||
| 64 | pub 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. |
| 64 | pub struct AdcConfig { | 84 | #[derive(Copy, Clone)] |
| 85 | #[non_exhaustive] | ||
| 86 | pub 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 | ||
| 98 | impl 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. |
| 77 | pub struct Adc<'d, T: Instance, M: Mode> { | 109 | pub 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 | ||
| 86 | impl<'d, T: Instance> Adc<'d, T, Blocking> { | 118 | impl<'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 | ||
| 246 | impl<'d, T: Instance> Adc<'d, T, Async> { | 276 | impl<'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 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_mspm0::adc::{self, Adc, AdcChannel, AdcConfig, Resolution, Vrsel}; | 6 | use embassy_mspm0::adc::{self, Adc, AdcChannel, Vrsel}; |
| 7 | use embassy_mspm0::{bind_interrupts, peripherals, Config}; | 7 | use embassy_mspm0::{bind_interrupts, peripherals, Config}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_halt as _}; | 9 | use {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 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_mspm0::adc::{self, Adc, AdcChannel, AdcConfig, Resolution, Vrsel}; | 6 | use embassy_mspm0::adc::{self, Adc, AdcChannel, Vrsel}; |
| 7 | use embassy_mspm0::{bind_interrupts, peripherals, Config}; | 7 | use embassy_mspm0::{bind_interrupts, peripherals, Config}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_halt as _}; | 9 | use {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)]; |
