最近要做一个高速AD采集系统,打算采用STM32F417+FPGA+DP83848+LWIP+FreeRTOS完成,基于去年用STM32+LAN8720+LWIP+UCOS完成以太网——5通道RS485通信转发的经验,本以为这次的以太网通信部分不过小菜一叠,然而事实并非如此,主要现象是,程序下进去后,RJ45绿灯常亮,黄灯闪烁,说明PHY配置是没问题的,但是ping不通,应用程序也连不上。
核对电路图,发现MDIO居然忘加上拉电阻...没办法,只能飞线加上拉。
然而加了上拉以后,ping有时候能通,有时候请求超时,有时候又是无法访问目标主机,使用网络调试助手与串口做互收互发测试,只有在初次上电后才能收发1个数据帧。
列出所有寄存器值,发现DP83848_PHY_StatusRegister:0x2615,其中BIT13为1:
RECEIVE ERROR LATCH | 0, RO/LH | Receive Error Latch: This bit will be cleared upon a read of the RECR register. 1 = Receive error event has occurred since last read of RXERCNT (address 15h, Page 0). 0 = No receive error event has occurred. |
emm,就这个错误,我一直以为是程序哪里有问题导致的,最终花了两天才定位到问题点...居然是ETH_REF_CLK时钟导致的问题
DATASHEET写着:
CLK_OUT | O | 25 | 25 MHz CLOCK OUTPUT: In MII mode, this pin provides a 25 MHz clock output to the system. In RMII mode, this pin provides a 50 MHz clock output to the system. This allows other devices to use the reference clock from the DP83848VYB without requiring additional clock sources. |
因此我就直接把这个CLK_OUT当作ETH_REF_CLK用了,直到我在TI的一份文档DP83848 Sin 10/100Mb/s Ethernet Transcvr Reduced Media Indep Interfce RMII Mode (PDF 168 KB)中看到这样一句话:
The 25MHz_OUT signal is a delayed version of the X1/REF_CLK input. While this clock may be used for other purposes, it should not be used as the timing reference for RMII control and data signals.
好了,只能割线,将X1/REF_CLK引入ETH_REF_CLK
再ping,偶尔超时,考虑到板子Layout时PHY与STM32拉得比较远,又是飞线引入的ETH_REF_CLK,因此再加一颗120R电阻,问题完美解决!
最后再分享一些个人认为使用DP83848需要注意的地方。
1.如果程序是从LAN8720改到DP83848,还是使用RMII的话,程序需要改动的部分就只有PHY地址
Table 6-5. PHY Address Mapping
Pin # | PHYAD Function | RXD Function |
42 | PHYAD0 | COL |
43 | PHYAD1 | RXD_0 |
44 | PHYAD2 | RXD_1 |
45 | PHYAD3 | RXD_2 |
46 | PHYAD4 | RXD_3 |
DP83848的地址决定于 { RXD[3:0],COL }五个引脚,其中RXD[3:0]芯片内部弱下拉,COL 内部弱上拉,因此默认地址为00001
如果外围电路RXD[3:0]这四个引脚接VCC上拉,对应的地址位变为1;如果COL接下拉,对应地址变为0
举例:假如需要更改PHY地址为01100,则RXD3保持内部默认弱下拉,RXD2、RXD1外部接上拉,RXD0保持内部默认弱下拉,COL外部接下拉。
同时注意以下定义对应修改
#define DP83848_PHY_ADDRESS 0x01
#define PHY_SR ((uint16_t)0x10) /*DP83848 ——PHY状态寄存器*/
#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*DP83848 PHY速度值*/
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*DP83848 PHY连接状态值*/
2.DP83848的MII MODE SELECT由PIN39——MII_MODE (RX_DV) 和 PIN6——SNI_MODE (TXD_3)决定,注意默认状态芯片内部弱下拉
MII_MODE | SNI_MODE | MAC Interface Mode |
0 | X | MII Mode |
1 | 0 | RMII Mode |
1 | 1 | 10 Mb SNI Mode |
3. PIN7——PWR_DOWN/INT,可用于做网线热插拔中断,操作以下两个寄存器配置即可,即使芯片内部已有上拉,但最好外部上拉更稳定
/* Enable event based interrupts && PWRDOWN_INT is an Interrupt Output. */
ETH_WritePHYRegister( DP83848_PHY_ADDRESS, DP83848_MII_InterruptControlRegister, 0x0003 );
/* Enable Interrupt on change of link status */
ETH_WritePHYRegister( DP83848_PHY_ADDRESS, DP83848_MII_InterruptStatusRegister, 0x0060 );