diff options
| author | Raul Alimbekov <[email protected]> | 2025-12-16 09:05:22 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-16 09:05:22 +0300 |
| commit | c9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch) | |
| tree | 6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-stm32/src/gpio.rs | |
| parent | cde24a3ef1117653ba5ed4184102b33f745782fb (diff) | |
| parent | 5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff) | |
Merge branch 'main' into main
Diffstat (limited to 'embassy-stm32/src/gpio.rs')
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 73 |
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 @@ | |||
| 4 | use core::convert::Infallible; | 4 | use core::convert::Infallible; |
| 5 | 5 | ||
| 6 | use critical_section::CriticalSection; | 6 | use critical_section::CriticalSection; |
| 7 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 7 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 8 | 8 | ||
| 9 | use crate::pac::gpio::{self, vals}; | 9 | use crate::pac::gpio::{self, vals}; |
| 10 | use crate::peripherals; | 10 | use crate::peripherals; |
| @@ -592,7 +592,7 @@ impl AfType { | |||
| 592 | 592 | ||
| 593 | #[inline(never)] | 593 | #[inline(never)] |
| 594 | #[cfg(gpio_v1)] | 594 | #[cfg(gpio_v1)] |
| 595 | fn set_as_af(pin_port: u8, af_type: AfType) { | 595 | fn 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)] |
| 652 | fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) { | 652 | fn 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)] |
| 666 | fn set_speed(pin_port: u8, speed: Speed) { | 666 | fn 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)] |
| 675 | fn set_as_analog(pin_port: u8) { | 675 | fn 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)] |
| 691 | fn get_pull(pin_port: u8) -> Pull { | 695 | fn 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>; | |||
| 727 | pub struct AfioRemapNotApplicable; | 731 | pub struct AfioRemapNotApplicable; |
| 728 | 732 | ||
| 729 | pub(crate) trait SealedPin { | 733 | pub(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))] | ||
| 810 | pub 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)] | ||
| 817 | pub 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)] |
| 803 | pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static { | 822 | pub 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)] | ||
| 831 | pub 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. |
| 824 | pub struct AnyPin { | 846 | pub struct AnyPin { |
| 825 | pin_port: u8, | 847 | pin_port: PinNumber, |
| 826 | } | 848 | } |
| 827 | 849 | ||
| 828 | impl AnyPin { | 850 | impl 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 | ||
| 850 | impl_peripheral!(AnyPin); | 872 | impl_peripheral!(AnyPin); |
| 851 | impl Pin for AnyPin { | 873 | impl Pin for AnyPin {} |
| 852 | #[cfg(feature = "exti")] | ||
| 853 | type ExtiChannel = crate::exti::AnyChannel; | ||
| 854 | } | ||
| 855 | impl SealedPin for AnyPin { | 874 | impl 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 { | |||
| 864 | foreach_pin!( | 883 | foreach_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 | } |
