aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Špaček <[email protected]>2024-06-01 18:16:40 +0200
committerJan Špaček <[email protected]>2024-06-16 21:11:55 +0200
commit94007ce6e0fc59e374902eadcc31616e56068e43 (patch)
tree014302ef421d4cfdc6e816737793f3ad147d7bc1
parent1a2c8cecded9805970dc63f495723c690c01397e (diff)
stm32/gpio: refactor AfType
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs10
-rw-r--r--embassy-stm32/src/can/fdcan.rs10
-rw-r--r--embassy-stm32/src/dcmi.rs5
-rw-r--r--embassy-stm32/src/dsihost.rs5
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs12
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs6
-rw-r--r--embassy-stm32/src/fmc.rs5
-rw-r--r--embassy-stm32/src/gpio.rs492
-rw-r--r--embassy-stm32/src/hrtim/mod.rs16
-rw-r--r--embassy-stm32/src/i2c/mod.rs50
-rw-r--r--embassy-stm32/src/i2s.rs21
-rw-r--r--embassy-stm32/src/ltdc.rs5
-rw-r--r--embassy-stm32/src/macros.rs18
-rw-r--r--embassy-stm32/src/ospi/mod.rs168
-rw-r--r--embassy-stm32/src/qspi/mod.rs62
-rw-r--r--embassy-stm32/src/rcc/mco.rs5
-rw-r--r--embassy-stm32/src/sai/mod.rs20
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs69
-rw-r--r--embassy-stm32/src/spi/mod.rs54
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs7
-rw-r--r--embassy-stm32/src/timer/input_capture.rs8
-rw-r--r--embassy-stm32/src/timer/pwm_input.rs10
-rw-r--r--embassy-stm32/src/timer/qei.rs6
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs6
-rw-r--r--embassy-stm32/src/tsc/mod.rs54
-rw-r--r--embassy-stm32/src/usart/buffered.rs20
-rw-r--r--embassy-stm32/src/usart/mod.rs75
-rw-r--r--embassy-stm32/src/usb/otg.rs10
-rw-r--r--embassy-stm32/src/usb/usb.rs5
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs10
-rw-r--r--tests/stm32/src/bin/gpio.rs4
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};
18use super::frame::{Envelope, Frame}; 18use super::frame::{Envelope, Frame};
19use super::util; 19use super::util;
20use crate::can::enums::{BusError, TryReadError}; 20use crate::can::enums::{BusError, TryReadError};
21use crate::gpio::AFType; 21use crate::gpio::{AfType, OutputType, Pull, Speed};
22use crate::interrupt::typelevel::Interrupt; 22use crate::interrupt::typelevel::Interrupt;
23use crate::rcc::{self, RccPeripheral}; 23use crate::rcc::{self, RccPeripheral};
24use crate::{interrupt, peripherals, Peripheral}; 24use crate::{interrupt, peripherals, Peripheral};
@@ -188,8 +188,8 @@ impl<'d> Can<'d> {
188 let info = T::info(); 188 let info = T::info();
189 let regs = &T::info().regs; 189 let regs = &T::info().regs;
190 190
191 rx.set_as_af(rx.af_num(), AFType::Input); 191 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
192 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 192 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
193 193
194 rcc::enable_and_reset::<T>(); 194 rcc::enable_and_reset::<T>();
195 195
@@ -223,8 +223,8 @@ impl<'d> Can<'d> {
223 info.sce_interrupt.enable(); 223 info.sce_interrupt.enable();
224 } 224 }
225 225
226 rx.set_as_af(rx.af_num(), AFType::Input); 226 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
227 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 227 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
228 228
229 Registers(T::regs()).leave_init_mode(); 229 Registers(T::regs()).leave_init_mode();
230 230
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};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use crate::can::fd::peripheral::Registers; 12use crate::can::fd::peripheral::Registers;
13use crate::gpio::AFType; 13use crate::gpio::{AfType, OutputType, Pull, Speed};
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral}; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peripheral}; 16use crate::{interrupt, peripherals, Peripheral};
@@ -184,8 +184,8 @@ impl<'d> CanConfigurator<'d> {
184 ) -> CanConfigurator<'d> { 184 ) -> CanConfigurator<'d> {
185 into_ref!(_peri, rx, tx); 185 into_ref!(_peri, rx, tx);
186 186
187 rx.set_as_af(rx.af_num(), AFType::Input); 187 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
188 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 188 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
189 189
190 rcc::enable_and_reset::<T>(); 190 rcc::enable_and_reset::<T>();
191 191
@@ -193,8 +193,8 @@ impl<'d> CanConfigurator<'d> {
193 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); 193 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
194 T::registers().into_config_mode(config); 194 T::registers().into_config_mode(config);
195 195
196 rx.set_as_af(rx.af_num(), AFType::Input); 196 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
197 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 197 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
198 198
199 unsafe { 199 unsafe {
200 T::IT0Interrupt::unpend(); // Not unsafe 200 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};
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::dma::Transfer; 9use crate::dma::Transfer;
10use crate::gpio::{AFType, Speed}; 10use crate::gpio::{AfType, Pull};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, rcc, Peripheral}; 12use crate::{interrupt, rcc, Peripheral};
13 13
@@ -109,8 +109,7 @@ macro_rules! config_pins {
109 into_ref!($($pin),*); 109 into_ref!($($pin),*);
110 critical_section::with(|_| { 110 critical_section::with(|_| {
111 $( 111 $(
112 $pin.set_as_af($pin.af_num(), AFType::Input); 112 $pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
113 $pin.set_speed(Speed::VeryHigh);
114 )* 113 )*
115 }) 114 })
116 }; 115 };
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;
5use embassy_hal_internal::{into_ref, PeripheralRef}; 5use embassy_hal_internal::{into_ref, PeripheralRef};
6 6
7//use crate::gpio::{AnyPin, SealedPin}; 7//use crate::gpio::{AnyPin, SealedPin};
8use crate::gpio::{AFType, AnyPin, Pull, Speed}; 8use crate::gpio::{AfType, AnyPin, OutputType, Speed};
9use crate::rcc::{self, RccPeripheral}; 9use crate::rcc::{self, RccPeripheral};
10use crate::{peripherals, Peripheral}; 10use crate::{peripherals, Peripheral};
11 11
@@ -80,8 +80,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
80 rcc::enable_and_reset::<T>(); 80 rcc::enable_and_reset::<T>();
81 81
82 // Set Tearing Enable pin according to CubeMx example 82 // Set Tearing Enable pin according to CubeMx example
83 te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); 83 te.set_as_af(te.af_num(), AfType::output(OutputType::PushPull, Speed::Low));
84 te.set_speed(Speed::Low);
85 /* 84 /*
86 T::regs().wcr().modify(|w| { 85 T::regs().wcr().modify(|w| {
87 w.set_dsien(true); 86 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
12pub(crate) use self::rx_desc::{RDes, RDesRing}; 12pub(crate) use self::rx_desc::{RDes, RDesRing};
13pub(crate) use self::tx_desc::{TDes, TDesRing}; 13pub(crate) use self::tx_desc::{TDes, TDesRing};
14use super::*; 14use super::*;
15use crate::gpio::{AFType, AnyPin, SealedPin}; 15#[cfg(eth_v1a)]
16use crate::gpio::Pull;
17use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
16use crate::interrupt::InterruptExt; 18use crate::interrupt::InterruptExt;
17#[cfg(eth_v1a)] 19#[cfg(eth_v1a)]
18use crate::pac::AFIO; 20use crate::pac::AFIO;
@@ -61,7 +63,7 @@ macro_rules! config_in_pins {
61 critical_section::with(|_| { 63 critical_section::with(|_| {
62 $( 64 $(
63 // TODO properly create a set_as_input function 65 // TODO properly create a set_as_input function
64 $pin.set_as_af($pin.af_num(), AFType::Input); 66 $pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
65 )* 67 )*
66 }) 68 })
67 } 69 }
@@ -72,8 +74,7 @@ macro_rules! config_af_pins {
72 ($($pin:ident),*) => { 74 ($($pin:ident),*) => {
73 critical_section::with(|_| { 75 critical_section::with(|_| {
74 $( 76 $(
75 // We are lucky here, this configures to max speed (50MHz) 77 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
76 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
77 )* 78 )*
78 }) 79 })
79 }; 80 };
@@ -84,8 +85,7 @@ macro_rules! config_pins {
84 ($($pin:ident),*) => { 85 ($($pin:ident),*) => {
85 critical_section::with(|_| { 86 critical_section::with(|_| {
86 $( 87 $(
87 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 88 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
88 $pin.set_speed(crate::gpio::Speed::VeryHigh);
89 )* 89 )*
90 }) 90 })
91 }; 91 };
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;
8 8
9pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 9pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
10use super::*; 10use super::*;
11use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed}; 11use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
12use crate::interrupt::InterruptExt; 12use crate::interrupt::InterruptExt;
13use crate::pac::ETH; 13use crate::pac::ETH;
14use crate::rcc::SealedRccPeripheral; 14use crate::rcc::SealedRccPeripheral;
@@ -56,8 +56,8 @@ macro_rules! config_pins {
56 ($($pin:ident),*) => { 56 ($($pin:ident),*) => {
57 critical_section::with(|_| { 57 critical_section::with(|_| {
58 $( 58 $(
59 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 59 // TODO: shouldn't some pins be configured as inputs?
60 $pin.set_speed(Speed::VeryHigh); 60 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
61 )* 61 )*
62 }) 62 })
63 }; 63 };
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;
3 3
4use embassy_hal_internal::into_ref; 4use embassy_hal_internal::into_ref;
5 5
6use crate::gpio::{AFType, Pull, Speed}; 6use crate::gpio::{AfType, OutputType, Pull, Speed};
7use crate::{rcc, Peripheral}; 7use crate::{rcc, Peripheral};
8 8
9/// FMC driver 9/// FMC driver
@@ -76,8 +76,7 @@ macro_rules! config_pins {
76 ($($pin:ident),*) => { 76 ($($pin:ident),*) => {
77 into_ref!($($pin),*); 77 into_ref!($($pin),*);
78 $( 78 $(
79 $pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up); 79 $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up));
80 $pin.set_speed(Speed::VeryHigh);
81 )* 80 )*
82 }; 81 };
83} 82}
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> {
32 } 32 }
33 33
34 /// Put the pin into input mode. 34 /// Put the pin into input mode.
35 #[inline] 35 ///
36 /// The internal weak pull-up and pull-down resistors will be enabled according to `pull`.
37 #[inline(never)]
36 pub fn set_as_input(&mut self, pull: Pull) { 38 pub fn set_as_input(&mut self, pull: Pull) {
37 critical_section::with(|_| { 39 critical_section::with(|_| {
38 let r = self.pin.block(); 40 let r = self.pin.block();
@@ -51,35 +53,35 @@ impl<'d> Flex<'d> {
51 Pull::None => vals::CnfIn::FLOATING, 53 Pull::None => vals::CnfIn::FLOATING,
52 }; 54 };
53 55
54 let crlh = if n < 8 { 0 } else { 1 }; 56 r.cr(n / 8).modify(|w| {
55 r.cr(crlh).modify(|w| {
56 w.set_mode(n % 8, vals::Mode::INPUT); 57 w.set_mode(n % 8, vals::Mode::INPUT);
57 w.set_cnf_in(n % 8, cnf); 58 w.set_cnf_in(n % 8, cnf);
58 }); 59 });
59 } 60 }
60 #[cfg(gpio_v2)] 61 #[cfg(gpio_v2)]
61 { 62 {
62 r.pupdr().modify(|w| w.set_pupdr(n, pull.into())); 63 r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr()));
63 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); 64 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
64 r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); 65 r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
65 } 66 }
66 }); 67 });
67 } 68 }
68 69
69 /// Put the pin into output mode. 70 /// Put the pin into push-pull output mode.
70 /// 71 ///
71 /// The pin level will be whatever was set before (or low by default). If you want it to begin 72 /// The pin level will be whatever was set before (or low by default). If you want it to begin
72 /// at a specific level, call `set_high`/`set_low` on the pin first. 73 /// at a specific level, call `set_high`/`set_low` on the pin first.
73 #[inline] 74 ///
75 /// The internal weak pull-up and pull-down resistors will be disabled.
76 #[inline(never)]
74 pub fn set_as_output(&mut self, speed: Speed) { 77 pub fn set_as_output(&mut self, speed: Speed) {
75 critical_section::with(|_| { 78 critical_section::with(|_| {
76 let r = self.pin.block(); 79 let r = self.pin.block();
77 let n = self.pin.pin() as usize; 80 let n = self.pin.pin() as usize;
78 #[cfg(gpio_v1)] 81 #[cfg(gpio_v1)]
79 { 82 {
80 let crlh = if n < 8 { 0 } else { 1 }; 83 r.cr(n / 8).modify(|w| {
81 r.cr(crlh).modify(|w| { 84 w.set_mode(n % 8, speed.to_mode());
82 w.set_mode(n % 8, speed.into());
83 w.set_cnf_out(n % 8, vals::CnfOut::PUSHPULL); 85 w.set_cnf_out(n % 8, vals::CnfOut::PUSHPULL);
84 }); 86 });
85 } 87 }
@@ -87,44 +89,50 @@ impl<'d> Flex<'d> {
87 { 89 {
88 r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); 90 r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
89 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); 91 r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
90 self.pin.set_speed(speed); 92 r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr()));
91 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); 93 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
92 } 94 }
93 }); 95 });
94 } 96 }
95 97
96 /// Put the pin into input + output mode. 98 /// Put the pin into input + open-drain output mode.
97 /// 99 ///
98 /// This is commonly used for "open drain" mode. 100 /// The hardware will drive the line low if you set it to low, and will leave it floating if you set
99 /// the hardware will drive the line low if you set it to low, and will leave it floating if you set
100 /// it to high, in which case you can read the input to figure out whether another device 101 /// it to high, in which case you can read the input to figure out whether another device
101 /// is driving the line low. 102 /// is driving the line low.
102 /// 103 ///
103 /// The pin level will be whatever was set before (or low by default). If you want it to begin 104 /// The pin level will be whatever was set before (or low by default). If you want it to begin
104 /// at a specific level, call `set_high`/`set_low` on the pin first. 105 /// at a specific level, call `set_high`/`set_low` on the pin first.
105 #[inline] 106 ///
106 pub fn set_as_input_output(&mut self, speed: Speed, pull: Pull) { 107 /// The internal weak pull-up and pull-down resistors will be disabled.
108 #[inline(never)]
109 pub fn set_as_input_output(&mut self, speed: Speed) {
110 #[cfg(gpio_v1)]
107 critical_section::with(|_| { 111 critical_section::with(|_| {
108 let r = self.pin.block(); 112 let r = self.pin.block();
109 let n = self.pin.pin() as usize; 113 let n = self.pin.pin() as usize;
110 #[cfg(gpio_v1)] 114 r.cr(n / 8).modify(|w| w.set_mode(n % 8, speed.to_mode()));
111 { 115 r.cr(n / 8).modify(|w| w.set_cnf_out(n % 8, vals::CnfOut::OPENDRAIN));
112 let crlh = if n < 8 { 0 } else { 1 }; 116 });
113 match pull { 117
114 Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)), 118 #[cfg(gpio_v2)]
115 Pull::Down => r.bsrr().write(|w| w.set_br(n, true)), 119 self.set_as_input_output_pull(speed, Pull::None);
116 Pull::None => {} 120 }
117 } 121
118 r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into())); 122 /// Put the pin into input + open-drain output mode with internal pullup or pulldown.
119 r.cr(crlh).modify(|w| w.set_cnf_out(n % 8, vals::CnfOut::OPENDRAIN)); 123 ///
120 } 124 /// This works like [`Self::set_as_input_output()`], but it also allows to enable the internal
121 #[cfg(gpio_v2)] 125 /// weak pull-up or pull-down resistors.
122 { 126 #[inline(never)]
123 r.pupdr().modify(|w| w.set_pupdr(n, pull.into())); 127 #[cfg(gpio_v2)]
124 r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN)); 128 pub fn set_as_input_output_pull(&mut self, speed: Speed, pull: Pull) {
125 self.pin.set_speed(speed); 129 critical_section::with(|_| {
126 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); 130 let r = self.pin.block();
127 } 131 let n = self.pin.pin() as usize;
132 r.pupdr().modify(|w| w.set_pupdr(n, pull.to_pupdr()));
133 r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN));
134 r.ospeedr().modify(|w| w.set_ospeedr(n, speed.to_ospeedr()));
135 r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
128 }); 136 });
129 } 137 }
130 138
@@ -134,18 +142,18 @@ impl<'d> Flex<'d> {
134 /// as the mode change is handled by the driver. 142 /// as the mode change is handled by the driver.
135 #[inline] 143 #[inline]
136 pub fn set_as_analog(&mut self) { 144 pub fn set_as_analog(&mut self) {
145 // TODO: does this also need a critical section, like other methods?
137 self.pin.set_as_analog(); 146 self.pin.set_as_analog();
138 } 147 }
139 148
140 /// Put the pin into AF mode, unchecked. 149 /// Put the pin into AF mode, unchecked.
141 /// 150 ///
142 /// This puts the pin into the AF mode, with the requested number, pull and speed. This is 151 /// This puts the pin into the AF mode, with the requested number and AF type. This is
143 /// completely unchecked, it can attach the pin to literally any peripheral, so use with care. 152 /// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
144 #[inline] 153 #[inline]
145 pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) { 154 pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AfType) {
146 critical_section::with(|_| { 155 critical_section::with(|_| {
147 self.pin.set_as_af_pull(af_num, af_type, pull); 156 self.pin.set_as_af(af_num, af_type);
148 self.pin.set_speed(speed);
149 }); 157 });
150 } 158 }
151 159
@@ -223,21 +231,7 @@ impl<'d> Drop for Flex<'d> {
223 #[inline] 231 #[inline]
224 fn drop(&mut self) { 232 fn drop(&mut self) {
225 critical_section::with(|_| { 233 critical_section::with(|_| {
226 let r = self.pin.block(); 234 self.pin.set_as_disconnected();
227 let n = self.pin.pin() as usize;
228 #[cfg(gpio_v1)]
229 {
230 let crlh = if n < 8 { 0 } else { 1 };
231 r.cr(crlh).modify(|w| {
232 w.set_mode(n % 8, vals::Mode::INPUT);
233 w.set_cnf_in(n % 8, vals::CnfIn::FLOATING);
234 });
235 }
236 #[cfg(gpio_v2)]
237 {
238 r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
239 r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
240 }
241 }); 235 });
242 } 236 }
243} 237}
@@ -254,57 +248,56 @@ pub enum Pull {
254 Down, 248 Down,
255} 249}
256 250
257#[cfg(gpio_v2)] 251impl Pull {
258impl From<Pull> for vals::Pupdr { 252 #[cfg(gpio_v2)]
259 fn from(pull: Pull) -> Self { 253 const fn to_pupdr(self) -> vals::Pupdr {
260 use Pull::*; 254 match self {
261 255 Pull::None => vals::Pupdr::FLOATING,
262 match pull { 256 Pull::Up => vals::Pupdr::PULLUP,
263 None => vals::Pupdr::FLOATING, 257 Pull::Down => vals::Pupdr::PULLDOWN,
264 Up => vals::Pupdr::PULLUP,
265 Down => vals::Pupdr::PULLDOWN,
266 } 258 }
267 } 259 }
268} 260}
269 261
270/// Speed settings 262/// Speed setting for an output.
271/// 263///
272/// These vary depending on the chip, check the reference manual or datasheet for details. 264/// These vary depending on the chip, check the reference manual and datasheet ("I/O port
273#[allow(missing_docs)] 265/// characteristics") for details.
274#[derive(Debug, Copy, Clone)] 266#[derive(Debug, Copy, Clone)]
275#[cfg_attr(feature = "defmt", derive(defmt::Format))] 267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
276pub enum Speed { 268pub enum Speed {
269 #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT2MHZ")]
270 #[cfg_attr(gpio_v2, doc = "Output speed 00")]
277 Low, 271 Low,
272 #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT10MHZ")]
273 #[cfg_attr(gpio_v2, doc = "Output speed 01")]
278 Medium, 274 Medium,
279 #[cfg(not(any(syscfg_f0, gpio_v1)))] 275 #[cfg_attr(gpio_v2, doc = "Output speed 10")]
276 #[cfg(not(any(gpio_v1, syscfg_f0)))]
280 High, 277 High,
278 #[cfg_attr(gpio_v1, doc = "Output speed OUTPUT50MHZ")]
279 #[cfg_attr(gpio_v2, doc = "Output speed 10")]
281 VeryHigh, 280 VeryHigh,
282} 281}
283 282
284#[cfg(gpio_v1)] 283impl Speed {
285impl From<Speed> for vals::Mode { 284 #[cfg(gpio_v1)]
286 fn from(speed: Speed) -> Self { 285 const fn to_mode(self) -> vals::Mode {
287 use Speed::*; 286 match self {
288 287 Speed::Low => vals::Mode::OUTPUT2MHZ,
289 match speed { 288 Speed::Medium => vals::Mode::OUTPUT10MHZ,
290 Low => vals::Mode::OUTPUT2MHZ, 289 Speed::VeryHigh => vals::Mode::OUTPUT50MHZ,
291 Medium => vals::Mode::OUTPUT10MHZ,
292 VeryHigh => vals::Mode::OUTPUT50MHZ,
293 } 290 }
294 } 291 }
295}
296
297#[cfg(gpio_v2)]
298impl From<Speed> for vals::Ospeedr {
299 fn from(speed: Speed) -> Self {
300 use Speed::*;
301 292
302 match speed { 293 #[cfg(gpio_v2)]
303 Low => vals::Ospeedr::LOWSPEED, 294 const fn to_ospeedr(self: Speed) -> vals::Ospeedr {
304 Medium => vals::Ospeedr::MEDIUMSPEED, 295 match self {
296 Speed::Low => vals::Ospeedr::LOWSPEED,
297 Speed::Medium => vals::Ospeedr::MEDIUMSPEED,
305 #[cfg(not(syscfg_f0))] 298 #[cfg(not(syscfg_f0))]
306 High => vals::Ospeedr::HIGHSPEED, 299 Speed::High => vals::Ospeedr::HIGHSPEED,
307 VeryHigh => vals::Ospeedr::VERYHIGHSPEED, 300 Speed::VeryHigh => vals::Ospeedr::VERYHIGHSPEED,
308 } 301 }
309 } 302 }
310} 303}
@@ -445,17 +438,29 @@ pub struct OutputOpenDrain<'d> {
445} 438}
446 439
447impl<'d> OutputOpenDrain<'d> { 440impl<'d> OutputOpenDrain<'d> {
448 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed], [Pull] configuration. 441 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed].
449 #[inline] 442 #[inline]
450 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { 443 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed) -> Self {
451 let mut pin = Flex::new(pin); 444 let mut pin = Flex::new(pin);
452
453 match initial_output { 445 match initial_output {
454 Level::High => pin.set_high(), 446 Level::High => pin.set_high(),
455 Level::Low => pin.set_low(), 447 Level::Low => pin.set_low(),
456 } 448 }
449 pin.set_as_input_output(speed);
450 Self { pin }
451 }
457 452
458 pin.set_as_input_output(speed, pull); 453 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level], [Speed]
454 /// and [Pull].
455 #[inline]
456 #[cfg(gpio_v2)]
457 pub fn new_pull(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self {
458 let mut pin = Flex::new(pin);
459 match initial_output {
460 Level::High => pin.set_high(),
461 Level::Low => pin.set_low(),
462 }
463 pin.set_as_input_output_pull(speed, pull);
459 Self { pin } 464 Self { pin }
460 } 465 }
461 466
@@ -521,6 +526,8 @@ impl<'d> OutputOpenDrain<'d> {
521} 526}
522 527
523/// GPIO output type 528/// GPIO output type
529#[derive(Debug, Copy, Clone)]
530#[cfg_attr(feature = "defmt", derive(defmt::Format))]
524pub enum OutputType { 531pub enum OutputType {
525 /// Drive the pin both high or low. 532 /// Drive the pin both high or low.
526 PushPull, 533 PushPull,
@@ -528,25 +535,170 @@ pub enum OutputType {
528 OpenDrain, 535 OpenDrain,
529} 536}
530 537
531impl From<OutputType> for AFType { 538impl OutputType {
532 fn from(value: OutputType) -> Self { 539 #[cfg(gpio_v1)]
533 match value { 540 const fn to_cnf_out(self) -> vals::CnfOut {
534 OutputType::OpenDrain => AFType::OutputOpenDrain, 541 match self {
535 OutputType::PushPull => AFType::OutputPushPull, 542 OutputType::PushPull => vals::CnfOut::ALTPUSHPULL,
543 OutputType::OpenDrain => vals::CnfOut::ALTOPENDRAIN,
544 }
545 }
546
547 #[cfg(gpio_v2)]
548 const fn to_ot(self) -> vals::Ot {
549 match self {
550 OutputType::PushPull => vals::Ot::PUSHPULL,
551 OutputType::OpenDrain => vals::Ot::OPENDRAIN,
552 }
553 }
554}
555
556/// Alternate function type settings.
557#[derive(Copy, Clone)]
558#[cfg(gpio_v1)]
559pub struct AfType {
560 mode: vals::Mode,
561 cnf: u8,
562 pull: Pull,
563}
564
565#[cfg(gpio_v1)]
566impl AfType {
567 /// Input with optional pullup or pulldown.
568 pub const fn input(pull: Pull) -> Self {
569 let cnf_in = match pull {
570 Pull::Up | Pull::Down => vals::CnfIn::PULL,
571 Pull::None => vals::CnfIn::FLOATING,
572 };
573 Self {
574 mode: vals::Mode::INPUT,
575 cnf: cnf_in.to_bits(),
576 pull,
577 }
578 }
579
580 /// Output with output type and speed and no pull-up or pull-down.
581 pub const fn output(output_type: OutputType, speed: Speed) -> Self {
582 Self {
583 mode: speed.to_mode(),
584 cnf: output_type.to_cnf_out().to_bits(),
585 pull: Pull::None,
536 } 586 }
537 } 587 }
538} 588}
539 589
540/// Alternate function type settings 590#[inline(never)]
541#[derive(Debug, Copy, Clone)] 591#[cfg(gpio_v1)]
542#[cfg_attr(feature = "defmt", derive(defmt::Format))] 592fn set_as_af(pin_port: u8, _af_num: u8, af_type: AfType) {
543pub enum AFType { 593 let pin = unsafe { AnyPin::steal(pin_port) };
544 /// Input 594 let r = pin.block();
545 Input, 595 let n = pin._pin() as usize;
546 /// Output, drive the pin both high or low. 596
547 OutputPushPull, 597 r.cr(n / 8).modify(|w| {
548 /// Output, drive the pin low, or don't drive it at all if the output level is high. 598 w.set_mode(n % 8, af_type.mode);
549 OutputOpenDrain, 599 // note that we are writing the CNF field, which is exposed as both `cnf_in` and `cnf_out`
600 // in the PAC. the choice of `cnf_in` instead of `cnf_out` in this code is arbitrary and
601 // does not affect the result.
602 w.set_cnf_in(n % 8, vals::CnfIn::from_bits(af_type.cnf));
603 });
604
605 match af_type.pull {
606 Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)),
607 Pull::Down => r.bsrr().write(|w| w.set_br(n, true)),
608 Pull::None => {}
609 }
610}
611
612/// Alternate function type settings.
613#[derive(Copy, Clone)]
614#[cfg(gpio_v2)]
615pub struct AfType {
616 pupdr: vals::Pupdr,
617 ot: vals::Ot,
618 ospeedr: vals::Ospeedr,
619}
620
621#[cfg(gpio_v2)]
622impl AfType {
623 /// Input with optional pullup or pulldown.
624 pub const fn input(pull: Pull) -> Self {
625 Self {
626 pupdr: pull.to_pupdr(),
627 ot: vals::Ot::PUSHPULL,
628 ospeedr: vals::Ospeedr::LOWSPEED,
629 }
630 }
631
632 /// Output with output type and speed and no pull-up or pull-down.
633 pub const fn output(output_type: OutputType, speed: Speed) -> Self {
634 Self::output_pull(output_type, speed, Pull::None)
635 }
636
637 /// Output with output type, speed and pull-up or pull-down;
638 pub const fn output_pull(output_type: OutputType, speed: Speed, pull: Pull) -> Self {
639 Self {
640 pupdr: pull.to_pupdr(),
641 ot: output_type.to_ot(),
642 ospeedr: speed.to_ospeedr(),
643 }
644 }
645}
646
647#[inline(never)]
648#[cfg(gpio_v2)]
649fn set_as_af(pin_port: u8, af_num: u8, af_type: AfType) {
650 let pin = unsafe { AnyPin::steal(pin_port) };
651 let r = pin.block();
652 let n = pin._pin() as usize;
653
654 r.afr(n / 8).modify(|w| w.set_afr(n % 8, af_num));
655 r.pupdr().modify(|w| w.set_pupdr(n, af_type.pupdr));
656 r.otyper().modify(|w| w.set_ot(n, af_type.ot));
657 r.ospeedr().modify(|w| w.set_ospeedr(n, af_type.ospeedr));
658 r.moder().modify(|w| w.set_moder(n, vals::Moder::ALTERNATE));
659}
660
661#[inline(never)]
662fn set_as_analog(pin_port: u8) {
663 let pin = unsafe { AnyPin::steal(pin_port) };
664 let r = pin.block();
665 let n = pin._pin() as usize;
666
667 #[cfg(gpio_v1)]
668 r.cr(n / 8).modify(|w| {
669 w.set_mode(n % 8, vals::Mode::INPUT);
670 w.set_cnf_in(n % 8, vals::CnfIn::ANALOG);
671 });
672
673 #[cfg(gpio_v2)]
674 r.moder().modify(|w| w.set_moder(n, vals::Moder::ANALOG));
675}
676
677#[inline(never)]
678fn get_pull(pin_port: u8) -> Pull {
679 let pin = unsafe { AnyPin::steal(pin_port) };
680 let r = pin.block();
681 let n = pin._pin() as usize;
682
683 #[cfg(gpio_v1)]
684 return match r.cr(n / 8).read().mode(n % 8) {
685 vals::Mode::INPUT => match r.cr(n / 8).read().cnf_in(n % 8) {
686 vals::CnfIn::PULL => match r.odr().read().odr(n) {
687 vals::Odr::LOW => Pull::Down,
688 vals::Odr::HIGH => Pull::Up,
689 },
690 _ => Pull::None,
691 },
692 _ => Pull::None,
693 };
694
695 #[cfg(gpio_v2)]
696 return match r.pupdr().read().pupdr(n) {
697 vals::Pupdr::FLOATING => Pull::None,
698 vals::Pupdr::PULLDOWN => Pull::Down,
699 vals::Pupdr::PULLUP => Pull::Up,
700 vals::Pupdr::_RESERVED_3 => Pull::None,
701 };
550} 702}
551 703
552pub(crate) trait SealedPin { 704pub(crate) trait SealedPin {
@@ -556,6 +708,7 @@ pub(crate) trait SealedPin {
556 fn _pin(&self) -> u8 { 708 fn _pin(&self) -> u8 {
557 self.pin_port() % 16 709 self.pin_port() % 16
558 } 710 }
711
559 #[inline] 712 #[inline]
560 fn _port(&self) -> u8 { 713 fn _port(&self) -> u8 {
561 self.pin_port() / 16 714 self.pin_port() / 16
@@ -581,146 +734,31 @@ pub(crate) trait SealedPin {
581 } 734 }
582 735
583 #[inline] 736 #[inline]
584 fn set_as_af(&self, af_num: u8, af_type: AFType) { 737 fn set_as_af(&self, af_num: u8, af_type: AfType) {
585 self.set_as_af_pull(af_num, af_type, Pull::None); 738 set_as_af(self.pin_port(), af_num, af_type)
586 }
587
588 #[cfg(gpio_v1)]
589 #[inline]
590 fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) {
591 // F1 uses the AFIO register for remapping.
592 // For now, this is not implemented, so af_num is ignored
593 // _af_num should be zero here, since it is not set by stm32-data
594 let r = self.block();
595 let n = self._pin() as usize;
596 let crlh = if n < 8 { 0 } else { 1 };
597 match af_type {
598 AFType::Input => {
599 let cnf = match pull {
600 Pull::Up => {
601 r.bsrr().write(|w| w.set_bs(n, true));
602 vals::CnfIn::PULL
603 }
604 Pull::Down => {
605 r.bsrr().write(|w| w.set_br(n, true));
606 vals::CnfIn::PULL
607 }
608 Pull::None => vals::CnfIn::FLOATING,
609 };
610
611 r.cr(crlh).modify(|w| {
612 w.set_mode(n % 8, vals::Mode::INPUT);
613 w.set_cnf_in(n % 8, cnf);
614 });
615 }
616 AFType::OutputPushPull => {
617 r.cr(crlh).modify(|w| {
618 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
619 w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
620 });
621 }
622 AFType::OutputOpenDrain => {
623 r.cr(crlh).modify(|w| {
624 w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
625 w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
626 });
627 }
628 }
629 }
630
631 #[cfg(gpio_v2)]
632 #[inline]
633 fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) {
634 let pin = self._pin() as usize;
635 let block = self.block();
636 block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
637 match af_type {
638 AFType::Input => {}
639 AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)),
640 AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
641 }
642 block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
643
644 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE));
645 } 739 }
646 740
647 #[inline] 741 #[inline]
648 fn set_as_analog(&self) { 742 fn set_as_analog(&self) {
649 let pin = self._pin() as usize; 743 set_as_analog(self.pin_port());
650 let block = self.block();
651 #[cfg(gpio_v1)]
652 {
653 let crlh = if pin < 8 { 0 } else { 1 };
654 block.cr(crlh).modify(|w| {
655 w.set_mode(pin % 8, vals::Mode::INPUT);
656 w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
657 });
658 }
659 #[cfg(gpio_v2)]
660 block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
661 } 744 }
662 745
663 /// Set the pin as "disconnected", ie doing nothing and consuming the lowest 746 /// Set the pin as "disconnected", ie doing nothing and consuming the lowest
664 /// amount of power possible. 747 /// amount of power possible.
665 /// 748 ///
666 /// This is currently the same as set_as_analog but is semantically different really. 749 /// This is currently the same as [`Self::set_as_analog()`] but is semantically different
667 /// Drivers should set_as_disconnected pins when dropped. 750 /// really. Drivers should `set_as_disconnected()` pins when dropped.
751 ///
752 /// Note that this also disables the internal weak pull-up and pull-down resistors.
668 #[inline] 753 #[inline]
669 fn set_as_disconnected(&self) { 754 fn set_as_disconnected(&self) {
670 self.set_as_analog(); 755 self.set_as_analog();
671 } 756 }
672 757
673 /// Sets the speed of the output pin.
674 ///
675 /// This should never be called for AFType::Input on the STM32F1 series, since MODE and
676 /// CNF bits are not independent. If the CNF bits are altered afterwards as well, this
677 /// will put the pin into output mode.
678 #[inline]
679 fn set_speed(&self, speed: Speed) {
680 let pin = self._pin() as usize;
681
682 #[cfg(gpio_v1)]
683 {
684 let crlh = if pin < 8 { 0 } else { 1 };
685 self.block().cr(crlh).modify(|w| {
686 w.set_mode(pin % 8, speed.into());
687 });
688 }
689
690 #[cfg(gpio_v2)]
691 self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
692 }
693
694 /// Get the pull-up configuration. 758 /// Get the pull-up configuration.
695 #[inline] 759 #[inline]
696 fn pull(&self) -> Pull { 760 fn pull(&self) -> Pull {
697 critical_section::with(|_| { 761 critical_section::with(|_| get_pull(self.pin_port()))
698 let r = self.block();
699 let n = self._pin() as usize;
700 #[cfg(gpio_v1)]
701 {
702 let crlh = if n < 8 { 0 } else { 1 };
703 match r.cr(crlh).read().mode(n % 8) {
704 vals::Mode::INPUT => match r.cr(crlh).read().cnf_in(n % 8) {
705 vals::CnfIn::PULL => match r.odr().read().odr(n) {
706 vals::Odr::LOW => Pull::Down,
707 vals::Odr::HIGH => Pull::Up,
708 },
709 _ => Pull::None,
710 },
711 _ => Pull::None,
712 }
713 }
714 #[cfg(gpio_v2)]
715 {
716 match r.pupdr().read().pupdr(n) {
717 vals::Pupdr::FLOATING => Pull::None,
718 vals::Pupdr::PULLDOWN => Pull::Down,
719 vals::Pupdr::PULLUP => Pull::Up,
720 vals::Pupdr::_RESERVED_3 => Pull::None,
721 }
722 }
723 })
724 } 762 }
725} 763}
726 764
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;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8pub use traits::Instance; 8pub use traits::Instance;
9 9
10use crate::gpio::{AFType, AnyPin}; 10use crate::gpio::{AfType, AnyPin, OutputType, Speed};
11use crate::time::Hertz; 11use crate::time::Hertz;
12use crate::{rcc, Peripheral}; 12use crate::{rcc, Peripheral};
13 13
@@ -80,9 +80,10 @@ macro_rules! advanced_channel_impl {
80 into_ref!(pin); 80 into_ref!(pin);
81 critical_section::with(|_| { 81 critical_section::with(|_| {
82 pin.set_low(); 82 pin.set_low();
83 pin.set_as_af(pin.af_num(), AFType::OutputPushPull); 83 pin.set_as_af(
84 #[cfg(gpio_v2)] 84 pin.af_num(),
85 pin.set_speed(crate::gpio::Speed::VeryHigh); 85 AfType::output(OutputType::PushPull, Speed::VeryHigh),
86 );
86 }); 87 });
87 PwmPin { 88 PwmPin {
88 _pin: pin.map_into(), 89 _pin: pin.map_into(),
@@ -97,9 +98,10 @@ macro_rules! advanced_channel_impl {
97 into_ref!(pin); 98 into_ref!(pin);
98 critical_section::with(|_| { 99 critical_section::with(|_| {
99 pin.set_low(); 100 pin.set_low();
100 pin.set_as_af(pin.af_num(), AFType::OutputPushPull); 101 pin.set_as_af(
101 #[cfg(gpio_v2)] 102 pin.af_num(),
102 pin.set_speed(crate::gpio::Speed::VeryHigh); 103 AfType::output(OutputType::PushPull, Speed::VeryHigh),
104 );
103 }); 105 });
104 ComplementaryPwmPin { 106 ComplementaryPwmPin {
105 _pin: pin.map_into(), 107 _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;
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
16 16
17use crate::dma::ChannelAndRequest; 17use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 18#[cfg(gpio_v2)]
19use crate::gpio::Pull;
20use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
19use crate::interrupt::typelevel::Interrupt; 21use crate::interrupt::typelevel::Interrupt;
20use crate::mode::{Async, Blocking, Mode}; 22use crate::mode::{Async, Blocking, Mode};
21use crate::rcc::{RccInfo, SealedRccPeripheral}; 23use crate::rcc::{RccInfo, SealedRccPeripheral};
@@ -50,11 +52,13 @@ pub struct Config {
50 /// 52 ///
51 /// Using external pullup resistors is recommended for I2C. If you do 53 /// Using external pullup resistors is recommended for I2C. If you do
52 /// have external pullups you should not enable this. 54 /// have external pullups you should not enable this.
55 #[cfg(gpio_v2)]
53 pub sda_pullup: bool, 56 pub sda_pullup: bool,
54 /// Enable internal pullup on SCL. 57 /// Enable internal pullup on SCL.
55 /// 58 ///
56 /// Using external pullup resistors is recommended for I2C. If you do 59 /// Using external pullup resistors is recommended for I2C. If you do
57 /// have external pullups you should not enable this. 60 /// have external pullups you should not enable this.
61 #[cfg(gpio_v2)]
58 pub scl_pullup: bool, 62 pub scl_pullup: bool,
59 /// Timeout. 63 /// Timeout.
60 #[cfg(feature = "time")] 64 #[cfg(feature = "time")]
@@ -64,7 +68,9 @@ pub struct Config {
64impl Default for Config { 68impl Default for Config {
65 fn default() -> Self { 69 fn default() -> Self {
66 Self { 70 Self {
71 #[cfg(gpio_v2)]
67 sda_pullup: false, 72 sda_pullup: false,
73 #[cfg(gpio_v2)]
68 scl_pullup: false, 74 scl_pullup: false,
69 #[cfg(feature = "time")] 75 #[cfg(feature = "time")]
70 timeout: embassy_time::Duration::from_millis(1000), 76 timeout: embassy_time::Duration::from_millis(1000),
@@ -73,18 +79,32 @@ impl Default for Config {
73} 79}
74 80
75impl Config { 81impl Config {
76 fn scl_pull_mode(&self) -> Pull { 82 fn scl_af(&self) -> AfType {
77 match self.scl_pullup { 83 #[cfg(gpio_v1)]
78 true => Pull::Up, 84 return AfType::output(OutputType::OpenDrain, Speed::Medium);
79 false => Pull::Down, 85 #[cfg(gpio_v2)]
80 } 86 return AfType::output_pull(
87 OutputType::OpenDrain,
88 Speed::Medium,
89 match self.scl_pullup {
90 true => Pull::Up,
91 false => Pull::Down,
92 },
93 );
81 } 94 }
82 95
83 fn sda_pull_mode(&self) -> Pull { 96 fn sda_af(&self) -> AfType {
84 match self.sda_pullup { 97 #[cfg(gpio_v1)]
85 true => Pull::Up, 98 return AfType::output(OutputType::OpenDrain, Speed::Medium);
86 false => Pull::Down, 99 #[cfg(gpio_v2)]
87 } 100 return AfType::output_pull(
101 OutputType::OpenDrain,
102 Speed::Medium,
103 match self.sda_pullup {
104 true => Pull::Up,
105 false => Pull::Down,
106 },
107 );
88 } 108 }
89} 109}
90 110
@@ -118,8 +138,8 @@ impl<'d> I2c<'d, Async> {
118 ) -> Self { 138 ) -> Self {
119 Self::new_inner( 139 Self::new_inner(
120 peri, 140 peri,
121 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()), 141 new_pin!(scl, config.scl_af()),
122 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()), 142 new_pin!(sda, config.sda_af()),
123 new_dma!(tx_dma), 143 new_dma!(tx_dma),
124 new_dma!(rx_dma), 144 new_dma!(rx_dma),
125 freq, 145 freq,
@@ -139,8 +159,8 @@ impl<'d> I2c<'d, Blocking> {
139 ) -> Self { 159 ) -> Self {
140 Self::new_inner( 160 Self::new_inner(
141 peri, 161 peri,
142 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()), 162 new_pin!(scl, config.scl_af()),
143 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()), 163 new_pin!(sda, config.sda_af()),
144 None, 164 None,
145 None, 165 None,
146 freq, 166 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 @@
3use embassy_hal_internal::into_ref; 3use embassy_hal_internal::into_ref;
4 4
5use crate::dma::ChannelAndRequest; 5use crate::dma::ChannelAndRequest;
6use crate::gpio::{AFType, AnyPin, SealedPin, Speed}; 6use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
7use crate::mode::Async; 7use crate::mode::Async;
8use crate::pac::spi::vals; 8use crate::pac::spi::vals;
9use crate::spi::{Config as SpiConfig, *}; 9use crate::spi::{Config as SpiConfig, *};
@@ -180,7 +180,7 @@ impl<'d> I2S<'d> {
180 into_ref!(sd); 180 into_ref!(sd);
181 Self::new_inner( 181 Self::new_inner(
182 peri, 182 peri,
183 new_pin!(sd, AFType::OutputPushPull, Speed::VeryHigh), 183 new_pin!(sd, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
184 None, 184 None,
185 ws, 185 ws,
186 ck, 186 ck,
@@ -209,7 +209,7 @@ impl<'d> I2S<'d> {
209 Self::new_inner( 209 Self::new_inner(
210 peri, 210 peri,
211 None, 211 None,
212 new_pin!(sd, AFType::OutputPushPull, Speed::VeryHigh), 212 new_pin!(sd, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
213 ws, 213 ws,
214 ck, 214 ck,
215 mck, 215 mck,
@@ -244,8 +244,8 @@ impl<'d> I2S<'d> {
244 into_ref!(txsd, rxsd); 244 into_ref!(txsd, rxsd);
245 Self::new_inner( 245 Self::new_inner(
246 peri, 246 peri,
247 new_pin!(txsd, AFType::OutputPushPull, Speed::VeryHigh), 247 new_pin!(txsd, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
248 new_pin!(rxsd, AFType::OutputPushPull, Speed::VeryHigh), 248 new_pin!(rxsd, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
249 ws, 249 ws,
250 ck, 250 ck,
251 mck, 251 mck,
@@ -292,14 +292,9 @@ impl<'d> I2S<'d> {
292 ) -> Self { 292 ) -> Self {
293 into_ref!(ws, ck, mck); 293 into_ref!(ws, ck, mck);
294 294
295 ws.set_as_af(ws.af_num(), AFType::OutputPushPull); 295 ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
296 ws.set_speed(Speed::VeryHigh); 296 ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
297 297 mck.set_as_af(mck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
298 ck.set_as_af(ck.af_num(), AFType::OutputPushPull);
299 ck.set_speed(Speed::VeryHigh);
300
301 mck.set_as_af(mck.af_num(), AFType::OutputPushPull);
302 mck.set_speed(Speed::VeryHigh);
303 298
304 let mut spi_cfg = SpiConfig::default(); 299 let mut spi_cfg = SpiConfig::default();
305 spi_cfg.frequency = freq; 300 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> {
62 62
63 rcc::enable_and_reset::<T>(); 63 rcc::enable_and_reset::<T>();
64 64
65 //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh, Pull::None); 65 //new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh));
66 66
67 // Set Tearing Enable pin according to CubeMx example 67 // Set Tearing Enable pin according to CubeMx example
68 //te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); 68 //te.set_as_af_pull(te.af_num(), AfType::output(OutputType::PushPull, Speed::Low));
69 //te.set_speed(Speed::Low);
70 /* 69 /*
71 T::regs().wcr().modify(|w| { 70 T::regs().wcr().modify(|w| {
72 w.set_dsien(true); 71 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 {
97} 97}
98 98
99macro_rules! new_pin { 99macro_rules! new_pin {
100 ($name:ident, $aftype:expr) => {{ 100 ($name:ident, $af_type:expr) => {{
101 new_pin!($name, $aftype, crate::gpio::Speed::Medium, crate::gpio::Pull::None)
102 }};
103 ($name:ident, $aftype:expr, $speed:expr) => {
104 new_pin!($name, $aftype, $speed, crate::gpio::Pull::None)
105 };
106 ($name:ident, $aftype:expr, $speed:expr, $pull:expr) => {{
107 let pin = $name.into_ref(); 101 let pin = $name.into_ref();
108 pin.set_as_af_pull(pin.af_num(), $aftype, $pull); 102 pin.set_as_af(pin.af_num(), $af_type);
109 // Do not call set_speed on AFType::Input, as MODE and CNF bits are not independent
110 // for gpio_v1
111 match $aftype {
112 crate::gpio::AFType::Input => {}
113 _ => {
114 pin.set_speed($speed);
115 }
116 };
117 Some(pin.map_into()) 103 Some(pin.map_into())
118 }}; 104 }};
119} 105}
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::*;
13use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits}; 13use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits};
14 14
15use crate::dma::{word, ChannelAndRequest}; 15use crate::dma::{word, ChannelAndRequest};
16use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 16use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
17use crate::mode::{Async, Blocking, Mode as PeriMode}; 17use crate::mode::{Async, Blocking, Mode as PeriMode};
18use crate::pac::octospi::{vals, Octospi as Regs}; 18use crate::pac::octospi::{vals, Octospi as Regs};
19use crate::rcc::{self, RccPeripheral}; 19use crate::rcc::{self, RccPeripheral};
@@ -548,16 +548,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
548 ) -> Self { 548 ) -> Self {
549 Self::new_inner( 549 Self::new_inner(
550 peri, 550 peri,
551 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 551 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
552 new_pin!(d1, AFType::Input, Speed::VeryHigh), 552 new_pin!(d1, AfType::input(Pull::None)),
553 None, 553 None,
554 None, 554 None,
555 None, 555 None,
556 None, 556 None,
557 None, 557 None,
558 None, 558 None,
559 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 559 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
560 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 560 new_pin!(
561 nss,
562 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
563 ),
561 None, 564 None,
562 None, 565 None,
563 config, 566 config,
@@ -577,16 +580,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
577 ) -> Self { 580 ) -> Self {
578 Self::new_inner( 581 Self::new_inner(
579 peri, 582 peri,
580 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 583 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
581 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 584 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
582 None, 585 None,
583 None, 586 None,
584 None, 587 None,
585 None, 588 None,
586 None, 589 None,
587 None, 590 None,
588 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 591 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
589 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 592 new_pin!(
593 nss,
594 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
595 ),
590 None, 596 None,
591 None, 597 None,
592 config, 598 config,
@@ -608,16 +614,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
608 ) -> Self { 614 ) -> Self {
609 Self::new_inner( 615 Self::new_inner(
610 peri, 616 peri,
611 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 617 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
612 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 618 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
613 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 619 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
614 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 620 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
615 None, 621 None,
616 None, 622 None,
617 None, 623 None,
618 None, 624 None,
619 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 625 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
620 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 626 new_pin!(
627 nss,
628 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
629 ),
621 None, 630 None,
622 None, 631 None,
623 config, 632 config,
@@ -643,16 +652,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
643 ) -> Self { 652 ) -> Self {
644 Self::new_inner( 653 Self::new_inner(
645 peri, 654 peri,
646 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 655 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
647 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 656 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
648 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 657 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
649 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 658 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
650 new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), 659 new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
651 new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), 660 new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
652 new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), 661 new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
653 new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), 662 new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
654 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 663 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
655 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 664 new_pin!(
665 nss,
666 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
667 ),
656 None, 668 None,
657 None, 669 None,
658 config, 670 config,
@@ -678,16 +690,19 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
678 ) -> Self { 690 ) -> Self {
679 Self::new_inner( 691 Self::new_inner(
680 peri, 692 peri,
681 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 693 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
682 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 694 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
683 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 695 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
684 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 696 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
685 new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), 697 new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
686 new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), 698 new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
687 new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), 699 new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
688 new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), 700 new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
689 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 701 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
690 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 702 new_pin!(
703 nss,
704 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
705 ),
691 None, 706 None,
692 None, 707 None,
693 config, 708 config,
@@ -710,16 +725,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
710 ) -> Self { 725 ) -> Self {
711 Self::new_inner( 726 Self::new_inner(
712 peri, 727 peri,
713 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 728 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
714 new_pin!(d1, AFType::Input, Speed::VeryHigh), 729 new_pin!(d1, AfType::input(Pull::None)),
715 None, 730 None,
716 None, 731 None,
717 None, 732 None,
718 None, 733 None,
719 None, 734 None,
720 None, 735 None,
721 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 736 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
722 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 737 new_pin!(
738 nss,
739 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
740 ),
723 None, 741 None,
724 new_dma!(dma), 742 new_dma!(dma),
725 config, 743 config,
@@ -740,16 +758,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
740 ) -> Self { 758 ) -> Self {
741 Self::new_inner( 759 Self::new_inner(
742 peri, 760 peri,
743 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 761 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
744 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 762 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
745 None, 763 None,
746 None, 764 None,
747 None, 765 None,
748 None, 766 None,
749 None, 767 None,
750 None, 768 None,
751 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 769 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
752 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 770 new_pin!(
771 nss,
772 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
773 ),
753 None, 774 None,
754 new_dma!(dma), 775 new_dma!(dma),
755 config, 776 config,
@@ -772,16 +793,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
772 ) -> Self { 793 ) -> Self {
773 Self::new_inner( 794 Self::new_inner(
774 peri, 795 peri,
775 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 796 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
776 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 797 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
777 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 798 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
778 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 799 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
779 None, 800 None,
780 None, 801 None,
781 None, 802 None,
782 None, 803 None,
783 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 804 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
784 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 805 new_pin!(
806 nss,
807 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
808 ),
785 None, 809 None,
786 new_dma!(dma), 810 new_dma!(dma),
787 config, 811 config,
@@ -808,16 +832,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
808 ) -> Self { 832 ) -> Self {
809 Self::new_inner( 833 Self::new_inner(
810 peri, 834 peri,
811 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 835 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
812 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 836 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
813 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 837 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
814 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 838 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
815 new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), 839 new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
816 new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), 840 new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
817 new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), 841 new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
818 new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), 842 new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
819 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 843 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
820 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 844 new_pin!(
845 nss,
846 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
847 ),
821 None, 848 None,
822 new_dma!(dma), 849 new_dma!(dma),
823 config, 850 config,
@@ -844,16 +871,19 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
844 ) -> Self { 871 ) -> Self {
845 Self::new_inner( 872 Self::new_inner(
846 peri, 873 peri,
847 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 874 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
848 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 875 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
849 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 876 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
850 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 877 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
851 new_pin!(d4, AFType::OutputPushPull, Speed::VeryHigh), 878 new_pin!(d4, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
852 new_pin!(d5, AFType::OutputPushPull, Speed::VeryHigh), 879 new_pin!(d5, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
853 new_pin!(d6, AFType::OutputPushPull, Speed::VeryHigh), 880 new_pin!(d6, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
854 new_pin!(d7, AFType::OutputPushPull, Speed::VeryHigh), 881 new_pin!(d7, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
855 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 882 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
856 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 883 new_pin!(
884 nss,
885 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
886 ),
857 None, 887 None,
858 new_dma!(dma), 888 new_dma!(dma),
859 config, 889 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};
10use enums::*; 10use enums::*;
11 11
12use crate::dma::ChannelAndRequest; 12use crate::dma::ChannelAndRequest;
13use crate::gpio::{AFType, AnyPin, Pull, Speed}; 13use crate::gpio::{AfType, AnyPin, OutputType, Pull, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::quadspi::Quadspi as Regs; 15use crate::pac::quadspi::Quadspi as Regs;
16use crate::rcc::{self, RccPeripheral}; 16use crate::rcc::{self, RccPeripheral};
@@ -248,12 +248,15 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> {
248 ) -> Self { 248 ) -> Self {
249 Self::new_inner( 249 Self::new_inner(
250 peri, 250 peri,
251 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 251 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
252 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 252 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
253 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 253 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
254 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 254 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
255 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 255 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
256 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 256 new_pin!(
257 nss,
258 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
259 ),
257 None, 260 None,
258 config, 261 config,
259 FlashSelection::Flash1, 262 FlashSelection::Flash1,
@@ -273,12 +276,15 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> {
273 ) -> Self { 276 ) -> Self {
274 Self::new_inner( 277 Self::new_inner(
275 peri, 278 peri,
276 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 279 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
277 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 280 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
278 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 281 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
279 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 282 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
280 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 283 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
281 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 284 new_pin!(
285 nss,
286 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
287 ),
282 None, 288 None,
283 config, 289 config,
284 FlashSelection::Flash2, 290 FlashSelection::Flash2,
@@ -301,12 +307,15 @@ impl<'d, T: Instance> Qspi<'d, T, Async> {
301 ) -> Self { 307 ) -> Self {
302 Self::new_inner( 308 Self::new_inner(
303 peri, 309 peri,
304 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 310 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
305 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 311 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
306 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 312 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
307 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 313 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
308 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 314 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
309 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 315 new_pin!(
316 nss,
317 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
318 ),
310 new_dma!(dma), 319 new_dma!(dma),
311 config, 320 config,
312 FlashSelection::Flash1, 321 FlashSelection::Flash1,
@@ -327,12 +336,15 @@ impl<'d, T: Instance> Qspi<'d, T, Async> {
327 ) -> Self { 336 ) -> Self {
328 Self::new_inner( 337 Self::new_inner(
329 peri, 338 peri,
330 new_pin!(d0, AFType::OutputPushPull, Speed::VeryHigh), 339 new_pin!(d0, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
331 new_pin!(d1, AFType::OutputPushPull, Speed::VeryHigh), 340 new_pin!(d1, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
332 new_pin!(d2, AFType::OutputPushPull, Speed::VeryHigh), 341 new_pin!(d2, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
333 new_pin!(d3, AFType::OutputPushPull, Speed::VeryHigh), 342 new_pin!(d3, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
334 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh), 343 new_pin!(sck, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
335 new_pin!(nss, AFType::OutputPushPull, Speed::VeryHigh, Pull::Up), 344 new_pin!(
345 nss,
346 AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)
347 ),
336 new_dma!(dma), 348 new_dma!(dma),
337 config, 349 config,
338 FlashSelection::Flash2, 350 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;
2 2
3use embassy_hal_internal::into_ref; 3use embassy_hal_internal::into_ref;
4 4
5use crate::gpio::{AFType, Speed}; 5use crate::gpio::{AfType, OutputType, Speed};
6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] 6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
7pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; 7pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
8#[cfg(not(any( 8#[cfg(not(any(
@@ -101,8 +101,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
101 101
102 critical_section::with(|_| unsafe { 102 critical_section::with(|_| unsafe {
103 T::_apply_clock_settings(source, prescaler); 103 T::_apply_clock_settings(source, prescaler);
104 pin.set_as_af(pin.af_num(), AFType::OutputPushPull); 104 pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
105 pin.set_speed(Speed::VeryHigh);
106 }); 105 });
107 106
108 Self { phantom: PhantomData } 107 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};
9pub use crate::dma::word; 9pub use crate::dma::word;
10#[cfg(not(gpdma))] 10#[cfg(not(gpdma))]
11use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; 11use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
12use crate::gpio::{AFType, AnyPin, SealedPin as _}; 12use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
13use crate::pac::sai::{vals, Sai as Regs}; 13use crate::pac::sai::{vals, Sai as Regs};
14use crate::rcc::{self, RccPeripheral}; 14use crate::rcc::{self, RccPeripheral};
15use crate::{peripherals, Peripheral}; 15use crate::{peripherals, Peripheral};
@@ -656,17 +656,17 @@ fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut
656} 656}
657 657
658// return the type for (sd, sck) 658// return the type for (sd, sck)
659fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) { 659fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AfType, AfType) {
660 ( 660 (
661 //sd is defined by tx/rx mode 661 //sd is defined by tx/rx mode
662 match tx_rx { 662 match tx_rx {
663 TxRx::Transmitter => AFType::OutputPushPull, 663 TxRx::Transmitter => AfType::output(OutputType::PushPull, Speed::VeryHigh),
664 TxRx::Receiver => AFType::Input, 664 TxRx::Receiver => AfType::input(Pull::None),
665 }, 665 },
666 //clocks (mclk, sck and fs) are defined by master/slave 666 //clocks (mclk, sck and fs) are defined by master/slave
667 match mode { 667 match mode {
668 Mode::Master => AFType::OutputPushPull, 668 Mode::Master => AfType::output(OutputType::PushPull, Speed::VeryHigh),
669 Mode::Slave => AFType::Input, 669 Mode::Slave => AfType::input(Pull::None),
670 }, 670 },
671 ) 671 )
672} 672}
@@ -768,9 +768,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
768 into_ref!(mclk); 768 into_ref!(mclk);
769 769
770 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); 770 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
771
772 mclk.set_as_af(mclk.af_num(), ck_af_type); 771 mclk.set_as_af(mclk.af_num(), ck_af_type);
773 mclk.set_speed(crate::gpio::Speed::VeryHigh);
774 772
775 if config.master_clock_divider == MasterClockDivider::MasterClockDisabled { 773 if config.master_clock_divider == MasterClockDivider::MasterClockDisabled {
776 config.master_clock_divider = MasterClockDivider::Div1; 774 config.master_clock_divider = MasterClockDivider::Div1;
@@ -796,12 +794,8 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
796 794
797 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); 795 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
798 sd.set_as_af(sd.af_num(), sd_af_type); 796 sd.set_as_af(sd.af_num(), sd_af_type);
799 sd.set_speed(crate::gpio::Speed::VeryHigh);
800
801 sck.set_as_af(sck.af_num(), ck_af_type); 797 sck.set_as_af(sck.af_num(), ck_af_type);
802 sck.set_speed(crate::gpio::Speed::VeryHigh);
803 fs.set_as_af(fs.af_num(), ck_af_type); 798 fs.set_as_af(fs.af_num(), ck_af_type);
804 fs.set_speed(crate::gpio::Speed::VeryHigh);
805 799
806 let sub_block = S::WHICH; 800 let sub_block = S::WHICH;
807 let request = dma.request(); 801 let request = dma.request();
@@ -834,9 +828,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
834 into_ref!(dma, peri, sd); 828 into_ref!(dma, peri, sd);
835 829
836 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); 830 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
837
838 sd.set_as_af(sd.af_num(), sd_af_type); 831 sd.set_as_af(sd.af_num(), sd_af_type);
839 sd.set_speed(crate::gpio::Speed::VeryHigh);
840 832
841 let sub_block = S::WHICH; 833 let sub_block = S::WHICH;
842 let request = dma.request(); 834 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;
13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
14 14
15use crate::dma::NoDma; 15use crate::dma::NoDma;
16use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed}; 16#[cfg(gpio_v2)]
17use crate::gpio::Pull;
18use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
17use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
18use crate::pac::sdmmc::Sdmmc as RegBlock; 20use crate::pac::sdmmc::Sdmmc as RegBlock;
19use crate::rcc::{self, RccPeripheral}; 21use crate::rcc::{self, RccPeripheral};
@@ -292,6 +294,13 @@ pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma<T> = NoDma> {
292 card: Option<Card>, 294 card: Option<Card>,
293} 295}
294 296
297const CLK_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh);
298#[cfg(gpio_v1)]
299const CMD_AF: AfType = AfType::output(OutputType::PushPull, Speed::VeryHigh);
300#[cfg(gpio_v2)]
301const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up);
302const DATA_AF: AfType = CMD_AF;
303
295#[cfg(sdmmc_v1)] 304#[cfg(sdmmc_v1)]
296impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { 305impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
297 /// Create a new SDMMC driver, with 1 data lane. 306 /// Create a new SDMMC driver, with 1 data lane.
@@ -307,13 +316,9 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
307 into_ref!(clk, cmd, d0); 316 into_ref!(clk, cmd, d0);
308 317
309 critical_section::with(|_| { 318 critical_section::with(|_| {
310 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); 319 clk.set_as_af(clk.af_num(), CLK_AF);
311 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); 320 cmd.set_as_af(cmd.af_num(), CMD_AF);
312 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); 321 d0.set_as_af(d0.af_num(), DATA_AF);
313
314 clk.set_speed(Speed::VeryHigh);
315 cmd.set_speed(Speed::VeryHigh);
316 d0.set_speed(Speed::VeryHigh);
317 }); 322 });
318 323
319 Self::new_inner( 324 Self::new_inner(
@@ -345,19 +350,12 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
345 into_ref!(clk, cmd, d0, d1, d2, d3); 350 into_ref!(clk, cmd, d0, d1, d2, d3);
346 351
347 critical_section::with(|_| { 352 critical_section::with(|_| {
348 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); 353 clk.set_as_af(clk.af_num(), CLK_AF);
349 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); 354 cmd.set_as_af(cmd.af_num(), CMD_AF);
350 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); 355 d0.set_as_af(d0.af_num(), DATA_AF);
351 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up); 356 d1.set_as_af(d1.af_num(), DATA_AF);
352 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up); 357 d2.set_as_af(d2.af_num(), DATA_AF);
353 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up); 358 d3.set_as_af(d3.af_num(), DATA_AF);
354
355 clk.set_speed(Speed::VeryHigh);
356 cmd.set_speed(Speed::VeryHigh);
357 d0.set_speed(Speed::VeryHigh);
358 d1.set_speed(Speed::VeryHigh);
359 d2.set_speed(Speed::VeryHigh);
360 d3.set_speed(Speed::VeryHigh);
361 }); 359 });
362 360
363 Self::new_inner( 361 Self::new_inner(
@@ -388,13 +386,9 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
388 into_ref!(clk, cmd, d0); 386 into_ref!(clk, cmd, d0);
389 387
390 critical_section::with(|_| { 388 critical_section::with(|_| {
391 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); 389 clk.set_as_af(clk.af_num(), CLK_AF);
392 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); 390 cmd.set_as_af(cmd.af_num(), CMD_AF);
393 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); 391 d0.set_as_af(d0.af_num(), DATA_AF);
394
395 clk.set_speed(Speed::VeryHigh);
396 cmd.set_speed(Speed::VeryHigh);
397 d0.set_speed(Speed::VeryHigh);
398 }); 392 });
399 393
400 Self::new_inner( 394 Self::new_inner(
@@ -425,19 +419,12 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
425 into_ref!(clk, cmd, d0, d1, d2, d3); 419 into_ref!(clk, cmd, d0, d1, d2, d3);
426 420
427 critical_section::with(|_| { 421 critical_section::with(|_| {
428 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None); 422 clk.set_as_af(clk.af_num(), CLK_AF);
429 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up); 423 cmd.set_as_af(cmd.af_num(), CMD_AF);
430 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up); 424 d0.set_as_af(d0.af_num(), DATA_AF);
431 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up); 425 d1.set_as_af(d1.af_num(), DATA_AF);
432 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up); 426 d2.set_as_af(d2.af_num(), DATA_AF);
433 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up); 427 d3.set_as_af(d3.af_num(), DATA_AF);
434
435 clk.set_speed(Speed::VeryHigh);
436 cmd.set_speed(Speed::VeryHigh);
437 d0.set_speed(Speed::VeryHigh);
438 d1.set_speed(Speed::VeryHigh);
439 d2.set_speed(Speed::VeryHigh);
440 d3.set_speed(Speed::VeryHigh);
441 }); 428 });
442 429
443 Self::new_inner( 430 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;
10pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 10pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
11 11
12use crate::dma::{word, ChannelAndRequest}; 12use crate::dma::{word, ChannelAndRequest};
13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 15use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::{RccInfo, SealedRccPeripheral}; 16use crate::rcc::{RccInfo, SealedRccPeripheral};
@@ -90,11 +90,21 @@ impl Config {
90 } 90 }
91 } 91 }
92 92
93 fn sck_pull_mode(&self) -> Pull { 93 #[cfg(gpio_v1)]
94 match self.mode.polarity { 94 fn sck_af(&self) -> AfType {
95 Polarity::IdleLow => Pull::Down, 95 AfType::output(OutputType::PushPull, Speed::VeryHigh)
96 Polarity::IdleHigh => Pull::Up, 96 }
97 } 97
98 #[cfg(gpio_v2)]
99 fn sck_af(&self) -> AfType {
100 AfType::output_pull(
101 OutputType::PushPull,
102 Speed::VeryHigh,
103 match self.mode.polarity {
104 Polarity::IdleLow => Pull::Down,
105 Polarity::IdleHigh => Pull::Up,
106 },
107 )
98 } 108 }
99} 109}
100/// SPI driver. 110/// SPI driver.
@@ -453,9 +463,9 @@ impl<'d> Spi<'d, Blocking> {
453 ) -> Self { 463 ) -> Self {
454 Self::new_inner( 464 Self::new_inner(
455 peri, 465 peri,
456 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 466 new_pin!(sck, config.sck_af()),
457 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 467 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
458 new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), 468 new_pin!(miso, AfType::input(config.miso_pull)),
459 None, 469 None,
460 None, 470 None,
461 config, 471 config,
@@ -471,9 +481,9 @@ impl<'d> Spi<'d, Blocking> {
471 ) -> Self { 481 ) -> Self {
472 Self::new_inner( 482 Self::new_inner(
473 peri, 483 peri,
474 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 484 new_pin!(sck, config.sck_af()),
475 None, 485 None,
476 new_pin!(miso, AFType::Input, Speed::VeryHigh, config.miso_pull), 486 new_pin!(miso, AfType::input(config.miso_pull)),
477 None, 487 None,
478 None, 488 None,
479 config, 489 config,
@@ -489,8 +499,8 @@ impl<'d> Spi<'d, Blocking> {
489 ) -> Self { 499 ) -> Self {
490 Self::new_inner( 500 Self::new_inner(
491 peri, 501 peri,
492 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 502 new_pin!(sck, config.sck_af()),
493 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 503 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
494 None, 504 None,
495 None, 505 None,
496 None, 506 None,
@@ -509,7 +519,7 @@ impl<'d> Spi<'d, Blocking> {
509 Self::new_inner( 519 Self::new_inner(
510 peri, 520 peri,
511 None, 521 None,
512 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 522 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
513 None, 523 None,
514 None, 524 None,
515 None, 525 None,
@@ -531,9 +541,9 @@ impl<'d> Spi<'d, Async> {
531 ) -> Self { 541 ) -> Self {
532 Self::new_inner( 542 Self::new_inner(
533 peri, 543 peri,
534 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 544 new_pin!(sck, config.sck_af()),
535 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 545 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
536 new_pin!(miso, AFType::Input, Speed::VeryHigh), 546 new_pin!(miso, AfType::input(config.miso_pull)),
537 new_dma!(tx_dma), 547 new_dma!(tx_dma),
538 new_dma!(rx_dma), 548 new_dma!(rx_dma),
539 config, 549 config,
@@ -551,9 +561,9 @@ impl<'d> Spi<'d, Async> {
551 ) -> Self { 561 ) -> Self {
552 Self::new_inner( 562 Self::new_inner(
553 peri, 563 peri,
554 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 564 new_pin!(sck, config.sck_af()),
555 None, 565 None,
556 new_pin!(miso, AFType::Input, Speed::VeryHigh), 566 new_pin!(miso, AfType::input(config.miso_pull)),
557 #[cfg(any(spi_v1, spi_f1, spi_v2))] 567 #[cfg(any(spi_v1, spi_f1, spi_v2))]
558 new_dma!(tx_dma), 568 new_dma!(tx_dma),
559 #[cfg(any(spi_v3, spi_v4, spi_v5))] 569 #[cfg(any(spi_v3, spi_v4, spi_v5))]
@@ -573,8 +583,8 @@ impl<'d> Spi<'d, Async> {
573 ) -> Self { 583 ) -> Self {
574 Self::new_inner( 584 Self::new_inner(
575 peri, 585 peri,
576 new_pin!(sck, AFType::OutputPushPull, Speed::VeryHigh, config.sck_pull_mode()), 586 new_pin!(sck, config.sck_af()),
577 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 587 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
578 None, 588 None,
579 new_dma!(tx_dma), 589 new_dma!(tx_dma),
580 None, 590 None,
@@ -594,7 +604,7 @@ impl<'d> Spi<'d, Async> {
594 Self::new_inner( 604 Self::new_inner(
595 peri, 605 peri,
596 None, 606 None,
597 new_pin!(mosi, AFType::OutputPushPull, Speed::VeryHigh), 607 new_pin!(mosi, AfType::output(OutputType::PushPull, Speed::VeryHigh)),
598 None, 608 None,
599 new_dma!(tx_dma), 609 new_dma!(tx_dma),
600 None, 610 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 {
32 into_ref!(pin); 32 into_ref!(pin);
33 critical_section::with(|_| { 33 critical_section::with(|_| {
34 pin.set_low(); 34 pin.set_low();
35 pin.set_as_af(pin.af_num(), output_type.into()); 35 pin.set_as_af(
36 #[cfg(gpio_v2)] 36 pin.af_num(),
37 pin.set_speed(crate::gpio::Speed::VeryHigh); 37 crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh),
38 );
38 }); 39 });
39 ComplementaryPwmPin { 40 ComplementaryPwmPin {
40 _pin: pin.map_into(), 41 _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::{
12 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, 12 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin,
13 GeneralInstance4Channel, 13 GeneralInstance4Channel,
14}; 14};
15use crate::gpio::{AFType, AnyPin, Pull}; 15use crate::gpio::{AfType, AnyPin, Pull};
16use crate::interrupt::typelevel::{Binding, Interrupt}; 16use crate::interrupt::typelevel::{Binding, Interrupt};
17use crate::time::Hertz; 17use crate::time::Hertz;
18use crate::Peripheral; 18use crate::Peripheral;
@@ -38,11 +38,9 @@ macro_rules! channel_impl {
38 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 38 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
39 impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { 39 impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> {
40 #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] 40 #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")]
41 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull_type: Pull) -> Self { 41 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull: Pull) -> Self {
42 into_ref!(pin); 42 into_ref!(pin);
43 43 pin.set_as_af(pin.af_num(), AfType::input(pull));
44 pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type);
45
46 CapturePin { 44 CapturePin {
47 _pin: pin.map_into(), 45 _pin: pin.map_into(),
48 phantom: PhantomData, 46 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;
4 4
5use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; 5use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource};
6use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 6use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel};
7use crate::gpio::{AFType, Pull}; 7use crate::gpio::{AfType, Pull};
8use crate::time::Hertz; 8use crate::time::Hertz;
9use crate::Peripheral; 9use crate::Peripheral;
10 10
@@ -19,12 +19,12 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
19 pub fn new( 19 pub fn new(
20 tim: impl Peripheral<P = T> + 'd, 20 tim: impl Peripheral<P = T> + 'd,
21 pin: impl Peripheral<P = impl Channel1Pin<T>> + 'd, 21 pin: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
22 pull_type: Pull, 22 pull: Pull,
23 freq: Hertz, 23 freq: Hertz,
24 ) -> Self { 24 ) -> Self {
25 into_ref!(pin); 25 into_ref!(pin);
26 26
27 pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); 27 pin.set_as_af(pin.af_num(), AfType::input(pull));
28 28
29 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) 29 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2)
30 } 30 }
@@ -33,12 +33,12 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
33 pub fn new_alt( 33 pub fn new_alt(
34 tim: impl Peripheral<P = T> + 'd, 34 tim: impl Peripheral<P = T> + 'd,
35 pin: impl Peripheral<P = impl Channel2Pin<T>> + 'd, 35 pin: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
36 pull_type: Pull, 36 pull: Pull,
37 freq: Hertz, 37 freq: Hertz,
38 ) -> Self { 38 ) -> Self {
39 into_ref!(pin); 39 into_ref!(pin);
40 40
41 pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); 41 pin.set_as_af(pin.af_num(), AfType::input(pull));
42 42
43 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) 43 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1)
44 } 44 }
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;
7 7
8use super::low_level::Timer; 8use super::low_level::Timer;
9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel};
10use crate::gpio::{AFType, AnyPin}; 10use crate::gpio::{AfType, AnyPin, Pull};
11use crate::Peripheral; 11use crate::Peripheral;
12 12
13/// Counting direction 13/// Counting direction
@@ -37,9 +37,7 @@ macro_rules! channel_impl {
37 into_ref!(pin); 37 into_ref!(pin);
38 critical_section::with(|_| { 38 critical_section::with(|_| {
39 pin.set_low(); 39 pin.set_low();
40 pin.set_as_af(pin.af_num(), AFType::Input); 40 pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
41 #[cfg(gpio_v2)]
42 pin.set_speed(crate::gpio::Speed::VeryHigh);
43 }); 41 });
44 QeiPin { 42 QeiPin {
45 _pin: pin.map_into(), 43 _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};
6 6
7use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; 7use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
8use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel}; 8use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel};
9use crate::gpio::{AnyPin, OutputType}; 9use crate::gpio::{AfType, AnyPin, OutputType, Speed};
10use crate::time::Hertz; 10use crate::time::Hertz;
11use crate::Peripheral; 11use crate::Peripheral;
12 12
@@ -35,9 +35,7 @@ macro_rules! channel_impl {
35 into_ref!(pin); 35 into_ref!(pin);
36 critical_section::with(|_| { 36 critical_section::with(|_| {
37 pin.set_low(); 37 pin.set_low();
38 pin.set_as_af(pin.af_num(), output_type.into()); 38 pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh));
39 #[cfg(gpio_v2)]
40 pin.set_speed(crate::gpio::Speed::VeryHigh);
41 }); 39 });
42 PwmPin { 40 PwmPin {
43 _pin: pin.map_into(), 41 _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;
70use embassy_hal_internal::{into_ref, PeripheralRef}; 70use embassy_hal_internal::{into_ref, PeripheralRef};
71pub use enums::*; 71pub use enums::*;
72 72
73use crate::gpio::{AFType, AnyPin}; 73use crate::gpio::{AfType, AnyPin, OutputType, Speed};
74use crate::pac::tsc::Tsc as Regs; 74use crate::pac::tsc::Tsc as Regs;
75use crate::rcc::{self, RccPeripheral}; 75use crate::rcc::{self, RccPeripheral};
76use crate::{peripherals, Peripheral}; 76use crate::{peripherals, Peripheral};
@@ -371,11 +371,14 @@ macro_rules! group_impl {
371 pin.set_low(); 371 pin.set_low();
372 pin.set_as_af( 372 pin.set_as_af(
373 pin.af_num(), 373 pin.af_num(),
374 match role { 374 AfType::output(
375 PinType::Channel => AFType::OutputPushPull, 375 match role {
376 PinType::Sample => AFType::OutputOpenDrain, 376 PinType::Channel => OutputType::PushPull,
377 PinType::Shield => AFType::OutputPushPull, 377 PinType::Sample => OutputType::OpenDrain,
378 }, 378 PinType::Shield => OutputType::PushPull,
379 },
380 Speed::VeryHigh,
381 ),
379 ); 382 );
380 self.d1 = Some(TscPin { 383 self.d1 = Some(TscPin {
381 _pin: pin.map_into(), 384 _pin: pin.map_into(),
@@ -392,11 +395,14 @@ macro_rules! group_impl {
392 pin.set_low(); 395 pin.set_low();
393 pin.set_as_af( 396 pin.set_as_af(
394 pin.af_num(), 397 pin.af_num(),
395 match role { 398 AfType::output(
396 PinType::Channel => AFType::OutputPushPull, 399 match role {
397 PinType::Sample => AFType::OutputOpenDrain, 400 PinType::Channel => OutputType::PushPull,
398 PinType::Shield => AFType::OutputPushPull, 401 PinType::Sample => OutputType::OpenDrain,
399 }, 402 PinType::Shield => OutputType::PushPull,
403 },
404 Speed::VeryHigh,
405 ),
400 ); 406 );
401 self.d2 = Some(TscPin { 407 self.d2 = Some(TscPin {
402 _pin: pin.map_into(), 408 _pin: pin.map_into(),
@@ -413,11 +419,14 @@ macro_rules! group_impl {
413 pin.set_low(); 419 pin.set_low();
414 pin.set_as_af( 420 pin.set_as_af(
415 pin.af_num(), 421 pin.af_num(),
416 match role { 422 AfType::output(
417 PinType::Channel => AFType::OutputPushPull, 423 match role {
418 PinType::Sample => AFType::OutputOpenDrain, 424 PinType::Channel => OutputType::PushPull,
419 PinType::Shield => AFType::OutputPushPull, 425 PinType::Sample => OutputType::OpenDrain,
420 }, 426 PinType::Shield => OutputType::PushPull,
427 },
428 Speed::VeryHigh,
429 ),
421 ); 430 );
422 self.d3 = Some(TscPin { 431 self.d3 = Some(TscPin {
423 _pin: pin.map_into(), 432 _pin: pin.map_into(),
@@ -434,11 +443,14 @@ macro_rules! group_impl {
434 pin.set_low(); 443 pin.set_low();
435 pin.set_as_af( 444 pin.set_as_af(
436 pin.af_num(), 445 pin.af_num(),
437 match role { 446 AfType::output(
438 PinType::Channel => AFType::OutputPushPull, 447 match role {
439 PinType::Sample => AFType::OutputOpenDrain, 448 PinType::Channel => OutputType::PushPull,
440 PinType::Shield => AFType::OutputPushPull, 449 PinType::Sample => OutputType::OpenDrain,
441 }, 450 PinType::Shield => OutputType::PushPull,
451 },
452 Speed::VeryHigh,
453 ),
442 ); 454 );
443 self.d4 = Some(TscPin { 455 self.d4 = Some(TscPin {
444 _pin: pin.map_into(), 456 _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::{
15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, 15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance,
16 Regs, RtsPin, RxPin, TxPin, 16 Regs, RtsPin, RxPin, TxPin,
17}; 17};
18use crate::gpio::{AFType, AnyPin, SealedPin as _}; 18use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
19use crate::interrupt::{self, InterruptExt}; 19use crate::interrupt::{self, InterruptExt};
20use crate::time::Hertz; 20use crate::time::Hertz;
21 21
@@ -210,8 +210,8 @@ impl<'d> BufferedUart<'d> {
210 ) -> Result<Self, ConfigError> { 210 ) -> Result<Self, ConfigError> {
211 Self::new_inner( 211 Self::new_inner(
212 peri, 212 peri,
213 new_pin!(rx, AFType::Input), 213 new_pin!(rx, AfType::input(Pull::None)),
214 new_pin!(tx, AFType::OutputPushPull), 214 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
215 None, 215 None,
216 None, 216 None,
217 None, 217 None,
@@ -235,10 +235,10 @@ impl<'d> BufferedUart<'d> {
235 ) -> Result<Self, ConfigError> { 235 ) -> Result<Self, ConfigError> {
236 Self::new_inner( 236 Self::new_inner(
237 peri, 237 peri,
238 new_pin!(rx, AFType::Input), 238 new_pin!(rx, AfType::input(Pull::None)),
239 new_pin!(tx, AFType::OutputPushPull), 239 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
240 new_pin!(rts, AFType::OutputPushPull), 240 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)),
241 new_pin!(cts, AFType::Input), 241 new_pin!(cts, AfType::input(Pull::None)),
242 None, 242 None,
243 tx_buffer, 243 tx_buffer,
244 rx_buffer, 244 rx_buffer,
@@ -260,11 +260,11 @@ impl<'d> BufferedUart<'d> {
260 ) -> Result<Self, ConfigError> { 260 ) -> Result<Self, ConfigError> {
261 Self::new_inner( 261 Self::new_inner(
262 peri, 262 peri,
263 new_pin!(rx, AFType::Input), 263 new_pin!(rx, AfType::input(Pull::None)),
264 new_pin!(tx, AFType::OutputPushPull), 264 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
265 None, 265 None,
266 None, 266 None,
267 new_pin!(de, AFType::OutputPushPull), 267 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)),
268 tx_buffer, 268 tx_buffer,
269 rx_buffer, 269 rx_buffer,
270 config, 270 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;
14use futures_util::future::{select, Either}; 14use futures_util::future::{select, Either};
15 15
16use crate::dma::ChannelAndRequest; 16use crate::dma::ChannelAndRequest;
17use crate::gpio::{AFType, AnyPin, SealedPin as _}; 17use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
18use crate::interrupt::typelevel::Interrupt as _; 18use crate::interrupt::typelevel::Interrupt as _;
19use crate::interrupt::{self, Interrupt, InterruptExt}; 19use crate::interrupt::{self, Interrupt, InterruptExt};
20use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
@@ -159,11 +159,11 @@ pub struct Config {
159 #[cfg(any(usart_v3, usart_v4))] 159 #[cfg(any(usart_v3, usart_v4))]
160 pub swap_rx_tx: bool, 160 pub swap_rx_tx: bool,
161 161
162 /// Set this to true to invert TX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). 162 /// Set this to true to invert TX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle).
163 #[cfg(any(usart_v3, usart_v4))] 163 #[cfg(any(usart_v3, usart_v4))]
164 pub invert_tx: bool, 164 pub invert_tx: bool,
165 165
166 /// Set this to true to invert RX pin signal values (V<sub>DD</sub> =0/mark, Gnd = 1/idle). 166 /// Set this to true to invert RX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle).
167 #[cfg(any(usart_v3, usart_v4))] 167 #[cfg(any(usart_v3, usart_v4))]
168 pub invert_rx: bool, 168 pub invert_rx: bool,
169 169
@@ -172,19 +172,20 @@ pub struct Config {
172} 172}
173 173
174impl Config { 174impl Config {
175 fn tx_af(&self) -> AFType { 175 fn tx_af(&self) -> AfType {
176 #[cfg(any(usart_v3, usart_v4))] 176 #[cfg(any(usart_v3, usart_v4))]
177 if self.swap_rx_tx { 177 if self.swap_rx_tx {
178 return AFType::Input; 178 return AfType::input(Pull::None);
179 }; 179 };
180 AFType::OutputPushPull 180 AfType::output(OutputType::PushPull, Speed::Medium)
181 } 181 }
182 fn rx_af(&self) -> AFType { 182
183 fn rx_af(&self) -> AfType {
183 #[cfg(any(usart_v3, usart_v4))] 184 #[cfg(any(usart_v3, usart_v4))]
184 if self.swap_rx_tx { 185 if self.swap_rx_tx {
185 return AFType::OutputPushPull; 186 return AfType::output(OutputType::PushPull, Speed::Medium);
186 }; 187 };
187 AFType::Input 188 AfType::input(Pull::None)
188 } 189 }
189} 190}
190 191
@@ -342,7 +343,7 @@ impl<'d> UartTx<'d, Async> {
342 ) -> Result<Self, ConfigError> { 343 ) -> Result<Self, ConfigError> {
343 Self::new_inner( 344 Self::new_inner(
344 peri, 345 peri,
345 new_pin!(tx, AFType::OutputPushPull), 346 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
346 None, 347 None,
347 new_dma!(tx_dma), 348 new_dma!(tx_dma),
348 config, 349 config,
@@ -359,8 +360,8 @@ impl<'d> UartTx<'d, Async> {
359 ) -> Result<Self, ConfigError> { 360 ) -> Result<Self, ConfigError> {
360 Self::new_inner( 361 Self::new_inner(
361 peri, 362 peri,
362 new_pin!(tx, AFType::OutputPushPull), 363 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
363 new_pin!(cts, AFType::Input), 364 new_pin!(cts, AfType::input(Pull::None)),
364 new_dma!(tx_dma), 365 new_dma!(tx_dma),
365 config, 366 config,
366 ) 367 )
@@ -401,7 +402,13 @@ impl<'d> UartTx<'d, Blocking> {
401 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 402 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
402 config: Config, 403 config: Config,
403 ) -> Result<Self, ConfigError> { 404 ) -> Result<Self, ConfigError> {
404 Self::new_inner(peri, new_pin!(tx, AFType::OutputPushPull), None, None, config) 405 Self::new_inner(
406 peri,
407 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
408 None,
409 None,
410 config,
411 )
405 } 412 }
406 413
407 /// Create a new blocking tx-only UART with a clear-to-send pin 414 /// Create a new blocking tx-only UART with a clear-to-send pin
@@ -413,8 +420,8 @@ impl<'d> UartTx<'d, Blocking> {
413 ) -> Result<Self, ConfigError> { 420 ) -> Result<Self, ConfigError> {
414 Self::new_inner( 421 Self::new_inner(
415 peri, 422 peri,
416 new_pin!(tx, AFType::OutputPushPull), 423 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
417 new_pin!(cts, AFType::Input), 424 new_pin!(cts, AfType::input(Pull::None)),
418 None, 425 None,
419 config, 426 config,
420 ) 427 )
@@ -508,7 +515,13 @@ impl<'d> UartRx<'d, Async> {
508 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 515 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
509 config: Config, 516 config: Config,
510 ) -> Result<Self, ConfigError> { 517 ) -> Result<Self, ConfigError> {
511 Self::new_inner(peri, new_pin!(rx, AFType::Input), None, new_dma!(rx_dma), config) 518 Self::new_inner(
519 peri,
520 new_pin!(rx, AfType::input(Pull::None)),
521 None,
522 new_dma!(rx_dma),
523 config,
524 )
512 } 525 }
513 526
514 /// Create a new rx-only UART with a request-to-send pin 527 /// Create a new rx-only UART with a request-to-send pin
@@ -522,8 +535,8 @@ impl<'d> UartRx<'d, Async> {
522 ) -> Result<Self, ConfigError> { 535 ) -> Result<Self, ConfigError> {
523 Self::new_inner( 536 Self::new_inner(
524 peri, 537 peri,
525 new_pin!(rx, AFType::Input), 538 new_pin!(rx, AfType::input(Pull::None)),
526 new_pin!(rts, AFType::OutputPushPull), 539 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)),
527 new_dma!(rx_dma), 540 new_dma!(rx_dma),
528 config, 541 config,
529 ) 542 )
@@ -751,7 +764,7 @@ impl<'d> UartRx<'d, Blocking> {
751 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 764 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
752 config: Config, 765 config: Config,
753 ) -> Result<Self, ConfigError> { 766 ) -> Result<Self, ConfigError> {
754 Self::new_inner(peri, new_pin!(rx, AFType::Input), None, None, config) 767 Self::new_inner(peri, new_pin!(rx, AfType::input(Pull::None)), None, None, config)
755 } 768 }
756 769
757 /// Create a new rx-only UART with a request-to-send pin 770 /// Create a new rx-only UART with a request-to-send pin
@@ -763,8 +776,8 @@ impl<'d> UartRx<'d, Blocking> {
763 ) -> Result<Self, ConfigError> { 776 ) -> Result<Self, ConfigError> {
764 Self::new_inner( 777 Self::new_inner(
765 peri, 778 peri,
766 new_pin!(rx, AFType::Input), 779 new_pin!(rx, AfType::input(Pull::None)),
767 new_pin!(rts, AFType::OutputPushPull), 780 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)),
768 None, 781 None,
769 config, 782 config,
770 ) 783 )
@@ -968,8 +981,8 @@ impl<'d> Uart<'d, Async> {
968 peri, 981 peri,
969 new_pin!(rx, config.rx_af()), 982 new_pin!(rx, config.rx_af()),
970 new_pin!(tx, config.tx_af()), 983 new_pin!(tx, config.tx_af()),
971 new_pin!(rts, AFType::OutputPushPull), 984 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)),
972 new_pin!(cts, AFType::Input), 985 new_pin!(cts, AfType::input(Pull::None)),
973 None, 986 None,
974 new_dma!(tx_dma), 987 new_dma!(tx_dma),
975 new_dma!(rx_dma), 988 new_dma!(rx_dma),
@@ -995,7 +1008,7 @@ impl<'d> Uart<'d, Async> {
995 new_pin!(tx, config.tx_af()), 1008 new_pin!(tx, config.tx_af()),
996 None, 1009 None,
997 None, 1010 None,
998 new_pin!(de, AFType::OutputPushPull), 1011 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)),
999 new_dma!(tx_dma), 1012 new_dma!(tx_dma),
1000 new_dma!(rx_dma), 1013 new_dma!(rx_dma),
1001 config, 1014 config,
@@ -1030,7 +1043,7 @@ impl<'d> Uart<'d, Async> {
1030 Self::new_inner( 1043 Self::new_inner(
1031 peri, 1044 peri,
1032 None, 1045 None,
1033 new_pin!(tx, AFType::OutputPushPull), 1046 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
1034 None, 1047 None,
1035 None, 1048 None,
1036 None, 1049 None,
@@ -1066,7 +1079,7 @@ impl<'d> Uart<'d, Async> {
1066 peri, 1079 peri,
1067 None, 1080 None,
1068 None, 1081 None,
1069 new_pin!(rx, AFType::OutputPushPull), 1082 new_pin!(rx, AfType::output(OutputType::PushPull, Speed::Medium)),
1070 None, 1083 None,
1071 None, 1084 None,
1072 new_dma!(tx_dma), 1085 new_dma!(tx_dma),
@@ -1125,8 +1138,8 @@ impl<'d> Uart<'d, Blocking> {
1125 peri, 1138 peri,
1126 new_pin!(rx, config.rx_af()), 1139 new_pin!(rx, config.rx_af()),
1127 new_pin!(tx, config.tx_af()), 1140 new_pin!(tx, config.tx_af()),
1128 new_pin!(rts, AFType::OutputPushPull), 1141 new_pin!(rts, AfType::output(OutputType::PushPull, Speed::Medium)),
1129 new_pin!(cts, AFType::Input), 1142 new_pin!(cts, AfType::input(Pull::None)),
1130 None, 1143 None,
1131 None, 1144 None,
1132 None, 1145 None,
@@ -1149,7 +1162,7 @@ impl<'d> Uart<'d, Blocking> {
1149 new_pin!(tx, config.tx_af()), 1162 new_pin!(tx, config.tx_af()),
1150 None, 1163 None,
1151 None, 1164 None,
1152 new_pin!(de, AFType::OutputPushPull), 1165 new_pin!(de, AfType::output(OutputType::PushPull, Speed::Medium)),
1153 None, 1166 None,
1154 None, 1167 None,
1155 config, 1168 config,
@@ -1181,7 +1194,7 @@ impl<'d> Uart<'d, Blocking> {
1181 Self::new_inner( 1194 Self::new_inner(
1182 peri, 1195 peri,
1183 None, 1196 None,
1184 new_pin!(tx, AFType::OutputPushPull), 1197 new_pin!(tx, AfType::output(OutputType::PushPull, Speed::Medium)),
1185 None, 1198 None,
1186 None, 1199 None,
1187 None, 1200 None,
@@ -1214,7 +1227,7 @@ impl<'d> Uart<'d, Blocking> {
1214 peri, 1227 peri,
1215 None, 1228 None,
1216 None, 1229 None,
1217 new_pin!(rx, AFType::OutputPushPull), 1230 new_pin!(rx, AfType::output(OutputType::PushPull, Speed::Medium)),
1218 None, 1231 None,
1219 None, 1232 None,
1220 None, 1233 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::{
10 PhyType, State, 10 PhyType, State,
11}; 11};
12 12
13use crate::gpio::AFType; 13use crate::gpio::{AfType, OutputType, Speed};
14use crate::interrupt; 14use crate::interrupt;
15use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
16use crate::rcc::{self, RccPeripheral}; 16use crate::rcc::{self, RccPeripheral};
@@ -39,9 +39,7 @@ macro_rules! config_ulpi_pins {
39 into_ref!($($pin),*); 39 into_ref!($($pin),*);
40 critical_section::with(|_| { 40 critical_section::with(|_| {
41 $( 41 $(
42 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 42 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
43 #[cfg(gpio_v2)]
44 $pin.set_speed(crate::gpio::Speed::VeryHigh);
45 )* 43 )*
46 }) 44 })
47 }; 45 };
@@ -77,8 +75,8 @@ impl<'d, T: Instance> Driver<'d, T> {
77 ) -> Self { 75 ) -> Self {
78 into_ref!(dp, dm); 76 into_ref!(dp, dm);
79 77
80 dp.set_as_af(dp.af_num(), AFType::OutputPushPull); 78 dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
81 dm.set_as_af(dm.af_num(), AFType::OutputPushPull); 79 dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
82 80
83 let regs = T::regs(); 81 let regs = T::regs();
84 82
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> {
277 277
278 #[cfg(not(stm32l1))] 278 #[cfg(not(stm32l1))]
279 { 279 {
280 dp.set_as_af(dp.af_num(), crate::gpio::AFType::OutputPushPull); 280 use crate::gpio::{AfType, OutputType, Speed};
281 dm.set_as_af(dm.af_num(), crate::gpio::AFType::OutputPushPull); 281 dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
282 dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
282 } 283 }
283 #[cfg(stm32l1)] 284 #[cfg(stm32l1)]
284 let _ = (dp, dm); // suppress "unused" warnings. 285 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 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::gpio::{AFType, Flex, Pull, Speed}; 6use embassy_stm32::gpio::{AfType, Flex, OutputType, Speed};
7use embassy_stm32::time::{khz, Hertz}; 7use embassy_stm32::time::{khz, Hertz};
8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; 8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; 9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
@@ -83,10 +83,10 @@ impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
83 let mut ch2 = Flex::new(ch2); 83 let mut ch2 = Flex::new(ch2);
84 let mut ch3 = Flex::new(ch3); 84 let mut ch3 = Flex::new(ch3);
85 let mut ch4 = Flex::new(ch4); 85 let mut ch4 = Flex::new(ch4);
86 ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); 86 ch1.set_as_af_unchecked(af1, AfType::output(OutputType::PushPull, Speed::VeryHigh));
87 ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); 87 ch2.set_as_af_unchecked(af2, AfType::output(OutputType::PushPull, Speed::VeryHigh));
88 ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); 88 ch3.set_as_af_unchecked(af3, AfType::output(OutputType::PushPull, Speed::VeryHigh));
89 ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); 89 ch4.set_as_af_unchecked(af4, AfType::output(OutputType::PushPull, Speed::VeryHigh));
90 90
91 let mut this = Self { 91 let mut this = Self {
92 tim: LLTimer::new(tim), 92 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) {
112 let b = Input::new(&mut b, Pull::Down); 112 let b = Input::new(&mut b, Pull::Down);
113 // no pull, the status is undefined 113 // no pull, the status is undefined
114 114
115 let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low, Pull::None); 115 let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low);
116 delay(); 116 delay();
117 assert!(b.is_low()); 117 assert!(b.is_low());
118 a.set_high(); // High-Z output 118 a.set_high(); // High-Z output
@@ -203,7 +203,7 @@ async fn main(_spawner: Spawner) {
203 203
204 let mut a = Flex::new(&mut a); 204 let mut a = Flex::new(&mut a);
205 a.set_low(); 205 a.set_low();
206 a.set_as_input_output(Speed::Low, Pull::None); 206 a.set_as_input_output(Speed::Low);
207 delay(); 207 delay();
208 assert!(b.is_low()); 208 assert!(b.is_low());
209 a.set_high(); // High-Z output 209 a.set_high(); // High-Z output