Трудности с PHY Ethernet

Я работаю над дизайном на основе микрочипа (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 (полный или полудуплекс), оно все равно будет иметь то же значение.

Микрочип предложил мне попытаться изолировать проблему с помощью обратной связи, но я не уверен, как это сделать. Я могу сделать это на уровне MAC с помощью регистра управления сетью, но после этого - как я могу отправлять и получать на этом уровне, чтобы проверить, работает ли он? Я могу сделать это на уровне PHY, используя регистр управления основным режимом, но опять же, как проверить после того, как я установил это?

Я приказываю оценочной комиссии попытаться сделать это там - чтобы я мог сравнить результаты с тем, что я вижу, и попытаться экстраполировать (хотя интерфейс немного отличается, так как я использую пакет LQFP, а не BGA, но эта часть интерфейса, надеюсь, идентична.

Другие вопросы, которые, вероятно, имеют меньше шансов получить ответ при обмене стеками - есть ли где-нибудь описание того, как должны выглядеть сигналы, поступающие в PHY и выходящие из нее, так что, если это аппаратная проблема, я должен знать, что Ищу?

Любой, кто имеет какое-либо представление об этом, любая помощь будет принята с благодарностью.

2 ответа

Ответ - плохое подключение разъема RJ11 к плате, что после устранения проблемы решило проблему.

Код (как есть) не проходит проверку тайм-аута через долгое время. Значение в ul_value всегда 0x7859, что, насколько я понимаю, означает:

Пожалуйста, прочитайте значение регистра управления основным режимом (BMCR), проверьте 11-битное значение (IEEE Power Down). Если его ноль означает, что регистр PHY мы можем получить, но некоторые операции или ссылки не могут быть установлены, или произойдет тайм-аут автоматического отрицания.

Соответственно, проверьте в листе данных, как включить INT/PWDN в регистре или любой конфигурации ремешка, для моего случая включите 7-ми битный регистр CFG3. Это может решить вышеупомянутую проблему.

Другие вопросы по тегам