?? dm9161ae.c
字號(hào):
//#include "uart_defs.h"
#include "DM9161AE.h"
#include "sep4020.h"
#include "def.h"
#include "hardware_intc.h"
/***************************************************************************************
* 函數(shù)名: delay
* 功能說(shuō)明: 錯(cuò)誤顯示延時(shí)函數(shù)
* NOTE:
****************************************************************************************/
VOID delay(UINT32 num)
{
UINT32 i;
for(i = 0;i < num;i++);
}
void DM9161AE_DlyAutoNegAck()
{
UINT32 i;
for(i = 0;i < 500000;i++);
}
void phy_soft_reset()
{
write_reg(MAC_MII_ADDRESS, 0x00);
write_reg(MAC_MII_TXDATA, 0x8000);
write_reg(MAC_MII_CMD, 0x04);
}
void phy_hard_reset()
{
UINT32 i;
*(RP)GPIO_PORTH_SEL |= 0X40;
*(RP)GPIO_PORTH_DATA |= 0X40;
*(RP)GPIO_PORTH_DIR &= ~0X40;
for(i=0;i<10000;i++);
*(RP)GPIO_PORTH_SEL |= 0X40;
*(RP)GPIO_PORTH_DATA &= ~0X40;
*(RP)GPIO_PORTH_DIR &= ~0X40;
for(i=0;i<10000;i++);
*(RP)GPIO_PORTH_SEL |= 0X40;
*(RP)GPIO_PORTH_DATA |= 0X40;
*(RP)GPIO_PORTH_DIR &= ~0X40;
}
/*void phy_hard_reset()
{
UINT32 i;
*(RP)GPIO_PORTA_SEL |= 0X200;
*(RP)GPIO_PORTA_DATA |= 0X200;
*(RP)GPIO_PORTA_DIR &= ~0X200;
for(i=0;i<10000;i++);
*(RP)GPIO_PORTA_SEL |= 0X200;
*(RP)GPIO_PORTA_DATA &= ~0X200;
*(RP)GPIO_PORTA_DIR &= ~0X200;
for(i=0;i<100000;i++);
*(RP)GPIO_PORTA_SEL |= 0X200;
*(RP)GPIO_PORTA_DATA |= 0X200;
*(RP)GPIO_PORTA_DIR &= ~0X200;
}
*/
//************** write MII reg **************//
//*******************************************//
void NetNIC_PhyRegWr(U16 Phy_addr, U16 address, U16 data)
{
U32 mii_status;
write_reg(MAC_MII_ADDRESS, (U32)(address) | Phy_addr);
write_reg(MAC_MII_TXDATA, (U32)data);
write_reg(MAC_MII_CMD, 0x4);
delay(8000);
while(1) {
mii_status = read_reg(MAC_MII_STATUS);
if ((mii_status & 0x2) == 0) break;
}
return;
}
//*************** read MII reg ***************//
//********************************************//
U16 NetNIC_PhyRegRd(U16 Phy_addr, U16 address)
{
U16 mii_rxdata;
U32 mii_status;
write_reg(MAC_MII_ADDRESS, (U32)(address) | Phy_addr);
write_reg(MAC_MII_CMD, 0x2);
delay(4000);
while(1) {
mii_status = read_reg(MAC_MII_STATUS);
if ((mii_status & 0x2) == 0) break;
}
mii_rxdata = (U16)read_reg(MAC_MII_RXDATA);
return(mii_rxdata);
}
/*
*********************************************************************************************************
* NetNIC_PhyInit()
*
* Description : Initialize phyter (ethernet link controller)
* This instance configures the Davicom DM9161AE PHY
*
* Argument(s) : none.
*
* Return(s) : 1 for OK, 0 for error
*
* Caller(s) : AT91SAM7X256_EMAC_Init
*
* Note(s) : Assumes the MDI port as already been enabled for the PHY.
* : This is performed in net_nic.c, AT91SAM7X256_EMAC_Init().
*********************************************************************************************************
*/
STATUS NetNIC_PhyInit ()
{
UINT16 reg_val;
STATUS status;
reg_val = 0; /* Init reg_val & void it to prevent a compiler */
(void)reg_val; /* warning since its not referenced in MII Mode */
phy_hard_reset();
#ifndef RMII
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMCR); /* Read the Basic Mode Control Register (twice) */
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMCR); /* Read the Basic Mode Control Register (twice) */
reg_val &= ~BMCR_ISOLATE; /* Mask off 'Disconnect from MII bit (BMCR_ISOLATE) */
NetNIC_PhyRegWr(AT91C_PHY_ADDR, DM9161AE_BMCR, reg_val); /* Put the PHY into MII mode */
#endif
status = NetNIC_PhyAutoNeg(); /* Perform auto-negotiation */
return status; /* This is done because the AutoNegotiation Error */
} /* is not fatal and does not return upon discovery */
/*
*********************************************************************************************************
* NetNIC_PhyAutoNeg()
*
* Description : Do link auto-negotiation
*
* Argument(s) : none.
*
* Return(s) : 1 = no error, 0 = error
*
* Caller(s) : NetNIC_PhyInit.
*
* Note(s) : none.
*********************************************************************************************************
*/
STATUS NetNIC_PhyAutoNeg ()
{
UINT16 i;
UINT16 reg_val;
BOOLEAN link;
i = DM9161AE_INIT_AUTO_NEG_RETRIES; /* Set the # of retries before declaring a timeout */
link = NetNIC_PhyLinkState(); /* Get the current link state. 1=linked, 0=no link */
if (link == DEF_OFF) {
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMCR); /* Get current control register value */
reg_val |= DEF_BIT_09; /* Set the auto-negotiation start bit */
NetNIC_PhyRegWr(AT91C_PHY_ADDR, DM9161AE_BMCR, reg_val); /* Initiate auto-negotiation */
do { /* Do while auto-neg incomplete, or retries expired */
DM9161AE_DlyAutoNegAck(); /* Wait for a while auto-neg to proceed (net_bsp.c) */
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Read the Basic Mode Status Register */
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Read the Basic Mode Status Register */
i--;
} while (((reg_val & BMSR_LSTATUS) == 0) && (i > 0)); /* While link not established and retries remain */
}
if (i == 0) { /* If we are out of retries... */
return NET_PHY_ERR_AUTONEG_TIMEOUT; /* Return a timeout error */
} else {
return NET_PHY_ERR_NONE; /* Link up and retries remain */
}
}
/*
*********************************************************************************************************
* NetNIC_PhyAutoNegState()
*
* Description : Returns state of auto-negotiation
* This instance probe the Davicom DM9161AE '3.3V Dual-Speed Fast Ethernet Transceiver'
*
* Argument(s) : none.
*
* Return(s) : State of auto-negociation (DEF_OFF = not completed, DEF_ON = completed).
*
* Caller(s) : NetNIC_PhyInit.
*
* Note(s) : If any error is encountered while reading the PHY, this function
* will return Auto Negotiation State = DEF_OFF (incomplete).
*********************************************************************************************************
*/
BOOLEAN NetNIC_PhyAutoNegState ()
{
UINT32 reg_val;
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR);
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR);
if ((reg_val & BMSR_ANEGCOMPLETE) == BMSR_ANEGCOMPLETE) { /* DM9161AE register 0x01: Basic Status Register #1 */
return (DEF_ON); /* BIT 5 Signal the result of the auto negotiation */
} else { /* 1 = complete, 0 = incomplete */
return (DEF_OFF);
}
}
/*
*********************************************************************************************************
* NetNIC_PhyLinkState()
*
* Description : Returns state of ethernet link
* This instance probe the Davicom DM9161AE '3.3V Dual-Speed Fast Ethernet Transceiver'
*
* Argument(s) : none.
*
* Return(s) : State of ethernet link (DEF_OFF = link down, DEF_ON = link up).
*
* Caller(s) : NetNIC_PhyISR_Handler.
*
* Note(s) : If any error is encountered while reading the PHY, this function
* will return link state = DEF_OFF.
*********************************************************************************************************
*/
BOOLEAN NetNIC_PhyLinkState ()
{
UINT16 reg_val;
/* DM9161AE register 0x01: Basic Status Register #1 */
/* BIT 2 , Link Status, 1 = linked, 0 = not linked. */
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR);
reg_val = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR);
reg_val &= BMSR_LSTATUS;
if (reg_val == BMSR_LSTATUS) {
return (DEF_ON);
} else {
return (DEF_OFF);
}
}
/*
*********************************************************************************************************
* NetPHY_GetLinkSpeed()
*
* Description : Returns the speed of the current Ethernet link
* This probes the Davicom DM9161AE '3.3V Dual-Speed Fast Ethernet Transceiver'
*
* Argument(s) : none.
*
* Return(s) : 0 = No Link, 10 = 10mbps, 100 = 100mbps
*
* Caller(s) : AT91SAM7X256_EMAC_Init()
*
* Note(s) : none.
*********************************************************************************************************
*/
UINT32 NetPHY_GetLinkSpeed ()
{
UINT32 bmsr;
UINT32 bmcr;
UINT32 lpa;
bmsr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Get Link Status from PHY status reg. Requires 2 reads */
bmsr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Get Link Status from PHY status reg. Requires 2 reads */
if ((bmsr & BMSR_LSTATUS) == 0) {
return (NET_PHY_SPD_0); /* No link */
}
bmcr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Read the PHY Control Register */
if ((bmcr & BMCR_ANENABLE) == BMCR_ANENABLE) { /* If AutoNegotiation is enabled */
if ((bmsr & BMSR_ANEGCOMPLETE) == 0) { /* If AutoNegotiation is not complete */
return (NET_PHY_SPD_0); /* AutoNegotitation in progress */
}
lpa = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_ANLPAR); /* Read the Link Partner Ability Register */
if (((lpa & LPA_100FULL) == LPA_100FULL) || ((lpa & LPA_100HALF) == LPA_100HALF)) {
return (NET_PHY_SPD_100);
} else {
return (NET_PHY_SPD_10);
}
} else { /* Auto-negotiation not enabled, get speed from BMCR */
if ((bmcr & BMCR_SPEED100) == BMCR_SPEED100) {
return (NET_PHY_SPD_100);
} else {
return (NET_PHY_SPD_10);
}
}
}
/*
*********************************************************************************************************
* NetPHY_GetDuplex()
*
* Description : Returns the duplex mode of the current Ethernet link
* This probes the Davicom DM9161AE '3.3V Dual-Speed Fast Ethernet Transceiver'
*
* Argument(s) : none.
*
* Return(s) : 0 = Unknown (Auto-Neg in progress), 1 = Half Duplex, 2 = Full Duplex
*
* Caller(s) : AT91SAM7X256_EMAC_Init()
*
* Note(s) : none.
*********************************************************************************************************
*/
UINT32 NetPHY_GetLinkDuplex ()
{
UINT32 bmcr;
UINT32 bmsr;
UINT32 lpa;
bmsr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Get Link Status from PHY status reg. Requires 2 reads */
bmsr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Get Link Status from PHY status reg. Requires 2 reads */
if ((bmsr & BMSR_LSTATUS) == 0) {
return (NET_PHY_DUPLEX_UNKNOWN); /* No link, return 'Duplex Uknown' */
}
bmcr = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_BMSR); /* Read the PHY Control Register */
if ((bmcr & BMCR_ANENABLE) == BMCR_ANENABLE) { /* If AutoNegotiation is enabled */
if ((bmsr & BMSR_ANEGCOMPLETE) == 0) { /* If AutoNegotiation is not complete */
return (NET_PHY_DUPLEX_UNKNOWN); /* AutoNegotitation in progress */
}
lpa = NetNIC_PhyRegRd(AT91C_PHY_ADDR, DM9161AE_ANLPAR); /* Read the Link Partner Ability Register */
if (((lpa & LPA_100FULL) == LPA_100FULL) || ((lpa & LPA_10FULL) == LPA_10FULL)) {
return (NET_PHY_DUPLEX_FULL);
} else {
return (NET_PHY_DUPLEX_HALF);
}
} else { /* Auto-negotiation not enabled, get duplex from BMCR */
if ((bmcr & BMCR_FULLDPLX) == BMCR_FULLDPLX) {
return (NET_PHY_DUPLEX_FULL);
} else {
return (NET_PHY_DUPLEX_HALF);
}
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -