1

我正在研究基于 Microchip(Atmel)SAM3X8C 的设计。设计的以太网部分几乎是从 ATSAM3S-EK2-ND 板上复制而来的(我没有,但图纸是制作布局的基础)。我一直与 Microchip 联系,他查看了图纸(和代码)并认为它是正确的。

问题是我无法完成硬件初始化,并且不知道如何继续。

使用的 PHY 是 Davicom DS9161A,它由 ASF 直接支持(选择该部件是因为它与评估板上使用的相同)。与 PHY 的通信正常,我知道这是因为在 ASF 生成的代码中,我正在读取和写入寄存器 - 而我知道其值的寄存器正在读取正确的值(例如,PHYID1 寄存器给出了正确的值0x0181)。

尝试打开链接时会出现此问题。如果我尝试进行自动配置,它会因超时而失败。这发生在尝试进行自动协商的 ASF 生成的代码中。我在这里包含了代码,因此我可以对到目前为止我所尝试的内容发表一些评论:

uint8_t ethernet_phy_auto_negotiate(Emac *p_emac, uint8_t uc_phy_addr)
{
    uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
    uint32_t ul_value;
    uint32_t ul_phy_anar;
    uint32_t ul_phy_analpar;
    uint32_t ul_retry_count = 0;
    uint8_t uc_fd = 0;
    uint8_t uc_speed = 0;
    uint8_t uc_rc = EMAC_TIMEOUT;

    emac_enable_management(p_emac, true);

    /* Set up control register */
    uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    ul_value &= ~MII_AUTONEG; /* Remove auto-negotiation enable */
    ul_value &= ~(MII_LOOPBACK | MII_POWER_DOWN);
    ul_value |= MII_ISOLATE; /* Electrically isolate PHY */
    uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    /* 
     * Set the Auto_negotiation Advertisement Register.
     * MII advertising for Next page.
     * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
     */
    ul_phy_anar = MII_TX_FDX | MII_TX_HDX | MII_10_FDX | MII_10_HDX | 
            MII_AN_IEEE_802_3;
    uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_ANAR, ul_phy_anar);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    /* Read & modify control register */
    uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    ul_value |= MII_SPEED_SELECT | MII_AUTONEG | MII_DUPLEX_MODE;
    uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    /* Restart auto negotiation */
    ul_value |= MII_RESTART_AUTONEG;
    ul_value &= ~MII_ISOLATE;
    uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    /* Check if auto negotiation is completed */
    while (1) {
        uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMSR, &ul_value);
        if (uc_rc != EMAC_OK) {
            emac_enable_management(p_emac, false);
            return uc_rc;
        }
        /* Done successfully */
        if (ul_value & MII_AUTONEG_COMP) {
            break;
        }

        /* Timeout check */
        if (ul_retry_max) {
            if (++ul_retry_count >= ul_retry_max) {
                emac_enable_management(p_emac, false);
                return EMAC_TIMEOUT;
            }
        }
    }

    /* Get the auto negotiate link partner base page */
    uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_ANLPAR, &ul_phy_analpar);
    if (uc_rc != EMAC_OK) {
        emac_enable_management(p_emac, false);
        return uc_rc;
    }

    /* Set up the EMAC link speed */
    if ((ul_phy_anar & ul_phy_analpar) & MII_TX_FDX) {
        /* Set MII for 100BaseTX and Full Duplex */
        uc_speed = true;
        uc_fd = true;
    } else if ((ul_phy_anar & ul_phy_analpar) & MII_10_FDX) {
        /* Set MII for 10BaseT and Full Duplex */
        uc_speed = false;
        uc_fd = true;
    } else if ((ul_phy_anar & ul_phy_analpar) & MII_TX_HDX) {
        /* Set MII for 100BaseTX and half Duplex */
        uc_speed = true;
        uc_fd = false;
    } else if ((ul_phy_anar & ul_phy_analpar) & MII_10_HDX) {
        /* Set MII for 10BaseT and half Duplex */
        uc_speed = false;
        uc_fd = false;
    }

    emac_set_speed(p_emac, uc_speed);
    emac_enable_full_duplex(p_emac, uc_fd);

    emac_enable_rmii(p_emac, ETH_PHY_MODE);
    emac_enable_transceiver_clock(p_emac, true);

    emac_enable_management(p_emac, false);
    return uc_rc;
}

很长一段时间后,代码(原样)在超时检查中失败。ul_value 中的值始终为 0x7859,据我了解,这意味着:

DM9161A 无法在 100BASE-T4 模式下执行 DM9161A 能够在全双工模式下执行 100BASE-TX DM9161A 能够在半双工模式下执行 100BASE-TX DM9161A 能够在全双工模式下执行 10BASE-T DM9161A 能够在半双工模式下执行 10BASE-T PHY 将接受前导码被抑制的管理帧 自动协商过程未完成 检测到远程故障条件 DM9161A 能够执行自动协商 链路未建立 没有 jabber 扩展寄存器功能

现在,我不知道为什么会出现远程故障情况,也不明白为什么永远无法建立链接。如果我跳过自动协商,并尝试将其强制为 10baseT(全双工或半双工)或 100baseT(全双工或半双工),它仍然具有相同的值。

Microchip 建议我尝试通过回送来隔离问题,但我不确定如何执行此操作。我可以使用网络控制寄存器在 MAC 级别执行此操作,但在完成此操作之后 - 我如何在此级别发送和接收以检查它是否正常工作?我可以使用基本模式控制寄存器在 PHY 级别上执行此操作,但同样,我设置后如何测试?

我正在订购评估板尝试在那里执行此操作 - 以便我可以将结果与我所看到的进行比较,并尝试推断(尽管接口略有不同,因为我使用的是 LQFP 封装,而不是 BGA,但是界面的那部分希望是相同的。

其他可能在堆栈交换中得到回答的机会较小的问题 - 是否有任何地方描述了进出 PHY 的信号应该是什么样的,所以如果是硬件问题,我应该知道该怎么做寻找?

任何对此有任何见解的人,将不胜感激。

4

2 回答 2

2

答案是 RJ11 连接器与板子的连接不良,一旦修复,问题就解决了。

于 2017-10-29T07:46:21.127 回答
0

很长一段时间后,代码(原样)在超时检查中失败。ul_value 中的值始终为 0x7859,据我了解,这意味着:

请读取基本模式控制寄存器(BMCR)的值,检查 11 位(IEEE Power Down)值。如果它为零,这意味着我们可以访问 PHY 寄存器,但无法建立某些操作或链接,或者会发生自动否定超时。

相应地在数据表中检查如何在寄存器或任何带配置中启用 INT/PWDN,就我而言,启用第 7 位 CFG3 寄存器。或许可以解决上述问题。

于 2018-02-13T12:57:11.807 回答