调试cube生成的f107+lan8720代码

之前用的w5500,无奈芯片越来越贵了,正好手头上有100来颗lan8720a,直接将方案改了吧。

以前在深圳工作时公司的网关正好用的这个方案,直接抄吧。

硬件设计网口无晶振,由mcu的mco脚输出,50Mhz模式,其他都是通用连接方式

接下来入正题:由于以前用的标准库,现在试一试hal库。打开cubemx,一顿骚操作后配置完成,生成代码。

第一个问题,调试口,官方默认如果不设置就关闭swd和jtag,造成无法2次下载程序,需要将system core->sys->debug改成对应模式,我用的serial wire,即swd。

接下来可以正常调试了,功能上仅仅使能了dhcp,但代码跑起来完全失败。

第二个问题,地址设置,需要将eth->parameter settings->general:ethernet configuration->phy address改成对应的值,我这边是0.

好了,再试,依然不行,接下来我用示波器看了一下mco脚,也确实有50mhz

第三个问题,代码都是采用的默认参数,有些参数偏小,修改的部分有默认任务栈空间调大,操作系统堆空间加大,当然这个可能和结果无关,过程得记录下来

还是不行,无奈将之前标准库代码拿来试一下,完全没问题。

对比代码,加入了几个打印信息,确定芯片id能否识别。由于cubemx并没有生成其id寄存器偏移地址,所以这里直接写死

    uint32_t id_0,id_1;
    HAL_ETH_ReadPHYRegister(&heth,2,&id_0);
    HAL_ETH_ReadPHYRegister(&heth,3,&id_1);
    printf("PHY_ID = %X\n", (id_0<<16) | (id_1)); 

其中寄存器地址2和3分别对应文档以下说明

 最后id读出来了,完全没问题。

于是第四个问题,又从lwip内部着手,但是我查了半天也没看到cubemx怎么将lwip的debug功能开启,只能开启全局的,各功能模块根本没有,于是找到lwipopts.h文件,添加以下内容

#define DHCP_DEBUG            0xf7
#define UDP_DEBUG            0xf7
#define NETIF_DEBUG            0xf7

这里千万别让第4位为1,即0x08,因为这个位是是否阻塞功能的,看下面代码段

好了,继续看结果吧,总的来说就是dhcp一直在广播,没收到回复而超时。

那就只能对比以前的代码了。最终发现

最后关键问题。生成的代码在自动协商速率完成后读取的是寄存器1的结果,然后我看网上有的说是31,我看手册上也确实有说31可以读到

这里我就断点调试查看了一下读出来的值,结果是0x04(00000100),即速度那儿是001 ,对应的是10m 半双工,这就不对了。

反过来我看之前的代码,读取的是地址1,确实也有速度指示

 于是,我就改成以前的方式再试,果不其然,成功了。

文件stm32f1xx_hal_eth.c

函数HAL_ETH_Init

在auto-negotiation完成后

    /* Read the result of the auto-negotiation */
    if ((HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg)) != HAL_OK)
    {
      /* In case of write timeout */
      err = ETH_ERROR;

      /* Config MAC and DMA */
      ETH_MACDMAConfig(heth, err);

      /* Set the ETH peripheral state to READY */
      heth->State = HAL_ETH_STATE_READY;

      /* Return HAL_ERROR */
      return HAL_ERROR;
    }
    //上面是原生成代码
	 //HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);
	if((phyreg & PHY_100M_T4) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
	  (heth->Init).Speed = ETH_SPEED_100M;
    }
    else if((phyreg & PHY_100M_Duplex) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
	  (heth->Init).Speed = ETH_SPEED_100M;
    }
    else if((phyreg & PHY_100M_Half) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
      (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
	  (heth->Init).Speed = ETH_SPEED_100M;
    }
    else if((phyreg & PHY_10M_Duplex) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
	  (heth->Init).Speed = ETH_SPEED_10M;
    }
    else if((phyreg & PHY_10M_Half) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
      (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
	  (heth->Init).Speed = ETH_SPEED_10M;
    }


	 #if 0        //原生成代码
    /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
    if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
    {
      /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
    }
    else
    {
      /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
      (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
    }
    /* Configure the MAC with the speed fixed by the auto-negotiation process */
    if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
    {
      /* Set Ethernet speed to 10M following the auto-negotiation */
      (heth->Init).Speed = ETH_SPEED_10M;
    }
    else
    {
      /* Set Ethernet speed to 100M following the auto-negotiation */
      (heth->Init).Speed = ETH_SPEED_100M;
    }
	 #endif

其中几个宏定义如下

#define PHY_100M_Duplex            (0x4000)
#define PHY_100M_Half            (0x2000)
#define PHY_10M_Duplex            (0x1000)
#define PHY_10M_Half            (0x0800)
#define PHY_100M_T4                (0x8000)

另外修改的地方不止这一个,还有一个地方在连接状态更新那儿,这个我就不细说了

回过头来思考,其实寄存器31也可以,但为啥就是不对呢,值得注意的是这个是special修饰了的,难到是要进入某个模式吗,这个我现在反正没搞懂

另外可以考虑修改以下定义,以免动原生库文件

根据代码分析应该不难,这里也不再研究 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值