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.

[参考译文] DP83TC814S-Q1:ETH 的待机和正常模式配置

Guru**** 1139930 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1253184/dp83tc814s-q1-standby-and-normal-mode-configurations-for-eth

器件型号:DP83TC814S-Q1

大家好、我之前研究过待机和正常模式的配置。

每当我尝试将器件配置为待机模式时、请执行以下步骤:

//写入寄存器0x1F 位[7]-> 1. (直接访问)
//将 LPS_CFG3寄存器0x18C 写入0x0010,等于'10000b'。 (MMD1F 访问)
//读取 LPS_STATUS 寄存器0x18E 以检查 ETH PHY 的状态 (MMD1F 访问)
//在回读操作成功之前,尝试设置配置寄存器。
在下面的代码片段中、您可以找到相应的操作。 我认为寄存器读取和写入操作在很大程度上
void BusSleepMode::ConfigureETHPhytoStandbyMode(void)
{
    uint16_t registerData = 1U;
    registerData = registerData<<7U;
    if(WRITE_STATUS_OK == Phy_write_register(0x1FU, registerData))
    {
        // Readback the register to check operation is successful or not.
        if(READ_STATUS_OK == Phy_read_register(0x1FU, &registerData))
        {
            if(1U == ((registerData>>7U) & 0x0001U ))
            {
                LOGI(&gETHNM_Log_ctx, "Write operation is successful for 0x1F");
                while(contextInstanceSM.getETHPhyResetStatus() == false)
                {
                    // Write to 0x18C '10000b' which is equal to 0x10
                    static_cast<void>(MMD1F_write_register(0x18CU, 0x0010U));
                    uint16_t readBack;

                    static_cast<void>(MMD1F_read_register(0x18EU, &readBack));

                    LOGD(&gETHNM_Log_ctx, "READBACK FOR STANDBY: ", readBack);
                    if(1U == ((readBack>>1U) & 0x0001U))
                    {
                        contextInstanceSM.setETHPhyResetConfigurationFlag();
                        LOGI(&gETHNM_Log_ctx, "Standby configuration is made. PHY is running in reset mode now.");
                        break;
                    }
                    else
                    {
                        LOGE(&gETHNM_Log_ctx, "Standby configuration is failed.");
                    }
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                }
            }
        }
    }
    else
    {
        LOGE(&gETHNM_Log_ctx, "Write register to 0x1F returned fail.");
    }
    

}
对于正常模式配置、我基本上遵循以下步骤:
//写入寄存器0x1F 位[7]-> 0。
//将 LPS_CFG3寄存器0x18C 写入0x0001,即等于"1b"。
//读取 LPS_STATUS 寄存器0x18E 以检查 ETH PHY 的状态
//直到状态为预期值,尝试设置。
void NetworkMode::ConfigureETHPhytoNormalMode(void)
{
    uint16_t registerData = 0U;
    registerData = registerData<<7U;
    if(true == contextInstanceSM.getETHPhyResetStatus())
    {
        // Clear out the register data.
        if( WRITE_STATUS_OK == Phy_write_register(0x1FU, registerData))
        {
            if(READ_STATUS_OK == Phy_read_register(0x1FU, &registerData))
            {
                if(0U == ((registerData>>7U) & 0x0001U ))
                {
                    LOGI(&gETHNM_Log_ctx, "Read operation is successful for 0x1F. Bit is cleared.");
                    while(contextInstanceSM.getETHPhyResetStatus() == true)
                    {
                        // Write 0x18C to '1b' to set the normal mode.
                        static_cast<void>(MMD1F_write_register(0x18CU, 0x0001U));

                        uint16_t readBack;
                        static_cast<void>(MMD1F_read_register(0x18EU, &readBack));
                        
                        LOGD(&gETHNM_Log_ctx, "READBACK FOR NORMAL: ", readBack);
                        
                        if(1U == ((readBack>>2U) & 0x0001U))
                        {
                            contextInstanceSM.clearETHPhyResetConfigurationFlag();
                            LOGI(&gETHNM_Log_ctx, "Reset configuration is cleared. PHY is running in normal mode.");
                            break;
                        }
                        else
                        {
                            LOGE(&gETHNM_Log_ctx, "Reset configuration is failed.");
                        }
                        std::this_thread::sleep_for(std::chrono::milliseconds(10));
                    }
                }
            }
        }
        else
        {
            LOGE(&gETHNM_Log_ctx, "Write register to 0x1F returned fail.");
        }
        // Set the link status up by using ioctl functions
        changeLinkStatus("eth0");
        changeLinkStatus("vlan1");
    }
}
在这些配置后、每当我切换到正常模式时、我就会在2秒内无法发送数据。
这些配置是否正确、或者我是否需要在其他地方检查?
Br、
支付宝
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    请允许我复查您的意见并更新您的最新信息。

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Rahul

    我还尝试将其设置为复位模式、方法是将引脚14和15设置为独立试验、但状态未改变。 它仍会在配置后2秒后发送帧。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    如果 PHY 处于正常模式和自主运行状态、则 PHY 将 在 POR 完成后自动尝试与有效链路伙伴建立链路。

    从待机模式更改为正常模式后,是否注意到链路断开或链路建立?

    [quote userid="571472" url="~/support/interface-group/interface/f/interface-forum/1253184/dp83tc814s-q1-standby-and-normal-mode-configurations-for-eth 通过这些配置后,每次切换到正常模式时,我都无法发送数据2秒钟。

    是否 从待机模式更改为正常模式?

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Rahul:

    进入待机模式后、 我观察到、链路状态已更改为未激活、物理接口上的所有发送操作均暂停、对于正常模式配置、链路状态已更改为链路建立状态、进入正常状态2秒后、开始发送帧。 每次用2秒是奇怪的情况。 此外、我还应该告知您这一点、我目前正在使用 VLAN 接口。 我不确定使用 VLAN 会产生什么影响。

    从待机模式更改为正常模式后、我观察到了这种情况。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    另外、我忘记说、当我通过 MMD1F 方法读取0x18B 寄存器时、此寄存器的输出为0。 我认为这表示自主操作未启用、因为没有寄存器的说明。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    请允许我与我的团队核实更多详细信息、然后再联系您。

    您是否可以通过禁用 VLAN 标记来检查此情况并注意到任何改进?

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    static bool checkMediaStatus(void)
    {
        const char *ifName = "fec0";
        int sockFd = socket(AF_INET, SOCK_DGRAM, 0);
        bool retVal = false;  
        if( sockFd != -1)
        {
            struct ifmediareq ifmr;
            strncpy(ifmr.ifm_name, ifName, sizeof(ifName));
            if( -1 == ioctl(sockFd, SIOCGIFMEDIA, &ifmr))
            {
                LOGE(&gETHNM_Log_ctx, "Failed to get media status");
            }
            else
            {
                if(ifmr.ifm_status & IFM_ACTIVE)
                {
                    LOGI(&gETHNM_Log_ctx, "Link is established. Checked by media status");
                    retVal = true;
                }
                else
                {
                    LOGE(&gETHNM_Log_ctx, "Link is not established. Checked by media status.");
                }
                close(sockFd);
            }
        }
        else
        {
            LOGE(&gETHNM_Log_ctx, "Failed to open socket");
        }
        return retVal;
    }

    我还尝试了在更改链接状态后收集媒体状态的检查方法。  

    此外、如果您想更改链接状态器件、我也会添加该器件。

    static void changeLinkStatus(void)
    {
        int sockfd;
        
        // Ethernet interface name
        std::string interfaceName = "fec0";
    
        // Socket creation
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            LOGE(&gETHNM_Log_ctx, "Socket is not created", static_cast<const char *>(strerror(errno)));
        }
        else
        {
            struct ifreq ifr;
    
            // Copy the interface name
            static_cast<void>(strncpy(ifr.ifr_name, interfaceName.c_str(), sizeof(interfaceName.c_str())));
    
            // Get the link status 
            if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) == -1) {
                LOGE(&gETHNM_Log_ctx, "ioctl error", static_cast<const char *>(strerror(errno)));
                // In case of error close the socket
                static_cast<void>(close(sockfd));
            }
            else
            {
                // Set the interface link status to UP
                ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
                
                // Set the new interface link status by ioctl
                if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) == -1) {
                    LOGE(&gETHNM_Log_ctx, "ioctl error", static_cast<const char *>(strerror(errno)));
                    // In case of error close the socket
                    static_cast<void>(close(sockfd));
                }
                else
                {
                    LOGI(&gETHNM_Log_ctx, "Link status is set to UP");
                    // Close socket after successfull operation
                    static_cast<void>(close(sockfd));
                }
            }
        }
    }

    配置正常模式 checkMediaStatus 函数后返回 false 并持续2秒。 我还尝试了禁用 VLAN 接口并从物理接口发送帧,但这种情况没有任何变化。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Alpay 的测试和分享您的反馈。 请在本周结束前给我时间与我的同事核对、并向您更新最新信息。

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    上电时 PHY 处于主/从模式是什么?

    如果 PHY 处于主模式、则  只要所有电源均可用且器件自举以实现管理运行、PHY 就应在上电和复位后自动进入待机模式。

    默认情况下,PHY 在哪种模式下自举?

    我正在尝试了解您的器件在上电时的状态以及此处评估的测试用例是什么。

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Rahul:

    我已经尝试通过检查以下2个寄存器来读取主从模式选项的配置:

    static void checkMasterSlaveConfiguration(void)
    {
        uint16_t masterSlaveData;
    
        MMD1F_read_register(0x0834U, &masterSlaveData);
        if(masterSlaveData & 0x4000)
        {
            LOGI(&gETHNM_Log_ctx,"Master configuration bit is set.");
        }
        else
        {
            LOGI(&gETHNM_Log_ctx,"Slave configuration bit is set.");
        }
    }
    
    static void checkLED0Configuration(void)
    {
        uint16_t led0Data;
        // Read the data at 0x450h
        MMD1F_read_register(0x450U, &led0Data);
        // Condition 0100b
        if( led0Data & 0x0004U)
        {
            LOGI(&gETHNM_Log_ctx,"LED_0 Status: link OK + 100Base-T1 Master");
        }
        // Condition 0101b
        else if( led0Data & 0x0005U)
        {
            LOGI(&gETHNM_Log_ctx,"LED_0 Status: link OK + 100Base-T1 Slave");
        }
    }

    CheckMasterSlaveConfiguration 函数输出被打印出来、并且提示它被配置为从设备。 我已经查看了数据表8.4.5.1章节、其中显示 MMD1_PMA_CTRL_2寄存器(地址0x1834)位[14]表示主模式或从模式配置、LED_0控制自举配置。 LED_0否则情况打印为 9744、这意味着位[3-0]为零、并且表示链路正常。  

    我在进入待机模式之前以及在将其配置为正常模式之前执行了这些操作。

    此外、我已在通过下面的代码片段配置待机和正常模式之前检查了模式。

    static void checkMode(void)
    {
        uint16_t readMode;
    
        MMD1F_read_register(0x18EU, &readMode);
        // Standby 10b -> 0x0002
        if( readMode & 0x0002U)
        {
            LOGI(&gETHNM_Log_ctx,"Mode is set to standby.");
        }
        else if( readMode & 0x0004U)
        {
            LOGI(&gETHNM_Log_ctx,"Mode is set to normal.");
        }
    }

    检测器设置为正常。 将其配置为待机模式后、可以将其视为待机模式。 它会仔细检查100Base-T1从站配置的情况。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    我希望此软件实施指南将为您提供帮助:

    https://www.ti.com/lit/an/snla404/snla404.pdf?ts = 1691170196909

    此应用手册中的流程图应该可以帮助您进行代码实现。

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经执行了 《软件实施指南》中介绍的步骤、但遗憾的是没有效果。  

    代码片段如下所示:

    // Trials for speed up.
    struct dp83812_init_reg {
    	int	reg;
    	int	val;
    };
    // Init optimization configuration for DP83TC814 which are taken from the linux driver of TI.
    static const struct dp83812_init_reg dp83812_slave_cs2_0_init[] = {
        {0x523, 0x0001}, // Disable link up
        {0x834, 0x0001}, // Configure to slave mode
    	{0x873, 0x0821}, // Configuration to enable shorter linkup time
    	{0x896, 0x22ff}, // Configuration to enable shorter linkup time
    	{0x89E, 0x0000}, // Configuration to enable shorter linkup time
    	{0x523, 0x0000}, // Enable Link up
    };
    
    /**
     * Initialization of TI DP83TC811 BroadR-Reach PHY.
     *
     * @param   mx6q   Pointer to device data structure.
     * @return  Execution status.
     */
    static int mx6q_ti_dp83tc811_phy_init(mx6q_dev_t *mx6q)
    {
        int phy_addr;
        int timeout;
        uint16_t phy_data;
    
        if (mx6q->cfg.verbose > 3) {
            log(LOG_INFO, "%s()...", __FUNCTION__);
            /* Read strap configuration */
            phy_data = mmd_read_reg(mx6q, 0x1F, 0x45D);
            log(LOG_ERR, " CHIP_SOR_1(0x45D) = 0x%X", phy_data);
        }
    
        phy_addr = mx6q->cfg.phy_addr;
        // Go into managed mode.
        mmd_write_reg(mx6q, 0x1F, 0x18B, 0x0000);
    
        // Calculate the size of the array
        size_t sizeOfSlaveConfig = sizeof(dp83812_slave_cs2_0_init) / sizeof(dp83812_slave_cs2_0_init[0]);
        // Write the optimization parameters to the slave config
        for(int i = 0; i < sizeOfSlaveConfig; i++)
        {
            mmd_write_reg(mx6q, 0x1F, dp83812_slave_cs2_0_init[i].reg, dp83812_slave_cs2_0_init[i].val);
            log(LOG_ERR,">>>> WRITING TO 0x%X VAL 0x%X\n", dp83812_slave_cs2_0_init[i].reg, dp83812_slave_cs2_0_init[i].val);
        }
    
        /* Autonomous mode */
        mmd_write_reg(mx6q, 0x1F, 0x18B, 0x0040);
        /* 10ms delay inspired by TI DP83TC81x linux driver */
        nic_delay(10);
        /* Soft reset */
        mx6q_mii_write(mx6q, phy_addr, 0x1F, 0x4000);
    	/* Read BMSR Register 0x0001 – Basic Mode Status Register */
    	phy_data = mx6q_mii_read(mx6q, phy_addr, 0x1);
        if ((phy_data & BMSR_LINK_STATUS) != BMSR_LINK_STATUS) {
            log(LOG_ERR, "%s(): PHY link not established", __FUNCTION__);
            return -1;
        }
        
        return 0;
    
    }

    我已经检查了我从这里下载的 Linux 驱动程序代码。 根据 snla389a、我将这些配置作为从模式配置。 他们彼此都很方便。 完成必要的配置后、我将其设置为自主模式、并在 Phy 的初始化阶段进行软复位。

    想知道这个芯片的载波状态是在变为正常模式后2秒后、即使链路状态被设置为已建立。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alpay、

    我建议对814使用附加的 Linux 驱动程序:
    dp83tc812.c

    您使用的是哪个 xMII 接口? PHY 的 MDI 侧决定链路状态、载波状态(在 SoC 侧)可由 MII 决定。

    由于 PHY 仅支持100Mbps 速率、SoC 的配置可能需要时间? 连接的驱动程序强制将 PHY 的速度设置为100Mbps。

    此致、
    拉胡尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当我尝试将模式切换到主模式时、以太网 PHY 没有发送任何消息。 这是否与 SoC 配置有关? 我以为是这样、但我不太确定。 下面我总结了我所做的全部工作。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请忽略为主从配置编写的注释、我已经解决了该问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Alpay 分享总结、请让我重温一下并更新内容。

    此致、
    拉胡尔