From ea4e7bc3d23c3deb44fa6029f70ddcd72dfa4d35 Mon Sep 17 00:00:00 2001 From: everdrone Date: Sun, 21 Sep 2025 17:23:39 +0200 Subject: Use `PinNumber` to accomodate chips with more than 256 pins --- embassy-stm32/src/exti.rs | 16 ++++++++-------- embassy-stm32/src/gpio.rs | 37 +++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 376fdccb8..bc4ecd1cc 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -8,7 +8,7 @@ use core::task::{Context, Poll}; use embassy_hal_internal::{impl_peripheral, PeripheralType}; use embassy_sync::waitqueue::AtomicWaker; -use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull}; +use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, PinNumber, Pull}; use crate::pac::exti::regs::Lines; use crate::pac::EXTI; use crate::{interrupt, pac, peripherals, Peri}; @@ -226,12 +226,12 @@ impl<'d> embedded_hal_async::digital::Wait for ExtiInput<'d> { #[must_use = "futures do nothing unless you `.await` or poll them"] struct ExtiInputFuture<'a> { - pin: u8, + pin: PinNumber, phantom: PhantomData<&'a mut AnyPin>, } impl<'a> ExtiInputFuture<'a> { - fn new(pin: u8, port: u8, rising: bool, falling: bool) -> Self { + fn new(pin: PinNumber, port: PinNumber, rising: bool, falling: bool) -> Self { critical_section::with(|_| { let pin = pin as usize; exticr_regs().exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port)); @@ -334,20 +334,20 @@ trait SealedChannel {} #[allow(private_bounds)] pub trait Channel: PeripheralType + SealedChannel + Sized { /// Get the EXTI channel number. - fn number(&self) -> u8; + fn number(&self) -> PinNumber; } /// Type-erased EXTI channel. /// /// This represents ownership over any EXTI channel, known at runtime. pub struct AnyChannel { - number: u8, + number: PinNumber, } impl_peripheral!(AnyChannel); impl SealedChannel for AnyChannel {} impl Channel for AnyChannel { - fn number(&self) -> u8 { + fn number(&self) -> PinNumber { self.number } } @@ -356,7 +356,7 @@ macro_rules! impl_exti { ($type:ident, $number:expr) => { impl SealedChannel for peripherals::$type {} impl Channel for peripherals::$type { - fn number(&self) -> u8 { + fn number(&self) -> PinNumber { $number } } @@ -364,7 +364,7 @@ macro_rules! impl_exti { impl From for AnyChannel { fn from(val: peripherals::$type) -> Self { Self { - number: val.number() as u8, + number: val.number() as PinNumber, } } } diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 5a8d23183..ba5cf24c6 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -592,7 +592,7 @@ impl AfType { #[inline(never)] #[cfg(gpio_v1)] -fn set_as_af(pin_port: u8, af_type: AfType) { +fn set_as_af(pin_port: PinNumber, af_type: AfType) { let pin = unsafe { AnyPin::steal(pin_port) }; let r = pin.block(); let n = pin._pin() as usize; @@ -649,12 +649,12 @@ impl AfType { #[inline(never)] #[cfg(gpio_v2)] -fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) { +fn set_as_af(pin_port: PinNumber, af_num: u8, af_type: AfType) { let pin = unsafe { AnyPin::steal(pin_port) }; let r = pin.block(); let n = pin._pin() as usize; - r.afr(n / 8).modify(|w| w.set_afr(n % 8, af_num)); + r.afr(n / 8).modify(|w| w.set_afr(n % 8, af_num as u8)); r.pupdr().modify(|w| w.set_pupdr(n, af_type.pupdr)); r.otyper().modify(|w| w.set_ot(n, af_type.ot)); r.ospeedr().modify(|w| w.set_ospeedr(n, af_type.ospeedr)); @@ -663,7 +663,7 @@ fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) { #[inline(never)] #[cfg(gpio_v2)] -fn set_speed(pin_port: u8, speed: Speed) { +fn set_speed(pin_port: PinNumber, speed: Speed) { let pin = unsafe { AnyPin::steal(pin_port) }; let r = pin.block(); let n = pin._pin() as usize; @@ -672,7 +672,7 @@ fn set_speed(pin_port: u8, speed: Speed) { } #[inline(never)] -fn set_as_analog(pin_port: u8) { +fn set_as_analog(pin_port: PinNumber) { let pin = unsafe { AnyPin::steal(pin_port) }; let r = pin.block(); let n = pin._pin() as usize; @@ -688,7 +688,7 @@ fn set_as_analog(pin_port: u8) { } #[inline(never)] -fn get_pull(pin_port: u8) -> Pull { +fn get_pull(pin_port: PinNumber) -> Pull { let pin = unsafe { AnyPin::steal(pin_port) }; let r = pin.block(); let n = pin._pin() as usize; @@ -727,15 +727,15 @@ pub struct AfioRemapBool; pub struct AfioRemapNotApplicable; pub(crate) trait SealedPin { - fn pin_port(&self) -> u8; + fn pin_port(&self) -> PinNumber; #[inline] - fn _pin(&self) -> u8 { + fn _pin(&self) -> PinNumber { self.pin_port() % 16 } #[inline] - fn _port(&self) -> u8 { + fn _port(&self) -> PinNumber { self.pin_port() / 16 } @@ -798,6 +798,11 @@ pub(crate) trait SealedPin { } } +#[cfg(not(stm32n6))] +pub type PinNumber = u8; +#[cfg(stm32n6)] +pub type PinNumber = u16; + /// GPIO pin trait. #[allow(private_bounds)] pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { @@ -809,20 +814,20 @@ pub trait Pin: PeripheralType + Into + SealedPin + Sized + 'static { /// Number of the pin within the port (0..31) #[inline] - fn pin(&self) -> u8 { + fn pin(&self) -> PinNumber { self._pin() } /// Port of the pin #[inline] - fn port(&self) -> u8 { + fn port(&self) -> PinNumber { self._port() } } /// Type-erased GPIO pin pub struct AnyPin { - pin_port: u8, + pin_port: PinNumber, } impl AnyPin { @@ -830,12 +835,12 @@ impl AnyPin { /// /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc... #[inline] - pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> { + pub unsafe fn steal(pin_port: PinNumber) -> Peri<'static, Self> { Peri::new_unchecked(Self { pin_port }) } #[inline] - fn _port(&self) -> u8 { + fn _port(&self) -> PinNumber { self.pin_port / 16 } @@ -854,7 +859,7 @@ impl Pin for AnyPin { } impl SealedPin for AnyPin { #[inline] - fn pin_port(&self) -> u8 { + fn pin_port(&self) -> PinNumber { self.pin_port } } @@ -869,7 +874,7 @@ foreach_pin!( } impl SealedPin for peripherals::$pin_name { #[inline] - fn pin_port(&self) -> u8 { + fn pin_port(&self) -> PinNumber { $port_num * 16 + $pin_num } } -- cgit