44//! which pins can have a specific function, and provides
55//! functionality for setting up clocks and the MAC peripheral
66
7+ use crate :: {
8+ dma:: EthernetDMA ,
9+ stm32:: { ETHERNET_DMA , ETHERNET_MAC } ,
10+ } ;
11+
712#[ cfg( feature = "stm32f4xx-hal" ) ]
8- use stm32f4xx_hal:: {
9- bb,
13+ use crate :: hal:: bb;
14+
15+ #[ cfg( any(
16+ feature = "stm32f4xx-hal" ,
17+ feature = "stm32f7xx-hal" ,
18+ feature = "stm32h7xx-hal"
19+ ) ) ]
20+ use crate :: hal:: {
1021 gpio:: {
1122 gpioa:: { PA1 , PA7 } ,
1223 gpiob:: { PB11 , PB12 , PB13 } ,
1324 gpioc:: { PC4 , PC5 } ,
14- gpiog:: { PG11 , PG13 , PG14 } ,
25+ gpiog:: { PG11 , PG13 } ,
1526 Input ,
1627 Speed :: VeryHigh ,
1728 } ,
1829 pac:: { RCC , SYSCFG } ,
1930} ;
2031
21- #[ cfg( feature = "stm32f7xx-hal" ) ]
32+ #[ cfg( any( feature = "stm32f4xx-hal" , feature = "stm32f7xx-hal" ) ) ]
33+ use crate :: hal:: gpio:: gpiog:: PG14 ;
34+
35+ #[ cfg( any( feature = "stm32f7xx-hal" , feature = "stm32h7xx-hal" ) ) ]
2236use cortex_m:: interrupt;
2337
24- #[ cfg( feature = "stm32f7xx-hal" ) ]
25- use stm32f7xx_hal:: {
26- gpio:: {
27- gpioa:: { PA1 , PA7 } ,
28- gpiob:: { PB11 , PB12 , PB13 } ,
29- gpioc:: { PC4 , PC5 } ,
30- gpiog:: { PG11 , PG13 , PG14 } ,
31- Input ,
32- Speed :: VeryHigh ,
33- } ,
34- pac:: { RCC , SYSCFG } ,
35- } ;
38+ #[ cfg( feature = "f-series" ) ]
39+ use crate :: stm32:: ETHERNET_MMC ;
3640
37- use crate :: {
38- dma:: EthernetDMA ,
39- stm32:: { ETHERNET_DMA , ETHERNET_MAC , ETHERNET_MMC } ,
40- } ;
41+ #[ cfg( feature = "stm32h7xx-hal" ) ]
42+ use crate :: stm32:: ETHERNET_MTL ;
4143
4244#[ cfg( feature = "ptp" ) ]
43- use crate :: { ptp:: EthernetPTP , stm32 :: ETHERNET_PTP } ;
45+ use crate :: ptp:: EthernetPTP ;
4446
4547// Enable syscfg and ethernet clocks. Reset the Ethernet MAC.
4648pub ( crate ) fn setup ( ) {
49+ #[ cfg( feature = "stm32h7xx-hal" ) ]
50+ interrupt:: free ( |_| {
51+ // SAFETY: we only perform interrupt-free modifications of RCC.
52+ let rcc = unsafe { & * RCC :: ptr ( ) } ;
53+ let syscfg = unsafe { & * SYSCFG :: ptr ( ) } ;
54+
55+ rcc. apb4enr . modify ( |_, w| w. syscfgen ( ) . set_bit ( ) ) ;
56+ rcc. ahb1enr . modify ( |_, w| {
57+ w. eth1macen ( )
58+ . set_bit ( )
59+ . eth1rxen ( )
60+ . set_bit ( )
61+ . eth1txen ( )
62+ . set_bit ( )
63+ } ) ;
64+
65+ // Select RMII mode
66+ //
67+ // SAFETY: this is the correct value for RMII mode.
68+ syscfg. pmcr . modify ( |_, w| unsafe { w. epis ( ) . bits ( 0b100 ) } ) ;
69+
70+ // Reset pulse to MAC.
71+ rcc. ahb1rstr . modify ( |_, w| w. eth1macrst ( ) . set_bit ( ) ) ;
72+ rcc. ahb1rstr . modify ( |_, w| w. eth1macrst ( ) . clear_bit ( ) ) ;
73+ } ) ;
74+
4775 #[ cfg( feature = "stm32f4xx-hal" ) ]
4876 unsafe {
4977 const SYSCFG_BIT : u8 = 14 ;
@@ -178,44 +206,21 @@ pin_trait!(
178206 [ RmiiRxD1 , "RMII RX Data Pin 1" , "RXD1" ]
179207) ;
180208
181- /// Trait needed to setup the pins for the Ethernet peripheral.
182- pub trait AlternateVeryHighSpeed {
183- /// Puts the pin in the Alternate Function 11 with Very High Speed.
184- fn into_af11_very_high_speed ( self ) ;
185- }
186-
187209/// A struct that contains all peripheral parts required to configure
188210/// the ethernet peripheral.
189211#[ allow( missing_docs) ]
190212pub struct PartsIn {
191213 pub mac : ETHERNET_MAC ,
192- pub mmc : ETHERNET_MMC ,
193214 pub dma : ETHERNET_DMA ,
194- #[ cfg( feature = "ptp" ) ]
195- pub ptp : ETHERNET_PTP ,
196- }
197215
198- #[ cfg( feature = "ptp" ) ]
199- impl From < ( ETHERNET_MAC , ETHERNET_MMC , ETHERNET_DMA , ETHERNET_PTP ) > for PartsIn {
200- fn from ( value : ( ETHERNET_MAC , ETHERNET_MMC , ETHERNET_DMA , ETHERNET_PTP ) ) -> Self {
201- Self {
202- mac : value. 0 ,
203- mmc : value. 1 ,
204- dma : value. 2 ,
205- ptp : value. 3 ,
206- }
207- }
208- }
216+ #[ cfg( feature = "f-series" ) ]
217+ pub mmc : ETHERNET_MMC ,
209218
210- #[ cfg( not( feature = "ptp" ) ) ]
211- impl From < ( ETHERNET_MAC , ETHERNET_MMC , ETHERNET_DMA ) > for PartsIn {
212- fn from ( value : ( ETHERNET_MAC , ETHERNET_MMC , ETHERNET_DMA ) ) -> Self {
213- Self {
214- mac : value. 0 ,
215- mmc : value. 1 ,
216- dma : value. 2 ,
217- }
218- }
219+ #[ cfg( feature = "stm32h7xx-hal" ) ]
220+ pub mtl : ETHERNET_MTL ,
221+
222+ #[ cfg( all( feature = "ptp" , feature = "f-series" ) ) ]
223+ pub ptp : crate :: stm32:: ETHERNET_PTP ,
219224}
220225
221226/// Access to all configured parts of the ethernet peripheral.
@@ -229,20 +234,10 @@ pub struct Parts<'rx, 'tx, T> {
229234 pub ptp : EthernetPTP ,
230235}
231236
232- #[ cfg( feature = "ptp" ) ]
233- impl < ' rx , ' tx , T > Parts < ' rx , ' tx , T > {
234- /// Split this [`Parts`] into its components.
235- pub fn split ( self ) -> ( T , EthernetDMA < ' rx , ' tx > , EthernetPTP ) {
236- ( self . mac , self . dma , self . ptp )
237- }
238- }
239-
240- #[ cfg( not( feature = "ptp" ) ) ]
241- impl < ' rx , ' tx , T > Parts < ' rx , ' tx , T > {
242- /// Split this [`Parts`] into its components.
243- pub fn split ( self ) -> ( T , EthernetDMA < ' rx , ' tx > ) {
244- ( self . mac , self . dma )
245- }
237+ /// Trait needed to setup the pins for the Ethernet peripheral.
238+ pub trait AlternateVeryHighSpeed {
239+ /// Puts the pin in the Alternate Function 11 with Very High Speed.
240+ fn into_af11_very_high_speed ( self ) ;
246241}
247242
248243/// A struct that represents a combination of pins to be used
@@ -305,6 +300,33 @@ macro_rules! impl_pins {
305300 } ;
306301}
307302
303+ #[ cfg( feature = "stm32h7xx-hal" ) ]
304+ impl_pins ! (
305+ RmiiRefClk : [
306+ PA1 <Input >,
307+ ] ,
308+ RmiiCrsDv : [
309+ PA7 <Input >,
310+ ] ,
311+ RmiiTxEN : [
312+ PB11 <Input >,
313+ PG11 <Input >,
314+ ] ,
315+ RmiiTxD0 : [
316+ PB12 <Input >,
317+ PG13 <Input >,
318+ ] ,
319+ RmiiTxD1 : [
320+ PB13 <Input >,
321+ ] ,
322+ RmiiRxD0 : [
323+ PC4 <Input >,
324+ ] ,
325+ RmiiRxD1 : [
326+ PC5 <Input >,
327+ ] ,
328+ ) ;
329+
308330#[ cfg( any( feature = "stm32f4xx-hal" , feature = "stm32f7xx-hal" ) ) ]
309331impl_pins ! (
310332 RmiiRefClk : [
0 commit comments