aboutsummaryrefslogtreecommitdiff
path: root/embassy-imxrt/src/gpio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-imxrt/src/gpio.rs')
-rw-r--r--embassy-imxrt/src/gpio.rs1060
1 files changed, 1060 insertions, 0 deletions
diff --git a/embassy-imxrt/src/gpio.rs b/embassy-imxrt/src/gpio.rs
new file mode 100644
index 000000000..6883c4ee0
--- /dev/null
+++ b/embassy-imxrt/src/gpio.rs
@@ -0,0 +1,1060 @@
1//! GPIO
2
3use core::convert::Infallible;
4use core::future::Future;
5use core::marker::PhantomData;
6use core::pin::Pin as FuturePin;
7use core::task::{Context, Poll};
8
9use embassy_hal_internal::interrupt::InterruptExt;
10use embassy_sync::waitqueue::AtomicWaker;
11
12use crate::clocks::enable_and_reset;
13use crate::iopctl::IopctlPin;
14pub use crate::iopctl::{AnyPin, DriveMode, DriveStrength, Function, Inverter, Pull, SlewRate};
15use crate::sealed::Sealed;
16use crate::{interrupt, peripherals, Peri, PeripheralType};
17
18// This should be unique per IMXRT package
19const PORT_COUNT: usize = 8;
20
21/// Digital input or output level.
22#[derive(Debug, Eq, PartialEq, Copy, Clone)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24pub enum Level {
25 /// Logic Low
26 Low,
27 /// Logic High
28 High,
29}
30
31impl From<bool> for Level {
32 fn from(val: bool) -> Self {
33 match val {
34 true => Self::High,
35 false => Self::Low,
36 }
37 }
38}
39
40impl From<Level> for bool {
41 fn from(level: Level) -> bool {
42 match level {
43 Level::Low => false,
44 Level::High => true,
45 }
46 }
47}
48
49/// Interrupt trigger levels.
50#[derive(Debug, Eq, PartialEq, Copy, Clone)]
51#[cfg_attr(feature = "defmt", derive(defmt::Format))]
52pub enum InterruptType {
53 /// Trigger on level.
54 Level,
55 /// Trigger on edge.
56 Edge,
57}
58
59#[cfg(feature = "rt")]
60#[interrupt]
61#[allow(non_snake_case)]
62fn GPIO_INTA() {
63 irq_handler(&GPIO_WAKERS);
64}
65
66#[cfg(feature = "rt")]
67struct BitIter(u32);
68
69#[cfg(feature = "rt")]
70impl Iterator for BitIter {
71 type Item = u32;
72
73 fn next(&mut self) -> Option<Self::Item> {
74 match self.0.trailing_zeros() {
75 32 => None,
76 b => {
77 self.0 &= !(1 << b);
78 Some(b)
79 }
80 }
81 }
82}
83
84#[cfg(feature = "rt")]
85fn irq_handler(port_wakers: &[Option<&PortWaker>]) {
86 let reg = unsafe { crate::pac::Gpio::steal() };
87
88 for (port, port_waker) in port_wakers.iter().enumerate() {
89 let Some(port_waker) = port_waker else {
90 continue;
91 };
92
93 let stat = reg.intstata(port).read().bits();
94 for pin in BitIter(stat) {
95 // Clear the interrupt from this pin
96 reg.intstata(port).write(|w| unsafe { w.status().bits(1 << pin) });
97 // Disable interrupt from this pin
98 reg.intena(port)
99 .modify(|r, w| unsafe { w.int_en().bits(r.int_en().bits() & !(1 << pin)) });
100
101 let Some(waker) = port_waker.get_waker(pin as usize) else {
102 continue;
103 };
104
105 waker.wake();
106 }
107 }
108}
109
110/// Initialization Logic
111/// Note: GPIO port clocks are initialized in the clocks module.
112pub(crate) fn init() {
113 // Enable GPIO clocks
114 enable_and_reset::<peripherals::HSGPIO0>();
115 enable_and_reset::<peripherals::HSGPIO1>();
116 enable_and_reset::<peripherals::HSGPIO2>();
117 enable_and_reset::<peripherals::HSGPIO3>();
118 enable_and_reset::<peripherals::HSGPIO4>();
119 enable_and_reset::<peripherals::HSGPIO5>();
120 enable_and_reset::<peripherals::HSGPIO6>();
121 enable_and_reset::<peripherals::HSGPIO7>();
122
123 // Enable INTA
124 interrupt::GPIO_INTA.unpend();
125
126 // SAFETY:
127 //
128 // At this point, all GPIO interrupts are masked. No interrupts
129 // will trigger until a pin is configured as Input, which can only
130 // happen after initialization of the HAL
131 unsafe { interrupt::GPIO_INTA.enable() };
132}
133
134/// Input Sense mode.
135pub trait Sense: Sealed {}
136
137/// Sense Enabled Flex pin.
138///
139/// This is a true flex pin as the input buffer is enabled.
140/// It can sense its own level when even when configured as an output pin.
141pub enum SenseEnabled {}
142impl Sealed for SenseEnabled {}
143impl Sense for SenseEnabled {}
144
145/// Sense Enabled Flex pin.
146///
147/// This is **not** a true flex pin as the input buffer is disabled.
148/// It cannot be turned into an input and it cannot see its own state, but it consumes less power.
149/// Consider using a sense enabled flex pin if you need to read the pin's state or turn this into an input,
150/// however note that **power consumption may be increased**.
151pub enum SenseDisabled {}
152impl Sealed for SenseDisabled {}
153impl Sense for SenseDisabled {}
154
155/// Flex pin.
156///
157/// This pin can be either an input or output pin. The output level register bit will
158/// remain set while not in output mode, so the pin's level will be 'remembered' when it is not in
159/// output mode.
160pub struct Flex<'d, S: Sense> {
161 pin: Peri<'d, AnyPin>,
162 _sense_mode: PhantomData<S>,
163}
164
165impl<S: Sense> Flex<'_, S> {
166 /// Converts pin to output pin
167 ///
168 /// The pin level will be whatever was set before (or low by default). If you want it to begin
169 /// at a specific level, call `set_high`/`set_low` on the pin first.
170 pub fn set_as_output(&mut self, mode: DriveMode, strength: DriveStrength, slew_rate: SlewRate) {
171 self.pin
172 .set_pull(Pull::None)
173 .set_drive_mode(mode)
174 .set_drive_strength(strength)
175 .set_slew_rate(slew_rate);
176
177 self.pin.block().dirset(self.pin.port()).write(|w|
178 // SAFETY: Writing a 0 to bits in this register has no effect,
179 // however PAC has it marked unsafe due to using the bits() method.
180 // There is not currently a "safe" method for setting a single-bit.
181 unsafe { w.dirsetp().bits(1 << self.pin.pin()) });
182 }
183
184 /// Set high
185 pub fn set_high(&mut self) {
186 self.pin.block().set(self.pin.port()).write(|w|
187 // SAFETY: Writing a 0 to bits in this register has no effect,
188 // however PAC has it marked unsafe due to using the bits() method.
189 // There is not currently a "safe" method for setting a single-bit.
190 unsafe { w.setp().bits(1 << self.pin.pin()) });
191 }
192
193 /// Set low
194 pub fn set_low(&mut self) {
195 self.pin.block().clr(self.pin.port()).write(|w|
196 // SAFETY: Writing a 0 to bits in this register has no effect,
197 // however PAC has it marked unsafe due to using the bits() method.
198 // There is not currently a "safe" method for setting a single-bit.
199 unsafe { w.clrp().bits(1 << self.pin.pin()) });
200 }
201
202 /// Set level
203 pub fn set_level(&mut self, level: Level) {
204 match level {
205 Level::High => self.set_high(),
206 Level::Low => self.set_low(),
207 }
208 }
209
210 /// Is the output level high?
211 #[must_use]
212 pub fn is_set_high(&self) -> bool {
213 !self.is_set_low()
214 }
215
216 /// Is the output level low?
217 #[must_use]
218 pub fn is_set_low(&self) -> bool {
219 (self.pin.block().set(self.pin.port()).read().setp().bits() & (1 << self.pin.pin())) == 0
220 }
221
222 /// Toggle
223 pub fn toggle(&mut self) {
224 self.pin.block().not(self.pin.port()).write(|w|
225 // SAFETY: Writing a 0 to bits in this register has no effect,
226 // however PAC has it marked unsafe due to using the bits() method.
227 // There is not currently a "safe" method for setting a single-bit.
228 unsafe { w.notp().bits(1 << self.pin.pin()) });
229 }
230}
231
232impl<S: Sense> Drop for Flex<'_, S> {
233 #[inline]
234 fn drop(&mut self) {
235 critical_section::with(|_| {
236 self.pin.reset();
237 });
238 }
239}
240
241impl<'d> Flex<'d, SenseEnabled> {
242 /// New flex pin.
243 pub fn new_with_sense(pin: Peri<'d, impl GpioPin>) -> Self {
244 pin.set_function(Function::F0)
245 .disable_analog_multiplex()
246 .enable_input_buffer();
247
248 Self {
249 pin: pin.into(),
250 _sense_mode: PhantomData::<SenseEnabled>,
251 }
252 }
253
254 /// Converts pin to input pin
255 pub fn set_as_input(&mut self, pull: Pull, inverter: Inverter) {
256 self.pin.set_pull(pull).set_input_inverter(inverter);
257
258 self.pin.block().dirclr(self.pin.port()).write(|w|
259 // SAFETY: Writing a 0 to bits in this register has no effect,
260 // however PAC has it marked unsafe due to using the bits() method.
261 // There is not currently a "safe" method for setting a single-bit.
262 unsafe { w.dirclrp().bits(1 << self.pin.pin()) });
263 }
264
265 /// Converts pin to special function pin
266 /// # Safety
267 /// Unsafe to require justifying change from default to a special function
268 ///
269 pub unsafe fn set_as_special_function(&mut self, func: Function) {
270 self.pin.set_function(func);
271 }
272
273 /// Is high?
274 #[must_use]
275 pub fn is_high(&self) -> bool {
276 !self.is_low()
277 }
278
279 /// Is low?
280 #[must_use]
281 pub fn is_low(&self) -> bool {
282 self.pin.block().b(self.pin.port()).b_(self.pin.pin()).read() == 0
283 }
284
285 /// Current level
286 #[must_use]
287 pub fn get_level(&self) -> Level {
288 self.is_high().into()
289 }
290
291 /// Wait until the pin is high. If it is already high, return immediately.
292 #[inline]
293 pub async fn wait_for_high(&mut self) {
294 InputFuture::new(self.pin.reborrow(), InterruptType::Level, Level::High).await;
295 }
296
297 /// Wait until the pin is low. If it is already low, return immediately.
298 #[inline]
299 pub async fn wait_for_low(&mut self) {
300 InputFuture::new(self.pin.reborrow(), InterruptType::Level, Level::Low).await;
301 }
302
303 /// Wait for the pin to undergo a transition from low to high.
304 #[inline]
305 pub async fn wait_for_rising_edge(&mut self) {
306 InputFuture::new(self.pin.reborrow(), InterruptType::Edge, Level::High).await;
307 }
308
309 /// Wait for the pin to undergo a transition from high to low.
310 #[inline]
311 pub async fn wait_for_falling_edge(&mut self) {
312 InputFuture::new(self.pin.reborrow(), InterruptType::Edge, Level::Low).await;
313 }
314
315 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
316 #[inline]
317 pub async fn wait_for_any_edge(&mut self) {
318 if self.is_high() {
319 InputFuture::new(self.pin.reborrow(), InterruptType::Edge, Level::Low).await;
320 } else {
321 InputFuture::new(self.pin.reborrow(), InterruptType::Edge, Level::High).await;
322 }
323 }
324
325 /// Return a new Flex pin instance with level sensing disabled.
326 ///
327 /// Consumes less power than a flex pin with sensing enabled.
328 #[must_use]
329 pub fn disable_sensing(self) -> Flex<'d, SenseDisabled> {
330 // Cloning the pin is ok since we consume self immediately
331 let new_pin = unsafe { self.pin.clone_unchecked() };
332 drop(self);
333 Flex::<SenseDisabled>::new(new_pin)
334 }
335}
336
337impl<'d> Flex<'d, SenseDisabled> {
338 /// New flex pin.
339 pub fn new(pin: Peri<'d, impl GpioPin>) -> Self {
340 pin.set_function(Function::F0)
341 .disable_analog_multiplex()
342 .disable_input_buffer();
343
344 Self {
345 pin: pin.into(),
346 _sense_mode: PhantomData::<SenseDisabled>,
347 }
348 }
349
350 /// Return a new Flex pin instance with level sensing enabled.
351 #[must_use]
352 pub fn enable_sensing(self) -> Flex<'d, SenseEnabled> {
353 // Cloning the pin is ok since we consume self immediately
354 let new_pin = unsafe { self.pin.clone_unchecked() };
355 drop(self);
356 Flex::new_with_sense(new_pin)
357 }
358}
359
360/// Input pin
361pub struct Input<'d> {
362 // When Input is dropped, Flex's drop() will make sure the pin is reset to its default state.
363 pin: Flex<'d, SenseEnabled>,
364}
365
366impl<'d> Input<'d> {
367 /// New input pin
368 pub fn new(pin: Peri<'d, impl GpioPin>, pull: Pull, inverter: Inverter) -> Self {
369 let mut pin = Flex::new_with_sense(pin);
370 pin.set_as_input(pull, inverter);
371 Self { pin }
372 }
373
374 /// Is high?
375 #[must_use]
376 pub fn is_high(&self) -> bool {
377 self.pin.is_high()
378 }
379
380 /// Is low?
381 #[must_use]
382 pub fn is_low(&self) -> bool {
383 self.pin.is_low()
384 }
385
386 /// Input level
387 #[must_use]
388 pub fn get_level(&self) -> Level {
389 self.pin.get_level()
390 }
391
392 /// Wait until the pin is high. If it is already high, return immediately.
393 #[inline]
394 pub async fn wait_for_high(&mut self) {
395 self.pin.wait_for_high().await;
396 }
397
398 /// Wait until the pin is low. If it is already low, return immediately.
399 #[inline]
400 pub async fn wait_for_low(&mut self) {
401 self.pin.wait_for_low().await;
402 }
403
404 /// Wait for the pin to undergo a transition from low to high.
405 #[inline]
406 pub async fn wait_for_rising_edge(&mut self) {
407 self.pin.wait_for_rising_edge().await;
408 }
409
410 /// Wait for the pin to undergo a transition from high to low.
411 #[inline]
412 pub async fn wait_for_falling_edge(&mut self) {
413 self.pin.wait_for_falling_edge().await;
414 }
415
416 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
417 #[inline]
418 pub async fn wait_for_any_edge(&mut self) {
419 self.pin.wait_for_any_edge().await;
420 }
421}
422
423#[must_use = "futures do nothing unless you `.await` or poll them"]
424struct InputFuture<'d> {
425 pin: Peri<'d, AnyPin>,
426}
427
428impl<'d> InputFuture<'d> {
429 fn new(pin: Peri<'d, impl GpioPin>, int_type: InterruptType, level: Level) -> Self {
430 critical_section::with(|_| {
431 // Clear any existing pending interrupt on this pin
432 pin.block()
433 .intstata(pin.port())
434 .write(|w| unsafe { w.status().bits(1 << pin.pin()) });
435
436 /* Pin interrupt configuration */
437 pin.block().intedg(pin.port()).modify(|r, w| match int_type {
438 InterruptType::Edge => unsafe { w.bits(r.bits() | (1 << pin.pin())) },
439 InterruptType::Level => unsafe { w.bits(r.bits() & !(1 << pin.pin())) },
440 });
441
442 pin.block().intpol(pin.port()).modify(|r, w| match level {
443 Level::High => unsafe { w.bits(r.bits() & !(1 << pin.pin())) },
444 Level::Low => unsafe { w.bits(r.bits() | (1 << pin.pin())) },
445 });
446
447 // Enable pin interrupt on GPIO INT A
448 pin.block()
449 .intena(pin.port())
450 .modify(|r, w| unsafe { w.int_en().bits(r.int_en().bits() | (1 << pin.pin())) });
451 });
452
453 Self { pin: pin.into() }
454 }
455}
456
457impl Future for InputFuture<'_> {
458 type Output = ();
459
460 fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
461 // We need to register/re-register the waker for each poll because any
462 // calls to wake will deregister the waker.
463 if self.pin.port() >= GPIO_WAKERS.len() {
464 panic!("Invalid GPIO port index {}", self.pin.port());
465 }
466
467 let port_waker = GPIO_WAKERS[self.pin.port()];
468 if port_waker.is_none() {
469 panic!("Waker not present for GPIO port {}", self.pin.port());
470 }
471
472 let waker = port_waker.unwrap().get_waker(self.pin.pin());
473 if waker.is_none() {
474 panic!(
475 "Waker not present for GPIO pin {}, port {}",
476 self.pin.pin(),
477 self.pin.port()
478 );
479 }
480 waker.unwrap().register(cx.waker());
481
482 // Double check that the pin interrut has been disabled by IRQ handler
483 if self.pin.block().intena(self.pin.port()).read().bits() & (1 << self.pin.pin()) == 0 {
484 Poll::Ready(())
485 } else {
486 Poll::Pending
487 }
488 }
489}
490
491/// Output pin
492/// Cannot be set as an input and cannot read its own pin state!
493/// Consider using a Flex pin if you want that functionality, at the cost of higher power consumption.
494pub struct Output<'d> {
495 // When Output is dropped, Flex's drop() will make sure the pin is reset to its default state.
496 pin: Flex<'d, SenseDisabled>,
497}
498
499impl<'d> Output<'d> {
500 /// New output pin
501 pub fn new(
502 pin: Peri<'d, impl GpioPin>,
503 initial_output: Level,
504 mode: DriveMode,
505 strength: DriveStrength,
506 slew_rate: SlewRate,
507 ) -> Self {
508 let mut pin = Flex::new(pin);
509 pin.set_level(initial_output);
510 pin.set_as_output(mode, strength, slew_rate);
511
512 Self { pin }
513 }
514
515 /// Set high
516 pub fn set_high(&mut self) {
517 self.pin.set_high();
518 }
519
520 /// Set low
521 pub fn set_low(&mut self) {
522 self.pin.set_low();
523 }
524
525 /// Toggle
526 pub fn toggle(&mut self) {
527 self.pin.toggle();
528 }
529
530 /// Set level
531 pub fn set_level(&mut self, level: Level) {
532 self.pin.set_level(level);
533 }
534
535 /// Is set high?
536 #[must_use]
537 pub fn is_set_high(&self) -> bool {
538 self.pin.is_set_high()
539 }
540
541 /// Is set low?
542 #[must_use]
543 pub fn is_set_low(&self) -> bool {
544 self.pin.is_set_low()
545 }
546}
547
548trait SealedPin: IopctlPin {
549 fn pin_port(&self) -> usize;
550
551 fn port(&self) -> usize {
552 self.pin_port() / 32
553 }
554
555 fn pin(&self) -> usize {
556 self.pin_port() % 32
557 }
558
559 fn block(&self) -> crate::pac::Gpio {
560 // SAFETY: Assuming GPIO pin specific registers are only accessed through this HAL,
561 // this is safe because the HAL ensures ownership or exclusive mutable references
562 // to pins.
563 unsafe { crate::pac::Gpio::steal() }
564 }
565}
566
567/// GPIO pin trait.
568#[allow(private_bounds)]
569pub trait GpioPin: SealedPin + Sized + PeripheralType + Into<AnyPin> + 'static {
570 /// Type-erase the pin.
571 fn degrade(self) -> AnyPin {
572 // SAFETY: This is only called within the GpioPin trait, which is only
573 // implemented within this module on valid pin peripherals and thus
574 // has been verified to be correct.
575 unsafe { AnyPin::steal(self.port() as u8, self.pin() as u8) }
576 }
577}
578
579impl SealedPin for AnyPin {
580 fn pin_port(&self) -> usize {
581 self.pin_port()
582 }
583}
584impl GpioPin for AnyPin {}
585
586macro_rules! impl_pin {
587 ($pin_periph:ident, $pin_port:expr, $pin_no:expr) => {
588 impl SealedPin for crate::peripherals::$pin_periph {
589 fn pin_port(&self) -> usize {
590 $pin_port * 32 + $pin_no
591 }
592 }
593 impl GpioPin for crate::peripherals::$pin_periph {}
594 impl From<crate::peripherals::$pin_periph> for AnyPin {
595 fn from(value: crate::peripherals::$pin_periph) -> Self {
596 value.degrade()
597 }
598 }
599 };
600}
601
602/// Container for pin wakers
603struct PortWaker {
604 offset: usize,
605 wakers: &'static [AtomicWaker],
606}
607
608impl PortWaker {
609 fn get_waker(&self, pin: usize) -> Option<&AtomicWaker> {
610 self.wakers.get(pin - self.offset)
611 }
612}
613
614macro_rules! define_port_waker {
615 ($name:ident, $start:expr, $end:expr) => {
616 mod $name {
617 static PIN_WAKERS: [super::AtomicWaker; $end - $start + 1] =
618 [const { super::AtomicWaker::new() }; $end - $start + 1];
619 pub static WAKER: super::PortWaker = super::PortWaker {
620 offset: $start,
621 wakers: &PIN_WAKERS,
622 };
623 }
624 };
625}
626
627// GPIO port 0
628define_port_waker!(port0_waker, 0, 31);
629impl_pin!(PIO0_0, 0, 0);
630impl_pin!(PIO0_1, 0, 1);
631impl_pin!(PIO0_2, 0, 2);
632impl_pin!(PIO0_3, 0, 3);
633impl_pin!(PIO0_4, 0, 4);
634impl_pin!(PIO0_5, 0, 5);
635impl_pin!(PIO0_6, 0, 6);
636impl_pin!(PIO0_7, 0, 7);
637impl_pin!(PIO0_8, 0, 8);
638impl_pin!(PIO0_9, 0, 9);
639impl_pin!(PIO0_10, 0, 10);
640impl_pin!(PIO0_11, 0, 11);
641impl_pin!(PIO0_12, 0, 12);
642impl_pin!(PIO0_13, 0, 13);
643impl_pin!(PIO0_14, 0, 14);
644impl_pin!(PIO0_15, 0, 15);
645impl_pin!(PIO0_16, 0, 16);
646impl_pin!(PIO0_17, 0, 17);
647impl_pin!(PIO0_18, 0, 18);
648impl_pin!(PIO0_19, 0, 19);
649impl_pin!(PIO0_20, 0, 20);
650impl_pin!(PIO0_21, 0, 21);
651impl_pin!(PIO0_22, 0, 22);
652impl_pin!(PIO0_23, 0, 23);
653impl_pin!(PIO0_24, 0, 24);
654impl_pin!(PIO0_25, 0, 25);
655impl_pin!(PIO0_26, 0, 26);
656impl_pin!(PIO0_27, 0, 27);
657impl_pin!(PIO0_28, 0, 28);
658impl_pin!(PIO0_29, 0, 29);
659impl_pin!(PIO0_30, 0, 30);
660impl_pin!(PIO0_31, 0, 31);
661
662// GPIO port 1
663define_port_waker!(port1_waker, 0, 31);
664impl_pin!(PIO1_0, 1, 0);
665impl_pin!(PIO1_1, 1, 1);
666impl_pin!(PIO1_2, 1, 2);
667impl_pin!(PIO1_3, 1, 3);
668impl_pin!(PIO1_4, 1, 4);
669impl_pin!(PIO1_5, 1, 5);
670impl_pin!(PIO1_6, 1, 6);
671impl_pin!(PIO1_7, 1, 7);
672impl_pin!(PIO1_8, 1, 8);
673impl_pin!(PIO1_9, 1, 9);
674impl_pin!(PIO1_10, 1, 10);
675impl_pin!(PIO1_11, 1, 11);
676impl_pin!(PIO1_12, 1, 12);
677impl_pin!(PIO1_13, 1, 13);
678impl_pin!(PIO1_14, 1, 14);
679impl_pin!(PIO1_15, 1, 15);
680impl_pin!(PIO1_16, 1, 16);
681impl_pin!(PIO1_17, 1, 17);
682impl_pin!(PIO1_18, 1, 18);
683impl_pin!(PIO1_19, 1, 19);
684impl_pin!(PIO1_20, 1, 20);
685impl_pin!(PIO1_21, 1, 21);
686impl_pin!(PIO1_22, 1, 22);
687impl_pin!(PIO1_23, 1, 23);
688impl_pin!(PIO1_24, 1, 24);
689impl_pin!(PIO1_25, 1, 25);
690impl_pin!(PIO1_26, 1, 26);
691impl_pin!(PIO1_27, 1, 27);
692impl_pin!(PIO1_28, 1, 28);
693impl_pin!(PIO1_29, 1, 29);
694impl_pin!(PIO1_30, 1, 30);
695impl_pin!(PIO1_31, 1, 31);
696
697// GPIO port 2
698define_port_waker!(port2_waker, 0, 31);
699impl_pin!(PIO2_0, 2, 0);
700impl_pin!(PIO2_1, 2, 1);
701impl_pin!(PIO2_2, 2, 2);
702impl_pin!(PIO2_3, 2, 3);
703impl_pin!(PIO2_4, 2, 4);
704impl_pin!(PIO2_5, 2, 5);
705impl_pin!(PIO2_6, 2, 6);
706impl_pin!(PIO2_7, 2, 7);
707impl_pin!(PIO2_8, 2, 8);
708impl_pin!(PIO2_9, 2, 9);
709impl_pin!(PIO2_10, 2, 10);
710impl_pin!(PIO2_11, 2, 11);
711impl_pin!(PIO2_12, 2, 12);
712impl_pin!(PIO2_13, 2, 13);
713impl_pin!(PIO2_14, 2, 14);
714impl_pin!(PIO2_15, 2, 15);
715impl_pin!(PIO2_16, 2, 16);
716impl_pin!(PIO2_17, 2, 17);
717impl_pin!(PIO2_18, 2, 18);
718impl_pin!(PIO2_19, 2, 19);
719impl_pin!(PIO2_20, 2, 20);
720impl_pin!(PIO2_21, 2, 21);
721impl_pin!(PIO2_22, 2, 22);
722impl_pin!(PIO2_23, 2, 23);
723impl_pin!(PIO2_24, 2, 24);
724impl_pin!(PIO2_25, 2, 25);
725impl_pin!(PIO2_26, 2, 26);
726impl_pin!(PIO2_27, 2, 27);
727impl_pin!(PIO2_28, 2, 28);
728impl_pin!(PIO2_29, 2, 29);
729impl_pin!(PIO2_30, 2, 30);
730impl_pin!(PIO2_31, 2, 31);
731
732// GPIO port 3
733define_port_waker!(port3_waker, 0, 31);
734impl_pin!(PIO3_0, 3, 0);
735impl_pin!(PIO3_1, 3, 1);
736impl_pin!(PIO3_2, 3, 2);
737impl_pin!(PIO3_3, 3, 3);
738impl_pin!(PIO3_4, 3, 4);
739impl_pin!(PIO3_5, 3, 5);
740impl_pin!(PIO3_6, 3, 6);
741impl_pin!(PIO3_7, 3, 7);
742impl_pin!(PIO3_8, 3, 8);
743impl_pin!(PIO3_9, 3, 9);
744impl_pin!(PIO3_10, 3, 10);
745impl_pin!(PIO3_11, 3, 11);
746impl_pin!(PIO3_12, 3, 12);
747impl_pin!(PIO3_13, 3, 13);
748impl_pin!(PIO3_14, 3, 14);
749impl_pin!(PIO3_15, 3, 15);
750impl_pin!(PIO3_16, 3, 16);
751impl_pin!(PIO3_17, 3, 17);
752impl_pin!(PIO3_18, 3, 18);
753impl_pin!(PIO3_19, 3, 19);
754impl_pin!(PIO3_20, 3, 20);
755impl_pin!(PIO3_21, 3, 21);
756impl_pin!(PIO3_22, 3, 22);
757impl_pin!(PIO3_23, 3, 23);
758impl_pin!(PIO3_24, 3, 24);
759impl_pin!(PIO3_25, 3, 25);
760impl_pin!(PIO3_26, 3, 26);
761impl_pin!(PIO3_27, 3, 27);
762impl_pin!(PIO3_28, 3, 28);
763impl_pin!(PIO3_29, 3, 29);
764impl_pin!(PIO3_30, 3, 30);
765impl_pin!(PIO3_31, 3, 31);
766
767// GPIO port 4
768define_port_waker!(port4_waker, 0, 10);
769impl_pin!(PIO4_0, 4, 0);
770impl_pin!(PIO4_1, 4, 1);
771impl_pin!(PIO4_2, 4, 2);
772impl_pin!(PIO4_3, 4, 3);
773impl_pin!(PIO4_4, 4, 4);
774impl_pin!(PIO4_5, 4, 5);
775impl_pin!(PIO4_6, 4, 6);
776impl_pin!(PIO4_7, 4, 7);
777impl_pin!(PIO4_8, 4, 8);
778impl_pin!(PIO4_9, 4, 9);
779impl_pin!(PIO4_10, 4, 10);
780
781// GPIO port 7
782define_port_waker!(port7_waker, 24, 31);
783impl_pin!(PIO7_24, 7, 24);
784impl_pin!(PIO7_25, 7, 25);
785impl_pin!(PIO7_26, 7, 26);
786impl_pin!(PIO7_27, 7, 27);
787impl_pin!(PIO7_28, 7, 28);
788impl_pin!(PIO7_29, 7, 29);
789impl_pin!(PIO7_30, 7, 30);
790impl_pin!(PIO7_31, 7, 31);
791
792static GPIO_WAKERS: [Option<&PortWaker>; PORT_COUNT] = [
793 Some(&port0_waker::WAKER),
794 Some(&port1_waker::WAKER),
795 Some(&port2_waker::WAKER),
796 Some(&port3_waker::WAKER),
797 Some(&port4_waker::WAKER),
798 None,
799 None,
800 Some(&port7_waker::WAKER),
801];
802
803impl embedded_hal_02::digital::v2::InputPin for Flex<'_, SenseEnabled> {
804 type Error = Infallible;
805
806 #[inline]
807 fn is_high(&self) -> Result<bool, Self::Error> {
808 Ok(self.is_high())
809 }
810
811 #[inline]
812 fn is_low(&self) -> Result<bool, Self::Error> {
813 Ok(self.is_low())
814 }
815}
816
817impl<S: Sense> embedded_hal_02::digital::v2::OutputPin for Flex<'_, S> {
818 type Error = Infallible;
819
820 #[inline]
821 fn set_high(&mut self) -> Result<(), Self::Error> {
822 self.set_high();
823 Ok(())
824 }
825
826 #[inline]
827 fn set_low(&mut self) -> Result<(), Self::Error> {
828 self.set_low();
829 Ok(())
830 }
831}
832
833impl embedded_hal_02::digital::v2::StatefulOutputPin for Flex<'_, SenseEnabled> {
834 #[inline]
835 fn is_set_high(&self) -> Result<bool, Self::Error> {
836 Ok(self.is_set_high())
837 }
838
839 #[inline]
840 fn is_set_low(&self) -> Result<bool, Self::Error> {
841 Ok(self.is_set_low())
842 }
843}
844
845impl<S: Sense> embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'_, S> {
846 type Error = Infallible;
847
848 #[inline]
849 fn toggle(&mut self) -> Result<(), Self::Error> {
850 self.toggle();
851 Ok(())
852 }
853}
854
855impl embedded_hal_02::digital::v2::InputPin for Input<'_> {
856 type Error = Infallible;
857
858 #[inline]
859 fn is_high(&self) -> Result<bool, Self::Error> {
860 Ok(self.is_high())
861 }
862
863 #[inline]
864 fn is_low(&self) -> Result<bool, Self::Error> {
865 Ok(self.is_low())
866 }
867}
868
869impl embedded_hal_02::digital::v2::OutputPin for Output<'_> {
870 type Error = Infallible;
871
872 #[inline]
873 fn set_high(&mut self) -> Result<(), Self::Error> {
874 self.set_high();
875 Ok(())
876 }
877
878 #[inline]
879 fn set_low(&mut self) -> Result<(), Self::Error> {
880 self.set_low();
881 Ok(())
882 }
883}
884
885impl embedded_hal_02::digital::v2::StatefulOutputPin for Output<'_> {
886 #[inline]
887 fn is_set_high(&self) -> Result<bool, Self::Error> {
888 Ok(self.is_set_high())
889 }
890
891 #[inline]
892 fn is_set_low(&self) -> Result<bool, Self::Error> {
893 Ok(self.is_set_low())
894 }
895}
896
897impl embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'_> {
898 type Error = Infallible;
899
900 #[inline]
901 fn toggle(&mut self) -> Result<(), Self::Error> {
902 self.toggle();
903 Ok(())
904 }
905}
906
907impl<S: Sense> embedded_hal_1::digital::ErrorType for Flex<'_, S> {
908 type Error = Infallible;
909}
910
911impl embedded_hal_1::digital::InputPin for Flex<'_, SenseEnabled> {
912 #[inline]
913 fn is_high(&mut self) -> Result<bool, Self::Error> {
914 // Dereference of self is used here and a few other places to
915 // access the correct method (since different types/traits
916 // share method names)
917 Ok((*self).is_high())
918 }
919
920 #[inline]
921 fn is_low(&mut self) -> Result<bool, Self::Error> {
922 Ok((*self).is_low())
923 }
924}
925
926impl<S: Sense> embedded_hal_1::digital::OutputPin for Flex<'_, S> {
927 #[inline]
928 fn set_high(&mut self) -> Result<(), Self::Error> {
929 self.set_high();
930 Ok(())
931 }
932
933 #[inline]
934 fn set_low(&mut self) -> Result<(), Self::Error> {
935 self.set_low();
936 Ok(())
937 }
938}
939
940impl embedded_hal_1::digital::StatefulOutputPin for Flex<'_, SenseEnabled> {
941 #[inline]
942 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
943 Ok((*self).is_set_high())
944 }
945
946 #[inline]
947 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
948 Ok((*self).is_set_low())
949 }
950}
951
952impl<'d> embedded_hal_async::digital::Wait for Flex<'d, SenseEnabled> {
953 #[inline]
954 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
955 self.wait_for_high().await;
956 Ok(())
957 }
958
959 #[inline]
960 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
961 self.wait_for_low().await;
962 Ok(())
963 }
964
965 #[inline]
966 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
967 self.wait_for_rising_edge().await;
968 Ok(())
969 }
970
971 #[inline]
972 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
973 self.wait_for_falling_edge().await;
974 Ok(())
975 }
976
977 #[inline]
978 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
979 self.wait_for_any_edge().await;
980 Ok(())
981 }
982}
983
984impl embedded_hal_1::digital::ErrorType for Input<'_> {
985 type Error = Infallible;
986}
987
988impl embedded_hal_1::digital::InputPin for Input<'_> {
989 #[inline]
990 fn is_high(&mut self) -> Result<bool, Self::Error> {
991 Ok((*self).is_high())
992 }
993
994 #[inline]
995 fn is_low(&mut self) -> Result<bool, Self::Error> {
996 Ok((*self).is_low())
997 }
998}
999
1000impl<'d> embedded_hal_async::digital::Wait for Input<'d> {
1001 #[inline]
1002 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
1003 self.wait_for_high().await;
1004 Ok(())
1005 }
1006
1007 #[inline]
1008 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
1009 self.wait_for_low().await;
1010 Ok(())
1011 }
1012
1013 #[inline]
1014 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
1015 self.wait_for_rising_edge().await;
1016 Ok(())
1017 }
1018
1019 #[inline]
1020 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
1021 self.wait_for_falling_edge().await;
1022 Ok(())
1023 }
1024
1025 #[inline]
1026 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
1027 self.wait_for_any_edge().await;
1028 Ok(())
1029 }
1030}
1031
1032impl embedded_hal_1::digital::ErrorType for Output<'_> {
1033 type Error = Infallible;
1034}
1035
1036impl embedded_hal_1::digital::OutputPin for Output<'_> {
1037 #[inline]
1038 fn set_high(&mut self) -> Result<(), Self::Error> {
1039 self.set_high();
1040 Ok(())
1041 }
1042
1043 #[inline]
1044 fn set_low(&mut self) -> Result<(), Self::Error> {
1045 self.set_low();
1046 Ok(())
1047 }
1048}
1049
1050impl embedded_hal_1::digital::StatefulOutputPin for Output<'_> {
1051 #[inline]
1052 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1053 Ok((*self).is_set_high())
1054 }
1055
1056 #[inline]
1057 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1058 Ok((*self).is_set_low())
1059 }
1060}