diff options
| author | crispaudio <[email protected]> | 2025-09-14 01:34:49 +0200 |
|---|---|---|
| committer | crispaudio <[email protected]> | 2025-09-14 01:34:49 +0200 |
| commit | 31b5a3f0a4fafd425aef34b9d6fb93ead851b4c6 (patch) | |
| tree | 43987fc7e35cdd3d0a533ee2818bd464299a39e8 /embassy-mspm0/src | |
| parent | b2fa01cec7164980333a17355af215feb3cb33c2 (diff) | |
mspm0-adc: implement From for AnyAdcChannel
Diffstat (limited to 'embassy-mspm0/src')
| -rw-r--r-- | embassy-mspm0/src/adc.rs | 64 |
1 files changed, 29 insertions, 35 deletions
diff --git a/embassy-mspm0/src/adc.rs b/embassy-mspm0/src/adc.rs index 71569aef0..5b93e9a6e 100644 --- a/embassy-mspm0/src/adc.rs +++ b/embassy-mspm0/src/adc.rs | |||
| @@ -217,7 +217,7 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> { | |||
| 217 | }); | 217 | }); |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | fn setup_blocking_channel(&mut self, channel: &mut impl AdcChannel<T>) { | 220 | fn setup_blocking_channel(&mut self, channel: &Peri<'d, impl AdcChannel<T>>) { |
| 221 | channel.setup(); | 221 | channel.setup(); |
| 222 | 222 | ||
| 223 | // CTL0.ENC must be 0 to write the MEMCTL register | 223 | // CTL0.ENC must be 0 to write the MEMCTL register |
| @@ -262,7 +262,7 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> { | |||
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | /// Read one ADC channel in blocking mode using the config provided at initialization. | 264 | /// Read one ADC channel in blocking mode using the config provided at initialization. |
| 265 | pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { | 265 | pub fn blocking_read(&mut self, channel: &Peri<'d, impl AdcChannel<T>>) -> u16 { |
| 266 | self.setup_blocking_channel(channel); | 266 | self.setup_blocking_channel(channel); |
| 267 | self.enable_conversion(); | 267 | self.enable_conversion(); |
| 268 | self.start_conversion(); | 268 | self.start_conversion(); |
| @@ -292,7 +292,7 @@ impl<'d, T: Instance> Adc<'d, T, Async> { | |||
| 292 | .await; | 292 | .await; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | fn setup_async_channel(&self, id: usize, channel: &impl AdcChannel<T>, vrsel: Vrsel) { | 295 | fn setup_async_channel(&self, id: usize, channel: &Peri<'d, impl AdcChannel<T>>, vrsel: Vrsel) { |
| 296 | let vrsel = vals::Vrsel::from_bits(vrsel as u8); | 296 | let vrsel = vals::Vrsel::from_bits(vrsel as u8); |
| 297 | // Conversion mem config | 297 | // Conversion mem config |
| 298 | self.info.regs.memctl(id).modify(|reg| { | 298 | self.info.regs.memctl(id).modify(|reg| { |
| @@ -316,7 +316,7 @@ impl<'d, T: Instance> Adc<'d, T, Async> { | |||
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | /// Read one ADC channel asynchronously using the config provided at initialization. | 318 | /// Read one ADC channel asynchronously using the config provided at initialization. |
| 319 | pub async fn read_channel(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { | 319 | pub async fn read_channel(&mut self, channel: &Peri<'d, impl AdcChannel<T>>) -> u16 { |
| 320 | channel.setup(); | 320 | channel.setup(); |
| 321 | 321 | ||
| 322 | // CTL0.ENC must be 0 to write the MEMCTL register | 322 | // CTL0.ENC must be 0 to write the MEMCTL register |
| @@ -345,24 +345,18 @@ impl<'d, T: Instance> Adc<'d, T, Async> { | |||
| 345 | /// use embassy_mspm0::adc::{Adc, AdcChannel, Vrsel}; | 345 | /// use embassy_mspm0::adc::{Adc, AdcChannel, Vrsel}; |
| 346 | /// | 346 | /// |
| 347 | /// let mut adc = Adc::new_async(p.ADC0, adc_config, Irqs); | 347 | /// let mut adc = Adc::new_async(p.ADC0, adc_config, Irqs); |
| 348 | /// let pin1 = p.PA14.degrade_adc(); | 348 | /// let sequence = [(&p.PA22.into(), Vrsel::VddaVssa), (&p.PA20.into(), Vrsel::VddaVssa)]; |
| 349 | /// let pin2 = p.PA25.degrade_adc(); | ||
| 350 | /// let sequence = [(&pin1, Vrsel::VddaVssa), (&pin2, Vrsel::VddaVssa)]; | ||
| 351 | /// let mut readings = [0u16; 2]; | 349 | /// let mut readings = [0u16; 2]; |
| 352 | /// | 350 | /// |
| 353 | /// adc.read_sequence( | 351 | /// adc.read_sequence(sequence.into_iter(), &mut readings).await; |
| 354 | /// sequence.into_iter(), | ||
| 355 | /// &mut readings, | ||
| 356 | /// ) | ||
| 357 | /// .await; | ||
| 358 | /// defmt::info!("Measurements: {}", readings); | 352 | /// defmt::info!("Measurements: {}", readings); |
| 359 | /// ``` | 353 | /// ``` |
| 360 | pub async fn read_sequence<'a>( | 354 | pub async fn read_sequence<'a>( |
| 361 | &mut self, | 355 | &mut self, |
| 362 | sequence: impl ExactSizeIterator<Item = (&'a AnyAdcChannel<T>, Vrsel)>, | 356 | sequence: impl ExactSizeIterator<Item = (&'a Peri<'d, AnyAdcChannel<T>>, Vrsel)>, |
| 363 | readings: &mut [u16], | 357 | readings: &mut [u16], |
| 364 | ) where | 358 | ) where |
| 365 | T: 'a, | 359 | 'd: 'a, |
| 366 | { | 360 | { |
| 367 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); | 361 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); |
| 368 | assert!( | 362 | assert!( |
| @@ -398,7 +392,7 @@ impl<'d, T: Instance> Adc<'d, T, Async> { | |||
| 398 | 392 | ||
| 399 | /// Peripheral instance trait. | 393 | /// Peripheral instance trait. |
| 400 | #[allow(private_bounds)] | 394 | #[allow(private_bounds)] |
| 401 | pub trait Instance: SealedInstance + PeripheralType { | 395 | pub trait Instance: PeripheralType + SealedInstance { |
| 402 | type Interrupt: crate::interrupt::typelevel::Interrupt; | 396 | type Interrupt: crate::interrupt::typelevel::Interrupt; |
| 403 | } | 397 | } |
| 404 | 398 | ||
| @@ -460,8 +454,8 @@ macro_rules! impl_adc_instance { | |||
| 460 | /// This is useful in scenarios where you need the ADC channels to have the same type, such as | 454 | /// This is useful in scenarios where you need the ADC channels to have the same type, such as |
| 461 | /// storing them in an array. | 455 | /// storing them in an array. |
| 462 | pub struct AnyAdcChannel<T> { | 456 | pub struct AnyAdcChannel<T> { |
| 463 | channel: u8, | 457 | pub(crate) channel: u8, |
| 464 | _phantom: PhantomData<T>, | 458 | pub(crate) _phantom: PhantomData<T>, |
| 465 | } | 459 | } |
| 466 | 460 | ||
| 467 | impl_peripheral!(AnyAdcChannel<T: Instance>); | 461 | impl_peripheral!(AnyAdcChannel<T: Instance>); |
| @@ -481,36 +475,36 @@ impl<T> AnyAdcChannel<T> { | |||
| 481 | 475 | ||
| 482 | /// ADC channel. | 476 | /// ADC channel. |
| 483 | #[allow(private_bounds)] | 477 | #[allow(private_bounds)] |
| 484 | pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { | 478 | pub trait AdcChannel<T>: PeripheralType + Into<AnyAdcChannel<T>> + SealedAdcChannel<T> + Sized {} |
| 485 | /// Allows an ADC channel to be converted into a type-erased [`AnyAdcChannel`]. | ||
| 486 | #[allow(unused_mut)] | ||
| 487 | fn degrade_adc(mut self) -> AnyAdcChannel<T> { | ||
| 488 | self.setup(); | ||
| 489 | |||
| 490 | AnyAdcChannel { | ||
| 491 | channel: self.channel(), | ||
| 492 | _phantom: PhantomData, | ||
| 493 | } | ||
| 494 | } | ||
| 495 | } | ||
| 496 | 479 | ||
| 497 | pub(crate) trait SealedAdcChannel<T> { | 480 | pub(crate) trait SealedAdcChannel<T> { |
| 498 | fn setup(&mut self) {} | 481 | fn setup(&self) {} |
| 499 | 482 | ||
| 500 | fn channel(&self) -> u8; | 483 | fn channel(&self) -> u8; |
| 501 | } | 484 | } |
| 502 | 485 | ||
| 503 | macro_rules! impl_adc_pin { | 486 | macro_rules! impl_adc_pin { |
| 504 | ($inst:ident, $pin:ident, $ch:expr) => { | 487 | ($inst: ident, $pin: ident, $ch: expr) => { |
| 505 | impl crate::adc::AdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {} | 488 | impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {} |
| 506 | impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> { | 489 | impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin { |
| 507 | fn setup(&mut self) { | 490 | fn setup(&self) { |
| 508 | <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(self); | 491 | crate::gpio::SealedPin::set_as_analog(self); |
| 509 | } | 492 | } |
| 510 | 493 | ||
| 511 | fn channel(&self) -> u8 { | 494 | fn channel(&self) -> u8 { |
| 512 | $ch | 495 | $ch |
| 513 | } | 496 | } |
| 514 | } | 497 | } |
| 498 | |||
| 499 | impl From<crate::peripherals::$pin> for crate::adc::AnyAdcChannel<peripherals::$inst> { | ||
| 500 | fn from(val: crate::peripherals::$pin) -> Self { | ||
| 501 | crate::adc::SealedAdcChannel::<peripherals::$inst>::setup(&val); | ||
| 502 | |||
| 503 | Self { | ||
| 504 | channel: crate::adc::SealedAdcChannel::<peripherals::$inst>::channel(&val), | ||
| 505 | _phantom: core::marker::PhantomData, | ||
| 506 | } | ||
| 507 | } | ||
| 508 | } | ||
| 515 | }; | 509 | }; |
| 516 | } | 510 | } |
