[Example][TC397以太网例程详解] - 13.PHY 初始化
Aurix TriCore TC397 以太网官方例程
关键词
TC397 官方例程;TC397 以太网例程;TC397 GETH;
简介
本篇为 Aurix TriCore TC397 以太网官方例程分析,重点关注其硬件行为
调试所用的开发板型号:KIT-A2G-TC397-5V-TFT
所使用的例程:Ethernet_1_KIT_TC397_TFT
英飞凌 TriCore 官方例程下载地址:
https://github.com/Infineon/AURIX_code_examples
目录
// 函数调用栈
core0_main()
|--> Ifx_Lwip_init()
|--> netif_add()
|--> ifx_netif_init()
|--> low_level_init() // 硬件初始化
|--> IfxGeth_Eth_Phy_Rtl8211f_init()
IfxGeth_Eth_Phy_Rtl8211f_init() 完成 PHY(RTL8211F)的初始化:
// Libraries/Ethernet/lwip/port/src/netif.c
static void low_level_init(netif_t *netif)
{
...
IfxGeth_Eth_Phy_Rtl8211f_init();
MDIO 用于配置 PHY 芯片状态、读取寄存器、PHY 地址、LINK 状态等操作,英飞凌定义了 MDIO 接口的读写函数:
-
IfxGeth_Eth_Phy_Rtl8211f_read_mdio_reg():通过 MDIO 读取对应的寄存器;
-
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg():通过 MDIO 向对应的寄存器写值;
1.MDIO 读写方式
IfxGeth_Eth_Phy_Rtl8211f_read_mdio_reg() 读取 RTL8211F 的 MDIO 寄存器:
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
void IfxGeth_Eth_Phy_Rtl8211f_read_mdio_reg(uint32 layeraddr,
uint32 regaddr,
uint32 *pdata)
{
// 5bit Physical Layer Adddress, 5bit GMII Regnr,
// 4bit csrclock divider, Read, Busy
GETH_MAC_MDIO_ADDRESS.U = (layeraddr << 21) |
(regaddr << 16) |
(0 << 8) |
(3 << 2) |
(1 << 0);
// 等待 MDIO 读写完成,等待 GB == 0
IFXGETH_PHY_RTL8211F_WAIT_MDIO_READY();
|--> while (GETH_MAC_MDIO_ADDRESS.B.GB) {}
// get data,读取数据
*pdata = GETH_MAC_MDIO_DATA.U;
}
其中,layeraddr 为寄存器页地址,regaddr 为寄存器在该寄存器页中的地址
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg() 将数据写入 RTL8211F 的 MDIO 寄存器:
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
void IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(uint32 layeraddr,
uint32 regaddr,
uint32 data)
{
// put data,写入数据
GETH_MAC_MDIO_DATA.U = data;
// 5bit Physical Layer Adddress, 5bit GMII Regnr,
// 4bit csrclock divider, Write, Busy
GETH_MAC_MDIO_ADDRESS.U = (layeraddr << 21) |
(regaddr << 16) |
(0 << 8) |
(1 << 2) |
(1 << 0);
// 等待 MDIO 读写完成,等待 GB == 0
IFXGETH_PHY_RTL8211F_WAIT_MDIO_READY();
|--> while (GETH_MAC_MDIO_ADDRESS.B.GB) {}
}
其中,layeraddr 为寄存器页地址,regaddr 为寄存器在该寄存器页中的地址,相关寄存器位及其值的含义如下:
-
MAC_MDIO_ADDRESS.PA:Physical Layer Address,[25:21],指示当前访问的 PHY 寄存器页地址;
-
MAC_MDIO_ADDRESS.RDA:Register/Device Address,[20:16],指示当前访问的 PHY 寄存器在该寄存器页中的地址;
-
MAC_MDIO_ADDRESS.CR:CSR Clock Range,[11:8],MDC 的时钟频率;
-
MAC_MDIO_ADDRESS.GOC_0:GMII Operation Command 0,[2],操作码的低位;
-
MAC_MDIO_ADDRESS.GOC_1:GMII Operation Command 1,[3],操作码的高位;
-
GOC_0 和 GOC_1 共同组成操作码,其含义如下:
-
00:未使用;
-
01:表示当前执行写入操作;
-
10:当前操作的是 Clause 45 使用的预读取增量地址;
-
11:表示当前执行读取操作;
-
-
MAC_MDIO_ADDRESS.GB:GMII Busy,[0],占用当前 MDIO,当读写操作完成后自动将其置 "0";
-
MAC_MDIO_DATA.GD:GMII Data,[15:0],PHY 寄存器的内容(RTL8211F 的寄存器为 16-bit);
2.初始化流程
IfxGeth_Eth_Phy_Rtl8211f_init() 通过向 RTL8211F 的 MDIO 写入控制信息,控制 PHY 完成初始化
2.1.复位 RTL8211F
发送 RTL8211F 复位请求的流程如下:
-
读取 MAC_MDIO_ADDRESS.GB,其值为 "1" 表示 MDIO 被占用(正在读写),等待占用解除(读写完成),数据传输完成后,硬件会自动将该位置 "0",表示解除占用;
-
通过 MDIO 操作 RTL8211F 的 BMCR(Basic Mode Control Register) 寄存器,地址为 0x0000,写入值为 0x8000,即 MAC_MDIO_DATA.GD = 0x8000(BMCR 寄存器第 15 位置 "1"),BMCR 的 bit-15 为复位请求,写 "1" 将触发 RTL8211F 的复位操作;
-
RTL8211F 复位完成后,自动将 BMCR 的 bit-15 设置为 "0",读取 BMCR 寄存器,等待 RTL8211F 复位完成;
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
uint32 IfxGeth_Eth_Phy_Rtl8211f_init(void)
{
// 等待 MDIO 解除占用
IFXGETH_PHY_RTL8211F_WAIT_MDIO_READY();
|--> while (GETH_MAC_MDIO_ADDRESS.B.GB) {}
// reset PHY
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_BMCR, 0x8000);
uint32 value;
do
{ // 等待 PHY 复位完成
IfxGeth_Eth_Phy_Rtl8211f_read_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_BMCR, &value);
} while (value & 0x8000); // wait for reset to finish
2.2.PHY 设置
IFXGETH_PHY_RTL8211F_MDIO_PAGSR 为 RTL8211F 的 PAGSR 寄存器地址(0x1F),该寄存器用于切换寄存器页,写入值为 0xD08,即切换至 MIICR (MII Control Register) 寄存器所在页,然后在该页内,读取地址为 0x11 的寄存器,使能发送延迟,然后将值写回 0x11 地址的寄存器:
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
uint32 IfxGeth_Eth_Phy_Rtl8211f_init(void)
{
...
// ---------------------------------------------------------
// setup PHY
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_PAGSR, 0xd08);
IfxGeth_Eth_Phy_Rtl8211f_read_mdio_reg(0, 0x11, &value);
// ---------------------------------------------------------
// ---------------------------------------------------------
value |= 0x100; // enable TX-delay
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, 0x11, value);
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_PAGSR, 0x0);
// ---------------------------------------------------------
注意:目前尚不明确 0xD08 寄存器页中,地址为 0x11 的寄存器的具体含义
2.3.LED 设置
设置网口的 LED 指示灯:
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
uint32 IfxGeth_Eth_Phy_Rtl8211f_init(void)
{
...
// ---------------------------------------------------------
/* Set LEDs */
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_PAGSR, 0xd04);
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_LCR, 0x8170);
// ---------------------------------------------------------
// ---------------------------------------------------------
// EEE off for all leds
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_EEELCR, 0x0);
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_PAGSR, 0x0);
// ---------------------------------------------------------
向 RTL8211F 的 PAGSR 寄存器写入 0xD04,将寄存器页切换至 0xD04,RTL8211F 的 LCR 与 EEELCR 两个寄存器均位于该寄存器页中,LCR 寄存器写入 0x8170,EEELCR 寄存器写入 0x0
LCR 寄存器位的定义如下:

EEELCR 寄存器位的定义如下:

2.4.使能/重启自动协商
向 RTL8211F 的 BMCR 寄存器写入 0x1200,涉及以下位:
-
ANE:Auto-Negotiation Enable,置 "1" 使能自动协商;
-
Restart_AN:Restart Auto-Negotiation,置 "1" 重启自动协商;
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
uint32 IfxGeth_Eth_Phy_Rtl8211f_init(void)
{
...
// enable auto-negotiation, restart auto-negotiation
IfxGeth_Eth_Phy_Rtl8211f_write_mdio_reg(0, IFXGETH_PHY_RTL8211F_MDIO_BMCR, 0x1200);
最后,标记 RTL8211F 初始化完成(IfxGeth_Eth_Phy_Rtl8211f_iPhyInitDone = 1)
// Libraries/Ethernet/Phy_Rtl8211f/IfxGeth_Phy_Rtl8211f.c
uint32 IfxGeth_Eth_Phy_Rtl8211f_init(void)
{
...
// done
IfxGeth_Eth_Phy_Rtl8211f_iPhyInitDone = 1;
return 1;
}
更多推荐



所有评论(0)