embedded_c_sdk_bind_hal/gpio/
pin.rs1use crate::ll_api::{ll_cmd::*, GpioInitFlag};
4use core::convert::Infallible;
5use embassy_hal_internal::{Peri, PeripheralType};
6
7pub struct Flex<'d> {
13 pub(crate) pin: Peri<'d, AnyPin>,
14}
15
16impl<'d> Flex<'d> {
17 #[inline]
23 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
24 Self { pin: pin.into() }
26 }
27
28 #[inline(never)]
32 pub fn set_as_input(&mut self, pull: Pull) {
33 let port = self.pin._port();
34 let pin = self.pin._pin();
35 let flag = pull.to_pupdr();
36
37 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, port, pin, flag);
38 }
39
40 #[inline(never)]
47 pub fn set_as_output(&mut self) {
48 let port = self.pin._port();
49 let pin = self.pin._pin();
50 let flag = GpioInitFlag::OutPP as u32;
51
52 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, port, pin, flag);
53 }
54
55 #[inline(never)]
57 pub fn set_as_open_drain(&mut self) {
58 let port = self.pin._port();
59 let pin = self.pin._pin();
60 let flag = GpioInitFlag::OutOD as u32;
61
62 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, port, pin, flag);
63 }
64
65 pub fn set_as_alternate(&mut self, mode: AltMode) {
67 let port = self.pin._port();
68 let pin = self.pin._pin();
69 let flag = mode.to_flag();
70
71 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, port, pin, flag);
72 }
73
74 pub fn set_as_analog(&mut self) {
76 let port = self.pin._port();
77 let pin = self.pin._pin();
78 let flag = GpioInitFlag::Analog as u32;
79
80 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, port, pin, flag);
81 }
82
83 #[inline]
85 pub fn is_high(&self) -> bool {
86 let port = self.pin._port();
87 let pin = self.pin._pin();
88
89 ll_invoke_inner!(INVOKE_ID_GPIO_GET_INPUT, port, pin) > 0
90 }
91
92 #[inline]
94 pub fn is_low(&self) -> bool {
95 let port = self.pin._port();
96 let pin = self.pin._pin();
97
98 ll_invoke_inner!(INVOKE_ID_GPIO_GET_INPUT, port, pin) == 0
99 }
100
101 #[inline]
103 pub fn get_level(&self) -> Level {
104 self.is_high().into()
105 }
106
107 #[inline]
109 pub fn is_set_high(&self) -> bool {
110 !self.is_set_low()
111 }
112
113 #[inline]
115 pub fn is_set_low(&self) -> bool {
116 let port = self.pin._port();
117 let pin = self.pin._pin();
118
119 ll_invoke_inner!(INVOKE_ID_GPIO_GET_OUTPUT, port, pin) == 0
120 }
121
122 #[inline]
124 pub fn get_output_level(&self) -> Level {
125 self.is_set_high().into()
126 }
127
128 #[inline]
130 pub fn set_high(&mut self) {
131 self.pin.set_high();
132 }
133
134 #[inline]
136 pub fn set_low(&mut self) {
137 self.pin.set_low();
138 }
139
140 #[inline]
142 pub fn set_level(&mut self, level: Level) {
143 match level {
144 Level::Low => self.pin.set_low(),
145 Level::High => self.pin.set_high(),
146 }
147 }
148
149 #[inline]
151 pub fn toggle(&mut self) {
152 if self.is_set_low() {
153 self.set_high()
154 } else {
155 self.set_low()
156 }
157 }
158}
159
160impl<'d> Drop for Flex<'d> {
161 #[inline]
162 fn drop(&mut self) {
163 }
165}
166
167#[derive(Debug, Eq, PartialEq, Copy, Clone)]
169pub enum Pull {
170 None,
172 Up,
174 Down,
176}
177
178impl Pull {
179 const fn to_pupdr(self) -> u32 {
180 match self {
181 Pull::None => GpioInitFlag::InFloating as u32,
182 Pull::Up => GpioInitFlag::InPU as u32,
183 Pull::Down => GpioInitFlag::InPD as u32,
184 }
185 }
186}
187
188pub struct Input<'d> {
190 pub(crate) pin: Flex<'d>,
191}
192
193impl<'d> Input<'d> {
194 #[inline]
196 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
197 let mut pin = Flex::new(pin);
198 pin.set_as_input(pull);
199 Self { pin }
200 }
201
202 #[inline]
204 pub fn is_high(&self) -> bool {
205 self.pin.is_high()
206 }
207
208 #[inline]
210 pub fn is_low(&self) -> bool {
211 self.pin.is_low()
212 }
213
214 #[inline]
216 pub fn get_level(&self) -> Level {
217 self.pin.get_level()
218 }
219}
220
221#[derive(Debug, Eq, PartialEq, Copy, Clone)]
223pub enum Level {
224 Low,
226 High,
228}
229
230impl From<bool> for Level {
231 fn from(val: bool) -> Self {
232 match val {
233 true => Self::High,
234 false => Self::Low,
235 }
236 }
237}
238
239impl From<Level> for bool {
240 fn from(level: Level) -> bool {
241 match level {
242 Level::Low => false,
243 Level::High => true,
244 }
245 }
246}
247
248pub struct Output<'d> {
254 pub(crate) pin: Flex<'d>,
255}
256
257impl<'d> Output<'d> {
258 #[inline]
260 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
261 let mut pin = Flex::new(pin);
262 match initial_output {
263 Level::High => pin.set_high(),
264 Level::Low => pin.set_low(),
265 }
266 pin.set_as_output();
267 Self { pin }
268 }
269
270 #[inline]
272 pub fn set_high(&mut self) {
273 self.pin.set_high();
274 }
275
276 #[inline]
278 pub fn set_low(&mut self) {
279 self.pin.set_low();
280 }
281
282 #[inline]
284 pub fn set_level(&mut self, level: Level) {
285 self.pin.set_level(level)
286 }
287
288 #[inline]
290 pub fn is_set_high(&self) -> bool {
291 self.pin.is_set_high()
292 }
293
294 #[inline]
296 pub fn is_set_low(&self) -> bool {
297 self.pin.is_set_low()
298 }
299
300 #[inline]
302 pub fn get_output_level(&self) -> Level {
303 self.pin.get_output_level()
304 }
305
306 #[inline]
308 pub fn toggle(&mut self) {
309 self.pin.toggle();
310 }
311}
312
313pub struct OutputOpenDrain<'d> {
319 pub(crate) pin: Flex<'d>,
320}
321
322impl<'d> OutputOpenDrain<'d> {
323 #[inline]
325 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
326 let mut pin = Flex::new(pin);
327 match initial_output {
328 Level::High => pin.set_high(),
329 Level::Low => pin.set_low(),
330 }
331 pin.set_as_open_drain();
332 Self { pin }
333 }
334
335 #[inline]
337 pub fn is_high(&self) -> bool {
338 !self.pin.is_low()
339 }
340
341 #[inline]
343 pub fn is_low(&self) -> bool {
344 self.pin.is_low()
345 }
346
347 #[inline]
349 pub fn get_level(&self) -> Level {
350 self.pin.get_level()
351 }
352
353 #[inline]
355 pub fn set_high(&mut self) {
356 self.pin.set_high();
357 }
358
359 #[inline]
361 pub fn set_low(&mut self) {
362 self.pin.set_low();
363 }
364
365 #[inline]
367 pub fn set_level(&mut self, level: Level) {
368 self.pin.set_level(level);
369 }
370
371 #[inline]
373 pub fn is_set_high(&self) -> bool {
374 self.pin.is_set_high()
375 }
376
377 #[inline]
379 pub fn is_set_low(&self) -> bool {
380 self.pin.is_set_low()
381 }
382
383 #[inline]
385 pub fn get_output_level(&self) -> Level {
386 self.pin.get_output_level()
387 }
388
389 #[inline]
391 pub fn toggle(&mut self) {
392 self.pin.toggle()
393 }
394}
395
396pub enum AltMode {
397 AF(u8),
398 AFOD,
399 AFPP,
400}
401
402impl AltMode {
403 fn to_flag(&self) -> u32 {
404 match self {
405 AltMode::AF(idx) => {
406 use GpioInitFlag::*;
407 const AF_FLAGS: [GpioInitFlag; 8] = [AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7];
408 AF_FLAGS.get(*idx as usize).copied().unwrap_or(AF0) as u32
409 }
410 AltMode::AFOD => GpioInitFlag::AFOD as u32,
411 AltMode::AFPP => GpioInitFlag::AFPP as u32,
412 }
413 }
414}
415
416pub struct Alternate<'d> {
418 pub(crate) _pin: Flex<'d>,
419}
420
421impl<'d> Alternate<'d> {
422 #[inline]
424 pub fn new(pin: Peri<'d, impl Pin>, mode: AltMode) -> Self {
425 let mut pin = Flex::new(pin);
426 pin.set_as_alternate(mode);
427 Self { _pin: pin }
428 }
429}
430
431pub struct Analog<'d> {
433 pub(crate) _pin: Flex<'d>,
434}
435
436impl<'d> Analog<'d> {
437 #[inline]
439 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
440 let mut pin = Flex::new(pin);
441 pin.set_as_analog();
442 Self { _pin: pin }
443 }
444}
445
446pub(crate) trait SealedPin {
447 fn pin_port(&self) -> u8;
448
449 #[inline]
450 fn _pin(&self) -> u8 {
451 self.pin_port() % 16
452 }
453
454 #[inline]
455 fn _port(&self) -> u8 {
456 self.pin_port() / 16
457 }
458
459 #[inline]
466 fn set_high(&self) {
467 let port = self._port();
468 let pin = self._pin();
469
470 ll_invoke_inner!(INVOKE_ID_GPIO_SET, port, pin, 1);
471 }
472
473 #[inline]
475 fn set_low(&self) {
476 let port = self._port();
477 let pin = self._pin();
478
479 ll_invoke_inner!(INVOKE_ID_GPIO_SET, port, pin, 0);
480 }
481}
482
483#[allow(private_bounds)]
485pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
486 #[inline]
488 fn pin(&self) -> u8 {
489 self._pin()
490 }
491
492 #[inline]
494 fn port(&self) -> u8 {
495 self._port()
496 }
497}
498
499pub struct AnyPin {
501 pin_port: u8,
502}
503
504impl AnyPin {
505 #[inline]
509 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
510 Peri::new_unchecked(Self { pin_port })
511 }
512
513 #[inline]
514 fn _port(&self) -> u8 {
515 self.pin_port / 16
516 }
517}
518
519impl Copy for AnyPin {}
520
521impl Clone for AnyPin {
522 fn clone(&self) -> Self {
523 *self
524 }
525}
526impl PeripheralType for AnyPin {}
527
528impl Pin for AnyPin {}
529
530impl SealedPin for AnyPin {
531 #[inline]
532 fn pin_port(&self) -> u8 {
533 self.pin_port
534 }
535}
536
537crate::foreach_pin!(
538 ($pin_name:ident, $port_num:expr, $pin_num:expr) => {
539 impl SealedPin for $crate::peripherals::$pin_name {
540 #[inline]
541 fn pin_port(&self) -> u8 {
542 $port_num * 16 + $pin_num
543 }
544 }
545
546 impl From<$crate::peripherals::$pin_name> for AnyPin {
547 fn from(val: $crate::peripherals::$pin_name) -> Self {
548 Self {
549 pin_port: val.pin_port(),
550 }
551 }
552 }
553 };
554);
555
556impl<'d> embedded_hal::digital::ErrorType for Input<'d> {
557 type Error = Infallible;
558}
559
560impl<'d> embedded_hal::digital::InputPin for Input<'d> {
561 #[inline]
562 fn is_high(&mut self) -> Result<bool, Self::Error> {
563 Ok(Input::is_high(self))
564 }
565
566 #[inline]
567 fn is_low(&mut self) -> Result<bool, Self::Error> {
568 Ok(Input::is_low(self))
569 }
570}
571
572impl<'d> embedded_hal::digital::ErrorType for Output<'d> {
573 type Error = Infallible;
574}
575
576impl<'d> embedded_hal::digital::OutputPin for Output<'d> {
577 #[inline]
578 fn set_high(&mut self) -> Result<(), Self::Error> {
579 Output::set_high(self);
580 Ok(())
581 }
582
583 #[inline]
584 fn set_low(&mut self) -> Result<(), Self::Error> {
585 Output::set_low(self);
586 Ok(())
587 }
588}
589
590impl<'d> embedded_hal::digital::StatefulOutputPin for Output<'d> {
591 #[inline]
592 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
593 Ok(Output::is_set_high(self))
594 }
595
596 #[inline]
598 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
599 Ok(Output::is_set_low(self))
600 }
601}
602
603impl<'d> embedded_hal::digital::ErrorType for OutputOpenDrain<'d> {
604 type Error = Infallible;
605}
606
607impl<'d> embedded_hal::digital::InputPin for OutputOpenDrain<'d> {
608 #[inline]
609 fn is_high(&mut self) -> Result<bool, Self::Error> {
610 Ok(OutputOpenDrain::is_high(self))
611 }
612
613 #[inline]
614 fn is_low(&mut self) -> Result<bool, Self::Error> {
615 Ok(OutputOpenDrain::is_low(self))
616 }
617}
618
619impl<'d> embedded_hal::digital::OutputPin for OutputOpenDrain<'d> {
620 #[inline]
621 fn set_high(&mut self) -> Result<(), Self::Error> {
622 OutputOpenDrain::set_high(self);
623 Ok(())
624 }
625
626 #[inline]
627 fn set_low(&mut self) -> Result<(), Self::Error> {
628 OutputOpenDrain::set_low(self);
629 Ok(())
630 }
631}
632
633impl<'d> embedded_hal::digital::StatefulOutputPin for OutputOpenDrain<'d> {
634 #[inline]
635 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
636 Ok(OutputOpenDrain::is_set_high(self))
637 }
638
639 #[inline]
641 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
642 Ok(OutputOpenDrain::is_set_low(self))
643 }
644}
645
646impl<'d> embedded_hal::digital::InputPin for Flex<'d> {
647 #[inline]
648 fn is_high(&mut self) -> Result<bool, Self::Error> {
649 Ok(Flex::is_high(self))
650 }
651
652 #[inline]
653 fn is_low(&mut self) -> Result<bool, Self::Error> {
654 Ok(Flex::is_low(self))
655 }
656}
657
658impl<'d> embedded_hal::digital::OutputPin for Flex<'d> {
659 #[inline]
660 fn set_high(&mut self) -> Result<(), Self::Error> {
661 Flex::set_high(self);
662 Ok(())
663 }
664
665 #[inline]
666 fn set_low(&mut self) -> Result<(), Self::Error> {
667 Flex::set_low(self);
668 Ok(())
669 }
670}
671
672impl<'d> embedded_hal::digital::ErrorType for Flex<'d> {
673 type Error = Infallible;
674}
675
676impl<'d> embedded_hal::digital::StatefulOutputPin for Flex<'d> {
677 #[inline]
678 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
679 Ok(Flex::is_set_high(self))
680 }
681
682 #[inline]
684 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
685 Ok(Flex::is_set_low(self))
686 }
687}