aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-02-10 21:38:03 +0100
committerDario Nieuwenhuis <[email protected]>2022-02-10 21:38:03 +0100
commitb99ab3d5d9d8fdee135956dcbc2111b00abd1d72 (patch)
tree53f3723e24ba49b98f0a792aa9835141ef56729e /embassy-stm32/src
parent9d682aa1fae81d9bb56bb41304828144b9a0d4a7 (diff)
stm32: Add standard crate-wide macros for pin/dma traits, switch all drivers to use them.
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/can/bxcan.rs42
-rw-r--r--embassy-stm32/src/dcmi.rs435
-rw-r--r--embassy-stm32/src/dma/mod.rs5
-rw-r--r--embassy-stm32/src/eth/mod.rs55
-rw-r--r--embassy-stm32/src/eth/v1c/mod.rs205
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs199
-rw-r--r--embassy-stm32/src/fmc/mod.rs52
-rw-r--r--embassy-stm32/src/fmc/pins.rs676
-rw-r--r--embassy-stm32/src/gpio.rs7
-rw-r--r--embassy-stm32/src/i2c/mod.rs91
-rw-r--r--embassy-stm32/src/lib.rs1
-rw-r--r--embassy-stm32/src/pwm/mod.rs85
-rw-r--r--embassy-stm32/src/pwm/pins.rs126
-rw-r--r--embassy-stm32/src/pwm/simple_pwm.rs52
-rw-r--r--embassy-stm32/src/rcc/h7.rs44
-rw-r--r--embassy-stm32/src/sdmmc/v2.rs101
-rw-r--r--embassy-stm32/src/spi/mod.rs114
-rw-r--r--embassy-stm32/src/spi/v1.rs10
-rw-r--r--embassy-stm32/src/spi/v2.rs10
-rw-r--r--embassy-stm32/src/spi/v3.rs10
-rw-r--r--embassy-stm32/src/traits.rs53
-rw-r--r--embassy-stm32/src/usart/mod.rs153
-rw-r--r--embassy-stm32/src/usb_otg.rs157
23 files changed, 904 insertions, 1779 deletions
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index 3c8c27308..987ccad54 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -4,10 +4,7 @@ use core::ops::{Deref, DerefMut};
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
5use embassy_hal_common::unborrow; 5use embassy_hal_common::unborrow;
6 6
7use crate::gpio::{ 7use crate::gpio::sealed::AFType;
8 sealed::AFType::{OutputOpenDrain, OutputPushPull},
9 Pin,
10};
11use crate::{peripherals, rcc::RccPeripheral}; 8use crate::{peripherals, rcc::RccPeripheral};
12 9
13pub use bxcan::*; 10pub use bxcan::*;
@@ -26,8 +23,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
26 unborrow!(peri, rx, tx); 23 unborrow!(peri, rx, tx);
27 24
28 unsafe { 25 unsafe {
29 rx.set_as_af(rx.af_num(), OutputOpenDrain); 26 rx.set_as_af(rx.af_num(), AFType::OutputOpenDrain);
30 tx.set_as_af(tx.af_num(), OutputPushPull); 27 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
31 } 28 }
32 29
33 T::enable(); 30 T::enable();
@@ -66,24 +63,12 @@ impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
66} 63}
67 64
68pub(crate) mod sealed { 65pub(crate) mod sealed {
69 use super::*;
70
71 pub trait Instance { 66 pub trait Instance {
72 fn regs() -> &'static crate::pac::can::Can; 67 fn regs() -> &'static crate::pac::can::Can;
73 } 68 }
74
75 pub trait RxPin<T: Instance>: Pin {
76 fn af_num(&self) -> u8;
77 }
78
79 pub trait TxPin<T: Instance>: Pin {
80 fn af_num(&self) -> u8;
81 }
82} 69}
83 70
84pub trait Instance: sealed::Instance + RccPeripheral {} 71pub trait Instance: sealed::Instance + RccPeripheral {}
85pub trait RxPin<T: Instance>: sealed::RxPin<T> {}
86pub trait TxPin<T: Instance>: sealed::TxPin<T> {}
87 72
88crate::pac::peripherals!( 73crate::pac::peripherals!(
89 (can, $inst:ident) => { 74 (can, $inst:ident) => {
@@ -125,29 +110,20 @@ crate::pac::peripherals!(
125 }; 110 };
126); 111);
127 112
128macro_rules! impl_pin { 113pin_trait!(RxPin, Instance);
129 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => { 114pin_trait!(TxPin, Instance);
130 impl $signal<peripherals::$inst> for peripherals::$pin {}
131
132 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
133 fn af_num(&self) -> u8 {
134 $af
135 }
136 }
137 };
138}
139 115
140crate::pac::peripheral_pins!( 116crate::pac::peripheral_pins!(
141 ($inst:ident, can, CAN, $pin:ident, TX, $af:expr) => { 117 ($inst:ident, can, CAN, $pin:ident, TX, $af:expr) => {
142 impl_pin!($inst, $pin, TxPin, $af); 118 pin_trait_impl!(TxPin, $inst, $pin, $af);
143 }; 119 };
144 ($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => { 120 ($inst:ident, can, CAN, $pin:ident, RX, $af:expr) => {
145 impl_pin!($inst, $pin, RxPin, $af); 121 pin_trait_impl!(RxPin, $inst, $pin, $af);
146 }; 122 };
147 ($inst:ident, can, CAN, $pin:ident, TX) => { 123 ($inst:ident, can, CAN, $pin:ident, TX) => {
148 impl_pin!($inst, $pin, TxPin, 0); 124 pin_trait_impl!(TxPin, $inst, $pin, 0);
149 }; 125 };
150 ($inst:ident, can, CAN, $pin:ident, RX) => { 126 ($inst:ident, can, CAN, $pin:ident, RX) => {
151 impl_pin!($inst, $pin, RxPin, 0); 127 pin_trait_impl!(RxPin, $inst, $pin, 0);
152 }; 128 };
153); 129);
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index cbfa5f098..1fa19e87a 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -1,22 +1,13 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::task::Poll; 2use core::task::Poll;
3 3
4use crate::gpio::sealed::Pin as __GpioPin;
5use crate::gpio::Pin as GpioPin;
6use embassy::interrupt::{Interrupt, InterruptExt}; 4use embassy::interrupt::{Interrupt, InterruptExt};
7use embassy::util::Unborrow; 5use embassy::util::Unborrow;
8use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
9use embassy_hal_common::unborrow; 7use embassy_hal_common::unborrow;
10use futures::future::poll_fn; 8use futures::future::poll_fn;
11 9
12#[macro_export] 10use crate::gpio::{sealed::AFType, Speed};
13macro_rules! configure {
14 ($($name:ident),*) => {
15 $(
16 unsafe { $name.unborrow() }.configure();
17 )*
18 }
19}
20 11
21/// The level on the VSync pin when the data is not valid on the parallel interface. 12/// The level on the VSync pin when the data is not valid on the parallel interface.
22#[derive(Clone, Copy, PartialEq)] 13#[derive(Clone, Copy, PartialEq)]
@@ -76,7 +67,20 @@ impl Default for Config {
76 } 67 }
77} 68}
78 69
79pub struct Dcmi<'d, T: Instance, Dma: FrameDma> { 70macro_rules! config_pins {
71 ($($pin:ident),*) => {
72 unborrow!($($pin),*);
73 // NOTE(unsafe) Exclusive access to the registers
74 critical_section::with(|_| unsafe {
75 $(
76 $pin.set_as_af($pin.af_num(), AFType::Input);
77 $pin.set_speed(Speed::VeryHigh);
78 )*
79 })
80 };
81}
82
83pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
80 inner: T, 84 inner: T,
81 dma: Dma, 85 dma: Dma,
82 phantom: PhantomData<&'d mut T>, 86 phantom: PhantomData<&'d mut T>,
@@ -85,53 +89,54 @@ pub struct Dcmi<'d, T: Instance, Dma: FrameDma> {
85impl<'d, T, Dma> Dcmi<'d, T, Dma> 89impl<'d, T, Dma> Dcmi<'d, T, Dma>
86where 90where
87 T: Instance, 91 T: Instance,
88 Dma: FrameDma, 92 Dma: FrameDma<T>,
89{ 93{
90 pub fn new_8bit( 94 pub fn new_8bit(
91 peri: impl Unborrow<Target = T> + 'd, 95 peri: impl Unborrow<Target = T> + 'd,
92 dma: impl Unborrow<Target = Dma> + 'd, 96 dma: impl Unborrow<Target = Dma> + 'd,
93 irq: impl Unborrow<Target = T::Interrupt> + 'd, 97 irq: impl Unborrow<Target = T::Interrupt> + 'd,
94 d0: impl Unborrow<Target = impl D0Pin> + 'd, 98 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
95 d1: impl Unborrow<Target = impl D1Pin> + 'd, 99 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
96 d2: impl Unborrow<Target = impl D2Pin> + 'd, 100 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
97 d3: impl Unborrow<Target = impl D3Pin> + 'd, 101 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
98 d4: impl Unborrow<Target = impl D4Pin> + 'd, 102 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
99 d5: impl Unborrow<Target = impl D5Pin> + 'd, 103 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
100 d6: impl Unborrow<Target = impl D6Pin> + 'd, 104 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
101 d7: impl Unborrow<Target = impl D7Pin> + 'd, 105 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
102 v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, 106 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
103 h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, 107 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
104 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 108 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
105 config: Config, 109 config: Config,
106 ) -> Self { 110 ) -> Self {
107 unborrow!(peri, dma, irq); 111 unborrow!(peri, dma, irq);
108 configure!(d0, d1, d2, d3, d4, d5, d6, d7); 112 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
109 configure!(v_sync, h_sync, pixclk); 113 config_pins!(v_sync, h_sync, pixclk);
110 114
111 Self::new_inner(peri, dma, irq, config, false, 0b00) 115 Self::new_inner(peri, dma, irq, config, false, 0b00)
112 } 116 }
117
113 pub fn new_10bit( 118 pub fn new_10bit(
114 peri: impl Unborrow<Target = T> + 'd, 119 peri: impl Unborrow<Target = T> + 'd,
115 dma: impl Unborrow<Target = Dma> + 'd, 120 dma: impl Unborrow<Target = Dma> + 'd,
116 irq: impl Unborrow<Target = T::Interrupt> + 'd, 121 irq: impl Unborrow<Target = T::Interrupt> + 'd,
117 d0: impl Unborrow<Target = impl D0Pin> + 'd, 122 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
118 d1: impl Unborrow<Target = impl D1Pin> + 'd, 123 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
119 d2: impl Unborrow<Target = impl D2Pin> + 'd, 124 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
120 d3: impl Unborrow<Target = impl D3Pin> + 'd, 125 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
121 d4: impl Unborrow<Target = impl D4Pin> + 'd, 126 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
122 d5: impl Unborrow<Target = impl D5Pin> + 'd, 127 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
123 d6: impl Unborrow<Target = impl D6Pin> + 'd, 128 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
124 d7: impl Unborrow<Target = impl D7Pin> + 'd, 129 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
125 d8: impl Unborrow<Target = impl D8Pin> + 'd, 130 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
126 d9: impl Unborrow<Target = impl D9Pin> + 'd, 131 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
127 v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, 132 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
128 h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, 133 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
129 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 134 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
130 config: Config, 135 config: Config,
131 ) -> Self { 136 ) -> Self {
132 unborrow!(peri, dma, irq); 137 unborrow!(peri, dma, irq);
133 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 138 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
134 configure!(v_sync, h_sync, pixclk); 139 config_pins!(v_sync, h_sync, pixclk);
135 140
136 Self::new_inner(peri, dma, irq, config, false, 0b01) 141 Self::new_inner(peri, dma, irq, config, false, 0b01)
137 } 142 }
@@ -140,55 +145,56 @@ where
140 peri: impl Unborrow<Target = T> + 'd, 145 peri: impl Unborrow<Target = T> + 'd,
141 dma: impl Unborrow<Target = Dma> + 'd, 146 dma: impl Unborrow<Target = Dma> + 'd,
142 irq: impl Unborrow<Target = T::Interrupt> + 'd, 147 irq: impl Unborrow<Target = T::Interrupt> + 'd,
143 d0: impl Unborrow<Target = impl D0Pin> + 'd, 148 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
144 d1: impl Unborrow<Target = impl D1Pin> + 'd, 149 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
145 d2: impl Unborrow<Target = impl D2Pin> + 'd, 150 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
146 d3: impl Unborrow<Target = impl D3Pin> + 'd, 151 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
147 d4: impl Unborrow<Target = impl D4Pin> + 'd, 152 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
148 d5: impl Unborrow<Target = impl D5Pin> + 'd, 153 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
149 d6: impl Unborrow<Target = impl D6Pin> + 'd, 154 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
150 d7: impl Unborrow<Target = impl D7Pin> + 'd, 155 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
151 d8: impl Unborrow<Target = impl D8Pin> + 'd, 156 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
152 d9: impl Unborrow<Target = impl D9Pin> + 'd, 157 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
153 d10: impl Unborrow<Target = impl D10Pin> + 'd, 158 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
154 d11: impl Unborrow<Target = impl D11Pin> + 'd, 159 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
155 v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, 160 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
156 h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, 161 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
157 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 162 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
158 config: Config, 163 config: Config,
159 ) -> Self { 164 ) -> Self {
160 unborrow!(peri, dma, irq); 165 unborrow!(peri, dma, irq);
161 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 166 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
162 configure!(v_sync, h_sync, pixclk); 167 config_pins!(v_sync, h_sync, pixclk);
163 168
164 Self::new_inner(peri, dma, irq, config, false, 0b10) 169 Self::new_inner(peri, dma, irq, config, false, 0b10)
165 } 170 }
171
166 pub fn new_14bit( 172 pub fn new_14bit(
167 peri: impl Unborrow<Target = T> + 'd, 173 peri: impl Unborrow<Target = T> + 'd,
168 dma: impl Unborrow<Target = Dma> + 'd, 174 dma: impl Unborrow<Target = Dma> + 'd,
169 irq: impl Unborrow<Target = T::Interrupt> + 'd, 175 irq: impl Unborrow<Target = T::Interrupt> + 'd,
170 d0: impl Unborrow<Target = impl D0Pin> + 'd, 176 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
171 d1: impl Unborrow<Target = impl D1Pin> + 'd, 177 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
172 d2: impl Unborrow<Target = impl D2Pin> + 'd, 178 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
173 d3: impl Unborrow<Target = impl D3Pin> + 'd, 179 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
174 d4: impl Unborrow<Target = impl D4Pin> + 'd, 180 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
175 d5: impl Unborrow<Target = impl D5Pin> + 'd, 181 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
176 d6: impl Unborrow<Target = impl D6Pin> + 'd, 182 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
177 d7: impl Unborrow<Target = impl D7Pin> + 'd, 183 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
178 d8: impl Unborrow<Target = impl D8Pin> + 'd, 184 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
179 d9: impl Unborrow<Target = impl D9Pin> + 'd, 185 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
180 d10: impl Unborrow<Target = impl D10Pin> + 'd, 186 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
181 d11: impl Unborrow<Target = impl D11Pin> + 'd, 187 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
182 d12: impl Unborrow<Target = impl D12Pin> + 'd, 188 d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
183 d13: impl Unborrow<Target = impl D13Pin> + 'd, 189 d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
184 v_sync: impl Unborrow<Target = impl VSyncPin> + 'd, 190 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd,
185 h_sync: impl Unborrow<Target = impl HSyncPin> + 'd, 191 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd,
186 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 192 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
187 config: Config, 193 config: Config,
188 ) -> Self { 194 ) -> Self {
189 unborrow!(peri, dma, irq); 195 unborrow!(peri, dma, irq);
190 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 196 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
191 configure!(v_sync, h_sync, pixclk); 197 config_pins!(v_sync, h_sync, pixclk);
192 198
193 Self::new_inner(peri, dma, irq, config, false, 0b11) 199 Self::new_inner(peri, dma, irq, config, false, 0b11)
194 } 200 }
@@ -197,20 +203,20 @@ where
197 peri: impl Unborrow<Target = T> + 'd, 203 peri: impl Unborrow<Target = T> + 'd,
198 dma: impl Unborrow<Target = Dma> + 'd, 204 dma: impl Unborrow<Target = Dma> + 'd,
199 irq: impl Unborrow<Target = T::Interrupt> + 'd, 205 irq: impl Unborrow<Target = T::Interrupt> + 'd,
200 d0: impl Unborrow<Target = impl D0Pin> + 'd, 206 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
201 d1: impl Unborrow<Target = impl D1Pin> + 'd, 207 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
202 d2: impl Unborrow<Target = impl D2Pin> + 'd, 208 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
203 d3: impl Unborrow<Target = impl D3Pin> + 'd, 209 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
204 d4: impl Unborrow<Target = impl D4Pin> + 'd, 210 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
205 d5: impl Unborrow<Target = impl D5Pin> + 'd, 211 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
206 d6: impl Unborrow<Target = impl D6Pin> + 'd, 212 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
207 d7: impl Unborrow<Target = impl D7Pin> + 'd, 213 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
208 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 214 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
209 config: Config, 215 config: Config,
210 ) -> Self { 216 ) -> Self {
211 unborrow!(peri, dma, irq); 217 unborrow!(peri, dma, irq);
212 configure!(d0, d1, d2, d3, d4, d5, d6, d7); 218 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
213 configure!(pixclk); 219 config_pins!(pixclk);
214 220
215 Self::new_inner(peri, dma, irq, config, true, 0b00) 221 Self::new_inner(peri, dma, irq, config, true, 0b00)
216 } 222 }
@@ -219,22 +225,22 @@ where
219 peri: impl Unborrow<Target = T> + 'd, 225 peri: impl Unborrow<Target = T> + 'd,
220 dma: impl Unborrow<Target = Dma> + 'd, 226 dma: impl Unborrow<Target = Dma> + 'd,
221 irq: impl Unborrow<Target = T::Interrupt> + 'd, 227 irq: impl Unborrow<Target = T::Interrupt> + 'd,
222 d0: impl Unborrow<Target = impl D0Pin> + 'd, 228 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
223 d1: impl Unborrow<Target = impl D1Pin> + 'd, 229 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
224 d2: impl Unborrow<Target = impl D2Pin> + 'd, 230 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
225 d3: impl Unborrow<Target = impl D3Pin> + 'd, 231 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
226 d4: impl Unborrow<Target = impl D4Pin> + 'd, 232 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
227 d5: impl Unborrow<Target = impl D5Pin> + 'd, 233 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
228 d6: impl Unborrow<Target = impl D6Pin> + 'd, 234 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
229 d7: impl Unborrow<Target = impl D7Pin> + 'd, 235 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
230 d8: impl Unborrow<Target = impl D8Pin> + 'd, 236 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
231 d9: impl Unborrow<Target = impl D9Pin> + 'd, 237 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
232 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 238 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
233 config: Config, 239 config: Config,
234 ) -> Self { 240 ) -> Self {
235 unborrow!(peri, dma, irq); 241 unborrow!(peri, dma, irq);
236 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 242 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
237 configure!(pixclk); 243 config_pins!(pixclk);
238 244
239 Self::new_inner(peri, dma, irq, config, true, 0b01) 245 Self::new_inner(peri, dma, irq, config, true, 0b01)
240 } 246 }
@@ -243,51 +249,52 @@ where
243 peri: impl Unborrow<Target = T> + 'd, 249 peri: impl Unborrow<Target = T> + 'd,
244 dma: impl Unborrow<Target = Dma> + 'd, 250 dma: impl Unborrow<Target = Dma> + 'd,
245 irq: impl Unborrow<Target = T::Interrupt> + 'd, 251 irq: impl Unborrow<Target = T::Interrupt> + 'd,
246 d0: impl Unborrow<Target = impl D0Pin> + 'd, 252 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
247 d1: impl Unborrow<Target = impl D1Pin> + 'd, 253 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
248 d2: impl Unborrow<Target = impl D2Pin> + 'd, 254 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
249 d3: impl Unborrow<Target = impl D3Pin> + 'd, 255 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
250 d4: impl Unborrow<Target = impl D4Pin> + 'd, 256 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
251 d5: impl Unborrow<Target = impl D5Pin> + 'd, 257 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
252 d6: impl Unborrow<Target = impl D6Pin> + 'd, 258 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
253 d7: impl Unborrow<Target = impl D7Pin> + 'd, 259 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
254 d8: impl Unborrow<Target = impl D8Pin> + 'd, 260 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
255 d9: impl Unborrow<Target = impl D9Pin> + 'd, 261 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
256 d10: impl Unborrow<Target = impl D10Pin> + 'd, 262 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
257 d11: impl Unborrow<Target = impl D11Pin> + 'd, 263 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
258 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 264 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
259 config: Config, 265 config: Config,
260 ) -> Self { 266 ) -> Self {
261 unborrow!(peri, dma, irq); 267 unborrow!(peri, dma, irq);
262 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 268 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
263 configure!(pixclk); 269 config_pins!(pixclk);
264 270
265 Self::new_inner(peri, dma, irq, config, true, 0b10) 271 Self::new_inner(peri, dma, irq, config, true, 0b10)
266 } 272 }
273
267 pub fn new_es_14bit( 274 pub fn new_es_14bit(
268 peri: impl Unborrow<Target = T> + 'd, 275 peri: impl Unborrow<Target = T> + 'd,
269 dma: impl Unborrow<Target = Dma> + 'd, 276 dma: impl Unborrow<Target = Dma> + 'd,
270 irq: impl Unborrow<Target = T::Interrupt> + 'd, 277 irq: impl Unborrow<Target = T::Interrupt> + 'd,
271 d0: impl Unborrow<Target = impl D0Pin> + 'd, 278 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
272 d1: impl Unborrow<Target = impl D1Pin> + 'd, 279 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
273 d2: impl Unborrow<Target = impl D2Pin> + 'd, 280 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
274 d3: impl Unborrow<Target = impl D3Pin> + 'd, 281 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
275 d4: impl Unborrow<Target = impl D4Pin> + 'd, 282 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd,
276 d5: impl Unborrow<Target = impl D5Pin> + 'd, 283 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd,
277 d6: impl Unborrow<Target = impl D6Pin> + 'd, 284 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd,
278 d7: impl Unborrow<Target = impl D7Pin> + 'd, 285 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd,
279 d8: impl Unborrow<Target = impl D8Pin> + 'd, 286 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd,
280 d9: impl Unborrow<Target = impl D9Pin> + 'd, 287 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd,
281 d10: impl Unborrow<Target = impl D10Pin> + 'd, 288 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd,
282 d11: impl Unborrow<Target = impl D11Pin> + 'd, 289 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd,
283 d12: impl Unborrow<Target = impl D12Pin> + 'd, 290 d12: impl Unborrow<Target = impl D12Pin<T>> + 'd,
284 d13: impl Unborrow<Target = impl D13Pin> + 'd, 291 d13: impl Unborrow<Target = impl D13Pin<T>> + 'd,
285 pixclk: impl Unborrow<Target = impl PixClkPin> + 'd, 292 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd,
286 config: Config, 293 config: Config,
287 ) -> Self { 294 ) -> Self {
288 unborrow!(peri, dma, irq); 295 unborrow!(peri, dma, irq);
289 configure!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 296 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
290 configure!(pixclk); 297 config_pins!(pixclk);
291 298
292 Self::new_inner(peri, dma, irq, config, true, 0b11) 299 Self::new_inner(peri, dma, irq, config, true, 0b11)
293 } 300 }
@@ -424,75 +431,32 @@ where
424} 431}
425 432
426mod sealed { 433mod sealed {
427 use super::*; 434 pub trait Instance: crate::rcc::RccPeripheral {
428 use crate::rcc::RccPeripheral;
429
430 pub trait Instance: RccPeripheral {
431 fn regs(&self) -> crate::pac::dcmi::Dcmi; 435 fn regs(&self) -> crate::pac::dcmi::Dcmi;
432 } 436 }
433
434 pub trait FrameDma {
435 fn request(&self) -> crate::dma::Request;
436 }
437
438 macro_rules! pin {
439 ($name:ident) => {
440 pub trait $name: GpioPin {
441 fn configure(&mut self);
442 }
443 };
444 }
445
446 pin!(D0Pin);
447 pin!(D1Pin);
448 pin!(D2Pin);
449 pin!(D3Pin);
450 pin!(D4Pin);
451 pin!(D5Pin);
452 pin!(D6Pin);
453 pin!(D7Pin);
454 pin!(D8Pin);
455 pin!(D9Pin);
456 pin!(D10Pin);
457 pin!(D11Pin);
458 pin!(D12Pin);
459 pin!(D13Pin);
460
461 pin!(HSyncPin);
462 pin!(VSyncPin);
463 pin!(PixClkPin);
464} 437}
465 438
466pub trait Instance: sealed::Instance + 'static { 439pub trait Instance: sealed::Instance + 'static {
467 type Interrupt: Interrupt; 440 type Interrupt: Interrupt;
468} 441}
469 442
470pub trait FrameDma: sealed::FrameDma + crate::dma::Channel {} 443pin_trait!(D0Pin, Instance);
471 444pin_trait!(D1Pin, Instance);
472macro_rules! pin { 445pin_trait!(D2Pin, Instance);
473 ($name:ident) => { 446pin_trait!(D3Pin, Instance);
474 pub trait $name: sealed::$name + 'static {} 447pin_trait!(D4Pin, Instance);
475 }; 448pin_trait!(D5Pin, Instance);
476} 449pin_trait!(D6Pin, Instance);
477 450pin_trait!(D7Pin, Instance);
478pin!(D0Pin); 451pin_trait!(D8Pin, Instance);
479pin!(D1Pin); 452pin_trait!(D9Pin, Instance);
480pin!(D2Pin); 453pin_trait!(D10Pin, Instance);
481pin!(D3Pin); 454pin_trait!(D11Pin, Instance);
482pin!(D4Pin); 455pin_trait!(D12Pin, Instance);
483pin!(D5Pin); 456pin_trait!(D13Pin, Instance);
484pin!(D6Pin); 457pin_trait!(HSyncPin, Instance);
485pin!(D7Pin); 458pin_trait!(VSyncPin, Instance);
486pin!(D8Pin); 459pin_trait!(PixClkPin, Instance);
487pin!(D9Pin);
488pin!(D10Pin);
489pin!(D11Pin);
490pin!(D12Pin);
491pin!(D13Pin);
492
493pin!(HSyncPin);
494pin!(VSyncPin);
495pin!(PixClkPin);
496 460
497// allow unused as U5 sources do not contain interrupt nor dma data 461// allow unused as U5 sources do not contain interrupt nor dma data
498#[allow(unused)] 462#[allow(unused)]
@@ -516,112 +480,67 @@ crate::pac::interrupts! {
516 }; 480 };
517} 481}
518 482
519// allow unused as U5 sources do not contain interrupt nor dma data 483dma_trait!(FrameDma, Instance);
520#[allow(unused)]
521macro_rules! impl_dma {
522 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
523 impl<T> sealed::$signal for T
524 where
525 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
526 {
527 fn request(&self) -> crate::dma::Request {
528 $request
529 }
530 }
531
532 impl<T> $signal for T where T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux> {}
533 };
534 ($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
535 impl sealed::$signal for crate::peripherals::$channel {
536 fn request(&self) -> crate::dma::Request {
537 $request
538 }
539 }
540
541 impl $signal for crate::peripherals::$channel {}
542 };
543}
544 484
545crate::pac::peripheral_dma_channels! { 485crate::pac::peripheral_dma_channels! {
546 ($peri:ident, dcmi, $kind:ident, PSSI, $channel:tt, $request:expr) => { 486 ($peri:ident, dcmi, $kind:ident, PSSI, $channel:tt, $request:expr) => {
547 impl_dma!($peri, $channel, FrameDma, $request); 487 dma_trait_impl!(FrameDma, $peri, $channel, $request);
548 }; 488 };
549 ($peri:ident, dcmi, $kind:ident, DCMI, $channel:tt, $request:expr) => { 489 ($peri:ident, dcmi, $kind:ident, DCMI, $channel:tt, $request:expr) => {
550 impl_dma!($peri, $channel, FrameDma, $request); 490 dma_trait_impl!(FrameDma, $peri, $channel, $request);
551 };
552}
553
554macro_rules! impl_pin {
555 ($pin:ident, $signal:ident, $af:expr) => {
556 impl sealed::$signal for crate::peripherals::$pin {
557 fn configure(&mut self) {
558 // NOTE(unsafe) Exclusive access to the registers
559 critical_section::with(|_| unsafe {
560 self.set_as_af($af, crate::gpio::sealed::AFType::Input);
561 self.block().ospeedr().modify(|w| {
562 w.set_ospeedr(
563 self.pin() as usize,
564 crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED,
565 )
566 });
567 })
568 }
569 }
570
571 impl $signal for crate::peripherals::$pin {}
572 }; 491 };
573} 492}
574 493
575crate::pac::peripheral_pins!( 494crate::pac::peripheral_pins!(
576 ($inst:ident, dcmi, DCMI, $pin:ident, D0, $af:expr) => { 495 ($inst:ident, dcmi, DCMI, $pin:ident, D0, $af:expr) => {
577 impl_pin!($pin, D0Pin, $af); 496 pin_trait_impl!(D0Pin, $inst, $pin, $af);
578 }; 497 };
579 ($inst:ident, dcmi, DCMI, $pin:ident, D1, $af:expr) => { 498 ($inst:ident, dcmi, DCMI, $pin:ident, D1, $af:expr) => {
580 impl_pin!($pin, D1Pin, $af); 499 pin_trait_impl!(D1Pin, $inst, $pin, $af);
581 }; 500 };
582 ($inst:ident, dcmi, DCMI, $pin:ident, D2, $af:expr) => { 501 ($inst:ident, dcmi, DCMI, $pin:ident, D2, $af:expr) => {
583 impl_pin!($pin, D2Pin, $af); 502 pin_trait_impl!(D2Pin, $inst, $pin, $af);
584 }; 503 };
585 ($inst:ident, dcmi, DCMI, $pin:ident, D3, $af:expr) => { 504 ($inst:ident, dcmi, DCMI, $pin:ident, D3, $af:expr) => {
586 impl_pin!($pin, D3Pin, $af); 505 pin_trait_impl!(D3Pin, $inst, $pin, $af);
587 }; 506 };
588 ($inst:ident, dcmi, DCMI, $pin:ident, D4, $af:expr) => { 507 ($inst:ident, dcmi, DCMI, $pin:ident, D4, $af:expr) => {
589 impl_pin!($pin, D4Pin, $af); 508 pin_trait_impl!(D4Pin, $inst, $pin, $af);
590 }; 509 };
591 ($inst:ident, dcmi, DCMI, $pin:ident, D5, $af:expr) => { 510 ($inst:ident, dcmi, DCMI, $pin:ident, D5, $af:expr) => {
592 impl_pin!($pin, D5Pin, $af); 511 pin_trait_impl!(D5Pin, $inst, $pin, $af);
593 }; 512 };
594 ($inst:ident, dcmi, DCMI, $pin:ident, D6, $af:expr) => { 513 ($inst:ident, dcmi, DCMI, $pin:ident, D6, $af:expr) => {
595 impl_pin!($pin, D6Pin, $af); 514 pin_trait_impl!(D6Pin, $inst, $pin, $af);
596 }; 515 };
597 ($inst:ident, dcmi, DCMI, $pin:ident, D7, $af:expr) => { 516 ($inst:ident, dcmi, DCMI, $pin:ident, D7, $af:expr) => {
598 impl_pin!($pin, D7Pin, $af); 517 pin_trait_impl!(D7Pin, $inst, $pin, $af);
599 }; 518 };
600 ($inst:ident, dcmi, DCMI, $pin:ident, D8, $af:expr) => { 519 ($inst:ident, dcmi, DCMI, $pin:ident, D8, $af:expr) => {
601 impl_pin!($pin, D8Pin, $af); 520 pin_trait_impl!(D8Pin, $inst, $pin, $af);
602 }; 521 };
603 ($inst:ident, dcmi, DCMI, $pin:ident, D9, $af:expr) => { 522 ($inst:ident, dcmi, DCMI, $pin:ident, D9, $af:expr) => {
604 impl_pin!($pin, D9Pin, $af); 523 pin_trait_impl!(D9Pin, $inst, $pin, $af);
605 }; 524 };
606 ($inst:ident, dcmi, DCMI, $pin:ident, D10, $af:expr) => { 525 ($inst:ident, dcmi, DCMI, $pin:ident, D10, $af:expr) => {
607 impl_pin!($pin, D10Pin, $af); 526 pin_trait_impl!(D10Pin, $inst, $pin, $af);
608 }; 527 };
609 ($inst:ident, dcmi, DCMI, $pin:ident, D11, $af:expr) => { 528 ($inst:ident, dcmi, DCMI, $pin:ident, D11, $af:expr) => {
610 impl_pin!($pin, D11Pin, $af); 529 pin_trait_impl!(D11Pin, $inst, $pin, $af);
611 }; 530 };
612 ($inst:ident, dcmi, DCMI, $pin:ident, D12, $af:expr) => { 531 ($inst:ident, dcmi, DCMI, $pin:ident, D12, $af:expr) => {
613 impl_pin!($pin, D12Pin, $af); 532 pin_trait_impl!(D12Pin, $inst, $pin, $af);
614 }; 533 };
615 ($inst:ident, dcmi, DCMI, $pin:ident, D13, $af:expr) => { 534 ($inst:ident, dcmi, DCMI, $pin:ident, D13, $af:expr) => {
616 impl_pin!($pin, D13Pin, $af); 535 pin_trait_impl!(D13Pin, $inst, $pin, $af);
617 }; 536 };
618 ($inst:ident, dcmi, DCMI, $pin:ident, HSYNC, $af:expr) => { 537 ($inst:ident, dcmi, DCMI, $pin:ident, HSYNC, $af:expr) => {
619 impl_pin!($pin, HSyncPin, $af); 538 pin_trait_impl!(HSyncPin, $inst, $pin, $af);
620 }; 539 };
621 ($inst:ident, dcmi, DCMI, $pin:ident, VSYNC, $af:expr) => { 540 ($inst:ident, dcmi, DCMI, $pin:ident, VSYNC, $af:expr) => {
622 impl_pin!($pin, VSyncPin, $af); 541 pin_trait_impl!(VSyncPin, $inst, $pin, $af);
623 }; 542 };
624 ($inst:ident, dcmi, DCMI, $pin:ident, PIXCLK, $af:expr) => { 543 ($inst:ident, dcmi, DCMI, $pin:ident, PIXCLK, $af:expr) => {
625 impl_pin!($pin, PixClkPin, $af); 544 pin_trait_impl!(PixClkPin, $inst, $pin, $af);
626 }; 545 };
627); 546);
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 1c9661561..6bca969c8 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -18,9 +18,10 @@ use embassy::util::Unborrow;
18use embassy_hal_common::unborrow; 18use embassy_hal_common::unborrow;
19 19
20#[cfg(feature = "unstable-pac")] 20#[cfg(feature = "unstable-pac")]
21pub use transfers::*; 21pub mod low_level {
22 pub use super::transfers::*;
23}
22 24
23#[cfg(not(feature = "unstable-pac"))]
24pub(crate) use transfers::*; 25pub(crate) use transfers::*;
25 26
26#[cfg(any(bdma_v2, dma_v2, dmamux))] 27#[cfg(any(bdma_v2, dma_v2, dmamux))]
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 664c19daa..cf145e393 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -33,3 +33,58 @@ pub unsafe trait PHY {
33 /// Poll link to see if it is up and FD with 100Mbps 33 /// Poll link to see if it is up and FD with 100Mbps
34 fn poll_link<S: StationManagement>(sm: &mut S) -> bool; 34 fn poll_link<S: StationManagement>(sm: &mut S) -> bool;
35} 35}
36
37pub(crate) mod sealed {
38 pub trait Instance {
39 fn regs() -> crate::pac::eth::Eth;
40 }
41}
42
43pub trait Instance: sealed::Instance + Send + 'static {}
44
45impl sealed::Instance for crate::peripherals::ETH {
46 fn regs() -> crate::pac::eth::Eth {
47 crate::pac::ETH
48 }
49}
50impl Instance for crate::peripherals::ETH {}
51
52pin_trait!(RefClkPin, Instance);
53pin_trait!(MDIOPin, Instance);
54pin_trait!(MDCPin, Instance);
55pin_trait!(CRSPin, Instance);
56pin_trait!(RXD0Pin, Instance);
57pin_trait!(RXD1Pin, Instance);
58pin_trait!(TXD0Pin, Instance);
59pin_trait!(TXD1Pin, Instance);
60pin_trait!(TXEnPin, Instance);
61
62crate::pac::peripheral_pins!(
63 ($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
64 pin_trait_impl!(RefClkPin, $inst, $pin, $af);
65 };
66 ($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
67 pin_trait_impl!(MDIOPin, $inst, $pin, $af);
68 };
69 ($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
70 pin_trait_impl!(MDCPin, $inst, $pin, $af);
71 };
72 ($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
73 pin_trait_impl!(CRSPin, $inst, $pin, $af);
74 };
75 ($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
76 pin_trait_impl!(RXD0Pin, $inst, $pin, $af);
77 };
78 ($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
79 pin_trait_impl!(RXD1Pin, $inst, $pin, $af);
80 };
81 ($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
82 pin_trait_impl!(TXD0Pin, $inst, $pin, $af);
83 };
84 ($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
85 pin_trait_impl!(TXD1Pin, $inst, $pin, $af);
86 };
87 ($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
88 pin_trait_impl!(TXEnPin, $inst, $pin, $af);
89 };
90);
diff --git a/embassy-stm32/src/eth/v1c/mod.rs b/embassy-stm32/src/eth/v1c/mod.rs
index 89815c71f..1927a9a26 100644
--- a/embassy-stm32/src/eth/v1c/mod.rs
+++ b/embassy-stm32/src/eth/v1c/mod.rs
@@ -12,29 +12,31 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
12 12
13use crate::gpio::sealed::Pin as __GpioPin; 13use crate::gpio::sealed::Pin as __GpioPin;
14use crate::gpio::Pin as GpioPin; 14use crate::gpio::Pin as GpioPin;
15use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin}; 15use crate::gpio::{sealed::AFType, AnyPin, Speed};
16use crate::pac::gpio::vals::Ospeedr; 16use crate::pac::gpio::vals::Ospeedr;
17use crate::pac::{ETH, RCC, SYSCFG}; 17use crate::pac::{ETH, RCC, SYSCFG};
18use crate::peripherals;
19 18
20mod descriptors; 19mod descriptors;
21mod rx_desc; 20mod rx_desc;
22mod tx_desc; 21mod tx_desc;
23 22
24use super::{StationManagement, PHY}; 23use super::*;
25use descriptors::DescriptorRing; 24use descriptors::DescriptorRing;
26use stm32_metapac::eth::vals::{ 25use stm32_metapac::eth::vals::{
27 Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf, 26 Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf,
28}; 27};
29 28
30pub struct State<'d, const TX: usize, const RX: usize>(StateStorage<Inner<'d, TX, RX>>); 29pub struct State<'d, T: Instance, const TX: usize, const RX: usize>(
31impl<'d, const TX: usize, const RX: usize> State<'d, TX, RX> { 30 StateStorage<Inner<'d, T, TX, RX>>,
32 pub const fn new() -> Self { 31);
32impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
33 pub fn new() -> Self {
33 Self(StateStorage::new()) 34 Self(StateStorage::new())
34 } 35 }
35} 36}
36pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> { 37
37 state: PeripheralMutex<'d, Inner<'d, TX, RX>>, 38pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
39 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
38 pins: [AnyPin; 9], 40 pins: [AnyPin; 9],
39 _phy: P, 41 _phy: P,
40 clock_range: Cr, 42 clock_range: Cr,
@@ -42,21 +44,33 @@ pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> {
42 mac_addr: [u8; 6], 44 mac_addr: [u8; 6],
43} 45}
44 46
45impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { 47macro_rules! config_pins {
48 ($($pin:ident),*) => {
49 // NOTE(unsafe) Exclusive access to the registers
50 critical_section::with(|_| unsafe {
51 $(
52 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
53 $pin.set_speed(Speed::VeryHigh);
54 )*
55 })
56 };
57}
58
59impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T, P, TX, RX> {
46 /// safety: the returned instance is not leak-safe 60 /// safety: the returned instance is not leak-safe
47 pub unsafe fn new( 61 pub unsafe fn new(
48 state: &'d mut State<'d, TX, RX>, 62 state: &'d mut State<'d, T, TX, RX>,
49 peri: impl Unborrow<Target = peripherals::ETH> + 'd, 63 peri: impl Unborrow<Target = T> + 'd,
50 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, 64 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
51 ref_clk: impl Unborrow<Target = impl RefClkPin> + 'd, 65 ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
52 mdio: impl Unborrow<Target = impl MDIOPin> + 'd, 66 mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
53 mdc: impl Unborrow<Target = impl MDCPin> + 'd, 67 mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
54 crs: impl Unborrow<Target = impl CRSPin> + 'd, 68 crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
55 rx_d0: impl Unborrow<Target = impl RXD0Pin> + 'd, 69 rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
56 rx_d1: impl Unborrow<Target = impl RXD1Pin> + 'd, 70 rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
57 tx_d0: impl Unborrow<Target = impl TXD0Pin> + 'd, 71 tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
58 tx_d1: impl Unborrow<Target = impl TXD1Pin> + 'd, 72 tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
59 tx_en: impl Unborrow<Target = impl TXEnPin> + 'd, 73 tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
60 phy: P, 74 phy: P,
61 mac_addr: [u8; 6], 75 mac_addr: [u8; 6],
62 phy_addr: u8, 76 phy_addr: u8,
@@ -77,15 +91,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
77 SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true)); 91 SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true));
78 }); 92 });
79 93
80 ref_clk.configure(); 94 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
81 mdio.configure();
82 mdc.configure();
83 crs.configure();
84 rx_d0.configure();
85 rx_d1.configure();
86 tx_d0.configure();
87 tx_d1.configure();
88 tx_en.configure();
89 95
90 // NOTE(unsafe) We are ourselves not leak-safe. 96 // NOTE(unsafe) We are ourselves not leak-safe.
91 let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri)); 97 let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri));
@@ -204,8 +210,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
204 } 210 }
205} 211}
206 212
207unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement 213unsafe impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> StationManagement
208 for Ethernet<'d, P, TX, RX> 214 for Ethernet<'d, T, P, TX, RX>
209{ 215{
210 fn smi_read(&mut self, reg: u8) -> u16 { 216 fn smi_read(&mut self, reg: u8) -> u16 {
211 // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self` 217 // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self`
@@ -242,7 +248,9 @@ unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement
242 } 248 }
243} 249}
244 250
245impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX, RX> { 251impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Device
252 for Ethernet<'d, T, P, TX, RX>
253{
246 fn is_transmit_ready(&mut self) -> bool { 254 fn is_transmit_ready(&mut self) -> bool {
247 self.state.with(|s| s.desc_ring.tx.available()) 255 self.state.with(|s| s.desc_ring.tx.available())
248 } 256 }
@@ -279,7 +287,9 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX
279 } 287 }
280} 288}
281 289
282impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX, RX> { 290impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
291 for Ethernet<'d, T, P, TX, RX>
292{
283 fn drop(&mut self) { 293 fn drop(&mut self) {
284 // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers 294 // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers
285 unsafe { 295 unsafe {
@@ -312,13 +322,13 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
312 322
313//---------------------------------------------------------------------- 323//----------------------------------------------------------------------
314 324
315struct Inner<'d, const TX: usize, const RX: usize> { 325struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
316 _peri: PhantomData<&'d mut peripherals::ETH>, 326 _peri: PhantomData<&'d mut T>,
317 desc_ring: DescriptorRing<TX, RX>, 327 desc_ring: DescriptorRing<TX, RX>,
318} 328}
319 329
320impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> { 330impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
321 pub fn new(_peri: impl Unborrow<Target = peripherals::ETH> + 'd) -> Self { 331 pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
322 Self { 332 Self {
323 _peri: PhantomData, 333 _peri: PhantomData,
324 desc_ring: DescriptorRing::new(), 334 desc_ring: DescriptorRing::new(),
@@ -326,7 +336,7 @@ impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> {
326 } 336 }
327} 337}
328 338
329impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX> { 339impl<'d, T: Instance, const TX: usize, const RX: usize> PeripheralState for Inner<'d, T, TX, RX> {
330 type Interrupt = crate::interrupt::ETH; 340 type Interrupt = crate::interrupt::ETH;
331 341
332 fn on_interrupt(&mut self) { 342 fn on_interrupt(&mut self) {
@@ -351,123 +361,4 @@ impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX>
351 } 361 }
352} 362}
353 363
354mod sealed {
355 use super::*;
356
357 pub trait RefClkPin: GpioPin {
358 fn configure(&mut self);
359 }
360
361 pub trait MDIOPin: GpioPin {
362 fn configure(&mut self);
363 }
364
365 pub trait MDCPin: GpioPin {
366 fn configure(&mut self);
367 }
368
369 pub trait CRSPin: GpioPin {
370 fn configure(&mut self);
371 }
372
373 pub trait RXD0Pin: GpioPin {
374 fn configure(&mut self);
375 }
376
377 pub trait RXD1Pin: GpioPin {
378 fn configure(&mut self);
379 }
380
381 pub trait TXD0Pin: GpioPin {
382 fn configure(&mut self);
383 }
384
385 pub trait TXD1Pin: GpioPin {
386 fn configure(&mut self);
387 }
388
389 pub trait TXEnPin: GpioPin {
390 fn configure(&mut self);
391 }
392}
393
394pub trait RefClkPin: sealed::RefClkPin + 'static {}
395
396pub trait MDIOPin: sealed::MDIOPin + 'static {}
397
398pub trait MDCPin: sealed::MDCPin + 'static {}
399
400pub trait CRSPin: sealed::CRSPin + 'static {}
401
402pub trait RXD0Pin: sealed::RXD0Pin + 'static {}
403
404pub trait RXD1Pin: sealed::RXD1Pin + 'static {}
405
406pub trait TXD0Pin: sealed::TXD0Pin + 'static {}
407
408pub trait TXD1Pin: sealed::TXD1Pin + 'static {}
409
410pub trait TXEnPin: sealed::TXEnPin + 'static {}
411
412static WAKER: AtomicWaker = AtomicWaker::new(); 364static WAKER: AtomicWaker = AtomicWaker::new();
413
414macro_rules! impl_pin {
415 ($pin:ident, $signal:ident, $af:expr) => {
416 impl sealed::$signal for peripherals::$pin {
417 fn configure(&mut self) {
418 // NOTE(unsafe) Exclusive access to the registers
419 critical_section::with(|_| unsafe {
420 self.set_as_af($af, OutputPushPull);
421 self.block()
422 .ospeedr()
423 .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
424 })
425 }
426 }
427
428 impl $signal for peripherals::$pin {}
429 };
430}
431// impl sealed::RefClkPin for peripherals::PA1 {
432// fn configure(&mut self) {
433// // NOTE(unsafe) Exclusive access to the registers
434// critical_section::with(|_| unsafe {
435// self.set_as_af(11, OutputPushPull);
436// self.block()
437// .ospeedr()
438// .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
439// })
440// }
441// }
442
443// impl RefClkPin for peripherals::PA1 {}
444
445crate::pac::peripheral_pins!(
446 ($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
447 impl_pin!($pin, RefClkPin, $af);
448 };
449 ($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
450 impl_pin!($pin, MDIOPin, $af);
451 };
452 ($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
453 impl_pin!($pin, MDCPin, $af);
454 };
455 ($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
456 impl_pin!($pin, CRSPin, $af);
457 };
458 ($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
459 impl_pin!($pin, RXD0Pin, $af);
460 };
461 ($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
462 impl_pin!($pin, RXD1Pin, $af);
463 };
464 ($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
465 impl_pin!($pin, TXD0Pin, $af);
466 };
467 ($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
468 impl_pin!($pin, TXD1Pin, $af);
469 };
470 ($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
471 impl_pin!($pin, TXEnPin, $af);
472 };
473);
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 2f2dc4f38..ad81b1d51 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -8,25 +8,24 @@ use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStor
8use embassy_hal_common::unborrow; 8use embassy_hal_common::unborrow;
9use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 9use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
10 10
11use crate::gpio::sealed::Pin as __GpioPin; 11use crate::gpio::sealed::Pin as _;
12use crate::gpio::Pin as GpioPin; 12use crate::gpio::{sealed::AFType, AnyPin, Speed};
13use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin};
14use crate::pac::gpio::vals::Ospeedr;
15use crate::pac::{ETH, RCC, SYSCFG}; 13use crate::pac::{ETH, RCC, SYSCFG};
16use crate::peripherals;
17 14
18mod descriptors; 15mod descriptors;
19use super::{StationManagement, PHY}; 16use super::*;
20use descriptors::DescriptorRing; 17use descriptors::DescriptorRing;
21 18
22pub struct State<'d, const TX: usize, const RX: usize>(StateStorage<Inner<'d, TX, RX>>); 19pub struct State<'d, T: Instance, const TX: usize, const RX: usize>(
23impl<'d, const TX: usize, const RX: usize> State<'d, TX, RX> { 20 StateStorage<Inner<'d, T, TX, RX>>,
24 pub const fn new() -> Self { 21);
22impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
23 pub fn new() -> Self {
25 Self(StateStorage::new()) 24 Self(StateStorage::new())
26 } 25 }
27} 26}
28pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> { 27pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
29 state: PeripheralMutex<'d, Inner<'d, TX, RX>>, 28 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
30 pins: [AnyPin; 9], 29 pins: [AnyPin; 9],
31 _phy: P, 30 _phy: P,
32 clock_range: u8, 31 clock_range: u8,
@@ -34,21 +33,33 @@ pub struct Ethernet<'d, P: PHY, const TX: usize, const RX: usize> {
34 mac_addr: [u8; 6], 33 mac_addr: [u8; 6],
35} 34}
36 35
37impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { 36macro_rules! config_pins {
37 ($($pin:ident),*) => {
38 // NOTE(unsafe) Exclusive access to the registers
39 critical_section::with(|_| unsafe {
40 $(
41 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
42 $pin.set_speed(Speed::VeryHigh);
43 )*
44 })
45 };
46}
47
48impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T, P, TX, RX> {
38 /// safety: the returned instance is not leak-safe 49 /// safety: the returned instance is not leak-safe
39 pub unsafe fn new( 50 pub unsafe fn new(
40 state: &'d mut State<'d, TX, RX>, 51 state: &'d mut State<'d, T, TX, RX>,
41 peri: impl Unborrow<Target = peripherals::ETH> + 'd, 52 peri: impl Unborrow<Target = T> + 'd,
42 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, 53 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd,
43 ref_clk: impl Unborrow<Target = impl RefClkPin> + 'd, 54 ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd,
44 mdio: impl Unborrow<Target = impl MDIOPin> + 'd, 55 mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd,
45 mdc: impl Unborrow<Target = impl MDCPin> + 'd, 56 mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd,
46 crs: impl Unborrow<Target = impl CRSPin> + 'd, 57 crs: impl Unborrow<Target = impl CRSPin<T>> + 'd,
47 rx_d0: impl Unborrow<Target = impl RXD0Pin> + 'd, 58 rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd,
48 rx_d1: impl Unborrow<Target = impl RXD1Pin> + 'd, 59 rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd,
49 tx_d0: impl Unborrow<Target = impl TXD0Pin> + 'd, 60 tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd,
50 tx_d1: impl Unborrow<Target = impl TXD1Pin> + 'd, 61 tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd,
51 tx_en: impl Unborrow<Target = impl TXEnPin> + 'd, 62 tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd,
52 phy: P, 63 phy: P,
53 mac_addr: [u8; 6], 64 mac_addr: [u8; 6],
54 phy_addr: u8, 65 phy_addr: u8,
@@ -69,15 +80,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
69 SYSCFG.pmcr().modify(|w| w.set_epis(0b100)); 80 SYSCFG.pmcr().modify(|w| w.set_epis(0b100));
70 }); 81 });
71 82
72 ref_clk.configure(); 83 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
73 mdio.configure();
74 mdc.configure();
75 crs.configure();
76 rx_d0.configure();
77 rx_d1.configure();
78 tx_d0.configure();
79 tx_d1.configure();
80 tx_en.configure();
81 84
82 // NOTE(unsafe) We are ourselves not leak-safe. 85 // NOTE(unsafe) We are ourselves not leak-safe.
83 let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri)); 86 let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri));
@@ -193,8 +196,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> {
193 } 196 }
194} 197}
195 198
196unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement 199unsafe impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> StationManagement
197 for Ethernet<'d, P, TX, RX> 200 for Ethernet<'d, T, P, TX, RX>
198{ 201{
199 fn smi_read(&mut self, reg: u8) -> u16 { 202 fn smi_read(&mut self, reg: u8) -> u16 {
200 // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self` 203 // NOTE(unsafe) These registers aren't used in the interrupt and we have `&mut self`
@@ -231,7 +234,9 @@ unsafe impl<'d, P: PHY, const TX: usize, const RX: usize> StationManagement
231 } 234 }
232} 235}
233 236
234impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX, RX> { 237impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Device
238 for Ethernet<'d, T, P, TX, RX>
239{
235 fn is_transmit_ready(&mut self) -> bool { 240 fn is_transmit_ready(&mut self) -> bool {
236 self.state.with(|s| s.desc_ring.tx.available()) 241 self.state.with(|s| s.desc_ring.tx.available())
237 } 242 }
@@ -268,7 +273,9 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Device for Ethernet<'d, P, TX
268 } 273 }
269} 274}
270 275
271impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX, RX> { 276impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
277 for Ethernet<'d, T, P, TX, RX>
278{
272 fn drop(&mut self) { 279 fn drop(&mut self) {
273 // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers 280 // NOTE(unsafe) We have `&mut self` and the interrupt doesn't use this registers
274 unsafe { 281 unsafe {
@@ -301,9 +308,7 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
301 // NOTE(unsafe) Exclusive access to the regs 308 // NOTE(unsafe) Exclusive access to the regs
302 critical_section::with(|_| unsafe { 309 critical_section::with(|_| unsafe {
303 pin.set_as_analog(); 310 pin.set_as_analog();
304 pin.block() 311 pin.set_speed(Speed::Low);
305 .ospeedr()
306 .modify(|w| w.set_ospeedr(pin.pin() as usize, Ospeedr::LOWSPEED));
307 }) 312 })
308 } 313 }
309 } 314 }
@@ -311,13 +316,13 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Drop for Ethernet<'d, P, TX,
311 316
312//---------------------------------------------------------------------- 317//----------------------------------------------------------------------
313 318
314struct Inner<'d, const TX: usize, const RX: usize> { 319struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
315 _peri: PhantomData<&'d mut peripherals::ETH>, 320 _peri: PhantomData<&'d mut T>,
316 desc_ring: DescriptorRing<TX, RX>, 321 desc_ring: DescriptorRing<TX, RX>,
317} 322}
318 323
319impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> { 324impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
320 pub fn new(_peri: impl Unborrow<Target = peripherals::ETH> + 'd) -> Self { 325 pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self {
321 Self { 326 Self {
322 _peri: PhantomData, 327 _peri: PhantomData,
323 desc_ring: DescriptorRing::new(), 328 desc_ring: DescriptorRing::new(),
@@ -325,7 +330,7 @@ impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> {
325 } 330 }
326} 331}
327 332
328impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX> { 333impl<'d, T: Instance, const TX: usize, const RX: usize> PeripheralState for Inner<'d, T, TX, RX> {
329 type Interrupt = crate::interrupt::ETH; 334 type Interrupt = crate::interrupt::ETH;
330 335
331 fn on_interrupt(&mut self) { 336 fn on_interrupt(&mut self) {
@@ -350,110 +355,4 @@ impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX>
350 } 355 }
351} 356}
352 357
353mod sealed {
354 use super::*;
355
356 pub trait RefClkPin: GpioPin {
357 fn configure(&mut self);
358 }
359
360 pub trait MDIOPin: GpioPin {
361 fn configure(&mut self);
362 }
363
364 pub trait MDCPin: GpioPin {
365 fn configure(&mut self);
366 }
367
368 pub trait CRSPin: GpioPin {
369 fn configure(&mut self);
370 }
371
372 pub trait RXD0Pin: GpioPin {
373 fn configure(&mut self);
374 }
375
376 pub trait RXD1Pin: GpioPin {
377 fn configure(&mut self);
378 }
379
380 pub trait TXD0Pin: GpioPin {
381 fn configure(&mut self);
382 }
383
384 pub trait TXD1Pin: GpioPin {
385 fn configure(&mut self);
386 }
387
388 pub trait TXEnPin: GpioPin {
389 fn configure(&mut self);
390 }
391}
392
393pub trait RefClkPin: sealed::RefClkPin + 'static {}
394
395pub trait MDIOPin: sealed::MDIOPin + 'static {}
396
397pub trait MDCPin: sealed::MDCPin + 'static {}
398
399pub trait CRSPin: sealed::CRSPin + 'static {}
400
401pub trait RXD0Pin: sealed::RXD0Pin + 'static {}
402
403pub trait RXD1Pin: sealed::RXD1Pin + 'static {}
404
405pub trait TXD0Pin: sealed::TXD0Pin + 'static {}
406
407pub trait TXD1Pin: sealed::TXD1Pin + 'static {}
408
409pub trait TXEnPin: sealed::TXEnPin + 'static {}
410
411static WAKER: AtomicWaker = AtomicWaker::new(); 358static WAKER: AtomicWaker = AtomicWaker::new();
412
413macro_rules! impl_pin {
414 ($pin:ident, $signal:ident, $af:expr) => {
415 impl sealed::$signal for peripherals::$pin {
416 fn configure(&mut self) {
417 // NOTE(unsafe) Exclusive access to the registers
418 critical_section::with(|_| unsafe {
419 self.set_as_af($af, OutputPushPull);
420 self.block()
421 .ospeedr()
422 .modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
423 })
424 }
425 }
426
427 impl $signal for peripherals::$pin {}
428 };
429}
430
431crate::pac::peripheral_pins!(
432 ($inst:ident, eth, ETH, $pin:ident, REF_CLK, $af:expr) => {
433 impl_pin!($pin, RefClkPin, $af);
434 };
435 ($inst:ident, eth, ETH, $pin:ident, MDIO, $af:expr) => {
436 impl_pin!($pin, MDIOPin, $af);
437 };
438 ($inst:ident, eth, ETH, $pin:ident, MDC, $af:expr) => {
439 impl_pin!($pin, MDCPin, $af);
440 };
441 ($inst:ident, eth, ETH, $pin:ident, CRS_DV, $af:expr) => {
442 impl_pin!($pin, CRSPin, $af);
443 };
444 ($inst:ident, eth, ETH, $pin:ident, RXD0, $af:expr) => {
445 impl_pin!($pin, RXD0Pin, $af);
446 };
447 ($inst:ident, eth, ETH, $pin:ident, RXD1, $af:expr) => {
448 impl_pin!($pin, RXD1Pin, $af);
449 };
450 ($inst:ident, eth, ETH, $pin:ident, TXD0, $af:expr) => {
451 impl_pin!($pin, TXD0Pin, $af);
452 };
453 ($inst:ident, eth, ETH, $pin:ident, TXD1, $af:expr) => {
454 impl_pin!($pin, TXD1Pin, $af);
455 };
456 ($inst:ident, eth, ETH, $pin:ident, TX_EN, $af:expr) => {
457 impl_pin!($pin, TXEnPin, $af);
458 };
459);
diff --git a/embassy-stm32/src/fmc/mod.rs b/embassy-stm32/src/fmc/mod.rs
index afdb45af9..796964213 100644
--- a/embassy-stm32/src/fmc/mod.rs
+++ b/embassy-stm32/src/fmc/mod.rs
@@ -1,11 +1,13 @@
1mod pins;
2
3use core::marker::PhantomData; 1use core::marker::PhantomData;
4
5use embassy::util::Unborrow; 2use embassy::util::Unborrow;
6use embassy_hal_common::unborrow; 3use embassy_hal_common::unborrow;
7 4
8use pins::*; 5use crate::gpio::sealed::AFType::OutputPushPull;
6use crate::gpio::Speed;
7use crate::pac::gpio::vals::Pupdr;
8
9mod pins;
10pub use pins::*;
9 11
10pub struct Fmc<'d, T: Instance> { 12pub struct Fmc<'d, T: Instance> {
11 peri: PhantomData<&'d mut T>, 13 peri: PhantomData<&'d mut T>,
@@ -34,16 +36,21 @@ where
34 <T as crate::rcc::sealed::RccPeripheral>::frequency().0 36 <T as crate::rcc::sealed::RccPeripheral>::frequency().0
35 } 37 }
36} 38}
39
37macro_rules! config_pins { 40macro_rules! config_pins {
38 ($($pin:ident),*) => { 41 ($($pin:ident),*) => {
42 unborrow!($($pin),*);
39 $( 43 $(
40 $pin.configure(); 44 $pin.set_as_af($pin.af_num(), OutputPushPull);
45 $pin.set_speed(Speed::VeryHigh);
46 $pin.block().pupdr().modify(|w| w.set_pupdr($pin.pin() as usize, Pupdr::PULLUP));
41 )* 47 )*
42}; 48 };
43} 49}
44 50
45macro_rules! fmc_sdram_constructor { 51macro_rules! fmc_sdram_constructor {
46 ($name:ident: ( 52 ($name:ident: (
53 bank: $bank:expr,
47 addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*], 54 addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*],
48 ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*], 55 ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*],
49 d: [$(($d_pin_name:ident: $d_signal:ident)),*], 56 d: [$(($d_pin_name:ident: $d_signal:ident)),*],
@@ -52,21 +59,15 @@ macro_rules! fmc_sdram_constructor {
52 )) => { 59 )) => {
53 pub fn $name<CHIP: stm32_fmc::SdramChip>( 60 pub fn $name<CHIP: stm32_fmc::SdramChip>(
54 _instance: impl Unborrow<Target = T> + 'd, 61 _instance: impl Unborrow<Target = T> + 'd,
55 $($addr_pin_name: impl Unborrow<Target = impl $addr_signal> + 'd),*, 62 $($addr_pin_name: impl Unborrow<Target = impl $addr_signal<T>> + 'd),*,
56 $($ba_pin_name: impl Unborrow<Target = impl $ba_signal> + 'd),*, 63 $($ba_pin_name: impl Unborrow<Target = impl $ba_signal<T>> + 'd),*,
57 $($d_pin_name: impl Unborrow<Target = impl $d_signal> + 'd),*, 64 $($d_pin_name: impl Unborrow<Target = impl $d_signal<T>> + 'd),*,
58 $($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal> + 'd),*, 65 $($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal<T>> + 'd),*,
59 $($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal> + 'd),*, 66 $($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal<T>> + 'd),*,
60 chip: CHIP 67 chip: CHIP
61 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> { 68 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
62 unborrow!(
63 $($addr_pin_name),*,
64 $($ba_pin_name),*,
65 $($d_pin_name),*,
66 $($nbl_pin_name),*,
67 $($ctrl_pin_name),*
68 );
69 69
70 critical_section::with(|_| unsafe {
70 config_pins!( 71 config_pins!(
71 $($addr_pin_name),*, 72 $($addr_pin_name),*,
72 $($ba_pin_name),*, 73 $($ba_pin_name),*,
@@ -74,17 +75,12 @@ macro_rules! fmc_sdram_constructor {
74 $($nbl_pin_name),*, 75 $($nbl_pin_name),*,
75 $($ctrl_pin_name),* 76 $($ctrl_pin_name),*
76 ); 77 );
78 });
77 79
78 let fmc = Self { peri: PhantomData }; 80 let fmc = Self { peri: PhantomData };
79 stm32_fmc::Sdram::new( 81 stm32_fmc::Sdram::new_unchecked(
80 fmc, 82 fmc,
81 ( 83 $bank,
82 $($addr_pin_name),*,
83 $($ba_pin_name),*,
84 $($d_pin_name),*,
85 $($nbl_pin_name),*,
86 $($ctrl_pin_name),*,
87 ),
88 chip, 84 chip,
89 ) 85 )
90 } 86 }
@@ -93,6 +89,7 @@ macro_rules! fmc_sdram_constructor {
93 89
94impl<'d, T: Instance> Fmc<'d, T> { 90impl<'d, T: Instance> Fmc<'d, T> {
95 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: ( 91 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: (
92 bank: stm32_fmc::SdramTargetBank::Bank1,
96 addr: [ 93 addr: [
97 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) 94 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
98 ], 95 ],
@@ -112,6 +109,7 @@ impl<'d, T: Instance> Fmc<'d, T> {
112 )); 109 ));
113 110
114 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: ( 111 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: (
112 bank: stm32_fmc::SdramTargetBank::Bank2,
115 addr: [ 113 addr: [
116 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) 114 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
117 ], 115 ],
@@ -131,8 +129,6 @@ impl<'d, T: Instance> Fmc<'d, T> {
131 )); 129 ));
132} 130}
133 131
134pub trait Instance: sealed::Instance + 'static {}
135
136crate::pac::peripherals!( 132crate::pac::peripherals!(
137 (fmc, $inst:ident) => { 133 (fmc, $inst:ident) => {
138 impl crate::fmc::sealed::Instance for crate::peripherals::$inst { 134 impl crate::fmc::sealed::Instance for crate::peripherals::$inst {
diff --git a/embassy-stm32/src/fmc/pins.rs b/embassy-stm32/src/fmc/pins.rs
index c42c2792f..e390ad176 100644
--- a/embassy-stm32/src/fmc/pins.rs
+++ b/embassy-stm32/src/fmc/pins.rs
@@ -2,671 +2,417 @@ pub(crate) mod sealed {
2 pub trait Instance: crate::rcc::sealed::RccPeripheral { 2 pub trait Instance: crate::rcc::sealed::RccPeripheral {
3 fn regs() -> crate::pac::fmc::Fmc; 3 fn regs() -> crate::pac::fmc::Fmc;
4 } 4 }
5
6 macro_rules! declare_pin {
7 ($name:ident) => {
8 pub trait $name {
9 fn configure(&mut self);
10 }
11 };
12 }
13
14 declare_pin!(SDNWEPin);
15 declare_pin!(SDNCASPin);
16 declare_pin!(SDNRASPin);
17
18 declare_pin!(SDNE0Pin);
19 declare_pin!(SDNE1Pin);
20
21 declare_pin!(SDCKE0Pin);
22 declare_pin!(SDCKE1Pin);
23
24 declare_pin!(SDCLKPin);
25
26 declare_pin!(NBL0Pin);
27 declare_pin!(NBL1Pin);
28 declare_pin!(NBL2Pin);
29 declare_pin!(NBL3Pin);
30
31 declare_pin!(INTPin);
32 declare_pin!(NLPin);
33 declare_pin!(NWaitPin);
34
35 declare_pin!(NE1Pin);
36 declare_pin!(NE2Pin);
37 declare_pin!(NE3Pin);
38 declare_pin!(NE4Pin);
39
40 declare_pin!(NCEPin);
41 declare_pin!(NOEPin);
42 declare_pin!(NWEPin);
43 declare_pin!(ClkPin);
44
45 declare_pin!(BA0Pin);
46 declare_pin!(BA1Pin);
47
48 declare_pin!(D0Pin);
49 declare_pin!(D1Pin);
50 declare_pin!(D2Pin);
51 declare_pin!(D3Pin);
52 declare_pin!(D4Pin);
53 declare_pin!(D5Pin);
54 declare_pin!(D6Pin);
55 declare_pin!(D7Pin);
56 declare_pin!(D8Pin);
57 declare_pin!(D9Pin);
58 declare_pin!(D10Pin);
59 declare_pin!(D11Pin);
60 declare_pin!(D12Pin);
61 declare_pin!(D13Pin);
62 declare_pin!(D14Pin);
63 declare_pin!(D15Pin);
64 declare_pin!(D16Pin);
65 declare_pin!(D17Pin);
66 declare_pin!(D18Pin);
67 declare_pin!(D19Pin);
68 declare_pin!(D20Pin);
69 declare_pin!(D21Pin);
70 declare_pin!(D22Pin);
71 declare_pin!(D23Pin);
72 declare_pin!(D24Pin);
73 declare_pin!(D25Pin);
74 declare_pin!(D26Pin);
75 declare_pin!(D27Pin);
76 declare_pin!(D28Pin);
77 declare_pin!(D29Pin);
78 declare_pin!(D30Pin);
79 declare_pin!(D31Pin);
80
81 declare_pin!(DA0Pin);
82 declare_pin!(DA1Pin);
83 declare_pin!(DA2Pin);
84 declare_pin!(DA3Pin);
85 declare_pin!(DA4Pin);
86 declare_pin!(DA5Pin);
87 declare_pin!(DA6Pin);
88 declare_pin!(DA7Pin);
89 declare_pin!(DA8Pin);
90 declare_pin!(DA9Pin);
91 declare_pin!(DA10Pin);
92 declare_pin!(DA11Pin);
93 declare_pin!(DA12Pin);
94 declare_pin!(DA13Pin);
95 declare_pin!(DA14Pin);
96 declare_pin!(DA15Pin);
97
98 declare_pin!(A0Pin);
99 declare_pin!(A1Pin);
100 declare_pin!(A2Pin);
101 declare_pin!(A3Pin);
102 declare_pin!(A4Pin);
103 declare_pin!(A5Pin);
104 declare_pin!(A6Pin);
105 declare_pin!(A7Pin);
106 declare_pin!(A8Pin);
107 declare_pin!(A9Pin);
108 declare_pin!(A10Pin);
109 declare_pin!(A11Pin);
110 declare_pin!(A12Pin);
111 declare_pin!(A13Pin);
112 declare_pin!(A14Pin);
113 declare_pin!(A15Pin);
114 declare_pin!(A16Pin);
115 declare_pin!(A17Pin);
116 declare_pin!(A18Pin);
117 declare_pin!(A19Pin);
118 declare_pin!(A20Pin);
119 declare_pin!(A21Pin);
120 declare_pin!(A22Pin);
121 declare_pin!(A23Pin);
122 declare_pin!(A24Pin);
123 declare_pin!(A25Pin);
124} 5}
125 6
126macro_rules! declare_pin { 7pub trait Instance: sealed::Instance + 'static {}
127 ($name:ident, $fmc_pin:ident) => { 8
128 pub trait $name: sealed::$name + stm32_fmc::$fmc_pin + 'static {} 9pin_trait!(SDNWEPin, Instance);
129 }; 10pin_trait!(SDNCASPin, Instance);
130} 11pin_trait!(SDNRASPin, Instance);
131 12
132declare_pin!(SDNWEPin, SDNWE); 13pin_trait!(SDNE0Pin, Instance);
133declare_pin!(SDNCASPin, SDNCAS); 14pin_trait!(SDNE1Pin, Instance);
134declare_pin!(SDNRASPin, SDNRAS); 15
135 16pin_trait!(SDCKE0Pin, Instance);
136declare_pin!(SDNE0Pin, SDNE0); 17pin_trait!(SDCKE1Pin, Instance);
137declare_pin!(SDNE1Pin, SDNE1); 18
138 19pin_trait!(SDCLKPin, Instance);
139declare_pin!(SDCKE0Pin, SDCKE0); 20
140declare_pin!(SDCKE1Pin, SDCKE1); 21pin_trait!(NBL0Pin, Instance);
141 22pin_trait!(NBL1Pin, Instance);
142declare_pin!(SDCLKPin, SDCLK); 23pin_trait!(NBL2Pin, Instance);
143 24pin_trait!(NBL3Pin, Instance);
144declare_pin!(NBL0Pin, NBL0); 25
145declare_pin!(NBL1Pin, NBL1); 26pin_trait!(INTPin, Instance);
146declare_pin!(NBL2Pin, NBL2); 27pin_trait!(NLPin, Instance);
147declare_pin!(NBL3Pin, NBL3); 28pin_trait!(NWaitPin, Instance);
148 29
149declare_pin!(INTPin, INT); 30pin_trait!(NE1Pin, Instance);
150declare_pin!(NLPin, NL); 31pin_trait!(NE2Pin, Instance);
151declare_pin!(NWaitPin, NWAIT); 32pin_trait!(NE3Pin, Instance);
152 33pin_trait!(NE4Pin, Instance);
153declare_pin!(NE1Pin, NE1); 34
154declare_pin!(NE2Pin, NE2); 35pin_trait!(NCEPin, Instance);
155declare_pin!(NE3Pin, NE3); 36pin_trait!(NOEPin, Instance);
156declare_pin!(NE4Pin, NE4); 37pin_trait!(NWEPin, Instance);
157 38pin_trait!(ClkPin, Instance);
158declare_pin!(NCEPin, NCE); 39
159declare_pin!(NOEPin, NOE); 40pin_trait!(BA0Pin, Instance);
160declare_pin!(NWEPin, NWE); 41pin_trait!(BA1Pin, Instance);
161declare_pin!(ClkPin, CLK); 42
162 43pin_trait!(D0Pin, Instance);
163declare_pin!(BA0Pin, BA0); 44pin_trait!(D1Pin, Instance);
164declare_pin!(BA1Pin, BA1); 45pin_trait!(D2Pin, Instance);
165 46pin_trait!(D3Pin, Instance);
166declare_pin!(D0Pin, D0); 47pin_trait!(D4Pin, Instance);
167declare_pin!(D1Pin, D1); 48pin_trait!(D5Pin, Instance);
168declare_pin!(D2Pin, D2); 49pin_trait!(D6Pin, Instance);
169declare_pin!(D3Pin, D3); 50pin_trait!(D7Pin, Instance);
170declare_pin!(D4Pin, D4); 51pin_trait!(D8Pin, Instance);
171declare_pin!(D5Pin, D5); 52pin_trait!(D9Pin, Instance);
172declare_pin!(D6Pin, D6); 53pin_trait!(D10Pin, Instance);
173declare_pin!(D7Pin, D7); 54pin_trait!(D11Pin, Instance);
174declare_pin!(D8Pin, D8); 55pin_trait!(D12Pin, Instance);
175declare_pin!(D9Pin, D9); 56pin_trait!(D13Pin, Instance);
176declare_pin!(D10Pin, D10); 57pin_trait!(D14Pin, Instance);
177declare_pin!(D11Pin, D11); 58pin_trait!(D15Pin, Instance);
178declare_pin!(D12Pin, D12); 59pin_trait!(D16Pin, Instance);
179declare_pin!(D13Pin, D13); 60pin_trait!(D17Pin, Instance);
180declare_pin!(D14Pin, D14); 61pin_trait!(D18Pin, Instance);
181declare_pin!(D15Pin, D15); 62pin_trait!(D19Pin, Instance);
182declare_pin!(D16Pin, D16); 63pin_trait!(D20Pin, Instance);
183declare_pin!(D17Pin, D17); 64pin_trait!(D21Pin, Instance);
184declare_pin!(D18Pin, D18); 65pin_trait!(D22Pin, Instance);
185declare_pin!(D19Pin, D19); 66pin_trait!(D23Pin, Instance);
186declare_pin!(D20Pin, D20); 67pin_trait!(D24Pin, Instance);
187declare_pin!(D21Pin, D21); 68pin_trait!(D25Pin, Instance);
188declare_pin!(D22Pin, D22); 69pin_trait!(D26Pin, Instance);
189declare_pin!(D23Pin, D23); 70pin_trait!(D27Pin, Instance);
190declare_pin!(D24Pin, D24); 71pin_trait!(D28Pin, Instance);
191declare_pin!(D25Pin, D25); 72pin_trait!(D29Pin, Instance);
192declare_pin!(D26Pin, D26); 73pin_trait!(D30Pin, Instance);
193declare_pin!(D27Pin, D27); 74pin_trait!(D31Pin, Instance);
194declare_pin!(D28Pin, D28); 75
195declare_pin!(D29Pin, D29); 76pin_trait!(DA0Pin, Instance);
196declare_pin!(D30Pin, D30); 77pin_trait!(DA1Pin, Instance);
197declare_pin!(D31Pin, D31); 78pin_trait!(DA2Pin, Instance);
198 79pin_trait!(DA3Pin, Instance);
199declare_pin!(DA0Pin, DA0); 80pin_trait!(DA4Pin, Instance);
200declare_pin!(DA1Pin, DA1); 81pin_trait!(DA5Pin, Instance);
201declare_pin!(DA2Pin, DA2); 82pin_trait!(DA6Pin, Instance);
202declare_pin!(DA3Pin, DA3); 83pin_trait!(DA7Pin, Instance);
203declare_pin!(DA4Pin, DA4); 84pin_trait!(DA8Pin, Instance);
204declare_pin!(DA5Pin, DA5); 85pin_trait!(DA9Pin, Instance);
205declare_pin!(DA6Pin, DA6); 86pin_trait!(DA10Pin, Instance);
206declare_pin!(DA7Pin, DA7); 87pin_trait!(DA11Pin, Instance);
207declare_pin!(DA8Pin, DA8); 88pin_trait!(DA12Pin, Instance);
208declare_pin!(DA9Pin, DA9); 89pin_trait!(DA13Pin, Instance);
209declare_pin!(DA10Pin, DA10); 90pin_trait!(DA14Pin, Instance);
210declare_pin!(DA11Pin, DA11); 91pin_trait!(DA15Pin, Instance);
211declare_pin!(DA12Pin, DA12); 92
212declare_pin!(DA13Pin, DA13); 93pin_trait!(A0Pin, Instance);
213declare_pin!(DA14Pin, DA14); 94pin_trait!(A1Pin, Instance);
214declare_pin!(DA15Pin, DA15); 95pin_trait!(A2Pin, Instance);
215 96pin_trait!(A3Pin, Instance);
216declare_pin!(A0Pin, A0); 97pin_trait!(A4Pin, Instance);
217declare_pin!(A1Pin, A1); 98pin_trait!(A5Pin, Instance);
218declare_pin!(A2Pin, A2); 99pin_trait!(A6Pin, Instance);
219declare_pin!(A3Pin, A3); 100pin_trait!(A7Pin, Instance);
220declare_pin!(A4Pin, A4); 101pin_trait!(A8Pin, Instance);
221declare_pin!(A5Pin, A5); 102pin_trait!(A9Pin, Instance);
222declare_pin!(A6Pin, A6); 103pin_trait!(A10Pin, Instance);
223declare_pin!(A7Pin, A7); 104pin_trait!(A11Pin, Instance);
224declare_pin!(A8Pin, A8); 105pin_trait!(A12Pin, Instance);
225declare_pin!(A9Pin, A9); 106pin_trait!(A13Pin, Instance);
226declare_pin!(A10Pin, A10); 107pin_trait!(A14Pin, Instance);
227declare_pin!(A11Pin, A11); 108pin_trait!(A15Pin, Instance);
228declare_pin!(A12Pin, A12); 109pin_trait!(A16Pin, Instance);
229declare_pin!(A13Pin, A13); 110pin_trait!(A17Pin, Instance);
230declare_pin!(A14Pin, A14); 111pin_trait!(A18Pin, Instance);
231declare_pin!(A15Pin, A15); 112pin_trait!(A19Pin, Instance);
232declare_pin!(A16Pin, A16); 113pin_trait!(A20Pin, Instance);
233declare_pin!(A17Pin, A17); 114pin_trait!(A21Pin, Instance);
234declare_pin!(A18Pin, A18); 115pin_trait!(A22Pin, Instance);
235declare_pin!(A19Pin, A19); 116pin_trait!(A23Pin, Instance);
236declare_pin!(A20Pin, A20); 117pin_trait!(A24Pin, Instance);
237declare_pin!(A21Pin, A21); 118pin_trait!(A25Pin, Instance);
238declare_pin!(A22Pin, A22);
239declare_pin!(A23Pin, A23);
240declare_pin!(A24Pin, A24);
241declare_pin!(A25Pin, A25);
242
243macro_rules! impl_pin {
244 ($pin:ident, $signal:ident, $fmc_name:ident, $af:expr) => {
245 impl sealed::$signal for crate::peripherals::$pin {
246 fn configure(&mut self) {
247 use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
248 use crate::gpio::Pin;
249 use crate::gpio::Speed;
250 use crate::pac::gpio::vals::Pupdr;
251
252 critical_section::with(|_| unsafe {
253 self.set_as_af($af, OutputPushPull);
254 self.set_speed(Speed::VeryHigh);
255
256 self.block()
257 .pupdr()
258 .modify(|w| w.set_pupdr(self.pin() as usize, Pupdr::PULLUP));
259 })
260 }
261 }
262
263 impl stm32_fmc::$fmc_name for crate::peripherals::$pin {}
264
265 impl $signal for crate::peripherals::$pin {}
266 };
267}
268 119
269crate::pac::peripheral_pins!( 120crate::pac::peripheral_pins!(
270 ($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => { 121 ($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => {
271 impl_pin!($pin, A0Pin, A0, $af); 122 pin_trait_impl!(A0Pin, $inst, $pin, $af);
272 }; 123 };
273
274 ($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => { 124 ($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => {
275 impl_pin!($pin, A1Pin, A1, $af); 125 pin_trait_impl!(A1Pin, $inst, $pin, $af);
276 }; 126 };
277
278 ($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => { 127 ($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => {
279 impl_pin!($pin, A2Pin, A2, $af); 128 pin_trait_impl!(A2Pin, $inst, $pin, $af);
280 }; 129 };
281
282 ($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => { 130 ($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => {
283 impl_pin!($pin, A3Pin, A3, $af); 131 pin_trait_impl!(A3Pin, $inst, $pin, $af);
284 }; 132 };
285
286 ($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => { 133 ($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => {
287 impl_pin!($pin, A4Pin, A4, $af); 134 pin_trait_impl!(A4Pin, $inst, $pin, $af);
288 }; 135 };
289
290 ($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => { 136 ($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => {
291 impl_pin!($pin, A5Pin, A5, $af); 137 pin_trait_impl!(A5Pin, $inst, $pin, $af);
292 }; 138 };
293
294 ($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => { 139 ($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => {
295 impl_pin!($pin, A6Pin, A6, $af); 140 pin_trait_impl!(A6Pin, $inst, $pin, $af);
296 }; 141 };
297
298 ($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => { 142 ($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => {
299 impl_pin!($pin, A7Pin, A7, $af); 143 pin_trait_impl!(A7Pin, $inst, $pin, $af);
300 }; 144 };
301
302 ($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => { 145 ($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => {
303 impl_pin!($pin, A8Pin, A8, $af); 146 pin_trait_impl!(A8Pin, $inst, $pin, $af);
304 }; 147 };
305
306 ($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => { 148 ($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => {
307 impl_pin!($pin, A9Pin, A9, $af); 149 pin_trait_impl!(A9Pin, $inst, $pin, $af);
308 }; 150 };
309
310 ($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => { 151 ($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => {
311 impl_pin!($pin, A10Pin, A10, $af); 152 pin_trait_impl!(A10Pin, $inst, $pin, $af);
312 }; 153 };
313
314 ($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => { 154 ($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => {
315 impl_pin!($pin, A11Pin, A11, $af); 155 pin_trait_impl!(A11Pin, $inst, $pin, $af);
316 }; 156 };
317
318 ($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => { 157 ($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => {
319 impl_pin!($pin, A12Pin, A12, $af); 158 pin_trait_impl!(A12Pin, $inst, $pin, $af);
320 }; 159 };
321
322 ($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => { 160 ($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => {
323 impl_pin!($pin, A13Pin, A13, $af); 161 pin_trait_impl!(A13Pin, $inst, $pin, $af);
324 }; 162 };
325
326 ($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => { 163 ($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => {
327 impl_pin!($pin, A14Pin, A14, $af); 164 pin_trait_impl!(A14Pin, $inst, $pin, $af);
328 }; 165 };
329
330 ($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => { 166 ($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => {
331 impl_pin!($pin, A15Pin, A15, $af); 167 pin_trait_impl!(A15Pin, $inst, $pin, $af);
332 }; 168 };
333
334 ($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => { 169 ($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => {
335 impl_pin!($pin, A16Pin, A16, $af); 170 pin_trait_impl!(A16Pin, $inst, $pin, $af);
336 }; 171 };
337
338 ($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => { 172 ($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => {
339 impl_pin!($pin, A17Pin, A17, $af); 173 pin_trait_impl!(A17Pin, $inst, $pin, $af);
340 }; 174 };
341
342 ($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => { 175 ($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => {
343 impl_pin!($pin, A18Pin, A18, $af); 176 pin_trait_impl!(A18Pin, $inst, $pin, $af);
344 }; 177 };
345
346 ($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => { 178 ($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => {
347 impl_pin!($pin, A19Pin, A19, $af); 179 pin_trait_impl!(A19Pin, $inst, $pin, $af);
348 }; 180 };
349
350 ($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => { 181 ($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => {
351 impl_pin!($pin, A20Pin, A20, $af); 182 pin_trait_impl!(A20Pin, $inst, $pin, $af);
352 }; 183 };
353
354 ($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => { 184 ($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => {
355 impl_pin!($pin, A21Pin, A21, $af); 185 pin_trait_impl!(A21Pin, $inst, $pin, $af);
356 }; 186 };
357
358 ($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => { 187 ($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => {
359 impl_pin!($pin, A22Pin, A22, $af); 188 pin_trait_impl!(A22Pin, $inst, $pin, $af);
360 }; 189 };
361
362 ($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => { 190 ($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => {
363 impl_pin!($pin, A23Pin, A23, $af); 191 pin_trait_impl!(A23Pin, $inst, $pin, $af);
364 }; 192 };
365
366 ($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => { 193 ($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => {
367 impl_pin!($pin, A24Pin, A24, $af); 194 pin_trait_impl!(A24Pin, $inst, $pin, $af);
368 }; 195 };
369
370 ($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => { 196 ($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => {
371 impl_pin!($pin, A25Pin, A25, $af); 197 pin_trait_impl!(A25Pin, $inst, $pin, $af);
372 }; 198 };
373);
374
375crate::pac::peripheral_pins!(
376 ($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => { 199 ($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => {
377 impl_pin!($pin, D0Pin, D0, $af); 200 pin_trait_impl!(D0Pin, $inst, $pin, $af);
378 }; 201 };
379
380 ($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => { 202 ($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => {
381 impl_pin!($pin, D1Pin, D1, $af); 203 pin_trait_impl!(D1Pin, $inst, $pin, $af);
382 }; 204 };
383
384 ($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => { 205 ($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => {
385 impl_pin!($pin, D2Pin, D2, $af); 206 pin_trait_impl!(D2Pin, $inst, $pin, $af);
386 }; 207 };
387
388 ($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => { 208 ($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => {
389 impl_pin!($pin, D3Pin, D3, $af); 209 pin_trait_impl!(D3Pin, $inst, $pin, $af);
390 }; 210 };
391
392 ($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => { 211 ($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => {
393 impl_pin!($pin, D4Pin, D4, $af); 212 pin_trait_impl!(D4Pin, $inst, $pin, $af);
394 }; 213 };
395
396 ($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => { 214 ($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => {
397 impl_pin!($pin, D5Pin, D5, $af); 215 pin_trait_impl!(D5Pin, $inst, $pin, $af);
398 }; 216 };
399
400 ($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => { 217 ($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => {
401 impl_pin!($pin, D6Pin, D6, $af); 218 pin_trait_impl!(D6Pin, $inst, $pin, $af);
402 }; 219 };
403
404 ($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => { 220 ($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => {
405 impl_pin!($pin, D7Pin, D7, $af); 221 pin_trait_impl!(D7Pin, $inst, $pin, $af);
406 }; 222 };
407
408 ($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => { 223 ($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => {
409 impl_pin!($pin, D8Pin, D8, $af); 224 pin_trait_impl!(D8Pin, $inst, $pin, $af);
410 }; 225 };
411
412 ($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => { 226 ($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => {
413 impl_pin!($pin, D9Pin, D9, $af); 227 pin_trait_impl!(D9Pin, $inst, $pin, $af);
414 }; 228 };
415
416 ($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => { 229 ($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => {
417 impl_pin!($pin, D10Pin, D10, $af); 230 pin_trait_impl!(D10Pin, $inst, $pin, $af);
418 }; 231 };
419
420 ($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => { 232 ($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => {
421 impl_pin!($pin, D11Pin, D11, $af); 233 pin_trait_impl!(D11Pin, $inst, $pin, $af);
422 }; 234 };
423
424 ($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => { 235 ($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => {
425 impl_pin!($pin, D12Pin, D12, $af); 236 pin_trait_impl!(D12Pin, $inst, $pin, $af);
426 }; 237 };
427
428 ($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => { 238 ($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => {
429 impl_pin!($pin, D13Pin, D13, $af); 239 pin_trait_impl!(D13Pin, $inst, $pin, $af);
430 }; 240 };
431
432 ($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => { 241 ($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => {
433 impl_pin!($pin, D14Pin, D14, $af); 242 pin_trait_impl!(D14Pin, $inst, $pin, $af);
434 }; 243 };
435
436 ($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => { 244 ($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => {
437 impl_pin!($pin, D15Pin, D15, $af); 245 pin_trait_impl!(D15Pin, $inst, $pin, $af);
438 }; 246 };
439
440 ($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => { 247 ($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => {
441 impl_pin!($pin, D16Pin, D16, $af); 248 pin_trait_impl!(D16Pin, $inst, $pin, $af);
442 }; 249 };
443
444 ($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => { 250 ($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => {
445 impl_pin!($pin, D17Pin, D17, $af); 251 pin_trait_impl!(D17Pin, $inst, $pin, $af);
446 }; 252 };
447
448 ($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => { 253 ($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => {
449 impl_pin!($pin, D18Pin, D18, $af); 254 pin_trait_impl!(D18Pin, $inst, $pin, $af);
450 }; 255 };
451
452 ($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => { 256 ($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => {
453 impl_pin!($pin, D19Pin, D19, $af); 257 pin_trait_impl!(D19Pin, $inst, $pin, $af);
454 }; 258 };
455
456 ($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => { 259 ($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => {
457 impl_pin!($pin, D20Pin, D20, $af); 260 pin_trait_impl!(D20Pin, $inst, $pin, $af);
458 }; 261 };
459
460 ($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => { 262 ($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => {
461 impl_pin!($pin, D21Pin, D21, $af); 263 pin_trait_impl!(D21Pin, $inst, $pin, $af);
462 }; 264 };
463
464 ($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => { 265 ($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => {
465 impl_pin!($pin, D22Pin, D22, $af); 266 pin_trait_impl!(D22Pin, $inst, $pin, $af);
466 }; 267 };
467
468 ($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => { 268 ($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => {
469 impl_pin!($pin, D23Pin, D23, $af); 269 pin_trait_impl!(D23Pin, $inst, $pin, $af);
470 }; 270 };
471
472 ($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => { 271 ($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => {
473 impl_pin!($pin, D24Pin, D24, $af); 272 pin_trait_impl!(D24Pin, $inst, $pin, $af);
474 }; 273 };
475
476 ($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => { 274 ($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => {
477 impl_pin!($pin, D25Pin, D25, $af); 275 pin_trait_impl!(D25Pin, $inst, $pin, $af);
478 }; 276 };
479
480 ($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => { 277 ($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => {
481 impl_pin!($pin, D26Pin, D26, $af); 278 pin_trait_impl!(D26Pin, $inst, $pin, $af);
482 }; 279 };
483
484 ($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => { 280 ($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => {
485 impl_pin!($pin, D27Pin, D27, $af); 281 pin_trait_impl!(D27Pin, $inst, $pin, $af);
486 }; 282 };
487
488 ($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => { 283 ($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => {
489 impl_pin!($pin, D28Pin, D28, $af); 284 pin_trait_impl!(D28Pin, $inst, $pin, $af);
490 }; 285 };
491
492 ($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => { 286 ($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => {
493 impl_pin!($pin, D29Pin, D29, $af); 287 pin_trait_impl!(D29Pin, $inst, $pin, $af);
494 }; 288 };
495
496 ($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => { 289 ($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => {
497 impl_pin!($pin, D30Pin, D30, $af); 290 pin_trait_impl!(D30Pin, $inst, $pin, $af);
498 }; 291 };
499
500 ($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => { 292 ($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => {
501 impl_pin!($pin, D31Pin, D31, $af); 293 pin_trait_impl!(D31Pin, $inst, $pin, $af);
502 }; 294 };
503);
504
505crate::pac::peripheral_pins!(
506 ($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => { 295 ($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => {
507 impl_pin!($pin, DA0Pin, DA0, $af); 296 pin_trait_impl!(DA0Pin, $inst, $pin, $af);
508 }; 297 };
509
510 ($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => { 298 ($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => {
511 impl_pin!($pin, DA1Pin, DA1, $af); 299 pin_trait_impl!(DA1Pin, $inst, $pin, $af);
512 }; 300 };
513
514 ($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => { 301 ($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => {
515 impl_pin!($pin, DA2Pin, DA2, $af); 302 pin_trait_impl!(DA2Pin, $inst, $pin, $af);
516 }; 303 };
517
518 ($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => { 304 ($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => {
519 impl_pin!($pin, DA3Pin, DA3, $af); 305 pin_trait_impl!(DA3Pin, $inst, $pin, $af);
520 }; 306 };
521
522 ($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => { 307 ($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => {
523 impl_pin!($pin, DA4Pin, DA4, $af); 308 pin_trait_impl!(DA4Pin, $inst, $pin, $af);
524 }; 309 };
525
526 ($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => { 310 ($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => {
527 impl_pin!($pin, DA5Pin, DA5, $af); 311 pin_trait_impl!(DA5Pin, $inst, $pin, $af);
528 }; 312 };
529
530 ($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => { 313 ($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => {
531 impl_pin!($pin, DA6Pin, DA6, $af); 314 pin_trait_impl!(DA6Pin, $inst, $pin, $af);
532 }; 315 };
533
534 ($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => { 316 ($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => {
535 impl_pin!($pin, DA7Pin, DA7, $af); 317 pin_trait_impl!(DA7Pin, $inst, $pin, $af);
536 }; 318 };
537
538 ($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => { 319 ($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => {
539 impl_pin!($pin, DA8Pin, DA8, $af); 320 pin_trait_impl!(DA8Pin, $inst, $pin, $af);
540 }; 321 };
541
542 ($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => { 322 ($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => {
543 impl_pin!($pin, DA9Pin, DA9, $af); 323 pin_trait_impl!(DA9Pin, $inst, $pin, $af);
544 }; 324 };
545
546 ($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => { 325 ($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => {
547 impl_pin!($pin, DA10Pin, DA10, $af); 326 pin_trait_impl!(DA10Pin, $inst, $pin, $af);
548 }; 327 };
549
550 ($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => { 328 ($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => {
551 impl_pin!($pin, DA11Pin, DA11, $af); 329 pin_trait_impl!(DA11Pin, $inst, $pin, $af);
552 }; 330 };
553
554 ($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => { 331 ($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => {
555 impl_pin!($pin, DA12Pin, DA12, $af); 332 pin_trait_impl!(DA12Pin, $inst, $pin, $af);
556 }; 333 };
557
558 ($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => { 334 ($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => {
559 impl_pin!($pin, DA13Pin, DA13, $af); 335 pin_trait_impl!(DA13Pin, $inst, $pin, $af);
560 }; 336 };
561
562 ($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => { 337 ($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => {
563 impl_pin!($pin, DA14Pin, DA14, $af); 338 pin_trait_impl!(DA14Pin, $inst, $pin, $af);
564 }; 339 };
565
566 ($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => { 340 ($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => {
567 impl_pin!($pin, DA15Pin, DA15, $af); 341 pin_trait_impl!(DA15Pin, $inst, $pin, $af);
568 }; 342 };
569
570);
571
572crate::pac::peripheral_pins!(
573 ($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => { 343 ($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => {
574 impl_pin!($pin, SDNWEPin, SDNWE, $af); 344 pin_trait_impl!(SDNWEPin, $inst, $pin, $af);
575 }; 345 };
576
577 ($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => { 346 ($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => {
578 impl_pin!($pin, SDNCASPin, SDNCAS, $af); 347 pin_trait_impl!(SDNCASPin, $inst, $pin, $af);
579 }; 348 };
580
581 ($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => { 349 ($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => {
582 impl_pin!($pin, SDNRASPin, SDNRAS, $af); 350 pin_trait_impl!(SDNRASPin, $inst, $pin, $af);
583 }; 351 };
584
585 ($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => { 352 ($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => {
586 impl_pin!($pin, SDNE0Pin, SDNE0, $af); 353 pin_trait_impl!(SDNE0Pin, $inst, $pin, $af);
587 }; 354 };
588
589 ($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => { 355 ($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => {
590 impl_pin!($pin, SDNE1Pin, SDNE1, $af); 356 pin_trait_impl!(SDNE1Pin, $inst, $pin, $af);
591 }; 357 };
592
593 ($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => { 358 ($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => {
594 impl_pin!($pin, SDCKE0Pin, SDCKE0, $af); 359 pin_trait_impl!(SDCKE0Pin, $inst, $pin, $af);
595 }; 360 };
596
597 ($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => { 361 ($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => {
598 impl_pin!($pin, SDCKE1Pin, SDCKE1, $af); 362 pin_trait_impl!(SDCKE1Pin, $inst, $pin, $af);
599 }; 363 };
600
601 ($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => { 364 ($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => {
602 impl_pin!($pin, SDCLKPin, SDCLK, $af); 365 pin_trait_impl!(SDCLKPin, $inst, $pin, $af);
603 }; 366 };
604
605 ($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => { 367 ($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => {
606 impl_pin!($pin, NBL0Pin, NBL0, $af); 368 pin_trait_impl!(NBL0Pin, $inst, $pin, $af);
607 }; 369 };
608
609 ($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => { 370 ($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => {
610 impl_pin!($pin, NBL1Pin, NBL1, $af); 371 pin_trait_impl!(NBL1Pin, $inst, $pin, $af);
611 }; 372 };
612
613 ($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => { 373 ($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => {
614 impl_pin!($pin, NBL2Pin, NBL2, $af); 374 pin_trait_impl!(NBL2Pin, $inst, $pin, $af);
615 }; 375 };
616
617 ($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => { 376 ($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => {
618 impl_pin!($pin, NBL3Pin, NBL3, $af); 377 pin_trait_impl!(NBL3Pin, $inst, $pin, $af);
619 }; 378 };
620
621 ($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => { 379 ($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => {
622 impl_pin!($pin, INTPin, INT, $af); 380 pin_trait_impl!(INTPin, $inst, $pin, $af);
623 }; 381 };
624
625 ($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => { 382 ($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => {
626 impl_pin!($pin, NLPin, NL, $af); 383 pin_trait_impl!(NLPin, $inst, $pin, $af);
627 }; 384 };
628
629 ($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => { 385 ($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => {
630 impl_pin!($pin, NWaitPin, NWAIT, $af); 386 pin_trait_impl!(NWaitPin, $inst, $pin, $af);
631 }; 387 };
632
633 ($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => { 388 ($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => {
634 impl_pin!($pin, NE1Pin, NE1, $af); 389 pin_trait_impl!(NE1Pin, $inst, $pin, $af);
635 }; 390 };
636
637 ($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => { 391 ($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => {
638 impl_pin!($pin, NE2Pin, NE2, $af); 392 pin_trait_impl!(NE2Pin, $inst, $pin, $af);
639 }; 393 };
640
641 ($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => { 394 ($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => {
642 impl_pin!($pin, NE3Pin, NE3, $af); 395 pin_trait_impl!(NE3Pin, $inst, $pin, $af);
643 }; 396 };
644
645 ($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => { 397 ($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => {
646 impl_pin!($pin, NE4Pin, NE4, $af); 398 pin_trait_impl!(NE4Pin, $inst, $pin, $af);
647 }; 399 };
648
649 ($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => { 400 ($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => {
650 impl_pin!($pin, NCEPin, NCE, $af); 401 pin_trait_impl!(NCEPin, $inst, $pin, $af);
651 }; 402 };
652
653 ($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => { 403 ($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => {
654 impl_pin!($pin, NOEPin, NOE, $af); 404 pin_trait_impl!(NOEPin, $inst, $pin, $af);
655 }; 405 };
656
657 ($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => { 406 ($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => {
658 impl_pin!($pin, NWEPin, NWE, $af); 407 pin_trait_impl!(NWEPin, $inst, $pin, $af);
659 }; 408 };
660
661 ($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => { 409 ($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => {
662 impl_pin!($pin, ClkPin, CLK, $af); 410 pin_trait_impl!(ClkPin, $inst, $pin, $af);
663 }; 411 };
664
665 ($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => { 412 ($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => {
666 impl_pin!($pin, BA0Pin, BA0, $af); 413 pin_trait_impl!(BA0Pin, $inst, $pin, $af);
667 }; 414 };
668
669 ($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => { 415 ($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => {
670 impl_pin!($pin, BA1Pin, BA1, $af); 416 pin_trait_impl!(BA1Pin, $inst, $pin, $af);
671 }; 417 };
672); 418);
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 175abbd27..0cd8f66d0 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -483,7 +483,7 @@ pub(crate) mod sealed {
483 pub trait OptionalPin {} 483 pub trait OptionalPin {}
484} 484}
485 485
486pub trait Pin: sealed::Pin + Sized { 486pub trait Pin: sealed::Pin + Sized + 'static {
487 #[cfg(feature = "exti")] 487 #[cfg(feature = "exti")]
488 type ExtiChannel: crate::exti::Channel; 488 type ExtiChannel: crate::exti::Channel;
489 489
@@ -638,3 +638,8 @@ mod eh02 {
638 } 638 }
639 } 639 }
640} 640}
641
642#[cfg(feature = "unstable-pac")]
643pub mod low_level {
644 pub use super::sealed::*;
645}
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 2dcb9b720..0980fd9e8 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -5,7 +5,7 @@ use embassy::interrupt::Interrupt;
5#[cfg_attr(i2c_v1, path = "v1.rs")] 5#[cfg_attr(i2c_v1, path = "v1.rs")]
6#[cfg_attr(i2c_v2, path = "v2.rs")] 6#[cfg_attr(i2c_v2, path = "v2.rs")]
7mod _version; 7mod _version;
8use crate::{dma, peripherals}; 8use crate::peripherals;
9pub use _version::*; 9pub use _version::*;
10 10
11#[derive(Debug)] 11#[derive(Debug)]
@@ -21,44 +21,20 @@ pub enum Error {
21} 21}
22 22
23pub(crate) mod sealed { 23pub(crate) mod sealed {
24 use super::dma; 24 pub trait Instance: crate::rcc::RccPeripheral {
25 use crate::gpio::Pin;
26 use crate::rcc::RccPeripheral;
27
28 pub trait Instance: RccPeripheral {
29 fn regs() -> crate::pac::i2c::I2c; 25 fn regs() -> crate::pac::i2c::I2c;
30
31 fn state_number() -> usize; 26 fn state_number() -> usize;
32 } 27 }
33
34 pub trait SclPin<T: Instance>: Pin {
35 fn af_num(&self) -> u8;
36 }
37
38 pub trait SdaPin<T: Instance>: Pin {
39 fn af_num(&self) -> u8;
40 }
41
42 pub trait RxDma<T: Instance> {
43 fn request(&self) -> dma::Request;
44 }
45
46 pub trait TxDma<T: Instance> {
47 fn request(&self) -> dma::Request;
48 }
49} 28}
50 29
51pub trait Instance: sealed::Instance + 'static { 30pub trait Instance: sealed::Instance + 'static {
52 type Interrupt: Interrupt; 31 type Interrupt: Interrupt;
53} 32}
54 33
55pub trait SclPin<T: Instance>: sealed::SclPin<T> + 'static {} 34pin_trait!(SclPin, Instance);
56 35pin_trait!(SdaPin, Instance);
57pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + 'static {} 36dma_trait!(RxDma, Instance);
58 37dma_trait!(TxDma, Instance);
59pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {}
60
61pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {}
62 38
63macro_rules! i2c_state { 39macro_rules! i2c_state {
64 (I2C1) => { 40 (I2C1) => {
@@ -93,77 +69,34 @@ crate::pac::interrupts!(
93 impl Instance for peripherals::$inst { 69 impl Instance for peripherals::$inst {
94 type Interrupt = crate::interrupt::$irq; 70 type Interrupt = crate::interrupt::$irq;
95 } 71 }
96
97 }; 72 };
98); 73);
99 74
100macro_rules! impl_pin {
101 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
102 impl $signal<peripherals::$inst> for peripherals::$pin {}
103
104 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
105 fn af_num(&self) -> u8 {
106 $af
107 }
108 }
109 };
110}
111
112#[cfg(not(rcc_f1))] 75#[cfg(not(rcc_f1))]
113crate::pac::peripheral_pins!( 76crate::pac::peripheral_pins!(
114 ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => { 77 ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
115 impl_pin!($inst, $pin, SdaPin, $af); 78 pin_trait_impl!(SdaPin, $inst, $pin, $af);
116 }; 79 };
117
118 ($inst:ident, i2c, I2C, $pin:ident, SCL, $af:expr) => { 80 ($inst:ident, i2c, I2C, $pin:ident, SCL, $af:expr) => {
119 impl_pin!($inst, $pin, SclPin, $af); 81 pin_trait_impl!(SclPin, $inst, $pin, $af);
120 }; 82 };
121); 83);
122 84
123#[cfg(rcc_f1)] 85#[cfg(rcc_f1)]
124crate::pac::peripheral_pins!( 86crate::pac::peripheral_pins!(
125 ($inst:ident, i2c, I2C, $pin:ident, SDA) => { 87 ($inst:ident, i2c, I2C, $pin:ident, SDA) => {
126 impl_pin!($inst, $pin, SdaPin, 0); 88 pin_trait_impl!(SdaPin, $inst, $pin, 0);
127 }; 89 };
128
129 ($inst:ident, i2c, I2C, $pin:ident, SCL) => { 90 ($inst:ident, i2c, I2C, $pin:ident, SCL) => {
130 impl_pin!($inst, $pin, SclPin, 0); 91 pin_trait_impl!(SdaPin, $inst, $pin, 0);
131 }; 92 };
132); 93);
133 94
134#[allow(unused)]
135macro_rules! impl_dma {
136 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
137 impl<T> sealed::$signal<peripherals::$inst> for T
138 where
139 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
140 {
141 fn request(&self) -> dma::Request {
142 $request
143 }
144 }
145
146 impl<T> $signal<peripherals::$inst> for T where
147 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
148 {
149 }
150 };
151 ($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
152 impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
153 fn request(&self) -> dma::Request {
154 $request
155 }
156 }
157
158 impl $signal<peripherals::$inst> for peripherals::$channel {}
159 };
160}
161
162crate::pac::peripheral_dma_channels! { 95crate::pac::peripheral_dma_channels! {
163 ($peri:ident, i2c, $kind:ident, RX, $channel:tt, $request:expr) => { 96 ($peri:ident, i2c, $kind:ident, RX, $channel:tt, $request:expr) => {
164 impl_dma!($peri, $channel, RxDma, $request); 97 dma_trait_impl!(RxDma, $peri, $channel, $request);
165 }; 98 };
166 ($peri:ident, i2c, $kind:ident, TX, $channel:tt, $request:expr) => { 99 ($peri:ident, i2c, $kind:ident, TX, $channel:tt, $request:expr) => {
167 impl_dma!($peri, $channel, TxDma, $request); 100 dma_trait_impl!(TxDma, $peri, $channel, $request);
168 }; 101 };
169} 102}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index a910f6950..b985b3e4f 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -13,6 +13,7 @@ pub mod fmt;
13// Utilities 13// Utilities
14pub mod interrupt; 14pub mod interrupt;
15pub mod time; 15pub mod time;
16mod traits;
16 17
17// Always-present hardware 18// Always-present hardware
18pub mod dma; 19pub mod dma;
diff --git a/embassy-stm32/src/pwm/mod.rs b/embassy-stm32/src/pwm/mod.rs
index 17a7cbd0a..7b41e8a56 100644
--- a/embassy-stm32/src/pwm/mod.rs
+++ b/embassy-stm32/src/pwm/mod.rs
@@ -1,11 +1,3 @@
1#[cfg(feature = "unstable-pac")]
2#[macro_use]
3pub mod pins;
4
5#[cfg(not(feature = "unstable-pac"))]
6#[macro_use]
7pub(crate) mod pins;
8
9pub mod simple_pwm; 1pub mod simple_pwm;
10 2
11#[cfg(feature = "unstable-pac")] 3#[cfg(feature = "unstable-pac")]
@@ -62,7 +54,7 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
62pub(crate) mod sealed { 54pub(crate) mod sealed {
63 use super::*; 55 use super::*;
64 56
65 pub trait CaptureCompareCapable16bitInstance: crate::timer::sealed::Basic16bitInstance { 57 pub trait CaptureCompare16bitInstance: crate::timer::sealed::Basic16bitInstance {
66 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); 58 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
67 59
68 unsafe fn enable_channel(&mut self, channel: Channel, enable: bool); 60 unsafe fn enable_channel(&mut self, channel: Channel, enable: bool);
@@ -72,7 +64,7 @@ pub(crate) mod sealed {
72 unsafe fn get_max_compare_value(&self) -> u16; 64 unsafe fn get_max_compare_value(&self) -> u16;
73 } 65 }
74 66
75 pub trait CaptureCompareCapable32bitInstance: 67 pub trait CaptureCompare32bitInstance:
76 crate::timer::sealed::GeneralPurpose32bitInstance 68 crate::timer::sealed::GeneralPurpose32bitInstance
77 { 69 {
78 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); 70 unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
@@ -85,19 +77,22 @@ pub(crate) mod sealed {
85 } 77 }
86} 78}
87 79
88pub trait CaptureCompareCapable16bitInstance: 80pub trait CaptureCompare16bitInstance:
89 sealed::CaptureCompareCapable16bitInstance + crate::timer::Basic16bitInstance + 'static 81 sealed::CaptureCompare16bitInstance + crate::timer::Basic16bitInstance + 'static
90{ 82{
91} 83}
92pub trait CaptureCompareCapable32bitInstance: 84pub trait CaptureCompare32bitInstance:
93 sealed::CaptureCompareCapable32bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static 85 sealed::CaptureCompare32bitInstance
86 + CaptureCompare16bitInstance
87 + crate::timer::GeneralPurpose32bitInstance
88 + 'static
94{ 89{
95} 90}
96 91
97#[allow(unused)] 92#[allow(unused)]
98macro_rules! impl_compare_capable_16bit { 93macro_rules! impl_compare_capable_16bit {
99 ($inst:ident) => { 94 ($inst:ident) => {
100 impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 95 impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
101 unsafe fn set_output_compare_mode( 96 unsafe fn set_output_compare_mode(
102 &mut self, 97 &mut self,
103 channel: crate::pwm::Channel, 98 channel: crate::pwm::Channel,
@@ -134,7 +129,7 @@ macro_rules! impl_compare_capable_16bit {
134 129
135crate::pac::interrupts! { 130crate::pac::interrupts! {
136 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { 131 ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
137 impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 132 impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
138 unsafe fn set_output_compare_mode( 133 unsafe fn set_output_compare_mode(
139 &mut self, 134 &mut self,
140 channel: crate::pwm::Channel, 135 channel: crate::pwm::Channel,
@@ -167,14 +162,14 @@ crate::pac::interrupts! {
167 } 162 }
168 } 163 }
169 164
170 impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 165 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
171 166
172 } 167 }
173 }; 168 };
174 169
175 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { 170 ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
176 impl_compare_capable_16bit!($inst); 171 impl_compare_capable_16bit!($inst);
177 impl crate::pwm::sealed::CaptureCompareCapable32bitInstance for crate::peripherals::$inst { 172 impl crate::pwm::sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
178 unsafe fn set_output_compare_mode( 173 unsafe fn set_output_compare_mode(
179 &mut self, 174 &mut self,
180 channel: crate::pwm::Channel, 175 channel: crate::pwm::Channel,
@@ -200,16 +195,16 @@ crate::pac::interrupts! {
200 self.regs_gp32().arr().read().arr() as u32 195 self.regs_gp32().arr().read().arr() as u32
201 } 196 }
202 } 197 }
203 impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 198 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
204 199
205 } 200 }
206 impl CaptureCompareCapable32bitInstance for crate::peripherals::$inst { 201 impl CaptureCompare32bitInstance for crate::peripherals::$inst {
207 202
208 } 203 }
209 }; 204 };
210 205
211 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { 206 ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
212 impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 207 impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
213 unsafe fn set_output_compare_mode( 208 unsafe fn set_output_compare_mode(
214 &mut self, 209 &mut self,
215 channel: crate::pwm::Channel, 210 channel: crate::pwm::Channel,
@@ -242,56 +237,72 @@ crate::pac::interrupts! {
242 } 237 }
243 } 238 }
244 239
245 impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst { 240 impl CaptureCompare16bitInstance for crate::peripherals::$inst {
246 241
247 } 242 }
248 }; 243 };
249} 244}
250 245
246pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
247pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance);
248pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
249pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance);
250pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
251pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
252pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
253pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
254pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
255pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
256pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
257pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
258pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
259pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
260pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
261
251crate::pac::peripheral_pins!( 262crate::pac::peripheral_pins!(
252 ($inst:ident, timer, $block:ident, $pin:ident, CH1, $af:expr) => { 263 ($inst:ident, timer, $block:ident, $pin:ident, CH1, $af:expr) => {
253 impl_pin!($inst, Channel1Pin, $pin, $af); 264 pin_trait_impl!(Channel1Pin, $inst, $pin, $af);
254 }; 265 };
255 ($inst:ident, timer, $block:ident, $pin:ident, CH1N, $af:expr) => { 266 ($inst:ident, timer, $block:ident, $pin:ident, CH1N, $af:expr) => {
256 impl_pin!($inst, Channel1ComplementaryPin, $pin, $af); 267 pin_trait_impl!(Channel1ComplementaryPin, $inst, $pin, $af);
257 }; 268 };
258 ($inst:ident, timer, $block:ident, $pin:ident, CH2, $af:expr) => { 269 ($inst:ident, timer, $block:ident, $pin:ident, CH2, $af:expr) => {
259 impl_pin!($inst, Channel2Pin, $pin, $af); 270 pin_trait_impl!(Channel2Pin, $inst, $pin, $af);
260 }; 271 };
261 ($inst:ident, timer, $block:ident, $pin:ident, CH2N, $af:expr) => { 272 ($inst:ident, timer, $block:ident, $pin:ident, CH2N, $af:expr) => {
262 impl_pin!($inst, Channel2ComplementaryPin, $pin, $af); 273 pin_trait_impl!(Channel2ComplementaryPin, $inst, $pin, $af);
263 }; 274 };
264 ($inst:ident, timer, $block:ident, $pin:ident, CH3, $af:expr) => { 275 ($inst:ident, timer, $block:ident, $pin:ident, CH3, $af:expr) => {
265 impl_pin!($inst, Channel3Pin, $pin, $af); 276 pin_trait_impl!(Channel3Pin, $inst, $pin, $af);
266 }; 277 };
267 ($inst:ident, timer, $block:ident, $pin:ident, CH3N, $af:expr) => { 278 ($inst:ident, timer, $block:ident, $pin:ident, CH3N, $af:expr) => {
268 impl_pin!($inst, Channel3ComplementaryPin, $pin, $af); 279 pin_trait_impl!(Channel3ComplementaryPin, $inst, $pin, $af);
269 }; 280 };
270 ($inst:ident, timer, $block:ident, $pin:ident, CH4, $af:expr) => { 281 ($inst:ident, timer, $block:ident, $pin:ident, CH4, $af:expr) => {
271 impl_pin!($inst, Channel4Pin, $pin, $af); 282 pin_trait_impl!(Channel4Pin, $inst, $pin, $af);
272 }; 283 };
273 ($inst:ident, timer, $block:ident, $pin:ident, CH4N, $af:expr) => { 284 ($inst:ident, timer, $block:ident, $pin:ident, CH4N, $af:expr) => {
274 impl_pin!($inst, Channel4ComplementaryPin, $pin, $af); 285 pin_trait_impl!(Channel4ComplementaryPin, $inst, $pin, $af);
275 }; 286 };
276 ($inst:ident, timer, $block:ident, $pin:ident, ETR, $af:expr) => { 287 ($inst:ident, timer, $block:ident, $pin:ident, ETR, $af:expr) => {
277 impl_pin!($inst, ExternalTriggerPin, $pin, $af); 288 pin_trait_impl!(ExternalTriggerPin, $inst, $pin, $af);
278 }; 289 };
279 ($inst:ident, timer, $block:ident, $pin:ident, BKIN, $af:expr) => { 290 ($inst:ident, timer, $block:ident, $pin:ident, BKIN, $af:expr) => {
280 impl_pin!($inst, BreakInputPin, $pin, $af); 291 pin_trait_impl!(BreakInputPin, $inst, $pin, $af);
281 }; 292 };
282 ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP1, $af:expr) => { 293 ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP1, $af:expr) => {
283 impl_pin!($inst, BreakInputComparator1Pin, $pin, $af); 294 pin_trait_impl!(BreakInputComparator1Pin, $inst, $pin, $af);
284 }; 295 };
285 ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP2, $af:expr) => { 296 ($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP2, $af:expr) => {
286 impl_pin!($inst, BreakInputComparator2Pin, $pin, $af); 297 pin_trait_impl!(BreakInputComparator2Pin, $inst, $pin, $af);
287 }; 298 };
288 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2, $af:expr) => { 299 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2, $af:expr) => {
289 impl_pin!($inst, BreakInput2Pin, $pin, $af); 300 pin_trait_impl!(BreakInput2Pin, $inst, $pin, $af);
290 }; 301 };
291 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP1, $af:expr) => { 302 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP1, $af:expr) => {
292 impl_pin!($inst, BreakInput2Comparator1Pin, $pin, $af); 303 pin_trait_impl!(BreakInput2Comparator1Pin, $inst, $pin, $af);
293 }; 304 };
294 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP2, $af:expr) => { 305 ($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP2, $af:expr) => {
295 impl_pin!($inst, BreakInput2Comparator2Pin, $pin, $af); 306 pin_trait_impl!(BreakInput2Comparator2Pin, $inst, $pin, $af);
296 }; 307 };
297); 308);
diff --git a/embassy-stm32/src/pwm/pins.rs b/embassy-stm32/src/pwm/pins.rs
deleted file mode 100644
index 059e76231..000000000
--- a/embassy-stm32/src/pwm/pins.rs
+++ /dev/null
@@ -1,126 +0,0 @@
1use crate::gpio::Pin;
2
3#[cfg(feature = "unstable-pac")]
4pub mod low_level {
5 pub use super::sealed::*;
6}
7
8pub(crate) mod sealed {
9 use crate::gpio::sealed::Pin;
10
11 pub trait Channel1Pin<Timer>: Pin {
12 unsafe fn configure(&mut self);
13 }
14 pub trait Channel1ComplementaryPin<Timer>: Pin {
15 unsafe fn configure(&mut self);
16 }
17
18 pub trait Channel2Pin<Timer>: Pin {
19 unsafe fn configure(&mut self);
20 }
21 pub trait Channel2ComplementaryPin<Timer>: Pin {
22 unsafe fn configure(&mut self);
23 }
24
25 pub trait Channel3Pin<Timer>: Pin {
26 unsafe fn configure(&mut self);
27 }
28 pub trait Channel3ComplementaryPin<Timer>: Pin {
29 unsafe fn configure(&mut self);
30 }
31
32 pub trait Channel4Pin<Timer>: Pin {
33 unsafe fn configure(&mut self);
34 }
35 pub trait Channel4ComplementaryPin<Timer>: Pin {
36 unsafe fn configure(&mut self);
37 }
38
39 pub trait ExternalTriggerPin<Timer>: Pin {
40 unsafe fn configure(&mut self);
41 }
42
43 pub trait BreakInputPin<Timer>: Pin {
44 unsafe fn configure(&mut self);
45 }
46 pub trait BreakInputComparator1Pin<Timer>: Pin {
47 unsafe fn configure(&mut self);
48 }
49 pub trait BreakInputComparator2Pin<Timer>: Pin {
50 unsafe fn configure(&mut self);
51 }
52
53 pub trait BreakInput2Pin<Timer>: Pin {
54 unsafe fn configure(&mut self);
55 }
56 pub trait BreakInput2Comparator1Pin<Timer>: Pin {
57 unsafe fn configure(&mut self);
58 }
59 pub trait BreakInput2Comparator2Pin<Timer>: Pin {
60 unsafe fn configure(&mut self);
61 }
62}
63pub trait Channel1Pin<Timer>: sealed::Channel1Pin<Timer> + Pin + 'static {}
64pub trait Channel1ComplementaryPin<Timer>:
65 sealed::Channel1ComplementaryPin<Timer> + Pin + 'static
66{
67}
68
69pub trait Channel2Pin<Timer>: sealed::Channel2Pin<Timer> + 'static {}
70pub trait Channel2ComplementaryPin<Timer>:
71 sealed::Channel2ComplementaryPin<Timer> + Pin + 'static
72{
73}
74
75pub trait Channel3Pin<Timer>: sealed::Channel3Pin<Timer> + 'static {}
76pub trait Channel3ComplementaryPin<Timer>:
77 sealed::Channel3ComplementaryPin<Timer> + Pin + 'static
78{
79}
80
81pub trait Channel4Pin<Timer>: sealed::Channel4Pin<Timer> + 'static {}
82pub trait Channel4ComplementaryPin<Timer>:
83 sealed::Channel4ComplementaryPin<Timer> + Pin + 'static
84{
85}
86
87pub trait ExternalTriggerPin<Timer>: sealed::ExternalTriggerPin<Timer> + Pin + 'static {}
88
89pub trait BreakInputPin<Timer>: sealed::BreakInputPin<Timer> + Pin + 'static {}
90pub trait BreakInputComparator1Pin<Timer>:
91 sealed::BreakInputComparator1Pin<Timer> + Pin + 'static
92{
93}
94pub trait BreakInputComparator2Pin<Timer>:
95 sealed::BreakInputComparator2Pin<Timer> + Pin + 'static
96{
97}
98
99pub trait BreakInput2Pin<Timer>: sealed::BreakInput2Pin<Timer> + Pin + 'static {}
100pub trait BreakInput2Comparator1Pin<Timer>:
101 sealed::BreakInput2Comparator1Pin<Timer> + Pin + 'static
102{
103}
104pub trait BreakInput2Comparator2Pin<Timer>:
105 sealed::BreakInput2Comparator2Pin<Timer> + Pin + 'static
106{
107}
108
109#[allow(unused)]
110macro_rules! impl_pin {
111 ($timer:ident, $signal:ident, $pin:ident, $af:expr) => {
112 impl crate::pwm::pins::sealed::$signal<crate::peripherals::$timer>
113 for crate::peripherals::$pin
114 {
115 unsafe fn configure(&mut self) {
116 use crate::gpio::sealed::{AFType, Pin};
117 use crate::gpio::Speed;
118 self.set_low();
119 self.set_speed(Speed::VeryHigh);
120 self.set_as_af($af, AFType::OutputPushPull);
121 }
122 }
123
124 impl crate::pwm::pins::$signal<crate::peripherals::$timer> for crate::peripherals::$pin {}
125 };
126}
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/pwm/simple_pwm.rs
index 6e1b9ce0d..3706cc5ba 100644
--- a/embassy-stm32/src/pwm/simple_pwm.rs
+++ b/embassy-stm32/src/pwm/simple_pwm.rs
@@ -1,25 +1,40 @@
1use crate::{
2 pwm::{pins::*, CaptureCompareCapable16bitInstance, Channel, OutputCompareMode},
3 time::Hertz,
4};
5use core::marker::PhantomData; 1use core::marker::PhantomData;
6use embassy::util::Unborrow; 2use embassy::util::Unborrow;
7use embassy_hal_common::unborrow; 3use embassy_hal_common::unborrow;
8 4
5use super::*;
6#[allow(unused_imports)]
7use crate::gpio::sealed::{AFType, Pin};
8use crate::time::Hertz;
9
9pub struct SimplePwm<'d, T> { 10pub struct SimplePwm<'d, T> {
10 phantom: PhantomData<&'d mut T>, 11 phantom: PhantomData<&'d mut T>,
11 inner: T, 12 inner: T,
12} 13}
13 14
14impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> { 15macro_rules! config_pins {
16 ($($pin:ident),*) => {
17 unborrow!($($pin),*);
18 // NOTE(unsafe) Exclusive access to the registers
19 critical_section::with(|_| unsafe {
20 $(
21 $pin.set_low();
22 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
23 #[cfg(gpio_v2)]
24 $pin.set_speed(crate::gpio::Speed::VeryHigh);
25 )*
26 })
27 };
28}
29
30impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
15 pub fn new_1ch<F: Into<Hertz>>( 31 pub fn new_1ch<F: Into<Hertz>>(
16 tim: impl Unborrow<Target = T> + 'd, 32 tim: impl Unborrow<Target = T> + 'd,
17 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 33 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
18 freq: F, 34 freq: F,
19 ) -> Self { 35 ) -> Self {
20 unborrow!(ch1); 36 Self::new_inner(tim, freq, move || {
21 Self::new_inner(tim, freq, move || unsafe { 37 config_pins!(ch1);
22 ch1.configure();
23 }) 38 })
24 } 39 }
25 40
@@ -29,10 +44,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
29 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, 44 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
30 freq: F, 45 freq: F,
31 ) -> Self { 46 ) -> Self {
32 unborrow!(ch1, ch2); 47 Self::new_inner(tim, freq, move || {
33 Self::new_inner(tim, freq, move || unsafe { 48 config_pins!(ch1, ch2);
34 ch1.configure();
35 ch2.configure();
36 }) 49 })
37 } 50 }
38 51
@@ -43,11 +56,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
43 ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, 56 ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
44 freq: F, 57 freq: F,
45 ) -> Self { 58 ) -> Self {
46 unborrow!(ch1, ch2, ch3); 59 Self::new_inner(tim, freq, move || {
47 Self::new_inner(tim, freq, move || unsafe { 60 config_pins!(ch1, ch2, ch3);
48 ch1.configure();
49 ch2.configure();
50 ch3.configure();
51 }) 61 })
52 } 62 }
53 63
@@ -59,12 +69,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
59 ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd, 69 ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd,
60 freq: F, 70 freq: F,
61 ) -> Self { 71 ) -> Self {
62 unborrow!(ch1, ch2, ch3, ch4); 72 Self::new_inner(tim, freq, move || {
63 Self::new_inner(tim, freq, move || unsafe { 73 config_pins!(ch1, ch2, ch3, ch4);
64 ch1.configure();
65 ch2.configure();
66 ch3.configure();
67 ch4.configure();
68 }) 74 })
69 } 75 }
70 76
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs
index e5e604d09..23c916365 100644
--- a/embassy-stm32/src/rcc/h7.rs
+++ b/embassy-stm32/src/rcc/h7.rs
@@ -4,8 +4,8 @@ use embassy::util::Unborrow;
4use embassy_hal_common::unborrow; 4use embassy_hal_common::unborrow;
5use stm32_metapac::rcc::vals::{Mco1, Mco2}; 5use stm32_metapac::rcc::vals::{Mco1, Mco2};
6 6
7use crate::gpio::sealed::Pin as __GpioPin; 7use crate::gpio::sealed::AFType;
8use crate::gpio::Pin; 8use crate::gpio::Speed;
9use crate::pac::rcc::vals::Timpre; 9use crate::pac::rcc::vals::Timpre;
10use crate::pac::rcc::vals::{Ckpersel, Dppre, Hpre, Hsebyp, Hsidiv, Pllsrc, Sw}; 10use crate::pac::rcc::vals::{Ckpersel, Dppre, Hpre, Hsebyp, Hsidiv, Pllsrc, Sw};
11use crate::pac::{PWR, RCC, SYSCFG}; 11use crate::pac::{PWR, RCC, SYSCFG};
@@ -318,21 +318,15 @@ impl McoSource for Mco2Source {
318} 318}
319 319
320pub(crate) mod sealed { 320pub(crate) mod sealed {
321 use super::*;
322
323 pub trait McoInstance { 321 pub trait McoInstance {
324 type Source; 322 type Source;
325 unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8); 323 unsafe fn apply_clock_settings(source: Self::Source, prescaler: u8);
326 } 324 }
327
328 pub trait McoPin<T: McoInstance>: Pin {
329 fn configure(&mut self);
330 }
331} 325}
332 326
333pub trait McoInstance: sealed::McoInstance + 'static {} 327pub trait McoInstance: sealed::McoInstance + 'static {}
334 328
335pub trait McoPin<T: McoInstance>: sealed::McoPin<T> + 'static {} 329pin_trait!(McoPin, McoInstance);
336 330
337macro_rules! impl_peri { 331macro_rules! impl_peri {
338 ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { 332 ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
@@ -354,32 +348,12 @@ macro_rules! impl_peri {
354impl_peri!(MCO1, Mco1, set_mco1, set_mco1pre); 348impl_peri!(MCO1, Mco1, set_mco1, set_mco1pre);
355impl_peri!(MCO2, Mco2, set_mco2, set_mco2pre); 349impl_peri!(MCO2, Mco2, set_mco2, set_mco2pre);
356 350
357macro_rules! impl_pin {
358 ($peri:ident, $pin:ident, $af:expr) => {
359 impl McoPin<peripherals::$peri> for peripherals::$pin {}
360
361 impl sealed::McoPin<peripherals::$peri> for peripherals::$pin {
362 fn configure(&mut self) {
363 critical_section::with(|_| unsafe {
364 self.set_as_af($af, crate::gpio::sealed::AFType::OutputPushPull);
365 self.block().ospeedr().modify(|w| {
366 w.set_ospeedr(
367 self.pin() as usize,
368 crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED,
369 )
370 });
371 })
372 }
373 }
374 };
375}
376
377crate::pac::peripheral_pins!( 351crate::pac::peripheral_pins!(
378 ($inst:ident, rcc, RCC, $pin:ident, MCO_1, $af:expr) => { 352 ($inst:ident, rcc, RCC, $pin:ident, MCO_1, $af:expr) => {
379 impl_pin!(MCO1, $pin, $af); 353 pin_trait_impl!(McoPin, MCO1, $pin, $af);
380 }; 354 };
381 ($inst:ident, rcc, RCC, $pin:ident, MCO_2, $af:expr) => { 355 ($inst:ident, rcc, RCC, $pin:ident, MCO_2, $af:expr) => {
382 impl_pin!(MCO2, $pin, $af); 356 pin_trait_impl!(McoPin, MCO2, $pin, $af);
383 }; 357 };
384); 358);
385 359
@@ -396,11 +370,11 @@ impl<'d, T: McoInstance> Mco<'d, T> {
396 ) -> Self { 370 ) -> Self {
397 unborrow!(pin); 371 unborrow!(pin);
398 372
399 unsafe { 373 critical_section::with(|_| unsafe {
400 T::apply_clock_settings(source.into_raw(), prescaler.into_raw()); 374 T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
401 } 375 pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
402 376 pin.set_speed(Speed::VeryHigh);
403 pin.configure(); 377 });
404 378
405 Self { 379 Self {
406 phantom: PhantomData, 380 phantom: PhantomData,
diff --git a/embassy-stm32/src/sdmmc/v2.rs b/embassy-stm32/src/sdmmc/v2.rs
index 784a07f5b..733b8fdd9 100644
--- a/embassy-stm32/src/sdmmc/v2.rs
+++ b/embassy-stm32/src/sdmmc/v2.rs
@@ -1140,7 +1140,6 @@ impl Cmd {
1140 1140
1141pub(crate) mod sealed { 1141pub(crate) mod sealed {
1142 use super::*; 1142 use super::*;
1143 use crate::gpio::Pin as GpioPin;
1144 1143
1145 pub trait Instance { 1144 pub trait Instance {
1146 type Interrupt: Interrupt; 1145 type Interrupt: Interrupt;
@@ -1148,51 +1147,21 @@ pub(crate) mod sealed {
1148 fn inner() -> SdmmcInner; 1147 fn inner() -> SdmmcInner;
1149 fn state() -> &'static AtomicWaker; 1148 fn state() -> &'static AtomicWaker;
1150 } 1149 }
1151 pub trait CkPin<T: Instance>: GpioPin {
1152 const AF_NUM: u8;
1153 }
1154 pub trait CmdPin<T: Instance>: GpioPin {
1155 const AF_NUM: u8;
1156 }
1157 pub trait D0Pin<T: Instance>: GpioPin {
1158 const AF_NUM: u8;
1159 }
1160 pub trait D1Pin<T: Instance>: GpioPin {
1161 const AF_NUM: u8;
1162 }
1163 pub trait D2Pin<T: Instance>: GpioPin {
1164 const AF_NUM: u8;
1165 }
1166 pub trait D3Pin<T: Instance>: GpioPin {
1167 const AF_NUM: u8;
1168 }
1169 pub trait D4Pin<T: Instance>: GpioPin {
1170 const AF_NUM: u8;
1171 }
1172 pub trait D5Pin<T: Instance>: GpioPin {
1173 const AF_NUM: u8;
1174 }
1175 pub trait D6Pin<T: Instance>: GpioPin {
1176 const AF_NUM: u8;
1177 }
1178 pub trait D7Pin<T: Instance>: GpioPin {
1179 const AF_NUM: u8;
1180 }
1181 1150
1182 pub trait Pins<T: Instance> {} 1151 pub trait Pins<T: Instance> {}
1183} 1152}
1184 1153
1185pub trait Instance: sealed::Instance + 'static {} 1154pub trait Instance: sealed::Instance + 'static {}
1186pub trait CkPin<T: Instance>: sealed::CkPin<T> + 'static {} 1155pin_trait!(CkPin, Instance);
1187pub trait CmdPin<T: Instance>: sealed::CmdPin<T> + 'static {} 1156pin_trait!(CmdPin, Instance);
1188pub trait D0Pin<T: Instance>: sealed::D0Pin<T> + 'static {} 1157pin_trait!(D0Pin, Instance);
1189pub trait D1Pin<T: Instance>: sealed::D1Pin<T> + 'static {} 1158pin_trait!(D1Pin, Instance);
1190pub trait D2Pin<T: Instance>: sealed::D2Pin<T> + 'static {} 1159pin_trait!(D2Pin, Instance);
1191pub trait D3Pin<T: Instance>: sealed::D3Pin<T> + 'static {} 1160pin_trait!(D3Pin, Instance);
1192pub trait D4Pin<T: Instance>: sealed::D4Pin<T> + 'static {} 1161pin_trait!(D4Pin, Instance);
1193pub trait D5Pin<T: Instance>: sealed::D5Pin<T> + 'static {} 1162pin_trait!(D5Pin, Instance);
1194pub trait D6Pin<T: Instance>: sealed::D6Pin<T> + 'static {} 1163pin_trait!(D6Pin, Instance);
1195pub trait D7Pin<T: Instance>: sealed::D7Pin<T> + 'static {} 1164pin_trait!(D7Pin, Instance);
1196 1165
1197pub trait Pins<T: Instance>: sealed::Pins<T> + 'static { 1166pub trait Pins<T: Instance>: sealed::Pins<T> + 'static {
1198 const BUSWIDTH: BusWidth; 1167 const BUSWIDTH: BusWidth;
@@ -1258,37 +1227,37 @@ where
1258 // clk 1227 // clk
1259 let block = clk_pin.block(); 1228 let block = clk_pin.block();
1260 let n = clk_pin.pin() as usize; 1229 let n = clk_pin.pin() as usize;
1261 let afr_num = CLK::AF_NUM; 1230 let afr_num = clk_pin.af_num();
1262 configure_pin(block, n, afr_num, false); 1231 configure_pin(block, n, afr_num, false);
1263 1232
1264 // cmd 1233 // cmd
1265 let block = cmd_pin.block(); 1234 let block = cmd_pin.block();
1266 let n = cmd_pin.pin() as usize; 1235 let n = cmd_pin.pin() as usize;
1267 let afr_num = CMD::AF_NUM; 1236 let afr_num = cmd_pin.af_num();
1268 configure_pin(block, n, afr_num, true); 1237 configure_pin(block, n, afr_num, true);
1269 1238
1270 // d0 1239 // d0
1271 let block = d0_pin.block(); 1240 let block = d0_pin.block();
1272 let n = d0_pin.pin() as usize; 1241 let n = d0_pin.pin() as usize;
1273 let afr_num = D0::AF_NUM; 1242 let afr_num = d0_pin.af_num();
1274 configure_pin(block, n, afr_num, true); 1243 configure_pin(block, n, afr_num, true);
1275 1244
1276 // d1 1245 // d1
1277 let block = d1_pin.block(); 1246 let block = d1_pin.block();
1278 let n = d1_pin.pin() as usize; 1247 let n = d1_pin.pin() as usize;
1279 let afr_num = D1::AF_NUM; 1248 let afr_num = d1_pin.af_num();
1280 configure_pin(block, n, afr_num, true); 1249 configure_pin(block, n, afr_num, true);
1281 1250
1282 // d2 1251 // d2
1283 let block = d2_pin.block(); 1252 let block = d2_pin.block();
1284 let n = d2_pin.pin() as usize; 1253 let n = d2_pin.pin() as usize;
1285 let afr_num = D2::AF_NUM; 1254 let afr_num = d2_pin.af_num();
1286 configure_pin(block, n, afr_num, true); 1255 configure_pin(block, n, afr_num, true);
1287 1256
1288 // d3 1257 // d3
1289 let block = d3_pin.block(); 1258 let block = d3_pin.block();
1290 let n = d3_pin.pin() as usize; 1259 let n = d3_pin.pin() as usize;
1291 let afr_num = D3::AF_NUM; 1260 let afr_num = d3_pin.af_num();
1292 configure_pin(block, n, afr_num, true); 1261 configure_pin(block, n, afr_num, true);
1293 }); 1262 });
1294 } 1263 }
@@ -1404,19 +1373,19 @@ where
1404 // clk 1373 // clk
1405 let block = clk_pin.block(); 1374 let block = clk_pin.block();
1406 let n = clk_pin.pin() as usize; 1375 let n = clk_pin.pin() as usize;
1407 let afr_num = CLK::AF_NUM; 1376 let afr_num = clk_pin.af_num();
1408 configure_pin(block, n, afr_num, false); 1377 configure_pin(block, n, afr_num, false);
1409 1378
1410 // cmd 1379 // cmd
1411 let block = cmd_pin.block(); 1380 let block = cmd_pin.block();
1412 let n = cmd_pin.pin() as usize; 1381 let n = cmd_pin.pin() as usize;
1413 let afr_num = CMD::AF_NUM; 1382 let afr_num = cmd_pin.af_num();
1414 configure_pin(block, n, afr_num, true); 1383 configure_pin(block, n, afr_num, true);
1415 1384
1416 // d0 1385 // d0
1417 let block = d0_pin.block(); 1386 let block = d0_pin.block();
1418 let n = d0_pin.pin() as usize; 1387 let n = d0_pin.pin() as usize;
1419 let afr_num = D0::AF_NUM; 1388 let afr_num = d0_pin.af_num();
1420 configure_pin(block, n, afr_num, true); 1389 configure_pin(block, n, afr_num, true);
1421 }); 1390 });
1422 } 1391 }
@@ -1491,49 +1460,39 @@ crate::pac::peripherals!(
1491 }; 1460 };
1492); 1461);
1493 1462
1494macro_rules! impl_pin {
1495 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
1496 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
1497 const AF_NUM: u8 = $af;
1498 }
1499
1500 impl $signal<peripherals::$inst> for peripherals::$pin {}
1501 };
1502}
1503
1504crate::pac::peripheral_pins!( 1463crate::pac::peripheral_pins!(
1505 ($inst:ident, sdmmc, SDMMC, $pin:ident, CK, $af:expr) => { 1464 ($inst:ident, sdmmc, SDMMC, $pin:ident, CK, $af:expr) => {
1506 impl_pin!($inst, $pin, CkPin, $af); 1465 pin_trait_impl!(CkPin, $inst, $pin, $af);
1507 }; 1466 };
1508 ($inst:ident, sdmmc, SDMMC, $pin:ident, CMD, $af:expr) => { 1467 ($inst:ident, sdmmc, SDMMC, $pin:ident, CMD, $af:expr) => {
1509 impl_pin!($inst, $pin, CmdPin, $af); 1468 pin_trait_impl!(CmdPin, $inst, $pin, $af);
1510 }; 1469 };
1511 ($inst:ident, sdmmc, SDMMC, $pin:ident, D0, $af:expr) => { 1470 ($inst:ident, sdmmc, SDMMC, $pin:ident, D0, $af:expr) => {
1512 impl_pin!($inst, $pin, D0Pin, $af); 1471 pin_trait_impl!(D0Pin, $inst, $pin, $af);
1513 }; 1472 };
1514 ($inst:ident, sdmmc, SDMMC, $pin:ident, D1, $af:expr) => { 1473 ($inst:ident, sdmmc, SDMMC, $pin:ident, D1, $af:expr) => {
1515 impl_pin!($inst, $pin, D1Pin, $af); 1474 pin_trait_impl!(D1Pin, $inst, $pin, $af);
1516 }; 1475 };
1517 ($inst:ident, sdmmc, SDMMC, $pin:ident, D2, $af:expr) => { 1476 ($inst:ident, sdmmc, SDMMC, $pin:ident, D2, $af:expr) => {
1518 impl_pin!($inst, $pin, D2Pin, $af); 1477 pin_trait_impl!(D2Pin, $inst, $pin, $af);
1519 }; 1478 };
1520 ($inst:ident, sdmmc, SDMMC, $pin:ident, D3, $af:expr) => { 1479 ($inst:ident, sdmmc, SDMMC, $pin:ident, D3, $af:expr) => {
1521 impl_pin!($inst, $pin, D3Pin, $af); 1480 pin_trait_impl!(D3Pin, $inst, $pin, $af);
1522 }; 1481 };
1523 ($inst:ident, sdmmc, SDMMC, $pin:ident, D4, $af:expr) => { 1482 ($inst:ident, sdmmc, SDMMC, $pin:ident, D4, $af:expr) => {
1524 impl_pin!($inst, $pin, D4Pin, $af); 1483 pin_trait_impl!(D4Pin, $inst, $pin, $af);
1525 }; 1484 };
1526 ($inst:ident, sdmmc, SDMMC, $pin:ident, D5, $af:expr) => { 1485 ($inst:ident, sdmmc, SDMMC, $pin:ident, D5, $af:expr) => {
1527 impl_pin!($inst, $pin, D5Pin, $af); 1486 pin_trait_impl!(D5Pin, $inst, $pin, $af);
1528 }; 1487 };
1529 ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => { 1488 ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => {
1530 impl_pin!($inst, $pin, D6Pin, $af); 1489 pin_trait_impl!(D6Pin, $inst, $pin, $af);
1531 }; 1490 };
1532 ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => { 1491 ($inst:ident, sdmmc, SDMMC, $pin:ident, D6, $af:expr) => {
1533 impl_pin!($inst, $pin, D7Pin, $af); 1492 pin_trait_impl!(D7Pin, $inst, $pin, $af);
1534 }; 1493 };
1535 ($inst:ident, sdmmc, SDMMC, $pin:ident, D8, $af:expr) => { 1494 ($inst:ident, sdmmc, SDMMC, $pin:ident, D8, $af:expr) => {
1536 impl_pin!($inst, $pin, D8Pin, $af); 1495 pin_trait_impl!(D8Pin, $inst, $pin, $af);
1537 }; 1496 };
1538); 1497);
1539 1498
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index c0cd56fc3..d92f21f82 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -6,10 +6,9 @@ use embassy::util::Unborrow;
6use embassy_hal_common::unborrow; 6use embassy_hal_common::unborrow;
7 7
8use self::sealed::WordSize; 8use self::sealed::WordSize;
9use crate::dma;
10use crate::dma::NoDma; 9use crate::dma::NoDma;
11use crate::gpio::sealed::{AFType, Pin as _}; 10use crate::gpio::sealed::{AFType, Pin as _};
12use crate::gpio::{AnyPin, Pin}; 11use crate::gpio::AnyPin;
13use crate::pac::spi::{regs, vals}; 12use crate::pac::spi::{regs, vals};
14use crate::peripherals; 13use crate::peripherals;
15use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
@@ -416,23 +415,23 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
416 415
417 pub async fn write(&mut self, data: &[u8]) -> Result<(), Error> 416 pub async fn write(&mut self, data: &[u8]) -> Result<(), Error>
418 where 417 where
419 Tx: TxDmaChannel<T>, 418 Tx: TxDma<T>,
420 { 419 {
421 self.write_dma_u8(data).await 420 self.write_dma_u8(data).await
422 } 421 }
423 422
424 pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> 423 pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error>
425 where 424 where
426 Tx: TxDmaChannel<T>, 425 Tx: TxDma<T>,
427 Rx: RxDmaChannel<T>, 426 Rx: RxDma<T>,
428 { 427 {
429 self.read_dma_u8(data).await 428 self.read_dma_u8(data).await
430 } 429 }
431 430
432 pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> 431 pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error>
433 where 432 where
434 Tx: TxDmaChannel<T>, 433 Tx: TxDma<T>,
435 Rx: RxDmaChannel<T>, 434 Rx: RxDma<T>,
436 { 435 {
437 self.transfer_dma_u8(read, write).await 436 self.transfer_dma_u8(read, write).await
438 } 437 }
@@ -682,9 +681,7 @@ mod eh1 {
682 } 681 }
683 } 682 }
684 683
685 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8> 684 impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::Write<u8> for Spi<'d, T, Tx, Rx> {
686 for Spi<'d, T, Tx, Rx>
687 {
688 type WriteFuture<'a> 685 type WriteFuture<'a>
689 where 686 where
690 Self: 'a, 687 Self: 'a,
@@ -712,8 +709,8 @@ mod eh1 {
712 } 709 }
713 } 710 }
714 711
715 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> 712 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::Read<u8>
716 embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx> 713 for Spi<'d, T, Tx, Rx>
717 { 714 {
718 type ReadFuture<'a> 715 type ReadFuture<'a>
719 where 716 where
@@ -742,8 +739,8 @@ mod eh1 {
742 } 739 }
743 } 740 }
744 741
745 impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> 742 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::ReadWrite<u8>
746 embedded_hal_async::spi::ReadWrite<u8> for Spi<'d, T, Tx, Rx> 743 for Spi<'d, T, Tx, Rx>
747 { 744 {
748 type TransferFuture<'a> 745 type TransferFuture<'a>
749 where 746 where
@@ -800,26 +797,6 @@ pub(crate) mod sealed {
800 fn regs() -> &'static crate::pac::spi::Spi; 797 fn regs() -> &'static crate::pac::spi::Spi;
801 } 798 }
802 799
803 pub trait SckPin<T: Instance>: Pin {
804 fn af_num(&self) -> u8;
805 }
806
807 pub trait MosiPin<T: Instance>: Pin {
808 fn af_num(&self) -> u8;
809 }
810
811 pub trait MisoPin<T: Instance>: Pin {
812 fn af_num(&self) -> u8;
813 }
814
815 pub trait TxDmaChannel<T: Instance> {
816 fn request(&self) -> dma::Request;
817 }
818
819 pub trait RxDmaChannel<T: Instance> {
820 fn request(&self) -> dma::Request;
821 }
822
823 pub trait Word: Copy + 'static { 800 pub trait Word: Copy + 'static {
824 const WORDSIZE: WordSize; 801 const WORDSIZE: WordSize;
825 } 802 }
@@ -886,11 +863,11 @@ impl Word for u8 {}
886impl Word for u16 {} 863impl Word for u16 {}
887 864
888pub trait Instance: sealed::Instance + RccPeripheral {} 865pub trait Instance: sealed::Instance + RccPeripheral {}
889pub trait SckPin<T: Instance>: sealed::SckPin<T> {} 866pin_trait!(SckPin, Instance);
890pub trait MosiPin<T: Instance>: sealed::MosiPin<T> {} 867pin_trait!(MosiPin, Instance);
891pub trait MisoPin<T: Instance>: sealed::MisoPin<T> {} 868pin_trait!(MisoPin, Instance);
892pub trait TxDmaChannel<T: Instance>: sealed::TxDmaChannel<T> + dma::Channel {} 869dma_trait!(RxDma, Instance);
893pub trait RxDmaChannel<T: Instance>: sealed::RxDmaChannel<T> + dma::Channel {} 870dma_trait!(TxDma, Instance);
894 871
895crate::pac::peripherals!( 872crate::pac::peripherals!(
896 (spi, $inst:ident) => { 873 (spi, $inst:ident) => {
@@ -904,80 +881,37 @@ crate::pac::peripherals!(
904 }; 881 };
905); 882);
906 883
907macro_rules! impl_pin {
908 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
909 impl $signal<peripherals::$inst> for peripherals::$pin {}
910
911 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
912 fn af_num(&self) -> u8 {
913 $af
914 }
915 }
916 };
917}
918
919#[cfg(not(rcc_f1))] 884#[cfg(not(rcc_f1))]
920crate::pac::peripheral_pins!( 885crate::pac::peripheral_pins!(
921 ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => { 886 ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
922 impl_pin!($inst, $pin, SckPin, $af); 887 pin_trait_impl!(SckPin, $inst, $pin, $af);
923 }; 888 };
924
925 ($inst:ident, spi, SPI, $pin:ident, MOSI, $af:expr) => { 889 ($inst:ident, spi, SPI, $pin:ident, MOSI, $af:expr) => {
926 impl_pin!($inst, $pin, MosiPin, $af); 890 pin_trait_impl!(MosiPin, $inst, $pin, $af);
927 }; 891 };
928
929 ($inst:ident, spi, SPI, $pin:ident, MISO, $af:expr) => { 892 ($inst:ident, spi, SPI, $pin:ident, MISO, $af:expr) => {
930 impl_pin!($inst, $pin, MisoPin, $af); 893 pin_trait_impl!(MisoPin, $inst, $pin, $af);
931 }; 894 };
932); 895);
933 896
934#[cfg(rcc_f1)] 897#[cfg(rcc_f1)]
935crate::pac::peripheral_pins!( 898crate::pac::peripheral_pins!(
936 ($inst:ident, spi, SPI, $pin:ident, SCK) => { 899 ($inst:ident, spi, SPI, $pin:ident, SCK) => {
937 impl_pin!($inst, $pin, SckPin, 0); 900 pin_trait_impl!(SckPin, $inst, $pin, 0);
938 }; 901 };
939
940 ($inst:ident, spi, SPI, $pin:ident, MOSI) => { 902 ($inst:ident, spi, SPI, $pin:ident, MOSI) => {
941 impl_pin!($inst, $pin, MosiPin, 0); 903 pin_trait_impl!(MosiPin, $inst, $pin, 0);
942 }; 904 };
943
944 ($inst:ident, spi, SPI, $pin:ident, MISO) => { 905 ($inst:ident, spi, SPI, $pin:ident, MISO) => {
945 impl_pin!($inst, $pin, MisoPin, 0); 906 pin_trait_impl!(MisoPin, $inst, $pin, 0);
946 }; 907 };
947); 908);
948 909
949macro_rules! impl_dma {
950 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
951 impl<T> sealed::$signal<peripherals::$inst> for T
952 where
953 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
954 {
955 fn request(&self) -> dma::Request {
956 $request
957 }
958 }
959
960 impl<T> $signal<peripherals::$inst> for T where
961 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
962 {
963 }
964 };
965 ($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
966 impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
967 fn request(&self) -> dma::Request {
968 $request
969 }
970 }
971
972 impl $signal<peripherals::$inst> for peripherals::$channel {}
973 };
974}
975
976crate::pac::peripheral_dma_channels! { 910crate::pac::peripheral_dma_channels! {
977 ($peri:ident, spi, $kind:ident, RX, $channel:tt, $request:expr) => { 911 ($peri:ident, spi, $kind:ident, RX, $channel:tt, $request:expr) => {
978 impl_dma!($peri, $channel, RxDmaChannel, $request); 912 dma_trait_impl!(RxDma, $peri, $channel, $request);
979 }; 913 };
980 ($peri:ident, spi, $kind:ident, TX, $channel:tt, $request:expr) => { 914 ($peri:ident, spi, $kind:ident, TX, $channel:tt, $request:expr) => {
981 impl_dma!($peri, $channel, TxDmaChannel, $request); 915 dma_trait_impl!(TxDma, $peri, $channel, $request);
982 }; 916 };
983} 917}
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
index 68e5a7348..5dd4dc2db 100644
--- a/embassy-stm32/src/spi/v1.rs
+++ b/embassy-stm32/src/spi/v1.rs
@@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> 9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where 10 where
11 Tx: TxDmaChannel<T>, 11 Tx: TxDma<T>,
12 { 12 {
13 unsafe { 13 unsafe {
14 T::regs().cr1().modify(|w| { 14 T::regs().cr1().modify(|w| {
@@ -40,8 +40,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
40 40
41 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> 41 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
42 where 42 where
43 Tx: TxDmaChannel<T>, 43 Tx: TxDma<T>,
44 Rx: RxDmaChannel<T>, 44 Rx: RxDma<T>,
45 { 45 {
46 unsafe { 46 unsafe {
47 T::regs().cr1().modify(|w| { 47 T::regs().cr1().modify(|w| {
@@ -93,8 +93,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
93 write: *const [u8], 93 write: *const [u8],
94 ) -> Result<(), Error> 94 ) -> Result<(), Error>
95 where 95 where
96 Tx: TxDmaChannel<T>, 96 Tx: TxDma<T>,
97 Rx: RxDmaChannel<T>, 97 Rx: RxDma<T>,
98 { 98 {
99 let (_, rx_len) = slice_ptr_parts(read); 99 let (_, rx_len) = slice_ptr_parts(read);
100 let (_, tx_len) = slice_ptr_parts(write); 100 let (_, tx_len) = slice_ptr_parts(write);
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
index 78bb1192b..3820fcac1 100644
--- a/embassy-stm32/src/spi/v2.rs
+++ b/embassy-stm32/src/spi/v2.rs
@@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> 9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where 10 where
11 Tx: TxDmaChannel<T>, 11 Tx: TxDma<T>,
12 { 12 {
13 unsafe { 13 unsafe {
14 T::regs().cr1().modify(|w| { 14 T::regs().cr1().modify(|w| {
@@ -45,8 +45,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
45 45
46 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> 46 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
47 where 47 where
48 Tx: TxDmaChannel<T>, 48 Tx: TxDma<T>,
49 Rx: RxDmaChannel<T>, 49 Rx: RxDma<T>,
50 { 50 {
51 unsafe { 51 unsafe {
52 T::regs().cr1().modify(|w| { 52 T::regs().cr1().modify(|w| {
@@ -98,8 +98,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
98 write: *const [u8], 98 write: *const [u8],
99 ) -> Result<(), Error> 99 ) -> Result<(), Error>
100 where 100 where
101 Tx: TxDmaChannel<T>, 101 Tx: TxDma<T>,
102 Rx: RxDmaChannel<T>, 102 Rx: RxDma<T>,
103 { 103 {
104 let (_, rx_len) = slice_ptr_parts(read); 104 let (_, rx_len) = slice_ptr_parts(read);
105 let (_, tx_len) = slice_ptr_parts(write); 105 let (_, tx_len) = slice_ptr_parts(write);
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs
index 50650da1b..9e766cfdb 100644
--- a/embassy-stm32/src/spi/v3.rs
+++ b/embassy-stm32/src/spi/v3.rs
@@ -8,7 +8,7 @@ use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error> 9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where 10 where
11 Tx: TxDmaChannel<T>, 11 Tx: TxDma<T>,
12 { 12 {
13 self.set_word_size(WordSize::EightBit); 13 self.set_word_size(WordSize::EightBit);
14 unsafe { 14 unsafe {
@@ -48,8 +48,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
48 48
49 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error> 49 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
50 where 50 where
51 Tx: TxDmaChannel<T>, 51 Tx: TxDma<T>,
52 Rx: RxDmaChannel<T>, 52 Rx: RxDma<T>,
53 { 53 {
54 self.set_word_size(WordSize::EightBit); 54 self.set_word_size(WordSize::EightBit);
55 unsafe { 55 unsafe {
@@ -104,8 +104,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
104 write: *const [u8], 104 write: *const [u8],
105 ) -> Result<(), Error> 105 ) -> Result<(), Error>
106 where 106 where
107 Tx: TxDmaChannel<T>, 107 Tx: TxDma<T>,
108 Rx: RxDmaChannel<T>, 108 Rx: RxDma<T>,
109 { 109 {
110 let (_, rx_len) = slice_ptr_parts(read); 110 let (_, rx_len) = slice_ptr_parts(read);
111 let (_, tx_len) = slice_ptr_parts(write); 111 let (_, tx_len) = slice_ptr_parts(write);
diff --git a/embassy-stm32/src/traits.rs b/embassy-stm32/src/traits.rs
new file mode 100644
index 000000000..b27628703
--- /dev/null
+++ b/embassy-stm32/src/traits.rs
@@ -0,0 +1,53 @@
1#![macro_use]
2
3macro_rules! pin_trait {
4 ($signal:ident, $instance:path) => {
5 pub trait $signal<T: $instance>: crate::gpio::Pin {
6 fn af_num(&self) -> u8;
7 }
8 };
9}
10
11macro_rules! pin_trait_impl {
12 ($signal:ident, $instance:ident, $pin:ident, $af:expr) => {
13 impl $signal<crate::peripherals::$instance> for crate::peripherals::$pin {
14 fn af_num(&self) -> u8 {
15 $af
16 }
17 }
18 };
19}
20
21// ====================
22
23macro_rules! dma_trait {
24 ($signal:ident, $instance:path) => {
25 pub trait $signal<T: $instance>: crate::dma::Channel {
26 fn request(&self) -> crate::dma::Request;
27 }
28 };
29}
30
31#[allow(unused)]
32macro_rules! dma_trait_impl {
33 // DMAMUX
34 ($signal:ident, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
35 impl<T> $signal<crate::peripherals::$instance> for T
36 where
37 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
38 {
39 fn request(&self) -> crate::dma::Request {
40 $request
41 }
42 }
43 };
44
45 // No DMAMUX
46 ($signal:ident, $instance:ident, {channel: $channel:ident}, $request:expr) => {
47 impl $signal<crate::peripherals::$instance> for crate::peripherals::$channel {
48 fn request(&self) -> crate::dma::Request {
49 $request
50 }
51 }
52 };
53}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 5f0281f46..f17ae0add 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -7,10 +7,9 @@ use embassy_hal_common::unborrow;
7 7
8use crate::dma::NoDma; 8use crate::dma::NoDma;
9use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull}; 9use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
10use crate::gpio::Pin;
11use crate::pac::usart::{regs, vals}; 10use crate::pac::usart::{regs, vals};
11use crate::peripherals;
12use crate::rcc::RccPeripheral; 12use crate::rcc::RccPeripheral;
13use crate::{dma, peripherals};
14 13
15#[derive(Clone, Copy, PartialEq, Eq, Debug)] 14#[derive(Clone, Copy, PartialEq, Eq, Debug)]
16pub enum DataBits { 15pub enum DataBits {
@@ -601,46 +600,23 @@ unsafe fn clear_interrupt_flag(r: crate::pac::usart::Usart, flag: InterruptFlag)
601} 600}
602 601
603pub(crate) mod sealed { 602pub(crate) mod sealed {
604 use super::*;
605
606 pub trait Instance { 603 pub trait Instance {
607 fn regs(&self) -> crate::pac::usart::Usart; 604 fn regs(&self) -> crate::pac::usart::Usart;
608 } 605 }
609 pub trait RxPin<T: Instance>: Pin {
610 fn af_num(&self) -> u8;
611 }
612 pub trait TxPin<T: Instance>: Pin {
613 fn af_num(&self) -> u8;
614 }
615 pub trait CtsPin<T: Instance>: Pin {
616 fn af_num(&self) -> u8;
617 }
618 pub trait RtsPin<T: Instance>: Pin {
619 fn af_num(&self) -> u8;
620 }
621 pub trait CkPin<T: Instance>: Pin {
622 fn af_num(&self) -> u8;
623 }
624
625 pub trait RxDma<T: Instance> {
626 fn request(&self) -> dma::Request;
627 }
628
629 pub trait TxDma<T: Instance> {
630 fn request(&self) -> dma::Request;
631 }
632} 606}
633 607
634pub trait Instance: sealed::Instance + RccPeripheral { 608pub trait Instance: sealed::Instance + RccPeripheral {
635 type Interrupt: Interrupt; 609 type Interrupt: Interrupt;
636} 610}
637pub trait RxPin<T: Instance>: sealed::RxPin<T> {} 611
638pub trait TxPin<T: Instance>: sealed::TxPin<T> {} 612pin_trait!(RxPin, Instance);
639pub trait CtsPin<T: Instance>: sealed::CtsPin<T> {} 613pin_trait!(TxPin, Instance);
640pub trait RtsPin<T: Instance>: sealed::RtsPin<T> {} 614pin_trait!(CtsPin, Instance);
641pub trait CkPin<T: Instance>: sealed::CkPin<T> {} 615pin_trait!(RtsPin, Instance);
642pub trait RxDma<T: Instance>: sealed::RxDma<T> + dma::Channel {} 616pin_trait!(CkPin, Instance);
643pub trait TxDma<T: Instance>: sealed::TxDma<T> + dma::Channel {} 617
618dma_trait!(TxDma, Instance);
619dma_trait!(RxDma, Instance);
644 620
645crate::pac::interrupts!( 621crate::pac::interrupts!(
646 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { 622 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
@@ -653,57 +629,44 @@ crate::pac::interrupts!(
653 impl Instance for peripherals::$inst { 629 impl Instance for peripherals::$inst {
654 type Interrupt = crate::interrupt::$irq; 630 type Interrupt = crate::interrupt::$irq;
655 } 631 }
656
657 }; 632 };
658); 633);
659 634
660macro_rules! impl_pin {
661 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
662 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
663 fn af_num(&self) -> u8 {
664 $af
665 }
666 }
667
668 impl $signal<peripherals::$inst> for peripherals::$pin {}
669 };
670}
671
672#[cfg(not(rcc_f1))] 635#[cfg(not(rcc_f1))]
673crate::pac::peripheral_pins!( 636crate::pac::peripheral_pins!(
674 637
675 // USART 638 // USART
676 ($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => { 639 ($inst:ident, usart, USART, $pin:ident, TX, $af:expr) => {
677 impl_pin!($inst, $pin, TxPin, $af); 640 pin_trait_impl!(TxPin, $inst, $pin, $af);
678 }; 641 };
679 ($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => { 642 ($inst:ident, usart, USART, $pin:ident, RX, $af:expr) => {
680 impl_pin!($inst, $pin, RxPin, $af); 643 pin_trait_impl!(RxPin, $inst, $pin, $af);
681 }; 644 };
682 ($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => { 645 ($inst:ident, usart, USART, $pin:ident, CTS, $af:expr) => {
683 impl_pin!($inst, $pin, CtsPin, $af); 646 pin_trait_impl!(CtsPin, $inst, $pin, $af);
684 }; 647 };
685 ($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => { 648 ($inst:ident, usart, USART, $pin:ident, RTS, $af:expr) => {
686 impl_pin!($inst, $pin, RtsPin, $af); 649 pin_trait_impl!(RtsPin, $inst, $pin, $af);
687 }; 650 };
688 ($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => { 651 ($inst:ident, usart, USART, $pin:ident, CK, $af:expr) => {
689 impl_pin!($inst, $pin, CkPin, $af); 652 pin_trait_impl!(CkPin, $inst, $pin, $af);
690 }; 653 };
691 654
692 // UART 655 // UART
693 ($inst:ident, uart, UART, $pin:ident, TX, $af:expr) => { 656 ($inst:ident, usart, UART, $pin:ident, TX, $af:expr) => {
694 impl_pin!($inst, $pin, TxPin, $af); 657 pin_trait_impl!(TxPin, $inst, $pin, $af);
695 }; 658 };
696 ($inst:ident, uart, UART, $pin:ident, RX, $af:expr) => { 659 ($inst:ident, usart, UART, $pin:ident, RX, $af:expr) => {
697 impl_pin!($inst, $pin, RxPin, $af); 660 pin_trait_impl!(RxPin, $inst, $pin, $af);
698 }; 661 };
699 ($inst:ident, uart, UART, $pin:ident, CTS, $af:expr) => { 662 ($inst:ident, usart, UART, $pin:ident, CTS, $af:expr) => {
700 impl_pin!($inst, $pin, CtsPin, $af); 663 pin_trait_impl!(CtsPin, $inst, $pin, $af);
701 }; 664 };
702 ($inst:ident, uart, UART, $pin:ident, RTS, $af:expr) => { 665 ($inst:ident, usart, UART, $pin:ident, RTS, $af:expr) => {
703 impl_pin!($inst, $pin, RtsPin, $af); 666 pin_trait_impl!(RtsPin, $inst, $pin, $af);
704 }; 667 };
705 ($inst:ident, uart, UART, $pin:ident, CK, $af:expr) => { 668 ($inst:ident, usart, UART, $pin:ident, CK, $af:expr) => {
706 impl_pin!($inst, $pin, CkPin, $af); 669 pin_trait_impl!(CkPin, $inst, $pin, $af);
707 }; 670 };
708); 671);
709 672
@@ -712,78 +675,50 @@ crate::pac::peripheral_pins!(
712 675
713 // USART 676 // USART
714 ($inst:ident, usart, USART, $pin:ident, TX) => { 677 ($inst:ident, usart, USART, $pin:ident, TX) => {
715 impl_pin!($inst, $pin, TxPin, 0); 678 pin_trait_impl!(TxPin, $inst, $pin, 0);
716 }; 679 };
717 ($inst:ident, usart, USART, $pin:ident, RX) => { 680 ($inst:ident, usart, USART, $pin:ident, RX) => {
718 impl_pin!($inst, $pin, RxPin, 0); 681 pin_trait_impl!(RxPin, $inst, $pin, 0);
719 }; 682 };
720 ($inst:ident, usart, USART, $pin:ident, CTS) => { 683 ($inst:ident, usart, USART, $pin:ident, CTS) => {
721 impl_pin!($inst, $pin, CtsPin, 0); 684 pin_trait_impl!(CtsPin, $inst, $pin, 0);
722 }; 685 };
723 ($inst:ident, usart, USART, $pin:ident, RTS) => { 686 ($inst:ident, usart, USART, $pin:ident, RTS) => {
724 impl_pin!($inst, $pin, RtsPin, 0); 687 pin_trait_impl!(RtsPin, $inst, $pin, 0);
725 }; 688 };
726 ($inst:ident, usart, USART, $pin:ident, CK) => { 689 ($inst:ident, usart, USART, $pin:ident, CK) => {
727 impl_pin!($inst, $pin, CkPin, 0); 690 pin_trait_impl!(CkPin, $inst, $pin, 0);
728 }; 691 };
729 692
730 // UART 693 // UART
731 ($inst:ident, uart, UART, $pin:ident, TX) => { 694 ($inst:ident, usart, UART, $pin:ident, TX) => {
732 impl_pin!($inst, $pin, TxPin, 0); 695 pin_trait_impl!(TxPin, $inst, $pin, 0);
733 }; 696 };
734 ($inst:ident, uart, UART, $pin:ident, RX) => { 697 ($inst:ident, usart, UART, $pin:ident, RX) => {
735 impl_pin!($inst, $pin, RxPin, 0); 698 pin_trait_impl!(RxPin, $inst, $pin, 0);
736 }; 699 };
737 ($inst:ident, uart, UART, $pin:ident, CTS) => { 700 ($inst:ident, usart, UART, $pin:ident, CTS) => {
738 impl_pin!($inst, $pin, CtsPin, 0); 701 pin_trait_impl!(CtsPin, $inst, $pin, 0);
739 }; 702 };
740 ($inst:ident, uart, UART, $pin:ident, RTS) => { 703 ($inst:ident, usart, UART, $pin:ident, RTS) => {
741 impl_pin!($inst, $pin, RtsPin, 0); 704 pin_trait_impl!(RtsPin, $inst, $pin, 0);
742 }; 705 };
743 ($inst:ident, uart, UART, $pin:ident, CK) => { 706 ($inst:ident, usart, UART, $pin:ident, CK) => {
744 impl_pin!($inst, $pin, CkPin, 0); 707 pin_trait_impl!(CkPin, $inst, $pin, 0);
745 }; 708 };
746); 709);
747 710
748#[allow(unused)]
749macro_rules! impl_dma {
750 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
751 impl<T> sealed::$signal<peripherals::$inst> for T
752 where
753 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
754 {
755 fn request(&self) -> dma::Request {
756 $request
757 }
758 }
759
760 impl<T> $signal<peripherals::$inst> for T where
761 T: crate::dma::MuxChannel<Mux = crate::dma::$dmamux>
762 {
763 }
764 };
765 ($inst:ident, {channel: $channel:ident}, $signal:ident, $request:expr) => {
766 impl sealed::$signal<peripherals::$inst> for peripherals::$channel {
767 fn request(&self) -> dma::Request {
768 $request
769 }
770 }
771
772 impl $signal<peripherals::$inst> for peripherals::$channel {}
773 };
774}
775
776crate::pac::peripheral_dma_channels! { 711crate::pac::peripheral_dma_channels! {
777 ($peri:ident, usart, $kind:ident, RX, $channel:tt, $request:expr) => { 712 ($peri:ident, usart, $kind:ident, RX, $channel:tt, $request:expr) => {
778 impl_dma!($peri, $channel, RxDma, $request); 713 dma_trait_impl!(RxDma, $peri, $channel, $request);
779 }; 714 };
780 ($peri:ident, usart, $kind:ident, TX, $channel:tt, $request:expr) => { 715 ($peri:ident, usart, $kind:ident, TX, $channel:tt, $request:expr) => {
781 impl_dma!($peri, $channel, TxDma, $request); 716 dma_trait_impl!(TxDma, $peri, $channel, $request);
782 }; 717 };
783 ($peri:ident, uart, $kind:ident, RX, $channel:tt, $request:expr) => { 718 ($peri:ident, uart, $kind:ident, RX, $channel:tt, $request:expr) => {
784 impl_dma!($peri, $channel, RxDma, $request); 719 dma_trait_impl!(RxDma, $peri, $channel, $request);
785 }; 720 };
786 ($peri:ident, uart, $kind:ident, TX, $channel:tt, $request:expr) => { 721 ($peri:ident, uart, $kind:ident, TX, $channel:tt, $request:expr) => {
787 impl_dma!($peri, $channel, TxDma, $request); 722 dma_trait_impl!(TxDma, $peri, $channel, $request);
788 }; 723 };
789} 724}
diff --git a/embassy-stm32/src/usb_otg.rs b/embassy-stm32/src/usb_otg.rs
index b3494ee7a..bdce6f44b 100644
--- a/embassy-stm32/src/usb_otg.rs
+++ b/embassy-stm32/src/usb_otg.rs
@@ -1,16 +1,25 @@
1use crate::{peripherals, rcc::RccPeripheral};
2use core::marker::PhantomData; 1use core::marker::PhantomData;
3use embassy::util::Unborrow; 2use embassy::util::Unborrow;
4use embassy_hal_common::unborrow; 3use embassy_hal_common::unborrow;
4use synopsys_usb_otg::{PhyType, UsbPeripheral};
5
6use crate::gpio::sealed::AFType;
7use crate::gpio::Speed;
8use crate::{peripherals, rcc::RccPeripheral};
9
5pub use embassy_hal_common::usb::*; 10pub use embassy_hal_common::usb::*;
6pub use synopsys_usb_otg::UsbBus; 11pub use synopsys_usb_otg::UsbBus;
7use synopsys_usb_otg::{PhyType, UsbPeripheral};
8 12
9macro_rules! config_pins { 13macro_rules! config_ulpi_pins {
10 ($($pin:ident),*) => { 14 ($($pin:ident),*) => {
11 $( 15 unborrow!($($pin),*);
12 $pin.configure(); 16 // NOTE(unsafe) Exclusive access to the registers
13 )* 17 critical_section::with(|_| unsafe {
18 $(
19 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
20 $pin.set_speed(Speed::VeryHigh);
21 )*
22 })
14 }; 23 };
15} 24}
16 25
@@ -27,7 +36,11 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
27 dm: impl Unborrow<Target = impl DmPin<T>> + 'd, 36 dm: impl Unborrow<Target = impl DmPin<T>> + 'd,
28 ) -> Self { 37 ) -> Self {
29 unborrow!(dp, dm); 38 unborrow!(dp, dm);
30 config_pins!(dp, dm); 39
40 unsafe {
41 dp.set_as_af(dp.af_num(), AFType::OutputPushPull);
42 dm.set_as_af(dm.af_num(), AFType::OutputPushPull);
43 }
31 44
32 Self { 45 Self {
33 phantom: PhantomData, 46 phantom: PhantomData,
@@ -51,10 +64,10 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
51 ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd, 64 ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd,
52 ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd, 65 ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd,
53 ) -> Self { 66 ) -> Self {
54 unborrow!(ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp); 67 config_ulpi_pins!(
55 unborrow!(ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, ulpi_d7); 68 ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4,
56 config_pins!(ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp); 69 ulpi_d5, ulpi_d6, ulpi_d7
57 config_pins!(ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, ulpi_d7); 70 );
58 71
59 Self { 72 Self {
60 phantom: PhantomData, 73 phantom: PhantomData,
@@ -100,48 +113,27 @@ pub(crate) mod sealed {
100 const FIFO_DEPTH_WORDS: usize; 113 const FIFO_DEPTH_WORDS: usize;
101 const ENDPOINT_COUNT: usize; 114 const ENDPOINT_COUNT: usize;
102 } 115 }
103
104 macro_rules! declare_pins {
105 ($name:ident) => {
106 pub trait $name<T: Instance> {
107 fn configure(&mut self);
108 }
109 };
110
111 ($($name:ident),*) => {
112 $(
113 declare_pins!($name);
114 )*
115 };
116 }
117
118 // Internal PHY pins
119 declare_pins!(DpPin, DmPin);
120
121 // External PHY pins
122 declare_pins!(UlpiClkPin, UlpiDirPin, UlpiNxtPin, UlpiStpPin);
123 declare_pins!(UlpiD0Pin, UlpiD1Pin, UlpiD2Pin, UlpiD3Pin);
124 declare_pins!(UlpiD4Pin, UlpiD5Pin, UlpiD6Pin, UlpiD7Pin);
125} 116}
126 117
127pub trait Instance: sealed::Instance + RccPeripheral {} 118pub trait Instance: sealed::Instance + RccPeripheral {}
128 119
129macro_rules! declare_pins { 120// Internal PHY pins
130 ($name:ident) => { 121pin_trait!(DpPin, Instance);
131 pub trait $name<T: Instance>: sealed::$name<T> {} 122pin_trait!(DmPin, Instance);
132 }; 123
133 124// External PHY pins
134 ($($name:ident),*) => { 125pin_trait!(UlpiClkPin, Instance);
135 $( 126pin_trait!(UlpiDirPin, Instance);
136 declare_pins!($name); 127pin_trait!(UlpiNxtPin, Instance);
137 )* 128pin_trait!(UlpiStpPin, Instance);
138 }; 129pin_trait!(UlpiD0Pin, Instance);
139} 130pin_trait!(UlpiD1Pin, Instance);
140 131pin_trait!(UlpiD2Pin, Instance);
141declare_pins!(DpPin, DmPin); 132pin_trait!(UlpiD3Pin, Instance);
142declare_pins!(UlpiClkPin, UlpiDirPin, UlpiNxtPin, UlpiStpPin); 133pin_trait!(UlpiD4Pin, Instance);
143declare_pins!(UlpiD0Pin, UlpiD1Pin, UlpiD2Pin, UlpiD3Pin); 134pin_trait!(UlpiD5Pin, Instance);
144declare_pins!(UlpiD4Pin, UlpiD5Pin, UlpiD6Pin, UlpiD7Pin); 135pin_trait!(UlpiD6Pin, Instance);
136pin_trait!(UlpiD7Pin, Instance);
145 137
146crate::pac::peripherals!( 138crate::pac::peripherals!(
147 (otgfs, $inst:ident) => { 139 (otgfs, $inst:ident) => {
@@ -240,93 +232,58 @@ crate::pac::interrupts!(
240 }; 232 };
241); 233);
242 234
243macro_rules! impl_pin {
244 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
245 impl $signal<peripherals::$inst> for peripherals::$pin {}
246
247 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
248 fn configure(&mut self) {
249 use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
250
251 critical_section::with(|_| unsafe {
252 self.set_as_af($af, OutputPushPull);
253 });
254 }
255 }
256 };
257}
258
259// ULPI pins have to be set to VeryHigh speed
260macro_rules! impl_ulpi_pin {
261 ($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
262 impl $signal<peripherals::$inst> for peripherals::$pin {}
263
264 impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
265 fn configure(&mut self) {
266 use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
267 use crate::gpio::Speed;
268
269 critical_section::with(|_| unsafe {
270 self.set_as_af($af, OutputPushPull);
271 self.set_speed(Speed::VeryHigh);
272 });
273 }
274 }
275 };
276}
277
278crate::pac::peripheral_pins!( 235crate::pac::peripheral_pins!(
279 // FS internal phy pins 236 // FS internal phy pins
280 ($inst:ident, otgfs, OTG_FS, $pin:ident, DP, $af:expr) => { 237 ($inst:ident, otgfs, OTG_FS, $pin:ident, DP, $af:expr) => {
281 impl_pin!($inst, $pin, DpPin, $af); 238 pin_trait_impl!(DpPin, $inst, $pin, $af);
282 }; 239 };
283 ($inst:ident, otgfs, OTG_FS, $pin:ident, DM, $af:expr) => { 240 ($inst:ident, otgfs, OTG_FS, $pin:ident, DM, $af:expr) => {
284 impl_pin!($inst, $pin, DmPin, $af); 241 pin_trait_impl!(DmPin, $inst, $pin, $af);
285 }; 242 };
286 243
287 // HS internal phy pins 244 // HS internal phy pins
288 ($inst:ident, otghs, OTG_HS, $pin:ident, DP, $af:expr) => { 245 ($inst:ident, otghs, OTG_HS, $pin:ident, DP, $af:expr) => {
289 impl_pin!($inst, $pin, DpPin, $af); 246 pin_trait_impl!(DpPin, $inst, $pin, $af);
290 }; 247 };
291 ($inst:ident, otghs, OTG_HS, $pin:ident, DM, $af:expr) => { 248 ($inst:ident, otghs, OTG_HS, $pin:ident, DM, $af:expr) => {
292 impl_pin!($inst, $pin, DmPin, $af); 249 pin_trait_impl!(DmPin, $inst, $pin, $af);
293 }; 250 };
294 251
295 // HS external phy pins 252 // HS external phy pins
296 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_CK, $af:expr) => { 253 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_CK, $af:expr) => {
297 impl_ulpi_pin!($inst, $pin, UlpiClkPin, $af); 254 pin_trait_impl!(UlpiClkPin, $inst, $pin, $af);
298 }; 255 };
299 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_DIR, $af:expr) => { 256 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_DIR, $af:expr) => {
300 impl_ulpi_pin!($inst, $pin, UlpiDirPin, $af); 257 pin_trait_impl!(UlpiDirPin, $inst, $pin, $af);
301 }; 258 };
302 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_NXT, $af:expr) => { 259 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_NXT, $af:expr) => {
303 impl_ulpi_pin!($inst, $pin, UlpiNxtPin, $af); 260 pin_trait_impl!(UlpiNxtPin, $inst, $pin, $af);
304 }; 261 };
305 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_STP, $af:expr) => { 262 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_STP, $af:expr) => {
306 impl_ulpi_pin!($inst, $pin, UlpiStpPin, $af); 263 pin_trait_impl!(UlpiStpPin, $inst, $pin, $af);
307 }; 264 };
308 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D0, $af:expr) => { 265 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D0, $af:expr) => {
309 impl_ulpi_pin!($inst, $pin, UlpiD0Pin, $af); 266 pin_trait_impl!(UlpiD0Pin, $inst, $pin, $af);
310 }; 267 };
311 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D1, $af:expr) => { 268 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D1, $af:expr) => {
312 impl_ulpi_pin!($inst, $pin, UlpiD1Pin, $af); 269 pin_trait_impl!(UlpiD1Pin, $inst, $pin, $af);
313 }; 270 };
314 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D2, $af:expr) => { 271 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D2, $af:expr) => {
315 impl_ulpi_pin!($inst, $pin, UlpiD2Pin, $af); 272 pin_trait_impl!(UlpiD2Pin, $inst, $pin, $af);
316 }; 273 };
317 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D3, $af:expr) => { 274 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D3, $af:expr) => {
318 impl_ulpi_pin!($inst, $pin, UlpiD3Pin, $af); 275 pin_trait_impl!(UlpiD3Pin, $inst, $pin, $af);
319 }; 276 };
320 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D4, $af:expr) => { 277 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D4, $af:expr) => {
321 impl_ulpi_pin!($inst, $pin, UlpiD4Pin, $af); 278 pin_trait_impl!(UlpiD4Pin, $inst, $pin, $af);
322 }; 279 };
323 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D5, $af:expr) => { 280 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D5, $af:expr) => {
324 impl_ulpi_pin!($inst, $pin, UlpiD5Pin, $af); 281 pin_trait_impl!(UlpiD5Pin, $inst, $pin, $af);
325 }; 282 };
326 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D6, $af:expr) => { 283 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D6, $af:expr) => {
327 impl_ulpi_pin!($inst, $pin, UlpiD6Pin, $af); 284 pin_trait_impl!(UlpiD6Pin, $inst, $pin, $af);
328 }; 285 };
329 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D7, $af:expr) => { 286 ($inst:ident, otghs, OTG_HS, $pin:ident, ULPI_D7, $af:expr) => {
330 impl_ulpi_pin!($inst, $pin, UlpiD7Pin, $af); 287 pin_trait_impl!(UlpiD7Pin, $inst, $pin, $af);
331 }; 288 };
332); 289);