2024年3月17日发(作者:)

DM9161的物理地址是通过接收的4个脚26到29(与RXD3—RXD0复用)以及

35脚CRS/PHYAD4来确定的。具体来说,就是在上电复位的时候,根据这几个脚的高电

平来确定地址。

比如我手头的板子上采用的RMMI,只接了RXD0,RXD1,其他几个脚空着,所以

上电时只有RXD0与RXD1是高电平,因此DM9161物理地址为3.

还有一个方法也可以很好的确定其物理地址。就是采用查询的方法,DM9161的物理

地址肯定是0—31,比如DM9161的寄存器2的内容恒定为0x181,把物理地址0—31

依次试一次,能从寄存器2读出来0x181的就是实际的物理地址。

实现代码如下:(atmel的代码)

//-----------------------------------------------------------------------------

/// Find a valid PHY Address ( from 0 to 31 ).

/// Check BMSR register ( not 0 nor 0xFFFF )

/// Return 0xFF when no valid PHY Address found.

/// param pDm Pointer to the Dm9161 instance

//-----------------------------------------------------------------------------

static unsigned char DM9161_FindValidPhy(Dm9161 * pDm)

{

unsigned int retryMax;

unsigned int value=0;

unsigned char rc;

unsigned char phyAddress;

unsigned char cnt;

TRACE_DEBUG("DM9161_FindValidPhynr");

ASSERT(pDm, "F: DM9161_FindValidPhynr");

EMAC_EnableMdio();

phyAddress = pDm->phyAddress;

retryMax = pDm->retryMax;

// Check current phyAddress

rc = phyAddress;

if( EMAC_ReadPhy(phyAddress, DM9161_PHYID1, &value, retryMax) == 0 ) {

TRACE_ERROR("DM9161 PROBLEMnr");

}

TRACE_DEBUG("_PHYID1 : 0x%X, addr: %dnr", value, phyAddress);

// Find another one

if (value != DM9161_OUI_MSB) {

rc = 0xFF;

for(cnt = 0; cnt < 32; cnt ++) {

phyAddress = (phyAddress + 1) & 0x1F;

if( EMAC_ReadPhy(phyAddress, DM9161_PHYID1, &value, retryMax) ==

0 ) {

TRACE_ERROR("DM9161 PROBLEMnr");

}

TRACE_DEBUG("_PHYID1 : 0x%X, addr: %dnr", value, phyAddress);

if (value == DM9161_OUI_MSB) {

rc = phyAddress;

break;

}

}

}

EMAC_DisableMdio();

if (rc != 0xFF) {

TRACE_INFO("** Valid PHY Found: %dnr", rc);

EMAC_ReadPhy(phyAddress, DM9161_DSCSR, &value, retryMax);

TRACE_DEBUG("_DSCSR : 0x%X, addr: %dnr", value, phyAddress);

}

return rc;

}