使用的是rt-thread1.0.4版本,源码下下来解压,在stm32f107vct6芯片上跑。用的是dm9161aep芯片,以RMII方式连接,通过stm32上的MCO引脚给dm9161提供50MHz的CLK信号。
将源代码中eth模式的宏定义由MII模式改为RMII模式,取消lwip的dhcp功能。编译、下载,对于神舟IV开发板,程序可以正常运行,dm9161aep正常工作,电脑能够识别到网口,能够ping通。但是我们自己画的板子上却只能显示连上,但是不能ping通。
为什么能够连上?通过单步调试,发现只要stm32引脚MCO一给dm9161提供50M的信号,dm9161马上就能工作,PC端马上就能连上网口,不管程序有没有在运行。所以简单的理解就是,dm9161只要有电,CLK脚有50M信号,电脑就能识别到它。所以,能够ping通才表示dm9161在正常的工作。
我对比了rt-thread中eth的初始化设置和没有操作系统的例程中的代码,发现有些地方还是有点不一样的。
在rt-thread的初始化过程中,它少了一段程序,程序如下所示:
这段程序主要是对phy芯片寄存器进行配置,通过读取预先定义好的值来确定phy芯片是10M模式还是100M模式?是全双工还是半双工?是否开启协商功能(对于这个功能,我也搞不清楚,感觉开和不开PC都能够识别到),这中间的延时还是必须要加的,至于延时多少,我也没有仔细研究过,我延时的时间有点长的。
通过上网查了一些,发现rt-thread有对为什么去掉这一部分有进行解释。因为phy本身不通过外部初始化就可以进行正常工作了的,同时phy的地址是和外部引脚连接有关,所以rt-thread源代码中没有对phy进行设置,直接让phy芯片工作在初始的状态。
我试了一下,dm9161 adr2~adr4引脚悬空,其地址为0x00。而dp83848的地址为0x01(0x00为隔离模式,数据手册上是这么说的,具体未知)。自己的板子只要加上这段,就可以正常的跑起来了。但是,它必须是先连好网线,然后再通电,它才会工作正常。如果先通电,再连网线,那工作就不正常了。待我具体调调,找找具体那边出问题了。
我用了一种最笨的方法,就是把上面的++timeout给注释掉了,这样的话,它就一直会等待网线的连接,只有连接上了网线,程序才会继续向下执行。
将源代码中eth模式的宏定义由MII模式改为RMII模式,取消lwip的dhcp功能。编译、下载,对于神舟IV开发板,程序可以正常运行,dm9161aep正常工作,电脑能够识别到网口,能够ping通。但是我们自己画的板子上却只能显示连上,但是不能ping通。
为什么能够连上?通过单步调试,发现只要stm32引脚MCO一给dm9161提供50M的信号,dm9161马上就能工作,PC端马上就能连上网口,不管程序有没有在运行。所以简单的理解就是,dm9161只要有电,CLK脚有50M信号,电脑就能识别到它。所以,能够ping通才表示dm9161在正常的工作。
我对比了rt-thread中eth的初始化设置和没有操作系统的例程中的代码,发现有些地方还是有点不一样的。
在rt-thread的初始化过程中,它少了一段程序,程序如下所示:
1 /*-------------------- PHY initialization and configuration ----------------*/ 2 /* Put the PHY in reset mode */ 3 if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset))) 4 { 5 /* Return ERROR in case of write timeout */ 6 return ETH_ERROR; 7 } 8 9 /* Delay to assure PHY reset */ 10 Delay(PHY_ResetDelay); 11 12 13 if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable) 14 { 15 /* We wait for linked satus... */ 16 do 17 { 18 timeout++; 19 } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO)); 20 /* Return ERROR in case of timeout */ 21 if(timeout == PHY_READ_TO) 22 { 23 return ETH_ERROR; 24 } 25 /* Reset Timeout counter */ 26 timeout = 0; 27 28 /* Enable Auto-Negotiation */ 29 if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation))) 30 { 31 /* Return ERROR in case of write timeout */ 32 return ETH_ERROR; 33 } 34 35 /* Wait until the autonegotiation will be completed */ 36 do 37 { 38 timeout++; 39 } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO)); 40 /* Return ERROR in case of timeout */ 41 if(timeout == PHY_READ_TO) 42 { 43 return ETH_ERROR; 44 } 45 /* Reset Timeout counter */ 46 timeout = 0; 47 48 /* Read the result of the autonegotiation */ 49 RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR); 50 51 /* Configure the MAC with the Duplex Mode fixed by the autonegotiation process */ 52 if((RegValue & PHY_Duplex_Status) != (uint32_t)RESET) 53 { 54 /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */ 55 ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex; 56 57 } 58 else 59 { 60 /* Set Ethernet duplex mode to HalfDuplex following the autonegotiation */ 61 ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex; 62 } 63 /* Configure the MAC with the speed fixed by the autonegotiation process */ 64 if(RegValue & PHY_Speed_Status) 65 { 66 /* Set Ethernet speed to 10M following the autonegotiation */ 67 ETH_InitStruct->ETH_Speed = ETH_Speed_10M; 68 } 69 else 70 { 71 /* Set Ethernet speed to 100M following the autonegotiation */ 72 ETH_InitStruct->ETH_Speed = ETH_Speed_100M; 73 } 74 } 75 else 76 { 77 if(!ETH_WritePHYRegister(PHYAddress, PHY_BCR, ((uint16_t)(ETH_InitStruct->ETH_Mode >> 3) | 78 (uint16_t)(ETH_InitStruct->ETH_Speed >> 1)))) 79 { 80 /* Return ERROR in case of write timeout */ 81 return ETH_ERROR; 82 } 83 /* Delay to assure PHY configuration */ 84 Delay(PHY_ConfigDelay); 85 86 }
通过上网查了一些,发现rt-thread有对为什么去掉这一部分有进行解释。因为phy本身不通过外部初始化就可以进行正常工作了的,同时phy的地址是和外部引脚连接有关,所以rt-thread源代码中没有对phy进行设置,直接让phy芯片工作在初始的状态。
我试了一下,dm9161 adr2~adr4引脚悬空,其地址为0x00。而dp83848的地址为0x01(0x00为隔离模式,数据手册上是这么说的,具体未知)。自己的板子只要加上这段,就可以正常的跑起来了。但是,它必须是先连好网线,然后再通电,它才会工作正常。如果先通电,再连网线,那工作就不正常了。待我具体调调,找找具体那边出问题了。
我用了一种最笨的方法,就是把上面的++timeout给注释掉了,这样的话,它就一直会等待网线的连接,只有连接上了网线,程序才会继续向下执行。