CH32V307 内置 10 M PHY 自动协商

    你好,这边移植 TCP/IP 协议栈时,发现一个问题,在网线一直插入的情况下,通过 BMCR 重启自动协商后,功能异常。


    手动启动协商后,ALPAR 以及 PHYSR 不能正确指示工作状态(通过对端网管交换机可以看到链路工作状态,但是与 ALPAR 以及 PHYSR 指示的状态不匹配),测试外置 PHY 没有该问题,请教该如何处理


注一:网线未插拔,手动启动协商状态异常

注二:手动启动协商时,如果手动插拔一下网线,ALPAR 及 PHYSR 正常,但再次手动启动协商时异常

注三:PHY 状态管理使用定期轮询方式,未使用 PHYLINK 中断

注四:现在我的解决方案是 HOOK 了 ETH_WritePHYRegister() 这个函数,当检测到 BMCR 写入自动协商命令时,强制关闭 10M PHY 时钟并等待一段时间以后,再次开启该时钟,也就是实际上不执行手动自动协商命令,短暂测试方案可行,不知道有没有隐患。


测试代码如图:

    for ( ;; ) {
      printf ("PHY:\r\n");
      uint16_t BMCR  = ETH_ReadPHYRegister (1, 0x00);
      uint16_t BMSR  = ETH_ReadPHYRegister (1, 0x01);
      uint16_t ALPAR = ETH_ReadPHYRegister (1, 0x05);
      uint16_t PHYSR = ETH_ReadPHYRegister (1, 0x10);
      uint16_t MDIX  = ETH_ReadPHYRegister (1, 0x1E);

      printf (" BMCR: %04X\r\n", BMCR);
      printf (" BMSR: %04X\r\n", BMSR);
      printf ("ALPAR: %04X\r\n", ALPAR);
      printf ("PHYSR: %04X\r\n", PHYSR);
      printf (" MDIX: %04X\r\n", MDIX);

      vTaskDelay (1000);

      printf ("Restart Auto-Negotiation\r\n");
      ETH_WritePHYRegister (1, 0x00, BMCR | 0x0200);

      vTaskDelay (5000);
      BMCR  = ETH_ReadPHYRegister (1, 0x00);
      BMSR  = ETH_ReadPHYRegister (1, 0x01);
      ALPAR = ETH_ReadPHYRegister (1, 0x05);
      PHYSR = ETH_ReadPHYRegister (1, 0x10);
      MDIX  = ETH_ReadPHYRegister (1, 0x1E);

      printf (" BMCR: %04X\r\n", BMCR);
      printf (" BMSR: %04X\r\n", BMSR);
      printf ("ALPAR: %04X\r\n", ALPAR);
      printf ("PHYSR: %04X\r\n", PHYSR);
      printf (" MDIX: %04X\r\n", MDIX);
    }

测试结果如图


启动协商过程中插拔一次网线

1716946755191595.png


启动协商过程中,保持网线一直有效连接

1716946755649699.png


您好,您的处理方式是没有什么问题的,主要问题在于对端有概率把我们发的协商包当作数据包,导致对端不会发协商包,此时307也不会获取到对端的协商能力,因此ANLPAR为0,如有其他问题可邮箱沟通(zl@wch.cn)。


好的


只有登录才能回复,可以选择微信账号登录