zynq7000_hal/gpio/
emio.rs

1//! EMIO (Extended Multiplexed I/O) resource management module.
2use zynq7000::gpio::MmioGpio;
3
4pub use crate::gpio::PinState;
5
6pub struct EmioPin {
7    offset: usize,
8}
9
10impl EmioPin {
11    /// Steal an EMIO peripheral instance pin.
12    ///
13    /// It is recommended to retrieve EMIO pins safely by using the [Pins::new] and [Pins::take]
14    /// API instead
15    ///
16    /// # Safety
17    ///
18    /// This allows to create multiple instances of the same pin, which can lead to
19    /// data races on concurrent access.
20    pub unsafe fn steal(offset: usize) -> Self {
21        Self { offset }
22    }
23
24    /// This offset ranges from 0 to 64.
25    pub fn offset(&self) -> usize {
26        self.offset
27    }
28}
29
30pub struct Pins {
31    emios: [Option<EmioPin>; 64],
32}
33
34impl Pins {
35    /// Create a new EMIO pin structure.
36    ///
37    /// This structure is supposed to be used as a singleton. It will configure all
38    /// EMIO pins as inputs. If you want to retrieve individual pins without this structure,
39    /// use [EmioPin::steal] instead.
40    pub fn new(mut mmio: MmioGpio) -> Self {
41        let mut emios = [const { None }; 64];
42        // Configure all EMIO pins as inputs.
43        mmio.bank_2().write_dirm(0);
44        mmio.bank_3().write_dirm(0);
45
46        (0..64).for_each(|i| {
47            emios[i] = Some(EmioPin { offset: i });
48        });
49        Self { emios }
50    }
51
52    pub fn take(&mut self, offset: usize) -> Option<EmioPin> {
53        self.emios[offset].take()
54    }
55
56    pub fn give(&mut self, emio: EmioPin) {
57        self.emios[emio.offset].replace(emio);
58    }
59}