superficial ethmac cleanup

This commit is contained in:
Sebastien Bourdeauducq 2017-08-05 16:24:22 +08:00
parent 648b4da9da
commit e8d6d84ac5
1 changed files with 55 additions and 84 deletions

View File

@ -4,9 +4,9 @@ use tm4c129x;
use core::slice; use core::slice;
use smoltcp::Error; use smoltcp::Error;
use smoltcp::phy::{DeviceLimits, Device}; use smoltcp::phy::{DeviceLimits, Device};
use smoltcp::wire::{EthernetAddress};
const EPHY_BMCR: u8 = 0x00; // Ethernet PHY Basic Mode Control const EPHY_BMCR: u8 = 0x00; // Ethernet PHY Basic Mode Control
#[allow(dead_code)]
const EPHY_BMSR: u8 = 0x01; // Ethernet PHY Basic Mode Status const EPHY_BMSR: u8 = 0x01; // Ethernet PHY Basic Mode Status
const EPHY_ID1: u8 = 0x02; // Ethernet PHY Identifier Register 1 const EPHY_ID1: u8 = 0x02; // Ethernet PHY Identifier Register 1
const EPHY_ID2: u8 = 0x03; // Ethernet PHY Identifier Register 2 const EPHY_ID2: u8 = 0x03; // Ethernet PHY Identifier Register 2
@ -60,8 +60,8 @@ static mut EMAC_DATA: EmacData = EmacData {
rx_pkt_buf: [0; ETH_RX_BUFFER_COUNT * ETH_RX_BUFFER_SIZE], rx_pkt_buf: [0; ETH_RX_BUFFER_COUNT * ETH_RX_BUFFER_SIZE],
}; };
pub fn delay(d: i32) { fn delay(d: u32) {
for x in 0..d { for _ in 0..d {
unsafe { unsafe {
asm!(" asm!("
NOP NOP
@ -71,48 +71,52 @@ pub fn delay(d: i32) {
} }
fn phy_read(reg_addr: u8) -> u16 { fn phy_read(reg_addr: u8) -> u16 {
unsafe { cortex_m::interrupt::free(|cs| {
let emac0 = tm4c129x::EMAC0.get(); let emac0 = tm4c129x::EMAC0.borrow(cs);
// Make sure the MII is idle // Make sure the MII is idle
while (*emac0).miiaddr.read().miib().bit() {}; while emac0.miiaddr.read().miib().bit() {};
// Tell the MAC to read the given PHY register // Tell the MAC to read the given PHY register
(*emac0).miiaddr.write(|w| { unsafe {
emac0.miiaddr.write(|w| {
w.cr()._100_150() w.cr()._100_150()
.mii().bits(reg_addr & 0x1F) .mii().bits(reg_addr & 0x1F)
.miib().bit(true) .miib().bit(true)
}); });
}
// Wait for the read to complete // Wait for the read to complete
while (*emac0).miiaddr.read().miib().bit() {}; while emac0.miiaddr.read().miib().bit() {};
(*emac0).miidata.read().data().bits() emac0.miidata.read().data().bits()
} })
} }
fn phy_write(reg_addr: u8, reg_data: u16) { fn phy_write(reg_addr: u8, reg_data: u16) {
unsafe { cortex_m::interrupt::free(|cs| {
let emac0 = tm4c129x::EMAC0.get(); let emac0 = tm4c129x::EMAC0.borrow(cs);
// Make sure the MII is idle // Make sure the MII is idle
while (*emac0).miiaddr.read().miib().bit() {}; while emac0.miiaddr.read().miib().bit() {};
(*emac0).miidata.write(|w| { unsafe {
emac0.miidata.write(|w| {
w.data().bits(reg_data) w.data().bits(reg_data)
}); });
// Tell the MAC to write the given PHY register // Tell the MAC to write the given PHY register
(*emac0).miiaddr.write(|w| { emac0.miiaddr.write(|w| {
w.cr()._100_150() w.cr()._100_150()
.mii().bits(reg_addr & 0x1F) .mii().bits(reg_addr & 0x1F)
.miiw().bit(true) .miiw().bit(true)
.miib().bit(true) .miib().bit(true)
}); });
}
// Wait for the read to complete // Wait for the read to complete
while (*emac0).miiaddr.read().miib().bit() {}; while emac0.miiaddr.read().miib().bit() {};
} })
} }
// Writes a value to an extended PHY register in MMD address space // Writes a value to an extended PHY register in MMD address space
@ -149,7 +153,7 @@ pub fn init(mac_addr: [u8; 6]) {
emac0.miiaddr.write(|w| w.cr()._100_150()); // Set the MII CSR clock speed. emac0.miiaddr.write(|w| w.cr()._100_150()); // Set the MII CSR clock speed.
// Checking PHY // Checking PHY
if (phy_read(EPHY_ID1) != 0x2000) | (phy_read(EPHY_ID2) != 0xA221) { // TM4C1294 PHY IDs if (phy_read(EPHY_ID1) != 0x2000) | (phy_read(EPHY_ID2) != 0xA221) {
panic!("PHY ID error!"); panic!("PHY ID error!");
} }
@ -158,7 +162,7 @@ pub fn init(mac_addr: [u8; 6]) {
while 1 == (phy_read(EPHY_BMCR) & 1) {}; // Wait for the reset to be completed while 1 == (phy_read(EPHY_BMCR) & 1) {}; // Wait for the reset to be completed
// Configure PHY LEDs // Configure PHY LEDs
phy_write_ext(EPHY_LEDCFG, 0x0008); //LED0 Link OK/Blink on TX/RX Activit phy_write_ext(EPHY_LEDCFG, 0x0008); // LED0 Link OK/Blink on TX/RX Activity
// Tell the PHY to start an auto-negotiation cycle // Tell the PHY to start an auto-negotiation cycle
phy_write(EPHY_BMCR, 0b00010010_00000000); // ANEN and RESTARTAN phy_write(EPHY_BMCR, 0b00010010_00000000); // ANEN and RESTARTAN
@ -216,8 +220,8 @@ pub fn init(mac_addr: [u8; 6]) {
); );
// Initialize hash table // Initialize hash table
emac0.hashtbll.write(|w| unsafe { w.htl().bits(0 as u32)}); emac0.hashtbll.write(|w| unsafe { w.htl().bits(0)});
emac0.hashtblh.write(|w| unsafe { w.hth().bits(0 as u32)}); emac0.hashtblh.write(|w| unsafe { w.hth().bits(0)});
emac0.flowctl.write(|w| unsafe { w.bits(0)}); // Disable flow control ??? emac0.flowctl.write(|w| unsafe { w.bits(0)}); // Disable flow control ???
@ -298,38 +302,6 @@ pub fn init(mac_addr: [u8; 6]) {
}); });
} }
pub fn info() {
unsafe {
static mut BMSR1: u16 = 0;
static mut R1: u32 = 0;
// Display EMAC status(es) if need
let emac0 = tm4c129x::EMAC0.get();
// let r = (*emac0).dmaris.read().bits();
let r = 0;
if R1 != r {
println!("R=0x{:08x}", r);
}
R1 = r;
// Display PHY/media status
let bmsr = phy_read(EPHY_BMSR);
if BMSR1 != bmsr {
println!("PHY BMSR=0x{:04x}", bmsr);
}
BMSR1 = bmsr;
// Display packets count
let rxp = EMAC_DATA.rx_counter;
EMAC_DATA.rx_counter = 0;
let txp = EMAC_DATA.tx_counter;
EMAC_DATA.tx_counter = 0;
if (0 != rxp) || (0 != txp) {
println!("RX_PKT={} TX_PKT={}", rxp, txp);
}
}
}
fn release_rx_buf() { fn release_rx_buf() {
unsafe { unsafe {
EMAC_DATA.rx_cur_desc += ETH_DESC_U32_SIZE; EMAC_DATA.rx_cur_desc += ETH_DESC_U32_SIZE;
@ -355,7 +327,7 @@ impl Device for EthernetDevice {
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> { fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
unsafe { unsafe {
if 0 == (EMAC_DATA.rx_desc_buf[EMAC_DATA.rx_cur_desc + 0] & EMAC_RDES0_OWN) { if (EMAC_DATA.rx_desc_buf[EMAC_DATA.rx_cur_desc + 0] & EMAC_RDES0_OWN) == 0 {
// check for the whole packet in the buffer and no any error // check for the whole packet in the buffer and no any error
if (EMAC_RDES0_FS | EMAC_RDES0_LS) == EMAC_DATA.rx_desc_buf[EMAC_DATA.rx_cur_desc + 0] & (EMAC_RDES0_FS | EMAC_RDES0_LS | EMAC_RDES0_ES) { if (EMAC_RDES0_FS | EMAC_RDES0_LS) == EMAC_DATA.rx_desc_buf[EMAC_DATA.rx_cur_desc + 0] & (EMAC_RDES0_FS | EMAC_RDES0_LS | EMAC_RDES0_ES) {
// Retrieve the length of the frame // Retrieve the length of the frame
@ -370,7 +342,7 @@ impl Device for EthernetDevice {
Err(Error::Exhausted) Err(Error::Exhausted)
} }
} else { } else {
Err(Error::Exhausted) // currently no bufferes to process Err(Error::Exhausted) // currently no buffers to process
} }
} }
} }
@ -378,7 +350,7 @@ impl Device for EthernetDevice {
fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> { fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
unsafe { unsafe {
// Check if the TX DMA buffer released // Check if the TX DMA buffer released
if 0 == (EMAC_DATA.tx_desc_buf[EMAC_DATA.tx_cur_desc + 0] & EMAC_TDES0_OWN) { if (EMAC_DATA.tx_desc_buf[EMAC_DATA.tx_cur_desc + 0] & EMAC_TDES0_OWN) == 0 {
// Write the number of bytes to send // Write the number of bytes to send
EMAC_DATA.tx_desc_buf[EMAC_DATA.tx_cur_desc + 1] = length as u32 & EMAC_TDES1_TBS1; EMAC_DATA.tx_desc_buf[EMAC_DATA.tx_cur_desc + 1] = length as u32 & EMAC_TDES1_TBS1;
@ -386,7 +358,6 @@ impl Device for EthernetDevice {
ETH_TX_BUFFER_SIZE))) ETH_TX_BUFFER_SIZE)))
} else { } else {
// to do if need: Instruct the DMA to poll the receive descriptor list // to do if need: Instruct the DMA to poll the receive descriptor list
Err(Error::Exhausted) Err(Error::Exhausted)
} }
} }
@ -440,7 +411,7 @@ impl Drop for TxBuffer {
} }
EMAC_DATA.tx_cur_desc = tx_next_desc; EMAC_DATA.tx_cur_desc = tx_next_desc;
EMAC_DATA.tx_counter += 1; // Increment RX statistics EMAC_DATA.tx_counter += 1;
} }
} }
} }