1#![macro_use]
8use core::convert::Infallible;
9
10use critical_section::CriticalSection;
11use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
12
13use crate::pac::gpio::{self, vals};
14use crate::{pac, peripherals, Peripheral};
15
16pub struct Flex<'d> {
22 pub(crate) pin: PeripheralRef<'d, AnyPin>,
23}
24
25impl<'d> Flex<'d> {
26 #[inline]
32 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
33 into_ref!(pin);
34 Self {
36 pin: pin.map_into(),
37 }
38 }
39
40 #[inline(never)]
44 pub fn set_as_input(&mut self, pull: Pull) {
45 critical_section::with(|_| {
46 let r = self.pin.block();
47 let n = self.pin.pin() as usize;
48
49 r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr()));
50 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
51 r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
52 });
53 }
54
55 #[inline(never)]
62 pub fn set_as_output(&mut self, speed: Speed) {
63 critical_section::with(|_| {
64 let r = self.pin.block();
65 let n = self.pin.pin() as usize;
66
67 r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
68 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
69 r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr()));
70 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
71 });
72 }
73
74 #[inline(never)]
85 pub fn set_as_input_output(&mut self, speed: Speed) {
86 self.set_as_input_output_pull(speed, Pull::None);
87 }
88
89 #[inline(never)]
94 pub fn set_as_input_output_pull(&mut self, speed: Speed, pull: Pull) {
95 critical_section::with(|_| {
96 let r = self.pin.block();
97 let n = self.pin.pin() as usize;
98 r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr()));
99 r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN));
100 r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr()));
101 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
102 });
103 }
104
105 #[inline]
110 pub fn set_as_analog(&mut self) {
111 self.pin.set_as_analog();
113 }
114
115 #[inline]
120 pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AfType) {
121 critical_section::with(|_| {
122 self.pin.set_as_af(af_num, af_type);
123 });
124 }
125
126 #[inline]
128 pub fn is_high(&self) -> bool {
129 !self.is_low()
130 }
131
132 #[inline]
134 pub fn is_low(&self) -> bool {
135 let state = self.pin.block().idr().read().idr(self.pin.pin() as _);
136 state == vals::Idr::LOW
137 }
138
139 #[inline]
141 pub fn get_level(&self) -> Level {
142 self.is_high().into()
143 }
144
145 #[inline]
147 pub fn is_set_high(&self) -> bool {
148 !self.is_set_low()
149 }
150
151 #[inline]
153 pub fn is_set_low(&self) -> bool {
154 let state = self.pin.block().odr().read().odr(self.pin.pin() as _);
155 state == vals::Odr::LOW
156 }
157
158 #[inline]
160 pub fn get_output_level(&self) -> Level {
161 self.is_set_high().into()
162 }
163
164 #[inline]
166 pub fn set_high(&mut self) {
167 self.pin.set_high();
168 }
169
170 #[inline]
172 pub fn set_low(&mut self) {
173 self.pin.set_low();
174 }
175
176 #[inline]
178 pub fn set_level(&mut self, level: Level) {
179 match level {
180 Level::Low => self.pin.set_low(),
181 Level::High => self.pin.set_high(),
182 }
183 }
184
185 #[inline]
187 pub fn toggle(&mut self) {
188 if self.is_set_low() {
189 self.set_high()
190 } else {
191 self.set_low()
192 }
193 }
194}
195
196impl<'d> Drop for Flex<'d> {
197 #[inline]
198 fn drop(&mut self) {
199 critical_section::with(|_| {
200 self.pin.set_as_disconnected();
201 });
202 }
203}
204
205#[derive(Debug, Eq, PartialEq, Copy, Clone)]
207#[cfg_attr(feature = "defmt", derive(defmt::Format))]
208pub enum Pull {
209 None,
211 Up,
213 Down,
215}
216
217impl Pull {
218 const fn to_pupdr(self) -> vals::Pupdr {
219 match self {
220 Pull::None => vals::Pupdr::FLOATING,
221 Pull::Up => vals::Pupdr::PULLUP,
222 Pull::Down => vals::Pupdr::PULLDOWN,
223 }
224 }
225}
226
227#[derive(Debug, Copy, Clone)]
232#[cfg_attr(feature = "defmt", derive(defmt::Format))]
233pub enum Speed {
234 Low,
236 Medium,
238 High,
240 VeryHigh,
242}
243
244impl Speed {
245 const fn to_ospeedr(self: Speed) -> vals::Ospeedr {
246 match self {
247 Speed::Low => vals::Ospeedr::LOWSPEED,
248 Speed::Medium => vals::Ospeedr::MEDIUMSPEED,
249 Speed::High => vals::Ospeedr::HIGHSPEED,
251 Speed::VeryHigh => vals::Ospeedr::VERYHIGHSPEED,
252 }
253 }
254}
255
256pub struct Input<'d> {
258 pub(crate) pin: Flex<'d>,
259}
260
261impl<'d> Input<'d> {
262 #[inline]
264 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self {
265 let mut pin = Flex::new(pin);
266 pin.set_as_input(pull);
267 Self { pin }
268 }
269
270 #[inline]
272 pub fn is_high(&self) -> bool {
273 self.pin.is_high()
274 }
275
276 #[inline]
278 pub fn is_low(&self) -> bool {
279 self.pin.is_low()
280 }
281
282 #[inline]
284 pub fn get_level(&self) -> Level {
285 self.pin.get_level()
286 }
287}
288
289#[derive(Debug, Eq, PartialEq, Copy, Clone)]
291#[cfg_attr(feature = "defmt", derive(defmt::Format))]
292pub enum Level {
293 Low,
295 High,
297}
298
299impl From<bool> for Level {
300 fn from(val: bool) -> Self {
301 match val {
302 true => Self::High,
303 false => Self::Low,
304 }
305 }
306}
307
308impl From<Level> for bool {
309 fn from(level: Level) -> bool {
310 match level {
311 Level::Low => false,
312 Level::High => true,
313 }
314 }
315}
316
317pub struct Output<'d> {
323 pub(crate) pin: Flex<'d>,
324}
325
326impl<'d> Output<'d> {
327 #[inline]
329 pub fn new(
330 pin: impl Peripheral<P = impl Pin> + 'd,
331 initial_output: Level,
332 speed: Speed,
333 ) -> Self {
334 let mut pin = Flex::new(pin);
335 match initial_output {
336 Level::High => pin.set_high(),
337 Level::Low => pin.set_low(),
338 }
339 pin.set_as_output(speed);
340 Self { pin }
341 }
342
343 #[inline]
345 pub fn set_high(&mut self) {
346 self.pin.set_high();
347 }
348
349 #[inline]
351 pub fn set_low(&mut self) {
352 self.pin.set_low();
353 }
354
355 #[inline]
357 pub fn set_level(&mut self, level: Level) {
358 self.pin.set_level(level)
359 }
360
361 #[inline]
363 pub fn is_set_high(&self) -> bool {
364 self.pin.is_set_high()
365 }
366
367 #[inline]
369 pub fn is_set_low(&self) -> bool {
370 self.pin.is_set_low()
371 }
372
373 #[inline]
375 pub fn get_output_level(&self) -> Level {
376 self.pin.get_output_level()
377 }
378
379 #[inline]
381 pub fn toggle(&mut self) {
382 self.pin.toggle();
383 }
384}
385
386pub struct OutputOpenDrain<'d> {
392 pub(crate) pin: Flex<'d>,
393}
394
395impl<'d> OutputOpenDrain<'d> {
396 #[inline]
398 pub fn new(
399 pin: impl Peripheral<P = impl Pin> + 'd,
400 initial_output: Level,
401 speed: Speed,
402 ) -> Self {
403 let mut pin = Flex::new(pin);
404 match initial_output {
405 Level::High => pin.set_high(),
406 Level::Low => pin.set_low(),
407 }
408 pin.set_as_input_output(speed);
409 Self { pin }
410 }
411
412 #[inline]
415 pub fn new_pull(
416 pin: impl Peripheral<P = impl Pin> + 'd,
417 initial_output: Level,
418 speed: Speed,
419 pull: Pull,
420 ) -> Self {
421 let mut pin = Flex::new(pin);
422 match initial_output {
423 Level::High => pin.set_high(),
424 Level::Low => pin.set_low(),
425 }
426 pin.set_as_input_output_pull(speed, pull);
427 Self { pin }
428 }
429
430 #[inline]
432 pub fn is_high(&self) -> bool {
433 !self.pin.is_low()
434 }
435
436 #[inline]
438 pub fn is_low(&self) -> bool {
439 self.pin.is_low()
440 }
441
442 #[inline]
444 pub fn get_level(&self) -> Level {
445 self.pin.get_level()
446 }
447
448 #[inline]
450 pub fn set_high(&mut self) {
451 self.pin.set_high();
452 }
453
454 #[inline]
456 pub fn set_low(&mut self) {
457 self.pin.set_low();
458 }
459
460 #[inline]
462 pub fn set_level(&mut self, level: Level) {
463 self.pin.set_level(level);
464 }
465
466 #[inline]
468 pub fn is_set_high(&self) -> bool {
469 self.pin.is_set_high()
470 }
471
472 #[inline]
474 pub fn is_set_low(&self) -> bool {
475 self.pin.is_set_low()
476 }
477
478 #[inline]
480 pub fn get_output_level(&self) -> Level {
481 self.pin.get_output_level()
482 }
483
484 #[inline]
486 pub fn toggle(&mut self) {
487 self.pin.toggle()
488 }
489}
490
491#[derive(Debug, Copy, Clone)]
493#[cfg_attr(feature = "defmt", derive(defmt::Format))]
494pub enum OutputType {
495 PushPull,
497 OpenDrain,
499}
500
501impl OutputType {
502 const fn to_ot(self) -> vals::Ot {
503 match self {
504 OutputType::PushPull => vals::Ot::PUSHPULL,
505 OutputType::OpenDrain => vals::Ot::OPENDRAIN,
506 }
507 }
508}
509
510#[derive(Copy, Clone)]
512pub struct AfType {
513 pupdr: vals::Pupdr,
514 ot: vals::Ot,
515 ospeedr: vals::Ospeedr,
516}
517
518impl AfType {
519 pub const fn input(pull: Pull) -> Self {
521 Self {
522 pupdr: pull.to_pupdr(),
523 ot: vals::Ot::PUSHPULL,
524 ospeedr: vals::Ospeedr::LOWSPEED,
525 }
526 }
527
528 pub const fn output(output_type: OutputType, speed: Speed) -> Self {
530 Self::output_pull(output_type, speed, Pull::None)
531 }
532
533 pub const fn output_pull(output_type: OutputType, speed: Speed, pull: Pull) -> Self {
535 Self {
536 pupdr: pull.to_pupdr(),
537 ot: output_type.to_ot(),
538 ospeedr: speed.to_ospeedr(),
539 }
540 }
541}
542
543#[inline(never)]
544fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) {
545 let pin = unsafe { AnyPin::steal(pin_port) };
546 let r = pin.block();
547 let n = pin._pin() as usize;
548
549 r.afr(n / 8).modify(|w| w.set_afr(n % 8, af_num));
550 r.pupdr().modify(|w| w.set_pupdr(n, af_type.pupdr));
551 r.otyper().modify(|w| w.set_ot(n, af_type.ot));
552 r.ospeedr().modify(|w| w.set_ospeedr(n, af_type.ospeedr));
553 r.moder().modify(|w| w.set_moder(n, vals::Moder::ALTERNATE));
554}
555
556#[inline(never)]
557fn set_as_analog(pin_port: u8) {
558 let pin = unsafe { AnyPin::steal(pin_port) };
559 let r = pin.block();
560 let n = pin._pin() as usize;
561
562 r.moder().modify(|w| w.set_moder(n, vals::Moder::ANALOG));
563}
564
565pub(crate) trait SealedPin {
580 fn pin_port(&self) -> u8;
581
582 #[inline]
583 fn _pin(&self) -> u8 {
584 self.pin_port() % 16
585 }
586
587 #[inline]
588 fn _port(&self) -> u8 {
589 self.pin_port() / 16
590 }
591
592 #[inline]
593 fn block(&self) -> gpio::Gpio {
594 pac::GPIO(self._port() as _)
595 }
596
597 #[inline]
599 fn set_high(&self) {
600 let n = self._pin() as _;
601 self.block().bsrr().write(|w| w.set_bs(n, true));
602 }
603
604 #[inline]
606 fn set_low(&self) {
607 let n = self._pin() as _;
608 self.block().brr().write(|w| w.set_br(n, true));
609 }
610
611 #[inline]
612 fn set_as_af(&self, af_num: u8, af_type: AfType) {
613 set_as_af(self.pin_port(), af_num, af_type)
614 }
615
616 #[inline]
617 fn set_as_analog(&self) {
618 set_as_analog(self.pin_port());
619 }
620
621 #[inline]
629 fn set_as_disconnected(&self) {
630 self.set_as_analog();
631 }
632
633 }
639
640#[allow(private_bounds)]
642pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
643 #[cfg(feature = "exti")]
647 type ExtiChannel: crate::exti::Channel;
648
649 #[inline]
651 fn pin(&self) -> u8 {
652 self._pin()
653 }
654
655 #[inline]
657 fn port(&self) -> u8 {
658 self._port()
659 }
660
661 #[inline]
667 fn degrade(self) -> AnyPin {
668 AnyPin {
669 pin_port: self.pin_port(),
670 }
671 }
672}
673
674pub struct AnyPin {
676 pin_port: u8,
677}
678
679impl AnyPin {
680 #[inline]
684 pub unsafe fn steal(pin_port: u8) -> Self {
685 Self { pin_port }
686 }
687
688 #[inline]
689 fn _port(&self) -> u8 {
690 self.pin_port / 16
691 }
692
693 }
700
701impl_peripheral!(AnyPin);
702impl Pin for AnyPin {
703 #[cfg(feature = "exti")]
704 type ExtiChannel = crate::exti::AnyChannel;
705}
706impl SealedPin for AnyPin {
707 #[inline]
708 fn pin_port(&self) -> u8 {
709 self.pin_port
710 }
711}
712
713foreach_pin!(
716 ($pin_name:ident, $port_name:ident, $port_num:expr, $pin_num:expr, $exti_ch:ident) => {
717 impl Pin for peripherals::$pin_name {
718 #[cfg(feature = "exti")]
719 type ExtiChannel = peripherals::$exti_ch;
720 }
721 impl SealedPin for peripherals::$pin_name {
722 #[inline]
723 fn pin_port(&self) -> u8 {
724 $port_num * 16 + $pin_num
725 }
726 }
727
728 impl From<peripherals::$pin_name> for AnyPin {
729 fn from(x: peripherals::$pin_name) -> Self {
730 x.degrade()
731 }
732 }
733 };
734);
735
736pub(crate) unsafe fn init(_cs: CriticalSection) {
737 crate::_generated::init_gpio();
741}
742
743impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> {
744 type Error = Infallible;
745
746 #[inline]
747 fn is_high(&self) -> Result<bool, Self::Error> {
748 Ok(self.is_high())
749 }
750
751 #[inline]
752 fn is_low(&self) -> Result<bool, Self::Error> {
753 Ok(self.is_low())
754 }
755}
756
757impl<'d> embedded_hal_02::digital::v2::OutputPin for Output<'d> {
758 type Error = Infallible;
759
760 #[inline]
761 fn set_high(&mut self) -> Result<(), Self::Error> {
762 self.set_high();
763 Ok(())
764 }
765
766 #[inline]
767 fn set_low(&mut self) -> Result<(), Self::Error> {
768 self.set_low();
769 Ok(())
770 }
771}
772
773impl<'d> embedded_hal_02::digital::v2::StatefulOutputPin for Output<'d> {
774 #[inline]
775 fn is_set_high(&self) -> Result<bool, Self::Error> {
776 Ok(self.is_set_high())
777 }
778
779 #[inline]
781 fn is_set_low(&self) -> Result<bool, Self::Error> {
782 Ok(self.is_set_low())
783 }
784}
785
786impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d> {
787 type Error = Infallible;
788 #[inline]
789 fn toggle(&mut self) -> Result<(), Self::Error> {
790 self.toggle();
791 Ok(())
792 }
793}
794
795impl<'d> embedded_hal_02::digital::v2::InputPin for OutputOpenDrain<'d> {
796 type Error = Infallible;
797
798 fn is_high(&self) -> Result<bool, Self::Error> {
799 Ok(self.is_high())
800 }
801
802 fn is_low(&self) -> Result<bool, Self::Error> {
803 Ok(self.is_low())
804 }
805}
806
807impl<'d> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d> {
808 type Error = Infallible;
809
810 #[inline]
811 fn set_high(&mut self) -> Result<(), Self::Error> {
812 self.set_high();
813 Ok(())
814 }
815
816 #[inline]
817 fn set_low(&mut self) -> Result<(), Self::Error> {
818 self.set_low();
819 Ok(())
820 }
821}
822
823impl<'d> embedded_hal_02::digital::v2::StatefulOutputPin for OutputOpenDrain<'d> {
824 #[inline]
825 fn is_set_high(&self) -> Result<bool, Self::Error> {
826 Ok(self.is_set_high())
827 }
828
829 #[inline]
831 fn is_set_low(&self) -> Result<bool, Self::Error> {
832 Ok(self.is_set_low())
833 }
834}
835
836impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for OutputOpenDrain<'d> {
837 type Error = Infallible;
838 #[inline]
839 fn toggle(&mut self) -> Result<(), Self::Error> {
840 self.toggle();
841 Ok(())
842 }
843}
844
845impl<'d> embedded_hal_02::digital::v2::InputPin for Flex<'d> {
846 type Error = Infallible;
847
848 #[inline]
849 fn is_high(&self) -> Result<bool, Self::Error> {
850 Ok(self.is_high())
851 }
852
853 #[inline]
854 fn is_low(&self) -> Result<bool, Self::Error> {
855 Ok(self.is_low())
856 }
857}
858
859impl<'d> embedded_hal_02::digital::v2::OutputPin for Flex<'d> {
860 type Error = Infallible;
861
862 #[inline]
863 fn set_high(&mut self) -> Result<(), Self::Error> {
864 self.set_high();
865 Ok(())
866 }
867
868 #[inline]
869 fn set_low(&mut self) -> Result<(), Self::Error> {
870 self.set_low();
871 Ok(())
872 }
873}
874
875impl<'d> embedded_hal_02::digital::v2::StatefulOutputPin for Flex<'d> {
876 #[inline]
877 fn is_set_high(&self) -> Result<bool, Self::Error> {
878 Ok(self.is_set_high())
879 }
880
881 #[inline]
883 fn is_set_low(&self) -> Result<bool, Self::Error> {
884 Ok(self.is_set_low())
885 }
886}
887
888impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'d> {
889 type Error = Infallible;
890 #[inline]
891 fn toggle(&mut self) -> Result<(), Self::Error> {
892 self.toggle();
893 Ok(())
894 }
895}
896
897impl<'d> embedded_hal_1::digital::ErrorType for Input<'d> {
898 type Error = Infallible;
899}
900
901impl<'d> embedded_hal_1::digital::InputPin for Input<'d> {
902 #[inline]
903 fn is_high(&mut self) -> Result<bool, Self::Error> {
904 Ok((*self).is_high())
905 }
906
907 #[inline]
908 fn is_low(&mut self) -> Result<bool, Self::Error> {
909 Ok((*self).is_low())
910 }
911}
912
913impl<'d> embedded_hal_1::digital::ErrorType for Output<'d> {
914 type Error = Infallible;
915}
916
917impl<'d> embedded_hal_1::digital::OutputPin for Output<'d> {
918 #[inline]
919 fn set_high(&mut self) -> Result<(), Self::Error> {
920 Ok(self.set_high())
921 }
922
923 #[inline]
924 fn set_low(&mut self) -> Result<(), Self::Error> {
925 Ok(self.set_low())
926 }
927}
928
929impl<'d> embedded_hal_1::digital::StatefulOutputPin for Output<'d> {
930 #[inline]
931 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
932 Ok((*self).is_set_high())
933 }
934
935 #[inline]
937 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
938 Ok((*self).is_set_low())
939 }
940}
941
942impl<'d> embedded_hal_1::digital::ErrorType for OutputOpenDrain<'d> {
943 type Error = Infallible;
944}
945
946impl<'d> embedded_hal_1::digital::InputPin for OutputOpenDrain<'d> {
947 #[inline]
948 fn is_high(&mut self) -> Result<bool, Self::Error> {
949 Ok((*self).is_high())
950 }
951
952 #[inline]
953 fn is_low(&mut self) -> Result<bool, Self::Error> {
954 Ok((*self).is_low())
955 }
956}
957
958impl<'d> embedded_hal_1::digital::OutputPin for OutputOpenDrain<'d> {
959 #[inline]
960 fn set_high(&mut self) -> Result<(), Self::Error> {
961 Ok(self.set_high())
962 }
963
964 #[inline]
965 fn set_low(&mut self) -> Result<(), Self::Error> {
966 Ok(self.set_low())
967 }
968}
969
970impl<'d> embedded_hal_1::digital::StatefulOutputPin for OutputOpenDrain<'d> {
971 #[inline]
972 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
973 Ok((*self).is_set_high())
974 }
975
976 #[inline]
978 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
979 Ok((*self).is_set_low())
980 }
981}
982
983impl<'d> embedded_hal_1::digital::InputPin for Flex<'d> {
984 #[inline]
985 fn is_high(&mut self) -> Result<bool, Self::Error> {
986 Ok((*self).is_high())
987 }
988
989 #[inline]
990 fn is_low(&mut self) -> Result<bool, Self::Error> {
991 Ok((*self).is_low())
992 }
993}
994
995impl<'d> embedded_hal_1::digital::OutputPin for Flex<'d> {
996 #[inline]
997 fn set_high(&mut self) -> Result<(), Self::Error> {
998 Ok(self.set_high())
999 }
1000
1001 #[inline]
1002 fn set_low(&mut self) -> Result<(), Self::Error> {
1003 Ok(self.set_low())
1004 }
1005}
1006
1007impl<'d> embedded_hal_1::digital::ErrorType for Flex<'d> {
1008 type Error = Infallible;
1009}
1010
1011impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> {
1012 #[inline]
1013 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1014 Ok((*self).is_set_high())
1015 }
1016
1017 #[inline]
1019 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1020 Ok((*self).is_set_low())
1021 }
1022}