⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9161.c

📁 IAR5.2下 AT91SAM9260 ARM 对 MCP2515 控制源化码
💻 C
📖 第 1 页 / 共 2 页
字号:

        PIO_Configure(pEmacPins, nbEmacPins);
        rc = EMAC_SetMdcClock( mck );
        if (!rc) {

            trace_LOG(trace_FATAL, "E: No Valid MDC clock\n\r");
            return 0;
        }

        // Check PHY Address
        phy = DM9161_FindValidPhy(pDm);
        if (phy == 0xFF) {

            trace_LOG(trace_ERROR, "E: PHY Access fail\n\r");
            return 0;
        }
        if(phy != pDm->phyAddress) {

            pDm->phyAddress = phy;

            DM9161_ResetPhy(pDm);

        }

    }
    else {

        trace_LOG(trace_ERROR, "E: PHY Reset Timeout\n\r");
    }

    return rc;
}

//-----------------------------------------------------------------------------
/// Issue a Auto Negotiation of the PHY
/// Return 1 if successfully, 0 if timeout.
/// \param pDm   Pointer to the Dm9161 instance
//-----------------------------------------------------------------------------
unsigned char DM9161_AutoNegotiate(Dm9161 *pDm)
{
    unsigned int retryMax;
    unsigned int value;
    unsigned int phyAnar;
    unsigned int phyAnalpar;
    unsigned int retryCount= 0;
    unsigned char phyAddress;
    unsigned char rc = 1;

    ASSERT(pDm, "F: DM9161_AutoNegotiate\n\r");
    phyAddress = pDm->phyAddress;
    retryMax = pDm->retryMax;

    EMAC_EnableMdio();

    if (!EMAC_ReadPhy(phyAddress, DM9161_PHYID1, &value, retryMax)) {
        trace_LOG(trace_DEBUG, "Pb EMAC_ReadPhy Id1\n\r");
        rc = 0;
        goto AutoNegotiateExit;
    }
    trace_LOG(trace_DEBUG, "ReadPhy Id1 0x%X, addresse: %d\n\r", value, phyAddress);
    if (!EMAC_ReadPhy(phyAddress, DM9161_PHYID2, &phyAnar, retryMax)) {
        trace_LOG(trace_DEBUG, "Pb EMAC_ReadPhy Id2\n\r");
        rc = 0;
        goto AutoNegotiateExit;
    }
    trace_LOG(trace_DEBUG, "ReadPhy Id2 0x%X\n\r", phyAnar);

    if( ( value == DM9161_OUI_MSB )
     && ( ((phyAnar>>10)&DM9161_LSB_MASK) == DM9161_OUI_LSB ) ) {

        trace_LOG(trace_DEBUG, "Vendor Number Model = 0x%X\n\r", ((phyAnar>>4)&0x3F));
        trace_LOG(trace_DEBUG, "Model Revision Number = 0x%X\n\r", (phyAnar&0x7));
    }
    else {
        trace_LOG(trace_ERROR, "Problem OUI value\n\r");
    }

    // Setup control register
    rc  = EMAC_ReadPhy(phyAddress, DM9161_BMCR, &value, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    value &= ~DM9161_AUTONEG;   // Remove autonegotiation enable
    value &= ~(DM9161_LOOPBACK|DM9161_POWER_DOWN);
    value |=  DM9161_ISOLATE;   // Electrically isolate PHY
    rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    // Set the Auto_negotiation Advertisement Register
    // MII advertising for Next page
    // 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3
    phyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
              DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
    rc = EMAC_WritePhy(phyAddress, DM9161_ANAR, phyAnar, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    // Read & modify control register
    rc  = EMAC_ReadPhy(phyAddress, DM9161_BMCR, &value, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
    rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    // Restart Auto_negotiation
    value |=  DM9161_RESTART_AUTONEG;
    value &= ~DM9161_ISOLATE;
    rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }
    trace_LOG(trace_DEBUG, " _BMCR: 0x%X\n\r", value);

    // Check AutoNegotiate complete
    while (1) {

        rc  = EMAC_ReadPhy(phyAddress, DM9161_BMSR, &value, retryMax);
        if (rc == 0) {

            trace_LOG(trace_DEBUG, "rc==0\n\r");
            goto AutoNegotiateExit;
        }
        // Done successfully
        if (value & DM9161_AUTONEG_COMP) {

            trace_LOG(trace_INFO, "AutoNegotiate complete\n\r");
            break;
        }
        // Timeout check
        if (retryMax) {

            if (++ retryCount >= retryMax) {

                DM9161_DumpRegisters(pDm);
                trace_LOG(trace_DEBUG, "TimeOut\n\r");
                goto AutoNegotiateExit;
            }
        }
    }

    // Get the AutoNeg Link partner base page
    rc  = EMAC_ReadPhy(phyAddress, DM9161_ANLPAR, &phyAnalpar, retryMax);
    if (rc == 0) {

        goto AutoNegotiateExit;
    }

    // Setup the EMAC link speed
    if ((phyAnar & phyAnalpar) & DM9161_TX_FDX) {

        // set MII for 100BaseTX and Full Duplex
        EMAC_SetLinkSpeed(1, 1);
    }
    else if ((phyAnar & phyAnalpar) & DM9161_10_FDX) {

        // set MII for 10BaseT and Full Duplex
        EMAC_SetLinkSpeed(0, 1);
    }
    else if ((phyAnar & phyAnalpar) & DM9161_TX_HDX) {

        // set MII for 100BaseTX and half Duplex
        EMAC_SetLinkSpeed(1, 0);
    }
    else if ((phyAnar & phyAnalpar) & DM9161_10_HDX) {

        // set MII for 10BaseT and half Duplex
        EMAC_SetLinkSpeed(0, 0);
    }

    // Setup EMAC mode
#if BOARD_EMAC_MODE_RMII != 1
    EMAC_EnableMII();
#else
    EMAC_EnableRMII();
#endif

AutoNegotiateExit:
    EMAC_DisableMdio();
    return rc;
}

//-----------------------------------------------------------------------------
/// Get the Link & speed settings, and automatically setup the EMAC with the
/// settings.
/// Return 1 if link found, 0 if no ethernet link.
/// \param pDm          Pointer to the Dm9161 instance
/// \param applySetting Apply the settings to EMAC interface
//-----------------------------------------------------------------------------
unsigned char DM9161_GetLinkSpeed(Dm9161 *pDm, unsigned char applySetting)
{
    unsigned int retryMax;
    unsigned int stat1;
    unsigned int stat2;
    unsigned char phyAddress;
    unsigned char rc = 1;

    trace_LOG(trace_DEBUG, "DM9161_GetLinkSpeed\n\r");
    ASSERT(pDm, "F: DM9161_GetLinkSpeed\n\r");

    EMAC_EnableMdio();
    phyAddress = pDm->phyAddress;
    retryMax = pDm->retryMax;

    rc  = EMAC_ReadPhy(phyAddress, DM9161_BMSR, &stat1, retryMax);
    if (rc == 0) {

        goto GetLinkSpeedExit;
    }

    if ((stat1 & DM9161_LINK_STATUS) == 0) {

        trace_LOG(trace_DEBUG, "Pb: LinkStat: 0x%x\n\r", stat1);

        rc = 0;
        goto GetLinkSpeedExit;
    }

    if (applySetting == 0) {

        trace_LOG(trace_DEBUG, "Pb: applySetting: 0x%x\n\r", applySetting);
        goto GetLinkSpeedExit;
    }

    // Re-configure Link speed
    rc  = EMAC_ReadPhy(phyAddress, DM9161_DSCSR, &stat2, retryMax);
    if (rc == 0) {

        trace_LOG(trace_DEBUG, "Pb: rc: 0x%x\n\r", rc);
        goto GetLinkSpeedExit;
    }

    if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {

        // set Emac for 100BaseTX and Full Duplex
        EMAC_SetLinkSpeed(1, 1);
    }

    if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {

        // set MII for 10BaseT and Full Duplex
        EMAC_SetLinkSpeed(0, 1);
    }

    if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {

        // set MII for 100BaseTX and Half Duplex
        EMAC_SetLinkSpeed(1, 0);
    }

    if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {

        // set MII for 10BaseT and Half Duplex
        EMAC_SetLinkSpeed(0, 0);
    }

    // Start the EMAC transfers
    trace_LOG(trace_DEBUG, "DM9161_GetLinkSpeed passed\n\r");

GetLinkSpeedExit:
    EMAC_DisableMdio();
    return rc;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -