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_low(&mut self) {
41 self.0.set_low();
42 }
43
44 #[inline]
45 pub fn is_set_high(&self) -> bool {
46 self.0.is_set_high()
47 }
48
49 #[inline]
50 pub fn is_set_low(&self) -> bool {
51 self.0.is_set_low()
52 }
53
54 #[inline]
56 pub fn toggle(&mut self) {
57 self.0.toggle();
58 }
59
60 #[inline]
61 pub fn configure_pulse_mode(&mut self, enable: bool, default_state: PinState) {
62 self.0.configure_pulse_mode(enable, default_state);
63 }
64
65 #[inline]
66 pub fn configure_delay(&mut self, delay_1: bool, delay_2: bool) {
67 self.0.configure_delay(delay_1, delay_2);
68 }
69}
70
71impl embedded_hal::digital::ErrorType for Output {
72 type Error = Infallible;
73}
74
75impl embedded_hal::digital::OutputPin for Output {
76 fn set_low(&mut self) -> Result<(), Self::Error> {
77 self.0.set_low();
78 Ok(())
79 }
80
81 fn set_high(&mut self) -> Result<(), Self::Error> {
82 self.0.set_high();
83 Ok(())
84 }
85}
86
87impl embedded_hal::digital::StatefulOutputPin for Output {
88 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
89 Ok(self.0.is_set_high())
90 }
91
92 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
93 Ok(self.0.is_set_low())
94 }
95
96 fn toggle(&mut self) -> Result<(), Self::Error> {
98 self.0.toggle();
99 Ok(())
100 }
101}
102
103#[derive(Debug)]
107pub struct Input(ll::LowLevelGpio);
108
109impl Input {
110 pub fn new_floating<I: PinId>(_pin: Pin<I>) -> Self {
111 let mut ll = ll::LowLevelGpio::new(I::ID);
112 ll.configure_as_input_floating();
113 Input(ll)
114 }
115
116 pub fn new_with_pull<I: PinId>(_pin: Pin<I>, pull: Pull) -> Self {
117 let mut ll = ll::LowLevelGpio::new(I::ID);
118 ll.configure_as_input_with_pull(pull);
119 Input(ll)
120 }
121
122 #[inline]
123 pub fn id(&self) -> DynPinId {
124 self.0.id()
125 }
126
127 #[cfg(feature = "vor1x")]
128 #[inline]
129 pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig) {
130 self.0.enable_interrupt(irq_cfg);
131 }
132
133 #[cfg(feature = "vor4x")]
134 #[inline]
135 pub fn enable_interrupt(
136 &mut self,
137 enable_in_nvic: bool,
138 ) -> Result<(), ll::PortDoesNotSupportInterrupts> {
139 self.0.enable_interrupt(enable_in_nvic)
140 }
141
142 #[inline]
143 pub fn configure_edge_interrupt(&mut self, edge: InterruptEdge) {
144 self.0.configure_edge_interrupt(edge);
145 }
146
147 #[inline]
148 pub fn configure_level_interrupt(&mut self, edge: InterruptLevel) {
149 self.0.configure_level_interrupt(edge);
150 }
151
152 #[inline]
153 pub fn configure_delay(&mut self, delay_1: bool, delay_2: bool) {
154 self.0.configure_delay(delay_1, delay_2);
155 }
156
157 #[inline]
158 pub fn configure_filter_type(&mut self, filter: FilterType, clksel: FilterClockSelect) {
159 self.0.configure_filter_type(filter, clksel);
160 }
161
162 #[inline]
163 pub fn is_low(&self) -> bool {
164 self.0.is_low()
165 }
166
167 #[inline]
168 pub fn is_high(&self) -> bool {
169 self.0.is_high()
170 }
171}
172
173impl embedded_hal::digital::ErrorType for Input {
174 type Error = Infallible;
175}
176
177impl embedded_hal::digital::InputPin for Input {
178 fn is_low(&mut self) -> Result<bool, Self::Error> {
179 Ok(self.0.is_low())
180 }
181
182 fn is_high(&mut self) -> Result<bool, Self::Error> {
183 Ok(self.0.is_high())
184 }
185}
186
187#[derive(Debug)]
188#[cfg_attr(feature = "defmt", derive(defmt::Format))]
189pub enum PinMode {
190 InputFloating,
191 InputWithPull(Pull),
192 OutputPushPull,
193 OutputOpenDrain,
194}
195
196impl PinMode {
197 pub fn is_input(&self) -> bool {
198 matches!(self, PinMode::InputFloating | PinMode::InputWithPull(_))
199 }
200
201 pub fn is_output(&self) -> bool {
202 !self.is_input()
203 }
204}
205
206#[derive(Debug)]
217pub struct Flex {
218 ll: ll::LowLevelGpio,
219 mode: PinMode,
220}
221
222impl Flex {
223 pub fn new<I: PinId>(_pin: Pin<I>) -> Self {
224 let mut ll = ll::LowLevelGpio::new(I::ID);
225 ll.configure_as_input_floating();
226 Flex {
227 ll,
228 mode: PinMode::InputFloating,
229 }
230 }
231
232 #[inline]
233 pub fn port(&self) -> Port {
234 self.ll.port()
235 }
236
237 #[inline]
238 pub fn offset(&self) -> usize {
239 self.ll.offset()
240 }
241
242 #[inline]
244 pub fn is_low(&self) -> bool {
245 self.ll.is_low()
246 }
247
248 #[inline]
250 pub fn is_high(&self) -> bool {
251 self.ll.is_high()
252 }
253
254 #[inline]
256 pub fn set_low(&mut self) {
257 if !self.mode.is_input() {
258 return;
259 }
260 self.ll.set_low();
261 }
262
263 #[inline]
265 pub fn set_high(&mut self) {
266 if !self.mode.is_input() {
267 return;
268 }
269 self.ll.set_high();
270 }
271}
272
273impl embedded_hal::digital::ErrorType for Flex {
274 type Error = Infallible;
275}
276
277impl embedded_hal::digital::InputPin for Flex {
278 fn is_low(&mut self) -> Result<bool, Self::Error> {
280 Ok(self.ll.is_low())
281 }
282
283 fn is_high(&mut self) -> Result<bool, Self::Error> {
285 Ok(self.ll.is_high())
286 }
287}
288
289impl embedded_hal::digital::OutputPin for Flex {
290 fn set_low(&mut self) -> Result<(), Self::Error> {
292 self.set_low();
293 Ok(())
294 }
295
296 fn set_high(&mut self) -> Result<(), Self::Error> {
298 self.set_high();
299 Ok(())
300 }
301}
302
303impl embedded_hal::digital::StatefulOutputPin for Flex {
304 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
307 Ok(self.ll.is_set_high())
308 }
309
310 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
313 Ok(self.ll.is_set_low())
314 }
315
316 fn toggle(&mut self) -> Result<(), Self::Error> {
321 self.ll.toggle();
322 Ok(())
323 }
324}
325
326pub struct IoPeriphPin {
330 ll: ll::LowLevelGpio,
331 fun_sel: FunctionSelect,
332}
333
334impl IoPeriphPin {
335 pub fn new_with_pin<I: PinId>(
336 _pin: Pin<I>,
337 fun_sel: FunctionSelect,
338 pull: Option<Pull>,
339 ) -> Self {
340 let mut ll = ll::LowLevelGpio::new(I::ID);
341 ll.configure_as_peripheral_pin(fun_sel, pull);
342 IoPeriphPin { ll, fun_sel }
343 }
344
345 pub fn new(pin_id: DynPinId, fun_sel: FunctionSelect, pull: Option<Pull>) -> Self {
346 let mut ll = ll::LowLevelGpio::new(pin_id);
347 ll.configure_as_peripheral_pin(fun_sel, pull);
348 IoPeriphPin { ll, fun_sel }
349 }
350
351 pub fn port(&self) -> Port {
352 self.ll.port()
353 }
354
355 pub fn offset(&self) -> usize {
356 self.ll.offset()
357 }
358
359 pub fn fun_sel(&self) -> FunctionSelect {
360 self.fun_sel
361 }
362}