diff options
Diffstat (limited to 'embassy-nrf/src/saadc.rs')
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 252 |
1 files changed, 243 insertions, 9 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index fd48faabb..e89338416 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -4,12 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::{compiler_fence, Ordering}; | 7 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use embassy_hal_internal::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| 11 | use embassy_hal_internal::{impl_peripheral, Peri}; | 11 | use embassy_hal_internal::{Peri, impl_peripheral}; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 13 | #[cfg(not(feature = "_nrf54l"))] | ||
| 13 | pub(crate) use vals::Psel as InputChannel; | 14 | pub(crate) use vals::Psel as InputChannel; |
| 14 | 15 | ||
| 15 | use crate::interrupt::InterruptExt; | 16 | use crate::interrupt::InterruptExt; |
| @@ -84,6 +85,7 @@ pub struct ChannelConfig<'d> { | |||
| 84 | /// Gain used to control the effective input range of the SAADC. | 85 | /// Gain used to control the effective input range of the SAADC. |
| 85 | pub gain: Gain, | 86 | pub gain: Gain, |
| 86 | /// Positive channel resistor control. | 87 | /// Positive channel resistor control. |
| 88 | #[cfg(not(feature = "_nrf54l"))] | ||
| 87 | pub resistor: Resistor, | 89 | pub resistor: Resistor, |
| 88 | /// Acquisition time in microseconds. | 90 | /// Acquisition time in microseconds. |
| 89 | pub time: Time, | 91 | pub time: Time, |
| @@ -98,7 +100,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 98 | pub fn single_ended(input: impl Input + 'd) -> Self { | 100 | pub fn single_ended(input: impl Input + 'd) -> Self { |
| 99 | Self { | 101 | Self { |
| 100 | reference: Reference::INTERNAL, | 102 | reference: Reference::INTERNAL, |
| 103 | #[cfg(not(feature = "_nrf54l"))] | ||
| 101 | gain: Gain::GAIN1_6, | 104 | gain: Gain::GAIN1_6, |
| 105 | #[cfg(feature = "_nrf54l")] | ||
| 106 | gain: Gain::GAIN2_8, | ||
| 107 | #[cfg(not(feature = "_nrf54l"))] | ||
| 102 | resistor: Resistor::BYPASS, | 108 | resistor: Resistor::BYPASS, |
| 103 | time: Time::_10US, | 109 | time: Time::_10US, |
| 104 | p_channel: input.degrade_saadc(), | 110 | p_channel: input.degrade_saadc(), |
| @@ -109,7 +115,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 109 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { | 115 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { |
| 110 | Self { | 116 | Self { |
| 111 | reference: Reference::INTERNAL, | 117 | reference: Reference::INTERNAL, |
| 118 | #[cfg(not(feature = "_nrf54l"))] | ||
| 112 | gain: Gain::GAIN1_6, | 119 | gain: Gain::GAIN1_6, |
| 120 | #[cfg(feature = "_nrf54l")] | ||
| 121 | gain: Gain::GAIN2_8, | ||
| 122 | #[cfg(not(feature = "_nrf54l"))] | ||
| 113 | resistor: Resistor::BYPASS, | 123 | resistor: Resistor::BYPASS, |
| 114 | time: Time::_10US, | 124 | time: Time::_10US, |
| 115 | p_channel: p_input.degrade_saadc(), | 125 | p_channel: p_input.degrade_saadc(), |
| @@ -118,6 +128,8 @@ impl<'d> ChannelConfig<'d> { | |||
| 118 | } | 128 | } |
| 119 | } | 129 | } |
| 120 | 130 | ||
| 131 | const CNT_UNIT: usize = if cfg!(feature = "_nrf54l") { 2 } else { 1 }; | ||
| 132 | |||
| 121 | /// Value returned by the SAADC callback, deciding what happens next. | 133 | /// Value returned by the SAADC callback, deciding what happens next. |
| 122 | #[derive(PartialEq)] | 134 | #[derive(PartialEq)] |
| 123 | pub enum CallbackResult { | 135 | pub enum CallbackResult { |
| @@ -150,20 +162,40 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 150 | r.oversample().write(|w| w.set_oversample(oversample.into())); | 162 | r.oversample().write(|w| w.set_oversample(oversample.into())); |
| 151 | 163 | ||
| 152 | for (i, cc) in channel_configs.iter().enumerate() { | 164 | for (i, cc) in channel_configs.iter().enumerate() { |
| 165 | #[cfg(not(feature = "_nrf54l"))] | ||
| 153 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); | 166 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); |
| 167 | #[cfg(feature = "_nrf54l")] | ||
| 168 | r.ch(i).pselp().write(|w| { | ||
| 169 | w.set_port(cc.p_channel.port()); | ||
| 170 | w.set_pin(cc.p_channel.pin()); | ||
| 171 | w.set_internal(cc.p_channel.internal()); | ||
| 172 | w.set_connect(cc.p_channel.connect()); | ||
| 173 | }); | ||
| 154 | if let Some(n_channel) = &cc.n_channel { | 174 | if let Some(n_channel) = &cc.n_channel { |
| 175 | #[cfg(not(feature = "_nrf54l"))] | ||
| 155 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); | 176 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); |
| 177 | #[cfg(feature = "_nrf54l")] | ||
| 178 | r.ch(i).pseln().write(|w| { | ||
| 179 | w.set_port(n_channel.port()); | ||
| 180 | w.set_pin(n_channel.pin()); | ||
| 181 | w.set_connect(n_channel.connect().to_bits().into()); | ||
| 182 | }); | ||
| 156 | } | 183 | } |
| 157 | r.ch(i).config().write(|w| { | 184 | r.ch(i).config().write(|w| { |
| 158 | w.set_refsel(cc.reference.into()); | 185 | w.set_refsel(cc.reference.into()); |
| 159 | w.set_gain(cc.gain.into()); | 186 | w.set_gain(cc.gain.into()); |
| 160 | w.set_tacq(cc.time.into()); | 187 | w.set_tacq(cc.time.into()); |
| 188 | #[cfg(feature = "_nrf54l")] | ||
| 189 | w.set_tconv(7); // 7 is the default from the Nordic C driver | ||
| 161 | w.set_mode(match cc.n_channel { | 190 | w.set_mode(match cc.n_channel { |
| 162 | None => vals::ConfigMode::SE, | 191 | None => vals::ConfigMode::SE, |
| 163 | Some(_) => vals::ConfigMode::DIFF, | 192 | Some(_) => vals::ConfigMode::DIFF, |
| 164 | }); | 193 | }); |
| 194 | #[cfg(not(feature = "_nrf54l"))] | ||
| 165 | w.set_resp(cc.resistor.into()); | 195 | w.set_resp(cc.resistor.into()); |
| 196 | #[cfg(not(feature = "_nrf54l"))] | ||
| 166 | w.set_resn(vals::Resn::BYPASS); | 197 | w.set_resn(vals::Resn::BYPASS); |
| 198 | #[cfg(not(feature = "_nrf54l"))] | ||
| 167 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); | 199 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); |
| 168 | }); | 200 | }); |
| 169 | } | 201 | } |
| @@ -222,7 +254,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 222 | 254 | ||
| 223 | // Set up the DMA | 255 | // Set up the DMA |
| 224 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); | 256 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); |
| 225 | r.result().maxcnt().write(|w| w.set_maxcnt(N as _)); | 257 | r.result().maxcnt().write(|w| w.set_maxcnt((N * CNT_UNIT) as _)); |
| 226 | 258 | ||
| 227 | // Reset and enable the end event | 259 | // Reset and enable the end event |
| 228 | r.events_end().write_value(0); | 260 | r.events_end().write_value(0); |
| @@ -354,7 +386,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 354 | 386 | ||
| 355 | // Set up the initial DMA | 387 | // Set up the initial DMA |
| 356 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); | 388 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 357 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N) as _)); | 389 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N * CNT_UNIT) as _)); |
| 358 | 390 | ||
| 359 | // Reset and enable the events | 391 | // Reset and enable the events |
| 360 | r.events_end().write_value(0); | 392 | r.events_end().write_value(0); |
| @@ -473,12 +505,21 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> { | |||
| 473 | let r = Self::regs(); | 505 | let r = Self::regs(); |
| 474 | r.enable().write(|w| w.set_enable(false)); | 506 | r.enable().write(|w| w.set_enable(false)); |
| 475 | for i in 0..N { | 507 | for i in 0..N { |
| 476 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | 508 | #[cfg(not(feature = "_nrf54l"))] |
| 477 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | 509 | { |
| 510 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | ||
| 511 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | ||
| 512 | } | ||
| 513 | #[cfg(feature = "_nrf54l")] | ||
| 514 | { | ||
| 515 | r.ch(i).pselp().write(|w| w.set_connect(vals::PselpConnect::NC)); | ||
| 516 | r.ch(i).pseln().write(|w| w.set_connect(vals::PselnConnect::NC)); | ||
| 517 | } | ||
| 478 | } | 518 | } |
| 479 | } | 519 | } |
| 480 | } | 520 | } |
| 481 | 521 | ||
| 522 | #[cfg(not(feature = "_nrf54l"))] | ||
| 482 | impl From<Gain> for vals::Gain { | 523 | impl From<Gain> for vals::Gain { |
| 483 | fn from(gain: Gain) -> Self { | 524 | fn from(gain: Gain) -> Self { |
| 484 | match gain { | 525 | match gain { |
| @@ -494,7 +535,24 @@ impl From<Gain> for vals::Gain { | |||
| 494 | } | 535 | } |
| 495 | } | 536 | } |
| 496 | 537 | ||
| 538 | #[cfg(feature = "_nrf54l")] | ||
| 539 | impl From<Gain> for vals::Gain { | ||
| 540 | fn from(gain: Gain) -> Self { | ||
| 541 | match gain { | ||
| 542 | Gain::GAIN2_8 => vals::Gain::GAIN2_8, | ||
| 543 | Gain::GAIN2_7 => vals::Gain::GAIN2_7, | ||
| 544 | Gain::GAIN2_6 => vals::Gain::GAIN2_6, | ||
| 545 | Gain::GAIN2_5 => vals::Gain::GAIN2_5, | ||
| 546 | Gain::GAIN2_4 => vals::Gain::GAIN2_4, | ||
| 547 | Gain::GAIN2_3 => vals::Gain::GAIN2_3, | ||
| 548 | Gain::GAIN1 => vals::Gain::GAIN1, | ||
| 549 | Gain::GAIN2 => vals::Gain::GAIN2, | ||
| 550 | } | ||
| 551 | } | ||
| 552 | } | ||
| 553 | |||
| 497 | /// Gain control | 554 | /// Gain control |
| 555 | #[cfg(not(feature = "_nrf54l"))] | ||
| 498 | #[non_exhaustive] | 556 | #[non_exhaustive] |
| 499 | #[derive(Clone, Copy)] | 557 | #[derive(Clone, Copy)] |
| 500 | pub enum Gain { | 558 | pub enum Gain { |
| @@ -516,11 +574,37 @@ pub enum Gain { | |||
| 516 | GAIN4 = 7, | 574 | GAIN4 = 7, |
| 517 | } | 575 | } |
| 518 | 576 | ||
| 577 | /// Gain control | ||
| 578 | #[cfg(feature = "_nrf54l")] | ||
| 579 | #[non_exhaustive] | ||
| 580 | #[derive(Clone, Copy)] | ||
| 581 | pub enum Gain { | ||
| 582 | /// 2/8 | ||
| 583 | GAIN2_8 = 0, | ||
| 584 | /// 2/7 | ||
| 585 | GAIN2_7 = 1, | ||
| 586 | /// 2/6 | ||
| 587 | GAIN2_6 = 2, | ||
| 588 | /// 2/5 | ||
| 589 | GAIN2_5 = 3, | ||
| 590 | /// 2/4 | ||
| 591 | GAIN2_4 = 4, | ||
| 592 | /// 2/3 | ||
| 593 | GAIN2_3 = 5, | ||
| 594 | /// 1 | ||
| 595 | GAIN1 = 6, | ||
| 596 | /// 2 | ||
| 597 | GAIN2 = 7, | ||
| 598 | } | ||
| 599 | |||
| 519 | impl From<Reference> for vals::Refsel { | 600 | impl From<Reference> for vals::Refsel { |
| 520 | fn from(reference: Reference) -> Self { | 601 | fn from(reference: Reference) -> Self { |
| 521 | match reference { | 602 | match reference { |
| 522 | Reference::INTERNAL => vals::Refsel::INTERNAL, | 603 | Reference::INTERNAL => vals::Refsel::INTERNAL, |
| 604 | #[cfg(not(feature = "_nrf54l"))] | ||
| 523 | Reference::VDD1_4 => vals::Refsel::VDD1_4, | 605 | Reference::VDD1_4 => vals::Refsel::VDD1_4, |
| 606 | #[cfg(feature = "_nrf54l")] | ||
| 607 | Reference::EXTERNAL => vals::Refsel::EXTERNAL, | ||
| 524 | } | 608 | } |
| 525 | } | 609 | } |
| 526 | } | 610 | } |
| @@ -531,10 +615,15 @@ impl From<Reference> for vals::Refsel { | |||
| 531 | pub enum Reference { | 615 | pub enum Reference { |
| 532 | /// Internal reference (0.6 V) | 616 | /// Internal reference (0.6 V) |
| 533 | INTERNAL = 0, | 617 | INTERNAL = 0, |
| 618 | #[cfg(not(feature = "_nrf54l"))] | ||
| 534 | /// VDD/4 as reference | 619 | /// VDD/4 as reference |
| 535 | VDD1_4 = 1, | 620 | VDD1_4 = 1, |
| 621 | /// PADC_EXT_REF_1V2 as reference | ||
| 622 | #[cfg(feature = "_nrf54l")] | ||
| 623 | EXTERNAL = 1, | ||
| 536 | } | 624 | } |
| 537 | 625 | ||
| 626 | #[cfg(not(feature = "_nrf54l"))] | ||
| 538 | impl From<Resistor> for vals::Resp { | 627 | impl From<Resistor> for vals::Resp { |
| 539 | fn from(resistor: Resistor) -> Self { | 628 | fn from(resistor: Resistor) -> Self { |
| 540 | match resistor { | 629 | match resistor { |
| @@ -549,6 +638,7 @@ impl From<Resistor> for vals::Resp { | |||
| 549 | /// Positive channel resistor control | 638 | /// Positive channel resistor control |
| 550 | #[non_exhaustive] | 639 | #[non_exhaustive] |
| 551 | #[derive(Clone, Copy)] | 640 | #[derive(Clone, Copy)] |
| 641 | #[cfg(not(feature = "_nrf54l"))] | ||
| 552 | pub enum Resistor { | 642 | pub enum Resistor { |
| 553 | /// Bypass resistor ladder | 643 | /// Bypass resistor ladder |
| 554 | BYPASS = 0, | 644 | BYPASS = 0, |
| @@ -560,6 +650,7 @@ pub enum Resistor { | |||
| 560 | VDD1_2 = 3, | 650 | VDD1_2 = 3, |
| 561 | } | 651 | } |
| 562 | 652 | ||
| 653 | #[cfg(not(feature = "_nrf54l"))] | ||
| 563 | impl From<Time> for vals::Tacq { | 654 | impl From<Time> for vals::Tacq { |
| 564 | fn from(time: Time) -> Self { | 655 | fn from(time: Time) -> Self { |
| 565 | match time { | 656 | match time { |
| @@ -573,6 +664,20 @@ impl From<Time> for vals::Tacq { | |||
| 573 | } | 664 | } |
| 574 | } | 665 | } |
| 575 | 666 | ||
| 667 | #[cfg(feature = "_nrf54l")] | ||
| 668 | impl From<Time> for u16 { | ||
| 669 | fn from(time: Time) -> Self { | ||
| 670 | match time { | ||
| 671 | Time::_3US => (3000 / 125) - 1, | ||
| 672 | Time::_5US => (5000 / 125) - 1, | ||
| 673 | Time::_10US => (10000 / 125) - 1, | ||
| 674 | Time::_15US => (15000 / 125) - 1, | ||
| 675 | Time::_20US => (20000 / 125) - 1, | ||
| 676 | Time::_40US => (40000 / 125) - 1, | ||
| 677 | } | ||
| 678 | } | ||
| 679 | } | ||
| 680 | |||
| 576 | /// Acquisition time, the time the SAADC uses to sample the input voltage | 681 | /// Acquisition time, the time the SAADC uses to sample the input voltage |
| 577 | #[non_exhaustive] | 682 | #[non_exhaustive] |
| 578 | #[derive(Clone, Copy)] | 683 | #[derive(Clone, Copy)] |
| @@ -657,7 +762,20 @@ pub enum Resolution { | |||
| 657 | } | 762 | } |
| 658 | 763 | ||
| 659 | pub(crate) trait SealedInput { | 764 | pub(crate) trait SealedInput { |
| 765 | #[cfg(not(feature = "_nrf54l"))] | ||
| 660 | fn channel(&self) -> InputChannel; | 766 | fn channel(&self) -> InputChannel; |
| 767 | |||
| 768 | #[cfg(feature = "_nrf54l")] | ||
| 769 | fn pin(&self) -> u8; | ||
| 770 | |||
| 771 | #[cfg(feature = "_nrf54l")] | ||
| 772 | fn port(&self) -> u8; | ||
| 773 | |||
| 774 | #[cfg(feature = "_nrf54l")] | ||
| 775 | fn internal(&self) -> vals::PselpInternal; | ||
| 776 | |||
| 777 | #[cfg(feature = "_nrf54l")] | ||
| 778 | fn connect(&self) -> vals::PselpConnect; | ||
| 661 | } | 779 | } |
| 662 | 780 | ||
| 663 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. | 781 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. |
| @@ -667,6 +785,7 @@ pub trait Input: SealedInput + Sized { | |||
| 667 | /// | 785 | /// |
| 668 | /// This allows using several inputs in situations that might require | 786 | /// This allows using several inputs in situations that might require |
| 669 | /// them to be the same type, like putting them in an array. | 787 | /// them to be the same type, like putting them in an array. |
| 788 | #[cfg(not(feature = "_nrf54l"))] | ||
| 670 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | 789 | fn degrade_saadc<'a>(self) -> AnyInput<'a> |
| 671 | where | 790 | where |
| 672 | Self: 'a, | 791 | Self: 'a, |
| @@ -676,17 +795,49 @@ pub trait Input: SealedInput + Sized { | |||
| 676 | _phantom: core::marker::PhantomData, | 795 | _phantom: core::marker::PhantomData, |
| 677 | } | 796 | } |
| 678 | } | 797 | } |
| 798 | |||
| 799 | /// Convert this SAADC input to a type-erased `AnyInput`. | ||
| 800 | /// | ||
| 801 | /// This allows using several inputs in situations that might require | ||
| 802 | /// them to be the same type, like putting them in an array. | ||
| 803 | #[cfg(feature = "_nrf54l")] | ||
| 804 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | ||
| 805 | where | ||
| 806 | Self: 'a, | ||
| 807 | { | ||
| 808 | AnyInput { | ||
| 809 | pin: self.pin(), | ||
| 810 | port: self.port(), | ||
| 811 | internal: self.internal(), | ||
| 812 | connect: self.connect(), | ||
| 813 | _phantom: core::marker::PhantomData, | ||
| 814 | } | ||
| 815 | } | ||
| 679 | } | 816 | } |
| 680 | 817 | ||
| 681 | /// A type-erased SAADC input. | 818 | /// A type-erased SAADC input. |
| 682 | /// | 819 | /// |
| 683 | /// This allows using several inputs in situations that might require | 820 | /// This allows using several inputs in situations that might require |
| 684 | /// them to be the same type, like putting them in an array. | 821 | /// them to be the same type, like putting them in an array. |
| 822 | #[cfg(not(feature = "_nrf54l"))] | ||
| 685 | pub struct AnyInput<'a> { | 823 | pub struct AnyInput<'a> { |
| 686 | channel: InputChannel, | 824 | channel: InputChannel, |
| 687 | _phantom: PhantomData<&'a ()>, | 825 | _phantom: PhantomData<&'a ()>, |
| 688 | } | 826 | } |
| 689 | 827 | ||
| 828 | /// A type-erased SAADC input. | ||
| 829 | /// | ||
| 830 | /// This allows using several inputs in situations that might require | ||
| 831 | /// them to be the same type, like putting them in an array. | ||
| 832 | #[cfg(feature = "_nrf54l")] | ||
| 833 | pub struct AnyInput<'a> { | ||
| 834 | pin: u8, | ||
| 835 | port: u8, | ||
| 836 | internal: vals::PselpInternal, | ||
| 837 | connect: vals::PselpConnect, | ||
| 838 | _phantom: PhantomData<&'a ()>, | ||
| 839 | } | ||
| 840 | |||
| 690 | impl<'a> AnyInput<'a> { | 841 | impl<'a> AnyInput<'a> { |
| 691 | /// Reborrow into a "child" AnyInput. | 842 | /// Reborrow into a "child" AnyInput. |
| 692 | /// | 843 | /// |
| @@ -694,21 +845,56 @@ impl<'a> AnyInput<'a> { | |||
| 694 | pub fn reborrow(&mut self) -> AnyInput<'_> { | 845 | pub fn reborrow(&mut self) -> AnyInput<'_> { |
| 695 | // safety: we're returning the clone inside a new Peripheral that borrows | 846 | // safety: we're returning the clone inside a new Peripheral that borrows |
| 696 | // self, so user code can't use both at the same time. | 847 | // self, so user code can't use both at the same time. |
| 697 | Self { | 848 | #[cfg(not(feature = "_nrf54l"))] |
| 698 | channel: self.channel, | 849 | { |
| 699 | _phantom: PhantomData, | 850 | Self { |
| 851 | channel: self.channel, | ||
| 852 | _phantom: PhantomData, | ||
| 853 | } | ||
| 854 | } | ||
| 855 | #[cfg(feature = "_nrf54l")] | ||
| 856 | { | ||
| 857 | Self { | ||
| 858 | pin: self.pin, | ||
| 859 | port: self.port, | ||
| 860 | internal: self.internal, | ||
| 861 | connect: self.connect, | ||
| 862 | _phantom: PhantomData, | ||
| 863 | } | ||
| 700 | } | 864 | } |
| 701 | } | 865 | } |
| 702 | } | 866 | } |
| 703 | 867 | ||
| 704 | impl SealedInput for AnyInput<'_> { | 868 | impl SealedInput for AnyInput<'_> { |
| 869 | #[cfg(not(feature = "_nrf54l"))] | ||
| 705 | fn channel(&self) -> InputChannel { | 870 | fn channel(&self) -> InputChannel { |
| 706 | self.channel | 871 | self.channel |
| 707 | } | 872 | } |
| 873 | |||
| 874 | #[cfg(feature = "_nrf54l")] | ||
| 875 | fn pin(&self) -> u8 { | ||
| 876 | self.pin | ||
| 877 | } | ||
| 878 | |||
| 879 | #[cfg(feature = "_nrf54l")] | ||
| 880 | fn port(&self) -> u8 { | ||
| 881 | self.port | ||
| 882 | } | ||
| 883 | |||
| 884 | #[cfg(feature = "_nrf54l")] | ||
| 885 | fn internal(&self) -> vals::PselpInternal { | ||
| 886 | self.internal | ||
| 887 | } | ||
| 888 | |||
| 889 | #[cfg(feature = "_nrf54l")] | ||
| 890 | fn connect(&self) -> vals::PselpConnect { | ||
| 891 | self.connect | ||
| 892 | } | ||
| 708 | } | 893 | } |
| 709 | 894 | ||
| 710 | impl Input for AnyInput<'_> {} | 895 | impl Input for AnyInput<'_> {} |
| 711 | 896 | ||
| 897 | #[cfg(not(feature = "_nrf54l"))] | ||
| 712 | macro_rules! impl_saadc_input { | 898 | macro_rules! impl_saadc_input { |
| 713 | ($pin:ident, $ch:ident) => { | 899 | ($pin:ident, $ch:ident) => { |
| 714 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); | 900 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); |
| @@ -723,15 +909,45 @@ macro_rules! impl_saadc_input { | |||
| 723 | }; | 909 | }; |
| 724 | } | 910 | } |
| 725 | 911 | ||
| 912 | #[cfg(feature = "_nrf54l")] | ||
| 913 | macro_rules! impl_saadc_input { | ||
| 914 | ($pin:ident, $port:expr, $ain:expr) => { | ||
| 915 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $port, $ain, AVDD, ANALOG_INPUT); | ||
| 916 | }; | ||
| 917 | (@local, $pin:ty, $port:expr, $ain:expr, $internal:ident, $connect:ident) => { | ||
| 918 | impl crate::saadc::SealedInput for $pin { | ||
| 919 | fn pin(&self) -> u8 { | ||
| 920 | $ain | ||
| 921 | } | ||
| 922 | |||
| 923 | fn port(&self) -> u8 { | ||
| 924 | $port | ||
| 925 | } | ||
| 926 | |||
| 927 | fn internal(&self) -> crate::pac::saadc::vals::PselpInternal { | ||
| 928 | crate::pac::saadc::vals::PselpInternal::$internal | ||
| 929 | } | ||
| 930 | |||
| 931 | fn connect(&self) -> crate::pac::saadc::vals::PselpConnect { | ||
| 932 | crate::pac::saadc::vals::PselpConnect::$connect | ||
| 933 | } | ||
| 934 | } | ||
| 935 | impl crate::saadc::Input for $pin {} | ||
| 936 | }; | ||
| 937 | } | ||
| 938 | |||
| 726 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 939 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 727 | /// internal voltage. | 940 | /// internal voltage. |
| 728 | pub struct VddInput; | 941 | pub struct VddInput; |
| 729 | 942 | ||
| 730 | impl_peripheral!(VddInput); | 943 | impl_peripheral!(VddInput); |
| 944 | #[cfg(not(feature = "_nrf54l"))] | ||
| 731 | #[cfg(not(feature = "_nrf91"))] | 945 | #[cfg(not(feature = "_nrf91"))] |
| 732 | impl_saadc_input!(@local, VddInput, VDD); | 946 | impl_saadc_input!(@local, VddInput, VDD); |
| 733 | #[cfg(feature = "_nrf91")] | 947 | #[cfg(feature = "_nrf91")] |
| 734 | impl_saadc_input!(@local, VddInput, VDD_GPIO); | 948 | impl_saadc_input!(@local, VddInput, VDD_GPIO); |
| 949 | #[cfg(feature = "_nrf54l")] | ||
| 950 | impl_saadc_input!(@local, VddInput, 0, 0, VDD, INTERNAL); | ||
| 735 | 951 | ||
| 736 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 952 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 737 | /// VDDH / 5 voltage. | 953 | /// VDDH / 5 voltage. |
| @@ -743,3 +959,21 @@ impl_peripheral!(VddhDiv5Input); | |||
| 743 | 959 | ||
| 744 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | 960 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] |
| 745 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); | 961 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); |
| 962 | |||
| 963 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 964 | /// AVDD internal voltage of the nrf54l chip family. | ||
| 965 | #[cfg(feature = "_nrf54l")] | ||
| 966 | pub struct AVddInput; | ||
| 967 | #[cfg(feature = "_nrf54l")] | ||
| 968 | embassy_hal_internal::impl_peripheral!(AVddInput); | ||
| 969 | #[cfg(feature = "_nrf54l")] | ||
| 970 | impl_saadc_input!(@local, AVddInput, 0, 0, AVDD, INTERNAL); | ||
| 971 | |||
| 972 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 973 | /// DVDD internal voltage of the nrf54l chip family. | ||
| 974 | #[cfg(feature = "_nrf54l")] | ||
| 975 | pub struct DVddInput; | ||
| 976 | #[cfg(feature = "_nrf54l")] | ||
| 977 | embassy_hal_internal::impl_peripheral!(DVddInput); | ||
| 978 | #[cfg(feature = "_nrf54l")] | ||
| 979 | impl_saadc_input!(@local, DVddInput, 0, 0, DVDD, INTERNAL); | ||
