aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa/src/gpio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mcxa/src/gpio.rs')
-rw-r--r--embassy-mcxa/src/gpio.rs1062
1 files changed, 1062 insertions, 0 deletions
diff --git a/embassy-mcxa/src/gpio.rs b/embassy-mcxa/src/gpio.rs
new file mode 100644
index 000000000..65f8df985
--- /dev/null
+++ b/embassy-mcxa/src/gpio.rs
@@ -0,0 +1,1062 @@
1//! GPIO driver built around a type-erased `Flex` pin, similar to other Embassy HALs.
2//! The exported `Output`/`Input` drivers own a `Flex` so they no longer depend on the
3//! concrete pin type.
4
5use core::convert::Infallible;
6use core::future::Future;
7use core::marker::PhantomData;
8use core::pin::pin;
9
10use embassy_hal_internal::{Peri, PeripheralType};
11use maitake_sync::WaitMap;
12use paste::paste;
13
14use crate::pac::interrupt;
15use crate::pac::port0::pcr0::{Dse, Inv, Mux, Pe, Ps, Sre};
16
17struct BitIter(u32);
18
19impl Iterator for BitIter {
20 type Item = usize;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 match self.0.trailing_zeros() {
24 32 => None,
25 b => {
26 self.0 &= !(1 << b);
27 Some(b as usize)
28 }
29 }
30 }
31}
32
33const PORT_COUNT: usize = 5;
34
35static PORT_WAIT_MAPS: [WaitMap<usize, ()>; PORT_COUNT] = [
36 WaitMap::new(),
37 WaitMap::new(),
38 WaitMap::new(),
39 WaitMap::new(),
40 WaitMap::new(),
41];
42
43fn irq_handler(port_index: usize, gpio_base: *const crate::pac::gpio0::RegisterBlock) {
44 let gpio = unsafe { &*gpio_base };
45 let isfr = gpio.isfr0().read().bits();
46
47 for pin in BitIter(isfr) {
48 // Clear all pending interrupts
49 gpio.isfr0().write(|w| unsafe { w.bits(1 << pin) });
50 gpio.icr(pin).modify(|_, w| w.irqc().irqc0()); // Disable interrupt
51
52 // Wake the corresponding port waker
53 if let Some(w) = PORT_WAIT_MAPS.get(port_index) {
54 w.wake(&pin, ());
55 }
56 }
57}
58
59#[interrupt]
60fn GPIO0() {
61 irq_handler(0, crate::pac::Gpio0::ptr());
62}
63
64#[interrupt]
65fn GPIO1() {
66 irq_handler(1, crate::pac::Gpio1::ptr());
67}
68
69#[interrupt]
70fn GPIO2() {
71 irq_handler(2, crate::pac::Gpio2::ptr());
72}
73
74#[interrupt]
75fn GPIO3() {
76 irq_handler(3, crate::pac::Gpio3::ptr());
77}
78
79#[interrupt]
80fn GPIO4() {
81 irq_handler(4, crate::pac::Gpio4::ptr());
82}
83
84pub(crate) unsafe fn init() {
85 use embassy_hal_internal::interrupt::InterruptExt;
86
87 crate::pac::interrupt::GPIO0.enable();
88 crate::pac::interrupt::GPIO1.enable();
89 crate::pac::interrupt::GPIO2.enable();
90 crate::pac::interrupt::GPIO3.enable();
91 crate::pac::interrupt::GPIO4.enable();
92
93 cortex_m::interrupt::enable();
94}
95
96/// Logical level for GPIO pins.
97#[derive(Copy, Clone, Eq, PartialEq, Debug)]
98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
99pub enum Level {
100 Low,
101 High,
102}
103
104impl From<bool> for Level {
105 fn from(val: bool) -> Self {
106 match val {
107 true => Self::High,
108 false => Self::Low,
109 }
110 }
111}
112
113#[derive(Copy, Clone, Eq, PartialEq, Debug)]
114pub enum Pull {
115 Disabled,
116 Up,
117 Down,
118}
119
120impl From<Pull> for (Pe, Ps) {
121 fn from(pull: Pull) -> Self {
122 match pull {
123 Pull::Disabled => (Pe::Pe0, Ps::Ps0),
124 Pull::Up => (Pe::Pe1, Ps::Ps1),
125 Pull::Down => (Pe::Pe1, Ps::Ps0),
126 }
127 }
128}
129
130#[derive(Copy, Clone, Eq, PartialEq, Debug)]
131pub enum SlewRate {
132 Fast,
133 Slow,
134}
135
136impl From<SlewRate> for Sre {
137 fn from(slew_rate: SlewRate) -> Self {
138 match slew_rate {
139 SlewRate::Fast => Sre::Sre0,
140 SlewRate::Slow => Sre::Sre1,
141 }
142 }
143}
144
145#[derive(Copy, Clone, Eq, PartialEq, Debug)]
146pub enum DriveStrength {
147 Normal,
148 Double,
149}
150
151impl From<DriveStrength> for Dse {
152 fn from(strength: DriveStrength) -> Self {
153 match strength {
154 DriveStrength::Normal => Dse::Dse0,
155 DriveStrength::Double => Dse::Dse1,
156 }
157 }
158}
159
160#[derive(Copy, Clone, Eq, PartialEq, Debug)]
161pub enum Inverter {
162 Disabled,
163 Enabled,
164}
165
166impl From<Inverter> for Inv {
167 fn from(strength: Inverter) -> Self {
168 match strength {
169 Inverter::Disabled => Inv::Inv0,
170 Inverter::Enabled => Inv::Inv1,
171 }
172 }
173}
174
175pub type Gpio = crate::peripherals::GPIO0;
176
177/// Type-erased representation of a GPIO pin.
178pub struct AnyPin {
179 port: usize,
180 pin: usize,
181 gpio: &'static crate::pac::gpio0::RegisterBlock,
182 port_reg: &'static crate::pac::port0::RegisterBlock,
183 pcr_reg: &'static crate::pac::port0::Pcr0,
184}
185
186impl AnyPin {
187 /// Create an `AnyPin` from raw components.
188 fn new(
189 port: usize,
190 pin: usize,
191 gpio: &'static crate::pac::gpio0::RegisterBlock,
192 port_reg: &'static crate::pac::port0::RegisterBlock,
193 pcr_reg: &'static crate::pac::port0::Pcr0,
194 ) -> Self {
195 Self {
196 port,
197 pin,
198 gpio,
199 port_reg,
200 pcr_reg,
201 }
202 }
203
204 #[inline(always)]
205 fn mask(&self) -> u32 {
206 1 << self.pin
207 }
208
209 #[inline(always)]
210 fn gpio(&self) -> &'static crate::pac::gpio0::RegisterBlock {
211 self.gpio
212 }
213
214 #[inline(always)]
215 pub fn port_index(&self) -> usize {
216 self.port
217 }
218
219 #[inline(always)]
220 pub fn pin_index(&self) -> usize {
221 self.pin
222 }
223
224 #[inline(always)]
225 fn port_reg(&self) -> &'static crate::pac::port0::RegisterBlock {
226 self.port_reg
227 }
228
229 #[inline(always)]
230 fn pcr_reg(&self) -> &'static crate::pac::port0::Pcr0 {
231 self.pcr_reg
232 }
233}
234
235embassy_hal_internal::impl_peripheral!(AnyPin);
236
237pub(crate) trait SealedPin {
238 fn pin_port(&self) -> usize;
239
240 fn port(&self) -> usize {
241 self.pin_port() / 32
242 }
243
244 fn pin(&self) -> usize {
245 self.pin_port() % 32
246 }
247
248 fn gpio(&self) -> &'static crate::pac::gpio0::RegisterBlock;
249
250 fn port_reg(&self) -> &'static crate::pac::port0::RegisterBlock;
251
252 fn pcr_reg(&self) -> &'static crate::pac::port0::Pcr0;
253
254 fn set_function(&self, function: Mux);
255
256 fn set_pull(&self, pull: Pull);
257
258 fn set_drive_strength(&self, strength: Dse);
259
260 fn set_slew_rate(&self, slew_rate: Sre);
261
262 fn set_enable_input_buffer(&self);
263}
264
265/// GPIO pin trait.
266#[allow(private_bounds)]
267pub trait GpioPin: SealedPin + Sized + PeripheralType + Into<AnyPin> + 'static {
268 /// Type-erase the pin.
269 fn degrade(self) -> AnyPin {
270 // SAFETY: This is only called within the GpioPin trait, which is only
271 // implemented within this module on valid pin peripherals and thus
272 // has been verified to be correct.
273 AnyPin::new(self.port(), self.pin(), self.gpio(), self.port_reg(), self.pcr_reg())
274 }
275}
276
277impl SealedPin for AnyPin {
278 fn pin_port(&self) -> usize {
279 self.port * 32 + self.pin
280 }
281
282 fn gpio(&self) -> &'static crate::pac::gpio0::RegisterBlock {
283 self.gpio()
284 }
285
286 fn port_reg(&self) -> &'static crate::pac::port0::RegisterBlock {
287 self.port_reg()
288 }
289
290 fn pcr_reg(&self) -> &'static crate::pac::port0::Pcr0 {
291 self.pcr_reg()
292 }
293
294 fn set_function(&self, function: Mux) {
295 self.pcr_reg().modify(|_, w| w.mux().variant(function));
296 }
297
298 fn set_pull(&self, pull: Pull) {
299 let (pull_enable, pull_select) = pull.into();
300 self.pcr_reg().modify(|_, w| {
301 w.pe().variant(pull_enable);
302 w.ps().variant(pull_select)
303 });
304 }
305
306 fn set_drive_strength(&self, strength: Dse) {
307 self.pcr_reg().modify(|_, w| w.dse().variant(strength));
308 }
309
310 fn set_slew_rate(&self, slew_rate: Sre) {
311 self.pcr_reg().modify(|_, w| w.sre().variant(slew_rate));
312 }
313
314 fn set_enable_input_buffer(&self) {
315 self.pcr_reg().modify(|_, w| w.ibe().ibe1());
316 }
317}
318
319impl GpioPin for AnyPin {}
320
321macro_rules! impl_pin {
322 ($peri:ident, $port:expr, $pin:expr, $block:ident) => {
323 paste! {
324 impl SealedPin for crate::peripherals::$peri {
325 fn pin_port(&self) -> usize {
326 $port * 32 + $pin
327 }
328
329 fn gpio(&self) -> &'static crate::pac::gpio0::RegisterBlock {
330 unsafe { &*crate::pac::$block::ptr() }
331 }
332
333 fn port_reg(&self) -> &'static crate::pac::port0::RegisterBlock {
334 unsafe { &*crate::pac::[<Port $port>]::ptr() }
335 }
336
337 fn pcr_reg(&self) -> &'static crate::pac::port0::Pcr0 {
338 self.port_reg().[<pcr $pin>]()
339 }
340
341 fn set_function(&self, function: Mux) {
342 unsafe {
343 let port_reg = &*crate::pac::[<Port $port>]::ptr();
344 port_reg.[<pcr $pin>]().modify(|_, w| {
345 w.mux().variant(function)
346 });
347 }
348 }
349
350 fn set_pull(&self, pull: Pull) {
351 let port_reg = unsafe {&*crate::pac::[<Port $port>]::ptr()};
352 let (pull_enable, pull_select) = pull.into();
353 port_reg.[<pcr $pin>]().modify(|_, w| {
354 w.pe().variant(pull_enable);
355 w.ps().variant(pull_select)
356 });
357 }
358
359 fn set_drive_strength(&self, strength: Dse) {
360 let port_reg = unsafe {&*crate::pac::[<Port $port>]::ptr()};
361 port_reg.[<pcr $pin>]().modify(|_, w| w.dse().variant(strength));
362 }
363
364 fn set_slew_rate(&self, slew_rate: Sre) {
365 let port_reg = unsafe {&*crate::pac::[<Port $port>]::ptr()};
366 port_reg.[<pcr $pin>]().modify(|_, w| w.sre().variant(slew_rate));
367 }
368
369 fn set_enable_input_buffer(&self) {
370 let port_reg = unsafe {&*crate::pac::[<Port $port>]::ptr()};
371 port_reg.[<pcr $pin>]().modify(|_, w| w.ibe().ibe1());
372 }
373 }
374
375 impl GpioPin for crate::peripherals::$peri {}
376
377 impl From<crate::peripherals::$peri> for AnyPin {
378 fn from(value: crate::peripherals::$peri) -> Self {
379 value.degrade()
380 }
381 }
382
383 impl crate::peripherals::$peri {
384 /// Convenience helper to obtain a type-erased handle to this pin.
385 pub fn degrade(&self) -> AnyPin {
386 AnyPin::new(self.port(), self.pin(), self.gpio(), self.port_reg(), self.pcr_reg())
387 }
388 }
389 }
390 };
391}
392
393impl_pin!(P0_0, 0, 0, Gpio0);
394impl_pin!(P0_1, 0, 1, Gpio0);
395impl_pin!(P0_2, 0, 2, Gpio0);
396impl_pin!(P0_3, 0, 3, Gpio0);
397impl_pin!(P0_4, 0, 4, Gpio0);
398impl_pin!(P0_5, 0, 5, Gpio0);
399impl_pin!(P0_6, 0, 6, Gpio0);
400impl_pin!(P0_7, 0, 7, Gpio0);
401impl_pin!(P0_8, 0, 8, Gpio0);
402impl_pin!(P0_9, 0, 9, Gpio0);
403impl_pin!(P0_10, 0, 10, Gpio0);
404impl_pin!(P0_11, 0, 11, Gpio0);
405impl_pin!(P0_12, 0, 12, Gpio0);
406impl_pin!(P0_13, 0, 13, Gpio0);
407impl_pin!(P0_14, 0, 14, Gpio0);
408impl_pin!(P0_15, 0, 15, Gpio0);
409impl_pin!(P0_16, 0, 16, Gpio0);
410impl_pin!(P0_17, 0, 17, Gpio0);
411impl_pin!(P0_18, 0, 18, Gpio0);
412impl_pin!(P0_19, 0, 19, Gpio0);
413impl_pin!(P0_20, 0, 20, Gpio0);
414impl_pin!(P0_21, 0, 21, Gpio0);
415impl_pin!(P0_22, 0, 22, Gpio0);
416impl_pin!(P0_23, 0, 23, Gpio0);
417impl_pin!(P0_24, 0, 24, Gpio0);
418impl_pin!(P0_25, 0, 25, Gpio0);
419impl_pin!(P0_26, 0, 26, Gpio0);
420impl_pin!(P0_27, 0, 27, Gpio0);
421impl_pin!(P0_28, 0, 28, Gpio0);
422impl_pin!(P0_29, 0, 29, Gpio0);
423impl_pin!(P0_30, 0, 30, Gpio0);
424impl_pin!(P0_31, 0, 31, Gpio0);
425
426impl_pin!(P1_0, 1, 0, Gpio1);
427impl_pin!(P1_1, 1, 1, Gpio1);
428impl_pin!(P1_2, 1, 2, Gpio1);
429impl_pin!(P1_3, 1, 3, Gpio1);
430impl_pin!(P1_4, 1, 4, Gpio1);
431impl_pin!(P1_5, 1, 5, Gpio1);
432impl_pin!(P1_6, 1, 6, Gpio1);
433impl_pin!(P1_7, 1, 7, Gpio1);
434impl_pin!(P1_8, 1, 8, Gpio1);
435impl_pin!(P1_9, 1, 9, Gpio1);
436impl_pin!(P1_10, 1, 10, Gpio1);
437impl_pin!(P1_11, 1, 11, Gpio1);
438impl_pin!(P1_12, 1, 12, Gpio1);
439impl_pin!(P1_13, 1, 13, Gpio1);
440impl_pin!(P1_14, 1, 14, Gpio1);
441impl_pin!(P1_15, 1, 15, Gpio1);
442impl_pin!(P1_16, 1, 16, Gpio1);
443impl_pin!(P1_17, 1, 17, Gpio1);
444impl_pin!(P1_18, 1, 18, Gpio1);
445impl_pin!(P1_19, 1, 19, Gpio1);
446impl_pin!(P1_20, 1, 20, Gpio1);
447impl_pin!(P1_21, 1, 21, Gpio1);
448impl_pin!(P1_22, 1, 22, Gpio1);
449impl_pin!(P1_23, 1, 23, Gpio1);
450impl_pin!(P1_24, 1, 24, Gpio1);
451impl_pin!(P1_25, 1, 25, Gpio1);
452impl_pin!(P1_26, 1, 26, Gpio1);
453impl_pin!(P1_27, 1, 27, Gpio1);
454impl_pin!(P1_28, 1, 28, Gpio1);
455impl_pin!(P1_29, 1, 29, Gpio1);
456impl_pin!(P1_30, 1, 30, Gpio1);
457impl_pin!(P1_31, 1, 31, Gpio1);
458
459impl_pin!(P2_0, 2, 0, Gpio2);
460impl_pin!(P2_1, 2, 1, Gpio2);
461impl_pin!(P2_2, 2, 2, Gpio2);
462impl_pin!(P2_3, 2, 3, Gpio2);
463impl_pin!(P2_4, 2, 4, Gpio2);
464impl_pin!(P2_5, 2, 5, Gpio2);
465impl_pin!(P2_6, 2, 6, Gpio2);
466impl_pin!(P2_7, 2, 7, Gpio2);
467impl_pin!(P2_8, 2, 8, Gpio2);
468impl_pin!(P2_9, 2, 9, Gpio2);
469impl_pin!(P2_10, 2, 10, Gpio2);
470impl_pin!(P2_11, 2, 11, Gpio2);
471impl_pin!(P2_12, 2, 12, Gpio2);
472impl_pin!(P2_13, 2, 13, Gpio2);
473impl_pin!(P2_14, 2, 14, Gpio2);
474impl_pin!(P2_15, 2, 15, Gpio2);
475impl_pin!(P2_16, 2, 16, Gpio2);
476impl_pin!(P2_17, 2, 17, Gpio2);
477impl_pin!(P2_18, 2, 18, Gpio2);
478impl_pin!(P2_19, 2, 19, Gpio2);
479impl_pin!(P2_20, 2, 20, Gpio2);
480impl_pin!(P2_21, 2, 21, Gpio2);
481impl_pin!(P2_22, 2, 22, Gpio2);
482impl_pin!(P2_23, 2, 23, Gpio2);
483impl_pin!(P2_24, 2, 24, Gpio2);
484impl_pin!(P2_25, 2, 25, Gpio2);
485impl_pin!(P2_26, 2, 26, Gpio2);
486impl_pin!(P2_27, 2, 27, Gpio2);
487impl_pin!(P2_28, 2, 28, Gpio2);
488impl_pin!(P2_29, 2, 29, Gpio2);
489impl_pin!(P2_30, 2, 30, Gpio2);
490impl_pin!(P2_31, 2, 31, Gpio2);
491
492impl_pin!(P3_0, 3, 0, Gpio3);
493impl_pin!(P3_1, 3, 1, Gpio3);
494impl_pin!(P3_2, 3, 2, Gpio3);
495impl_pin!(P3_3, 3, 3, Gpio3);
496impl_pin!(P3_4, 3, 4, Gpio3);
497impl_pin!(P3_5, 3, 5, Gpio3);
498impl_pin!(P3_6, 3, 6, Gpio3);
499impl_pin!(P3_7, 3, 7, Gpio3);
500impl_pin!(P3_8, 3, 8, Gpio3);
501impl_pin!(P3_9, 3, 9, Gpio3);
502impl_pin!(P3_10, 3, 10, Gpio3);
503impl_pin!(P3_11, 3, 11, Gpio3);
504impl_pin!(P3_12, 3, 12, Gpio3);
505impl_pin!(P3_13, 3, 13, Gpio3);
506impl_pin!(P3_14, 3, 14, Gpio3);
507impl_pin!(P3_15, 3, 15, Gpio3);
508impl_pin!(P3_16, 3, 16, Gpio3);
509impl_pin!(P3_17, 3, 17, Gpio3);
510impl_pin!(P3_18, 3, 18, Gpio3);
511impl_pin!(P3_19, 3, 19, Gpio3);
512impl_pin!(P3_20, 3, 20, Gpio3);
513impl_pin!(P3_21, 3, 21, Gpio3);
514impl_pin!(P3_22, 3, 22, Gpio3);
515impl_pin!(P3_23, 3, 23, Gpio3);
516impl_pin!(P3_24, 3, 24, Gpio3);
517impl_pin!(P3_25, 3, 25, Gpio3);
518impl_pin!(P3_26, 3, 26, Gpio3);
519impl_pin!(P3_27, 3, 27, Gpio3);
520impl_pin!(P3_28, 3, 28, Gpio3);
521impl_pin!(P3_29, 3, 29, Gpio3);
522impl_pin!(P3_30, 3, 30, Gpio3);
523impl_pin!(P3_31, 3, 31, Gpio3);
524
525impl_pin!(P4_0, 4, 0, Gpio4);
526impl_pin!(P4_1, 4, 1, Gpio4);
527impl_pin!(P4_2, 4, 2, Gpio4);
528impl_pin!(P4_3, 4, 3, Gpio4);
529impl_pin!(P4_4, 4, 4, Gpio4);
530impl_pin!(P4_5, 4, 5, Gpio4);
531impl_pin!(P4_6, 4, 6, Gpio4);
532impl_pin!(P4_7, 4, 7, Gpio4);
533impl_pin!(P4_8, 4, 8, Gpio4);
534impl_pin!(P4_9, 4, 9, Gpio4);
535impl_pin!(P4_10, 4, 10, Gpio4);
536impl_pin!(P4_11, 4, 11, Gpio4);
537impl_pin!(P4_12, 4, 12, Gpio4);
538impl_pin!(P4_13, 4, 13, Gpio4);
539impl_pin!(P4_14, 4, 14, Gpio4);
540impl_pin!(P4_15, 4, 15, Gpio4);
541impl_pin!(P4_16, 4, 16, Gpio4);
542impl_pin!(P4_17, 4, 17, Gpio4);
543impl_pin!(P4_18, 4, 18, Gpio4);
544impl_pin!(P4_19, 4, 19, Gpio4);
545impl_pin!(P4_20, 4, 20, Gpio4);
546impl_pin!(P4_21, 4, 21, Gpio4);
547impl_pin!(P4_22, 4, 22, Gpio4);
548impl_pin!(P4_23, 4, 23, Gpio4);
549impl_pin!(P4_24, 4, 24, Gpio4);
550impl_pin!(P4_25, 4, 25, Gpio4);
551impl_pin!(P4_26, 4, 26, Gpio4);
552impl_pin!(P4_27, 4, 27, Gpio4);
553impl_pin!(P4_28, 4, 28, Gpio4);
554impl_pin!(P4_29, 4, 29, Gpio4);
555impl_pin!(P4_30, 4, 30, Gpio4);
556impl_pin!(P4_31, 4, 31, Gpio4);
557
558/// A flexible pin that can be configured as input or output.
559pub struct Flex<'d> {
560 pin: Peri<'d, AnyPin>,
561 _marker: PhantomData<&'d mut ()>,
562}
563
564impl<'d> Flex<'d> {
565 /// Wrap the pin in a `Flex`.
566 ///
567 /// The pin remains unmodified. The initial output level is unspecified, but
568 /// can be changed before the pin is put into output mode.
569 pub fn new(pin: Peri<'d, impl GpioPin>) -> Self {
570 pin.set_function(Mux::Mux0);
571 Self {
572 pin: pin.into(),
573 _marker: PhantomData,
574 }
575 }
576
577 #[inline]
578 fn gpio(&self) -> &'static crate::pac::gpio0::RegisterBlock {
579 self.pin.gpio()
580 }
581
582 #[inline]
583 fn mask(&self) -> u32 {
584 self.pin.mask()
585 }
586
587 /// Put the pin into input mode.
588 pub fn set_as_input(&mut self) {
589 let mask = self.mask();
590 let gpio = self.gpio();
591
592 self.set_enable_input_buffer();
593
594 gpio.pddr().modify(|r, w| unsafe { w.bits(r.bits() & !mask) });
595 }
596
597 /// Put the pin into output mode.
598 pub fn set_as_output(&mut self) {
599 let mask = self.mask();
600 let gpio = self.gpio();
601
602 self.set_pull(Pull::Disabled);
603
604 gpio.pddr().modify(|r, w| unsafe { w.bits(r.bits() | mask) });
605 }
606
607 /// Set output level to High.
608 #[inline]
609 pub fn set_high(&mut self) {
610 self.gpio().psor().write(|w| unsafe { w.bits(self.mask()) });
611 }
612
613 /// Set output level to Low.
614 #[inline]
615 pub fn set_low(&mut self) {
616 self.gpio().pcor().write(|w| unsafe { w.bits(self.mask()) });
617 }
618
619 /// Set output level to the given `Level`.
620 #[inline]
621 pub fn set_level(&mut self, level: Level) {
622 match level {
623 Level::High => self.set_high(),
624 Level::Low => self.set_low(),
625 }
626 }
627
628 /// Toggle output level.
629 #[inline]
630 pub fn toggle(&mut self) {
631 self.gpio().ptor().write(|w| unsafe { w.bits(self.mask()) });
632 }
633
634 /// Get whether the pin input level is high.
635 #[inline]
636 pub fn is_high(&self) -> bool {
637 (self.gpio().pdir().read().bits() & self.mask()) != 0
638 }
639
640 /// Get whether the pin input level is low.
641 #[inline]
642 pub fn is_low(&self) -> bool {
643 !self.is_high()
644 }
645
646 /// Is the output pin set as high?
647 #[inline]
648 pub fn is_set_high(&self) -> bool {
649 self.is_high()
650 }
651
652 /// Is the output pin set as low?
653 #[inline]
654 pub fn is_set_low(&self) -> bool {
655 !self.is_set_high()
656 }
657
658 /// Configure the pin pull up/down level.
659 pub fn set_pull(&mut self, pull_select: Pull) {
660 self.pin.set_pull(pull_select);
661 }
662
663 /// Configure the pin drive strength.
664 pub fn set_drive_strength(&mut self, strength: DriveStrength) {
665 self.pin.set_drive_strength(strength.into());
666 }
667
668 /// Configure the pin slew rate.
669 pub fn set_slew_rate(&mut self, slew_rate: SlewRate) {
670 self.pin.set_slew_rate(slew_rate.into());
671 }
672
673 /// Enable input buffer for the pin.
674 pub fn set_enable_input_buffer(&mut self) {
675 self.pin.set_enable_input_buffer();
676 }
677
678 /// Get pin level.
679 pub fn get_level(&self) -> Level {
680 self.is_high().into()
681 }
682}
683
684/// Async methods
685impl<'d> Flex<'d> {
686 /// Helper function that waits for a given interrupt trigger
687 async fn wait_for_inner(&mut self, level: crate::pac::gpio0::icr::Irqc) {
688 // First, ensure that we have a waker that is ready for this port+pin
689 let w = PORT_WAIT_MAPS[self.pin.port].wait(self.pin.pin);
690 let mut w = pin!(w);
691 // Wait for the subscription to occur, which requires polling at least once
692 //
693 // This function returns a result, but can only be an Err if:
694 //
695 // * We call `.close()` on a WaitMap, which we never do
696 // * We have a duplicate key, which can't happen because `wait_for_*` methods
697 // take an &mut ref of their unique port+pin combo
698 //
699 // So we wait for it to complete, but ignore the result.
700 _ = w.as_mut().subscribe().await;
701
702 // Now that our waker is in the map, we can enable the appropriate interrupt
703 //
704 // Clear any existing pending interrupt on this pin
705 self.pin
706 .gpio()
707 .isfr0()
708 .write(|w| unsafe { w.bits(1 << self.pin.pin()) });
709 self.pin.gpio().icr(self.pin.pin()).write(|w| w.isf().isf1());
710
711 // Pin interrupt configuration
712 self.pin
713 .gpio()
714 .icr(self.pin.pin())
715 .modify(|_, w| w.irqc().variant(level));
716
717 // Finally, we can await the matching call to `.wake()` from the interrupt.
718 //
719 // Again, technically, this could return a result, but for the same reasons
720 // as above, this can't be an error in our case, so just wait for it to complete
721 _ = w.await;
722 }
723
724 /// Wait until the pin is high. If it is already high, return immediately.
725 #[inline]
726 pub fn wait_for_high(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
727 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc12)
728 }
729
730 /// Wait until the pin is low. If it is already low, return immediately.
731 #[inline]
732 pub fn wait_for_low(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
733 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc8)
734 }
735
736 /// Wait for the pin to undergo a transition from low to high.
737 #[inline]
738 pub fn wait_for_rising_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
739 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc9)
740 }
741
742 /// Wait for the pin to undergo a transition from high to low.
743 #[inline]
744 pub fn wait_for_falling_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
745 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc10)
746 }
747
748 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
749 #[inline]
750 pub fn wait_for_any_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
751 self.wait_for_inner(crate::pac::gpio0::icr::Irqc::Irqc11)
752 }
753}
754
755/// GPIO output driver that owns a `Flex` pin.
756pub struct Output<'d> {
757 flex: Flex<'d>,
758}
759
760impl<'d> Output<'d> {
761 /// Create a GPIO output driver for a [GpioPin] with the provided [Level].
762 pub fn new(pin: Peri<'d, impl GpioPin>, initial: Level, strength: DriveStrength, slew_rate: SlewRate) -> Self {
763 let mut flex = Flex::new(pin);
764 flex.set_level(initial);
765 flex.set_as_output();
766 flex.set_drive_strength(strength);
767 flex.set_slew_rate(slew_rate);
768 Self { flex }
769 }
770
771 /// Set the output as high.
772 #[inline]
773 pub fn set_high(&mut self) {
774 self.flex.set_high();
775 }
776
777 /// Set the output as low.
778 #[inline]
779 pub fn set_low(&mut self) {
780 self.flex.set_low();
781 }
782
783 /// Set the output level.
784 #[inline]
785 pub fn set_level(&mut self, level: Level) {
786 self.flex.set_level(level);
787 }
788
789 /// Toggle the output level.
790 #[inline]
791 pub fn toggle(&mut self) {
792 self.flex.toggle();
793 }
794
795 /// Is the output pin set as high?
796 #[inline]
797 pub fn is_set_high(&self) -> bool {
798 self.flex.is_high()
799 }
800
801 /// Is the output pin set as low?
802 #[inline]
803 pub fn is_set_low(&self) -> bool {
804 !self.is_set_high()
805 }
806
807 /// Expose the inner `Flex` if callers need to reconfigure the pin.
808 #[inline]
809 pub fn into_flex(self) -> Flex<'d> {
810 self.flex
811 }
812}
813
814/// GPIO input driver that owns a `Flex` pin.
815pub struct Input<'d> {
816 flex: Flex<'d>,
817}
818
819impl<'d> Input<'d> {
820 /// Create a GPIO input driver for a [GpioPin].
821 ///
822 pub fn new(pin: Peri<'d, impl GpioPin>, pull_select: Pull) -> Self {
823 let mut flex = Flex::new(pin);
824 flex.set_as_input();
825 flex.set_pull(pull_select);
826 Self { flex }
827 }
828
829 /// Get whether the pin input level is high.
830 #[inline]
831 pub fn is_high(&self) -> bool {
832 self.flex.is_high()
833 }
834
835 /// Get whether the pin input level is low.
836 #[inline]
837 pub fn is_low(&self) -> bool {
838 self.flex.is_low()
839 }
840
841 /// Expose the inner `Flex` if callers need to reconfigure the pin.
842 ///
843 /// Since Drive Strength and Slew Rate are not set when creating the Input
844 /// pin, they need to be set when converting
845 #[inline]
846 pub fn into_flex(mut self, strength: DriveStrength, slew_rate: SlewRate) -> Flex<'d> {
847 self.flex.set_drive_strength(strength);
848 self.flex.set_slew_rate(slew_rate);
849 self.flex
850 }
851
852 /// Get the pin level.
853 pub fn get_level(&self) -> Level {
854 self.flex.get_level()
855 }
856}
857
858/// Async methods
859impl<'d> Input<'d> {
860 /// Wait until the pin is high. If it is already high, return immediately.
861 #[inline]
862 pub fn wait_for_high(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
863 self.flex.wait_for_high()
864 }
865
866 /// Wait until the pin is low. If it is already low, return immediately.
867 #[inline]
868 pub fn wait_for_low(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
869 self.flex.wait_for_low()
870 }
871
872 /// Wait for the pin to undergo a transition from low to high.
873 #[inline]
874 pub fn wait_for_rising_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
875 self.flex.wait_for_rising_edge()
876 }
877
878 /// Wait for the pin to undergo a transition from high to low.
879 #[inline]
880 pub fn wait_for_falling_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
881 self.flex.wait_for_falling_edge()
882 }
883
884 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
885 #[inline]
886 pub fn wait_for_any_edge(&mut self) -> impl Future<Output = ()> + use<'_, 'd> {
887 self.flex.wait_for_any_edge()
888 }
889}
890
891impl embedded_hal_async::digital::Wait for Input<'_> {
892 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
893 self.wait_for_high().await;
894 Ok(())
895 }
896
897 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
898 self.wait_for_low().await;
899 Ok(())
900 }
901
902 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
903 self.wait_for_rising_edge().await;
904 Ok(())
905 }
906
907 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
908 self.wait_for_falling_edge().await;
909 Ok(())
910 }
911
912 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
913 self.wait_for_any_edge().await;
914 Ok(())
915 }
916}
917
918impl embedded_hal_async::digital::Wait for Flex<'_> {
919 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
920 self.wait_for_high().await;
921 Ok(())
922 }
923
924 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
925 self.wait_for_low().await;
926 Ok(())
927 }
928
929 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
930 self.wait_for_rising_edge().await;
931 Ok(())
932 }
933
934 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
935 self.wait_for_falling_edge().await;
936 Ok(())
937 }
938
939 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
940 self.wait_for_any_edge().await;
941 Ok(())
942 }
943}
944
945// Both embedded_hal 0.2 and 1.0 must be supported by embassy HALs.
946impl embedded_hal_02::digital::v2::InputPin for Flex<'_> {
947 // GPIO operations on this block cannot fail, therefor we set the error type
948 // to Infallible to guarantee that we can only produce Ok variants.
949 type Error = Infallible;
950
951 #[inline]
952 fn is_high(&self) -> Result<bool, Self::Error> {
953 Ok(self.is_high())
954 }
955
956 #[inline]
957 fn is_low(&self) -> Result<bool, Self::Error> {
958 Ok(self.is_low())
959 }
960}
961
962impl embedded_hal_02::digital::v2::InputPin for Input<'_> {
963 type Error = Infallible;
964
965 #[inline]
966 fn is_high(&self) -> Result<bool, Self::Error> {
967 Ok(self.is_high())
968 }
969
970 #[inline]
971 fn is_low(&self) -> Result<bool, Self::Error> {
972 Ok(self.is_low())
973 }
974}
975
976impl embedded_hal_02::digital::v2::OutputPin for Flex<'_> {
977 type Error = Infallible;
978
979 #[inline]
980 fn set_high(&mut self) -> Result<(), Self::Error> {
981 self.set_high();
982 Ok(())
983 }
984
985 #[inline]
986 fn set_low(&mut self) -> Result<(), Self::Error> {
987 self.set_low();
988 Ok(())
989 }
990}
991
992impl embedded_hal_02::digital::v2::StatefulOutputPin for Flex<'_> {
993 #[inline]
994 fn is_set_high(&self) -> Result<bool, Self::Error> {
995 Ok(self.is_set_high())
996 }
997
998 #[inline]
999 fn is_set_low(&self) -> Result<bool, Self::Error> {
1000 Ok(self.is_set_low())
1001 }
1002}
1003
1004impl embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'_> {
1005 type Error = Infallible;
1006
1007 #[inline]
1008 fn toggle(&mut self) -> Result<(), Self::Error> {
1009 self.toggle();
1010 Ok(())
1011 }
1012}
1013
1014impl embedded_hal_1::digital::ErrorType for Flex<'_> {
1015 type Error = Infallible;
1016}
1017
1018impl embedded_hal_1::digital::ErrorType for Input<'_> {
1019 type Error = Infallible;
1020}
1021
1022impl embedded_hal_1::digital::ErrorType for Output<'_> {
1023 type Error = Infallible;
1024}
1025
1026impl embedded_hal_1::digital::InputPin for Input<'_> {
1027 #[inline]
1028 fn is_high(&mut self) -> Result<bool, Self::Error> {
1029 Ok((*self).is_high())
1030 }
1031
1032 #[inline]
1033 fn is_low(&mut self) -> Result<bool, Self::Error> {
1034 Ok((*self).is_low())
1035 }
1036}
1037
1038impl embedded_hal_1::digital::OutputPin for Flex<'_> {
1039 #[inline]
1040 fn set_high(&mut self) -> Result<(), Self::Error> {
1041 self.set_high();
1042 Ok(())
1043 }
1044
1045 #[inline]
1046 fn set_low(&mut self) -> Result<(), Self::Error> {
1047 self.set_low();
1048 Ok(())
1049 }
1050}
1051
1052impl embedded_hal_1::digital::StatefulOutputPin for Flex<'_> {
1053 #[inline]
1054 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1055 Ok((*self).is_set_high())
1056 }
1057
1058 #[inline]
1059 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1060 Ok((*self).is_set_low())
1061 }
1062}