zynq7000_hal/gpio/
mio.rs

1//! Multiplexed I/O (MIO) module.
2//!
3//! This module provides a [singleton][Pins] for the resource management of all MIO pins. This
4//! also allows associating the pins, their modes and their IDs to the peripherals they are able to
5//! serve.
6use arbitrary_int::{u2, u3};
7use zynq7000::gpio::MmioGpio;
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub struct MuxConfig {
11    l3: u3,
12    l2: u2,
13    l1: bool,
14    l0: bool,
15}
16
17impl From<zynq7000::slcr::mio::Config> for MuxConfig {
18    fn from(value: zynq7000::slcr::mio::Config) -> Self {
19        Self::new(
20            value.l0_sel(),
21            value.l1_sel(),
22            value.l2_sel(),
23            value.l3_sel(),
24        )
25    }
26}
27
28impl MuxConfig {
29    #[inline]
30    pub const fn new(l0: bool, l1: bool, l2: u2, l3: u3) -> Self {
31        Self { l3, l2, l1, l0 }
32    }
33
34    #[inline]
35    pub const fn new_with_l0() -> Self {
36        Self::new(true, false, u2::new(0b00), u3::new(0b000))
37    }
38
39    #[inline]
40    pub const fn new_with_l1() -> Self {
41        Self::new(false, true, u2::new(0b00), u3::new(0b000))
42    }
43
44    #[inline]
45    pub const fn new_with_l2(l2: u2) -> Self {
46        Self::new(false, false, l2, u3::new(0b000))
47    }
48
49    #[inline]
50    pub const fn new_with_l3(l3: u3) -> Self {
51        Self::new(false, false, u2::new(0b00), l3)
52    }
53
54    #[inline]
55    pub const fn new_for_gpio() -> Self {
56        Self::new(false, false, u2::new(0), u3::new(0))
57    }
58
59    #[inline]
60    pub const fn l0_sel(&self) -> bool {
61        self.l0
62    }
63
64    #[inline]
65    pub const fn l1_sel(&self) -> bool {
66        self.l1
67    }
68
69    #[inline]
70    pub const fn l2_sel(&self) -> u2 {
71        self.l2
72    }
73
74    #[inline]
75    pub const fn l3_sel(&self) -> u3 {
76        self.l3
77    }
78}
79
80pub trait PinId {
81    const OFFSET: usize;
82}
83
84macro_rules! pin_id {
85    ($Id:ident, $num:literal) => {
86        // Need paste macro to use ident in doc attribute
87        paste::paste! {
88            #[doc = "Pin ID representing pin " $Id]
89            #[derive(Debug)]
90            pub enum $Id {}
91            impl $crate::sealed::Sealed for $Id {}
92            impl PinId for $Id {
93                const OFFSET: usize = $num;
94            }
95        }
96    };
97}
98
99pin_id!(Mio0, 0);
100pin_id!(Mio1, 1);
101pin_id!(Mio2, 2);
102pin_id!(Mio3, 3);
103pin_id!(Mio4, 4);
104pin_id!(Mio5, 5);
105pin_id!(Mio6, 6);
106pin_id!(Mio7, 7);
107pin_id!(Mio8, 8);
108pin_id!(Mio9, 9);
109pin_id!(Mio10, 10);
110pin_id!(Mio11, 11);
111pin_id!(Mio12, 12);
112pin_id!(Mio13, 13);
113pin_id!(Mio14, 14);
114pin_id!(Mio15, 15);
115#[cfg(not(feature = "7z010-7z007s-clg225"))]
116pin_id!(Mio16, 16);
117#[cfg(not(feature = "7z010-7z007s-clg225"))]
118pin_id!(Mio17, 17);
119#[cfg(not(feature = "7z010-7z007s-clg225"))]
120pin_id!(Mio18, 18);
121#[cfg(not(feature = "7z010-7z007s-clg225"))]
122pin_id!(Mio19, 19);
123#[cfg(not(feature = "7z010-7z007s-clg225"))]
124pin_id!(Mio20, 20);
125#[cfg(not(feature = "7z010-7z007s-clg225"))]
126pin_id!(Mio21, 21);
127#[cfg(not(feature = "7z010-7z007s-clg225"))]
128pin_id!(Mio22, 22);
129#[cfg(not(feature = "7z010-7z007s-clg225"))]
130pin_id!(Mio23, 23);
131#[cfg(not(feature = "7z010-7z007s-clg225"))]
132pin_id!(Mio24, 24);
133#[cfg(not(feature = "7z010-7z007s-clg225"))]
134pin_id!(Mio25, 25);
135#[cfg(not(feature = "7z010-7z007s-clg225"))]
136pin_id!(Mio26, 26);
137#[cfg(not(feature = "7z010-7z007s-clg225"))]
138pin_id!(Mio27, 27);
139pin_id!(Mio28, 28);
140pin_id!(Mio29, 29);
141pin_id!(Mio30, 30);
142pin_id!(Mio31, 31);
143
144pin_id!(Mio32, 32);
145pin_id!(Mio33, 33);
146pin_id!(Mio34, 34);
147pin_id!(Mio35, 35);
148pin_id!(Mio36, 36);
149pin_id!(Mio37, 37);
150pin_id!(Mio38, 38);
151pin_id!(Mio39, 39);
152#[cfg(not(feature = "7z010-7z007s-clg225"))]
153pin_id!(Mio40, 40);
154#[cfg(not(feature = "7z010-7z007s-clg225"))]
155pin_id!(Mio41, 41);
156#[cfg(not(feature = "7z010-7z007s-clg225"))]
157pin_id!(Mio42, 42);
158#[cfg(not(feature = "7z010-7z007s-clg225"))]
159pin_id!(Mio43, 43);
160#[cfg(not(feature = "7z010-7z007s-clg225"))]
161pin_id!(Mio44, 44);
162#[cfg(not(feature = "7z010-7z007s-clg225"))]
163pin_id!(Mio45, 45);
164#[cfg(not(feature = "7z010-7z007s-clg225"))]
165pin_id!(Mio46, 46);
166#[cfg(not(feature = "7z010-7z007s-clg225"))]
167pin_id!(Mio47, 47);
168pin_id!(Mio48, 48);
169pin_id!(Mio49, 49);
170#[cfg(not(feature = "7z010-7z007s-clg225"))]
171pin_id!(Mio50, 50);
172#[cfg(not(feature = "7z010-7z007s-clg225"))]
173pin_id!(Mio51, 51);
174pin_id!(Mio52, 52);
175pin_id!(Mio53, 53);
176
177pub trait MioPin: crate::sealed::Sealed {
178    fn offset(&self) -> usize;
179}
180
181pub struct Pin<I: PinId> {
182    phantom: core::marker::PhantomData<I>,
183}
184
185impl<I: PinId> Pin<I> {
186    #[inline]
187    const unsafe fn new() -> Self {
188        Self {
189            //pin: LowLevelPin::new(I::OFFSET),
190            phantom: core::marker::PhantomData,
191        }
192    }
193
194    /// Steal a typed MIO pin.
195    ///
196    /// Usually, you can just use the MIO pin members of the [Pins] structure.
197    /// However, if you pass the pins into a consuming peripheral driver which performs
198    /// immediate type erasure, and you require the pins for/after a re-configuration
199    /// of the system, you can unsafely steal the pin. This function will NOT perform any
200    /// re-configuration.
201    ///
202    /// # Safety
203    ///
204    /// This allows to create multiple instances of the same pin, which can lead to
205    /// data races on concurrent access.
206    #[inline]
207    pub const unsafe fn steal() -> Self {
208        unsafe { Self::new() }
209    }
210}
211
212pub struct Pins {
213    pub mio0: Pin<Mio0>,
214    pub mio1: Pin<Mio1>,
215    pub mio2: Pin<Mio2>,
216    pub mio3: Pin<Mio3>,
217    pub mio4: Pin<Mio4>,
218    pub mio5: Pin<Mio5>,
219    pub mio6: Pin<Mio6>,
220    pub mio7: Pin<Mio7>,
221    pub mio8: Pin<Mio8>,
222    pub mio9: Pin<Mio9>,
223    pub mio10: Pin<Mio10>,
224    pub mio11: Pin<Mio11>,
225    pub mio12: Pin<Mio12>,
226    pub mio13: Pin<Mio13>,
227    pub mio14: Pin<Mio14>,
228    pub mio15: Pin<Mio15>,
229    #[cfg(not(feature = "7z010-7z007s-clg225"))]
230    pub mio16: Pin<Mio16>,
231    #[cfg(not(feature = "7z010-7z007s-clg225"))]
232    pub mio17: Pin<Mio17>,
233    #[cfg(not(feature = "7z010-7z007s-clg225"))]
234    pub mio18: Pin<Mio18>,
235    #[cfg(not(feature = "7z010-7z007s-clg225"))]
236    pub mio19: Pin<Mio19>,
237    #[cfg(not(feature = "7z010-7z007s-clg225"))]
238    pub mio20: Pin<Mio20>,
239    #[cfg(not(feature = "7z010-7z007s-clg225"))]
240    pub mio21: Pin<Mio21>,
241    #[cfg(not(feature = "7z010-7z007s-clg225"))]
242    pub mio22: Pin<Mio22>,
243    #[cfg(not(feature = "7z010-7z007s-clg225"))]
244    pub mio23: Pin<Mio23>,
245    #[cfg(not(feature = "7z010-7z007s-clg225"))]
246    pub mio24: Pin<Mio24>,
247    #[cfg(not(feature = "7z010-7z007s-clg225"))]
248    pub mio25: Pin<Mio25>,
249    #[cfg(not(feature = "7z010-7z007s-clg225"))]
250    pub mio26: Pin<Mio26>,
251    #[cfg(not(feature = "7z010-7z007s-clg225"))]
252    pub mio27: Pin<Mio27>,
253    pub mio28: Pin<Mio28>,
254    pub mio29: Pin<Mio29>,
255    pub mio30: Pin<Mio30>,
256    pub mio31: Pin<Mio31>,
257
258    pub mio32: Pin<Mio32>,
259    pub mio33: Pin<Mio33>,
260    pub mio34: Pin<Mio34>,
261    pub mio35: Pin<Mio35>,
262    pub mio36: Pin<Mio36>,
263    pub mio37: Pin<Mio37>,
264    pub mio38: Pin<Mio38>,
265    pub mio39: Pin<Mio39>,
266    #[cfg(not(feature = "7z010-7z007s-clg225"))]
267    pub mio40: Pin<Mio40>,
268    #[cfg(not(feature = "7z010-7z007s-clg225"))]
269    pub mio41: Pin<Mio41>,
270    #[cfg(not(feature = "7z010-7z007s-clg225"))]
271    pub mio42: Pin<Mio42>,
272    #[cfg(not(feature = "7z010-7z007s-clg225"))]
273    pub mio43: Pin<Mio43>,
274    #[cfg(not(feature = "7z010-7z007s-clg225"))]
275    #[cfg(not(feature = "7z010-7z007s-clg225"))]
276    pub mio44: Pin<Mio44>,
277    #[cfg(not(feature = "7z010-7z007s-clg225"))]
278    pub mio45: Pin<Mio45>,
279    #[cfg(not(feature = "7z010-7z007s-clg225"))]
280    pub mio46: Pin<Mio46>,
281    #[cfg(not(feature = "7z010-7z007s-clg225"))]
282    pub mio47: Pin<Mio47>,
283    pub mio48: Pin<Mio48>,
284    pub mio49: Pin<Mio49>,
285    #[cfg(not(feature = "7z010-7z007s-clg225"))]
286    pub mio50: Pin<Mio50>,
287    #[cfg(not(feature = "7z010-7z007s-clg225"))]
288    pub mio51: Pin<Mio51>,
289    pub mio52: Pin<Mio52>,
290    pub mio53: Pin<Mio53>,
291}
292
293impl Pins {
294    pub const fn new(_mmio: MmioGpio) -> Self {
295        Self {
296            mio0: unsafe { Pin::new() },
297            mio1: unsafe { Pin::new() },
298            mio2: unsafe { Pin::new() },
299            mio3: unsafe { Pin::new() },
300            mio4: unsafe { Pin::new() },
301            mio5: unsafe { Pin::new() },
302            mio6: unsafe { Pin::new() },
303            mio7: unsafe { Pin::new() },
304            mio8: unsafe { Pin::new() },
305            mio9: unsafe { Pin::new() },
306            mio10: unsafe { Pin::new() },
307            mio11: unsafe { Pin::new() },
308            mio12: unsafe { Pin::new() },
309            mio13: unsafe { Pin::new() },
310            mio14: unsafe { Pin::new() },
311            mio15: unsafe { Pin::new() },
312            #[cfg(not(feature = "7z010-7z007s-clg225"))]
313            mio16: unsafe { Pin::new() },
314            #[cfg(not(feature = "7z010-7z007s-clg225"))]
315            mio17: unsafe { Pin::new() },
316            #[cfg(not(feature = "7z010-7z007s-clg225"))]
317            mio18: unsafe { Pin::new() },
318            #[cfg(not(feature = "7z010-7z007s-clg225"))]
319            mio19: unsafe { Pin::new() },
320            #[cfg(not(feature = "7z010-7z007s-clg225"))]
321            mio20: unsafe { Pin::new() },
322            #[cfg(not(feature = "7z010-7z007s-clg225"))]
323            mio21: unsafe { Pin::new() },
324            #[cfg(not(feature = "7z010-7z007s-clg225"))]
325            mio22: unsafe { Pin::new() },
326            #[cfg(not(feature = "7z010-7z007s-clg225"))]
327            mio23: unsafe { Pin::new() },
328            #[cfg(not(feature = "7z010-7z007s-clg225"))]
329            mio24: unsafe { Pin::new() },
330            #[cfg(not(feature = "7z010-7z007s-clg225"))]
331            mio25: unsafe { Pin::new() },
332            #[cfg(not(feature = "7z010-7z007s-clg225"))]
333            mio26: unsafe { Pin::new() },
334            #[cfg(not(feature = "7z010-7z007s-clg225"))]
335            mio27: unsafe { Pin::new() },
336            mio28: unsafe { Pin::new() },
337            mio29: unsafe { Pin::new() },
338            mio30: unsafe { Pin::new() },
339            mio31: unsafe { Pin::new() },
340
341            mio32: unsafe { Pin::new() },
342            mio33: unsafe { Pin::new() },
343            mio34: unsafe { Pin::new() },
344            mio35: unsafe { Pin::new() },
345            mio36: unsafe { Pin::new() },
346            mio37: unsafe { Pin::new() },
347            mio38: unsafe { Pin::new() },
348            mio39: unsafe { Pin::new() },
349            #[cfg(not(feature = "7z010-7z007s-clg225"))]
350            mio40: unsafe { Pin::new() },
351            #[cfg(not(feature = "7z010-7z007s-clg225"))]
352            mio41: unsafe { Pin::new() },
353            #[cfg(not(feature = "7z010-7z007s-clg225"))]
354            mio42: unsafe { Pin::new() },
355            #[cfg(not(feature = "7z010-7z007s-clg225"))]
356            mio43: unsafe { Pin::new() },
357            #[cfg(not(feature = "7z010-7z007s-clg225"))]
358            mio44: unsafe { Pin::new() },
359            #[cfg(not(feature = "7z010-7z007s-clg225"))]
360            mio45: unsafe { Pin::new() },
361            #[cfg(not(feature = "7z010-7z007s-clg225"))]
362            mio46: unsafe { Pin::new() },
363            #[cfg(not(feature = "7z010-7z007s-clg225"))]
364            mio47: unsafe { Pin::new() },
365            mio48: unsafe { Pin::new() },
366            mio49: unsafe { Pin::new() },
367            #[cfg(not(feature = "7z010-7z007s-clg225"))]
368            mio50: unsafe { Pin::new() },
369            #[cfg(not(feature = "7z010-7z007s-clg225"))]
370            mio51: unsafe { Pin::new() },
371            mio52: unsafe { Pin::new() },
372            mio53: unsafe { Pin::new() },
373        }
374    }
375}
376
377impl<I: PinId> MioPin for Pin<I> {
378    fn offset(&self) -> usize {
379        I::OFFSET
380    }
381}
382
383impl<I: PinId> crate::sealed::Sealed for Pin<I> {}