@@ -85,159 +85,6 @@ static mut RX_BUFFERS: [[u8; ETHERNET_MTU]; NUM_RX_DESCRIPTORS] =
8585static mut TX_BUFFERS : [ [ u8 ; ETHERNET_MTU ] ; NUM_TX_DESCRIPTORS ] =
8686 [ [ 0 ; ETHERNET_MTU ] ; NUM_TX_DESCRIPTORS ] ;
8787
88- fn emac_reset ( emac0 : & EMAC0 ) {
89- emac0. dmabusmod . modify ( |_, w| w. swr ( ) . set_bit ( ) ) ;
90-
91- while emac0. dmabusmod . read ( ) . swr ( ) . bit_is_set ( ) { }
92- }
93-
94- fn emac_phy_config_set (
95- emac0 : & EMAC0 ,
96- lock : & sysctl:: PowerControl ,
97- config : impl for <' r , ' w > FnOnce (
98- & ' r tm4c129x:: emac0:: pc:: R ,
99- & ' w mut tm4c129x:: emac0:: pc:: W ,
100- ) -> & ' w mut tm4c129x:: emac0:: pc:: W ,
101- ) {
102- emac0. pc . modify ( config) ;
103-
104- let pc = emac0. pc . read ( ) ;
105- if pc. phyext ( ) . bit_is_clear ( ) {
106- sysctl:: reset ( lock, sysctl:: Domain :: Ephy0 ) ;
107- for _ in 0 ..10000 {
108- cortex_m:: asm:: nop ( ) ;
109- }
110- }
111-
112- // TI's register definitions seem to disagree with the datasheet here - this
113- // register should be RW, and also doesn't seem to have the CLKEN field we need.
114- // For now just assert that the bit is already set to the value we expect.
115- if pc. pintfs ( ) . is_rmii ( ) {
116- // emac0.cc.modify(|_, w| w.clken().set_bit());
117- assert ! ( emac0. cc. read( ) . bits( ) & 0x00010000 == 0x00010000 ) ;
118- } else {
119- // emac0.cc.modify(|_, w| w.clken().clear_bit());
120- assert ! ( emac0. cc. read( ) . bits( ) & 0x00010000 == 0 ) ;
121- }
122-
123- sysctl:: reset ( lock, sysctl:: Domain :: Emac0 ) ;
124-
125- for _ in 0 ..1000 {
126- cortex_m:: asm:: nop ( ) ;
127- }
128- }
129-
130- fn emac_init (
131- emac0 : & EMAC0 ,
132- sysclk : u32 ,
133- mut rx_burst : u32 ,
134- mut tx_burst : u32 ,
135- desc_skip_size : u32 ,
136- ) {
137- // Parameter sanity checks.
138- assert ! ( desc_skip_size < 32 ) ;
139- assert ! ( tx_burst < 32 * 8 ) ;
140- assert ! ( rx_burst < 32 * 8 ) ;
141-
142- // Make sure that the DMA software reset is clear before continuing.
143- while emac0. dmabusmod . read ( ) . swr ( ) . bit_is_set ( ) { }
144-
145- emac0. dmabusmod . modify ( |_, w| {
146- // Set common flags. Note that this driver assumes we are always using 8 word
147- // descriptors so we need to OR in EMAC_DMABUSMOD_ATDS here.
148-
149- // Do we need to use the 8X burst length multiplier?
150- if tx_burst > 32 || rx_burst > 32 {
151- // Divide both burst lengths by 8 and set the 8X burst length multiplier.
152- w. _8xpbl ( ) . set_bit ( ) ;
153- tx_burst >>= 3 ;
154- rx_burst >>= 3 ;
155-
156- // Sanity check - neither burst length should have become zero. If they did,
157- // this indicates that the values passed are invalid.
158- assert ! ( tx_burst > 0 ) ;
159- assert ! ( rx_burst > 0 ) ;
160- } else {
161- w. _8xpbl ( ) . clear_bit ( ) ;
162- }
163-
164- // Are the receive and transmit burst lengths the same?
165- unsafe {
166- w. pbl ( ) . bits ( tx_burst as u8 ) ;
167- }
168- if rx_burst == tx_burst {
169- // Yes - set up to use a single burst length.
170- w. usp ( ) . clear_bit ( ) ;
171- } else {
172- // No - we need to use separate burst lengths for each.
173- w. usp ( ) . set_bit ( ) ;
174- unsafe {
175- w. rpbl ( ) . bits ( rx_burst as u8 ) ;
176- }
177- }
178-
179- // Finally, write the bus mode register.
180- w
181- } ) ;
182-
183- unsafe {
184- emac0. miiaddr . modify ( |_, w| {
185- w. cr ( ) . bits ( if sysclk < 20_000_000 {
186- panic ! ( )
187- } else if sysclk < 35_000_000 {
188- 0x8
189- } else if sysclk < 60_000_000 {
190- 0xc
191- } else if sysclk < 100_000_000 {
192- 0x0
193- } else if sysclk < 150_000_000 {
194- 0x4
195- } else {
196- panic ! ( )
197- } )
198- } ) ;
199- }
200-
201- // Disable all the MMC interrupts as these are enabled by default at reset.
202- unsafe {
203- emac0. mmcrxim . write ( |w| w. bits ( 0xffffffff ) ) ;
204- emac0. mmctxim . write ( |w| w. bits ( 0xffffffff ) ) ;
205- }
206- }
207-
208- fn emac_primary_addr_set ( emac0 : & EMAC0 , mac_addr : [ u8 ; 6 ] ) {
209- unsafe {
210- emac0. addr0h . write ( |w| {
211- w. addrhi ( )
212- . bits ( byteorder:: LittleEndian :: read_u16 ( & mac_addr[ 4 ..] ) )
213- } ) ;
214- emac0. addr0l . write ( |w| {
215- w. addrlo ( )
216- . bits ( byteorder:: LittleEndian :: read_u32 ( & mac_addr[ ..4 ] ) )
217- } ) ;
218- }
219- }
220-
221- fn emac_frame_filter_set (
222- emac0 : & EMAC0 ,
223- filter_opts : impl for <' r , ' w > FnOnce (
224- & ' r tm4c129x:: emac0:: framefltr:: R ,
225- & ' w mut tm4c129x:: emac0:: framefltr:: W ,
226- ) -> & ' w mut tm4c129x:: emac0:: framefltr:: W ,
227- ) {
228- emac0. framefltr . modify ( filter_opts)
229- }
230-
231- fn emac_tx_enable ( emac0 : & EMAC0 ) {
232- emac0. dmaopmode . modify ( |_, w| w. st ( ) . set_bit ( ) ) ;
233- emac0. cfg . modify ( |_, w| w. te ( ) . set_bit ( ) ) ;
234- }
235-
236- fn emac_rx_enable ( emac0 : & EMAC0 ) {
237- emac0. dmaopmode . modify ( |_, w| w. sr ( ) . set_bit ( ) ) ;
238- emac0. cfg . modify ( |_, w| w. re ( ) . set_bit ( ) ) ;
239- }
240-
24188pub struct EthernetDevice {
24289 emac0 : EMAC0 ,
24390 next_rx_descriptor : & ' static RDES ,
@@ -265,9 +112,11 @@ impl EthernetDevice {
265112 sysctl:: PowerState :: On ,
266113 ) ;
267114
268- emac_reset ( & emac0) ;
115+ emac0. dmabusmod . modify ( |_ , w| w . swr ( ) . set_bit ( ) ) ;
269116
270- emac_phy_config_set ( & emac0, lock, |_, w| {
117+ while emac0. dmabusmod . read ( ) . swr ( ) . bit_is_set ( ) { }
118+
119+ emac0. pc . modify ( |_, w| {
271120 // EMAC_PHY_TYPE_INTERNAL
272121 w. phyext ( ) . clear_bit ( ) ;
273122 w. pintfs ( ) . imii ( ) ;
@@ -281,24 +130,74 @@ impl EthernetDevice {
281130 w
282131 } ) ;
283132
284- emac_init ( & emac0, clocks. sysclk . 0 , 4 , 4 , 1 ) ;
133+ let pc = emac0. pc . read ( ) ;
134+ if pc. phyext ( ) . bit_is_clear ( ) {
135+ sysctl:: reset ( lock, sysctl:: Domain :: Ephy0 ) ;
136+ for _ in 0 ..10000 {
137+ cortex_m:: asm:: nop ( ) ;
138+ }
139+ }
140+
141+ // TI's register definitions seem to disagree with the datasheet here - this
142+ // register should be RW, and also doesn't seem to have the CLKEN field we need.
143+ // For now just assert that the bit is already set to the value we expect.
144+ if pc. pintfs ( ) . is_rmii ( ) {
145+ // emac0.cc.modify(|_, w| w.clken().set_bit());
146+ assert ! ( emac0. cc. read( ) . bits( ) & 0x00010000 == 0x00010000 ) ;
147+ } else {
148+ // emac0.cc.modify(|_, w| w.clken().clear_bit());
149+ assert ! ( emac0. cc. read( ) . bits( ) & 0x00010000 == 0 ) ;
150+ }
151+
152+ sysctl:: reset ( lock, sysctl:: Domain :: Emac0 ) ;
153+
154+ for _ in 0 ..1000 {
155+ cortex_m:: asm:: nop ( ) ;
156+ }
157+
158+ // Make sure that the DMA software reset is clear before continuing.
159+ while emac0. dmabusmod . read ( ) . swr ( ) . bit_is_set ( ) { }
160+
161+ emac0. dmabusmod . reset ( ) ;
162+
163+ unsafe {
164+ emac0. miiaddr . modify ( |_, w| {
165+ w. cr ( ) . bits ( if clocks. sysclk . 0 < 20_000_000 {
166+ panic ! ( )
167+ } else if clocks. sysclk . 0 < 35_000_000 {
168+ 0x8
169+ } else if clocks. sysclk . 0 < 60_000_000 {
170+ 0xc
171+ } else if clocks. sysclk . 0 < 100_000_000 {
172+ 0x0
173+ } else if clocks. sysclk . 0 < 150_000_000 {
174+ 0x4
175+ } else {
176+ panic ! ( )
177+ } )
178+ } ) ;
179+ }
180+
181+ // Disable all the MMC interrupts as these are enabled by default at reset.
182+ unsafe {
183+ emac0. mmcrxim . write ( |w| w. bits ( 0xffffffff ) ) ;
184+ emac0. mmctxim . write ( |w| w. bits ( 0xffffffff ) ) ;
185+ }
285186
286- // Set the configuration flags as specified. Note that we unconditionally
287- // OR in the EMAC_CFG_PS bit here since this implementation supports only
288- // MII and RMII interfaces to the PHYs.
289187 emac0. cfg . modify ( |_, w| {
188+ // w.saddr().bits(0x02);
189+ w. cst ( ) . set_bit ( ) ;
190+ w. ifg ( ) . _96 ( ) ;
290191 w. dupm ( ) . set_bit ( ) ;
192+ w. fes ( ) . set_bit ( ) ;
291193 w. ipc ( ) . set_bit ( ) ;
292- w. ifg ( ) . _96 ( ) ;
293- w. cst ( ) . set_bit ( ) ;
294194 w. acs ( ) . set_bit ( ) ;
295- // w.saddr().bits(0x02);
296195 w. bl ( ) . _1024 ( ) ;
297196
298197 w
299198 } ) ;
300199
301- emac0. wdogto . write ( |w| w . pwe ( ) . clear_bit ( ) ) ;
200+ emac0. wdogto . reset ( ) ;
302201
303202 emac0. dmaopmode . write ( |w| {
304203 w. rsf ( ) . set_bit ( ) ;
@@ -361,11 +260,24 @@ impl EthernetDevice {
361260 . write ( |w| w. bits ( & TX_DESCRIPTORS as * const _ as u32 ) ) ;
362261 }
363262
364- emac_primary_addr_set ( & emac0, [ 0x00u8 , 0x1A , 0xB6 , 0x00 , 0x02 , 0x74 ] ) ;
263+ {
264+ unsafe {
265+ let mac_addr = [ 0x00u8 , 0x1A , 0xB6 , 0x00 , 0x02 , 0x74 ] ;
266+
267+ emac0. addr0h . write ( |w| {
268+ w. addrhi ( )
269+ . bits ( byteorder:: LittleEndian :: read_u16 ( & mac_addr[ 4 ..] ) )
270+ } ) ;
271+ emac0. addr0l . write ( |w| {
272+ w. addrlo ( )
273+ . bits ( byteorder:: LittleEndian :: read_u32 ( & mac_addr[ ..4 ] ) )
274+ } ) ;
275+ }
276+ }
365277
366278 while ephy. bmsr . read ( & mut emac0) . linkstat ( ) . bit_is_clear ( ) { }
367279
368- emac_frame_filter_set ( & emac0, |_, w| {
280+ emac0. framefltr . modify ( |_, w| {
369281 w. ra ( ) . set_bit ( ) ;
370282 w. pr ( ) . set_bit ( ) ;
371283
@@ -377,8 +289,19 @@ impl EthernetDevice {
377289 emac0. ephyim . write ( |w| w. bits ( 0xffff_ffff ) ) ;
378290 }
379291
380- emac_tx_enable ( & emac0) ;
381- emac_rx_enable ( & emac0) ;
292+ emac0. dmaopmode . modify ( |_, w| {
293+ w. sr ( ) . set_bit ( ) ;
294+ w. st ( ) . set_bit ( ) ;
295+
296+ w
297+ } ) ;
298+ emac0. cfg . modify ( |_, w| {
299+ w. re ( ) . set_bit ( ) ;
300+ w. te ( ) . set_bit ( ) ;
301+
302+ w
303+ } ) ;
304+
382305 nvic. enable ( tm4c129x:: Interrupt :: EMAC0 ) ;
383306
384307 EthernetDevice {
0 commit comments