Skip to content

Commit e0af105

Browse files
committed
Inline into EthernetDevice::new()
1 parent 060af75 commit e0af105

File tree

1 file changed

+90
-167
lines changed

1 file changed

+90
-167
lines changed

tm4c129x-hal/src/ethernet.rs

Lines changed: 90 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -85,159 +85,6 @@ static mut RX_BUFFERS: [[u8; ETHERNET_MTU]; NUM_RX_DESCRIPTORS] =
8585
static 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-
24188
pub 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

Comments
 (0)