原创 为AM335x移植Linux内核主线代码(21)Ethernet段落篇

2015-1-14 09:30 4974 13 17 分类: MCU/ 嵌入式 文集: Linux Kernel的DTS

由于千兆PHY芯片AR8031的调试难度较大,RJ45变压器HR911130C比较贵,而且实验室并没有千兆设备,因此Ethernet功能测试板采用了RTL8201BL和HR911105A。

绘制好的测试板如图所示:

rtl8201_sch.jpg

 

rtl82021_brd.jpg


(Note:RTL8201的封装应该更大一些,另外NC的电阻要少一些,用跳线代替更漂亮一些;RJ45上面要接终端电阻,中间抽头要增加接地的电容。)
焊接好之后上电,发现路由器连上它的LED灯,闪烁状态和连上PC机一样,It's a good sign.

=============================================
第一步要弄清楚,RTL8201BL和AM335x应该怎么连线:

http://en.wikipedia.org/wiki/Media_Independent_Interface
Standard MII总共使用了15根线,外加2根MDIO线,如果要扩展PHY芯片,这些线除了其中两根(应该是TXCLK和RXCLK)以外都是不可共用的;而Reduce Media Independent Interface则用来解决这个问题。TXCLK和RXCLK的时钟频率在100Mbit/s时为25MHz,在10Mbit/s时为2.5MHz。

对于RMII来说,它将TXCLK和RXCLK合并,便于使用switch来共享;时钟频率由25MHz变成50MHz,而数据线减半;RXDV和CRS也合并;移除了COL信号。RMII没有信号能够定义full or half,因此需要MDIO来做这个工作(This must instead be communicated over the serial MDIO/MDC interface, but the standard does not specify a standard MDIO register bit for the duplex mode. This means that custom software is required for every PHY.);RMII也没有信号定义10 or 100 mode,这也需要通过MDIO来实现。

Gigabit Media Independent Interface,它的速度可以达到1000Mbit/s,时钟频率为125MHz,并且和MII兼容。GMII需要的信号有:GTXCLK、TXCLK、TXD[7:0]、TXEN、TXER、RXCLK、RXD[7:0]、RXDV、RXER、COL、CS,以及两根MDIO信号线。

Reduced Gigabit Media Independent Interface,它减少了一半的数据线,但并不是将时钟倍频,而是采用在上升和下降沿都采样的方法。它使用的信号有:RX_CTL、RXC、RXD[3:0]、TX_CTL、TXC、TXD[3:0],共12根线。跟GMII不一样的是,TXCLK一直都会被使用,且由MAC提供。由于Source-synchronous时钟(Source-Synchronous clocking refers to a technique used for timing symbols on a digital interface. Specifically, it refers to the technique of having the transmitting device send a clock signal along with the data signals)的原因,PCB的设计必须要使得TXCLK有1.5-2ns的时延。RGMII v2.0具备了可选的内部时延。

Serial Gigabit Media Independent Interface,maybe在光纤用得多一些吧。
Quad Serial Gigabit Media Independent Interface.
10 Gigabit Media Independent Interface.

了解这些MII的区别之后,再回过头看飞凌OK335xD的AR8031,它采用的是12根线的RGMII来连接MAC。至于RTL8201BL,它的TXCLK和RXCLK都为25M,同时由引脚分配可知它使用的是Standard MII;再看AM335x,它支持的是GMII,RMII和RGMII三种,并没有标准的MII。那它们之间该如何连接呢?

由于和Standard MII兼容的是GMII,所以RTL8201BL应该连接在AM335x的GMII Interface,而不是OK335xD使用的RGMII Interface. AM335x的GMII Interface由下面的信号组成:
见AM335x的技术手册“Table 14-6. GMII Interface Signal Descriptions in MII (100/10Mbps) Mode”

 * GMTCLK O:  The clock is generated by the CPSW and is running at 125MHz.
 * MtCLK I:  Provides the timing reference for transmit operations. 2.5MHz/10Mbps. 25MHz/100Mbps.
 * Mtxd O:  MTXD[7-4] pins of MTXD data are not used.
 * Mtxen O:  The transmit enable signal indicates that the MTXD pins are generating 4bit data.
 * MCOL I:  Hardware flow control for full-duplex or asserted not idle for half-duplex.
 * MCRS I:  Held low for full-duplex.
 * MRCLK I:  The receive clock. 2.5MHz/10Mbps. 25MHz/100Mbps.
 * MRXD I:  MRXD[7-4] pins of MRXD data are not used.
 * MRXDV I:  The receive data valid signal.
 * MDCLK O:  Management data clock.
 * MDIO I/O:  MDIO DATA.
 
现在,RTL8201BL和AM335x(ZCZ封装)的引脚连接就很清楚了:
 GMTCLK 《 == 》 *NC
 MtCLK   《 == 》 TXC          K18
 Mtxd    《 == 》 TXD[3:0]    K17 K16 K15 J18
 Mtxen   《 == 》 TXEN        J16
 MCOL    《 == 》 COL          H16  
 MCRS    《 == 》 CRS          H17  
 MRCLK   《 == 》 RXC          L18
 MRXD    《 == 》 RXD[3:0]    M16 L15 L16 L17
 MRXDV   《 == 》 RXDV        J17
 MDCLK   《 == 》 MDC         M18  
 MDIO     《 == 》 MDIO        M17  
 *NC      《 == 》 RXER/FXEN  J15
 
RTL8201BL不需要使用GMTCLK,因为它自身使用了25MHz的晶振;而RXER/FXEN在Table 14-6中虽然找不到对应的说明,但是它可以接到J15(MII1_RX_ER)上。

=============================================
第二步,更改U-Boot:

U-Boot里面关于MII功能的引脚mux应该是:
static struct module_pin_mux gmii1_pin_mux[] = {
        {OFFSET(mdio_clk),      MODE(0) | PULLUP_EN},
        {OFFSET(mdio_data),     MODE(0) | RXACTIVE | PULLUP_EN},
        {OFFSET(mii1_rxdv),     MODE(0) | RXACTIVE},
        {OFFSET(mii1_txen),     MODE(0)},
        {OFFSET(mii1_rxerr),    MODE(0) | RXACTIVE},
        {OFFSET(mii1_rxclk),    MODE(0) | RXACTIVE},
        {OFFSET(mii1_txclk),    MODE(0) | RXACTIVE},
        {OFFSET(mii1_col),      MODE(0) | RXACTIVE}
        {OFFSET(mii1_crs),      MODE(0) | RXACTIVE},
        {OFFSET(mii1_rxd0),     MODE(0) | RXACTIVE},
        {OFFSET(mii1_rxd1),     MODE(0) | RXACTIVE},
        {OFFSET(mii1_rxd2),     MODE(0) | RXACTIVE},
        {OFFSET(mii1_rxd3),     MODE(0) | RXACTIVE},
        {OFFSET(mii1_txd0),     MODE(0)},
        {OFFSET(mii1_txd1),     MODE(0)},
        {OFFSET(mii1_txd2),     MODE(0)},
        {OFFSET(mii1_txd3),     MODE(0)},
        {-1},
};

(* RXACTIVE: Input enable value for the Pad. Set to 0 for output only. Set to 1 for input or output. 所以凡是用做输入,或者双向的IO引脚都需要设置RXACTIVE标识。)

另外,需要更改的地方还有:
static struct cpsw_slave_data cpsw_slave = {
        .slave_reg_ofs  = 0x208,
        .sliver_reg_ofs = 0xD80,
        .phy_addr       = 2,
        .phy_if         = PHY_INTERFACE_MODE_MII,
};

phy_addr是我通过将RTL8201BL的PHYAD1/LED1引脚上拉而得到的地址,要注意的是RTL8201BL不支持PHY地址0,如果设置为0则会进入掉电模式(Seting the PHY address to 00000b will put the RTL8201BL into power down mode)。PHY_INTERFACE_MODE_MII则是设置为MII模式。

然后是在函数board_eth_init(bd_t *bis)添加这一句(如果原来有对cdev->miisel的操作则去掉它):
writel((GMII1_SEL_MII), &cdev->miisel);

编译之后下载并运行。

=============================================
第三步,调试RTL8201BL。

使用74HC595静态驱动的数码管指示U-Boot运行的步骤,并且把每个步骤之间的延时拉长到5S,会发现在phy_config执行之前,RTL8201和路由器的灯都闪烁正常,而之后RTL8201就变成了LINK、Full Duplex LED、Link 100/ACT LED灯常亮。因此将这个phy_config函数:
int board_phy_config(struct phy_device *phydev)
        __attribute__((weak, alias("__board_phy_config")));

将下面这个函数在board.c中定义(which means "do nothing"):
int board_phy_config(struct phy_device *phydev)
{
        printf("maria: __board_phy_config start:\n");
        HC595_dis_data(7777, 4, SM410806K);
        return 0;
}

还记得U-Boot系列8提到的alias符号吗?它的功能是,如果用户没有定义alias的符号,则使用它带的值;如果定义了,则使用自定义的值。这样,本来要执行__board_phy_config的,现在会执行board_phy_config,这也意味着phy会保持硬件设置的10Mbps,而不是config成100Mbps。

在10Mbps下,观察MDIO的寄存器,发现它Auto-negotiation完成;ping和tftp功能也成功。
至此,Ethernet PHY芯片的调试暂时告一段落,等到第二版重新布局的时候再调试100Mbps功能(因为就算再绘制小测试板,也不保证连接主控板和测试板的杜邦线不会带来干扰)。
Wish me luck!

=====================================================
ps: RTL8201的布线规范。
=====================================================
http://pdf.dzsc.com/2008714/200807142330489631.pdf
RTL8201 PCB Layouy Guide
1. Introduction
2. Placement

rtl8201_layout_1.jpg


A应该离RTL8201越近越好,B硬件离变压器越近越好;RJ45和变压器应该越近越好;偏置电阻离RTL8201越近越好,离TX+/-,RX+/-,以及时钟线越远越好;晶振不应放置在IO附近、板边缘以及变压器附近;晶振外壳应该良好接地(*也有人认为晶振外壳无需接地);磁性元件分开并呈90度放置;高功耗器件放置在电源附近;A和B的终端电阻为50欧姆,需要仔细考虑电容的选择;变压器离RTL8201越近越好;差分线需对称,而且变压器控制在10~12cm以内;差分线之间的长度差控制在2cm以内。

3. Trace Routing
避免直角;数字信号不要影响差分信号;仔细选择线长和线宽,线下最好有GND平面;线长不要超过波长的1/20,因此25MHz的线不要超过30cm,125MHz的线不要超过12cm;电源线要短粗,过孔要大一些;去耦电容需要单独打地孔,直径0.2inch以内;去耦电容离芯片越近越好,每个电源引脚都需要,磁珠(100欧姆@100Mhz)离引脚越近越好;差分线要等长;差分线之间要远一些,加上GND隔离;变压器应该是1:1/1:1。

4. Trace Connection of MII Interface to LAN Controller
MAC和RTL8201越近越好,最长不能超过10inch;TXD[0-3]、TXCLK、RXD[0-3]、RXCLK线长差别不超过1 inch;100MHz时TXCLK和RXCLK为25MHz,10MHz时TXCLK和RXCLK为2.5MHz;MAC离接插件1到7 inch,RTL8201离接插件1到3 inch。

5. Power and Ground Plane
电源线应短粗,电源平面应完整,留出模拟电源平面;A和B应该预留以后的2.5V版本;模拟地的返回路径应该和common GND差不多,如果没信心则使用整个地;不要使用直角;变压器和RJ45底下铺单独的地。

6. Notice at ACR Card
7. For better and more stable analog performance:
模拟地需良好的回流;为电源增加22uF和47nF的去耦电容;仔细选择晶振的参数,电容为20pF;模拟电源需要磁珠,而且离它越近越好。

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

DiracFatCat 2015-1-14 09:28

是的,这版原理图是测试板,没有画上终端电阻和电容,调试的时候用飞线加上了。

用户1825602 2015-1-13 15:11

你好,RJ45上面要接终端电阻,中间抽头要增加接地的电容,看你原理图中间抽头是NC

DiracFatCat 2014-12-30 09:10

在图上没有画出来,后面的调试记录里面补充了,差分线通过终端电阻和电容接地,P4和P5也是通过电容接地。

用户1543914 2014-12-29 16:03

话说网络接口变压器的公共端P$4 P$5都没使用,板子能工作??? QQ356290462
相关推荐阅读
DiracFatCat 2018-09-05 12:14
【博客大赛】卡尔曼滤波学习笔记(11)从位置估计速度
卡尔曼滤波器,不仅仅是一个低通滤波器,否则也不会持续发展50年。 示例:桑先生需要测试高速列车的性能。测试的目的是判断列车在直线上能否保持80m/s的速度。速度和位置每0.1秒测量一次,但是由于...
DiracFatCat 2018-08-31 19:32
【博客大赛】卡尔曼滤波学习笔记(10)一个简单的示例
《Kalman Filtering: Theory and Practice Using MATLAB》第三章,看不懂,暂时略过。《Kalman Filtering: Theory and Pract...
DiracFatCat 2018-07-19 15:09
对sed命令的练习
sed是流编辑器。它每次处理一个输入,因此很有效率。官方手册:https://www.gnu.org/software/sed/manual/sed.html学习Linux命令,当然要阅读官方手册,所...
DiracFatCat 2018-06-19 15:10
【博客大赛】卡尔曼滤波学习笔记(八)可观测性和可控制性 ...
可观测性是指,在给定模型的情况下,动力学系统的状态是否由它的输入输出唯一确定。可观测性是系统模型的特征。如果传感器矩阵H是可逆的,则本系统可观测,因为有:如果传感器矩阵H某些时候是不可逆的,则本系统仍...
DiracFatCat 2018-06-19 10:56
【博客大赛】卡尔曼滤波学习笔记(七)Z变换
如果我们仅仅对离散线性系统感兴趣,那么就使用下面这个表达式:如果u是常量,那么可以写成:为了简化表达式,我们可以将上面写成:离散线性时不变系统的Φ求解,可以使用Z变换。(* 由于本人已经忘记了Z变换的...
DiracFatCat 2018-06-19 10:54
【博客大赛】卡尔曼滤波学习笔记(六)拉普拉斯变换
对于线性时变/时不变系统,求解Φ(t)有多种方式,拉普拉斯变换是其中一种。(* 由于本人已经忘记了拉普拉斯变换的内容,因此本节待续。)...
EE直播间
更多
我要评论
4
13
关闭 站长推荐上一条 /3 下一条