pi_pinout/
lib.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
4pub struct PhysicalPin(pub u8);
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
7pub struct GpioPin(pub u8);
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
10pub struct WiringPiPin(pub u8);
11
12// Pin Translation Table
13//
14// | Physical | GPIO | WiringPi |
15// |----------|------|----------|
16// | 3        | 2    | 8        |
17// | 5        | 3    | 9        |
18// | 7        | 4    | 7        |
19// | 8        | 14   | 15       |
20// | 10       | 15   | 16       |
21// | 11       | 17   | 0        |
22// | 12       | 18   | 1        |
23// | 13       | 27   | 2        |
24// | 15       | 22   | 3        |
25// | 16       | 23   | 4        |
26// | 18       | 24   | 5        |
27// | 19       | 10   | 12       |
28// | 21       | 9    | 13       |
29// | 22       | 25   | 6        |
30// | 23       | 11   | 14       |
31// | 24       | 8    | 10       |
32// | 26       | 7    | 11       |
33// | 27       | 0    | 30       |
34// | 28       | 1    | 31       |
35// | 29       | 5    | 21       |
36// | 31       | 6    | 22       |
37// | 32       | 12   | 26       |
38// | 33       | 13   | 23       |
39// | 35       | 19   | 24       |
40// | 36       | 16   | 27       |
41// | 37       | 26   | 25       |
42// | 38       | 20   | 28       |
43// | 40       | 21   | 29       |
44
45impl From<PhysicalPin> for GpioPin {
46    fn from(pin: PhysicalPin) -> Self {
47        GpioPin(match pin.0 {
48            3 => 2,
49            5 => 3,
50            7 => 4,
51            8 => 14,
52            10 => 15,
53            11 => 17,
54            12 => 18,
55            13 => 27,
56            15 => 22,
57            16 => 23,
58            18 => 24,
59            19 => 10,
60            21 => 9,
61            22 => 25,
62            23 => 11,
63            24 => 8,
64            26 => 7,
65            27 => 0,
66            28 => 1,
67            29 => 5,
68            31 => 6,
69            32 => 12,
70            33 => 13,
71            35 => 19,
72            36 => 16,
73            37 => 26,
74            38 => 20,
75            40 => 21,
76            _ => panic!("Invalid pin number"),
77        })
78    }
79}
80
81impl From<PhysicalPin> for WiringPiPin {
82    fn from(pin: PhysicalPin) -> Self {
83        WiringPiPin(match pin.0 {
84            3 => 8,
85            5 => 9,
86            7 => 7,
87            8 => 15,
88            10 => 16,
89            11 => 0,
90            12 => 1,
91            13 => 2,
92            15 => 3,
93            16 => 4,
94            18 => 5,
95            19 => 12,
96            21 => 13,
97            22 => 6,
98            23 => 14,
99            24 => 10,
100            26 => 11,
101            27 => 30,
102            28 => 31,
103            29 => 21,
104            31 => 22,
105            32 => 26,
106            33 => 23,
107            35 => 24,
108            36 => 27,
109            37 => 25,
110            38 => 28,
111            40 => 29,
112            _ => panic!("Invalid pin number"),
113        })
114    }
115}
116
117impl From<GpioPin> for PhysicalPin {
118    fn from(pin: GpioPin) -> Self {
119        PhysicalPin(match pin.0 {
120            2 => 3,
121            3 => 5,
122            4 => 7,
123            14 => 8,
124            15 => 10,
125            17 => 11,
126            18 => 12,
127            27 => 13,
128            22 => 15,
129            23 => 16,
130            24 => 18,
131            10 => 19,
132            9 => 21,
133            25 => 22,
134            11 => 23,
135            8 => 24,
136            7 => 26,
137            0 => 27,
138            1 => 28,
139            5 => 29,
140            6 => 31,
141            12 => 32,
142            13 => 33,
143            19 => 35,
144            16 => 36,
145            26 => 37,
146            20 => 38,
147            21 => 40,
148            _ => panic!("Invalid pin number"),
149        })
150    }
151}
152
153impl From<GpioPin> for WiringPiPin {
154    fn from(pin: GpioPin) -> Self {
155        WiringPiPin(match pin.0 {
156            2 => 8,
157            3 => 9,
158            4 => 7,
159            14 => 15,
160            15 => 16,
161            17 => 0,
162            18 => 1,
163            27 => 2,
164            22 => 3,
165            23 => 4,
166            24 => 5,
167            10 => 12,
168            9 => 13,
169            25 => 6,
170            11 => 14,
171            8 => 10,
172            7 => 11,
173            0 => 30,
174            1 => 31,
175            5 => 21,
176            6 => 22,
177            12 => 26,
178            13 => 23,
179            19 => 24,
180            16 => 27,
181            26 => 25,
182            20 => 28,
183            21 => 29,
184            _ => panic!("Invalid pin number"),
185        })
186    }
187}
188
189impl From<WiringPiPin> for PhysicalPin {
190    fn from(pin: WiringPiPin) -> Self {
191        PhysicalPin(match pin.0 {
192            8 => 3,
193            9 => 5,
194            7 => 7,
195            15 => 8,
196            16 => 10,
197            0 => 11,
198            1 => 12,
199            2 => 13,
200            3 => 15,
201            4 => 16,
202            5 => 18,
203            12 => 19,
204            13 => 21,
205            6 => 22,
206            14 => 23,
207            10 => 24,
208            11 => 26,
209            30 => 27,
210            31 => 28,
211            21 => 29,
212            22 => 31,
213            26 => 32,
214            23 => 33,
215            24 => 35,
216            27 => 36,
217            25 => 37,
218            28 => 38,
219            29 => 40,
220            _ => panic!("Invalid pin number"),
221        })
222    }
223}
224
225impl From<WiringPiPin> for GpioPin {
226    fn from(pin: WiringPiPin) -> Self {
227        GpioPin(match pin.0 {
228            8 => 2,
229            9 => 3,
230            7 => 4,
231            15 => 14,
232            16 => 15,
233            0 => 17,
234            1 => 18,
235            2 => 27,
236            3 => 22,
237            4 => 23,
238            5 => 24,
239            12 => 10,
240            13 => 9,
241            6 => 25,
242            14 => 11,
243            10 => 8,
244            11 => 7,
245            30 => 0,
246            31 => 1,
247            21 => 5,
248            22 => 6,
249            26 => 12,
250            23 => 13,
251            24 => 19,
252            27 => 16,
253            25 => 26,
254            28 => 20,
255            29 => 21,
256            _ => panic!("Invalid pin number"),
257        })
258    }
259}
260
261mod tests {
262    use super::*;
263
264    #[test]
265    fn test_physical_to_gpio() {
266        assert_eq!(
267            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(3)),
268            GpioPin(22)
269        );
270        assert_eq!(
271            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(5)),
272            GpioPin(24)
273        );
274        assert_eq!(
275            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(7)),
276            GpioPin(4)
277        );
278        assert_eq!(
279            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(8)),
280            GpioPin(2)
281        );
282    }
283
284    #[test]
285    fn test_physical_to_wiringpi() {
286        assert_eq!(
287            <PhysicalPin as Into<WiringPiPin>>::into(PhysicalPin(3)),
288            WiringPiPin(8)
289        );
290        assert_eq!(
291            <PhysicalPin as Into<WiringPiPin>>::into(PhysicalPin(5)),
292            WiringPiPin(9)
293        );
294        assert_eq!(
295            <PhysicalPin as Into<WiringPiPin>>::into(PhysicalPin(7)),
296            WiringPiPin(7)
297        );
298        assert_eq!(
299            <PhysicalPin as Into<WiringPiPin>>::into(PhysicalPin(8)),
300            WiringPiPin(15)
301        );
302    }
303
304    #[test]
305    fn test_gpio_to_physical() {
306        assert_eq!(
307            <GpioPin as Into<PhysicalPin>>::into(GpioPin(2)),
308            PhysicalPin(3)
309        );
310        assert_eq!(
311            <GpioPin as Into<PhysicalPin>>::into(GpioPin(3)),
312            PhysicalPin(5)
313        );
314        assert_eq!(
315            <GpioPin as Into<PhysicalPin>>::into(GpioPin(4)),
316            PhysicalPin(7)
317        );
318        assert_eq!(
319            <GpioPin as Into<PhysicalPin>>::into(GpioPin(14)),
320            PhysicalPin(8)
321        );
322    }
323
324    #[test]
325    fn test_gpio_to_wiringpi() {
326        assert_eq!(
327            <GpioPin as Into<WiringPiPin>>::into(GpioPin(2)),
328            WiringPiPin(8)
329        );
330        assert_eq!(
331            <GpioPin as Into<WiringPiPin>>::into(GpioPin(3)),
332            WiringPiPin(9)
333        );
334        assert_eq!(
335            <GpioPin as Into<WiringPiPin>>::into(GpioPin(4)),
336            WiringPiPin(7)
337        );
338        assert_eq!(
339            <GpioPin as Into<WiringPiPin>>::into(GpioPin(14)),
340            WiringPiPin(15)
341        );
342    }
343
344    #[test]
345    fn test_wiringpi_to_physical() {
346        assert_eq!(
347            <WiringPiPin as Into<PhysicalPin>>::into(WiringPiPin(8)),
348            PhysicalPin(3)
349        );
350        assert_eq!(
351            <WiringPiPin as Into<PhysicalPin>>::into(WiringPiPin(9)),
352            PhysicalPin(5)
353        );
354        assert_eq!(
355            <WiringPiPin as Into<PhysicalPin>>::into(WiringPiPin(7)),
356            PhysicalPin(7)
357        );
358        assert_eq!(
359            <WiringPiPin as Into<PhysicalPin>>::into(WiringPiPin(15)),
360            PhysicalPin(8)
361        );
362    }
363
364    #[test]
365    fn test_wiringpi_to_gpio() {
366        assert_eq!(
367            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(8)),
368            GpioPin(2)
369        );
370        assert_eq!(
371            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(9)),
372            GpioPin(3)
373        );
374        assert_eq!(
375            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(7)),
376            GpioPin(4)
377        );
378        assert_eq!(
379            <WiringPiPin as Into<GpioPin>>::into(WiringPiPin(15)),
380            GpioPin(14)
381        );
382    }
383}