Cubemx+RTL8201驱动

Cubemx 生产的驱动只能选择LAN8742,无法适配RTL8201,这篇文字就分享一下如何逐步修改lan8742的代码去适配。

一、地址问题

入口函数:int32_t LAN8742_Init(lan8742_Object_t *pObj)

主要是做PHY 地址检测,但是我们查阅RTL8201手册得知:其PHY地址和2个LED引脚捆绑使用,地址为逻辑1时LED低电平有效。从其中至少得知两个信息:

1、2个引脚即2bit,即最多同时接入4个RTL8201

2、逻辑1时低电平,即上拉为0,下拉为1

查看自己的设备原理图中(自己的设备),两个LED上拉,则地址为0。

二、复位和开启自动协商

不同版本cubemx生成的驱动文件还有点差异,比如cubemx6.11+STM32H723生成的初始化函数就只有地址检测。早期的还有软件复位操作,见鬼。

我们这里主要要做的就是开启自动协商,和获取链接状态。

RTL8201和LAN8742的链接状态有差异,LAN8742在链接成功后需要读取0x1F寄存器,而RTL8201是其他寄存器。

我这里处理更简单,只需要判断协商是否完成,只要完成了就认为他是100Mbit/s。

如果有需要的话,还需要你自己实现:判断链接状态是否符合(比如目标是100M全双工,但是协商的是10M),需要进行二次协商或手动设置链接方式。

最后贴一下代码:

1、初始化 LAN8742_Init

#define PHY_ADDRESS 	0
#define PHY_NAGO_TIME	1000
#define PHY_RST_TIMEOUT	5000

 int32_t LAN8742_Init(lan8742_Object_t *pObj)
 {
   uint32_t tickstart = 0, regvalue = 0;
   int32_t status = LAN8742_STATUS_OK;
   
   if(pObj->Is_Initialized == 0)
   {
     if(pObj->IO.Init != 0)
     {
       /* GPIO and Clocks initialization */
       pObj->IO.Init();
     }
   
     /* Fixed address */
     pObj->DevAddr = PHY_ADDRESS;
     
     /* if device address is matched */
     if(status == LAN8742_STATUS_OK)
     {
       /* set a software reset  */
       if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0)
       { 
         /* get software reset status */
         if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) >= 0)
         { 
           tickstart = pObj->IO.GetTick();
           
           /* wait until software reset is done or timeout occured  */
           while(regvalue & LAN8742_BCR_SOFT_RESET)
           {
             if((pObj->IO.GetTick() - tickstart) <= PHY_RST_TIMEOUT)
             {
               if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) < 0)
               { 
                 status = LAN8742_STATUS_READ_ERROR;
                 break;
               }
             }
             else
             {
               status = LAN8742_STATUS_RESET_TIMEOUT;
               break;
             }
           } 
         }
         else
         {
           status = LAN8742_STATUS_READ_ERROR;
         }
       }
       else
       {
         status = LAN8742_STATUS_WRITE_ERROR;
       }
     }
   }
      
   if(status == LAN8742_STATUS_OK)
   {
	 status = LAN8742_StartAutoNego(pObj);
	 if(status == LAN8742_STATUS_OK)
	 {
	   tickstart =  pObj->IO.GetTick();
     
       /* Wait for 2s to perform initialization */
       while((pObj->IO.GetTick() - tickstart) <= PHY_NAGO_TIME)
       {
       }
       pObj->Is_Initialized = 1;
	 }
   }

   return status;
 }

2、获取状态 LAN8742_GetLinkState

int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
{
  uint32_t readval = 0;

  /* Read Status register  */
  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
  {
    return LAN8742_STATUS_READ_ERROR;
  }

  /* Read Status register again */
  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
  {
    return LAN8742_STATUS_READ_ERROR;
  }

  if((readval & LAN8742_BSR_LINK_STATUS) == 0)
  {
    /* Return Link Down status */
    return LAN8742_STATUS_LINK_DOWN;
  }

  /* Check Auto negotiation */
  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0)
  {
    return LAN8742_STATUS_READ_ERROR;
  }

  if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN)
  {
    if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE))
    {
      return LAN8742_STATUS_100MBITS_FULLDUPLEX;
    }
    else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT)
    {
      return LAN8742_STATUS_100MBITS_HALFDUPLEX;
    }
    else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)
    {
      return LAN8742_STATUS_10MBITS_FULLDUPLEX;
    }
    else
    {
      return LAN8742_STATUS_10MBITS_HALFDUPLEX;
    }
  }
  else /* Auto Nego enabled */
  {
    if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
    {
      return LAN8742_STATUS_READ_ERROR;
    }

    /* Check if auto nego not done */
    if((readval & LAN8742_BSR_AUTONEGO_CPLT) == 0)
    {
      return LAN8742_STATUS_AUTONEGO_NOTDONE;
    }
	else
	{
	  return LAN8742_STATUS_100MBITS_FULLDUPLEX;
	}
  }
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Cubemx是一款由ST公司开发的单片机可视化配置工具。它可以简化用户对于单片机的配置过程,使其更加方便、简单、快捷。 而RTL8201则是一款经典的PHY芯片,它常被用于以太网通信中,使其可以自动协商数据传输速率,从而在通信中达到更好的效果。 当使用Cubemx配置单片机时,需要对以太网通信进行配置,这时可以选择RTL8201作为PHY芯片。在使用Cubemx时,可以直接在库文件中找到与RTL8201相关的配置选项,输入相应的参数即可完成对PHY芯片的配置,但需要注意的是,对于不同的单片机型号,而且RTL8201的配置选项可能会不同。 通过使用Cubemx配置RTL8201,可以提高开发者开发单片机应用程序的效率,同时也可以使得以太网通信更加稳定,提升系统的可靠性和性能。 ### 回答2: CubeMX是一个非常强大的ST公司开发的自动代码生成工具,它可以极大地提高开发效率。而RTL8201是一款具有高速以太网通信能力的芯片。 结合起来,Cubemx RTL8201主要是指使用CubeMX快速构建STM32项目,其中涉及到使用RTL8201芯片实现高速以太网通信功能。CubeMX能够自动识别STM32的片型并生成对应的配置代码,包括系统时钟、GPIO、中断、DMA等。而RTL8201则负责在STM32与以太网之间进行转换,使得STM32可以通过以太网实现通信功能。 使用Cubemx RTL8201可以有效地缩短开发周期,降低开发难度。开发者只需要进行简单的配置,即可生成代码,实现以太网通信。同时,Cubemx RTL8201也确保了代码的可靠性和稳定性,避免了一些手写代码可能出现的错误和漏洞。 综上所述,Cubemx RTL8201是一个非常实用的工具,可以为工程师带来很大的便利。在实现以太网通信功能的时候,可以考虑使用这一工具,加速开发进度,提高开发效率。 ### 回答3: CubeMX是一款由STMicroelectronics(ST)开发的集成开发环境(IDE)工具,它为STM32微控制器提供了图形化界面进行代码生成和软件初始化。RTL8201是一款10/100Mbps PHY芯片,它是Realtek公司生产的以太网接口控制器。 在使用CubeMX时,可以选择添加RTL8201作为设备外设,从而可以快速生成支持以太网通信的软件初始化代码。 在开发过程中,需要配置PHY接口和MAC层参数,其中PHY接口需要指定时钟源和时钟频率,同时需要进行电气特性参数的设置。 对于RTL8201,其主要特点包括自动协商、自适应和远程电源等功能,同时支持以太网帧的发送和接收。开发者可以根据具体应用场景配置RTL8201的寄存器参数,以满足通信性能需求。 总之,使用CubeMXRTL8201可以快速实现以太网通信功能,从而适应于包括智能家居、工业控制和物联网等多种应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值