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, ®PHY); 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, ®3); 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, ®3); 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, ®); // 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, ®); 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, ®); 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; }