STM32的例子,先用官网的例子,文件名大概叫这个en.stsw-stm32070
ETH_BSP_Config
(1)ETH_GPIO_Config,配置腿,还配置MII还是RMII模式
(2)ETH_MACDMA_Config
2.1 ETH_AutoNegotiation_Enable
2.2 DMA
2.3 ETH_Init
这个函数有三个寄存器要特意指出,BCR,BSR,SR,
/* Put the PHY in reset mode */
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset)))
---------------------------------------------------------------------------------------
/* We wait for linked status...*/
do
{
timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));
---------------------------------------------------------------------------------------------
/* Read the result of the auto-negotiation */
RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR);
看下TI的datasheet,
---------------------------------------------------------------------------------------------------------------------------------------------
下面这两个函数看样都是为了一个事情,就看看网口有没有联网,
/* Configure the PHY to generate an interrupt on change of link status */
// Eth_Link_PHYITConfig(DP83848_PHY_ADDRESS);
/* Configure the EXTI for Ethernet link status. */
// Eth_Link_EXTIConfig();
--------------------------------------------------------------------------------------------------------------
另外PHY_MISR的含义是MII Interrupt Control Register (MICR),就是中断控制寄存器。
那么PHY_MISR只能在中断服务程序里面用么?看样子不是。在任务里面查询也是可以用的。
void Eth_Link_ITHandler(uint16_t PHYAddress) {
/* Check whether the link interrupt has occurred or not */
if(((ETH_ReadPHYRegister(PHYAddress, PHY_MISR)) & PHY_LINK_STATUS) != 0) {
if((ETH_ReadPHYRegister(PHYAddress, PHY_SR) & 1)) {
netif_set_link_up(&gnetif);
} else {
netif_set_link_down(&gnetif);
}
}
}
其中PHY_LINK_STATUS就是
Change of Link Status interrupt:
1 = Change of link status interrupt is pending and is cleared by the
current read.
0 = No change of link status interrupt pending
就是说只要变化了(由断开到连接,或者由连接到断开)就置1.
所以说我如果不想用中断的方法,而是想用查询的方法,那么我要检测是否发生变化,就是要把上个状态的值保存下来?不用!因为有PHY_MISR这个寄存器。这个寄存器在查询也可以用的。
=============================
另外在LwIP_Init里面有个钩子函数ETH_link_callback
/* Set the link callback function, this function is called on change of link status*/
netif_set_link_callback(&gnetif, ETH_link_callback);
ETH_link_callback这个函数的内容和这个函数EthStatus = ETH_Init(Ð_InitStructure, DP83848_PHY_ADDRESS);;的内容有必要比对一下。
ETH_link_callback主要对10M、100M自适应和MACCR寄存器进行了重新的配置。并且看起来如果不是适应的话,MACCR也不用配置。
这说明如果是自适应,如果不执行netif_set_link_callback(&gnetif, ETH_link_callback);,还真可能出问题!
看样子自适应带来了方便性,也给代码带来了很大的风险。
=================================================
另外,经过试验发现只有运行了Eth_Link_ITHandler,那么ETH_link_callback才会起作用。为啥?
因为前者内部调用了netif_set_link_up,而后者有if(netif_is_link_up(netif)) {.....}
=======================================================================
综上:搞得完全清楚,是很困难的事情。
目前表面上的知识已掌握,希望没有大的错误。
总结
(1)只有运行了Eth_Link_ITHandler,那么ETH_link_callback才会起作用
(2)网卡硬件重新配置主要是针对10M/100M自适应的。就是说如果用不着自适应的话,像ETH_link_callback这个函数基本没啥用。