由于我在项目中将该芯片作为PHY和SERDES使用,因此本文内容主要还是围绕PHY和SERDES的相关功能,至于其他功能则没有进行深入研究。


工作模式

在之前的硬件篇中有提到,该芯片有两种寻址模式:单芯片寻址和多芯片寻址。

  • 多芯片寻址
    对于多芯片寻址,需要给芯片设置一个非零的SMI地址(ADDR[4:0]的反码)。在多芯片寻址模式下,仅有两个寄存器(0x00:SMI Command Register 0x01:SMI Data Register)能够使用,内部各PORT的寄存器均由这两个寄存器间接访问。

通过向SMI Command Register的[9:5]写入内部SMI设备地址,[4:0]写入内部SMI寄存器地址来访问各个Port的内部寄存器,[11:10]决定决前是写入还是读出操作。

通过向SMI Data Register的[15:0]位写入或读取SMI Command Register设定的寄存器内容。

  • 单芯片寻址
    对于单芯片寻址,其SMI地址为0x00(针对整个芯片),即ADDR[4:0]=0x1F。

在单芯片寻址模式下,每个Port都有各自的SMI地址(针对内部每个Port),Port0-Port6对应的SMI地址分别为0x10-0x16(直接访问)。
若Port0、1、2、5、6接有外部PHY,则必须使用以下SMI地址,0x00对应Port0,0x01对应Port1,0x02对应Port2,0x05对应Port5,0x06对应Port6,这样PPU才能自动的轮询各个PHY获取各自的连接状况,速度,双工情况,流控状态等信息,这些外部PHY需要使用Global2 offset 0x18、0x19进行访问。对于Port3、Port4的内部PHY地址映射为0x03、0x04;Port0、Port1的内部SERDES映射为0x0C、0x0D,同样的,也是需要使用Global2 offset 0x18、0x19进行访问。

Global2 寄存器的 Offset24,25 寄存器

前文提到,两个非常重要的寄存器,即Global2 offset 0x18、0x19寄存器,在单芯片寻址模式下PHY和SERDES寄存器的访问都必须通过这两个寄存器间接访问。

  • Global2 offset 0x18 (SMI PHY Command Register)寄存器

与多芯片存储能够访问的Command Register寄存器一样,[9:5]写入SMI设备地址,[4:0]写入SMI寄存器地址来访问各个Port的内部寄存器,[11:10]决定当前是写入还是读出操作。

  • Global2 offset 0x19 (SMI PHY Data Register)寄存器

与SMI Data Register相同,通过[15:0]位写入或读取SMI Command Register设定的寄存器内容。

  • PHY读写函数(伪代码)
    对于单纯的PHY器件,如LAN8720A,我们对于PHY寄存器的访问(按照Clauses 22)直接通过SMI接口设置phy地址,和内部寄存器地址就可以访问了。
Preamble(32bits) Start(2bits) OP Code(2bits) PHYAD(5bits) REGAD(5bits) Turn Around(2bits) Data(16bits) Idle
Read 1…1 01 10 A4A3A2A1A0 R4R3R2R1R0 Z0 D15…D0 Z*
Write 1…1 01 01 A4A3A2A1A0 R4R3R2R1R0 Z0 D15…D0 Z*

而这里,对于88E6321的访问就不那么直接了,下面通过伪代码形式讲述如何正确读写内部PHY寄存器:
首先必须实现最直接的SMI读写函数,不同的平台实现方式可能不同,在STM32的HAL库下,提供了

HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)

但是这个函数的PhyAddress是由heth带入的,而我们要频繁在各个Port与Global寄存器间切换,因此改写该库函数,PhyAddress主动传入。

HAL_StatusTypeDef HAL_ETH_WritePHYRegister_New(ETH_HandleTypeDef *heth, uint16_t DevAddr, uint16_t PHYReg, uint32_t *RegValue)
HAL_StatusTypeDef HAL_ETH_ReadPHYRegister_New(ETH_HandleTypeDef *heth, uint16_t DevAddr, uint16_t PHYReg, uint32_t *RegValue)
//具体实现就是把原来heth传入的地址替换为DevAddr

有了最基础读写的函数,我们来构建内部PHY读写函数:

/*!* \fn write_smi_phy_reg* \brief PHY寄存器设置*          * \param [in] ETH_HandleTypeDef *heth STM32以太网结构体定义* \param [in] uint16_t dev_addr PHY地址,单芯片寻址模式下为0x03或0x04* \param [in] uint16_t reg_addr 寄存器地址* \param [in] uint32_t reg_value 写入值* * \retval error_code_t  */
error_code_t write_smi_phy_reg(ETH_HandleTypeDef *heth, uint16_t dev_addr, uint16_t reg_addr, uint32_t reg_value)
{volatile uint16_t time_out;uint32_t smi_reg;time_out = 100;/*!*  检测当前PHY是否Busy*/do {if (HAL_ETH_ReadPHYRegister_New(heth, GLOBAL2_DEV_ADDR(0x1C), SMI_PHY_CMD_REG(0x18), &smi_reg) != ok) {ERROR_MSG("Read SMI_PHY_CMD_REG register failed");return error;}if (time_out-- < 1) {ERROR_MSG("Read SMI_PHY_CMD_REG register timed out");return error;}} while (smi_reg & SMI_BUSY(0x8000));/*!*  先将需要写入的数据写入SMI_PHY_DATA_REG,待后续写命令时完成传输*/if (HAL_ETH_WritePHYRegister_New(heth, GLOBAL2_DEV_ADDR, SMI_PHY_DATA_REG, reg_value) != ok) {return error;}smi_reg = SMI_BUSY | (dev_addr << 5) | (SMI_WRITE(0x01) << 10) | (reg_addr << 0) | (SMI_CLAUSE22 << 12);//!< 设置需要写入的命令(写命令、smi地址、phy寄存器地址、条款) By: Ouqichen 2019年2月11日/*!*  写入命令*/if (HAL_ETH_WritePHYRegister_New(heth, GLOBAL2_DEV_ADDR, SMI_PHY_CMD_REG, smi_reg) != ok) {ERROR_MSG("Write PHY_QD_REG_SMI_PHY_CMD Register Failed");return error;}return ok;
}/*!* \fn read_smi_phy_reg* \brief PHY寄存器读取*          * \param [in] ETH_HandleTypeDef *heth STM32以太网结构体定义* \param [in] uint16_t dev_addr PHY地址,单芯片寻址模式下为0x03或0x04* \param [in] uint16_t reg_addr 寄存器地址* \param [out] uint32_t *reg_value 读出值* * \retval error_code_t */
error_code_t read_smi_phy_reg(ETH_HandleTypeDef *heth, uint16_t dev_addr, uint16_t reg_addr, uint32_t reg_value)
{volatile uint16_t time_out;uint32_t smi_reg;time_out =100;/*!*  检测当前PHY是否Busy*/do {if (HAL_ETH_ReadPHYRegister_New(heth, GLOBAL2_DEV_ADDR(0x1C), SMI_PHY_CMD_REG(0x18), &smi_reg) != ok) {ERROR_MSG("Read SMI_PHY_CMD_REG register failed");return error;}if (time_out-- < 1) {ERROR_MSG("Read SMI_PHY_CMD_REG register timed out");return error;}} while (smi_reg & SMI_BUSY(0x8000));smi_reg = SMI_BUSY | (dev_addr << 5) | (SMI_READ_22(0x02) << 10) | (reg_addr << 0) | (SMI_CLAUSE22 << 12);//!< 设置需要写入的命令(读命令、smi地址、phy寄存器地址、条款) By: Ouqichen 2019年2月11日/*!*  写入命令*/if (HAL_ETH_WritePHYRegister_New(heth, GLOBAL2_DEV_ADDR, SMI_PHY_CMD_REG, smi_reg) != ok) {ERROR_MSG("Write PHY_QD_REG_SMI_PHY_CMD Register Failed");return error;}time_out =100;/*!*  检测当前PHY是否Busy*/do {if (HAL_ETH_ReadPHYRegister_New(heth, GLOBAL2_DEV_ADDR(0x1C), SMI_PHY_CMD_REG(0x18), &smi_reg) != ok) {ERROR_MSG("Read SMI_PHY_CMD_REG register failed");return error;}if (time_out-- < 1) {ERROR_MSG("Read SMI_PHY_CMD_REG register timed out");return error;}} while (smi_reg & SMI_BUSY(0x8000));/*!*  待总线不忙碌时读取数据*/if (HAL_ETH_WritePHYRegister_New(heth, GLOBAL2_DEV_ADDR, SMI_PHY_DATA_REG, reg_value) != ok) {return error;}*reg_value = smi_reg;return ok;
}

从以上伪代码可以看出:写入PHY时,先写入数据,在写入命令。读取PHY时,先写入命令,等待数据准备完成,再读取数据

PHY寄存器

实现了PHY的读写函数后,再来看看有那些寄存器可以访问。
IEEE中只为PHY定义了32个寄存器地址,为了拓展寄存器地址,这里采用的页机制,其中寄存器22的[7:0]用于切换页。

这里介绍几个主要的寄存器:

  • Page 0, Register 0 Copper Control Register
    寄存器0是PHY控制寄存器,通过Control Register可以对PHY的主要工作状态进行设置,具体内容可以查询datasheet,下面介绍主要的功能:
    bit15 Copper Reset: 软复位功能,对其写“1”触发软复位,并在复位结束后自动清为“0”,在某些操作(如修改自协商模式)后需要软复位才能使其生效。
    bit14 Loopback: lookback测试功能,用于开发调试,写一使能该功能。
    bit12 Auto-Negotiation Enable: 自动协商使能位,软件复位后生效,具体的Auto-Negotiation选项设置,在Copper Auto-Negotiation Advertisement Register (Page 0, Register 4)配置。

  • Page 0, Register 1 Copper Status Register
    寄存器1是PHY状态寄存器,主要包含PHY的状态信息,如速率、双工情况、自协商是否完成、自协商能力等。
    bit5 Copper Auto-Negotiation Complete: 自动协商完成位,此时PHY的其他寄存器才是可靠的。
    bit2 Copper Link Status: Link状态指示位Link状态指示位,PHY Polling通过轮询该位来确定Link状态,该位只在Auto-Negotiation Complete完成后才可靠。
    FBI WARINIG下,这里的链路状态每次读取会得到上一次的链路状态,也就是这里的链路状态是滞后的,因此,想要获得最新状态,建议连续读取两次,或者直接读取寄存器17的bit10,获取实时状态。)

  • Page 0, Register 4 Copper Auto-Negotiation Advertisement Register
    寄存器4是指示自动协商所支持的能力的寄存器,在AN enable的情况下,该端口会使用快速连接脉冲(Fast Link Pulse FLP)与对端交互端口自协商能力,协商完成后,会选择双方均支持的能力建立连接。
    bit9-bit5 分别指示能够支持的能力。

  • Page 0, Register 5 Copper Link Partner Ability Register
    寄存器5用于指示自动协商后,对端的所支持的自协商能力,该寄存器在调试时非常有用,能够表明,链路上是否有数据交互。

  • Page 0, Register 9 1000BASE-T Control Register
    寄存器9用于设置1000BASE-T的主从配置与自协商能力。需要注意的是,1000BASE-X的自协商除了双工和流控信息之外,并不能协商速率信息,也就是说端口只能工作在1000M模式下。

  • Page 0, Register 10 1000BASE-T Status Register
    寄存器10主要用于保存自协商完成后的对端所支持的自协商能力。

  • Page 0, Register 16 Copper Specific Control Register 1
    寄存器16主要是寄存器0的拓展。
    bit10 强制设置网络已经连接功能 在我们进行lookback测试,而网线又不能接入时,可以强制使寄存器link up,而方便测试进行。
    bit6:5 MDI交差模式,一般来说设置为11b,PHY根据FLP信号自动切换为MDI或者MDIX,因此该功能需要自协商功能的支持。

  • Page 0, Register 17 Copper Specific Status Register 1
    寄存器17是主要是寄存器1的拓展,在这个寄存器中,我们可以获取到当前的连接状态,当前MDI Crossover的模式等。

  • Page 0, Register 18 Copper Specific Interrupt Enable Register
    寄存器18,顾名思义,就是中断使能寄存器。初始化时配置了相关中断使能后,一旦中断发生,INT0引脚则会拉低,此时MCU通过读取Register 19,则可以确定发生了什么中断。

  • Page 0, Register 19 Copper Interrupt Status Register
    寄存器19为中断状态寄存器,读取该寄存器将清除中断。

  • Page ANY, Register 22 Page Address
    bit7:0 页选择寄存器 用于在各个寄存器中进行页切换。

了解了以上主要寄存器,下面来实现具备页切换的PHY读写函数:

/*!* \fn read_smi_page_phy_reg* \brief 带页切换的PHY寄存器读取*          * \param [in] ETH_HandleTypeDef *heth STM32以太网结构体定义* \param [in] uint16_t port_num 端口号* \param [in] uint8_t page_num 页号码* \param [in] uint16_t reg_addr 寄存器地址* \param [out] uint32_t *reg_value 读出值* * \retval error_code_t */
error_code_t read_smi_page_phy_reg(ETH_HandleTypeDef *heth, uint8_t port_num, uint8_t page_num, uint16_t reg_addr, uint32_t *reg_value)
{error_code_t ret_value;ret_value = write_smi_phy_reg(heth, (uint16_t)port_num, SMI_PHY_PAGE_ANY_REG(0x16), (uint32_t)page_num);if (ret_value != ok)return ret_value;ret_value = read_smi_phy_reg(heth, (uint16_t)port_num, reg_addr, reg_value);return ret_value;
}/*!* \fn write_smi_phy_reg* \brief PHY寄存器设置*          * \param [in] ETH_HandleTypeDef *heth STM32以太网结构体定义* \param [in] uint16_t port_num 端口号* \param [in] uint8_t page_num 页号码* \param [in] uint16_t reg_addr 寄存器地址* \param [in] uint32_t reg_value 写入值* * \retval error_code_t  */
error_code_t read_smi_page_phy_reg(ETH_HandleTypeDef *heth, uint8_t port_num, uint8_t page_num, uint16_t reg_addr, uint32_t reg_value)
{error_code_t ret_value;ret_value = write_smi_phy_reg(heth, (uint16_t)port_num,SMI_PHY_PAGE_ANY_REG(0x16), (uint32_t)page_num);if (ret_value != ok)return ret_value;ret_value = write_smi_phy_reg(heth, (uint16_t)port_num, reg_addr, reg_value);return ret_value;
}

中断相关寄存器

88E632x包含了一个中断控制器,将各种中断统一合并到一个引脚INTn上。全局寄存器1 offset 0x04中包含了各种中断源的总开关,为了能够使用设备相关中断,我们需要将bit7 DevIntEn置为1 。

接着,还需要设置中断掩码(Global2 Offset1),确保PHY相关中断使能。

最后还需要设置PHY寄存器(0x12),使能具体使用哪些中断。

完成以上操作后,一旦相关中断发生,这会拉低88E632x的INTn引脚,MCU则可以通过下降沿触发中断,对芯片具体发生什么中断进行判断与处理。
需要注意的是,在中断发生后,如果没有对该中断进行处理,则该INTn引脚会一直处于低电平,这样就无法再次捕获相关中断了,因此,中断发生后应及时清除中断,清除中断需要读取2个寄存器,Global1 Offset 0 Switch Global Status Register 寄存器和PHY 19 Copper Interrupt Status Register寄存器。

SERDES寄存器

SERDES寄存器的配置与PHY基本相同,这里不再赘述,不过需要注意的是,光纤相关的自协商只能协商双工和流控等信息,而速率则是固定的,因此协商前需要确定通信速率。
在switch芯片的Px_SMODE可以决定是千兆还是百兆光纤。

通过读取 Fiber Specific Control Register 1的bit1:0可以知道其当前工作模式。

Marvell交换芯片88E6321/88E6320驱动总结-寄存器篇相关推荐

  1. Marvell交换芯片88E6321/88E6320驱动总结-硬件篇

    芯片特性 Marvell 88E6321/88E6320 是一个7-Port千兆以太网交换芯片.支持最新的IEEEE802.1 Audio Video Bridging标准. 芯片包含两个10.100 ...

  2. Marvell交换芯片88E6390驱动开发

    作者 QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 https://space.bilibili.com/208826118 参考 Marvell交换芯片8 ...

  3. Marvell 交换芯片DSA(分布式交换架构)功能介绍

    Marvell DSA(分布式交换架构)by 韩大卫@吉林师范大学*************** 请参见 Marvell Prestera/Cheetah/xcat/lion 系列交换芯片手册获取更详 ...

  4. 5-->详解《switch 数据接收驱动框架、mtk7621集成交换芯片mt7530》之一

    一. MTK7621 网络通讯原理简述 本篇博文分析的是mtk7621的芯片所内嵌的交换芯片mt7530的驱动程序,MTK7621采用内部的 MDIO 接口管理MT7530 的 switch 芯片:M ...

  5. Marvell宣战博通网络交换芯片,一大波饿狼扑食而来

    origin: http://www.esmchina.com/news/article/201704051517 一大批饿狼扑食而来,基础芯片领域--网络交换芯片江湖将掀起血雨腥风. 此前,网络交换 ...

  6. 6 -->详解《switch 数据接收驱动框架、mtk7621集成交换芯片mt7530》之二

    一. MTK7621 网络通讯原理简述 本篇博文分析的是mtk7621的芯片所内嵌的交换芯片mt7530的驱动程序,MTK7621采用内部的 MDIO 接口管理MT7530 的 switch 芯片:M ...

  7. 基于交换芯片的五元组的PCL规则过滤功能

    2019独角兽企业重金招聘Python工程师标准>>> 基于交换芯片的五元组的PCL规则过滤功能作者: 韩大卫@吉林师范大学2012.12.10Not Approved by Doc ...

  8. Marvell 88E1111PHY芯片简介

    1.PHY芯片简介 PHY芯片在OSI协议栈中属于最底层的物理层,与其它层的关系图如下: 从硬件上来说,一般PHY芯片为模数混合电路,负责接收电.光这类模拟信号,经过解调和A/D转换后通过MII接口将 ...

  9. 基于交换芯片的五元组过滤功能

    基于交换芯片的五元组的PCL规则过滤功能作者: 韩大卫@吉林师范大学2012.12.10Not Approved by Document Control Review Copy Only基于Marve ...

最新文章

  1. C# ASP.Net 设置外网访问
  2. randomaccessfile在移动设备多线程多服务器下载时写入慢的问题
  3. 谈谈对Canal(增量数据订阅与消费)的理解
  4. python爬虫设计_python爬虫设计(刷访问量,赞)
  5. python3环境变量和pip_Tool_linux环境安装python3和pip
  6. python redis模块常用_python redis 模块
  7. 吉林大学超星学习通04
  8. 前端框架bootstrap和可视化布局工具
  9. win10计算机本地组策略编辑器,如何打开Win10本地组策略编辑器?
  10. 机器视觉培训教程-硬件选型
  11. 虚拟机共享文件夹制作|Ubuntu与本机文件共享
  12. 数据中心网络图怎么画?几步教会你
  13. OBLOG4.0+DVBBS7.10 SP1整合
  14. html 按钮变成椭圆,HTML 渐变椭圆按钮
  15. 某云不限速破解详细教程附工具
  16. Spring Security 实战内容:实现自定义退出登录
  17. 祝福老朋友今天的收获
  18. 商城后台系统商品模型(类型)新增接口开发
  19. Unity Shader-遮挡处理(X-Ray,遮挡描边,遮挡半透,遮挡溶解)
  20. Android系统之SettingsProvider(二)

热门文章

  1. 音视频开发学习(三) -- RGB YUV HSV 颜色空间
  2. Panabit 智能应用网关
  3. 下载好python后,怎么打开,python怎么进入编程界面
  4. vue使用videojs播放mu38
  5. 新电脑的正确打开方式——(近万字图文并茂详细分步骤讲解)【万一那天你就有新电脑了呢】包括个性化·等你来解锁哦
  6. 哈理工oj 1073 病毒
  7. 在服务器中如何获取项目名,成都汇智动力-java获得项目路径
  8. 盘点七大接地气的翅片管式换热器设计软件
  9. 问卷调查+需求分析(部分)
  10. 如何在Java中转义HTML