diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 906978e8b..9e10a8b02 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -4,7 +4,10 @@ use core::ops::{Deref, DerefMut}; use embassy::util::Unborrow; use embassy_hal_common::unborrow; -use crate::gpio::Pin; +use crate::gpio::{ + sealed::OutputType::{OpenDrain, PushPull}, + Pin, +}; use crate::{peripherals, rcc::RccPeripheral}; pub use bxcan::*; @@ -23,8 +26,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> { unborrow!(peri, rx, tx); unsafe { - rx.set_as_af(rx.af_num()); - tx.set_as_af(tx.af_num()); + rx.set_as_af(rx.af_num(), OpenDrain); + tx.set_as_af(tx.af_num(), PushPull); } T::enable(); diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index ff734f78c..8eb7c3393 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -9,8 +9,8 @@ use embassy_hal_common::unborrow; use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; use crate::gpio::sealed::Pin as __GpioPin; -use crate::gpio::AnyPin; use crate::gpio::Pin as GpioPin; +use crate::gpio::{sealed::OutputType::PushPull, AnyPin}; use crate::pac::gpio::vals::Ospeedr; use crate::pac::{ETH, RCC, SYSCFG}; use crate::peripherals; @@ -416,7 +416,7 @@ macro_rules! impl_pin { fn configure(&mut self) { // NOTE(unsafe) Exclusive access to the registers critical_section::with(|_| unsafe { - self.set_as_af($af); + self.set_as_af($af, PushPull); self.block() .ospeedr() .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED)); diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 7812709ce..14f2559e1 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -264,6 +264,14 @@ impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> { pub(crate) mod sealed { use super::*; + /// Output type settings + #[derive(Debug)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum OutputType { + PushPull, + OpenDrain, + } + pub trait Pin { fn pin_port(&self) -> u8; @@ -299,7 +307,7 @@ pub(crate) mod sealed { } } - unsafe fn set_as_af(&self, af_num: u8) { + unsafe fn set_as_af(&self, af_num: u8, af_type: OutputType) { let pin = self._pin() as usize; let block = self.block(); block @@ -308,6 +316,17 @@ pub(crate) mod sealed { block .afr(pin / 8) .modify(|w| w.set_afr(pin % 8, vals::Afr(af_num))); + match af_type { + OutputType::PushPull => { + block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)) + } + OutputType::OpenDrain => block + .otyper() + .modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), + } + block + .pupdr() + .modify(|w| w.set_pupdr(pin, vals::Pupdr::FLOATING)); } unsafe fn set_as_analog(&self) { diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 578536855..c5d5dee0c 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -9,8 +9,7 @@ use embedded_hal::blocking::i2c::WriteRead; use crate::pac::i2c; -use crate::pac::gpio::vals::{Afr, Moder, Ot}; -use crate::pac::gpio::Gpio; +use crate::gpio::sealed::OutputType::OpenDrain; pub struct I2c<'d, T: Instance> { phantom: PhantomData<&'d mut T>, @@ -31,8 +30,8 @@ impl<'d, T: Instance> I2c<'d, T> { T::enable(); unsafe { - Self::configure_pin(scl.block(), scl.pin() as _, scl.af_num()); - Self::configure_pin(sda.block(), sda.pin() as _, sda.af_num()); + scl.set_as_af(scl.af_num(), OpenDrain); + sda.set_as_af(sda.af_num(), OpenDrain); } unsafe { @@ -69,13 +68,6 @@ impl<'d, T: Instance> I2c<'d, T> { } } - unsafe fn configure_pin(block: Gpio, pin: usize, af_num: u8) { - let (afr, n_af) = if pin < 8 { (0, pin) } else { (1, pin - 8) }; - block.moder().modify(|w| w.set_moder(pin, Moder::ALTERNATE)); - block.afr(afr).modify(|w| w.set_afr(n_af, Afr(af_num))); - block.otyper().modify(|w| w.set_ot(pin, Ot::OPENDRAIN)); - } - unsafe fn check_and_clear_error_flags(&self) -> Result { // Note that flags should only be cleared once they have been registered. If flags are // cleared otherwise, there may be an inherent race condition and flags may be missed. diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index 302b7a2a1..53d8252e6 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs @@ -1,7 +1,13 @@ #![macro_use] use crate::dma::NoDma; -use crate::gpio::{sealed::Pin, AnyPin}; +use crate::gpio::{ + sealed::{ + OutputType::{OpenDrain, PushPull}, + Pin, + }, + AnyPin, +}; use crate::pac::spi; use crate::spi::{ ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel, @@ -53,9 +59,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { unborrow!(sck, mosi, miso, txdma, rxdma); unsafe { - sck.set_as_af(sck.af_num()); - mosi.set_as_af(mosi.af_num()); - miso.set_as_af(miso.af_num()); + sck.set_as_af(sck.af_num(), PushPull); + mosi.set_as_af(mosi.af_num(), PushPull); + miso.set_as_af(miso.af_num(), OpenDrain); } let sck = sck.degrade(); diff --git a/embassy-stm32/src/usart/v1.rs b/embassy-stm32/src/usart/v1.rs index ec6677699..d1dd68305 100644 --- a/embassy-stm32/src/usart/v1.rs +++ b/embassy-stm32/src/usart/v1.rs @@ -1,3 +1,4 @@ +use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; use core::future::Future; use core::marker::PhantomData; use embassy::util::Unborrow; @@ -36,8 +37,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { let r = inner.regs(); unsafe { - rx.set_as_af(rx.af_num()); - tx.set_as_af(tx.af_num()); + rx.set_as_af(rx.af_num(), OpenDrain); + tx.set_as_af(tx.af_num(), PushPull); r.brr().write_value(regs::Brr(div)); r.cr1().write(|w| { diff --git a/embassy-stm32/src/usart/v2.rs b/embassy-stm32/src/usart/v2.rs index fc3036404..5e6696351 100644 --- a/embassy-stm32/src/usart/v2.rs +++ b/embassy-stm32/src/usart/v2.rs @@ -13,6 +13,7 @@ use futures::TryFutureExt; use super::*; use crate::dma::NoDma; +use crate::gpio::sealed::OutputType::{OpenDrain, PushPull}; use crate::pac::usart::{regs, vals}; pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { @@ -42,8 +43,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { let r = inner.regs(); unsafe { - rx.set_as_af(rx.af_num()); - tx.set_as_af(tx.af_num()); + rx.set_as_af(rx.af_num(), OpenDrain); + tx.set_as_af(tx.af_num(), PushPull); r.cr2().write(|_w| {}); r.cr3().write(|_w| {});