vorago_shared_hal/gpio/
mod.rs1use core::convert::Infallible;
3
4pub use crate::ioconfig::{FilterClockSelect, FilterType, regs::FunctionSelect};
5pub use crate::pins::{Pin, PinId};
6pub use embedded_hal::digital::PinState;
7pub use ll::{DynPinId, InterruptEdge, InterruptLevel, Port, Pull};
8
9pub mod asynch;
10pub mod ll;
11pub mod regs;
12
13#[derive(Debug)]
15pub struct Output(ll::LowLevelGpio);
16
17impl Output {
18 pub fn new<I: PinId>(_pin: Pin<I>, init_level: PinState) -> Self {
19 let mut ll = ll::LowLevelGpio::new(I::ID);
20 ll.configure_as_output_push_pull(init_level);
21 Output(ll)
22 }
23
24 #[inline]
25 pub fn port(&self) -> Port {
26 self.0.port()
27 }
28
29 #[inline]
30 pub fn offset(&self) -> usize {
31 self.0.offset()
32 }
33
34 #[inline]
35 pub fn set_high(&mut self) {
36 self.0.set_high();
37 }
38
39 #[inline]
40 pub fn set_state(&mut self, state: PinState) {
41 match state {
42 PinState::Low => self.set_low(),
43 PinState::High => self.set_high(),
44 }
45 }
46
47 #[inline]
48 pub fn set_low(&mut self) {
49 self.0.set_low();
50 }
51
52 #[inline]
53 pub fn is_set_high(&self) -> bool {
54 self.0.is_set_high()
55 }
56
57 #[inline]
58 pub fn is_set_low(&self) -> bool {
59 self.0.is_set_low()
60 }
61
62 #[inline]
64 pub fn toggle(&mut self) {
65 self.0.toggle();
66 }
67
68 #[inline]
69 pub fn configure_pulse_mode(&mut self, enable: bool, default_state: PinState) {
70 self.0.configure_pulse_mode(enable, default_state);
71 }
72
73 #[inline]
74 pub fn configure_delay(&mut self, delay_1: bool, delay_2: bool) {
75 self.0.configure_delay(delay_1, delay_2);
76 }
77}
78
79impl embedded_hal::digital::ErrorType for Output {
80 type Error = Infallible;
81}
82
83impl embedded_hal::digital::OutputPin for Output {
84 fn set_low(&mut self) -> Result<(), Self::Error> {
85 self.0.set_low();
86 Ok(())
87 }
88
89 fn set_high(&mut self) -> Result<(), Self::Error> {
90 self.0.set_high();
91 Ok(())
92 }
93}
94
95impl embedded_hal::digital::StatefulOutputPin for Output {
96 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
97 Ok(self.0.is_set_high())
98 }
99
100 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
101 Ok(self.0.is_set_low())
102 }
103
104 fn toggle(&mut self) -> Result<(), Self::Error> {
106 self.0.toggle();
107 Ok(())
108 }
109}
110
111#[derive(Debug)]
115pub struct Input(ll::LowLevelGpio);
116
117impl Input {
118 pub fn new_floating<I: PinId>(_pin: Pin<I>) -> Self {
119 let mut ll = ll::LowLevelGpio::new(I::ID);
120 ll.configure_as_input_floating();
121 Input(ll)
122 }
123
124 pub fn new_with_pull<I: PinId>(_pin: Pin<I>, pull: Pull) -> Self {
125 let mut ll = ll::LowLevelGpio::new(I::ID);
126 ll.configure_as_input_with_pull(pull);
127 Input(ll)
128 }
129
130 #[inline]
131 pub fn id(&self) -> DynPinId {
132 self.0.id()
133 }
134
135 #[inline]
136 pub fn enable_interrupt_gpio_only(&mut self) {
137 self.0.enable_interrupt_gpio_only();
138 }
139
140 #[cfg(feature = "vor1x")]
146 #[inline]
147 pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig, gpio: bool) {
148 self.0.enable_interrupt(irq_cfg, gpio);
149 }
150
151 #[cfg(feature = "vor4x")]
156 #[inline]
157 pub fn enable_interrupt(
158 &mut self,
159 enable_in_nvic: bool,
160 gpio: bool,
161 ) -> Result<(), ll::PortDoesNotSupportInterrupts> {
162 self.0.enable_interrupt(enable_in_nvic, gpio)
163 }
164
165 #[inline]
166 pub fn configure_edge_interrupt(&mut self, edge: InterruptEdge) {
167 self.0.configure_edge_interrupt(edge);
168 }
169
170 #[inline]
171 pub fn configure_level_interrupt(&mut self, edge: InterruptLevel) {
172 self.0.configure_level_interrupt(edge);
173 }
174
175 #[inline]
176 pub fn configure_delay(&mut self, delay_1: bool, delay_2: bool) {
177 self.0.configure_delay(delay_1, delay_2);
178 }
179
180 #[inline]
181 pub fn configure_filter_type(&mut self, filter: FilterType, clksel: FilterClockSelect) {
182 self.0.configure_filter_type(filter, clksel);
183 }
184
185 #[inline]
186 pub fn is_low(&self) -> bool {
187 self.0.is_low()
188 }
189
190 #[inline]
191 pub fn is_high(&self) -> bool {
192 self.0.is_high()
193 }
194}
195
196impl embedded_hal::digital::ErrorType for Input {
197 type Error = Infallible;
198}
199
200impl embedded_hal::digital::InputPin for Input {
201 fn is_low(&mut self) -> Result<bool, Self::Error> {
202 Ok(self.0.is_low())
203 }
204
205 fn is_high(&mut self) -> Result<bool, Self::Error> {
206 Ok(self.0.is_high())
207 }
208}
209
210#[derive(Debug)]
211#[cfg_attr(feature = "defmt", derive(defmt::Format))]
212pub enum PinMode {
213 InputFloating,
214 InputWithPull(Pull),
215 OutputPushPull,
216 OutputOpenDrain,
217}
218
219impl PinMode {
220 pub fn is_input(&self) -> bool {
221 matches!(self, PinMode::InputFloating | PinMode::InputWithPull(_))
222 }
223
224 pub fn is_output(&self) -> bool {
225 !self.is_input()
226 }
227}
228
229#[derive(Debug)]
240pub struct Flex {
241 ll: ll::LowLevelGpio,
242 mode: PinMode,
243}
244
245impl Flex {
246 pub fn new<I: PinId>(_pin: Pin<I>) -> Self {
247 let mut ll = ll::LowLevelGpio::new(I::ID);
248 ll.configure_as_input_floating();
249 Flex {
250 ll,
251 mode: PinMode::InputFloating,
252 }
253 }
254
255 #[inline]
256 pub fn port(&self) -> Port {
257 self.ll.port()
258 }
259
260 #[inline]
261 pub fn offset(&self) -> usize {
262 self.ll.offset()
263 }
264
265 #[inline]
267 pub fn is_low(&self) -> bool {
268 self.ll.is_low()
269 }
270
271 #[inline]
273 pub fn is_high(&self) -> bool {
274 self.ll.is_high()
275 }
276
277 #[inline]
279 pub fn set_low(&mut self) {
280 if !self.mode.is_input() {
281 return;
282 }
283 self.ll.set_low();
284 }
285
286 #[inline]
288 pub fn set_high(&mut self) {
289 if !self.mode.is_input() {
290 return;
291 }
292 self.ll.set_high();
293 }
294
295 #[inline]
296 pub fn set_state(&mut self, state: PinState) {
297 match state {
298 PinState::Low => self.set_low(),
299 PinState::High => self.set_high(),
300 }
301 }
302}
303
304impl embedded_hal::digital::ErrorType for Flex {
305 type Error = Infallible;
306}
307
308impl embedded_hal::digital::InputPin for Flex {
309 fn is_low(&mut self) -> Result<bool, Self::Error> {
311 Ok(self.ll.is_low())
312 }
313
314 fn is_high(&mut self) -> Result<bool, Self::Error> {
316 Ok(self.ll.is_high())
317 }
318}
319
320impl embedded_hal::digital::OutputPin for Flex {
321 fn set_low(&mut self) -> Result<(), Self::Error> {
323 self.set_low();
324 Ok(())
325 }
326
327 fn set_high(&mut self) -> Result<(), Self::Error> {
329 self.set_high();
330 Ok(())
331 }
332}
333
334impl embedded_hal::digital::StatefulOutputPin for Flex {
335 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
338 Ok(self.ll.is_set_high())
339 }
340
341 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
344 Ok(self.ll.is_set_low())
345 }
346
347 fn toggle(&mut self) -> Result<(), Self::Error> {
352 self.ll.toggle();
353 Ok(())
354 }
355}
356
357pub struct IoPeriphPin {
361 ll: ll::LowLevelGpio,
362 fun_sel: FunctionSelect,
363}
364
365impl IoPeriphPin {
366 pub fn new_with_pin<I: PinId>(
367 _pin: Pin<I>,
368 fun_sel: FunctionSelect,
369 pull: Option<Pull>,
370 ) -> Self {
371 let mut ll = ll::LowLevelGpio::new(I::ID);
372 ll.configure_as_peripheral_pin(fun_sel, pull);
373 IoPeriphPin { ll, fun_sel }
374 }
375
376 pub fn new(pin_id: DynPinId, fun_sel: FunctionSelect, pull: Option<Pull>) -> Self {
377 let mut ll = ll::LowLevelGpio::new(pin_id);
378 ll.configure_as_peripheral_pin(fun_sel, pull);
379 IoPeriphPin { ll, fun_sel }
380 }
381
382 pub fn port(&self) -> Port {
383 self.ll.port()
384 }
385
386 pub fn offset(&self) -> usize {
387 self.ll.offset()
388 }
389
390 pub fn fun_sel(&self) -> FunctionSelect {
391 self.fun_sel
392 }
393}