stm32/afio: make the A generic param only appear in chips with AFIO.

This commit is contained in:
Dario Nieuwenhuis 2025-09-05 23:44:25 +02:00
parent 7419b398bf
commit 35f4ae378c
16 changed files with 291 additions and 226 deletions

View File

@ -181,10 +181,10 @@ pub enum TryWriteError {
impl<'d> Can<'d> {
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
/// You must call [Can::enable_non_blocking] to use the peripheral.
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
_peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
+ interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
+ interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>

View File

@ -99,19 +99,19 @@ macro_rules! config_pins {
impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
/// safety: the returned instance is not leak-safe
pub fn new<const TX: usize, const RX: usize, A>(
pub fn new<const TX: usize, const RX: usize, #[cfg(afio)] A>(
queue: &'d mut PacketQueue<TX, RX>,
peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: Peri<'d, impl RefClkPin<T, A>>,
mdio: Peri<'d, impl MDIOPin<T, A>>,
mdc: Peri<'d, impl MDCPin<T, A>>,
crs: Peri<'d, impl CRSPin<T, A>>,
rx_d0: Peri<'d, impl RXD0Pin<T, A>>,
rx_d1: Peri<'d, impl RXD1Pin<T, A>>,
tx_d0: Peri<'d, impl TXD0Pin<T, A>>,
tx_d1: Peri<'d, impl TXD1Pin<T, A>>,
tx_en: Peri<'d, impl TXEnPin<T, A>>,
ref_clk: Peri<'d, if_afio!(impl RefClkPin<T, A>)>,
mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
crs: Peri<'d, if_afio!(impl CRSPin<T, A>)>,
rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
tx_d0: Peri<'d, if_afio!(impl TXD0Pin<T, A>)>,
tx_d1: Peri<'d, if_afio!(impl TXD1Pin<T, A>)>,
tx_en: Peri<'d, if_afio!(impl TXEnPin<T, A>)>,
phy: P,
mac_addr: [u8; 6],
) -> Self {
@ -291,24 +291,24 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
}
/// Create a new MII ethernet driver using 14 pins.
pub fn new_mii<const TX: usize, const RX: usize, A>(
pub fn new_mii<const TX: usize, const RX: usize, #[cfg(afio)] A>(
queue: &'d mut PacketQueue<TX, RX>,
peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
rx_clk: Peri<'d, impl RXClkPin<T, A>>,
tx_clk: Peri<'d, impl TXClkPin<T, A>>,
mdio: Peri<'d, impl MDIOPin<T, A>>,
mdc: Peri<'d, impl MDCPin<T, A>>,
rxdv: Peri<'d, impl RXDVPin<T, A>>,
rx_d0: Peri<'d, impl RXD0Pin<T, A>>,
rx_d1: Peri<'d, impl RXD1Pin<T, A>>,
rx_d2: Peri<'d, impl RXD2Pin<T, A>>,
rx_d3: Peri<'d, impl RXD3Pin<T, A>>,
tx_d0: Peri<'d, impl TXD0Pin<T, A>>,
tx_d1: Peri<'d, impl TXD1Pin<T, A>>,
tx_d2: Peri<'d, impl TXD2Pin<T, A>>,
tx_d3: Peri<'d, impl TXD3Pin<T, A>>,
tx_en: Peri<'d, impl TXEnPin<T, A>>,
rx_clk: Peri<'d, if_afio!(impl RXClkPin<T, A>)>,
tx_clk: Peri<'d, if_afio!(impl TXClkPin<T, A>)>,
mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
rxdv: Peri<'d, if_afio!(impl RXDVPin<T, A>)>,
rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
rx_d2: Peri<'d, if_afio!(impl RXD2Pin<T, A>)>,
rx_d3: Peri<'d, if_afio!(impl RXD3Pin<T, A>)>,
tx_d0: Peri<'d, if_afio!(impl TXD0Pin<T, A>)>,
tx_d1: Peri<'d, if_afio!(impl TXD1Pin<T, A>)>,
tx_d2: Peri<'d, if_afio!(impl TXD2Pin<T, A>)>,
tx_d3: Peri<'d, if_afio!(impl TXD3Pin<T, A>)>,
tx_en: Peri<'d, if_afio!(impl TXEnPin<T, A>)>,
phy: P,
mac_addr: [u8; 6],
) -> Self {

View File

@ -65,19 +65,19 @@ macro_rules! config_pins {
impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
/// Create a new RMII ethernet driver using 9 pins.
pub fn new<const TX: usize, const RX: usize, A>(
pub fn new<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>,
peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: Peri<'d, impl RefClkPin<T, A>>,
mdio: Peri<'d, impl MDIOPin<T, A>>,
mdc: Peri<'d, impl MDCPin<T, A>>,
crs: Peri<'d, impl CRSPin<T, A>>,
rx_d0: Peri<'d, impl RXD0Pin<T, A>>,
rx_d1: Peri<'d, impl RXD1Pin<T, A>>,
tx_d0: Peri<'d, impl TXD0Pin<T, A>>,
tx_d1: Peri<'d, impl TXD1Pin<T, A>>,
tx_en: Peri<'d, impl TXEnPin<T, A>>,
ref_clk: Peri<'d, impl RefClkPin<T>>,
mdio: Peri<'d, impl MDIOPin<T>>,
mdc: Peri<'d, impl MDCPin<T>>,
crs: Peri<'d, impl CRSPin<T>>,
rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: Peri<'d, impl RXD1Pin<T>>,
tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P,
mac_addr: [u8; 6],
) -> Self {
@ -110,24 +110,24 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
}
/// Create a new MII ethernet driver using 14 pins.
pub fn new_mii<const TX: usize, const RX: usize, A>(
pub fn new_mii<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>,
peri: Peri<'d, T>,
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
rx_clk: Peri<'d, impl RXClkPin<T, A>>,
tx_clk: Peri<'d, impl TXClkPin<T, A>>,
mdio: Peri<'d, impl MDIOPin<T, A>>,
mdc: Peri<'d, impl MDCPin<T, A>>,
rxdv: Peri<'d, impl RXDVPin<T, A>>,
rx_d0: Peri<'d, impl RXD0Pin<T, A>>,
rx_d1: Peri<'d, impl RXD1Pin<T, A>>,
rx_d2: Peri<'d, impl RXD2Pin<T, A>>,
rx_d3: Peri<'d, impl RXD3Pin<T, A>>,
tx_d0: Peri<'d, impl TXD0Pin<T, A>>,
tx_d1: Peri<'d, impl TXD1Pin<T, A>>,
tx_d2: Peri<'d, impl TXD2Pin<T, A>>,
tx_d3: Peri<'d, impl TXD3Pin<T, A>>,
tx_en: Peri<'d, impl TXEnPin<T, A>>,
rx_clk: Peri<'d, impl RXClkPin<T>>,
tx_clk: Peri<'d, impl TXClkPin<T>>,
mdio: Peri<'d, impl MDIOPin<T>>,
mdc: Peri<'d, impl MDCPin<T>>,
rxdv: Peri<'d, impl RXDVPin<T>>,
rx_d0: Peri<'d, impl RXD0Pin<T>>,
rx_d1: Peri<'d, impl RXD1Pin<T>>,
rx_d2: Peri<'d, impl RXD2Pin<T>>,
rx_d3: Peri<'d, impl RXD3Pin<T>>,
tx_d0: Peri<'d, impl TXD0Pin<T>>,
tx_d1: Peri<'d, impl TXD1Pin<T>>,
tx_d2: Peri<'d, impl TXD2Pin<T>>,
tx_d3: Peri<'d, impl TXD3Pin<T>>,
tx_en: Peri<'d, impl TXEnPin<T>>,
phy: P,
mac_addr: [u8; 6],
) -> Self {

View File

@ -718,6 +718,7 @@ pub struct AfioRemap<const V: u8>;
/// Holds the AFIO remap value for a peripheral's pin
pub struct AfioRemapBool<const V: bool>;
#[cfg(afio)]
/// Placeholder for a peripheral's pin which cannot be remapped via AFIO.
pub struct AfioRemapNotApplicable;

View File

@ -149,10 +149,10 @@ pub struct I2c<'d, M: Mode, IM: MasterMode> {
impl<'d> I2c<'d, Async, Master> {
/// Create a new I2C driver.
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
scl: Peri<'d, impl SclPin<T, A>>,
sda: Peri<'d, impl SdaPin<T, A>>,
scl: Peri<'d, if_afio!(impl SclPin<T, A>)>,
sda: Peri<'d, if_afio!(impl SdaPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
+ interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
+ 'd,
@ -173,10 +173,10 @@ impl<'d> I2c<'d, Async, Master> {
impl<'d> I2c<'d, Blocking, Master> {
/// Create a new blocking I2C driver.
pub fn new_blocking<T: Instance, A>(
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
scl: Peri<'d, impl SclPin<T, A>>,
sda: Peri<'d, impl SdaPin<T, A>>,
scl: Peri<'d, if_afio!(impl SclPin<T, A>)>,
sda: Peri<'d, if_afio!(impl SdaPin<T, A>)>,
config: Config,
) -> Self {
Self::new_inner(

View File

@ -237,12 +237,12 @@ pub struct I2S<'d, W: Word> {
impl<'d, W: Word> I2S<'d, W> {
/// Create a transmitter driver.
pub fn new_txonly<T: Instance, A>(
pub fn new_txonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sd: Peri<'d, impl MosiPin<T, A>>,
ws: Peri<'d, impl WsPin<T, A>>,
ck: Peri<'d, impl CkPin<T, A>>,
mck: Peri<'d, impl MckPin<T, A>>,
sd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
txdma: Peri<'d, impl TxDma<T>>,
txdma_buf: &'d mut [W],
config: Config,
@ -262,11 +262,11 @@ impl<'d, W: Word> I2S<'d, W> {
}
/// Create a transmitter driver without a master clock pin.
pub fn new_txonly_nomck<T: Instance, A>(
pub fn new_txonly_nomck<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sd: Peri<'d, impl MosiPin<T, A>>,
ws: Peri<'d, impl WsPin<T, A>>,
ck: Peri<'d, impl CkPin<T, A>>,
sd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
txdma: Peri<'d, impl TxDma<T>>,
txdma_buf: &'d mut [W],
config: Config,
@ -286,12 +286,12 @@ impl<'d, W: Word> I2S<'d, W> {
}
/// Create a receiver driver.
pub fn new_rxonly<T: Instance, A>(
pub fn new_rxonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sd: Peri<'d, impl MisoPin<T, A>>,
ws: Peri<'d, impl WsPin<T, A>>,
ck: Peri<'d, impl CkPin<T, A>>,
mck: Peri<'d, impl MckPin<T, A>>,
sd: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
rxdma: Peri<'d, impl RxDma<T>>,
rxdma_buf: &'d mut [W],
config: Config,
@ -313,13 +313,13 @@ impl<'d, W: Word> I2S<'d, W> {
#[cfg(any(spi_v4, spi_v5))]
/// Create a full duplex driver.
pub fn new_full_duplex<T: Instance, A>(
pub fn new_full_duplex<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
txsd: Peri<'d, impl MosiPin<T, A>>,
rxsd: Peri<'d, impl MisoPin<T, A>>,
ws: Peri<'d, impl WsPin<T, A>>,
ck: Peri<'d, impl CkPin<T, A>>,
mck: Peri<'d, impl MckPin<T, A>>,
txsd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
rxsd: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
txdma: Peri<'d, impl TxDma<T>>,
txdma_buf: &'d mut [W],
rxdma: Peri<'d, impl RxDma<T>>,
@ -459,12 +459,12 @@ impl<'d, W: Word> I2S<'d, W> {
}
}
fn new_inner<T: Instance, A>(
fn new_inner<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
txsd: Option<Peri<'d, AnyPin>>,
rxsd: Option<Peri<'d, AnyPin>>,
ws: Peri<'d, impl WsPin<T, A>>,
ck: Peri<'d, impl CkPin<T, A>>,
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
mck: Option<Peri<'d, AnyPin>>,
txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,

View File

@ -43,7 +43,7 @@ macro_rules! peri_trait_impl {
macro_rules! pin_trait {
($signal:ident, $instance:path $(, $mode:path)? $(, @$afio:ident)?) => {
#[doc = concat!(stringify!($signal), " pin trait")]
pub trait $signal<T: $instance $(, M: $mode)? $(, $afio)?>: crate::gpio::Pin {
pub trait $signal<T: $instance $(, M: $mode)? $(, #[cfg(afio)] $afio)?>: crate::gpio::Pin {
#[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))]
fn af_num(&self) -> u8;
@ -56,16 +56,23 @@ macro_rules! pin_trait {
macro_rules! pin_trait_impl {
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr $(, $afio:path)?) => {
#[cfg(afio)]
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)? $(, $afio)?> for crate::peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
#[cfg(afio)]
fn afio_remap(&self) {
// nothing
}
}
#[cfg(not(afio))]
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin {
fn af_num(&self) -> u8 {
$af
}
}
};
}
@ -190,3 +197,46 @@ macro_rules! new_pin {
Some(pin.into())
}};
}
#[cfg(afio)]
macro_rules! if_afio {
($($t:tt)*) => {
$($t)*
}
}
#[cfg(not(afio))]
macro_rules! if_afio {
(($a:ty, A)) => {
($a,)
};
(($a:ty, $b:ty, A)) => {
($a,$b)
};
(($a:ty, $b:ty, $c:ty, A)) => {
($a,$b, $c)
};
($type:ident<$lt:lifetime, $a:ty, $b:ty, A>) => {
$type<$lt, $a, $b>
};
($type:ident<$lt:lifetime, $a:ty, $b:ty, $c:ty, A>) => {
$type<$lt, $a, $b, $c>
};
($type:ident<$a:ty, A>) => {
$type<$a>
};
($type:ident<$a:ty, $b:ty, A>) => {
$type<$a, $b>
};
($type:ident<$a:ty, $b:ty, $c:ty, A>) => {
$type<$a, $b, $c>
};
(impl $trait:ident<$a:ty, A>) => {
impl $trait<$a>
};
(impl $trait:ident<$a:ty, $b:ty, A>) => {
impl $trait<$a, $b>
};
(impl $trait:ident<$a:ty, $b:ty, $c:ty, A>) => {
impl $trait<$a, $b, $c>
};
}

View File

@ -471,11 +471,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
impl<'d> Spi<'d, Blocking> {
/// Create a new blocking SPI driver.
pub fn new_blocking<T: Instance, A>(
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
mosi: Peri<'d, impl MosiPin<T, A>>,
miso: Peri<'d, impl MisoPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
config: Config,
) -> Self {
Self::new_inner(
@ -490,10 +490,10 @@ impl<'d> Spi<'d, Blocking> {
}
/// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI).
pub fn new_blocking_rxonly<T: Instance, A>(
pub fn new_blocking_rxonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
miso: Peri<'d, impl MisoPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
config: Config,
) -> Self {
Self::new_inner(
@ -508,10 +508,10 @@ impl<'d> Spi<'d, Blocking> {
}
/// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO).
pub fn new_blocking_txonly<T: Instance, A>(
pub fn new_blocking_txonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
mosi: Peri<'d, impl MosiPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
config: Config,
) -> Self {
Self::new_inner(
@ -528,9 +528,9 @@ impl<'d> Spi<'d, Blocking> {
/// Create a new SPI driver, in TX-only mode, without SCK pin.
///
/// This can be useful for bit-banging non-SPI protocols.
pub fn new_blocking_txonly_nosck<T: Instance, A>(
pub fn new_blocking_txonly_nosck<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
mosi: Peri<'d, impl MosiPin<T, A>>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
config: Config,
) -> Self {
Self::new_inner(
@ -547,11 +547,11 @@ impl<'d> Spi<'d, Blocking> {
impl<'d> Spi<'d, Async> {
/// Create a new SPI driver.
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
mosi: Peri<'d, impl MosiPin<T, A>>,
miso: Peri<'d, impl MisoPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
@ -568,10 +568,10 @@ impl<'d> Spi<'d, Async> {
}
/// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI).
pub fn new_rxonly<T: Instance, A>(
pub fn new_rxonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
miso: Peri<'d, impl MisoPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
#[cfg(any(spi_v1, spi_v2, spi_v3))] tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
@ -591,10 +591,10 @@ impl<'d> Spi<'d, Async> {
}
/// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO).
pub fn new_txonly<T: Instance, A>(
pub fn new_txonly<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
sck: Peri<'d, impl SckPin<T, A>>,
mosi: Peri<'d, impl MosiPin<T, A>>,
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
config: Config,
) -> Self {
@ -612,9 +612,9 @@ impl<'d> Spi<'d, Async> {
/// Create a new SPI driver, in TX-only mode, without SCK pin.
///
/// This can be useful for bit-banging non-SPI protocols.
pub fn new_txonly_nosck<T: Instance, A>(
pub fn new_txonly_nosck<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
mosi: Peri<'d, impl MosiPin<T, A>>,
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
config: Config,
) -> Self {

View File

@ -16,15 +16,15 @@ use crate::Peri;
/// Complementary PWM pin wrapper.
///
/// This wraps a pin to make it usable with PWM.
pub struct ComplementaryPwmPin<'d, T, C, A> {
pub struct ComplementaryPwmPin<'d, T, C, #[cfg(afio)] A> {
#[allow(unused)]
pin: Peri<'d, AnyPin>,
phantom: PhantomData<(T, C, A)>,
phantom: PhantomData<if_afio!((T, C, A))>,
}
impl<'d, T: AdvancedInstance4Channel, C: TimerChannel, A> ComplementaryPwmPin<'d, T, C, A> {
impl<'d, T: AdvancedInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(ComplementaryPwmPin<'d, T, C, A>) {
/// Create a new complementary PWM pin instance.
pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C, A>>, output_type: OutputType) -> Self {
pub fn new(pin: Peri<'d, if_afio!(impl TimerComplementaryPin<T, C, A>)>, output_type: OutputType) -> Self {
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(
@ -58,16 +58,16 @@ pub enum IdlePolarity {
impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
/// Create a new complementary PWM driver.
#[allow(clippy::too_many_arguments, unused)]
pub fn new<A>(
pub fn new<#[cfg(afio)] A>(
tim: Peri<'d, T>,
ch1: Option<PwmPin<'d, T, Ch1, A>>,
ch1n: Option<ComplementaryPwmPin<'d, T, Ch1, A>>,
ch2: Option<PwmPin<'d, T, Ch2, A>>,
ch2n: Option<ComplementaryPwmPin<'d, T, Ch2, A>>,
ch3: Option<PwmPin<'d, T, Ch3, A>>,
ch3n: Option<ComplementaryPwmPin<'d, T, Ch3, A>>,
ch4: Option<PwmPin<'d, T, Ch4, A>>,
ch4n: Option<ComplementaryPwmPin<'d, T, Ch4, A>>,
ch1: Option<if_afio!(PwmPin<'d, T, Ch1, A>)>,
ch1n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch1, A>)>,
ch2: Option<if_afio!(PwmPin<'d, T, Ch2, A>)>,
ch2n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch2, A>)>,
ch3: Option<if_afio!(PwmPin<'d, T, Ch3, A>)>,
ch3n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch3, A>)>,
ch4: Option<if_afio!(PwmPin<'d, T, Ch4, A>)>,
ch4n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch4, A>)>,
freq: Hertz,
counting_mode: CountingMode,
) -> Self {

View File

@ -17,14 +17,14 @@ use crate::Peri;
/// Capture pin wrapper.
///
/// This wraps a pin to make it usable with capture.
pub struct CapturePin<'d, T, C, A> {
pub struct CapturePin<'d, T, C, #[cfg(afio)] A> {
#[allow(unused)]
pin: Peri<'d, AnyPin>,
phantom: PhantomData<(T, C, A)>,
phantom: PhantomData<if_afio!((T, C, A))>,
}
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> CapturePin<'d, T, C, A> {
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(CapturePin<'d, T, C, A>) {
/// Create a new capture pin instance.
pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self {
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pull: Pull) -> Self {
pin.set_as_af(pin.af_num(), AfType::input(pull));
CapturePin {
pin: pin.into(),
@ -41,12 +41,12 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> {
impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
/// Create a new input capture driver.
#[allow(unused)]
pub fn new<A>(
pub fn new<#[cfg(afio)] A>(
tim: Peri<'d, T>,
ch1: Option<CapturePin<'d, T, Ch1, A>>,
ch2: Option<CapturePin<'d, T, Ch2, A>>,
ch3: Option<CapturePin<'d, T, Ch3, A>>,
ch4: Option<CapturePin<'d, T, Ch4, A>>,
ch1: Option<if_afio!(CapturePin<'d, T, Ch1, A>)>,
ch2: Option<if_afio!(CapturePin<'d, T, Ch2, A>)>,
ch3: Option<if_afio!(CapturePin<'d, T, Ch3, A>)>,
ch4: Option<if_afio!(CapturePin<'d, T, Ch4, A>)>,
_irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd,
freq: Hertz,
counting_mode: CountingMode,

View File

@ -64,7 +64,7 @@ impl SealedTriggerSource for Ext {}
impl<'d, T: GeneralInstance4Channel, C: TriggerSource + TimerChannel> TriggerPin<'d, T, C> {
/// Create a new Channel trigger pin instance.
pub fn new<A>(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self {
pub fn new<#[cfg(afio)] A>(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pull: Pull) -> Self {
pin.set_as_af(pin.af_num(), AfType::input(pull));
#[cfg(afio)]
pin.afio_remap();
@ -77,7 +77,7 @@ impl<'d, T: GeneralInstance4Channel, C: TriggerSource + TimerChannel> TriggerPin
impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> {
/// Create a new external trigger pin instance.
pub fn new_external<A>(pin: Peri<'d, impl ExternalTriggerPin<T, A>>, pull: Pull) -> Self {
pub fn new_external<#[cfg(afio)] A>(pin: Peri<'d, if_afio!(impl ExternalTriggerPin<T, A>)>, pull: Pull) -> Self {
pin.set_as_af(pin.af_num(), AfType::input(pull));
#[cfg(afio)]
pin.afio_remap();

View File

@ -18,7 +18,12 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> {
impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
/// Create a new PWM input driver.
pub fn new_ch1<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1, A>>, pull: Pull, freq: Hertz) -> Self {
pub fn new_ch1<#[cfg(afio)] A>(
tim: Peri<'d, T>,
pin: Peri<'d, if_afio!(impl TimerPin<T, Ch1, A>)>,
pull: Pull,
freq: Hertz,
) -> Self {
pin.set_as_af(pin.af_num(), AfType::input(pull));
#[cfg(afio)]
pin.afio_remap();
@ -27,7 +32,12 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
}
/// Create a new PWM input driver.
pub fn new_ch2<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2, A>>, pull: Pull, freq: Hertz) -> Self {
pub fn new_ch2<#[cfg(afio)] A>(
tim: Peri<'d, T>,
pin: Peri<'d, if_afio!(impl TimerPin<T, Ch2, A>)>,
pull: Pull,
freq: Hertz,
) -> Self {
pin.set_as_af(pin.af_num(), AfType::input(pull));
#[cfg(afio)]
pin.afio_remap();

View File

@ -20,15 +20,15 @@ pub enum Direction {
}
/// Wrapper for using a pin with QEI.
pub struct QeiPin<'d, T, Channel, A> {
pub struct QeiPin<'d, T, Channel, #[cfg(afio)] A> {
#[allow(unused)]
pin: Peri<'d, AnyPin>,
phantom: PhantomData<(T, Channel, A)>,
phantom: PhantomData<if_afio!((T, Channel, A))>,
}
impl<'d, T: GeneralInstance4Channel, C: QeiChannel, A> QeiPin<'d, T, C, A> {
impl<'d, T: GeneralInstance4Channel, C: QeiChannel, #[cfg(afio)] A> if_afio!(QeiPin<'d, T, C, A>) {
/// Create a new QEI pin instance.
pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>) -> Self {
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>) -> Self {
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
@ -62,7 +62,11 @@ pub struct Qei<'d, T: GeneralInstance4Channel> {
impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
/// Create a new quadrature decoder driver.
#[allow(unused)]
pub fn new<A>(tim: Peri<'d, T>, ch1: QeiPin<'d, T, Ch1, A>, ch2: QeiPin<'d, T, Ch2, A>) -> Self {
pub fn new<#[cfg(afio)] A>(
tim: Peri<'d, T>,
ch1: if_afio!(QeiPin<'d, T, Ch1, A>),
ch2: if_afio!(QeiPin<'d, T, Ch2, A>),
) -> Self {
Self::new_inner(tim)
}

View File

@ -14,10 +14,10 @@ use crate::Peri;
/// PWM pin wrapper.
///
/// This wraps a pin to make it usable with PWM.
pub struct PwmPin<'d, T, C, A> {
pub struct PwmPin<'d, T, C, #[cfg(afio)] A> {
#[allow(unused)]
pub(crate) pin: Peri<'d, AnyPin>,
phantom: PhantomData<(T, C, A)>,
phantom: PhantomData<if_afio!((T, C, A))>,
}
/// PWM pin config
@ -35,9 +35,9 @@ pub struct PwmPinConfig {
pub pull: Pull,
}
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> PwmPin<'d, T, C, A> {
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(PwmPin<'d, T, C, A>) {
/// Create a new PWM pin instance.
pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, output_type: OutputType) -> Self {
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, output_type: OutputType) -> Self {
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh));
@ -50,8 +50,8 @@ impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> PwmPin<'d, T, C, A> {
}
}
/// Create a new PWM pin instance with config.
pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C, A>>, pin_config: PwmPinConfig) -> Self {
/// Create a new PWM pin instance with a specific configuration.
pub fn new_with_config(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pin_config: PwmPinConfig) -> Self {
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(
@ -184,12 +184,12 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> {
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
/// Create a new simple PWM driver.
#[allow(unused)]
pub fn new<A>(
pub fn new<#[cfg(afio)] A>(
tim: Peri<'d, T>,
ch1: Option<PwmPin<'d, T, Ch1, A>>,
ch2: Option<PwmPin<'d, T, Ch2, A>>,
ch3: Option<PwmPin<'d, T, Ch3, A>>,
ch4: Option<PwmPin<'d, T, Ch4, A>>,
ch1: Option<if_afio!(PwmPin<'d, T, Ch1, A>)>,
ch2: Option<if_afio!(PwmPin<'d, T, Ch2, A>)>,
ch3: Option<if_afio!(PwmPin<'d, T, Ch3, A>)>,
ch4: Option<if_afio!(PwmPin<'d, T, Ch4, A>)>,
freq: Hertz,
counting_mode: CountingMode,
) -> Self {

View File

@ -208,10 +208,10 @@ impl<'d> SetConfig for BufferedUartTx<'d> {
impl<'d> BufferedUart<'d> {
/// Create a new bidirectional buffered UART driver
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@ -231,12 +231,12 @@ impl<'d> BufferedUart<'d> {
}
/// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
pub fn new_with_rtscts<T: Instance, A>(
pub fn new_with_rtscts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
cts: Peri<'d, impl CtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
@ -256,11 +256,11 @@ impl<'d> BufferedUart<'d> {
}
/// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin
pub fn new_with_rts_as_de<T: Instance, A>(
pub fn new_with_rts_as_de<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
@ -280,11 +280,11 @@ impl<'d> BufferedUart<'d> {
}
/// Create a new bidirectional buffered UART driver with only the request-to-send pin
pub fn new_with_rts<T: Instance, A>(
pub fn new_with_rts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
@ -305,11 +305,11 @@ impl<'d> BufferedUart<'d> {
/// Create a new bidirectional buffered UART driver with a driver-enable pin
#[cfg(not(any(usart_v1, usart_v2)))]
pub fn new_with_de<T: Instance, A>(
pub fn new_with_de<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
de: Peri<'d, impl DePin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
@ -340,9 +340,9 @@ impl<'d> BufferedUart<'d> {
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[doc(alias("HDSEL"))]
pub fn new_half_duplex<T: Instance, A>(
pub fn new_half_duplex<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],
@ -379,9 +379,9 @@ impl<'d> BufferedUart<'d> {
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[cfg(not(any(usart_v1, usart_v2)))]
#[doc(alias("HDSEL"))]
pub fn new_half_duplex_on_rx<T: Instance, A>(
pub fn new_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_buffer: &'d mut [u8],
rx_buffer: &'d mut [u8],

View File

@ -429,9 +429,9 @@ impl<'d, M: Mode> SetConfig for UartRx<'d, M> {
impl<'d> UartTx<'d, Async> {
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
config: Config,
) -> Result<Self, ConfigError> {
@ -439,10 +439,10 @@ impl<'d> UartTx<'d, Async> {
}
/// Create a new tx-only UART with a clear-to-send pin
pub fn new_with_cts<T: Instance, A>(
pub fn new_with_cts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
cts: Peri<'d, impl CtsPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
config: Config,
) -> Result<Self, ConfigError> {
@ -482,19 +482,19 @@ impl<'d> UartTx<'d, Blocking> {
/// Create a new blocking tx-only UART with no hardware flow control.
///
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
pub fn new_blocking<T: Instance, A>(
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(peri, new_pin!(tx, config.tx_af()), None, None, config)
}
/// Create a new blocking tx-only UART with a clear-to-send pin
pub fn new_blocking_with_cts<T: Instance, A>(
pub fn new_blocking_with_cts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
cts: Peri<'d, impl CtsPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(
@ -662,10 +662,10 @@ impl<'d> UartRx<'d, Async> {
/// Create a new rx-only UART with no hardware flow control.
///
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: Peri<'d, impl RxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
) -> Result<Self, ConfigError> {
@ -673,11 +673,11 @@ impl<'d> UartRx<'d, Async> {
}
/// Create a new rx-only UART with a request-to-send pin
pub fn new_with_rts<T: Instance, A>(
pub fn new_with_rts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: Peri<'d, impl RxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
) -> Result<Self, ConfigError> {
@ -913,19 +913,19 @@ impl<'d> UartRx<'d, Blocking> {
/// Create a new rx-only UART with no hardware flow control.
///
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
pub fn new_blocking<T: Instance, A>(
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(peri, new_pin!(rx, config.rx_af()), None, None, config)
}
/// Create a new rx-only UART with a request-to-send pin
pub fn new_blocking_with_rts<T: Instance, A>(
pub fn new_blocking_with_rts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(
@ -1109,10 +1109,10 @@ fn drop_tx_rx(info: &Info, state: &State) {
impl<'d> Uart<'d, Async> {
/// Create a new bidirectional UART
pub fn new<T: Instance, A>(
pub fn new<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
@ -1132,13 +1132,13 @@ impl<'d> Uart<'d, Async> {
}
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
pub fn new_with_rtscts<T: Instance, A>(
pub fn new_with_rtscts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rts: Peri<'d, impl RtsPin<T, A>>,
cts: Peri<'d, impl CtsPin<T, A>>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
@ -1158,12 +1158,12 @@ impl<'d> Uart<'d, Async> {
#[cfg(not(any(usart_v1, usart_v2)))]
/// Create a new bidirectional UART with a driver-enable pin
pub fn new_with_de<T: Instance, A>(
pub fn new_with_de<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
de: Peri<'d, impl DePin<T, A>>,
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
config: Config,
@ -1193,9 +1193,9 @@ impl<'d> Uart<'d, Async> {
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[doc(alias("HDSEL"))]
pub fn new_half_duplex<T: Instance, A>(
pub fn new_half_duplex<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
@ -1232,9 +1232,9 @@ impl<'d> Uart<'d, Async> {
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[cfg(not(any(usart_v1, usart_v2)))]
#[doc(alias("HDSEL"))]
pub fn new_half_duplex_on_rx<T: Instance, A>(
pub fn new_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: Peri<'d, impl TxDma<T>>,
rx_dma: Peri<'d, impl RxDma<T>>,
@ -1280,10 +1280,10 @@ impl<'d> Uart<'d, Async> {
impl<'d> Uart<'d, Blocking> {
/// Create a new blocking bidirectional UART.
pub fn new_blocking<T: Instance, A>(
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(
@ -1300,12 +1300,12 @@ impl<'d> Uart<'d, Blocking> {
}
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
pub fn new_blocking_with_rtscts<T: Instance, A>(
pub fn new_blocking_with_rtscts<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
rts: Peri<'d, impl RtsPin<T, A>>,
cts: Peri<'d, impl CtsPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(
@ -1323,11 +1323,11 @@ impl<'d> Uart<'d, Blocking> {
#[cfg(not(any(usart_v1, usart_v2)))]
/// Create a new bidirectional UART with a driver-enable pin
pub fn new_blocking_with_de<T: Instance, A>(
pub fn new_blocking_with_de<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
tx: Peri<'d, impl TxPin<T, A>>,
de: Peri<'d, impl DePin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_inner(
@ -1354,9 +1354,9 @@ impl<'d> Uart<'d, Blocking> {
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[doc(alias("HDSEL"))]
pub fn new_blocking_half_duplex<T: Instance, A>(
pub fn new_blocking_half_duplex<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
tx: Peri<'d, impl TxPin<T, A>>,
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
mut config: Config,
readback: HalfDuplexReadback,
) -> Result<Self, ConfigError> {
@ -1390,9 +1390,9 @@ impl<'d> Uart<'d, Blocking> {
/// on the line must be managed by software (for instance by using a centralized arbiter).
#[cfg(not(any(usart_v1, usart_v2)))]
#[doc(alias("HDSEL"))]
pub fn new_blocking_half_duplex_on_rx<T: Instance, A>(
pub fn new_blocking_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
peri: Peri<'d, T>,
rx: Peri<'d, impl RxPin<T, A>>,
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
mut config: Config,
readback: HalfDuplexReadback,
) -> Result<Self, ConfigError> {