embedded_c_sdk_bind_hal/gpio/
pin.rs1use crate::ll_api::{ll_cmd::*, GpioInitParam};
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 = GpioInitParam::OutPP.param();
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 = GpioInitParam::OutOD.param();
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 = GpioInitParam::Analog.param();
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 => GpioInitParam::InFloating.param(),
182 Pull::Up => GpioInitParam::InPU.param(),
183 Pull::Down => GpioInitParam::InPD.param(),
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 AFIN,
398 AFOD,
399 AFPP,
400 AF(u8),
401}
402
403impl AltMode {
404 fn to_flag(&self) -> u32 {
405 match self {
406 AltMode::AFIN => GpioInitParam::AFIN.param(),
407 AltMode::AFOD => GpioInitParam::AFOD.param(),
408 AltMode::AFPP => GpioInitParam::AFPP.param(),
409 AltMode::AF(idx) => GpioInitParam::AF(*idx).param(),
410 }
411 }
412}
413
414pub struct Alternate<'d> {
416 pub(crate) _pin: Flex<'d>,
417}
418
419impl<'d> Alternate<'d> {
420 #[inline]
422 pub fn new(pin: Peri<'d, impl Pin>, mode: AltMode) -> Self {
423 let mut pin = Flex::new(pin);
424 pin.set_as_alternate(mode);
425 Self { _pin: pin }
426 }
427}
428
429pub struct Analog<'d> {
431 pub(crate) _pin: Flex<'d>,
432}
433
434impl<'d> Analog<'d> {
435 #[inline]
437 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
438 let mut pin = Flex::new(pin);
439 pin.set_as_analog();
440 Self { _pin: pin }
441 }
442}
443
444pub(crate) trait SealedPin {
445 fn pin_port(&self) -> u8;
446
447 #[inline]
448 fn _pin(&self) -> u8 {
449 self.pin_port() % 16
450 }
451
452 #[inline]
453 fn _port(&self) -> u8 {
454 self.pin_port() / 16
455 }
456
457 #[inline]
464 fn set_high(&self) {
465 let port = self._port();
466 let pin = self._pin();
467
468 ll_invoke_inner!(INVOKE_ID_GPIO_SET, port, pin, 1);
469 }
470
471 #[inline]
473 fn set_low(&self) {
474 let port = self._port();
475 let pin = self._pin();
476
477 ll_invoke_inner!(INVOKE_ID_GPIO_SET, port, pin, 0);
478 }
479}
480
481#[allow(private_bounds)]
483pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
484 #[inline]
486 fn pin(&self) -> u8 {
487 self._pin()
488 }
489
490 #[inline]
492 fn port(&self) -> u8 {
493 self._port()
494 }
495}
496
497pub struct AnyPin {
499 pin_port: u8,
500}
501
502impl AnyPin {
503 #[inline]
507 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
508 Peri::new_unchecked(Self { pin_port })
509 }
510
511 #[inline]
512 fn _port(&self) -> u8 {
513 self.pin_port / 16
514 }
515}
516
517impl Copy for AnyPin {}
518
519impl Clone for AnyPin {
520 fn clone(&self) -> Self {
521 *self
522 }
523}
524impl PeripheralType for AnyPin {}
525
526impl Pin for AnyPin {}
527
528impl SealedPin for AnyPin {
529 #[inline]
530 fn pin_port(&self) -> u8 {
531 self.pin_port
532 }
533}
534
535crate::foreach_pin!(
536 ($pin_name:ident, $port_num:expr, $pin_num:expr) => {
537 impl Pin for $crate::peripherals::$pin_name {
538 }
539
540 impl SealedPin for $crate::peripherals::$pin_name {
541 #[inline]
542 fn pin_port(&self) -> u8 {
543 $port_num * 16 + $pin_num
544 }
545 }
546
547 impl From<$crate::peripherals::$pin_name> for AnyPin {
548 fn from(val: $crate::peripherals::$pin_name) -> Self {
549 Self {
550 pin_port: val.pin_port(),
551 }
552 }
553 }
554 };
555);
556
557impl<'d> embedded_hal::digital::ErrorType for Input<'d> {
558 type Error = Infallible;
559}
560
561impl<'d> embedded_hal::digital::InputPin for Input<'d> {
562 #[inline]
563 fn is_high(&mut self) -> Result<bool, Self::Error> {
564 Ok(Input::is_high(self))
565 }
566
567 #[inline]
568 fn is_low(&mut self) -> Result<bool, Self::Error> {
569 Ok(Input::is_low(self))
570 }
571}
572
573impl<'d> embedded_hal::digital::ErrorType for Output<'d> {
574 type Error = Infallible;
575}
576
577impl<'d> embedded_hal::digital::OutputPin for Output<'d> {
578 #[inline]
579 fn set_high(&mut self) -> Result<(), Self::Error> {
580 Output::set_high(self);
581 Ok(())
582 }
583
584 #[inline]
585 fn set_low(&mut self) -> Result<(), Self::Error> {
586 Output::set_low(self);
587 Ok(())
588 }
589}
590
591impl<'d> embedded_hal::digital::StatefulOutputPin for Output<'d> {
592 #[inline]
593 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
594 Ok(Output::is_set_high(self))
595 }
596
597 #[inline]
599 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
600 Ok(Output::is_set_low(self))
601 }
602}
603
604impl<'d> embedded_hal::digital::ErrorType for OutputOpenDrain<'d> {
605 type Error = Infallible;
606}
607
608impl<'d> embedded_hal::digital::InputPin for OutputOpenDrain<'d> {
609 #[inline]
610 fn is_high(&mut self) -> Result<bool, Self::Error> {
611 Ok(OutputOpenDrain::is_high(self))
612 }
613
614 #[inline]
615 fn is_low(&mut self) -> Result<bool, Self::Error> {
616 Ok(OutputOpenDrain::is_low(self))
617 }
618}
619
620impl<'d> embedded_hal::digital::OutputPin for OutputOpenDrain<'d> {
621 #[inline]
622 fn set_high(&mut self) -> Result<(), Self::Error> {
623 OutputOpenDrain::set_high(self);
624 Ok(())
625 }
626
627 #[inline]
628 fn set_low(&mut self) -> Result<(), Self::Error> {
629 OutputOpenDrain::set_low(self);
630 Ok(())
631 }
632}
633
634impl<'d> embedded_hal::digital::StatefulOutputPin for OutputOpenDrain<'d> {
635 #[inline]
636 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
637 Ok(OutputOpenDrain::is_set_high(self))
638 }
639
640 #[inline]
642 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
643 Ok(OutputOpenDrain::is_set_low(self))
644 }
645}
646
647impl<'d> embedded_hal::digital::InputPin for Flex<'d> {
648 #[inline]
649 fn is_high(&mut self) -> Result<bool, Self::Error> {
650 Ok(Flex::is_high(self))
651 }
652
653 #[inline]
654 fn is_low(&mut self) -> Result<bool, Self::Error> {
655 Ok(Flex::is_low(self))
656 }
657}
658
659impl<'d> embedded_hal::digital::OutputPin for Flex<'d> {
660 #[inline]
661 fn set_high(&mut self) -> Result<(), Self::Error> {
662 Flex::set_high(self);
663 Ok(())
664 }
665
666 #[inline]
667 fn set_low(&mut self) -> Result<(), Self::Error> {
668 Flex::set_low(self);
669 Ok(())
670 }
671}
672
673impl<'d> embedded_hal::digital::ErrorType for Flex<'d> {
674 type Error = Infallible;
675}
676
677impl<'d> embedded_hal::digital::StatefulOutputPin for Flex<'d> {
678 #[inline]
679 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
680 Ok(Flex::is_set_high(self))
681 }
682
683 #[inline]
685 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
686 Ok(Flex::is_set_low(self))
687 }
688}