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}