ethcat开发记录 二
SOEM移植到stm32f407+LAN8720硬件上的注意点
1、LAN8720的PHY地址问题。
2、LAN8720芯片在上电后要对复位引脚操作。
3、使能LAN8720的混杂模式,在新的HAL库里,这个设置包含在 ETH_MACFilterConfigTypeDef 结构体里,通过 HAL_ETH_SetMACFilterConfig函数配置。
完整代码:
/* ETH init function */
void MX_ETH_Init(void)
{
/* USER CODE BEGIN ETH_Init 0 */
//复位芯片
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);
/* USER CODE END ETH_Init 0 */
static uint8_t MACAddr[6];
/* USER CODE BEGIN ETH_Init 1 */
/* USER CODE END ETH_Init 1 */
heth.Instance = ETH;
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x00;
heth.Init.MACAddr = &MACAddr[0];
heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
heth.Init.TxDesc = DMATxDscrTab;
heth.Init.RxDesc = DMARxDscrTab;
heth.Init.RxBuffLen = 1524;
/* USER CODE BEGIN MACADDRESS */
/* USER CODE END MACADDRESS */
if (HAL_ETH_Init(&heth) != HAL_OK)
{
Error_Handler();
}
memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
/* USER CODE BEGIN ETH_Init 2 */
ETH_MACFilterConfigTypeDef pFilterConfig;
HAL_ETH_GetMACFilterConfig(&heth, &pFilterConfig);
pFilterConfig.PromiscuousMode=ENABLE;//使能混杂模式
HAL_ETH_SetMACFilterConfig(&heth, &pFilterConfig);
HAL_ETH_SetMDIOClockRange(&heth);
//判断lan8720芯片是否连接
uint32_t regvalue;
if(HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, PHY_SPECIAL_MODES_REG, ®value) != HAL_OK)
{
/* Can't read from this device address continue with next address */
return;
}
// if((regvalue & PHY_BASIC_STATUS_REG) == PHY_ADDR)
// {
// LOG_D("Found a phy, address:0x%02X", PHY_ADDR);
// }
//软复位
if(HAL_ETH_WritePHYRegister(&heth, PHY_ADDR, PHY_BCR, PHY_RESET) == HAL_OK)
{
HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, PHY_SPECIAL_MODES_REG, ®value);
uint32_t tickstart = HAL_GetTick();
/* wait until software reset is done or timeout occured */
while(regvalue & PHY_RESET)
{
if((HAL_GetTick() - tickstart) <= 500)
{
if(HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, PHY_BCR, ®value) != HAL_OK)
{
return;
}
}
}
}
//读lan8720工作模式,设置mac模块
if(HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, PHY_BCR, ®value) == HAL_OK)
{
regvalue |= PHY_FULLDUPLEX_100M;
HAL_ETH_WritePHYRegister(&heth, PHY_ADDR, PHY_BCR, regvalue);
//eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
ETH_MACConfigTypeDef macconfig;
HAL_ETH_GetMACConfig(&heth, &macconfig);
macconfig.DuplexMode = ETH_FULLDUPLEX_MODE;
macconfig.Speed = ETH_SPEED_100M;
HAL_ETH_SetMACConfig(&heth, &macconfig);
}
// else
// {
// status = RT_ERROR;
// }
//以太网模块开始工作
HAL_ETH_Start(&heth);
/* USER CODE END ETH_Init 2 */
}
4、底层数据读写函数
//读写以太网数据的函数,被soem的nicdrv.c中的函数调用 int EthWrPacket(uint8_t* pBuff, int Len) { uint32_t curidx=heth.TxDescList.CurTxDesc; HAL_StatusTypeDef HalStatus; TxBuffer.buffer=pBuff; TxBuffer.len=Len; TxConfig.TxBuffer=&TxBuffer; TxConfig.Length=Len; HalStatus = HAL_ETH_Transmit(&heth,&TxConfig,100); if (HalStatus == HAL_OK) return Len; // return the number of bytes readelse return -1; // no packet received } int EthRdPacket(void* pBuff) { HAL_StatusTypeDef HalStatus; HalStatus=HAL_ETH_ReadData(&heth,&pBuff); if (HalStatus == HAL_OK) return 1;else return -1; }
测试方法:调用 EthWrPacket 函数,发送任意数据,连接开发板与电脑,使用wireshark监视网络,可以收到开发板的数据。
LAN8720
引用请注明出处