This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DP83848I: ping issue

Part Number: DP83848I

Hi all,

i am making dp83848vii interface with lpc54so18 and i changed phy and i am getting link status and autonogation  but ping is not getting and i read all the register values are below (using lwipstack)

please help me to solve this 

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 * All rights reserved.
 * 
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_phy.h"
#include "fsl_debug_console.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @brief Defines the timeout macro. */
#define PHY_TIMEOUT_COUNT 0xFFFFFFU
volatile unsigned int loop;
/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*!
 * @brief Get the ENET instance from peripheral base address.
 *
 * @param base ENET peripheral base address.
 * @return ENET instance.
 */
extern uint32_t ENET_GetInstance(ENET_Type *base);

/*******************************************************************************
 * Variables
 ******************************************************************************/

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to enet clocks for each instance. */
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_LPC_ENET_COUNT];
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

/*******************************************************************************
 * Code
 ******************************************************************************/

status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) {
	uint32_t regPHY, Afterlink, CDCTRL1;
	uint32_t idReg = 0;
	uint32_t delay = PHY_TIMEOUT_COUNT;
	uint32_t instance = ENET_GetInstance(base);
	bool status = false;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
	/* Set SMI first. */
	CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)
    ENET_SetSMI(base, srcClock_Hz, false);
#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
	ENET_SetSMI(base);
#endif
	/* Initialization after PHY stars to work. */

	uint32_t idReg1 = 0, idReg2 = 0, auto_4h = 0, auto_5h = 0, BCR_0h = 0,
			reg3 = 0, beforelinkup = 0, afterlinkup = 0, add14_h = 0, bmcr = 0,
			reset = 0, msir = 0, bmcr1, PHY_RESET;

	PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &bmcr1);
	PRINTF(" initially -> 0x00U: 0x%04X\n", bmcr1);

	/* Reset first. */
	SYSCON->PRESETCTRL[2] = SYSCON_PRESETCTRL_ETH_RST_MASK;
	SYSCON->PRESETCTRL[2] &= ~SYSCON_PRESETCTRL_ETH_RST_MASK;

	PHY_Read(base, phyAddr, 0x19U, &regPHY);
	PRINTF("BEFORE LINKUP 0x19U: 0x%04X\n", regPHY);

	PHY_Read(base, phyAddr, 0x1BU, &CDCTRL1);
	PRINTF("before LINKUP  0x1B: 0x%04X\n", CDCTRL1);

	PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg1);
	PHY_Read(base, phyAddr, PHY_ID2_REG, &idReg2);
	PRINTF("PHY_ID1_REG: 0x%04X\n", idReg1);
	PRINTF("PHY_ID2_REG: 0x%04X\n", idReg2);

	if (((idReg1 << 16) | (idReg2 & 0xFFF0)) == 0x20005C90) {
		PRINTF("it is DP83848\n");
	} else if (((idReg1 << 16) | (idReg2 & 0xFFF0)) == PHY_CONTROL_ID1) {
		PRINTF("it is LAN8720\n");
	}

//	while ((idReg != PHY_CONTROL_ID1) && (delay != 0)) {
//		PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
//		PRINTF("PHY_ID1_REG: 0x%04X\n", idReg);
//		delay--;
//	}
//	PRINTF("PHY_CONTROL_ID1 pass \n");
//	if (!delay) {
//		return kStatus_Fail;
//	}

	delay = PHY_TIMEOUT_COUNT;

//	/* Reset PHY and wait until completion. */
//	PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
//	do {
//		PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &PHY_RESET);
//	} while (delay-- && PHY_RESET & PHY_BCTL_RESET_MASK);
//
//	if (!delay) {
//		return kStatus_Fail;
//	}
//	PRINTF("reset pass \n");
	/* Set the ability. */
//	PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
//			(PHY_ALL_CAPABLE_MASK | 0x1U));
//PRINTF("base address pass \n");
	/* Start Auto negotiation and wait until auto negotiation completion */
//	PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
//			(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));

// Put DP83848C PHY into reset mode
	PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, 0x8000);

	// Loop until hardware reset completes
	for (loop = 0; loop < 0x100000; loop++) {
		PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &reset);
		if (!(reset & 0x8000)) {
			PRINTF(" Reset has completed \n");
			loop = 0;
			// Reset has completed
			break;
		}
	}

	PHY_Read(base, phyAddr, 0x04U, &auto_4h);
	PHY_Read(base, phyAddr, 0x05U, &auto_5h);
	PRINTF("auto_4h: 0x%04X\n", auto_4h);
	PRINTF("auto_5h: 0x%04X\n", auto_5h);

	PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, 0x3300U);

	PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &bmcr);
	PRINTF("bmcr: 0x%04X\n", bmcr);

	int count = 0;
	for (loop = 0; loop < 0x100000; loop++) {
		PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &reg3);

		if (count < 10)
			PRINTF("0x3300U: 0x%04X\n", reg3);
		count++;

		if (reg3 & 0x0020) {

			PRINTF(" Autonegotiation has completed  \n");
			// Autonegotiation has completed
			break;
		}
	}

	/*****************************all register value********************************/
#if 0

	PRINTF(" *********************All Register Map******************************************************************\n");

	uint32_t ANAR_R=0,ANLPAR_R=0,ANLPARNP_R1=0,ANER_R=0,ANNPTR_R=0,PHYSTS_R=0,MICR_R=0,MISR_R=0,FCSCR_R=0,RECR_R=0,PCSR_R=0,RBR_R=0,LEDCR_R=0,PHYCR_R=0,BTSCR_10=0,CDCTRL1_R=0,EDCR_R=0;

	PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &bmcr);
	PRINTF("BMCR: 0x%04X\n", bmcr);

	PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &reg3);
	PRINTF("BMSR: 0x%04X\n", reg3);

	PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg1);
	PHY_Read(base, phyAddr, PHY_ID2_REG, &idReg2);
	PRINTF("PHY_ID1_REG: 0x%04X\n", idReg1);
	PRINTF("PHY_ID2_REG: 0x%04X\n", idReg2);

	PHY_Read(base, phyAddr, 0x04U, &ANAR_R);
	PRINTF("ANAR: 0x%04X\n", ANAR_R);

	PHY_Read(base, phyAddr, 0x05U, &ANLPAR_R);
	PRINTF("ANLPAR: 0x%04X\n", ANLPAR_R);

	PHY_Read(base, phyAddr, 0x05U, &ANLPARNP_R1);
	PRINTF("ANLPARNP: 0x%04X\n", ANLPARNP_R1);

	PHY_Read(base, phyAddr, 0x06U, &ANER_R);
	PRINTF("ANER: 0x%04X\n", ANER_R);

	PHY_Read(base, phyAddr, 0x07U, &ANNPTR_R);
	PRINTF("ANNPTR: 0x%04X\n", ANNPTR_R);

	PHY_Read(base, phyAddr, 0x10U, &PHYSTS_R);
	PRINTF("PHYSTS: 0x%04X\n", PHYSTS_R);

	PHY_Read(base, phyAddr, 0x11U, &MICR_R);
	PRINTF("MICR: 0x%04X\n", MICR_R);

	PHY_Read(base, phyAddr, 0x12U, &MISR_R);
	PRINTF("MISR: 0x%04X\n", MISR_R);

	PHY_Read(base, phyAddr, 0x14U, &FCSCR_R);
	PRINTF("FCSCR: 0x%04X\n", FCSCR_R);

	PHY_Read(base, phyAddr, 0x15U, &RECR_R);
	PRINTF("RECR: 0x%04X\n", RECR_R);

	PHY_Read(base, phyAddr, 0x16U, &PCSR_R);
	PRINTF("PCSR: 0x%04X\n", PCSR_R);

	PHY_Read(base, phyAddr, 0x17U, &RBR_R);
	PRINTF("RBR: 0x%04X\n", RBR_R);

	PHY_Read(base, phyAddr, 0x18U, &LEDCR_R);
	PRINTF("LEDCR: 0x%04X\n", LEDCR_R);

	PHY_Read(base, phyAddr, 0x19U, &PHYCR_R);
	PRINTF("PHYCR: 0x%04X\n", PHYCR_R);


	PHY_Read(base, phyAddr, 0x1AU, &BTSCR_10);
	PRINTF("10BTSCR: 0x%04X\n", BTSCR_10);


	PHY_Read(base, phyAddr, 0x1BU, &CDCTRL1_R);
	PRINTF("CDCTRL1: 0x%04X\n", CDCTRL1_R);

	PHY_Read(base, phyAddr, 0x1DU, &EDCR_R);
	PRINTF("EDCR: 0x%04X\n", EDCR_R);


#endif



	PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &BCR_0h);
	PRINTF("BCR_0h: 0x%04X\n", BCR_0h);
	PRINTF("after likn bmcr: 0x%04X\n", bmcr);

	PHY_Read(base, phyAddr, 0x12U, &msir);
	PRINTF("0x12h: 0x%04X\n", msir);

//int count=0;
//	delay = PHY_TIMEOUT_COUNT;
//	do {
//		PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &reg);
//		if(count<10)
//		PRINTF("PHY_ID1_REG: 0x%04X\n", reg);
//
//        count++;
//		delay--;
//	} while (delay && ((reg & PHY_SPECIALCTL_AUTONEGDONE_MASK) == 0));
//
//	PRINTF("auto negotiation completion pass \n");
//	if (!delay) {
//		return kStatus_Fail;
//	}

	/* Waiting a moment for phy stable. */
	PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &beforelinkup);
	PRINTF("beforelinkup: 0x%04X\n", beforelinkup);

	for (delay = 0; delay < PHY_TIMEOUT_COUNT; delay++) {
		__ASM("nop");
		PHY_GetLinkStatus(base, phyAddr, &status);

		if (status) {
			PRINTF("PHY link up\n");
			break;
		}
	}

	PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &afterlinkup);
	PRINTF("afterlinkup: 0x%04X\n", afterlinkup);

	PHY_Read(base, phyAddr, 0x14U, &add14_h);
	PRINTF("add14_h: 0x%04X\n", add14_h);

	PHY_Read(base, phyAddr, 0x19U, &Afterlink);
	PRINTF("AFTER LINKUP 0x19U: 0x%04X\n", Afterlink);

	PHY_Read(base, phyAddr, 0x1BU, &CDCTRL1);
	PRINTF("AFTER LINKUP 0x1B: 0x%04X\n", CDCTRL1);

//	for(int i=0;i<20;i++)
//	{
//
//		//PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &add14_h);
//		//PRINTF("add14_h: 0x%04X\n", add14_h);
//		PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &afterlinkup);
//		PRINTF("afterlinkup: 0x%04X\n", afterlinkup);
//		for(int j=0;j<10000000;j++);
//
//	}

	PRINTF("ALL Operation close \n");
	for (int j = 0; j < 20000000; j++)
		;
//	PHY_Read(base, phyAddr, 0x14U, &add14_h);
	PRINTF("afterlinkup: 0x%04X\n", afterlinkup);
//	PRINTF("add14_h: 0x%04X\n", add14_h);

	return kStatus_Success;
}

status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg,
		uint32_t data) {
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)
    uint32_t counter;

    /* Clear the SMI interrupt event. */
    ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);

    /* Starts a SMI write command. */
    ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);

    /* Wait for SMI complete. */
    for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
    {
        if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
        {
            break;
        }
    }

    /* Check for timeout. */
    if (!counter)
    {
        return kStatus_PHY_SMIVisitTimeout;
    }

    /* Clear MII interrupt event. */
    ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);

#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
	ENET_StartSMIWrite(base, phyAddr, phyReg, data);
	while (ENET_IsSMIBusy(base))
		;
#endif
	return kStatus_Success;
}

status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg,
		uint32_t *dataPtr) {
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)
    assert(dataPtr);

    uint32_t counter;

    /* Clear the MII interrupt event. */
    ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);

    /* Starts a SMI read command operation. */
    ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);

    /* Wait for MII complete. */
    for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
    {
        if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
        {
            break;
        }
    }

    /* Check for timeout. */
    if (!counter)
    {
        return kStatus_PHY_SMIVisitTimeout;
    }

    /* Get data from MII register. */
    *dataPtr = ENET_ReadSMIData(base);

    /* Clear MII interrupt event. */
    ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
	ENET_StartSMIRead(base, phyAddr, phyReg);
	while (ENET_IsSMIBusy(base))
		;
	*dataPtr = ENET_ReadSMIData(base);
#endif
	return kStatus_Success;
}

status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) {
	uint32_t reg;
	status_t result = kStatus_Success;

	/* Read the basic status register. */
	result = PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &reg);
	if (result == kStatus_Success) {
		if (reg & PHY_BSTATUS_LINKSTATUS_MASK) {
			/* link up. */
			*status = true;
		} else {
			*status = false;
		}
	}
	return result;
}

status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr,
		phy_speed_t *speed, phy_duplex_t *duplex) {
	assert(duplex);
	assert(speed);

	uint32_t reg;
	status_t result = kStatus_Success;

	/* Read the control two register. */
	result = PHY_Read(base, phyAddr, PHY_SEPCIAL_CONTROL_REG, &reg);
	if (result == kStatus_Success) {
		if (reg & PHY_SPECIALCTL_DUPLEX_MASK) {
			/* Full duplex. */
			*duplex = kPHY_FullDuplex;
		} else {
			/* Half duplex. */
			*duplex = kPHY_HalfDuplex;
		}

		if (reg & PHY_SPECIALCTL_100SPEED_MASK) {
			/* 100M speed. */
			*speed = kPHY_Speed100M;
		} else { /* 10M speed. */
			*speed = kPHY_Speed10M;
		}
	}
	return result;
}