当前位置: 首页 > 工具软件 > RX > 使用案例 >

DM9000调试记录:dm9000 rx: rx error, stop device

左丘峰
2023-12-01

       最近因项目需求,在一个单片机项目中需要用到两个网卡,实现双网卡UDP的通信。在这记录下,自己调试阶段遇到的一个坑,花了不少时间,避免大家犯同样的错误。

      项目所用平台:STM32F427  + UCOSII + LWIP + LAN8720  +  DM9000CIEP。

      LAN8720用F4自带的ETH,DM9000集成了PHY+MAC,所以外挂在F4的FMC的接口上,电路很简单。两款芯片我就不在这做介绍了,想了解的自己百度。

       现象:LAN8720数据收发都正常。但在调试DM9000的时候,用DM9000发送数据时,上位机接收正常,但是DM9000在接收数据时,log日志中总是打印:dm9000 rx: rx error, stop device。

       调试过程:

       1.对于LAN8720的调试,我是直接移植正点原子的阿波罗(F429)例程,正常使用,这里我就不细说怎么移植的了。但是有一个地方需要注意,F4是支持硬件产生UDP、TCP、IP的校验和,并在Lwipopts.h中用宏定义使能了,并且在ETH的参数配置时也使能。因为有些网卡如需要硬件支持产生校验和,则需要阅读datasheet,配置相关寄存器,比如说DM9000。

       2.对于DM9000的调试。DM9000的驱动我是使用的正点原子驱动(战舰扩展例程中LWIP的例程)。但是战舰是F1,使用的FSMC接口读取的SRAM的通信方式,F4的硬件升级成了FMC接口,我是模仿战舰配置FSMC的驱动,然后自己写了F4的FMC的驱动(基于hal库),坑就出现在这了,听我一一道来:FMSC有时序要求,所以FMC也少不了时序,然后我根据F4的主频写填写了相关的几个参数,我也度娘上找了FMC的驱动程序,都说后面三个参数在MODEA模式下 ,无需配置,然后我也照做了,配置成了0x00。然后在在配置好DM9000之后,通过LWIP协议栈来发送数据时,上位机可以收到数据,并正常接收数据,并且是一直都能接收数据正确,但是我在接收上位机数据时,偶然能接收几个正确数据,但是之后就直接报:dm9000 rx: rx error, stop device。

      两个网卡,四条通信链路,三条是通的,我没理由怀疑自己LWIP有问题,或者DM9000寄存器配置有问题,并且这个错误是在最底层接收数据时,数据没有按照DM9000的数据格式来,第一感觉这肯定是硬件问题,但是迫于人微言轻,硬件工程师说,是软件问题。。。。。,没有办法,只能自己慢慢找证据,证明清白啦,尝试过读取各个寄存器,重新建工程,单独只让DM9000工作等各种瞎折腾。

       真相大白之夜:

       在晚上睡觉时都在冥思呀,睡不着觉呀。数据接收有问题,有问题,有问题,有问题,有问题。。。。。是不是跟通信时序有问题,但是度娘上说只有三个参数有关系我也调了,并计算过,问题不大,那其他三个呢,我一直没动,然后一直在这想呀想呀,睡着了,然后到了第二天,自己试着修改这些时间参数,尝试几次之后,苍天啊,可以了。。。。。。。。。

    总结:

           dm9000 rx: rx error, stop device,这个问题是由于FMC的时序参数设置有问题。不要太迷行网上的说明及代码,得抱着怀疑态度。

  说明:

        1.在正常初始化DM9000之后,如果你想获取各个寄存器的值,在读取很多寄存器时,最好叫一个延时,要不然很可能也会报这个错。我为了查是不是寄存器配置错了,在初始化之后,一次性打印出几十个寄存器,也出现了这个错误。

       2.LWIP协议栈支持软件和硬件来产生校验,DM9000默认选的是软件去计算和校验的,F4支持硬件产生校验。

       3.在UCOS创建任务时,任务的优先级不要和TCPIP内核任务的优先级冲突了。

 

   这是FSMC的时序配置参数: 

   ReadWriteTiming.FSMC_AddressSetupTime = 0;        //地址建立时间
    ReadWriteTiming.FSMC_AddressHoldTime = 0;
    ReadWriteTiming.FSMC_DataSetupTime = 3;        //数据建立时间
    ReadWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
    ReadWriteTiming.FSMC_CLKDivision = 0x00;
    ReadWriteTiming.FSMC_DataLatency = 0x00;
    ReadWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;//使用模式A

 

 类似资料: