imxrt10xx/
gpio.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! i.MX RT GPIO driver
6//!
7//! # Design
8//!
9//! Allocate a [`Ports`] collection. Use this to access GPIO pins and GPIO ports.
10//!
11//! - A [`Port`] maps to a GPIO pin bank. `GPIO3` is a port. Ports may provide
12//!   access to pins. Ports handle interrupts.
13//! - A [`Pin`] maps to a physical GPIO pin. `GPIO3[17]` is a pin. It's identified
14//!   by its [`PinId`], [`SdB0_05`][PinId::SdB0_05]. Pins can be set as inputs or
15//!   outputs.
16//!
17//! # Example
18//!
19//! ```
20//! use imxrt10xx::gpio::{Ports, Port, PinId};
21//!
22//! # let ccm = imxrt10xx::ccm::Ccm::new();
23//! let ports = Ports::new(&ccm);
24//! let pin_from_id = ports.pin(PinId::Emc25);
25//! let pin_from_port = ports.gpio4.pin(25);
26//! assert_eq!(pin_from_id as *const _, pin_from_port as *const _);
27//! ```
28
29use cortexm7::support::atomic;
30use enum_primitive::cast::FromPrimitive;
31use enum_primitive::enum_from_primitive;
32use kernel::hil;
33use kernel::platform::chip::ClockInterface;
34use kernel::utilities::cells::OptionalCell;
35use kernel::utilities::registers::interfaces::{Readable, Writeable};
36use kernel::utilities::registers::{ReadOnly, ReadWrite, WriteOnly};
37use kernel::utilities::StaticRef;
38
39use crate::ccm;
40
41/// General-purpose I/Os
42#[repr(C)]
43struct GpioRegisters {
44    // GPIO data register
45    dr: ReadWrite<u32>,
46    // GPIO direction register
47    gdir: ReadWrite<u32>,
48    // GPIO pad status register
49    psr: ReadOnly<u32>,
50    // GPIO Interrupt configuration register 1
51    icr1: ReadWrite<u32>,
52    // GPIO Interrupt configuration register 2
53    icr2: ReadWrite<u32>,
54    // GPIO interrupt mask register
55    imr: ReadWrite<u32>,
56    // GPIO interrupt status register -- W1C - Write 1 to clear
57    isr: ReadWrite<u32>,
58    // GPIO edge select register
59    edge_sel: ReadWrite<u32>,
60    _reserved1: [u8; 100],
61    // GPIO data register set
62    dr_set: WriteOnly<u32>,
63    // GPIO data register clear
64    dr_clear: WriteOnly<u32>,
65    // GPIO data register toggle
66    dr_toggle: WriteOnly<u32>,
67}
68
69const GPIO1_BASE: StaticRef<GpioRegisters> =
70    unsafe { StaticRef::new(0x401B8000 as *const GpioRegisters) };
71
72const GPIO2_BASE: StaticRef<GpioRegisters> =
73    unsafe { StaticRef::new(0x401BC000 as *const GpioRegisters) };
74
75const GPIO3_BASE: StaticRef<GpioRegisters> =
76    unsafe { StaticRef::new(0x401C0000 as *const GpioRegisters) };
77
78const GPIO4_BASE: StaticRef<GpioRegisters> =
79    unsafe { StaticRef::new(0x401C4000 as *const GpioRegisters) };
80
81const GPIO5_BASE: StaticRef<GpioRegisters> =
82    unsafe { StaticRef::new(0x400C0000 as *const GpioRegisters) };
83
84enum_from_primitive! {
85    /// Imxrt1050-evkb has 5 GPIO ports labeled from 1-5 [^1]. This is represented
86    /// by three bits.
87    ///
88    /// [^1]: 12.5.1 GPIO memory map, page 1009 of the Reference Manual.
89    #[repr(u16)]
90    enum GpioPort {
91        GPIO1 = 0b000,
92        GPIO2 = 0b001,
93        GPIO3 = 0b010,
94        GPIO4 = 0b011,
95        GPIO5 = 0b100,
96    }
97}
98
99/// Creates a GPIO ID
100///
101/// Low 6 bits are the GPIO offset; the '17' in `GPIO2[17]`
102/// Next 3 bits are the GPIO port; the '2' in `GPIO2[17]` (base 0 index, 2 -> 1)
103const fn gpio_id(port: GpioPort, offset: u16) -> u16 {
104    ((port as u16) << 6) | offset & 0x3F
105}
106
107/// GPIO Pin Identifiers
108#[repr(u16)]
109#[derive(Copy, Clone)]
110pub enum PinId {
111    // GPIO1
112    AdB0_00 = gpio_id(GpioPort::GPIO1, 0),
113    AdB0_01 = gpio_id(GpioPort::GPIO1, 1),
114    AdB0_02 = gpio_id(GpioPort::GPIO1, 2),
115    AdB0_03 = gpio_id(GpioPort::GPIO1, 3),
116    AdB0_04 = gpio_id(GpioPort::GPIO1, 4),
117    AdB0_05 = gpio_id(GpioPort::GPIO1, 5),
118    AdB0_06 = gpio_id(GpioPort::GPIO1, 6),
119    AdB0_07 = gpio_id(GpioPort::GPIO1, 7),
120    AdB0_08 = gpio_id(GpioPort::GPIO1, 8),
121    AdB0_09 = gpio_id(GpioPort::GPIO1, 9),
122    AdB0_10 = gpio_id(GpioPort::GPIO1, 10),
123    AdB0_11 = gpio_id(GpioPort::GPIO1, 11),
124    AdB0_12 = gpio_id(GpioPort::GPIO1, 12),
125    AdB0_13 = gpio_id(GpioPort::GPIO1, 13),
126    AdB0_14 = gpio_id(GpioPort::GPIO1, 14),
127    AdB0_15 = gpio_id(GpioPort::GPIO1, 15),
128
129    AdB1_00 = gpio_id(GpioPort::GPIO1, 16),
130    AdB1_01 = gpio_id(GpioPort::GPIO1, 17),
131    AdB1_02 = gpio_id(GpioPort::GPIO1, 18),
132    AdB1_03 = gpio_id(GpioPort::GPIO1, 19),
133    AdB1_04 = gpio_id(GpioPort::GPIO1, 20),
134    AdB1_05 = gpio_id(GpioPort::GPIO1, 21),
135    AdB1_06 = gpio_id(GpioPort::GPIO1, 22),
136    AdB1_07 = gpio_id(GpioPort::GPIO1, 23),
137    AdB1_08 = gpio_id(GpioPort::GPIO1, 24),
138    AdB1_09 = gpio_id(GpioPort::GPIO1, 25),
139    AdB1_10 = gpio_id(GpioPort::GPIO1, 26),
140    AdB1_11 = gpio_id(GpioPort::GPIO1, 27),
141    AdB1_12 = gpio_id(GpioPort::GPIO1, 28),
142    AdB1_13 = gpio_id(GpioPort::GPIO1, 29),
143    AdB1_14 = gpio_id(GpioPort::GPIO1, 30),
144    AdB1_15 = gpio_id(GpioPort::GPIO1, 31),
145
146    // GPIO2
147    B0_00 = gpio_id(GpioPort::GPIO2, 0),
148    B0_01 = gpio_id(GpioPort::GPIO2, 1),
149    B0_02 = gpio_id(GpioPort::GPIO2, 2),
150    B0_03 = gpio_id(GpioPort::GPIO2, 3),
151    B0_04 = gpio_id(GpioPort::GPIO2, 4),
152    B0_05 = gpio_id(GpioPort::GPIO2, 5),
153    B0_06 = gpio_id(GpioPort::GPIO2, 6),
154    B0_07 = gpio_id(GpioPort::GPIO2, 7),
155    B0_08 = gpio_id(GpioPort::GPIO2, 8),
156    B0_09 = gpio_id(GpioPort::GPIO2, 9),
157    B0_10 = gpio_id(GpioPort::GPIO2, 10),
158    B0_11 = gpio_id(GpioPort::GPIO2, 11),
159    B0_12 = gpio_id(GpioPort::GPIO2, 12),
160    B0_13 = gpio_id(GpioPort::GPIO2, 13),
161    B0_14 = gpio_id(GpioPort::GPIO2, 14),
162    B0_15 = gpio_id(GpioPort::GPIO2, 15),
163
164    B1_00 = gpio_id(GpioPort::GPIO2, 16),
165    B1_01 = gpio_id(GpioPort::GPIO2, 17),
166    B1_02 = gpio_id(GpioPort::GPIO2, 18),
167    B1_03 = gpio_id(GpioPort::GPIO2, 19),
168    B1_04 = gpio_id(GpioPort::GPIO2, 20),
169    B1_05 = gpio_id(GpioPort::GPIO2, 21),
170    B1_06 = gpio_id(GpioPort::GPIO2, 22),
171    B1_07 = gpio_id(GpioPort::GPIO2, 23),
172    B1_08 = gpio_id(GpioPort::GPIO2, 24),
173    B1_09 = gpio_id(GpioPort::GPIO2, 25),
174    B1_10 = gpio_id(GpioPort::GPIO2, 26),
175    B1_11 = gpio_id(GpioPort::GPIO2, 27),
176    B1_12 = gpio_id(GpioPort::GPIO2, 28),
177    B1_13 = gpio_id(GpioPort::GPIO2, 29),
178    B1_14 = gpio_id(GpioPort::GPIO2, 30),
179    B1_15 = gpio_id(GpioPort::GPIO2, 31),
180
181    // GPIO3
182    SdB1_00 = gpio_id(GpioPort::GPIO3, 0),
183    SdB1_01 = gpio_id(GpioPort::GPIO3, 1),
184    SdB1_02 = gpio_id(GpioPort::GPIO3, 2),
185    SdB1_03 = gpio_id(GpioPort::GPIO3, 3),
186    SdB1_04 = gpio_id(GpioPort::GPIO3, 4),
187    SdB1_05 = gpio_id(GpioPort::GPIO3, 5),
188    SdB1_06 = gpio_id(GpioPort::GPIO3, 6),
189    SdB1_07 = gpio_id(GpioPort::GPIO3, 7),
190    SdB1_08 = gpio_id(GpioPort::GPIO3, 8),
191    SdB1_09 = gpio_id(GpioPort::GPIO3, 9),
192    SdB1_10 = gpio_id(GpioPort::GPIO3, 10),
193    SdB1_11 = gpio_id(GpioPort::GPIO3, 11),
194
195    SdB0_00 = gpio_id(GpioPort::GPIO3, 12),
196    SdB0_01 = gpio_id(GpioPort::GPIO3, 13),
197    SdB0_02 = gpio_id(GpioPort::GPIO3, 14),
198    SdB0_03 = gpio_id(GpioPort::GPIO3, 15),
199    SdB0_04 = gpio_id(GpioPort::GPIO3, 16),
200    SdB0_05 = gpio_id(GpioPort::GPIO3, 17),
201
202    Emc32 = gpio_id(GpioPort::GPIO3, 18),
203    Emc33 = gpio_id(GpioPort::GPIO3, 19),
204    Emc34 = gpio_id(GpioPort::GPIO3, 20),
205    Emc35 = gpio_id(GpioPort::GPIO3, 21),
206    Emc36 = gpio_id(GpioPort::GPIO3, 22),
207    Emc37 = gpio_id(GpioPort::GPIO3, 23),
208    Emc38 = gpio_id(GpioPort::GPIO3, 24),
209    Emc39 = gpio_id(GpioPort::GPIO3, 25),
210    Emc40 = gpio_id(GpioPort::GPIO3, 26),
211    Emc41 = gpio_id(GpioPort::GPIO3, 27),
212
213    // GPIO4
214    Emc00 = gpio_id(GpioPort::GPIO4, 0),
215    Emc01 = gpio_id(GpioPort::GPIO4, 1),
216    Emc02 = gpio_id(GpioPort::GPIO4, 2),
217    Emc03 = gpio_id(GpioPort::GPIO4, 3),
218    Emc04 = gpio_id(GpioPort::GPIO4, 4),
219    Emc05 = gpio_id(GpioPort::GPIO4, 5),
220    Emc06 = gpio_id(GpioPort::GPIO4, 6),
221    Emc07 = gpio_id(GpioPort::GPIO4, 7),
222    Emc08 = gpio_id(GpioPort::GPIO4, 8),
223    Emc09 = gpio_id(GpioPort::GPIO4, 9),
224    Emc10 = gpio_id(GpioPort::GPIO4, 10),
225    Emc11 = gpio_id(GpioPort::GPIO4, 11),
226    Emc12 = gpio_id(GpioPort::GPIO4, 12),
227    Emc13 = gpio_id(GpioPort::GPIO4, 13),
228    Emc14 = gpio_id(GpioPort::GPIO4, 14),
229    Emc15 = gpio_id(GpioPort::GPIO4, 15),
230    Emc16 = gpio_id(GpioPort::GPIO4, 16),
231    Emc17 = gpio_id(GpioPort::GPIO4, 17),
232    Emc18 = gpio_id(GpioPort::GPIO4, 18),
233    Emc19 = gpio_id(GpioPort::GPIO4, 19),
234    Emc20 = gpio_id(GpioPort::GPIO4, 20),
235    Emc21 = gpio_id(GpioPort::GPIO4, 21),
236    Emc22 = gpio_id(GpioPort::GPIO4, 22),
237    Emc23 = gpio_id(GpioPort::GPIO4, 23),
238    Emc24 = gpio_id(GpioPort::GPIO4, 24),
239    Emc25 = gpio_id(GpioPort::GPIO4, 25),
240    Emc26 = gpio_id(GpioPort::GPIO4, 26),
241    Emc27 = gpio_id(GpioPort::GPIO4, 27),
242    Emc28 = gpio_id(GpioPort::GPIO4, 28),
243    Emc29 = gpio_id(GpioPort::GPIO4, 29),
244    Emc30 = gpio_id(GpioPort::GPIO4, 30),
245    Emc31 = gpio_id(GpioPort::GPIO4, 31),
246
247    // GPIO5
248    Wakeup = gpio_id(GpioPort::GPIO5, 0),
249    PmicOnReq = gpio_id(GpioPort::GPIO5, 1),
250    PmicStbyReq = gpio_id(GpioPort::GPIO5, 2),
251}
252
253impl PinId {
254    /// Returns the port
255    fn port(self) -> GpioPort {
256        GpioPort::from_u16((self as u16) >> 6).unwrap()
257    }
258    /// Returns the pin offset, half-closed range [0, 32)
259    const fn offset(self) -> usize {
260        (self as usize) & 0x3F
261    }
262}
263
264/// GPIO pin mode
265///
266/// This describes the pin direction when it's a _GPIO pin_.
267/// It does not describe the direction for other I/O, like LPI2C
268/// or LPUART.
269///
270/// In order to set alternate functions such as LPI2C or LPUART,
271/// you will need to use iomuxc enable_sw_mux_ctl_pad_gpio with
272/// the specific MUX_MODE according to the reference manual (Chapter 11).
273/// For the gpio mode, input or output we set the GDIR pin accordingly [^1]
274///
275/// [^1]: 12.4.3. GPIO Programming, page 1008 of the Reference Manual
276pub enum Mode {
277    Input = 0b00,
278    Output = 0b01,
279}
280
281/// A GPIO port, like `GPIO3`
282///
283/// `Port`s contain collections of pins. Use `Port`s to access pin by their
284/// GPIO offset. See the module-level docs for an example.
285pub struct Port<'a, const N: usize> {
286    registers: StaticRef<GpioRegisters>,
287    clock: PortClock<'a>,
288    pins: [Pin<'a>; N],
289}
290
291/// Implementation of a port, generic over the number of
292/// pins
293impl<'a, const N: usize> Port<'a, N> {
294    const fn new(
295        registers: StaticRef<GpioRegisters>,
296        clock: PortClock<'a>,
297        pins: [Pin<'a>; N],
298    ) -> Self {
299        Self {
300            registers,
301            clock,
302            pins,
303        }
304    }
305
306    pub fn is_enabled_clock(&self) -> bool {
307        self.clock.is_enabled()
308    }
309
310    pub fn enable_clock(&self) {
311        self.clock.enable();
312    }
313
314    pub fn disable_clock(&self) {
315        self.clock.disable();
316    }
317
318    /// Returns the GPIO pin in this port
319    ///
320    /// This is an alterative API to [`Ports::pin`] that maps more closely
321    /// to the GPIO offset.
322    pub const fn pin(&self, offset: usize) -> &Pin<'a> {
323        &self.pins[offset]
324    }
325
326    pub fn handle_interrupt(&self) {
327        let imr_val: u32 = self.registers.imr.get();
328
329        // Read the `ISR` register and toggle the appropriate bits in
330        // `isr`. Once that is done, write the value of `isr` back. We
331        // can have a situation where memory value of `ISR` could have
332        // changed due to an external interrupt. `ISR` is a read/clear write
333        // 1 register (`rc_w1`). So, we only clear bits whose value has been
334        // transferred to `isr`.
335        let isr_val = unsafe {
336            atomic(|| {
337                let isr_val = self.registers.isr.get();
338                self.registers.isr.set(isr_val);
339                isr_val
340            })
341        };
342
343        BitOffsets(isr_val)
344            // Did we enable this interrupt?
345            .filter(|offset| imr_val & (1 << offset) != 0)
346            // Do we have a pin for that interrupt? (Likely)
347            .filter_map(|offset| self.pins.get(offset as usize))
348            // Call client
349            .for_each(|pin| {
350                pin.client.map(|client| client.fired());
351            });
352    }
353}
354
355type GPIO1<'a> = Port<'a, 32>;
356type GPIO2<'a> = Port<'a, 32>;
357type GPIO3<'a> = Port<'a, 28>;
358type GPIO4<'a> = Port<'a, 32>;
359type GPIO5<'a> = Port<'a, 3>;
360
361impl<'a> Port<'a, 32> {
362    const fn new_32(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
363        Self::new(
364            registers,
365            clock,
366            [
367                Pin::new(registers, 00),
368                Pin::new(registers, 01),
369                Pin::new(registers, 02),
370                Pin::new(registers, 03),
371                Pin::new(registers, 04),
372                Pin::new(registers, 05),
373                Pin::new(registers, 06),
374                Pin::new(registers, 07),
375                Pin::new(registers, 08),
376                Pin::new(registers, 09),
377                Pin::new(registers, 10),
378                Pin::new(registers, 11),
379                Pin::new(registers, 12),
380                Pin::new(registers, 13),
381                Pin::new(registers, 14),
382                Pin::new(registers, 15),
383                Pin::new(registers, 16),
384                Pin::new(registers, 17),
385                Pin::new(registers, 18),
386                Pin::new(registers, 19),
387                Pin::new(registers, 20),
388                Pin::new(registers, 21),
389                Pin::new(registers, 22),
390                Pin::new(registers, 23),
391                Pin::new(registers, 24),
392                Pin::new(registers, 25),
393                Pin::new(registers, 26),
394                Pin::new(registers, 27),
395                Pin::new(registers, 28),
396                Pin::new(registers, 29),
397                Pin::new(registers, 30),
398                Pin::new(registers, 31),
399            ],
400        )
401    }
402    const fn gpio1(ccm: &'a ccm::Ccm) -> GPIO1<'a> {
403        Self::new_32(
404            GPIO1_BASE,
405            PortClock(ccm::PeripheralClock::ccgr1(ccm, ccm::HCLK1::GPIO1)),
406        )
407    }
408    const fn gpio2(ccm: &'a ccm::Ccm) -> GPIO2<'a> {
409        Self::new_32(
410            GPIO2_BASE,
411            PortClock(ccm::PeripheralClock::ccgr0(ccm, ccm::HCLK0::GPIO2)),
412        )
413    }
414    const fn gpio4(ccm: &'a ccm::Ccm) -> GPIO4<'a> {
415        Self::new_32(
416            GPIO4_BASE,
417            PortClock(ccm::PeripheralClock::ccgr3(ccm, ccm::HCLK3::GPIO4)),
418        )
419    }
420}
421
422impl<'a> Port<'a, 28> {
423    const fn new_28(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
424        Self::new(
425            registers,
426            clock,
427            [
428                Pin::new(registers, 00),
429                Pin::new(registers, 01),
430                Pin::new(registers, 02),
431                Pin::new(registers, 03),
432                Pin::new(registers, 04),
433                Pin::new(registers, 05),
434                Pin::new(registers, 06),
435                Pin::new(registers, 07),
436                Pin::new(registers, 08),
437                Pin::new(registers, 09),
438                Pin::new(registers, 10),
439                Pin::new(registers, 11),
440                Pin::new(registers, 12),
441                Pin::new(registers, 13),
442                Pin::new(registers, 14),
443                Pin::new(registers, 15),
444                Pin::new(registers, 16),
445                Pin::new(registers, 17),
446                Pin::new(registers, 18),
447                Pin::new(registers, 19),
448                Pin::new(registers, 20),
449                Pin::new(registers, 21),
450                Pin::new(registers, 22),
451                Pin::new(registers, 23),
452                Pin::new(registers, 24),
453                Pin::new(registers, 25),
454                Pin::new(registers, 26),
455                Pin::new(registers, 27),
456            ],
457        )
458    }
459    const fn gpio3(ccm: &'a ccm::Ccm) -> GPIO3<'a> {
460        Self::new_28(
461            GPIO3_BASE,
462            PortClock(ccm::PeripheralClock::ccgr2(ccm, ccm::HCLK2::GPIO3)),
463        )
464    }
465}
466
467impl<'a> Port<'a, 3> {
468    const fn new_3(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
469        Self::new(
470            registers,
471            clock,
472            [
473                Pin::new(registers, 00),
474                Pin::new(registers, 01),
475                Pin::new(registers, 02),
476            ],
477        )
478    }
479    const fn gpio5(ccm: &'a ccm::Ccm) -> GPIO5<'a> {
480        Self::new_3(
481            GPIO5_BASE,
482            PortClock(ccm::PeripheralClock::ccgr1(ccm, ccm::HCLK1::GPIO5)),
483        )
484    }
485}
486
487/// All GPIO ports
488///
489/// Use [`new`](Ports::new) to create all GPIO ports, then use it to access GPIO
490/// pins and individual ports. See the public members for the GPIO ports
491#[non_exhaustive] // Fast GPIOs 6 through 9 not implemented
492pub struct Ports<'a> {
493    pub gpio1: GPIO1<'a>,
494    pub gpio2: GPIO2<'a>,
495    pub gpio3: GPIO3<'a>,
496    pub gpio4: GPIO4<'a>,
497    pub gpio5: GPIO5<'a>,
498}
499
500impl<'a> Ports<'a> {
501    pub const fn new(ccm: &'a ccm::Ccm) -> Self {
502        Self {
503            gpio1: GPIO1::gpio1(ccm),
504            gpio2: GPIO2::gpio2(ccm),
505            gpio3: GPIO3::gpio3(ccm),
506            gpio4: GPIO4::gpio4(ccm),
507            gpio5: GPIO5::gpio5(ccm),
508        }
509    }
510
511    /// Returns a GPIO pin
512    ///
513    /// For an interface that maps more closely to the numbers in
514    /// `GPIO3[17]`, use a combination of the [`Ports`] members, and [`Port::pin()`].
515    /// See the module-level docs for an example.
516    pub fn pin(&self, pin: PinId) -> &Pin<'a> {
517        match pin.port() {
518            GpioPort::GPIO1 => &self.gpio1.pins[pin.offset()],
519            GpioPort::GPIO2 => &self.gpio2.pins[pin.offset()],
520            GpioPort::GPIO3 => &self.gpio3.pins[pin.offset()],
521            GpioPort::GPIO4 => &self.gpio4.pins[pin.offset()],
522            GpioPort::GPIO5 => &self.gpio5.pins[pin.offset()],
523        }
524    }
525}
526
527struct PortClock<'a>(ccm::PeripheralClock<'a>);
528
529impl ClockInterface for PortClock<'_> {
530    fn is_enabled(&self) -> bool {
531        self.0.is_enabled()
532    }
533
534    fn enable(&self) {
535        self.0.enable();
536    }
537
538    fn disable(&self) {
539        self.0.disable();
540    }
541}
542
543/// A GPIO pin, like `GPIO3[17]`
544///
545/// `Pin` implements the `hil::gpio` traits. To acquire a `Pin`,
546///
547/// - use [`Ports::pin`] to reference a `Pin` by a [`PinId`], or
548/// - use a combination of the ports on [`Ports`], and [`Port::pin`]
549pub struct Pin<'a> {
550    registers: StaticRef<GpioRegisters>,
551    offset: usize,
552    client: OptionalCell<&'a dyn hil::gpio::Client>,
553}
554
555trait U32Ext {
556    fn set_bit(self, offset: usize) -> Self;
557    fn clear_bit(self, offset: usize) -> Self;
558    fn is_bit_set(&self, offset: usize) -> bool;
559}
560
561impl U32Ext for u32 {
562    #[inline(always)]
563    fn set_bit(self, offset: usize) -> u32 {
564        self | (1 << offset)
565    }
566    #[inline(always)]
567    fn clear_bit(self, offset: usize) -> u32 {
568        self & !(1 << offset)
569    }
570    #[inline(always)]
571    fn is_bit_set(&self, offset: usize) -> bool {
572        (self & (1 << offset)) != 0
573    }
574}
575
576impl Pin<'_> {
577    /// Fabricate a new `Pin` from a `PinId`
578    pub fn from_pin_id(pin_id: PinId) -> Self {
579        Self::new(
580            match pin_id.port() {
581                GpioPort::GPIO1 => GPIO1_BASE,
582                GpioPort::GPIO2 => GPIO2_BASE,
583                GpioPort::GPIO3 => GPIO3_BASE,
584                GpioPort::GPIO4 => GPIO4_BASE,
585                GpioPort::GPIO5 => GPIO5_BASE,
586            },
587            pin_id.offset(),
588        )
589    }
590    const fn new(registers: StaticRef<GpioRegisters>, offset: usize) -> Self {
591        Pin {
592            registers,
593            offset,
594            client: OptionalCell::empty(),
595        }
596    }
597
598    fn get_mode(&self) -> Mode {
599        if self.registers.gdir.get().is_bit_set(self.offset) {
600            Mode::Output
601        } else {
602            Mode::Input
603        }
604    }
605
606    fn set_mode(&self, mode: Mode) {
607        let gdir = self.registers.gdir.get();
608        let gdir = match mode {
609            Mode::Input => gdir.clear_bit(self.offset),
610            Mode::Output => gdir.set_bit(self.offset),
611        };
612        self.registers.gdir.set(gdir);
613    }
614
615    fn set_output_high(&self) {
616        self.registers.dr_set.set(1 << self.offset);
617    }
618
619    fn set_output_low(&self) {
620        self.registers.dr_clear.set(1 << self.offset);
621    }
622
623    fn is_output_high(&self) -> bool {
624        self.registers.dr.get().is_bit_set(self.offset)
625    }
626
627    fn toggle_output(&self) -> bool {
628        self.registers.dr_toggle.set(1 << self.offset);
629        self.is_output_high()
630    }
631
632    fn read_input(&self) -> bool {
633        self.registers.psr.get().is_bit_set(self.offset)
634    }
635
636    fn mask_interrupt(&self) {
637        let imr = self.registers.imr.get();
638        let imr = imr.clear_bit(self.offset);
639        self.registers.imr.set(imr);
640    }
641
642    fn unmask_interrupt(&self) {
643        let imr = self.registers.imr.get();
644        let imr = imr.set_bit(self.offset);
645        self.registers.imr.set(imr);
646    }
647
648    fn clear_pending(&self) {
649        self.registers.isr.set(1 << self.offset); // W1C
650    }
651
652    fn set_edge_sensitive(&self, sensitive: hil::gpio::InterruptEdge) {
653        use hil::gpio::InterruptEdge::{EitherEdge, FallingEdge, RisingEdge};
654        const RISING_EDGE_SENSITIVE: u32 = 0b10;
655        const FALLING_EDGE_SENSITIVE: u32 = 0b11;
656
657        let edge_sel = self.registers.edge_sel.get();
658        let icr_offset = (self.offset % 16) * 2;
659
660        let sensitive = match sensitive {
661            EitherEdge => {
662                let edge_sel = edge_sel.set_bit(self.offset);
663                self.registers.edge_sel.set(edge_sel);
664                // A high EDGE_SEL disregards the corresponding ICR[1|2] setting
665                return;
666            }
667            RisingEdge => RISING_EDGE_SENSITIVE << icr_offset,
668            FallingEdge => FALLING_EDGE_SENSITIVE << icr_offset,
669        };
670
671        let edge_sel = edge_sel.clear_bit(self.offset);
672        self.registers.edge_sel.set(edge_sel);
673
674        let icr_mask = 0b11 << icr_offset;
675        if self.offset < 16 {
676            let icr1 = self.registers.icr1.get();
677            let icr1 = (icr1 & !icr_mask) | sensitive;
678            self.registers.icr1.set(icr1);
679        } else {
680            let icr2 = self.registers.icr2.get();
681            let icr2 = (icr2 & !icr_mask) | sensitive;
682            self.registers.icr2.set(icr2);
683        }
684    }
685}
686
687impl hil::gpio::Configure for Pin<'_> {
688    fn make_output(&self) -> hil::gpio::Configuration {
689        self.set_mode(Mode::Output);
690        hil::gpio::Configuration::Output
691    }
692
693    fn make_input(&self) -> hil::gpio::Configuration {
694        self.set_mode(Mode::Input);
695        hil::gpio::Configuration::Input
696    }
697
698    fn deactivate_to_low_power(&self) {
699        // Not implemented yet
700    }
701
702    fn disable_output(&self) -> hil::gpio::Configuration {
703        // Not implemented yet
704        hil::gpio::Configuration::LowPower
705    }
706
707    fn disable_input(&self) -> hil::gpio::Configuration {
708        // Not implemented yet
709        hil::gpio::Configuration::LowPower
710    }
711
712    // PullUp or PullDown mode are set through the Iomux module
713    fn set_floating_state(&self, _mode: hil::gpio::FloatingState) {}
714
715    fn floating_state(&self) -> hil::gpio::FloatingState {
716        hil::gpio::FloatingState::PullNone
717    }
718
719    fn configuration(&self) -> hil::gpio::Configuration {
720        match self.get_mode() {
721            Mode::Input => hil::gpio::Configuration::Input,
722            Mode::Output => hil::gpio::Configuration::Output,
723        }
724    }
725}
726
727impl hil::gpio::Output for Pin<'_> {
728    fn set(&self) {
729        self.set_output_high();
730    }
731
732    fn clear(&self) {
733        self.set_output_low();
734    }
735
736    fn toggle(&self) -> bool {
737        self.toggle_output()
738    }
739}
740
741impl hil::gpio::Input for Pin<'_> {
742    fn read(&self) -> bool {
743        self.read_input()
744    }
745}
746
747impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> {
748    fn enable_interrupts(&self, mode: hil::gpio::InterruptEdge) {
749        unsafe {
750            atomic(|| {
751                // disable the interrupt
752                self.mask_interrupt();
753                self.clear_pending();
754                self.set_edge_sensitive(mode);
755
756                self.unmask_interrupt();
757            });
758        }
759    }
760
761    fn disable_interrupts(&self) {
762        unsafe {
763            atomic(|| {
764                self.mask_interrupt();
765                self.clear_pending();
766            });
767        }
768    }
769
770    fn set_client(&self, client: &'a dyn hil::gpio::Client) {
771        self.client.set(client);
772    }
773
774    fn is_pending(&self) -> bool {
775        self.registers.isr.get().is_bit_set(self.offset)
776    }
777}
778
779/// An iterator that returns the offsets of each high bit
780///
781/// Each offset is returned only once. There is no guarantee
782/// for iteration order.
783struct BitOffsets(u32);
784
785impl Iterator for BitOffsets {
786    type Item = u32;
787    fn next(&mut self) -> Option<Self::Item> {
788        if self.0 != 0 {
789            let offset = self.0.trailing_zeros();
790            self.0 &= self.0 - 1;
791            Some(offset)
792        } else {
793            None
794        }
795    }
796    fn size_hint(&self) -> (usize, Option<usize>) {
797        let popcnt = self.0.count_ones() as usize;
798        (popcnt, Some(popcnt))
799    }
800}
801
802impl ExactSizeIterator for BitOffsets {}
803
804#[cfg(test)]
805mod tests {
806    use super::BitOffsets;
807
808    #[test]
809    fn bit_offsets() {
810        fn check(word: u32, expected: impl ExactSizeIterator<Item = u32>) {
811            let offsets = BitOffsets(word);
812            assert_eq!(offsets.len(), expected.len());
813            assert!(
814                offsets.eq(expected),
815                "Incorrect bit offsets for word {:#b}",
816                word
817            );
818        }
819
820        check(0, core::iter::empty());
821        check(u32::max_value(), 0..32);
822        check(u32::max_value() >> 1, 0..31);
823        check(u32::max_value() << 1, 1..32);
824        check(0x5555_5555, (0..32).step_by(2));
825        check(0xAAAA_AAAA, (0..32).skip(1).step_by(2));
826    }
827}