aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/gpio.rs
diff options
context:
space:
mode:
authorRaul Alimbekov <[email protected]>2025-12-16 09:05:22 +0300
committerGitHub <[email protected]>2025-12-16 09:05:22 +0300
commitc9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch)
tree6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-stm32/src/gpio.rs
parentcde24a3ef1117653ba5ed4184102b33f745782fb (diff)
parent5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff)
Merge branch 'main' into main
Diffstat (limited to 'embassy-stm32/src/gpio.rs')
-rw-r--r--embassy-stm32/src/gpio.rs73
1 files changed, 47 insertions, 26 deletions
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 5a8d23183..5de8bad2c 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -4,7 +4,7 @@
4use core::convert::Infallible; 4use core::convert::Infallible;
5 5
6use critical_section::CriticalSection; 6use critical_section::CriticalSection;
7use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; 7use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral};
8 8
9use crate::pac::gpio::{self, vals}; 9use crate::pac::gpio::{self, vals};
10use crate::peripherals; 10use crate::peripherals;
@@ -592,7 +592,7 @@ impl AfType {
592 592
593#[inline(never)] 593#[inline(never)]
594#[cfg(gpio_v1)] 594#[cfg(gpio_v1)]
595fn set_as_af(pin_port: u8, af_type: AfType) { 595fn set_as_af(pin_port: PinNumber, af_type: AfType) {
596 let pin = unsafe { AnyPin::steal(pin_port) }; 596 let pin = unsafe { AnyPin::steal(pin_port) };
597 let r = pin.block(); 597 let r = pin.block();
598 let n = pin._pin() as usize; 598 let n = pin._pin() as usize;
@@ -649,7 +649,7 @@ impl AfType {
649 649
650#[inline(never)] 650#[inline(never)]
651#[cfg(gpio_v2)] 651#[cfg(gpio_v2)]
652fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) { 652fn set_as_af(pin_port: PinNumber, af_num: u8, af_type: AfType) {
653 let pin = unsafe { AnyPin::steal(pin_port) }; 653 let pin = unsafe { AnyPin::steal(pin_port) };
654 let r = pin.block(); 654 let r = pin.block();
655 let n = pin._pin() as usize; 655 let n = pin._pin() as usize;
@@ -663,7 +663,7 @@ fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) {
663 663
664#[inline(never)] 664#[inline(never)]
665#[cfg(gpio_v2)] 665#[cfg(gpio_v2)]
666fn set_speed(pin_port: u8, speed: Speed) { 666fn set_speed(pin_port: PinNumber, speed: Speed) {
667 let pin = unsafe { AnyPin::steal(pin_port) }; 667 let pin = unsafe { AnyPin::steal(pin_port) };
668 let r = pin.block(); 668 let r = pin.block();
669 let n = pin._pin() as usize; 669 let n = pin._pin() as usize;
@@ -672,7 +672,7 @@ fn set_speed(pin_port: u8, speed: Speed) {
672} 672}
673 673
674#[inline(never)] 674#[inline(never)]
675fn set_as_analog(pin_port: u8) { 675fn set_as_analog(pin_port: PinNumber) {
676 let pin = unsafe { AnyPin::steal(pin_port) }; 676 let pin = unsafe { AnyPin::steal(pin_port) };
677 let r = pin.block(); 677 let r = pin.block();
678 let n = pin._pin() as usize; 678 let n = pin._pin() as usize;
@@ -684,11 +684,15 @@ fn set_as_analog(pin_port: u8) {
684 }); 684 });
685 685
686 #[cfg(gpio_v2)] 686 #[cfg(gpio_v2)]
687 r.moder().modify(|w| w.set_moder(n, vals::Moder::ANALOG)); 687 {
688 #[cfg(any(stm32l47x, stm32l48x))]
689 r.ascr().modify(|w| w.set_asc(n, true));
690 r.moder().modify(|w| w.set_moder(n, vals::Moder::ANALOG));
691 }
688} 692}
689 693
690#[inline(never)] 694#[inline(never)]
691fn get_pull(pin_port: u8) -> Pull { 695fn get_pull(pin_port: PinNumber) -> Pull {
692 let pin = unsafe { AnyPin::steal(pin_port) }; 696 let pin = unsafe { AnyPin::steal(pin_port) };
693 let r = pin.block(); 697 let r = pin.block();
694 let n = pin._pin() as usize; 698 let n = pin._pin() as usize;
@@ -727,15 +731,15 @@ pub struct AfioRemapBool<const V: bool>;
727pub struct AfioRemapNotApplicable; 731pub struct AfioRemapNotApplicable;
728 732
729pub(crate) trait SealedPin { 733pub(crate) trait SealedPin {
730 fn pin_port(&self) -> u8; 734 fn pin_port(&self) -> PinNumber;
731 735
732 #[inline] 736 #[inline]
733 fn _pin(&self) -> u8 { 737 fn _pin(&self) -> PinNumber {
734 self.pin_port() % 16 738 self.pin_port() % 16
735 } 739 }
736 740
737 #[inline] 741 #[inline]
738 fn _port(&self) -> u8 { 742 fn _port(&self) -> PinNumber {
739 self.pin_port() / 16 743 self.pin_port() / 16
740 } 744 }
741 745
@@ -798,31 +802,49 @@ pub(crate) trait SealedPin {
798 } 802 }
799} 803}
800 804
801/// GPIO pin trait. 805/// GPIO pin number type.
806///
807/// Some chips have a total number of ports that exceeds 8, a larger integer
808/// is needed to hold the total pin number `(ports * number)`.
809#[cfg(not(stm32n6))]
810pub type PinNumber = u8;
811
812/// GPIO pin number type.
813///
814/// Some chips have a total number of ports that exceeds 8, a larger integer
815/// is needed to hold the total pin number `(ports * number)`.
816#[cfg(stm32n6)]
817pub type PinNumber = u16;
818
819/// Pin that can be used to configure an [ExtiInput](crate::exti::ExtiInput). This trait is lost when converting to [AnyPin].
820#[cfg(feature = "exti")]
802#[allow(private_bounds)] 821#[allow(private_bounds)]
803pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { 822pub trait ExtiPin: PeripheralType + SealedPin {
804 /// EXTI channel assigned to this pin. 823 /// EXTI channel assigned to this pin.
805 /// 824 ///
806 /// For example, PC4 uses EXTI4. 825 /// For example, PC4 uses EXTI4.
807 #[cfg(feature = "exti")]
808 type ExtiChannel: crate::exti::Channel; 826 type ExtiChannel: crate::exti::Channel;
827}
809 828
829/// GPIO pin trait.
830#[allow(private_bounds)]
831pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
810 /// Number of the pin within the port (0..31) 832 /// Number of the pin within the port (0..31)
811 #[inline] 833 #[inline]
812 fn pin(&self) -> u8 { 834 fn pin(&self) -> PinNumber {
813 self._pin() 835 self._pin()
814 } 836 }
815 837
816 /// Port of the pin 838 /// Port of the pin
817 #[inline] 839 #[inline]
818 fn port(&self) -> u8 { 840 fn port(&self) -> PinNumber {
819 self._port() 841 self._port()
820 } 842 }
821} 843}
822 844
823/// Type-erased GPIO pin 845/// Type-erased GPIO pin.
824pub struct AnyPin { 846pub struct AnyPin {
825 pin_port: u8, 847 pin_port: PinNumber,
826} 848}
827 849
828impl AnyPin { 850impl AnyPin {
@@ -830,12 +852,12 @@ impl AnyPin {
830 /// 852 ///
831 /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc... 853 /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc...
832 #[inline] 854 #[inline]
833 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> { 855 pub unsafe fn steal(pin_port: PinNumber) -> Peri<'static, Self> {
834 Peri::new_unchecked(Self { pin_port }) 856 Peri::new_unchecked(Self { pin_port })
835 } 857 }
836 858
837 #[inline] 859 #[inline]
838 fn _port(&self) -> u8 { 860 fn _port(&self) -> PinNumber {
839 self.pin_port / 16 861 self.pin_port / 16
840 } 862 }
841 863
@@ -848,13 +870,10 @@ impl AnyPin {
848} 870}
849 871
850impl_peripheral!(AnyPin); 872impl_peripheral!(AnyPin);
851impl Pin for AnyPin { 873impl Pin for AnyPin {}
852 #[cfg(feature = "exti")]
853 type ExtiChannel = crate::exti::AnyChannel;
854}
855impl SealedPin for AnyPin { 874impl SealedPin for AnyPin {
856 #[inline] 875 #[inline]
857 fn pin_port(&self) -> u8 { 876 fn pin_port(&self) -> PinNumber {
858 self.pin_port 877 self.pin_port
859 } 878 }
860} 879}
@@ -864,12 +883,14 @@ impl SealedPin for AnyPin {
864foreach_pin!( 883foreach_pin!(
865 ($pin_name:ident, $port_name:ident, $port_num:expr, $pin_num:expr, $exti_ch:ident) => { 884 ($pin_name:ident, $port_name:ident, $port_num:expr, $pin_num:expr, $exti_ch:ident) => {
866 impl Pin for peripherals::$pin_name { 885 impl Pin for peripherals::$pin_name {
867 #[cfg(feature = "exti")] 886 }
887 #[cfg(feature = "exti")]
888 impl ExtiPin for peripherals::$pin_name {
868 type ExtiChannel = peripherals::$exti_ch; 889 type ExtiChannel = peripherals::$exti_ch;
869 } 890 }
870 impl SealedPin for peripherals::$pin_name { 891 impl SealedPin for peripherals::$pin_name {
871 #[inline] 892 #[inline]
872 fn pin_port(&self) -> u8 { 893 fn pin_port(&self) -> PinNumber {
873 $port_num * 16 + $pin_num 894 $port_num * 16 + $pin_num
874 } 895 }
875 } 896 }