From 94007ce6e0fc59e374902eadcc31616e56068e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0pa=C4=8Dek?= <patek.mail@gmail.com> Date: Sat, 1 Jun 2024 18:16:40 +0200 Subject: [PATCH] stm32/gpio: refactor AfType --- embassy-stm32/src/can/bxcan/mod.rs | 10 +- embassy-stm32/src/can/fdcan.rs | 10 +- embassy-stm32/src/dcmi.rs | 5 +- embassy-stm32/src/dsihost.rs | 5 +- embassy-stm32/src/eth/v1/mod.rs | 12 +- embassy-stm32/src/eth/v2/mod.rs | 6 +- embassy-stm32/src/fmc.rs | 5 +- embassy-stm32/src/gpio.rs | 492 ++++++++++-------- embassy-stm32/src/hrtim/mod.rs | 16 +- embassy-stm32/src/i2c/mod.rs | 50 +- embassy-stm32/src/i2s.rs | 21 +- embassy-stm32/src/ltdc.rs | 5 +- embassy-stm32/src/macros.rs | 18 +- embassy-stm32/src/ospi/mod.rs | 168 +++--- embassy-stm32/src/qspi/mod.rs | 62 ++- embassy-stm32/src/rcc/mco.rs | 5 +- embassy-stm32/src/sai/mod.rs | 20 +- embassy-stm32/src/sdmmc/mod.rs | 69 +-- embassy-stm32/src/spi/mod.rs | 54 +- embassy-stm32/src/timer/complementary_pwm.rs | 7 +- embassy-stm32/src/timer/input_capture.rs | 8 +- embassy-stm32/src/timer/pwm_input.rs | 10 +- embassy-stm32/src/timer/qei.rs | 6 +- embassy-stm32/src/timer/simple_pwm.rs | 6 +- embassy-stm32/src/tsc/mod.rs | 54 +- embassy-stm32/src/usart/buffered.rs | 20 +- embassy-stm32/src/usart/mod.rs | 75 +-- embassy-stm32/src/usb/otg.rs | 10 +- embassy-stm32/src/usb/usb.rs | 5 +- .../stm32h7/src/bin/low_level_timer_api.rs | 10 +- tests/stm32/src/bin/gpio.rs | 4 +- 31 files changed, 667 insertions(+), 581 deletions(-) diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs index 53b94b9e2..278c93ff4 100644 --- a/embassy-stm32/src/can/bxcan/mod.rs +++ b/embassy-stm32/src/can/bxcan/mod.rs @@ -18,7 +18,7 @@ pub use super::common::{BufferedCanReceiver, BufferedCanSender}; use super::frame::{Envelope, Frame}; use super::util; use crate::can::enums::{BusError, TryReadError}; -use crate::gpio::AFType; +use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; use crate::{interrupt, peripherals, Peripheral}; @@ -188,8 +188,8 @@ impl<'d> Can<'d> { let info = T::info(); let regs = &T::info().regs; - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); + tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); rcc::enable_and_reset::<T>(); @@ -223,8 +223,8 @@ impl<'d> Can<'d> { info.sce_interrupt.enable(); } - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); + tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); Registers(T::regs()).leave_init_mode(); diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index f3ad718ae..c549313f3 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -10,7 +10,7 @@ use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender}; use embassy_sync::waitqueue::AtomicWaker; use crate::can::fd::peripheral::Registers; -use crate::gpio::AFType; +use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; use crate::{interrupt, peripherals, Peripheral}; @@ -184,8 +184,8 @@ impl<'d> CanConfigurator<'d> { ) -> CanConfigurator<'d> { into_ref!(_peri, rx, tx); - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); + tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); rcc::enable_and_reset::<T>(); @@ -193,8 +193,8 @@ impl<'d> CanConfigurator<'d> { config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); T::registers().into_config_mode(config); - rx.set_as_af(rx.af_num(), AFType::Input); - tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); + tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); unsafe { T::IT0Interrupt::unpend(); // Not unsafe diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index 858ae49ca..4ba4e824e 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs @@ -7,7 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use crate::dma::Transfer; -use crate::gpio::{AFType, Speed}; +use crate::gpio::{AfType, Pull}; use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, rcc, Peripheral}; @@ -109,8 +109,7 @@ macro_rules! config_pins { into_ref!($($pin),*); critical_section::with(|_| { $( - $pin.set_as_af($pin.af_num(), AFType::Input); - $pin.set_speed(Speed::VeryHigh); + $pin.set_as_af($pin.af_num(), AfType::input(Pull::None)); )* }) }; diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs index c59ee3f2d..51f124542 100644 --- a/embassy-stm32/src/dsihost.rs +++ b/embassy-stm32/src/dsihost.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use embassy_hal_internal::{into_ref, PeripheralRef}; //use crate::gpio::{AnyPin, SealedPin}; -use crate::gpio::{AFType, AnyPin, Pull, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::rcc::{self, RccPeripheral}; use crate::{peripherals, Peripheral}; @@ -80,8 +80,7 @@ impl<'d, T: Instance> DsiHost<'d, T> { rcc::enable_and_reset::<T>(); // Set Tearing Enable pin according to CubeMx example - te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); - te.set_speed(Speed::Low); + te.set_as_af(te.af_num(), AfType::output(OutputType::PushPull, Speed::Low)); /* T::regs().wcr().modify(|w| { w.set_dsien(true); diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index 6f0174def..cce75ece7 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs @@ -12,7 +12,9 @@ use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress pub(crate) use self::rx_desc::{RDes, RDesRing}; pub(crate) use self::tx_desc::{TDes, TDesRing}; use super::*; -use crate::gpio::{AFType, AnyPin, SealedPin}; +#[cfg(eth_v1a)] +use crate::gpio::Pull; +use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::interrupt::InterruptExt; #[cfg(eth_v1a)] use crate::pac::AFIO; @@ -61,7 +63,7 @@ macro_rules! config_in_pins { critical_section::with(|_| { $( // TODO properly create a set_as_input function - $pin.set_as_af($pin.af_num(), AFType::Input); + $pin.set_as_af($pin.af_num(), AfType::input(Pull::None)); )* }) } @@ -72,8 +74,7 @@ macro_rules! config_af_pins { ($($pin:ident),*) => { critical_section::with(|_| { $( - // We are lucky here, this configures to max speed (50MHz) - $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); + $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); )* }) }; @@ -84,8 +85,7 @@ macro_rules! config_pins { ($($pin:ident),*) => { critical_section::with(|_| { $( - $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); - $pin.set_speed(crate::gpio::Speed::VeryHigh); + $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); )* }) }; diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index a19aa42cf..b26f08cd9 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -8,7 +8,7 @@ use stm32_metapac::syscfg::vals::EthSelPhy; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; use super::*; -use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; use crate::interrupt::InterruptExt; use crate::pac::ETH; use crate::rcc::SealedRccPeripheral; @@ -56,8 +56,8 @@ macro_rules! config_pins { ($($pin:ident),*) => { critical_section::with(|_| { $( - $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); - $pin.set_speed(Speed::VeryHigh); + // TODO: shouldn't some pins be configured as inputs? + $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); )* }) }; diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 82d8089f4..7aea466e8 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use embassy_hal_internal::into_ref; -use crate::gpio::{AFType, Pull, Speed}; +use crate::gpio::{AfType, OutputType, Pull, Speed}; use crate::{rcc, Peripheral}; /// FMC driver @@ -76,8 +76,7 @@ macro_rules! config_pins { ($($pin:ident),*) => { into_ref!($($pin),*); $( - $pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up); - $pin.set_speed(Speed::VeryHigh); + $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)); )* }; } diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index de08127cf..86bc226a9 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs @@ -32,7 +32,9 @@ impl<'d> Flex<'d> { } /// Put the pin into input mode. - #[inline] + /// + /// The internal weak pull-up and pull-down resistors will be enabled according to `pull`. + #[inline(never)] pub fn set_as_input(&mut self, pull: Pull) { critical_section::with(|_| { let r = self.pin.block(); @@ -51,35 +53,35 @@ impl<'d> Flex<'d> { Pull::None => vals::CnfIn::FLOATING, }; - let crlh = if n < 8 { 0 } else { 1 }; - r.cr(crlh).modify(|w| { + r.cr(n / 8).modify(|w| { w.set_mode(n % 8, vals::Mode::INPUT); w.set_cnf_in(n % 8, cnf); }); } #[cfg(gpio_v2)] { - r.pupdr().modify(|w| w.set_pupdr(n, pull.into())); + r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr())); r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); } }); } - /// Put the pin into output mode. + /// Put the pin into push-pull output mode. /// /// The pin level will be whatever was set before (or low by default). If you want it to begin /// at a specific level, call `set_high`/`set_low` on the pin first. - #[inline] + /// + /// The internal weak pull-up and pull-down resistors will be disabled. + #[inline(never)] pub fn set_as_output(&mut self, speed: Speed) { critical_section::with(|_| { let r = self.pin.block(); let n = self.pin.pin() as usize; #[cfg(gpio_v1)] { - let crlh = if n < 8 { 0 } else { 1 }; - r.cr(crlh).modify(|w| { - w.set_mode(n % 8, speed.into()); + r.cr(n / 8).modify(|w| { + w.set_mode(n % 8, speed.to_mode()); w.set_cnf_out(n % 8, vals::CnfOut::PUSHPULL); }); } @@ -87,44 +89,50 @@ impl<'d> Flex<'d> { { r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); - self.pin.set_speed(speed); + r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr())); r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); } }); } - /// Put the pin into input + output mode. + /// Put the pin into input + open-drain output mode. /// - /// This is commonly used for "open drain" mode. - /// the hardware will drive the line low if you set it to low, and will leave it floating if you set + /// The hardware will drive the line low if you set it to low, and will leave it floating if you set /// it to high, in which case you can read the input to figure out whether another device /// is driving the line low. /// /// The pin level will be whatever was set before (or low by default). If you want it to begin /// at a specific level, call `set_high`/`set_low` on the pin first. - #[inline] - pub fn set_as_input_output(&mut self, speed: Speed, pull: Pull) { + /// + /// The internal weak pull-up and pull-down resistors will be disabled. + #[inline(never)] + pub fn set_as_input_output(&mut self, speed: Speed) { + #[cfg(gpio_v1)] critical_section::with(|_| { let r = self.pin.block(); let n = self.pin.pin() as usize; - #[cfg(gpio_v1)] - { - let crlh = if n < 8 { 0 } else { 1 }; - match pull { - Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)), - Pull::Down => r.bsrr().write(|w| w.set_br(n, true)), - Pull::None => {} - } - r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into())); - r.cr(crlh).modify(|w| w.set_cnf_out(n % 8, vals::CnfOut::OPENDRAIN)); - } - #[cfg(gpio_v2)] - { - r.pupdr().modify(|w| w.set_pupdr(n, pull.into())); - r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN)); - self.pin.set_speed(speed); - r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); - } + r.cr(n / 8).modify(|w| w.set_mode(n % 8, speed.to_mode())); + r.cr(n / 8).modify(|w| w.set_cnf_out(n % 8, vals::CnfOut::OPENDRAIN)); + }); + + #[cfg(gpio_v2)] + self.set_as_input_output_pull(speed, Pull::None); + } + + /// Put the pin into input + open-drain output mode with internal pullup or pulldown. + /// + /// This works like [`Self::set_as_input_output()`], but it also allows to enable the internal + /// weak pull-up or pull-down resistors. + #[inline(never)] + #[cfg(gpio_v2)] + pub fn set_as_input_output_pull(&mut self, speed: Speed, pull: Pull) { + critical_section::with(|_| { + let r = self.pin.block(); + let n = self.pin.pin() as usize; + r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr())); + r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN)); + r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr())); + r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); }); } @@ -134,18 +142,18 @@ impl<'d> Flex<'d> { /// as the mode change is handled by the driver. #[inline] pub fn set_as_analog(&mut self) { + // TODO: does this also need a critical section, like other methods? self.pin.set_as_analog(); } /// Put the pin into AF mode, unchecked. /// - /// This puts the pin into the AF mode, with the requested number, pull and speed. This is + /// This puts the pin into the AF mode, with the requested number and AF type. This is /// completely unchecked, it can attach the pin to literally any peripheral, so use with care. #[inline] - pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) { + pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AfType) { critical_section::with(|_| { - self.pin.set_as_af_pull(af_num, af_type, pull); - self.pin.set_speed(speed); + self.pin.set_as_af(af_num, af_type); }); } @@ -223,21 +231,7 @@ impl<'d> Drop for Flex<'d> { #[inline] fn drop(&mut self) { critical_section::with(|_| { - let r = self.pin.block(); - let n = self.pin.pin() as usize; - #[cfg(gpio_v1)] - { - let crlh = if n < 8 { 0 } else { 1 }; - r.cr(crlh).modify(|w| { - w.set_mode(n % 8, vals::Mode::INPUT); - w.set_cnf_in(n % 8, vals::CnfIn::FLOATING); - }); - } - #[cfg(gpio_v2)] - { - r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); - r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); - } + self.pin.set_as_disconnected(); }); } } @@ -254,57 +248,56 @@ pub enum Pull { Down, } -#[cfg(gpio_v2)] -impl From<Pull> for vals::Pupdr { - fn from(pull: Pull) -> Self { - use Pull::*; - - match pull { - None => vals::Pupdr::FLOATING, - Up => vals::Pupdr::PULLUP, - Down => vals::Pupdr::PULLDOWN, +impl Pull { + #[cfg(gpio_v2)] + const fn to_pupdr(self) -> vals::Pupdr { + match self { + Pull::None => vals::Pupdr::FLOATING, + Pull::Up => vals::Pupdr::PULLUP, + Pull::Down => vals::Pupdr::PULLDOWN, } } } -/// Speed settings +/// Speed setting for an output. /// -/// These vary depending on the chip, check the reference manual or datasheet for details. -#[allow(missing_docs)] +/// These vary depending on the chip, check the reference manual and datasheet ("I/O port +/// characteristics") for details. #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Speed { + #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT2MHZ")] + #[cfg_attr(gpio_v2, doc = "Output speed 00")] Low, + #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT10MHZ")] + #[cfg_attr(gpio_v2, doc = "Output speed 01")] Medium, - #[cfg(not(any(syscfg_f0, gpio_v1)))] + #[cfg_attr(gpio_v2, doc = "Output speed 10")] + #[cfg(not(any(gpio_v1, syscfg_f0)))] High, + #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT50MHZ")] + #[cfg_attr(gpio_v2, doc = "Output speed 10")] VeryHigh, } -#[cfg(gpio_v1)] -impl From<Speed> for vals::Mode { - fn from(speed: Speed) -> Self { - use Speed::*; - - match speed { - Low => vals::Mode::OUTPUT2MHZ, - Medium => vals::Mode::OUTPUT10MHZ, - VeryHigh => vals::Mode::OUTPUT50MHZ, +impl Speed { + #[cfg(gpio_v1)] + const fn to_mode(self) -> vals::Mode { + match self { + Speed::Low => vals::Mode::OUTPUT2MHZ, + Speed::Medium => vals::Mode::OUTPUT10MHZ, + Speed::VeryHigh => vals::Mode::OUTPUT50MHZ, } } -} -#[cfg(gpio_v2)] -impl From<Speed> for vals::Ospeedr { - fn from(speed: Speed) -> Self { - use Speed::*; - - match speed { - Low => vals::Ospeedr::LOWSPEED, - Medium => vals::Ospeedr::MEDIUMSPEED, + #[cfg(gpio_v2)] + const fn to_ospeedr(self: Speed) -> vals::Ospeedr { + match self { + Speed::Low => vals::Ospeedr::LOWSPEED, + Speed::Medium => vals::Ospeedr::MEDIUMSPEED, #[cfg(not(syscfg_f0))] - High => vals::Ospeedr::HIGHSPEED, - VeryHigh => vals::Ospeedr::VERYHIGHSPEED, + Speed::High => vals::Ospeedr::HIGHSPEED, + Speed::VeryHigh => vals::Ospeedr::VERYHIGHSPEED, } } } @@ -445,17 +438,29 @@ pub struct OutputOpenDrain<'d> { } impl<'d> OutputOpenDrain<'d> { - /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed], [Pull] configuration. + /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed]. #[inline] - pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { + pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed) -> Self { let mut pin = Flex::new(pin); - match initial_output { Level::High => pin.set_high(), Level::Low => pin.set_low(), } + pin.set_as_input_output(speed); + Self { pin } + } - pin.set_as_input_output(speed, pull); + /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level], [Speed] + /// and [Pull]. + #[inline] + #[cfg(gpio_v2)] + pub fn new_pull(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { + let mut pin = Flex::new(pin); + match initial_output { + Level::High => pin.set_high(), + Level::Low => pin.set_low(), + } + pin.set_as_input_output_pull(speed, pull); Self { pin } } @@ -521,6 +526,8 @@ impl<'d> OutputOpenDrain<'d> { } /// GPIO output type +#[derive(Debug, Copy, Clone)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum OutputType { /// Drive the pin both high or low. PushPull, @@ -528,25 +535,170 @@ pub enum OutputType { OpenDrain, } -impl From<OutputType> for AFType { - fn from(value: OutputType) -> Self { - match value { - OutputType::OpenDrain => AFType::OutputOpenDrain, - OutputType::PushPull => AFType::OutputPushPull, +impl OutputType { + #[cfg(gpio_v1)] + const fn to_cnf_out(self) -> vals::CnfOut { + match self { + OutputType::PushPull => vals::CnfOut::ALTPUSHPULL, + OutputType::OpenDrain => vals::CnfOut::ALTOPENDRAIN, + } + } + + #[cfg(gpio_v2)] + const fn to_ot(self) -> vals::Ot { + match self { + OutputType::PushPull => vals::Ot::PUSHPULL, + OutputType::OpenDrain => vals::Ot::OPENDRAIN, } } } -/// Alternate function type settings -#[derive(Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum AFType { - /// Input - Input, - /// Output, drive the pin both high or low. - OutputPushPull, - /// Output, drive the pin low, or don't drive it at all if the output level is high. - OutputOpenDrain, +/// Alternate function type settings. +#[derive(Copy, Clone)] +#[cfg(gpio_v1)] +pub struct AfType { + mode: vals::Mode, + cnf: u8, + pull: Pull, +} + +#[cfg(gpio_v1)] +impl AfType { + /// Input with optional pullup or pulldown. + pub const fn input(pull: Pull) -> Self { + let cnf_in = match pull { + Pull::Up | Pull::Down => vals::CnfIn::PULL, + Pull::None => vals::CnfIn::FLOATING, + }; + Self { + mode: vals::Mode::INPUT, + cnf: cnf_in.to_bits(), + pull, + } + } + + /// Output with output type and speed and no pull-up or pull-down. + pub const fn output(output_type: OutputType, speed: Speed) -> Self { + Self { + mode: speed.to_mode(), + cnf: output_type.to_cnf_out().to_bits(), + pull: Pull::None, + } + } +} + +#[inline(never)] +#[cfg(gpio_v1)] +fn set_as_af(pin_port: u8, _af_num: u8, af_type: AfType) { + let pin = unsafe { AnyPin::steal(pin_port) }; + let r = pin.block(); + let n = pin._pin() as usize; + + r.cr(n / 8).modify(|w| { + w.set_mode(n % 8, af_type.mode); + // note that we are writing the CNF field, which is exposed as both `cnf_in` and `cnf_out` + // in the PAC. the choice of `cnf_in` instead of `cnf_out` in this code is arbitrary and + // does not affect the result. + w.set_cnf_in(n % 8, vals::CnfIn::from_bits(af_type.cnf)); + }); + + match af_type.pull { + Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)), + Pull::Down => r.bsrr().write(|w| w.set_br(n, true)), + Pull::None => {} + } +} + +/// Alternate function type settings. +#[derive(Copy, Clone)] +#[cfg(gpio_v2)] +pub struct AfType { + pupdr: vals::Pupdr, + ot: vals::Ot, + ospeedr: vals::Ospeedr, +} + +#[cfg(gpio_v2)] +impl AfType { + /// Input with optional pullup or pulldown. + pub const fn input(pull: Pull) -> Self { + Self { + pupdr: pull.to_pupdr(), + ot: vals::Ot::PUSHPULL, + ospeedr: vals::Ospeedr::LOWSPEED, + } + } + + /// Output with output type and speed and no pull-up or pull-down. + pub const fn output(output_type: OutputType, speed: Speed) -> Self { + Self::output_pull(output_type, speed, Pull::None) + } + + /// Output with output type, speed and pull-up or pull-down; + pub const fn output_pull(output_type: OutputType, speed: Speed, pull: Pull) -> Self { + Self { + pupdr: pull.to_pupdr(), + ot: output_type.to_ot(), + ospeedr: speed.to_ospeedr(), + } + } +} + +#[inline(never)] +#[cfg(gpio_v2)] +fn set_as_af(pin_port: u8, 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.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)); + r.moder().modify(|w| w.set_moder(n, vals::Moder::ALTERNATE)); +} + +#[inline(never)] +fn set_as_analog(pin_port: u8) { + let pin = unsafe { AnyPin::steal(pin_port) }; + let r = pin.block(); + let n = pin._pin() as usize; + + #[cfg(gpio_v1)] + r.cr(n / 8).modify(|w| { + w.set_mode(n % 8, vals::Mode::INPUT); + w.set_cnf_in(n % 8, vals::CnfIn::ANALOG); + }); + + #[cfg(gpio_v2)] + r.moder().modify(|w| w.set_moder(n, vals::Moder::ANALOG)); +} + +#[inline(never)] +fn get_pull(pin_port: u8) -> Pull { + let pin = unsafe { AnyPin::steal(pin_port) }; + let r = pin.block(); + let n = pin._pin() as usize; + + #[cfg(gpio_v1)] + return match r.cr(n / 8).read().mode(n % 8) { + vals::Mode::INPUT => match r.cr(n / 8).read().cnf_in(n % 8) { + vals::CnfIn::PULL => match r.odr().read().odr(n) { + vals::Odr::LOW => Pull::Down, + vals::Odr::HIGH => Pull::Up, + }, + _ => Pull::None, + }, + _ => Pull::None, + }; + + #[cfg(gpio_v2)] + return match r.pupdr().read().pupdr(n) { + vals::Pupdr::FLOATING => Pull::None, + vals::Pupdr::PULLDOWN => Pull::Down, + vals::Pupdr::PULLUP => Pull::Up, + vals::Pupdr::_RESERVED_3 => Pull::None, + }; } pub(crate) trait SealedPin { @@ -556,6 +708,7 @@ pub(crate) trait SealedPin { fn _pin(&self) -> u8 { self.pin_port() % 16 } + #[inline] fn _port(&self) -> u8 { self.pin_port() / 16 @@ -581,146 +734,31 @@ pub(crate) trait SealedPin { } #[inline] - fn set_as_af(&self, af_num: u8, af_type: AFType) { - self.set_as_af_pull(af_num, af_type, Pull::None); - } - - #[cfg(gpio_v1)] - #[inline] - fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) { - // F1 uses the AFIO register for remapping. - // For now, this is not implemented, so af_num is ignored - // _af_num should be zero here, since it is not set by stm32-data - let r = self.block(); - let n = self._pin() as usize; - let crlh = if n < 8 { 0 } else { 1 }; - match af_type { - AFType::Input => { - let cnf = match pull { - Pull::Up => { - r.bsrr().write(|w| w.set_bs(n, true)); - vals::CnfIn::PULL - } - Pull::Down => { - r.bsrr().write(|w| w.set_br(n, true)); - vals::CnfIn::PULL - } - Pull::None => vals::CnfIn::FLOATING, - }; - - r.cr(crlh).modify(|w| { - w.set_mode(n % 8, vals::Mode::INPUT); - w.set_cnf_in(n % 8, cnf); - }); - } - AFType::OutputPushPull => { - r.cr(crlh).modify(|w| { - w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); - w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL); - }); - } - AFType::OutputOpenDrain => { - r.cr(crlh).modify(|w| { - w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); - w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN); - }); - } - } - } - - #[cfg(gpio_v2)] - #[inline] - fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { - let pin = self._pin() as usize; - let block = self.block(); - block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num)); - match af_type { - AFType::Input => {} - AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)), - AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), - } - block.pupdr().modify(|w| w.set_pupdr(pin, pull.into())); - - block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); + fn set_as_af(&self, af_num: u8, af_type: AfType) { + set_as_af(self.pin_port(), af_num, af_type) } #[inline] fn set_as_analog(&self) { - let pin = self._pin() as usize; - let block = self.block(); - #[cfg(gpio_v1)] - { - let crlh = if pin < 8 { 0 } else { 1 }; - block.cr(crlh).modify(|w| { - w.set_mode(pin % 8, vals::Mode::INPUT); - w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG); - }); - } - #[cfg(gpio_v2)] - block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); + set_as_analog(self.pin_port()); } /// Set the pin as "disconnected", ie doing nothing and consuming the lowest /// amount of power possible. /// - /// This is currently the same as set_as_analog but is semantically different really. - /// Drivers should set_as_disconnected pins when dropped. + /// This is currently the same as [`Self::set_as_analog()`] but is semantically different + /// really. Drivers should `set_as_disconnected()` pins when dropped. + /// + /// Note that this also disables the internal weak pull-up and pull-down resistors. #[inline] fn set_as_disconnected(&self) { self.set_as_analog(); } - /// Sets the speed of the output pin. - /// - /// This should never be called for AFType::Input on the STM32F1 series, since MODE and - /// CNF bits are not independent. If the CNF bits are altered afterwards as well, this - /// will put the pin into output mode. - #[inline] - fn set_speed(&self, speed: Speed) { - let pin = self._pin() as usize; - - #[cfg(gpio_v1)] - { - let crlh = if pin < 8 { 0 } else { 1 }; - self.block().cr(crlh).modify(|w| { - w.set_mode(pin % 8, speed.into()); - }); - } - - #[cfg(gpio_v2)] - self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); - } - /// Get the pull-up configuration. #[inline] fn pull(&self) -> Pull { - critical_section::with(|_| { - let r = self.block(); - let n = self._pin() as usize; - #[cfg(gpio_v1)] - { - let crlh = if n < 8 { 0 } else { 1 }; - match r.cr(crlh).read().mode(n % 8) { - vals::Mode::INPUT => match r.cr(crlh).read().cnf_in(n % 8) { - vals::CnfIn::PULL => match r.odr().read().odr(n) { - vals::Odr::LOW => Pull::Down, - vals::Odr::HIGH => Pull::Up, - }, - _ => Pull::None, - }, - _ => Pull::None, - } - } - #[cfg(gpio_v2)] - { - match r.pupdr().read().pupdr(n) { - vals::Pupdr::FLOATING => Pull::None, - vals::Pupdr::PULLDOWN => Pull::Down, - vals::Pupdr::PULLUP => Pull::Up, - vals::Pupdr::_RESERVED_3 => Pull::None, - } - } - }) + critical_section::with(|_| get_pull(self.pin_port())) } } diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index c9d5bff17..13343fc2a 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs @@ -7,7 +7,7 @@ use core::marker::PhantomData; use embassy_hal_internal::{into_ref, PeripheralRef}; pub use traits::Instance; -use crate::gpio::{AFType, AnyPin}; +use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::time::Hertz; use crate::{rcc, Peripheral}; @@ -80,9 +80,10 @@ macro_rules! advanced_channel_impl { into_ref!(pin); critical_section::with(|_| { pin.set_low(); - pin.set_as_af(pin.af_num(), AFType::OutputPushPull); - #[cfg(gpio_v2)] - pin.set_speed(crate::gpio::Speed::VeryHigh); + pin.set_as_af( + pin.af_num(), + AfType::output(OutputType::PushPull, Speed::VeryHigh), + ); }); PwmPin { _pin: pin.map_into(), @@ -97,9 +98,10 @@ macro_rules! advanced_channel_impl { into_ref!(pin); critical_section::with(|_| { pin.set_low(); - pin.set_as_af(pin.af_num(), AFType::OutputPushPull); - #[cfg(gpio_v2)] - pin.set_speed(crate::gpio::Speed::VeryHigh); + pin.set_as_af( + pin.af_num(), + AfType::output(OutputType::PushPull, Speed::VeryHigh), + ); }); ComplementaryPwmPin { _pin: pin.map_into(), diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index f43cb4567..739e960b9 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -15,7 +15,9 @@ use embassy_sync::waitqueue::AtomicWaker; use embassy_time::{Duration, Instant}; use crate::dma::ChannelAndRequest; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; +#[cfg(gpio_v2)] +use crate::gpio::Pull; +use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::mode::{Async, Blocking, Mode}; use crate::rcc::{RccInfo, SealedRccPeripheral}; @@ -50,11 +52,13 @@ pub struct Config { /// /// Using external pullup resistors is recommended for I2C. If you do /// have external pullups you should not enable this. + #[cfg(gpio_v2)] pub sda_pullup: bool, /// Enable internal pullup on SCL. /// /// Using external pullup resistors is recommended for I2C. If you do /// have external pullups you should not enable this. + #[cfg(gpio_v2)] pub scl_pullup: bool, /// Timeout. #[cfg(feature = "time")] @@ -64,7 +68,9 @@ pub struct Config { impl Default for Config { fn default() -> Self { Self { + #[cfg(gpio_v2)] sda_pullup: false, + #[cfg(gpio_v2)] scl_pullup: false, #[cfg(feature = "time")] timeout: embassy_time::Duration::from_millis(1000), @@ -73,18 +79,32 @@ impl Default for Config { } impl Config { - fn scl_pull_mode(&self) -> Pull { - match self.scl_pullup { - true => Pull::Up, - false => Pull::Down, - } + fn scl_af(&self) -> AfType { + #[cfg(gpio_v1)] + return AfType::output(OutputType::OpenDrain, Speed::Medium); + #[cfg(gpio_v2)] + return AfType::output_pull( + OutputType::OpenDrain, + Speed::Medium, + match self.scl_pullup { + true => Pull::Up, + false => Pull::Down, + }, + ); } - fn sda_pull_mode(&self) -> Pull { - match self.sda_pullup { - true => Pull::Up, - false => Pull::Down, - } + fn sda_af(&self) -> AfType { + #[cfg(gpio_v1)] + return AfType::output(OutputType::OpenDrain, Speed::Medium); + #[cfg(gpio_v2)] + return AfType::output_pull( + OutputType::OpenDrain, + Speed::Medium, + match self.sda_pullup { + true => Pull::Up, + false => Pull::Down, + }, + ); } } @@ -118,8 +138,8 @@ impl<'d> I2c<'d, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()), - new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()), + new_pin!(scl, config.scl_af()), + new_pin!(sda, config.sda_af()), new_dma!(tx_dma), new_dma!(rx_dma), freq, @@ -139,8 +159,8 @@ impl<'d> I2c<'d, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()), - new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()), + new_pin!(scl, config.scl_af()), + new_pin!(sda, config.sda_af()), None, None, freq, diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index f893dd235..094de2461 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs @@ -3,7 +3,7 @@ use embassy_hal_internal::into_ref; use crate::dma::ChannelAndRequest; -use crate::gpio::{AFType, AnyPin, SealedPin, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::mode::Async; use crate::pac::spi::vals; use crate::spi::{Config as SpiConfig, *}; @@ -180,7 +180,7 @@ impl<'d> I2S<'d> { into_ref!(sd); Self::new_inner( peri, - new_pin!(sd, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sd, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, ws, ck, @@ -209,7 +209,7 @@ impl<'d> I2S<'d> { Self::new_inner( peri, None, - new_pin!(sd, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sd, AfType::output(OutputType::PushPull, Speed::VeryHigh)), ws, ck, mck, @@ -244,8 +244,8 @@ impl<'d> I2S<'d> { into_ref!(txsd, rxsd); Self::new_inner( peri, - new_pin!(txsd, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(rxsd, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(txsd, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(rxsd, AfType::output(OutputType::PushPull, Speed::VeryHigh)), ws, ck, mck, @@ -292,14 +292,9 @@ impl<'d> I2S<'d> { ) -> Self { into_ref!(ws, ck, mck); - ws.set_as_af(ws.af_num(), AFType::OutputPushPull); - ws.set_speed(Speed::VeryHigh); - - ck.set_as_af(ck.af_num(), AFType::OutputPushPull); - ck.set_speed(Speed::VeryHigh); - - mck.set_as_af(mck.af_num(), AFType::OutputPushPull); - mck.set_speed(Speed::VeryHigh); + ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); + ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); + mck.set_as_af(mck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); let mut spi_cfg = SpiConfig::default(); spi_cfg.frequency = freq; diff --git a/embassy-stm32/src/ltdc.rs b/embassy-stm32/src/ltdc.rs index c262e7a0c..481d77843 100644 --- a/embassy-stm32/src/ltdc.rs +++ b/embassy-stm32/src/ltdc.rs @@ -62,11 +62,10 @@ impl<'d, T: Instance> Ltdc<'d, T> { rcc::enable_and_reset::<T>(); - //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh, Pull::None); + //new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)); // Set Tearing Enable pin according to CubeMx example - //te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); - //te.set_speed(Speed::Low); + //te.set_as_af_pull(te.af_num(), AfType::output(OutputType::PushPull, Speed::Low)); /* T::regs().wcr().modify(|w| { w.set_dsien(true); diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index dcd25cbe9..ae53deb08 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs @@ -97,23 +97,9 @@ macro_rules! new_dma { } macro_rules! new_pin { - ($name:ident, $aftype:expr) => {{ - new_pin!($name, $aftype, crate::gpio::Speed::Medium, crate::gpio::Pull::None) - }}; - ($name:ident, $aftype:expr, $speed:expr) => { - new_pin!($name, $aftype, $speed, crate::gpio::Pull::None) - }; - ($name:ident, $aftype:expr, $speed:expr, $pull:expr) => {{ + ($name:ident, $af_type:expr) => {{ let pin = $name.into_ref(); - pin.set_as_af_pull(pin.af_num(), $aftype, $pull); - // Do not call set_speed on AFType::Input, as MODE and CNF bits are not independent - // for gpio_v1 - match $aftype { - crate::gpio::AFType::Input => {} - _ => { - pin.set_speed($speed); - } - }; + pin.set_as_af(pin.af_num(), $af_type); Some(pin.map_into()) }}; } diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs index 882781cce..f6eb0d17c 100644 --- a/embassy-stm32/src/ospi/mod.rs +++ b/embassy-stm32/src/ospi/mod.rs @@ -13,7 +13,7 @@ pub use enums::*; use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits}; use crate::dma::{word, ChannelAndRequest}; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::octospi::{vals, Octospi as Regs}; use crate::rcc::{self, RccPeripheral}; @@ -548,16 +548,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::Input, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::input(Pull::None)), None, None, None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, None, config, @@ -577,16 +580,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, None, config, @@ -608,16 +614,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, None, config, @@ -643,16 +652,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, None, config, @@ -678,16 +690,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, None, config, @@ -710,16 +725,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::Input, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::input(Pull::None)), None, None, None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, new_dma!(dma), config, @@ -740,16 +758,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, new_dma!(dma), config, @@ -772,16 +793,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, None, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, new_dma!(dma), config, @@ -808,16 +832,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, new_dma!(dma), config, @@ -844,16 +871,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, new_dma!(dma), config, diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 06c8f4812..308947e99 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -10,7 +10,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use enums::*; use crate::dma::ChannelAndRequest; -use crate::gpio::{AFType, AnyPin, Pull, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, Speed}; use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::quadspi::Quadspi as Regs; use crate::rcc::{self, RccPeripheral}; @@ -248,12 +248,15 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, config, FlashSelection::Flash1, @@ -273,12 +276,15 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), None, config, FlashSelection::Flash2, @@ -301,12 +307,15 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), new_dma!(dma), config, FlashSelection::Flash1, @@ -327,12 +336,15 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), + new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!( + nss, + AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up) + ), new_dma!(dma), config, FlashSelection::Flash2, diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 40e963466..d1ce14c86 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; use embassy_hal_internal::into_ref; -use crate::gpio::{AFType, Speed}; +use crate::gpio::{AfType, OutputType, Speed}; #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; #[cfg(not(any( @@ -101,8 +101,7 @@ impl<'d, T: McoInstance> Mco<'d, T> { critical_section::with(|_| unsafe { T::_apply_clock_settings(source, prescaler); - pin.set_as_af(pin.af_num(), AFType::OutputPushPull); - pin.set_speed(Speed::VeryHigh); + pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); }); Self { phantom: PhantomData } diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 87bde12eb..c48d81b5f 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -9,7 +9,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; pub use crate::dma::word; #[cfg(not(gpdma))] use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; -use crate::gpio::{AFType, AnyPin, SealedPin as _}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::pac::sai::{vals, Sai as Regs}; use crate::rcc::{self, RccPeripheral}; use crate::{peripherals, Peripheral}; @@ -656,17 +656,17 @@ fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut } // return the type for (sd, sck) -fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) { +fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AfType, AfType) { ( //sd is defined by tx/rx mode match tx_rx { - TxRx::Transmitter => AFType::OutputPushPull, - TxRx::Receiver => AFType::Input, + TxRx::Transmitter => AfType::output(OutputType::PushPull, Speed::VeryHigh), + TxRx::Receiver => AfType::input(Pull::None), }, //clocks (mclk, sck and fs) are defined by master/slave match mode { - Mode::Master => AFType::OutputPushPull, - Mode::Slave => AFType::Input, + Mode::Master => AfType::output(OutputType::PushPull, Speed::VeryHigh), + Mode::Slave => AfType::input(Pull::None), }, ) } @@ -768,9 +768,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { into_ref!(mclk); let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); - mclk.set_as_af(mclk.af_num(), ck_af_type); - mclk.set_speed(crate::gpio::Speed::VeryHigh); if config.master_clock_divider == MasterClockDivider::MasterClockDisabled { config.master_clock_divider = MasterClockDivider::Div1; @@ -796,12 +794,8 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); sd.set_as_af(sd.af_num(), sd_af_type); - sd.set_speed(crate::gpio::Speed::VeryHigh); - sck.set_as_af(sck.af_num(), ck_af_type); - sck.set_speed(crate::gpio::Speed::VeryHigh); fs.set_as_af(fs.af_num(), ck_af_type); - fs.set_speed(crate::gpio::Speed::VeryHigh); let sub_block = S::WHICH; let request = dma.request(); @@ -834,9 +828,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { into_ref!(dma, peri, sd); let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); - sd.set_as_af(sd.af_num(), sd_af_type); - sd.set_speed(crate::gpio::Speed::VeryHigh); let sub_block = S::WHICH; let request = dma.request(); diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 9c14837e1..ee5539518 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs @@ -13,7 +13,9 @@ use embassy_sync::waitqueue::AtomicWaker; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; use crate::dma::NoDma; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed}; +#[cfg(gpio_v2)] +use crate::gpio::Pull; +use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; use crate::interrupt::typelevel::Interrupt; use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::rcc::{self, RccPeripheral}; @@ -292,6 +294,13 @@ pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma<T> = NoDma> { card: Option<Card>, } +const CLK_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh); +#[cfg(gpio_v1)] +const CMD_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh); +#[cfg(gpio_v2)] +const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up); +const DATA_AF: AfType = CMD_AF; + #[cfg(sdmmc_v1)] impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { /// Create a new SDMMC driver, with 1 data lane. @@ -307,13 +316,9 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { into_ref!(clk, cmd, d0); critical_section::with(|_| { - clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); - cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); - - clk.set_speed(Speed::VeryHigh); - cmd.set_speed(Speed::VeryHigh); - d0.set_speed(Speed::VeryHigh); + clk.set_as_af(clk.af_num(), CLK_AF); + cmd.set_as_af(cmd.af_num(), CMD_AF); + d0.set_as_af(d0.af_num(), DATA_AF); }); Self::new_inner( @@ -345,19 +350,12 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { into_ref!(clk, cmd, d0, d1, d2, d3); critical_section::with(|_| { - clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); - cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up); - - clk.set_speed(Speed::VeryHigh); - cmd.set_speed(Speed::VeryHigh); - d0.set_speed(Speed::VeryHigh); - d1.set_speed(Speed::VeryHigh); - d2.set_speed(Speed::VeryHigh); - d3.set_speed(Speed::VeryHigh); + clk.set_as_af(clk.af_num(), CLK_AF); + cmd.set_as_af(cmd.af_num(), CMD_AF); + d0.set_as_af(d0.af_num(), DATA_AF); + d1.set_as_af(d1.af_num(), DATA_AF); + d2.set_as_af(d2.af_num(), DATA_AF); + d3.set_as_af(d3.af_num(), DATA_AF); }); Self::new_inner( @@ -388,13 +386,9 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { into_ref!(clk, cmd, d0); critical_section::with(|_| { - clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); - cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); - - clk.set_speed(Speed::VeryHigh); - cmd.set_speed(Speed::VeryHigh); - d0.set_speed(Speed::VeryHigh); + clk.set_as_af(clk.af_num(), CLK_AF); + cmd.set_as_af(cmd.af_num(), CMD_AF); + d0.set_as_af(d0.af_num(), DATA_AF); }); Self::new_inner( @@ -425,19 +419,12 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { into_ref!(clk, cmd, d0, d1, d2, d3); critical_section::with(|_| { - clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); - cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); - d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); - d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up); - d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up); - d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up); - - clk.set_speed(Speed::VeryHigh); - cmd.set_speed(Speed::VeryHigh); - d0.set_speed(Speed::VeryHigh); - d1.set_speed(Speed::VeryHigh); - d2.set_speed(Speed::VeryHigh); - d3.set_speed(Speed::VeryHigh); + clk.set_as_af(clk.af_num(), CLK_AF); + cmd.set_as_af(cmd.af_num(), CMD_AF); + d0.set_as_af(d0.af_num(), DATA_AF); + d1.set_as_af(d1.af_num(), DATA_AF); + d2.set_as_af(d2.af_num(), DATA_AF); + d3.set_as_af(d3.af_num(), DATA_AF); }); Self::new_inner( diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 2e5f82dcb..656676d9f 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -10,7 +10,7 @@ use embassy_hal_internal::PeripheralRef; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; use crate::dma::{word, ChannelAndRequest}; -use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::pac::spi::{regs, vals, Spi as Regs}; use crate::rcc::{RccInfo, SealedRccPeripheral}; @@ -90,11 +90,21 @@ impl Config { } } - fn sck_pull_mode(&self) -> Pull { - match self.mode.polarity { - Polarity::IdleLow => Pull::Down, - Polarity::IdleHigh => Pull::Up, - } + #[cfg(gpio_v1)] + fn sck_af(&self) -> AfType { + AfType::output(OutputType::PushPull, Speed::VeryHigh) + } + + #[cfg(gpio_v2)] + fn sck_af(&self) -> AfType { + AfType::output_pull( + OutputType::PushPull, + Speed::VeryHigh, + match self.mode.polarity { + Polarity::IdleLow => Pull::Down, + Polarity::IdleHigh => Pull::Up, + }, + ) } } /// SPI driver. @@ -453,9 +463,9 @@ impl<'d> Spi<'d, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(miso, AfType::input(config.miso_pull)), None, None, config, @@ -471,9 +481,9 @@ impl<'d> Spi<'d, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(sck, config.sck_af()), None, - new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), + new_pin!(miso, AfType::input(config.miso_pull)), None, None, config, @@ -489,8 +499,8 @@ impl<'d> Spi<'d, Blocking> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, @@ -509,7 +519,7 @@ impl<'d> Spi<'d, Blocking> { Self::new_inner( peri, None, - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, None, None, @@ -531,9 +541,9 @@ impl<'d> Spi<'d, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), - new_pin!(miso, AFType::Input, Speed::VeryHigh), + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), + new_pin!(miso, AfType::input(config.miso_pull)), new_dma!(tx_dma), new_dma!(rx_dma), config, @@ -551,9 +561,9 @@ impl<'d> Spi<'d, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), + new_pin!(sck, config.sck_af()), None, - new_pin!(miso, AFType::Input, Speed::VeryHigh), + new_pin!(miso, AfType::input(config.miso_pull)), #[cfg(any(spi_v1, spi_f1, spi_v2))] new_dma!(tx_dma), #[cfg(any(spi_v3, spi_v4, spi_v5))] @@ -573,8 +583,8 @@ impl<'d> Spi<'d, Async> { ) -> Self { Self::new_inner( peri, - new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(sck, config.sck_af()), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, new_dma!(tx_dma), None, @@ -594,7 +604,7 @@ impl<'d> Spi<'d, Async> { Self::new_inner( peri, None, - new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), + new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)), None, new_dma!(tx_dma), None, diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index a892646cf..46ccbf3df 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs @@ -32,9 +32,10 @@ macro_rules! complementary_channel_impl { into_ref!(pin); critical_section::with(|_| { pin.set_low(); - pin.set_as_af(pin.af_num(), output_type.into()); - #[cfg(gpio_v2)] - pin.set_speed(crate::gpio::Speed::VeryHigh); + pin.set_as_af( + pin.af_num(), + crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), + ); }); ComplementaryPwmPin { _pin: pin.map_into(), diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index 0258d4077..341ac2c04 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs @@ -12,7 +12,7 @@ use super::{ CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, }; -use crate::gpio::{AFType, AnyPin, Pull}; +use crate::gpio::{AfType, AnyPin, Pull}; use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::time::Hertz; use crate::Peripheral; @@ -38,11 +38,9 @@ macro_rules! channel_impl { ($new_chx:ident, $channel:ident, $pin_trait:ident) => { impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] - pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull_type: Pull) -> Self { + pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull: Pull) -> Self { into_ref!(pin); - - pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); - + pin.set_as_af(pin.af_num(), AfType::input(pull)); CapturePin { _pin: pin.map_into(), phantom: PhantomData, diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index dcf098a78..e3eb6042a 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs @@ -4,7 +4,7 @@ use embassy_hal_internal::into_ref; use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; -use crate::gpio::{AFType, Pull}; +use crate::gpio::{AfType, Pull}; use crate::time::Hertz; use crate::Peripheral; @@ -19,12 +19,12 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { pub fn new( tim: impl Peripheral<P = T> + 'd, pin: impl Peripheral<P = impl Channel1Pin<T>> + 'd, - pull_type: Pull, + pull: Pull, freq: Hertz, ) -> Self { into_ref!(pin); - pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); + pin.set_as_af(pin.af_num(), AfType::input(pull)); Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) } @@ -33,12 +33,12 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { pub fn new_alt( tim: impl Peripheral<P = T> + 'd, pin: impl Peripheral<P = impl Channel2Pin<T>> + 'd, - pull_type: Pull, + pull: Pull, freq: Hertz, ) -> Self { into_ref!(pin); - pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); + pin.set_as_af(pin.af_num(), AfType::input(pull)); Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) } diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index ab9879be6..fc5835414 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs @@ -7,7 +7,7 @@ use stm32_metapac::timer::vals; use super::low_level::Timer; use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; -use crate::gpio::{AFType, AnyPin}; +use crate::gpio::{AfType, AnyPin, Pull}; use crate::Peripheral; /// Counting direction @@ -37,9 +37,7 @@ macro_rules! channel_impl { into_ref!(pin); critical_section::with(|_| { pin.set_low(); - pin.set_as_af(pin.af_num(), AFType::Input); - #[cfg(gpio_v2)] - pin.set_speed(crate::gpio::Speed::VeryHigh); + pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); }); QeiPin { _pin: pin.map_into(), diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index b54e9a0d6..b7771bd64 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs @@ -6,7 +6,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel}; -use crate::gpio::{AnyPin, OutputType}; +use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::time::Hertz; use crate::Peripheral; @@ -35,9 +35,7 @@ macro_rules! channel_impl { into_ref!(pin); critical_section::with(|_| { pin.set_low(); - pin.set_as_af(pin.af_num(), output_type.into()); - #[cfg(gpio_v2)] - pin.set_speed(crate::gpio::Speed::VeryHigh); + pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); }); PwmPin { _pin: pin.map_into(), diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index 8cab3a24c..8ba208ce7 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -70,7 +70,7 @@ use core::marker::PhantomData; use embassy_hal_internal::{into_ref, PeripheralRef}; pub use enums::*; -use crate::gpio::{AFType, AnyPin}; +use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::pac::tsc::Tsc as Regs; use crate::rcc::{self, RccPeripheral}; use crate::{peripherals, Peripheral}; @@ -371,11 +371,14 @@ macro_rules! group_impl { pin.set_low(); pin.set_as_af( pin.af_num(), - match role { - PinType::Channel => AFType::OutputPushPull, - PinType::Sample => AFType::OutputOpenDrain, - PinType::Shield => AFType::OutputPushPull, - }, + AfType::output( + match role { + PinType::Channel => OutputType::PushPull, + PinType::Sample => OutputType::OpenDrain, + PinType::Shield => OutputType::PushPull, + }, + Speed::VeryHigh, + ), ); self.d1 = Some(TscPin { _pin: pin.map_into(), @@ -392,11 +395,14 @@ macro_rules! group_impl { pin.set_low(); pin.set_as_af( pin.af_num(), - match role { - PinType::Channel => AFType::OutputPushPull, - PinType::Sample => AFType::OutputOpenDrain, - PinType::Shield => AFType::OutputPushPull, - }, + AfType::output( + match role { + PinType::Channel => OutputType::PushPull, + PinType::Sample => OutputType::OpenDrain, + PinType::Shield => OutputType::PushPull, + }, + Speed::VeryHigh, + ), ); self.d2 = Some(TscPin { _pin: pin.map_into(), @@ -413,11 +419,14 @@ macro_rules! group_impl { pin.set_low(); pin.set_as_af( pin.af_num(), - match role { - PinType::Channel => AFType::OutputPushPull, - PinType::Sample => AFType::OutputOpenDrain, - PinType::Shield => AFType::OutputPushPull, - }, + AfType::output( + match role { + PinType::Channel => OutputType::PushPull, + PinType::Sample => OutputType::OpenDrain, + PinType::Shield => OutputType::PushPull, + }, + Speed::VeryHigh, + ), ); self.d3 = Some(TscPin { _pin: pin.map_into(), @@ -434,11 +443,14 @@ macro_rules! group_impl { pin.set_low(); pin.set_as_af( pin.af_num(), - match role { - PinType::Channel => AFType::OutputPushPull, - PinType::Sample => AFType::OutputOpenDrain, - PinType::Shield => AFType::OutputPushPull, - }, + AfType::output( + match role { + PinType::Channel => OutputType::PushPull, + PinType::Sample => OutputType::OpenDrain, + PinType::Shield => OutputType::PushPull, + }, + Speed::VeryHigh, + ), ); self.d4 = Some(TscPin { _pin: pin.map_into(), diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index fd79e035e..33bc009a8 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -15,7 +15,7 @@ use super::{ clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, Regs, RtsPin, RxPin, TxPin, }; -use crate::gpio::{AFType, AnyPin, SealedPin as _}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::interrupt::{self, InterruptExt}; use crate::time::Hertz; @@ -210,8 +210,8 @@ impl<'d> BufferedUart<'d> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(rx, AFType::Input), - new_pin!(tx, AFType::OutputPushPull), + new_pin!(rx, AfType::input(Pull::None)), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, None, @@ -235,10 +235,10 @@ impl<'d> BufferedUart<'d> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(rx, AFType::Input), - new_pin!(tx, AFType::OutputPushPull), - new_pin!(rts, AFType::OutputPushPull), - new_pin!(cts, AFType::Input), + new_pin!(rx, AfType::input(Pull::None)), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(cts, AfType::input(Pull::None)), None, tx_buffer, rx_buffer, @@ -260,11 +260,11 @@ impl<'d> BufferedUart<'d> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(rx, AFType::Input), - new_pin!(tx, AFType::OutputPushPull), + new_pin!(rx, AfType::input(Pull::None)), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, - new_pin!(de, AFType::OutputPushPull), + new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), tx_buffer, rx_buffer, config, diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 53321391a..5754f783e 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -14,7 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker; use futures_util::future::{select, Either}; use crate::dma::ChannelAndRequest; -use crate::gpio::{AFType, AnyPin, SealedPin as _}; +use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; use crate::interrupt::typelevel::Interrupt as _; use crate::interrupt::{self, Interrupt, InterruptExt}; use crate::mode::{Async, Blocking, Mode}; @@ -159,11 +159,11 @@ pub struct Config { #[cfg(any(usart_v3, usart_v4))] pub swap_rx_tx: bool, - /// Set this to true to invert TX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). + /// Set this to true to invert TX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle). #[cfg(any(usart_v3, usart_v4))] pub invert_tx: bool, - /// Set this to true to invert RX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). + /// Set this to true to invert RX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle). #[cfg(any(usart_v3, usart_v4))] pub invert_rx: bool, @@ -172,19 +172,20 @@ pub struct Config { } impl Config { - fn tx_af(&self) -> AFType { + fn tx_af(&self) -> AfType { #[cfg(any(usart_v3, usart_v4))] if self.swap_rx_tx { - return AFType::Input; + return AfType::input(Pull::None); }; - AFType::OutputPushPull + AfType::output(OutputType::PushPull, Speed::Medium) } - fn rx_af(&self) -> AFType { + + fn rx_af(&self) -> AfType { #[cfg(any(usart_v3, usart_v4))] if self.swap_rx_tx { - return AFType::OutputPushPull; + return AfType::output(OutputType::PushPull, Speed::Medium); }; - AFType::Input + AfType::input(Pull::None) } } @@ -342,7 +343,7 @@ impl<'d> UartTx<'d, Async> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(tx, AFType::OutputPushPull), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), None, new_dma!(tx_dma), config, @@ -359,8 +360,8 @@ impl<'d> UartTx<'d, Async> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(tx, AFType::OutputPushPull), - new_pin!(cts, AFType::Input), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(cts, AfType::input(Pull::None)), new_dma!(tx_dma), config, ) @@ -401,7 +402,13 @@ impl<'d> UartTx<'d, Blocking> { tx: impl Peripheral<P = impl TxPin<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - Self::new_inner(peri, new_pin!(tx, AFType::OutputPushPull), None, None, config) + Self::new_inner( + peri, + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), + None, + None, + config, + ) } /// Create a new blocking tx-only UART with a clear-to-send pin @@ -413,8 +420,8 @@ impl<'d> UartTx<'d, Blocking> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(tx, AFType::OutputPushPull), - new_pin!(cts, AFType::Input), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(cts, AfType::input(Pull::None)), None, config, ) @@ -508,7 +515,13 @@ impl<'d> UartRx<'d, Async> { rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - Self::new_inner(peri, new_pin!(rx, AFType::Input), None, new_dma!(rx_dma), config) + Self::new_inner( + peri, + new_pin!(rx, AfType::input(Pull::None)), + None, + new_dma!(rx_dma), + config, + ) } /// Create a new rx-only UART with a request-to-send pin @@ -522,8 +535,8 @@ impl<'d> UartRx<'d, Async> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(rx, AFType::Input), - new_pin!(rts, AFType::OutputPushPull), + new_pin!(rx, AfType::input(Pull::None)), + new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), new_dma!(rx_dma), config, ) @@ -751,7 +764,7 @@ impl<'d> UartRx<'d, Blocking> { rx: impl Peripheral<P = impl RxPin<T>> + 'd, config: Config, ) -> Result<Self, ConfigError> { - Self::new_inner(peri, new_pin!(rx, AFType::Input), None, None, config) + Self::new_inner(peri, new_pin!(rx, AfType::input(Pull::None)), None, None, config) } /// Create a new rx-only UART with a request-to-send pin @@ -763,8 +776,8 @@ impl<'d> UartRx<'d, Blocking> { ) -> Result<Self, ConfigError> { Self::new_inner( peri, - new_pin!(rx, AFType::Input), - new_pin!(rts, AFType::OutputPushPull), + new_pin!(rx, AfType::input(Pull::None)), + new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), None, config, ) @@ -968,8 +981,8 @@ impl<'d> Uart<'d, Async> { peri, new_pin!(rx, config.rx_af()), new_pin!(tx, config.tx_af()), - new_pin!(rts, AFType::OutputPushPull), - new_pin!(cts, AFType::Input), + new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(cts, AfType::input(Pull::None)), None, new_dma!(tx_dma), new_dma!(rx_dma), @@ -995,7 +1008,7 @@ impl<'d> Uart<'d, Async> { new_pin!(tx, config.tx_af()), None, None, - new_pin!(de, AFType::OutputPushPull), + new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), new_dma!(tx_dma), new_dma!(rx_dma), config, @@ -1030,7 +1043,7 @@ impl<'d> Uart<'d, Async> { Self::new_inner( peri, None, - new_pin!(tx, AFType::OutputPushPull), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, None, @@ -1066,7 +1079,7 @@ impl<'d> Uart<'d, Async> { peri, None, None, - new_pin!(rx, AFType::OutputPushPull), + new_pin!(rx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, new_dma!(tx_dma), @@ -1125,8 +1138,8 @@ impl<'d> Uart<'d, Blocking> { peri, new_pin!(rx, config.rx_af()), new_pin!(tx, config.tx_af()), - new_pin!(rts, AFType::OutputPushPull), - new_pin!(cts, AFType::Input), + new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)), + new_pin!(cts, AfType::input(Pull::None)), None, None, None, @@ -1149,7 +1162,7 @@ impl<'d> Uart<'d, Blocking> { new_pin!(tx, config.tx_af()), None, None, - new_pin!(de, AFType::OutputPushPull), + new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, config, @@ -1181,7 +1194,7 @@ impl<'d> Uart<'d, Blocking> { Self::new_inner( peri, None, - new_pin!(tx, AFType::OutputPushPull), + new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, None, @@ -1214,7 +1227,7 @@ impl<'d> Uart<'d, Blocking> { peri, None, None, - new_pin!(rx, AFType::OutputPushPull), + new_pin!(rx, AfType::output(OutputType::PushPull, Speed::Medium)), None, None, None, diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index e5131250a..8ee8dcc36 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs @@ -10,7 +10,7 @@ use embassy_usb_synopsys_otg::{ PhyType, State, }; -use crate::gpio::AFType; +use crate::gpio::{AfType, OutputType, Speed}; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; @@ -39,9 +39,7 @@ macro_rules! config_ulpi_pins { into_ref!($($pin),*); critical_section::with(|_| { $( - $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); - #[cfg(gpio_v2)] - $pin.set_speed(crate::gpio::Speed::VeryHigh); + $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); )* }) }; @@ -77,8 +75,8 @@ impl<'d, T: Instance> Driver<'d, T> { ) -> Self { into_ref!(dp, dm); - dp.set_as_af(dp.af_num(), AFType::OutputPushPull); - dm.set_as_af(dm.af_num(), AFType::OutputPushPull); + dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); + dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); let regs = T::regs(); diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index b6c88ac9a..1d9d19a73 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs @@ -277,8 +277,9 @@ impl<'d, T: Instance> Driver<'d, T> { #[cfg(not(stm32l1))] { - dp.set_as_af(dp.af_num(), crate::gpio::AFType::OutputPushPull); - dm.set_as_af(dm.af_num(), crate::gpio::AFType::OutputPushPull); + use crate::gpio::{AfType, OutputType, Speed}; + dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); + dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); } #[cfg(stm32l1)] let _ = (dp, dm); // suppress "unused" warnings. diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index a95b44b74..b796996ea 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs @@ -3,7 +3,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::gpio::{AFType, Flex, Pull, Speed}; +use embassy_stm32::gpio::{AfType, Flex, OutputType, Speed}; use embassy_stm32::time::{khz, Hertz}; use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; @@ -83,10 +83,10 @@ impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { let mut ch2 = Flex::new(ch2); let mut ch3 = Flex::new(ch3); let mut ch4 = Flex::new(ch4); - ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); - ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); - ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); - ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); + ch1.set_as_af_unchecked(af1, AfType::output(OutputType::PushPull, Speed::VeryHigh)); + ch2.set_as_af_unchecked(af2, AfType::output(OutputType::PushPull, Speed::VeryHigh)); + ch3.set_as_af_unchecked(af3, AfType::output(OutputType::PushPull, Speed::VeryHigh)); + ch4.set_as_af_unchecked(af4, AfType::output(OutputType::PushPull, Speed::VeryHigh)); let mut this = Self { tim: LLTimer::new(tim), diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs index dfa299ab5..1d1018c5c 100644 --- a/tests/stm32/src/bin/gpio.rs +++ b/tests/stm32/src/bin/gpio.rs @@ -112,7 +112,7 @@ async fn main(_spawner: Spawner) { let b = Input::new(&mut b, Pull::Down); // no pull, the status is undefined - let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low, Pull::None); + let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low); delay(); assert!(b.is_low()); a.set_high(); // High-Z output @@ -203,7 +203,7 @@ async fn main(_spawner: Spawner) { let mut a = Flex::new(&mut a); a.set_low(); - a.set_as_input_output(Speed::Low, Pull::None); + a.set_as_input_output(Speed::Low); delay(); assert!(b.is_low()); a.set_high(); // High-Z output