1use anyhow::{Context, Result};
4use rppal::gpio::{self, Gpio};
5
6const BOARD_TYPE: u8 = 12;
7
8fn check_board_type() -> Result<bool> {
9 let type_pin = Gpio::new()?.get(BOARD_TYPE)?.into_input();
10
11 Ok(type_pin.is_low())
12}
13
14#[derive(Copy, Clone, Debug)]
16pub enum PinType {
17 D0,
19 D1,
21 D2,
23 D3,
25 D4,
27 D5,
29 D6,
31 D7,
33 D8,
35 D9,
37 D10,
39 D11,
41 D12,
43 D13,
45 D14,
47 D15,
49 D16,
51 A0,
53 A1,
55 A2,
57 A3,
59 A4,
61 A5,
63 A6,
65 A7,
67 P0,
69 P1,
71 P2,
73 P3,
75 P4,
77 P5,
79 P6,
81 P7,
83 P8,
85 P9,
87 P10,
89 P11,
91 P12,
93 P13,
95 SW,
97 User,
99 Led,
101 BoardType,
103 Rst,
105 BleInt,
107 BleRst,
109 McuRst,
111}
112
113impl PinType {
114 fn bcm_num(&self, board_type: bool) -> u8 {
115 match self {
116 PinType::D0 => 17,
117 PinType::D1 => {
118 if board_type {
119 18
120 } else {
121 4
122 }
123 }
124 PinType::D2 => 27,
125 PinType::D3 => 22,
126 PinType::D4 => 23,
127 PinType::D5 => 24,
128 PinType::D6 => 25,
129 PinType::D7 => 4,
130 PinType::D8 => 5,
131 PinType::D9 => 6,
132 PinType::D10 => 12,
133 PinType::D11 => 13,
134 PinType::D12 => 19,
135 PinType::D13 => 16,
136 PinType::D14 => 26,
137 PinType::D15 => 20,
138 PinType::D16 => 21,
139 PinType::SW => {
140 if board_type {
141 19
142 } else {
143 25
144 }
145 }
146 PinType::User => {
147 if board_type {
148 19
149 } else {
150 25
151 }
152 }
153 PinType::Led => 26,
154 PinType::BoardType => 12,
155 PinType::Rst => 16,
156 PinType::BleInt => 13,
157 PinType::BleRst => 20,
158 PinType::McuRst => {
159 if board_type {
160 21
161 } else {
162 5
163 }
164 }
165 _ => panic!("Cannot find bcm number for {:?}", self),
166 }
167 }
168
169 pub fn is_digital_pin(&self) -> bool {
171 matches!(
172 self,
173 PinType::D0
174 | PinType::D1
175 | PinType::D2
176 | PinType::D3
177 | PinType::D4
178 | PinType::D5
179 | PinType::D6
180 | PinType::D7
181 | PinType::D8
182 | PinType::D9
183 | PinType::D10
184 | PinType::D11
185 | PinType::D12
186 | PinType::D13
187 | PinType::D14
188 | PinType::D15
189 | PinType::D16
190 )
191 }
192
193 pub fn is_adc_pin(&self) -> bool {
195 matches!(
196 self,
197 PinType::D0
198 | PinType::A0
199 | PinType::A1
200 | PinType::A2
201 | PinType::A3
202 | PinType::A4
203 | PinType::A5
204 | PinType::A6
205 | PinType::A7
206 )
207 }
208
209 pub fn is_pwm_pin(&self) -> bool {
211 matches!(
212 self,
213 PinType::P0
214 | PinType::P1
215 | PinType::P2
216 | PinType::P3
217 | PinType::P4
218 | PinType::P5
219 | PinType::P6
220 | PinType::P7
221 | PinType::P8
222 | PinType::P9
223 | PinType::P10
224 | PinType::P11
225 | PinType::P12
226 | PinType::P13
227 )
228 }
229
230 pub fn adc_channel(&self) -> u8 {
232 match self {
233 PinType::A0 => 0,
234 PinType::A1 => 1,
235 PinType::A2 => 2,
236 PinType::A3 => 3,
237 PinType::A4 => 4,
238 PinType::A5 => 5,
239 PinType::A6 => 6,
240 PinType::A7 => 7,
241 _ => panic!("pin should be one of PinType::A0-P7, but passed {:?}", self),
242 }
243 }
244
245 pub fn pwm_channel(&self) -> u8 {
247 match self {
248 PinType::P0 => 0,
249 PinType::P1 => 1,
250 PinType::P2 => 2,
251 PinType::P3 => 3,
252 PinType::P4 => 4,
253 PinType::P5 => 5,
254 PinType::P6 => 6,
255 PinType::P7 => 7,
256 PinType::P8 => 8,
257 PinType::P9 => 9,
258 PinType::P10 => 10,
259 PinType::P11 => 11,
260 PinType::P12 => 12,
261 PinType::P13 => 13,
262 _ => panic!(
263 "pin should be one of PinType::P0-P13, but passed {:?}",
264 self
265 ),
266 }
267 }
268}
269
270#[derive(Debug)]
272pub struct RHPin {
273 pub gpio_pin: gpio::Pin,
275 pub bcm_num: u8,
277}
278
279impl RHPin {
280 pub fn new(pin_type: PinType) -> Result<Self> {
282 let board_type = check_board_type().context("Checking Board type failed")?;
283 let bcm_num = pin_type.bcm_num(board_type);
284 let gpio_pin = Gpio::new()?.get(bcm_num)?;
285
286 Ok(Self { gpio_pin, bcm_num })
287 }
288}