1
- use crate :: smi:: { self , read, write, StationManagement } ;
2
- use crate :: stm32:: ETHERNET_MAC ;
1
+ use crate :: stm32:: {
2
+ ethernet_mac:: { MACMIIAR , MACMIIDR } ,
3
+ ETHERNET_MAC ,
4
+ } ;
3
5
4
- pub struct NoSmi ;
6
+ /// MDIO pin types.
7
+ pub unsafe trait MdioPin { }
8
+ /// MDC pin types.
9
+ pub unsafe trait MdcPin { }
10
+
11
+ pub trait StationManagement {
12
+ fn read ( & self , phy : u8 , reg : u8 ) -> u16 ;
13
+ fn write ( & mut self , phy : u8 , reg : u8 , data : u16 ) ;
14
+ }
15
+
16
+ #[ inline( always) ]
17
+ fn smi_wait_ready ( iar : & MACMIIAR ) {
18
+ while iar. read ( ) . mb ( ) . bit_is_set ( ) { }
19
+ }
20
+
21
+ #[ inline( always) ]
22
+ fn smi_write ( iar : & MACMIIAR , dr : & MACMIIDR , phy : u8 , reg : u8 , data : u16 ) {
23
+ dr. write ( |w| {
24
+ #[ cfg_attr( not( feature = "stm32f107" ) , allow( unused_unsafe) ) ]
25
+ unsafe {
26
+ w. md ( ) . bits ( data)
27
+ }
28
+ } ) ;
29
+
30
+ iar. modify ( |_, w| {
31
+ #[ cfg_attr( not( feature = "stm32f107" ) , allow( unused_unsafe) ) ]
32
+ unsafe {
33
+ w. pa ( )
34
+ . bits ( phy)
35
+ . mr ( )
36
+ . bits ( reg)
37
+ /* Write operation MW=1*/
38
+ . mw ( )
39
+ . set_bit ( )
40
+ . mb ( )
41
+ . set_bit ( )
42
+ }
43
+ } ) ;
44
+ smi_wait_ready ( iar) ;
45
+ }
46
+
47
+ #[ inline( always) ]
48
+ fn smi_read ( iar : & MACMIIAR , dr : & MACMIIDR , phy : u8 , reg : u8 ) -> u16 {
49
+ iar. modify ( |_, w| {
50
+ #[ cfg_attr( not( feature = "stm32f107" ) , allow( unused_unsafe) ) ]
51
+ unsafe {
52
+ w. pa ( )
53
+ . bits ( phy)
54
+ . mr ( )
55
+ . bits ( reg)
56
+ /* Read operation MW=0 */
57
+ . mw ( )
58
+ . clear_bit ( )
59
+ . mb ( )
60
+ . set_bit ( )
61
+ }
62
+ } ) ;
63
+ smi_wait_ready ( iar) ;
64
+
65
+ // Return value:
66
+ dr. read ( ) . md ( ) . bits ( )
67
+ }
68
+
69
+ /// Station Management Interface with pins and registers borrowed from [`EthernetMAC`].
70
+ ///
71
+ /// Can also be constructed by borrowing from [`ETHERNET_MAC`] and borrowing the pins manually.
72
+ ///
73
+ /// Provides access to the MIIM implementation exposed by the MCU's MAC API.
74
+ pub struct Smi < ' eth , ' pins , Mdio , Mdc > {
75
+ macmiiar : & ' eth MACMIIAR ,
76
+ macmiidr : & ' eth MACMIIDR ,
77
+ _mdio : & ' pins mut Mdio ,
78
+ _mdc : & ' pins mut Mdc ,
79
+ }
80
+
81
+ impl < ' eth , ' pins , Mdio , Mdc > StationManagement for Smi < ' eth , ' pins , Mdio , Mdc >
82
+ where
83
+ Mdio : MdioPin ,
84
+ Mdc : MdcPin ,
85
+ {
86
+ /// Read an SMI register
87
+ fn read ( & self , phy : u8 , reg : u8 ) -> u16 {
88
+ smi_read ( & self . macmiiar , & self . macmiidr , phy, reg)
89
+ }
90
+
91
+ /// Write an SMI register
92
+ fn write ( & mut self , phy : u8 , reg : u8 , data : u16 ) {
93
+ smi_write ( & self . macmiiar , & self . macmiidr , phy, reg, data)
94
+ }
95
+ }
96
+
97
+ impl < ' eth , ' pins , Mdio , Mdc > Smi < ' eth , ' pins , Mdio , Mdc >
98
+ where
99
+ Mdio : MdioPin ,
100
+ Mdc : MdcPin ,
101
+ {
102
+ /// Create the temporary `Smi` instance.
103
+ ///
104
+ /// Temporarily take exclusive access to the MDIO and MDC pins to ensure they are not used
105
+ /// elsewhere for the duration of SMI communication.
106
+ pub fn new (
107
+ macmiiar : & ' eth MACMIIAR ,
108
+ macmiidr : & ' eth MACMIIDR ,
109
+ _mdio : & ' pins mut Mdio ,
110
+ _mdc : & ' pins mut Mdc ,
111
+ ) -> Self {
112
+ Self {
113
+ macmiiar,
114
+ macmiidr,
115
+ _mdio,
116
+ _mdc,
117
+ }
118
+ }
119
+
120
+ /// Read an SMI register
121
+ pub fn read ( & self , phy : u8 , reg : u8 ) -> u16 {
122
+ smi_read ( & self . macmiiar , & self . macmiidr , phy, reg)
123
+ }
124
+ }
125
+
126
+ #[ cfg( feature = "stm32f4xx-hal" ) ]
127
+ mod pin_impls {
128
+ use crate :: hal:: gpio:: { gpioa:: PA2 , gpioc:: PC1 , Alternate } ;
129
+
130
+ const AF11 : u8 = 11 ;
131
+
132
+ unsafe impl super :: MdioPin for PA2 < Alternate < AF11 > > { }
133
+ unsafe impl super :: MdcPin for PC1 < Alternate < AF11 > > { }
134
+ }
135
+
136
+ #[ cfg( feature = "stm32f7xx-hal" ) ]
137
+ mod pin_impls {
138
+ use crate :: hal:: gpio:: { gpioa:: PA2 , gpioc:: PC1 , Alternate } ;
139
+
140
+ const AF11 : u8 = 11 ;
141
+
142
+ unsafe impl super :: MdioPin for PA2 < Alternate < AF11 > > { }
143
+ unsafe impl super :: MdcPin for PC1 < Alternate < AF11 > > { }
144
+ }
145
+
146
+ #[ cfg( feature = "stm32f1xx-hal" ) ]
147
+ mod pin_impls {
148
+ use crate :: hal:: gpio:: { gpioa:: PA2 , gpioc:: PC1 , Alternate , PushPull } ;
149
+
150
+ unsafe impl super :: MdioPin for PA2 < Alternate < PushPull > > { }
151
+ unsafe impl super :: MdcPin for PC1 < Alternate < PushPull > > { }
152
+ }
5
153
6
154
/// Ethernet media access control (MAC).
7
155
pub struct EthernetMAC < SMI > {
@@ -18,12 +166,18 @@ impl EthernetMAC<NoSmi> {
18
166
}
19
167
}
20
168
169
+ /// The MAC does not have and does not provide access to its SMI
170
+ pub struct NoSmi ;
171
+
172
+ /// Access to the MAC's SMI can be obtained by borrowing [`MdioPin`] and [`MdcPin`] to it. For [`StationManagement`], see [`EthernetMAC::smi`]
21
173
pub struct BorrowedSmi ;
22
174
175
+ /// The SMI (and its pins) are owned. An [`EthernetMAC`] that owns
176
+ /// its SMI is [`StationManagement`]
23
177
pub struct OwnedSmi < MDIO , MDC >
24
178
where
25
- MDIO : smi :: MdioPin ,
26
- MDC : smi :: MdcPin ,
179
+ MDIO : MdioPin ,
180
+ MDC : MdcPin ,
27
181
{
28
182
_mdio : MDIO ,
29
183
_mdc : MDC ,
@@ -48,21 +202,21 @@ impl EthernetMAC<BorrowedSmi> {
48
202
& ' eth mut self ,
49
203
mdio : & ' pins mut Mdio ,
50
204
mdc : & ' pins mut Mdc ,
51
- ) -> smi :: Smi < ' eth , ' pins , Mdio , Mdc >
205
+ ) -> Smi < ' eth , ' pins , Mdio , Mdc >
52
206
where
53
- Mdio : smi :: MdioPin ,
54
- Mdc : smi :: MdcPin ,
207
+ Mdio : MdioPin ,
208
+ Mdc : MdcPin ,
55
209
{
56
- smi :: Smi :: new ( & self . eth_mac . macmiiar , & self . eth_mac . macmiidr , mdio, mdc)
210
+ Smi :: new ( & self . eth_mac . macmiiar , & self . eth_mac . macmiidr , mdio, mdc)
57
211
}
58
212
}
59
213
60
214
impl < MDIO , MDC > EthernetMAC < OwnedSmi < MDIO , MDC > >
61
215
where
62
- MDIO : smi :: MdioPin ,
63
- MDC : smi :: MdcPin ,
216
+ MDIO : MdioPin ,
217
+ MDC : MdcPin ,
64
218
{
65
- pub fn new_owned ( eth_mac : ETHERNET_MAC , mdio : MDIO , mdc : MDC ) -> Self {
219
+ pub fn new ( eth_mac : ETHERNET_MAC , mdio : MDIO , mdc : MDC ) -> Self {
66
220
Self {
67
221
eth_mac,
68
222
_state : OwnedSmi {
@@ -75,15 +229,15 @@ where
75
229
76
230
impl < MDIO , MDC > StationManagement for EthernetMAC < OwnedSmi < MDIO , MDC > >
77
231
where
78
- MDIO : smi :: MdioPin ,
79
- MDC : smi :: MdcPin ,
232
+ MDIO : MdioPin ,
233
+ MDC : MdcPin ,
80
234
{
81
235
fn read ( & self , phy : u8 , reg : u8 ) -> u16 {
82
- read ( & self . eth_mac . macmiiar , & self . eth_mac . macmiidr , phy, reg)
236
+ smi_read ( & self . eth_mac . macmiiar , & self . eth_mac . macmiidr , phy, reg)
83
237
}
84
238
85
239
fn write ( & mut self , phy : u8 , reg : u8 , data : u16 ) {
86
- write (
240
+ smi_write (
87
241
& self . eth_mac . macmiiar ,
88
242
& self . eth_mac . macmiidr ,
89
243
phy,
0 commit comments