I'm new to LPC and I'm trying to get a DP83848 PHY working with ENET. With some help, I've written a PHY layer to use with the LwIP example but I'm having some trouble reading the registers. Any time I read any of the registers on the PHY it's returning 0xFFFF. I think I've missed something in setting up the pins or perhaps the clocks.
Pictures of Pin's and Clocks attached.
Any guidance is appreciated!
PHY code:
const phy_operations_t phyd8opts = {.phyInit = phyDpInit,
.phyWrite = phyDpWrite,
.phyRead = phyDpRead,
.getLinkStatus = phyDpGetLinkStatus,
.getLinkSpeedDuplex = phyDpGetLinkSpeedDuplex,
.enableLoopback = NULL};
#define PHY_WRITE(x,y)MDIO_Write(handle->mdioHandle, handle->phyAddr, x, y)
#define PHY_READ(x,y)MDIO_Read(handle->mdioHandle, handle->phyAddr, x, y)
void phyDelay(uint32_t mills)
{
int i = 0;
while(i++ < (mills * 128000))
__asm__("nop");
}
status_t phyDpInit(phy_handle_t *handle, const phy_config_t *config)
{
uint32_t read;
int i;
MDIO_Init(handle->mdioHandle);
handle->phyAddr = config->phyAddr;
// Reset the phy
if(PHY_WRITE(DP8_BMCR_REG,DP8_RESET) == kStatus_Fail)
return kStatus_Fail;
i = 500;
while(i--)
{
phyDelay(1);
if(PHY_READ(DP8_BMCR_REG, &read) == kStatus_Fail)
return kStatus_Fail;
if(!(read & (DP8_RESET | DP8_POWER_DOWN)))
break;
}
if( i == -1 )
return kStatus_Timeout;
// Set the configuration
if(PHY_WRITE(DP8_BMCR_REG, DP8_AUTONEG) == kStatus_Fail)
return kStatus_Fail;
do
{
phyDelay(1);
PHY_READ(DP8_BMSR_REG, &read);
} while(!(read & DP8_AUTONEG_COMP));
return kStatus_Success;
}
status_t phyDpWrite(phy_handle_t *handle, uint32_t phyReg, uint32_t data)
{
return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
}
status_t phyDpRead(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr)
{
return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
}
status_t phyDpGetLinkStatus(phy_handle_t *handle, bool *status)
{
uint32_t read;
if(PHY_READ(DP8_BMSR_REG, &read) == kStatus_Success)
{
*status = (read & DP8_LINK_STATUS);
return kStatus_Success;
}
return kStatus_Fail;
}
status_t phyDpGetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
{
uint32_t read;
status_t ret;
ret = kStatus_Fail;
if(PHY_READ(DP8_BMSR_REG, &read) == kStatus_Success)
{
ret = kStatus_Success;
if(read & DP8_100BASE_TX_FD)
{
*speed = kPHY_Speed100M;
*duplex = kPHY_FullDuplex;
}
else if(read & DP8_100BASE_TX_HD)
{
*speed = kPHY_Speed100M;
*duplex = kPHY_HalfDuplex;
}
else if(read & DP8_10BASE_T_FD)
{
*speed = kPHY_Speed10M;
*duplex = kPHY_FullDuplex;
}
else if(read & DP8_10BASE_T_HD)
{
*speed = kPHY_Speed10M;
*duplex = kPHY_FullDuplex;
}
else
{
ret = kStatus_Fail;
}
}
return ret;
}
Hi,
Unfortunately, we do not have any implementation that you could use as reference for this PHY which is different from the one we use un our evaluation boards. I checked your pins and clocks and they seem correct.
I found this old thread from a customer that implemented drivers for this PHY and LPC1788 that you may find useful.
Change PHY to DP83848 in LWIP_lpc-v08.0 - NXP Community
Also, as far as I know the PHY you are using requires external reference clock so I don’t know if this could the because of the issue as well.
Best regards,
Felipe