Skip to main content

piggpio/
lib.rs

1/// There are two implementations of the `HW` struct.
2///
3#[cfg(all(
4    target_os = "linux",
5    any(target_arch = "aarch64", target_arch = "arm"),
6    target_env = "gnu"
7))]
8pub mod pi;
9
10#[cfg(all(
11    target_os = "linux",
12    any(target_arch = "aarch64", target_arch = "arm"),
13    target_env = "gnu"
14))]
15pub use pi::HW;
16
17#[cfg(not(all(
18    target_os = "linux",
19    any(target_arch = "aarch64", target_arch = "arm"),
20    target_env = "gnu"
21)))]
22pub mod fake_pi;
23
24#[cfg(not(all(
25    target_os = "linux",
26    any(target_arch = "aarch64", target_arch = "arm"),
27    target_env = "gnu"
28)))]
29pub use fake_pi::HW;
30use pigdef::description::HardwareDescription;
31
32mod pin_descriptions;
33
34pub mod config;
35
36/// Return the Description of the local GPIO hardware is available for use on this machine
37pub fn local_hardware() -> Option<HardwareDescription> {
38    // release build - Not Pi hardware
39    #[cfg(all(
40        not(debug_assertions),
41        not(all(
42            target_os = "linux",
43            any(target_arch = "aarch64", target_arch = "arm"),
44            target_env = "gnu"
45        ))
46    ))]
47    return None;
48
49    // debug build or Pi hardware
50    #[cfg(any(
51        debug_assertions,
52        all(
53            target_os = "linux",
54            any(target_arch = "aarch64", target_arch = "arm"),
55            target_env = "gnu"
56        )
57    ))]
58    Some(HW::new().description().clone())
59}
60
61/// Create a new HW instance - should only be called once
62pub fn get_hardware() -> Option<HW> {
63    // release build - Not Pi hardware
64    #[cfg(all(
65        not(debug_assertions),
66        not(all(
67            target_os = "linux",
68            any(target_arch = "aarch64", target_arch = "arm"),
69            target_env = "gnu"
70        ))
71    ))]
72    return None;
73
74    // debug build or Pi hardware
75    #[cfg(any(
76        debug_assertions,
77        all(
78            target_os = "linux",
79            any(target_arch = "aarch64", target_arch = "arm"),
80            target_env = "gnu"
81        )
82    ))]
83    Some(HW::new())
84}
85
86#[cfg(test)]
87mod test {
88    use pigdef::description::{PinDescription, PinDescriptionSet};
89    use pigdef::pin_function::PinFunction;
90    use std::borrow::Cow;
91
92    #[test]
93    fn get_hardware() {
94        let hw = crate::get_hardware().expect("Could not get hardware");
95        let description = hw.description();
96        let pins = description.pins.pins();
97        assert_eq!(pins.len(), 40);
98        assert_eq!(pins[0].name, "3V3")
99    }
100
101    #[test]
102    fn hw_can_be_got() {
103        let _hw = crate::get_hardware().expect("Could not get hardware");
104    }
105
106    #[test]
107    fn forty_board_pins() {
108        let hw = crate::get_hardware().expect("Could not get hardware");
109        assert_eq!(hw.description().pins.pins().len(), 40);
110    }
111
112    #[test]
113    fn bcm_pins_sort_in_order() {
114        // 0-27, not counting the gpio0 and gpio1 pins with no options
115        let hw = crate::get_hardware().expect("Could not get hardware");
116        let pin_set = hw.description().pins.clone();
117        let sorted_bcm_pins = pin_set.bcm_pins_sorted();
118        assert_eq!(pin_set.bcm_pins_sorted().len(), 26);
119        let mut previous = 1; // we start at GPIO2
120        for pin in sorted_bcm_pins {
121            assert_eq!(pin.bcm.expect("Could not get BCM pin number"), previous + 1);
122            previous = pin.bcm.expect("Could not get BCM pin number");
123        }
124    }
125
126    #[test]
127    fn display_pin_description() {
128        let pin = PinDescription {
129            bpn: 7,
130            bcm: Some(11),
131            name: Cow::from("Fake Pin"),
132            options: Cow::from(vec![]),
133        };
134
135        println!("Pin: {pin}");
136    }
137
138    #[test]
139    fn sort_bcm() {
140        let pin7 = PinDescription {
141            bpn: 7,
142            bcm: Some(11),
143            name: Cow::from("Fake Pin"),
144            options: Cow::from(vec![PinFunction::Input(None), PinFunction::Output(None)]),
145        };
146
147        let pin8 = PinDescription {
148            bpn: 8,
149            bcm: Some(1),
150            name: Cow::from("Fake Pin"),
151            options: Cow::from(vec![PinFunction::Input(None), PinFunction::Output(None)]),
152        };
153
154        let pins = [
155            pin7.clone(),
156            pin8,
157            pin7.clone(),
158            pin7.clone(),
159            pin7.clone(),
160            pin7.clone(),
161            pin7.clone(),
162            pin7.clone(),
163            pin7.clone(),
164            pin7.clone(),
165            pin7.clone(),
166            pin7.clone(),
167            pin7.clone(),
168            pin7.clone(),
169            pin7.clone(),
170            pin7.clone(),
171            pin7.clone(),
172            pin7.clone(),
173            pin7.clone(),
174            pin7.clone(),
175            pin7.clone(),
176            pin7.clone(),
177            pin7.clone(),
178            pin7.clone(),
179            pin7.clone(),
180            pin7.clone(),
181            pin7.clone(),
182            pin7.clone(),
183            pin7.clone(),
184            pin7.clone(),
185            pin7.clone(),
186            pin7.clone(),
187            pin7.clone(),
188            pin7.clone(),
189            pin7.clone(),
190            pin7.clone(),
191            pin7.clone(),
192            pin7.clone(),
193            pin7.clone(),
194            pin7.clone(),
195        ];
196        let pin_set = PinDescriptionSet::new(&pins);
197        assert_eq!(
198            pin_set
199                .pins()
200                .first()
201                .expect("Could not get pin")
202                .bcm
203                .expect("Could not get BCM Pin Number"),
204            11
205        );
206        assert_eq!(
207            pin_set
208                .pins()
209                .get(1)
210                .expect("Could not get pin")
211                .bcm
212                .expect("Could not get BCM Pin Number"),
213            1
214        );
215        assert_eq!(
216            pin_set
217                .bcm_pins_sorted()
218                .first()
219                .expect("Could not get pin")
220                .bcm
221                .expect("Could not get BCM Pin Number"),
222            1
223        );
224        assert_eq!(
225            pin_set
226                .bcm_pins_sorted()
227                .get(1)
228                .expect("Could not get pin")
229                .bcm
230                .expect("Could not get BCM Pin Number"),
231            11
232        );
233    }
234}