aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa/src/adc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mcxa/src/adc.rs')
-rw-r--r--embassy-mcxa/src/adc.rs429
1 files changed, 366 insertions, 63 deletions
diff --git a/embassy-mcxa/src/adc.rs b/embassy-mcxa/src/adc.rs
index 7475299ba..2e2fb0342 100644
--- a/embassy-mcxa/src/adc.rs
+++ b/embassy-mcxa/src/adc.rs
@@ -1,42 +1,29 @@
1//! ADC driver 1//! ADC driver
2use core::sync::atomic::{AtomicBool, Ordering}; 2use core::marker::PhantomData;
3 3
4use embassy_hal_internal::{Peri, PeripheralType}; 4use embassy_hal_internal::{Peri, PeripheralType};
5 5
6use paste::paste;
7use crate::pac;
8use crate::interrupt::typelevel::{Handler, Interrupt};
9use crate::gpio::{GpioPin, SealedPin};
10use maitake_sync::WaitCell;
11
6use crate::clocks::periph_helpers::{AdcClockSel, AdcConfig, Div4}; 12use crate::clocks::periph_helpers::{AdcClockSel, AdcConfig, Div4};
7use crate::clocks::{Gate, PoweredClock, enable_and_reset}; 13use crate::clocks::{Gate, PoweredClock, enable_and_reset};
8use crate::pac; 14
9use crate::pac::adc1::cfg::{HptExdi, Pwrsel, Refsel, Tcmdres, Tprictrl, Tres}; 15use crate::pac::adc1::cfg::{HptExdi, Pwrsel, Refsel, Tcmdres, Tprictrl, Tres};
10use crate::pac::adc1::cmdh1::{Avgs, Cmpen, Next, Sts}; 16use crate::pac::adc1::cmdh1::{Avgs, Cmpen, Next, Sts};
11use crate::pac::adc1::cmdl1::{Adch, Ctype, Mode}; 17use crate::pac::adc1::cmdl1::{Adch, Ctype, Mode};
12use crate::pac::adc1::ctrl::CalAvgs; 18use crate::pac::adc1::ctrl::CalAvgs;
13use crate::pac::adc1::tctrl::{Tcmd, Tpri}; 19use crate::pac::adc1::tctrl::{Tcmd, Tpri};
14 20
15type Regs = pac::adc1::RegisterBlock; 21/// Global wait cell for alarm notifications
22static WAKER: WaitCell = WaitCell::new();
16 23
17static INTERRUPT_TRIGGERED: AtomicBool = AtomicBool::new(false); 24const G_LPADC_RESULT_SHIFT: u32 = 0;
18// Token-based instance pattern like embassy-imxrt
19pub trait Instance: Gate<MrccPeriphConfig = AdcConfig> + PeripheralType {
20 fn ptr() -> *const Regs;
21}
22
23/// Token for ADC1
24pub type Adc1 = crate::peripherals::ADC1;
25impl Instance for crate::peripherals::ADC1 {
26 #[inline(always)]
27 fn ptr() -> *const Regs {
28 pac::Adc1::ptr()
29 }
30}
31
32// Also implement Instance for the Peri wrapper type
33// impl Instance for embassy_hal_internal::Peri<'_, crate::peripherals::ADC1> {
34// #[inline(always)]
35// fn ptr() -> *const Regs {
36// pac::Adc1::ptr()
37// }
38// }
39 25
26/// Trigger priority policy for ADC conversions.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)] 27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41#[repr(u8)] 28#[repr(u8)]
42pub enum TriggerPriorityPolicy { 29pub enum TriggerPriorityPolicy {
@@ -52,20 +39,40 @@ pub enum TriggerPriorityPolicy {
52 TriggerPriorityExceptionDisabled = 16, 39 TriggerPriorityExceptionDisabled = 16,
53} 40}
54 41
42/// Configuration for the LPADC peripheral.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)] 43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct LpadcConfig { 44pub struct LpadcConfig {
45 /// Control system transition to Stop and Wait power modes while ADC is converting.
46 /// When enabled in Doze mode, immediate entries to Wait or Stop are allowed.
47 /// When disabled, the ADC will wait for the current averaging iteration/FIFO storage to complete before acknowledging stop or wait mode entry.
57 pub enable_in_doze_mode: bool, 48 pub enable_in_doze_mode: bool,
49 /// Auto-Calibration Averages.
58 pub conversion_average_mode: CalAvgs, 50 pub conversion_average_mode: CalAvgs,
51 /// ADC analog circuits are pre-enabled and ready to execute conversions without startup delays(at the cost of higher DC current consumption).
59 pub enable_analog_preliminary: bool, 52 pub enable_analog_preliminary: bool,
53 /// Power-up delay value (in ADC clock cycles)
60 pub power_up_delay: u8, 54 pub power_up_delay: u8,
55 /// Reference voltage source selection
61 pub reference_voltage_source: Refsel, 56 pub reference_voltage_source: Refsel,
57 /// Power configuration selection.
62 pub power_level_mode: Pwrsel, 58 pub power_level_mode: Pwrsel,
59 /// Trigger priority policy for handling multiple triggers
63 pub trigger_priority_policy: TriggerPriorityPolicy, 60 pub trigger_priority_policy: TriggerPriorityPolicy,
61 /// Enables the ADC pausing function. When enabled, a programmable delay is inserted during command execution sequencing between LOOP iterations,
62 /// between commands in a sequence, and between conversions when command is executing in "Compare Until True" configuration.
64 pub enable_conv_pause: bool, 63 pub enable_conv_pause: bool,
64 /// Controls the duration of pausing during command execution sequencing. The pause delay is a count of (convPauseDelay*4) ADCK cycles.
65 /// Only available when ADC pausing function is enabled. The available value range is in 9-bit.
65 pub conv_pause_delay: u16, 66 pub conv_pause_delay: u16,
67 /// FIFO watermark level for interrupt generation.
68 /// When the number of datawords stored in the ADC Result FIFO is greater than the value in this field,
69 /// the ready flag would be asserted to indicate stored data has reached the programmable threshold.
66 pub fifo_watermark: u8, 70 pub fifo_watermark: u8,
71 /// Power configuration (normal/deep sleep behavior)
67 pub power: PoweredClock, 72 pub power: PoweredClock,
73 /// ADC clock source selection
68 pub source: AdcClockSel, 74 pub source: AdcClockSel,
75 /// Clock divider for ADC clock
69 pub div: Div4, 76 pub div: Div4,
70} 77}
71 78
@@ -89,6 +96,9 @@ impl Default for LpadcConfig {
89 } 96 }
90} 97}
91 98
99/// Configuration for a conversion command.
100///
101/// Defines the parameters for a single ADC conversion operation.
92#[derive(Debug, Clone, Copy, PartialEq, Eq)] 102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct ConvCommandConfig { 103pub struct ConvCommandConfig {
94 pub sample_channel_mode: Ctype, 104 pub sample_channel_mode: Ctype,
@@ -105,6 +115,10 @@ pub struct ConvCommandConfig {
105 pub enable_wait_trigger: bool, 115 pub enable_wait_trigger: bool,
106} 116}
107 117
118
119/// Configuration for a conversion trigger.
120///
121/// Defines how a trigger initiates ADC conversions.
108#[derive(Debug, Clone, Copy, PartialEq, Eq)] 122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub struct ConvTriggerConfig { 123pub struct ConvTriggerConfig {
110 pub target_command_id: Tcmd, 124 pub target_command_id: Tcmd,
@@ -113,6 +127,9 @@ pub struct ConvTriggerConfig {
113 pub enable_hardware_trigger: bool, 127 pub enable_hardware_trigger: bool,
114} 128}
115 129
130/// Result of an ADC conversion.
131///
132/// Contains the conversion value and metadata about the conversion.
116#[derive(Debug, Clone, Copy, PartialEq, Eq)] 133#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117pub struct ConvResult { 134pub struct ConvResult {
118 pub command_id_source: u32, 135 pub command_id_source: u32,
@@ -121,14 +138,59 @@ pub struct ConvResult {
121 pub conv_value: u16, 138 pub conv_value: u16,
122} 139}
123 140
141/// ADC interrupt handler.
142pub struct InterruptHandler<I: Instance> {
143 _phantom: PhantomData<I>,
144}
145
146/// ADC driver instance.
124pub struct Adc<'a, I: Instance> { 147pub struct Adc<'a, I: Instance> {
125 _inst: core::marker::PhantomData<&'a mut I>, 148 _inst: PhantomData<&'a mut I>,
126} 149}
127 150
128impl<'a, I: Instance> Adc<'a, I> { 151impl<'a, I: Instance> Adc<'a, I> {
129 /// initialize ADC 152 /// Initialize ADC with interrupt support.
130 pub fn new(_inst: Peri<'a, I>, config: LpadcConfig) -> Self { 153 ///
131 let adc = unsafe { &*I::ptr() }; 154 /// # Arguments
155 /// * `_inst` - ADC peripheral instance
156 /// * `pin` - GPIO pin to use for ADC
157 /// * `_irq` - Interrupt binding for this ADC instance
158 /// * `config` - ADC configuration
159 pub fn new(
160 _inst: Peri<'a, I>,
161 pin: Peri<'a, impl AdcPin<I>>,
162 _irq: impl crate::interrupt::typelevel::Binding<I::Interrupt, InterruptHandler<I>> + 'a,
163 config: LpadcConfig,
164 ) -> Self {
165 let adc = Self::new_inner(_inst, pin, config);
166
167 I::Interrupt::unpend();
168 unsafe { I::Interrupt::enable() };
169
170 adc
171 }
172
173 /// Initialize ADC without interrupt support (for polling mode).
174 ///
175 /// # Arguments
176 /// * `_inst` - ADC peripheral instance
177 /// * `pin` - GPIO pin to use for ADC input
178 /// * `config` - ADC configuration
179 pub fn new_polling(
180 _inst: Peri<'a, I>,
181 pin: Peri<'a, impl AdcPin<I>>,
182 config: LpadcConfig,
183 ) -> Self {
184 Self::new_inner(_inst, pin, config)
185 }
186
187 /// Internal initialization function shared by `new` and `new_polling`.
188 fn new_inner(
189 _inst: Peri<'a, I>,
190 pin: Peri<'a, impl AdcPin<I>>,
191 config: LpadcConfig,
192 ) -> Self {
193 let adc = &*I::ptr();
132 194
133 let _clock_freq = unsafe { 195 let _clock_freq = unsafe {
134 enable_and_reset::<I>(&AdcConfig { 196 enable_and_reset::<I>(&AdcConfig {
@@ -139,6 +201,8 @@ impl<'a, I: Instance> Adc<'a, I> {
139 .expect("Adc Init should not fail") 201 .expect("Adc Init should not fail")
140 }; 202 };
141 203
204 pin.mux();
205
142 /* Reset the module. */ 206 /* Reset the module. */
143 adc.ctrl().modify(|_, w| w.rst().held_in_reset()); 207 adc.ctrl().modify(|_, w| w.rst().held_in_reset());
144 adc.ctrl().modify(|_, w| w.rst().released_from_reset()); 208 adc.ctrl().modify(|_, w| w.rst().released_from_reset());
@@ -221,17 +285,20 @@ impl<'a, I: Instance> Adc<'a, I> {
221 adc.ctrl().modify(|_, w| w.adcen().enabled()); 285 adc.ctrl().modify(|_, w| w.adcen().enabled());
222 286
223 Self { 287 Self {
224 _inst: core::marker::PhantomData, 288 _inst: PhantomData,
225 } 289 }
226 } 290 }
227 291
292 /// Deinitialize the ADC peripheral.
228 pub fn deinit(&self) { 293 pub fn deinit(&self) {
229 let adc = unsafe { &*I::ptr() }; 294 let adc = &*I::ptr();
230 adc.ctrl().modify(|_, w| w.adcen().disabled()); 295 adc.ctrl().modify(|_, w| w.adcen().disabled());
231 } 296 }
232 297
298 /// Perform offset calibration.
299 /// Waits for calibration to complete before returning.
233 pub fn do_offset_calibration(&self) { 300 pub fn do_offset_calibration(&self) {
234 let adc = unsafe { &*I::ptr() }; 301 let adc = &*I::ptr();
235 // Enable calibration mode 302 // Enable calibration mode
236 adc.ctrl() 303 adc.ctrl()
237 .modify(|_, w| w.calofs().offset_calibration_request_pending()); 304 .modify(|_, w| w.calofs().offset_calibration_request_pending());
@@ -240,6 +307,13 @@ impl<'a, I: Instance> Adc<'a, I> {
240 while adc.stat().read().cal_rdy().is_not_set() {} 307 while adc.stat().read().cal_rdy().is_not_set() {}
241 } 308 }
242 309
310 /// Calculate gain conversion result from gain adjustment factor.
311 ///
312 /// # Arguments
313 /// * `gain_adjustment` - Gain adjustment factor
314 ///
315 /// # Returns
316 /// Gain calibration register value
243 pub fn get_gain_conv_result(&self, mut gain_adjustment: f32) -> u32 { 317 pub fn get_gain_conv_result(&self, mut gain_adjustment: f32) -> u32 {
244 let mut gcra_array = [0u32; 17]; 318 let mut gcra_array = [0u32; 17];
245 let mut gcalr: u32 = 0; 319 let mut gcalr: u32 = 0;
@@ -258,8 +332,9 @@ impl<'a, I: Instance> Adc<'a, I> {
258 gcalr 332 gcalr
259 } 333 }
260 334
335 /// Perform automatic gain calibration.
261 pub fn do_auto_calibration(&self) { 336 pub fn do_auto_calibration(&self) {
262 let adc = unsafe { &*I::ptr() }; 337 let adc = &*I::ptr();
263 adc.ctrl().modify(|_, w| w.cal_req().calibration_request_pending()); 338 adc.ctrl().modify(|_, w| w.cal_req().calibration_request_pending());
264 339
265 while adc.gcc0().read().rdy().is_gain_cal_not_valid() {} 340 while adc.gcc0().read().rdy().is_gain_cal_not_valid() {}
@@ -280,11 +355,21 @@ impl<'a, I: Instance> Adc<'a, I> {
280 while adc.stat().read().cal_rdy().is_not_set() {} 355 while adc.stat().read().cal_rdy().is_not_set() {}
281 } 356 }
282 357
358 /// Trigger ADC conversion(s) via software.
359 ///
360 /// Initiates conversion(s) for the trigger(s) specified in the bitmask.
361 /// Each bit in the mask corresponds to a trigger ID (bit 0 = trigger 0, etc.).
362 ///
363 /// # Arguments
364 /// * `trigger_id_mask` - Bitmask of trigger IDs to activate (bit N = trigger N)
283 pub fn do_software_trigger(&self, trigger_id_mask: u32) { 365 pub fn do_software_trigger(&self, trigger_id_mask: u32) {
284 let adc = unsafe { &*I::ptr() }; 366 let adc = &*I::ptr();
285 adc.swtrig().write(|w| unsafe { w.bits(trigger_id_mask) }); 367 adc.swtrig().write(|w| unsafe { w.bits(trigger_id_mask) });
286 } 368 }
287 369
370 /// Get default conversion command configuration.
371 /// # Returns
372 /// Default conversion command configuration
288 pub fn get_default_conv_command_config(&self) -> ConvCommandConfig { 373 pub fn get_default_conv_command_config(&self) -> ConvCommandConfig {
289 ConvCommandConfig { 374 ConvCommandConfig {
290 sample_channel_mode: Ctype::SingleEndedASideChannel, 375 sample_channel_mode: Ctype::SingleEndedASideChannel,
@@ -302,9 +387,17 @@ impl<'a, I: Instance> Adc<'a, I> {
302 } 387 }
303 } 388 }
304 389
305 //TBD Need to add cmdlx and cmdhx with x {2..7} 390 /// Set conversion command configuration.
391 ///
392 /// Configures a conversion command slot with the specified parameters.
393 /// Commands define how conversions are performed (channel, resolution, etc.).
394 ///
395 /// # Arguments
396 /// * `index` - Command index (currently only 1 is supported)
397 /// * `config` - Command configuration
398 ///TBD Need to add cmdlx and cmdhx with x {2..7}
306 pub fn set_conv_command_config(&self, index: u32, config: &ConvCommandConfig) { 399 pub fn set_conv_command_config(&self, index: u32, config: &ConvCommandConfig) {
307 let adc = unsafe { &*I::ptr() }; 400 let adc = &*I::ptr();
308 401
309 match index { 402 match index {
310 1 => { 403 1 => {
@@ -338,6 +431,10 @@ impl<'a, I: Instance> Adc<'a, I> {
338 } 431 }
339 } 432 }
340 433
434 /// Get default conversion trigger configuration.
435 ///
436 /// # Returns
437 /// Default conversion trigger configuration
341 pub fn get_default_conv_trigger_config(&self) -> ConvTriggerConfig { 438 pub fn get_default_conv_trigger_config(&self) -> ConvTriggerConfig {
342 ConvTriggerConfig { 439 ConvTriggerConfig {
343 target_command_id: Tcmd::NotValid, 440 target_command_id: Tcmd::NotValid,
@@ -347,8 +444,16 @@ impl<'a, I: Instance> Adc<'a, I> {
347 } 444 }
348 } 445 }
349 446
447 /// Set conversion trigger configuration.
448 ///
449 /// Configures a trigger to initiate conversions. Triggers can be
450 /// activated by software or hardware signals.
451 ///
452 /// # Arguments
453 /// * `trigger_id` - Trigger index (0-15)
454 /// * `config` - Trigger configuration
350 pub fn set_conv_trigger_config(&self, trigger_id: usize, config: &ConvTriggerConfig) { 455 pub fn set_conv_trigger_config(&self, trigger_id: usize, config: &ConvTriggerConfig) {
351 let adc = unsafe { &*I::ptr() }; 456 let adc = &*I::ptr();
352 let tctrl = &adc.tctrl(trigger_id); 457 let tctrl = &adc.tctrl(trigger_id);
353 458
354 tctrl.write(|w| unsafe { 459 tctrl.write(|w| unsafe {
@@ -363,47 +468,245 @@ impl<'a, I: Instance> Adc<'a, I> {
363 }); 468 });
364 } 469 }
365 470
471 /// Reset the FIFO buffer.
472 ///
473 /// Clears all pending conversion results from the FIFO.
366 pub fn do_reset_fifo(&self) { 474 pub fn do_reset_fifo(&self) {
367 let adc = unsafe { &*I::ptr() }; 475 let adc = &*I::ptr();
368 adc.ctrl().modify(|_, w| w.rstfifo0().trigger_reset()); 476 adc.ctrl().modify(|_, w| w.rstfifo0().trigger_reset());
369 } 477 }
370 478
479 /// Enable ADC interrupts.
480 ///
481 /// Enables the interrupt sources specified in the bitmask.
482 ///
483 /// # Arguments
484 /// * `mask` - Bitmask of interrupt sources to enable
371 pub fn enable_interrupt(&self, mask: u32) { 485 pub fn enable_interrupt(&self, mask: u32) {
372 let adc = unsafe { &*I::ptr() }; 486 let adc = &*I::ptr();
373 adc.ie().modify(|r, w| unsafe { w.bits(r.bits() | mask) }); 487 adc.ie().modify(|r, w| unsafe { w.bits(r.bits() | mask) });
374 INTERRUPT_TRIGGERED.store(false, Ordering::SeqCst);
375 } 488 }
376 489
377 pub fn is_interrupt_triggered(&self) -> bool { 490 /// Disable ADC interrupts.
378 INTERRUPT_TRIGGERED.load(Ordering::Relaxed) 491 ///
492 /// Disables the interrupt sources specified in the bitmask.
493 ///
494 /// # Arguments
495 /// * `mask` - Bitmask of interrupt sources to disable
496 pub fn disable_interrupt(&self, mask: u32) {
497 let adc = &*I::ptr();
498 adc.ie().modify(|r, w| unsafe { w.bits(r.bits() & !mask) });
379 } 499 }
380}
381 500
382pub fn get_conv_result() -> Option<ConvResult> { 501 /// Get conversion result from FIFO.
383 let adc = unsafe { &*pac::Adc1::ptr() }; 502 ///
384 let fifo = adc.resfifo0().read().bits(); 503 /// Reads and returns the next conversion result from the FIFO.
385 const VALID_MASK: u32 = 1 << 31; 504 /// Returns `None` if the FIFO is empty.
386 if fifo & VALID_MASK == 0 { 505 ///
387 return None; 506 /// # Returns
388 } 507 /// - `Some(ConvResult)` if a result is available
508 /// - `None` if the FIFO is empty
509 pub fn get_conv_result(&self) -> Option<ConvResult> {
510 let adc = &*I::ptr();
511 let fifo = adc.resfifo0().read().bits();
512 const VALID_MASK: u32 = 1 << 31;
513 if fifo & VALID_MASK == 0 {
514 return None;
515 }
389 516
390 Some(ConvResult { 517 Some(ConvResult {
391 command_id_source: (fifo >> 24) & 0x0F, 518 command_id_source: (fifo >> 24) & 0x0F,
392 loop_count_index: (fifo >> 20) & 0x0F, 519 loop_count_index: (fifo >> 20) & 0x0F,
393 trigger_id_source: (fifo >> 16) & 0x0F, 520 trigger_id_source: (fifo >> 16) & 0x0F,
394 conv_value: (fifo & 0xFFFF) as u16, 521 conv_value: (fifo & 0xFFFF) as u16,
395 }) 522 })
396} 523 }
397 524
398pub fn on_interrupt() { 525 /// Read ADC value asynchronously.
399 if get_conv_result().is_some() { 526 ///
400 INTERRUPT_TRIGGERED.store(true, Ordering::SeqCst); 527 /// Performs a single ADC conversion and returns the result when the ADC interrupt is triggered.
528 ///
529 /// The function:
530 /// 1. Enables the FIFO watermark interrupt
531 /// 2. Triggers a software conversion on trigger 0
532 /// 3. Waits for the conversion to complete
533 /// 4. Returns the conversion result
534 ///
535 /// # Returns
536 /// 16-bit ADC conversion value
537 pub async fn read(&mut self) -> u16 {
538 let wait = WAKER.subscribe().await;
539
540 self.enable_interrupt(0x1);
541 self.do_software_trigger(1);
542
543 let _ = wait.await;
544
545 let result = self.get_conv_result();
546 result.unwrap().conv_value >> G_LPADC_RESULT_SHIFT
401 } 547 }
402} 548}
403 549
404pub struct AdcHandler; 550impl<T: Instance> Handler<T::Interrupt> for InterruptHandler<T> {
405impl crate::interrupt::typelevel::Handler<crate::interrupt::typelevel::ADC1> for AdcHandler {
406 unsafe fn on_interrupt() { 551 unsafe fn on_interrupt() {
407 on_interrupt(); 552 T::ptr().ie().modify(|r, w| w.bits(r.bits() & !0x1));
553 WAKER.wake();
408 } 554 }
409} 555}
556
557mod sealed {
558 /// Seal a trait
559 pub trait Sealed {}
560}
561
562impl<I: GpioPin> sealed::Sealed for I {}
563
564trait SealedInstance {
565 fn ptr() -> &'static pac::adc0::RegisterBlock;
566}
567
568
569/// ADC Instance
570#[allow(private_bounds)]
571pub trait Instance: SealedInstance + PeripheralType + Gate<MrccPeriphConfig = AdcConfig> {
572 /// Interrupt for this ADC instance.
573 type Interrupt: Interrupt;
574}
575
576macro_rules! impl_instance {
577 ($($n:expr),*) => {
578 $(
579 paste!{
580 impl SealedInstance for crate::peripherals::[<ADC $n>] {
581 fn ptr() -> &'static pac::adc0::RegisterBlock {
582 unsafe { &*pac::[<Adc $n>]::ptr() }
583 }
584
585 }
586
587 impl Instance for crate::peripherals::[<ADC $n>] {
588 type Interrupt = crate::interrupt::typelevel::[<ADC $n>];
589 }
590 }
591 )*
592 };
593}
594
595impl_instance!(0, 1); //ADC2 and ADC3 missing in the PAC ??
596
597pub trait AdcPin<Instance>: GpioPin + sealed::Sealed + PeripheralType {
598 /// Set the given pin to the correct muxing state
599 fn mux(&self);
600}
601
602macro_rules! impl_pin {
603 ($pin:ident, $peri:ident, $func:ident, $trait:ident) => {
604 impl $trait<crate::peripherals::$peri> for crate::peripherals::$pin {
605 fn mux(&self) {
606 self.set_pull(crate::gpio::Pull::Disabled);
607 self.set_slew_rate(crate::gpio::SlewRate::Fast.into());
608 self.set_drive_strength(crate::gpio::DriveStrength::Normal.into());
609 self.set_function(crate::pac::port0::pcr0::Mux::$func);
610 }
611 }
612 };
613 }
614
615impl_pin!(P2_0, ADC0, Mux0, AdcPin);
616impl_pin!(P2_4, ADC0, Mux0, AdcPin);
617impl_pin!(P2_15, ADC0, Mux0, AdcPin);
618impl_pin!(P2_3, ADC0, Mux0, AdcPin);
619impl_pin!(P2_2, ADC0, Mux0, AdcPin);
620impl_pin!(P2_12, ADC0, Mux0, AdcPin);
621impl_pin!(P2_16, ADC0, Mux0, AdcPin);
622impl_pin!(P2_7, ADC0, Mux0, AdcPin);
623impl_pin!(P0_18, ADC0, Mux0, AdcPin);
624impl_pin!(P0_19, ADC0, Mux0, AdcPin);
625impl_pin!(P0_20, ADC0, Mux0, AdcPin);
626impl_pin!(P0_21, ADC0, Mux0, AdcPin);
627impl_pin!(P0_22, ADC0, Mux0, AdcPin);
628impl_pin!(P0_23, ADC0, Mux0, AdcPin);
629impl_pin!(P0_3, ADC0, Mux0, AdcPin);
630impl_pin!(P0_6, ADC0, Mux0, AdcPin);
631impl_pin!(P1_0, ADC0, Mux0, AdcPin);
632impl_pin!(P1_1, ADC0, Mux0, AdcPin);
633impl_pin!(P1_2, ADC0, Mux0, AdcPin);
634impl_pin!(P1_3, ADC0, Mux0, AdcPin);
635impl_pin!(P1_4, ADC0, Mux0, AdcPin);
636impl_pin!(P1_5, ADC0, Mux0, AdcPin);
637impl_pin!(P1_6, ADC0, Mux0, AdcPin);
638impl_pin!(P1_7, ADC0, Mux0, AdcPin);
639impl_pin!(P1_10, ADC0, Mux0, AdcPin);
640
641impl_pin!(P2_1, ADC1, Mux0, AdcPin);
642impl_pin!(P2_5, ADC1, Mux0, AdcPin);
643impl_pin!(P2_19, ADC1, Mux0, AdcPin);
644impl_pin!(P2_6, ADC1, Mux0, AdcPin);
645impl_pin!(P2_3, ADC1, Mux0, AdcPin);
646impl_pin!(P2_13, ADC1, Mux0, AdcPin);
647impl_pin!(P2_17, ADC1, Mux0, AdcPin);
648impl_pin!(P2_7, ADC1, Mux0, AdcPin);
649impl_pin!(P1_10, ADC1, Mux0, AdcPin);
650impl_pin!(P1_11, ADC1, Mux0, AdcPin);
651impl_pin!(P1_12, ADC1, Mux0, AdcPin);
652impl_pin!(P1_13, ADC1, Mux0, AdcPin);
653impl_pin!(P1_14, ADC1, Mux0, AdcPin);
654impl_pin!(P1_15, ADC1, Mux0, AdcPin);
655impl_pin!(P1_16, ADC1, Mux0, AdcPin);
656impl_pin!(P1_17, ADC1, Mux0, AdcPin);
657impl_pin!(P1_18, ADC1, Mux0, AdcPin);
658impl_pin!(P1_19, ADC1, Mux0, AdcPin);
659impl_pin!(P3_31, ADC1, Mux0, AdcPin);
660impl_pin!(P3_30, ADC1, Mux0, AdcPin);
661impl_pin!(P3_29, ADC1, Mux0, AdcPin);
662
663impl_pin!(P2_4, ADC2, Mux0, AdcPin);
664impl_pin!(P2_10, ADC2, Mux0, AdcPin);
665impl_pin!(P4_4, ADC2, Mux0, AdcPin);
666impl_pin!(P2_24, ADC2, Mux0, AdcPin);
667impl_pin!(P2_16, ADC2, Mux0, AdcPin);
668impl_pin!(P2_12, ADC2, Mux0, AdcPin);
669impl_pin!(P2_20, ADC2, Mux0, AdcPin);
670impl_pin!(P2_7, ADC2, Mux0, AdcPin);
671impl_pin!(P0_2, ADC2, Mux0, AdcPin);
672impl_pin!(P0_4, ADC2, Mux0, AdcPin);
673impl_pin!(P0_5, ADC2, Mux0, AdcPin);
674impl_pin!(P0_6, ADC2, Mux0, AdcPin);
675impl_pin!(P0_7, ADC2, Mux0, AdcPin);
676impl_pin!(P0_12, ADC2, Mux0, AdcPin);
677impl_pin!(P0_13, ADC2, Mux0, AdcPin);
678impl_pin!(P0_14, ADC2, Mux0, AdcPin);
679impl_pin!(P0_15, ADC2, Mux0, AdcPin);
680impl_pin!(P4_0, ADC2, Mux0, AdcPin);
681impl_pin!(P4_1, ADC2, Mux0, AdcPin);
682impl_pin!(P4_2, ADC2, Mux0, AdcPin);
683impl_pin!(P4_3, ADC2, Mux0, AdcPin);
684//impl_pin!(P4_4, ADC2, Mux0, AdcPin); // Conflit with ADC2_A3 and ADC2_A20 using the same pin
685impl_pin!(P4_5, ADC2, Mux0, AdcPin);
686impl_pin!(P4_6, ADC2, Mux0, AdcPin);
687impl_pin!(P4_7, ADC2, Mux0, AdcPin);
688
689impl_pin!(P2_5, ADC3, Mux0, AdcPin);
690impl_pin!(P2_11, ADC3, Mux0, AdcPin);
691impl_pin!(P2_23, ADC3, Mux0, AdcPin);
692impl_pin!(P2_25, ADC3, Mux0, AdcPin);
693impl_pin!(P2_17, ADC3, Mux0, AdcPin);
694impl_pin!(P2_13, ADC3, Mux0, AdcPin);
695impl_pin!(P2_21, ADC3, Mux0, AdcPin);
696impl_pin!(P2_7, ADC3, Mux0, AdcPin);
697impl_pin!(P3_2, ADC3, Mux0, AdcPin);
698impl_pin!(P3_3, ADC3, Mux0, AdcPin);
699impl_pin!(P3_4, ADC3, Mux0, AdcPin);
700impl_pin!(P3_5, ADC3, Mux0, AdcPin);
701impl_pin!(P3_6, ADC3, Mux0, AdcPin);
702impl_pin!(P3_7, ADC3, Mux0, AdcPin);
703impl_pin!(P3_12, ADC3, Mux0, AdcPin);
704impl_pin!(P3_13, ADC3, Mux0, AdcPin);
705impl_pin!(P3_14, ADC3, Mux0, AdcPin);
706impl_pin!(P3_15, ADC3, Mux0, AdcPin);
707impl_pin!(P3_20, ADC3, Mux0, AdcPin);
708impl_pin!(P3_21, ADC3, Mux0, AdcPin);
709impl_pin!(P3_22, ADC3, Mux0, AdcPin);
710impl_pin!(P3_23, ADC3, Mux0, AdcPin);
711impl_pin!(P3_24, ADC3, Mux0, AdcPin);
712impl_pin!(P3_25, ADC3, Mux0, AdcPin);