0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

以太网PHY寄存器分析 以太网PHY驱动软件配置

瑞萨MCU小百科 来源:瑞萨嵌入式小百科 2024-02-22 12:17 次阅读

我们对g_ethercat_ssc_port0_ext_cfg这个全局变量深入追踪,其成员变量 g_ether_PHY0,正好是一个PHY实例的详细描述体。

/* Instance structure to use this module. */
const ether_PHY_instance_t g_ether_PHY0 =
{
  .p_ctrl    = &g_ether_PHY0_ctrl,
  .p_cfg     = &g_ether_PHY0_cfg,
  .p_api     = &g_ether_PHY_on_ether_PHY
};

其中g_ether_PHY0_cfg是pyh实例的配置结构体:

const ether_PHY_cfg_t g_ether_PHY0_cfg =
{


  .channel          = 0,
  .PHY_lsi_address      = 0,
  .PHY_reset_wait_time    = 0x00020000,
  .mii_bit_access_wait_time = 0,             // Unused
  .flow_control       = ETHER_PHY_FLOW_CONTROL_DISABLE,
  .mii_type         = (ether_PHY_mii_type_t) 0, // Unused
  .p_context         = NULL,
  .p_extend         = &g_ether_PHY0_extend
};

这里又通过p_extend 做了扩展配置(其实可以合并在一起)如下所示:

const ether_PHY_extend_cfg_t g_ether_PHY0_extend =
{
  .port_type     = ETHER_PHY_PORT_TYPE_ETHER_CAT,
  .PHY_chip      = (ether_PHY_chip_t) ETHER_PHY_CHIP_VSC8541,
  .mdio_type     = ETHER_PHY_MDIO_GMAC,


  .bps        = ETHER_PHY_SPEED_100,
  .duplex       = ETHER_PHY_DUPLEX_FULL,
  .auto_negotiation  = ETHER_PHY_AUTO_NEGOTIATION_ON,


  .PHY_reset_pin   = BSP_IO_PORT_20_PIN_7,
  .PHY_reset_time   = 15000,


  .p_selector_instance = (ether_selector_instance_t *)&g_ether_selector0,
};

可以看到上面的扩展配置当中,PHY的具体硬件型号都已经列出,如PHY_chip = (ether_PHY_chip_t) ETHER_PHY_CHIP_;

可以看到在示例代码当中已经支持的PHY如下所示:

/** Identify PHY-LSI */
typedef enum e_ether_PHY_chip
{
  ETHER_PHY_CHIP_VSC8541 = (1 << 0), ///< VSC8541
    ETHER_PHY_CHIP_KSZ9131 = (1 << 1), ///< KSZ9131
    ETHER_PHY_CHIP_KSZ9031 = (1 << 2), ///< KSZ9031
    ETHER_PHY_CHIP_KSZ8081 = (1 << 3), ///< KSZ8081
    ETHER_PHY_CHIP_KSZ8041 = (1 << 4)  ///< KSZ8041
} ether_PHY_chip_t;

这里具体看一下 g_ether_selector0 这个 ether_selector_instance_t 类型的全局指针,指向 selector driver实例的成员变量:

typedef struct st_ether_selector_instance
{
  ether_selector_ctrl_t   * p_ctrl; ///< Pointer to the control structure for this instance
    ether_selector_cfg_t const * p_cfg;  ///< Pointer to the configuration structure for this instance
    ether_selector_api_t const * p_api;  ///< Pointer to the API structure for this instance
} ether_selector_instance_t;

这又是一个类似的结构体,通过三个指针来分别指向结构本身,selector的具体配置,和配置selector过程中所需要用的的成员方法api.

看一下selector的具体配置信息

typedef struct st_ether_selector_cfg
{
  uint8_t port;               ///< Port number
    ether_selector_PHYlink_polarity_t PHYlink; ///< PHY link signal polarity


    ether_selector_interface_t interface;      ///< Converter mode
    ether_selector_speed_t     speed;          ///< Converter Speed
    ether_selector_duplex_t    duplex;         ///< Converter Duplex
    ether_selector_ref_clock_t ref_clock;      ///< Converter REF_CLK
    void const               * p_extend;       ///< Placeholder for user extension.
} ether_selector_cfg_t;

可以看到selector 对应的端口号,PHY连接信号对应的极性,接口模式,速率,全双工,以及外部时钟输入。再看一下配置selector的过程中所需要用到的API函数:

const ether_selector_api_t g_ether_selector_on_ether_selector =
{
  .open     = R_ETHER_SELECTOR_Open,
  .converterSet = R_ETHER_SELECTOR_ConverterSet,
  .close    = R_ETHER_SELECTOR_Close,
  .versionGet  = R_ETHER_SELECTOR_VersionGet
};

其最主要的成员方法就是R_ETHER_SELECTOR_Open做了些什么:

先初始化ETHER_SELECTOR

 /* One time initialization for all ETHER_SELECTOR instances. */
  r_ether_selector_state_initialize();


  /* Unlock write access protection for Ethernet subsystem registers */
  r_ether_selector_reg_protection_disable(p_reg_ethss);
  
  /* Set the function of Ethernet ports. */
  sw_mode = ETHER_SELECTOR_CFG_MODE;
  p_reg_ethss->MODCTRL_b.SW_MODE = sw_mode & ETHER_SELECTOR_MODCTRL_BIT_SWMODE_MASK;
  
  /* Set the MAC of all port for half-duplex. */
  p_reg_ethss->SWDUPC_b.PHY_DUPLEX = 0;
  
  /* Set all Ethernet switch port to select not use 10Mbps. */
  p_reg_ethss->SWCTRL_b.SET10 = 0;

根据端口号来选择对应控制寄存器

/* Set RGMII/RMII Converter configuration */
  switch (port)
  {
    case 0:
    {
      p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[0];
      break;
    }


    case 1:
    {
      p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[1];
      break;
    }


    case 2:
    default:
    {
      p_reg_convctrl = (uint32_t *) &p_reg_ethss->CONVCTRL[2];
      break;
    }
  }

根据指向selector的配置信息:

const ether_selector_cfg_t g_ether_selector0_cfg =
{
  .port           = 0,
  .PHYlink          = ETHER_SELECTOR_PHYLINK_POLARITY_LOW,
  .interface         = ETHER_SELECTOR_INTERFACE_RGMII,
  .speed           = ETHER_SELECTOR_SPEED_100MBPS,
  .duplex          = ETHER_SELECTOR_DUPLEX_FULL,
  .ref_clock         = ETHER_SELECTOR_REF_CLOCK_INPUT,
  .p_extend         = NULL,
};

来对CONVCTRL[port_number]寄存器做相应的配置

2eb4a366-d138-11ee-a297-92fbcf53809c.png

这里结合RZ/T2M的用户手册,很容易理解其中的意思:

2ec2147e-d138-11ee-a297-92fbcf53809c.png

结合代码来看,总体ETHER_SELECTOR 的驱动的配置流程图台下所示:

2edfe864-d138-11ee-a297-92fbcf53809c.png

在对ETHER_SELECTOR驱动做完配置后,下面具体看一下对ETHER_PHY_CHIP这个PHY,代码具体做了哪些操作:

首先是做初始化:

2ef2df46-d138-11ee-a297-92fbcf53809c.png

oid ether_PHY_targets_initialize_vsc8541 (ether_PHY_instance_ctrl_t * p_instance_ctrl)
{
  /* Vendor Specific PHY Registers */
 #define ETHER_PHY_REG_LED_MODE_SELECT         (0x1D)
 #define ETHER_PHY_REG_LED_BEHAVIOR          (0x1E)
 #define ETHER_PHY_REG_EXTEND_GPIO_PAGE        (0x1F)
...

这个初始化函数,并没有对IEEE 标准规定的16个寄存器做读写操作,只对厂商自定义的寄存器做了配置。初始化完成之后,对是否打开自动协商的功能对PHY进行了读写:

2efeb3d4-d138-11ee-a297-92fbcf53809c.png

2f107bb4-d138-11ee-a297-92fbcf53809c.png

这里可以看到对PHY芯生来说,需要配置的寄存器并不是很多,大多数情况下,把自动协商寄存器配置好,就可以了。除此之后就是厂商自定义的寄存器的一些自定义的功能。这部分功能需要结合用户手册来理解和使用,大部分也是用来调试和指示的作用以及一些IEEE基本标准之外的特色功能,比如节能标准之类的。

对于用户说来,搞清楚数据结构之间的关联,剩下的就是驱动代码的执行逻辑,考虑到执行逻辑并不复杂,这里不展开来说。用户可以参考录屏材料进一步深入了解。

其它

经过验证的PHY芯片列表:

2f2436d6-d138-11ee-a297-92fbcf53809c.jpg






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 以太网
    +关注

    关注

    40

    文章

    5076

    浏览量

    166234
  • 寄存器
    +关注

    关注

    30

    文章

    5028

    浏览量

    117719
  • PHY
    PHY
    +关注

    关注

    2

    文章

    264

    浏览量

    51005

原文标题:工业以太网PHY驱动适配参考文档(完结篇)

文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    使用STM32H743做以太网,如何检测以太网是否掉线?

    目前使用STM32H743做以太网,目前我这里检测以太网掉线(物理线缆脱掉)的方式为读取PHY自动协商的状态,但是这个部分放在主循环中感觉很不好,之前使用的TI芯片,会有一个寄存器的B
    发表于 03-26 07:42

    1- 什么是以太网PHY

    以太网总线/接口技术
    EE_Voky
    发布于 :2022年09月15日 13:59:14

    以太网PHY码型变换问题

    求助以太网PHY 双极性归零码和单极性不归零码双向变换的方案,,,(10M)
    发表于 03-06 10:03

    以太网PHY怎么改变现代市场

    笔者在上一篇博客文章(《以太网PHY奥妙无穷,三件事您应了如指掌》)中谈论了以太网的演变及以太网物理层收发
    发表于 09-07 11:49

    STM32F407能不能同时使用USB PHY以太网PHY

    【求助】STM32F407能不能同时使用USB HPY和以太网HPY现在需要使用高速USB模拟一个USB设备和进行传输文件高速以太网接口,STM32F407能不能同时使用两个PHY
    发表于 11-21 10:42

    以太网控制外部PHY芯片模拟程序代码实现

    模拟程序模拟了简化的 LXT971A 芯片(Inter 公司的外部 PHY 芯片)。PHY 芯片通过 MIIM(媒体无关接口管理模块)来连接以太网控制,因此:• 当
    发表于 01-18 14:20

    以太网MAC芯片与PHY芯片的关系是什么

    如何实现单片以太网微控制以太网MAC是什么?什么是MII?以太网PHY是什么?网卡上除RJ-45接口外,还需要其它元件吗?造成
    发表于 12-28 06:22

    以太网芯片MAC和PHY的关系 精选资料分享

    问:如何实现单片以太网微控制?答:诀窍是将微控制以太网媒体接入控制(MAC)和物理接口收发
    发表于 07-29 09:22

    STM32F105/107系列以太网PHY设计

    STM32F105/107系列以太网PHY设计资料。图说的很详细,废话就不说了,自己看图吧。Technorati 标签: STM32F107,STM32F105,以太网,PHY
    发表于 08-05 06:55

    请问如何更换以太网PHY芯片?

    购买了OKMX6UL-C开发板,使用的以太网PHY芯片是KSZ8081RNB,使用RMII接口和ARM通信。我们做了另一个底板,仍然使用了KSZ8081,但是它非常难以手工焊接,想问一下,如果换成
    发表于 01-11 07:31

    如何对以太网PHY芯片的rmii pin脚进行配置

    如何对以太网PHY芯片的时钟进行配置?如何对以太网PHY芯片的gmac进行配置?如何对
    发表于 02-21 06:54

    RK3288搭配以太网PHY芯片需要注意哪些

    (1)以太网PHY芯片驱动及接口瑞芯微在设计RK 系列主控芯片时,有内置以太网MAC 控制,通常只需要搭配一颗
    发表于 08-31 17:15

    以太网PHY如何改变现代市场

    在本文里,笔者将重拾上次中断的话题,探讨以太网PHY在如何改变现代市场。 以太网是40多年前发明的。现在让我们快进跳过对IEEE 802.3(10Mbps以太网
    发表于 11-18 07:44

    什么是以太网

    分项规定和规范。由IEEE 802.3规定的一个最重要的部分就是以太网物理层晶体管(PHY)。 图1展示了数据如何传输到标准RJ45以太网线缆以及如何从该线缆传输到处理的范例性方框图
    发表于 11-18 06:56

    使用不同的以太网PHY,MDC信号的问题求解

    我们正忙于开发基于 LS1028A 处理以太网 PHY VSC8514XMK-03 的产品。我们在初始化以太网 PHY 时遇到问题。在文
    发表于 03-23 07:19