难搞哦 自动协商连不上网,手动协商只能到10M全双工
想问下有没有解决办法。
交换机是锐捷的S2910V2-48GT4SFP-L 千兆交换机
电脑连上测速500-800M带宽
开发环境:
STM32CubeMX(V6.10.0)和 Keil(V5.38.0) ARM版本5.06
用的STM32F429IGT6和LAN8720A
本地测试环境正常100M全双工,生产环境出现10M的情况,用的上面提到的锐捷交换机。
代码:
main中正常调用MX_LWIP_Init(), while(1)主循环中调用MX_LWIP_Process()
其他的设置MAC,IP,掩码,网关都确定没问题。
[C] 纯文本查看 复制代码
// STM32CubeMX生成的自协商代码 只有自协商 这个锐捷交换机会有一定概率连不上网
void ethernet_link_check_state_1(struct netif *netif)
{
ETH_MACConfigTypeDef MACConf = {0};
int32_t PHYLinkState = 0;
uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
{
HAL_ETH_Stop(&heth);
netif_set_down(netif);
netif_set_link_down(netif);
}
else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
{
switch (PHYLinkState)
{
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
default:
break;
}
if(linkchanged)
{
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&heth, &MACConf);
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
HAL_ETH_SetMACConfig(&heth, &MACConf);
HAL_ETH_Start(&heth);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
}
// 自己在原有基础上改的先自协商 没成功就手动协商 按照100M,10M的先后尝试。只有10M才能成功。强制100M后续没网
void ethernet_link_check_state(struct netif *netif)
{
ETH_MACConfigTypeDef MACConf = {0};
int32_t PHYLinkState = 0;
uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
static uint32_t last_time = 0;
static int32_t last_linkstate = 0;
// printf("netif_is_link_up:%u, PHYLinkState:%d\n", netif_is_link_up(netif), PHYLinkState);
if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
{
printf("1.netif_is_link_up:%u, PHYLinkState:%d\n", netif_is_link_up(netif), PHYLinkState);
printf("1.eth stop and set down.\n");
last_linkstate = LAN8742_STATUS_LINK_DOWN;
HAL_ETH_Stop(&heth);
netif_set_down(netif);
netif_set_link_down(netif);
}
else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
{
printf("2.netif_is_link_up:%u, PHYLinkState:%d\n", netif_is_link_up(netif), PHYLinkState);
// if (PHYLinkState == LAN8742_STATUS_10MBITS_FULLDUPLEX)
// {
// PHYLinkState = LAN8742_STATUS_100MBITS_FULLDUPLEX;
// }
// else
// if (PHYLinkState == LAN8742_STATUS_10MBITS_HALFDUPLEX)
// {
// PHYLinkState = LAN8742_STATUS_100MBITS_HALFDUPLEX;
// }
switch (PHYLinkState)
{
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
// case LAN8742_STATUS_10MBITS_FULLDUPLEX:
// duplex = ETH_FULLDUPLEX_MODE;
// speed = ETH_SPEED_100M;
// linkchanged = 1;
// break;
// case LAN8742_STATUS_10MBITS_HALFDUPLEX:
// duplex = ETH_HALFDUPLEX_MODE;
// speed = ETH_SPEED_100M;
// linkchanged = 1;
// break;
default:
break;
}
if(linkchanged)
{
printf("2.eth changed.\n");
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&heth, &MACConf);
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
HAL_ETH_SetMACConfig(&heth, &MACConf);
HAL_ETH_Start(&heth);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
else if(!netif_is_link_up(netif) && (HAL_GetTick() - last_time > 5000))
{
// printf("3netif_is_link_up:%u, PHYLinkState:%d\n", netif_is_link_up(netif), PHYLinkState);
if (last_linkstate == LAN8742_STATUS_LINK_DOWN) {
last_time = HAL_GetTick();
printf("3.set eth mode auto ");
int32_t status = LAN8742_StartAutoNego(&LAN8742);
if(status == LAN8742_STATUS_OK) {
printf("successfully.\n");
} else if (status == LAN8742_STATUS_READ_ERROR){
printf("but read bcr failed.\n");
} else if (status == LAN8742_STATUS_WRITE_ERROR){
printf("but write bcr failed.\n");
} else if (status == LAN8742_STATUS_ERROR){
printf("but status err.\n");
}
last_linkstate = LAN8742_STATUS_AUTONEGO_NOTDONE;
} else if (last_linkstate == LAN8742_STATUS_AUTONEGO_NOTDONE && (HAL_GetTick() - last_time < 10000)) {
} else {
last_time = HAL_GetTick();
PHYLinkState = last_linkstate;
PHYLinkState++;
if ( PHYLinkState < LAN8742_STATUS_100MBITS_FULLDUPLEX || PHYLinkState > LAN8742_STATUS_10MBITS_HALFDUPLEX) {
// if ( PHYLinkState < LAN8742_STATUS_100MBITS_FULLDUPLEX || PHYLinkState > LAN8742_STATUS_100MBITS_HALFDUPLEX) {
PHYLinkState = LAN8742_STATUS_100MBITS_FULLDUPLEX;
}
printf("3.set eth mode %d ", PHYLinkState);
int32_t status = LAN8742_SetLinkState(&LAN8742, PHYLinkState);
if(status == LAN8742_STATUS_OK) {
printf("successfully.\n");
} else if (status == LAN8742_STATUS_READ_ERROR){
printf("but read bcr failed.\n");
} else if (status == LAN8742_STATUS_WRITE_ERROR){
printf("but write bcr failed.\n");
} else if (status == LAN8742_STATUS_ERROR){
printf("but status err.\n");
}
last_linkstate = PHYLinkState;
}
HAL_ETH_Stop(&heth);
netif_set_down(netif);
netif_set_link_down(netif);
}
}
|