Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RTthread 网络之 8720A DP83848
发布于 2020-11-20 10:04:14 浏览:4328
订阅该版
[tocm] ##**项目背景** - 公司有个项目做UWB精准室内定位,需要用到网络通讯功能,在开始做之前我直接买了两个开发板上面的网络是 8720A 和 DP83848,我直接移植通过后,网络测试ping通正常,后期自己也参照8720A画了一个板子,正常使用。但是到了项目中后期,我测试稳定性的时候现在出现了问题,请允许我求助,分享,希望大佬们有遇到过的给予帮助,小弟在此万分感谢!!! ###**8720A** - 先上原理图和引脚设置 ![8720A原理图.png](/uploads/20201120/751d03b6c288cb5952693b4347639514.png) ![8720A引脚初始化.png](/uploads/20201120/e97107df0f49cd5b05d00c48b11092ea.png) 上面这部分直接在CubeMx中生成的。 - **配置1-自适应关闭 + 100M + 全双工** 1. 配置代码 ![8720A网络自适应100M全双工.png](/uploads/20201120/7a4e9f6a86216a3e65ff5a8971d9a034.png) 2. Hal库函数调用,这里我们只关心寄存器配置方面 ![a.png](/uploads/20201120/2fcb6b036171b233ad186aa968a3b7ae.png) ![b.png](/uploads/20201120/e79cde05535bd853704b9ab95557938b.png) ![c.png](/uploads/20201120/fd676e7f138c7f9dfa68080507104301.png) 3. 关于寄存器,这里面涉及到几个Phy芯片的寄存器,我们对照手册看一下 ![d.png](/uploads/20201120/4560fc2f1a287320d33e98ea85bd4703.png) ![bcr.png](/uploads/20201120/70b4ed1761c29e871c991fb2dc5531fc.png) ![bsr.png](/uploads/20201120/ce93056b8b6de9922307c5b361aedbbd.png) ![physr.png](/uploads/20201120/65c361458e314b982e9744f38d162331.png) ![8720寄存器bit.png](/uploads/20201120/289fb4fc4c0ea2321dbca24cdf61eafb.png) ![gg.png](/uploads/20201120/e8bbde74f599c2425c40a572b8aaf6f7.png) 4. Rtthread 后面启动一个线程时刻观测Phy状态,我们可以看到这里复位了一下,然后开启自适应,执行一次phy_linkchange,接下来通过软件定时器不停的执行. ![phylinkchange.png](/uploads/20201120/ad4afd0e216529e371f346a704809da7.png) 5. 这里面看一下这部分代码 ![phylinkchange-2.png](/uploads/20201120/ba5d69697bf88db288be9cedfbaa19cd.png) 6. 这里面的寄存器配置又换成了RTthread中的寄存器配置 ![phylinkchange-3.png](/uploads/20201120/7d732e62014da549ae0a3fe4e45cb54a.png) - **观测现象** 1. 这个时候状态寄存器,BSR(01) == 0x782D; PSR(1F)= 0 ![现象1.png](/uploads/20201120/37cdcf48021c1bdeb2635db3b738f6e7.png) 比较奇怪为什么 PSR 会等于 0 呢? 2. ping通状态,这时候可以ping通,时间比较久是因为开启了调试,但是Frame Failed ![现象2.png](/uploads/20201120/6179e6d50671c72cd432926892b7d31f.png) ![现象2-1.png](/uploads/20201120/bf8e1e49ce450c90762c6e7a136c5c39.png) 3. Debug 查看进入中断 ![现象3.png](/uploads/20201120/c64c0d1feb9423cd1eb2b7120d51287e.png) - **结论** 1. 这个时候我可以知道,开启自适应模式,芯片自适应到了 10M 半双工模式,正常触发中断,可以ping通。 - **修改** 1. 修改rtthread线程,关闭自适应功能 ![hh.png](/uploads/20201120/26d37c5913ca359932df2a0170b03ffa.png) - **观测现象** 1.这个时候状态寄存器,BSR(01) == 0x782D; PSR(1F)= 0 ![现象1-1.png](/uploads/20201120/a7e06bb5967341e82ab930168b39fc1b.png) 2. ping通状态,这时候可以ping通,时间比较久是因为开启了调试,但是Frame Failed 3. 中断正常触发 - **疑问** 1.配置修改自适应, 依旧是10M,Half ```C EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE; ``` 2.线程中屏蔽自适应,依旧是10M,Half ```C /* RESET PHY */ LOG_D("RESET PHY!"); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK); rt_thread_mdelay(2000); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK); ``` 3. PSR(1F) 读取为什么一直都是0 4. 为什么Frame Failed ## 关于DP83848 问题我追贴描述,现在要开会啦。。。
查看更多
4
个回答
默认排序
按发布时间排序
aozima
2020-11-20
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
> 开启自适应模式,芯片自适应到了 10M 半双工模式 感觉板子硬件设计没达标,建议换个开发板来验证下。 分析总结步骤不错的,赞一个。 代码标签不要用全角字符,帮你修改了一下。
Wzy2021
2021-08-04
这家伙很懒,什么也没写!
@zhujie 您好,stm32f407+lan8720使用rtt调试时也遇到10M的问题,无论自适应是否开启,网速均为10M。请问您问题解决了吗?怎么解决的呢?感谢您的回复!
zhujie
2020-11-20
这家伙很懒,什么也没写!
##DP83848 - **先上原理图** ![Dp83848原理图.png](/uploads/20201120/97921530310c4bafec896d8eb6c326b4.png) 1. 也是用的RMII接口,但是应该注意这个开发板选用的是有源晶振 2. 开发板上的Reset 引脚是和单片机 复位连接在一起的,不受我控制 - **配置代码及寄存器设置代码** 1. 配置代码同8720A 2. 寄存器配置代码这里面需要对照DataSheet看一下 ![Reg-1.png](/uploads/20201120/a76359c1732d39328e61c2affba28bf8.png) ![Reg-2.png](/uploads/20201120/2a952817eefb4cd99e4ba4df033d7634.png) ![Reg2-1.png](/uploads/20201120/2cf02deee034a25165758d0e9fc0c3d6.png) ![Reg2-2.png](/uploads/20201120/3b710cacea1349ee1b6017c5cc453f34.png) ![Reg2-3.1.png](/uploads/20201120/fa919d8b2a5a6bc99b35943dfa2ed94f.png) ![Reg2-3.2.png](/uploads/20201120/e4a8ef7e57df75dd6c34546b52ef4109.png) 3. 对应修改 Hal 中的寄存器配置位 和 drv_eth.h 中的配置位 ```C /* DP83848_PHY_ADDRESS Address*/ #define DP83848_PHY_ADDRESS 1U /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY ((uint32_t)0x00FFFFFFU) /* PHY Configuration delay */ #define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) #define PHY_READ_TO ((uint32_t)0x0000FFFFU) #define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ #define PHY_LINK_STATUS ((uint16_t)0x0001U) /*!< PHY Link mask */ #define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ ``` ```C // 为了防止寄存器配置错误,我把不使用的配置寄存器都屏蔽了 /* The PHY basic control register */ #define PHY_BASIC_CONTROL_REG 0x00U #define PHY_RESET_MASK (1<<15) #define PHY_AUTO_NEGOTIATION_MASK (1<<12) /* The PHY basic status register */ #define PHY_BASIC_STATUS_REG 0x01U #define PHY_LINKED_STATUS_MASK (1<<2) #define PHY_AUTONEGO_COMPLETE_MASK (1<<5) /* The PHY ID one register */ #define PHY_ID1_REG 0x02U ///* The PHY ID two register */ //#define PHY_ID2_REG 0x03U ///* The PHY auto-negotiate advertise register */ //#define PHY_AUTONEG_ADVERTISE_REG 0x04U #ifdef PHY_USING_DP83848C #define PHY_Status_REG 0x10U #define PHY_10M_MASK (1<<1) #define PHY_FULL_DUPLEX_MASK (1<<2) #define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK) #define PHY_Status_SPEED_100M(sr) (!PHY_Status_SPEED_10M(sr)) #define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK) /* The PHY interrupt source flag register. */ //#define PHY_INTERRUPT_FLAG_REG 0x12U //#define PHY_LINK_CHANGE_FLAG (1<<13) ///* The PHY interrupt control register. */ //#define PHY_INTERRUPT_CTRL_REG 0x11U //#define PHY_INTERRUPT_EN ((1<<0)|(1<<1)) ///* The PHY interrupt mask register. */ //#define PHY_INTERRUPT_MASK_REG 0x12U //#define PHY_INT_MASK (1<<5) #endif /* PHY_USING_DP83848C */ ``` - **修改 1** 1. 配置代码关闭自适应 ```C __HAL_RCC_ETH_CLK_ENABLE(); /* ETHERNET Configuration */ EthHandle.Instance = ETH; EthHandle.Init.MACAddr = (rt_uint8_t *)&stm32_eth_device.dev_addr[0]; EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE; EthHandle.Init.Speed = ETH_SPEED_100M; EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX; EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE; #ifdef RT_LWIP_USING_HW_CHECKSUM EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; #else EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE; #endif ``` 2. Rtthread 线程中关闭自适应 ```C static void phy_monitor_thread_entry(void *parameter) { uint8_t phy_addr = 0xFF; uint8_t detected_count = 0; while(phy_addr == 0xFF) { /* phy search */ rt_uint32_t i, temp; for (i = 0; i <= 0x1F; i++) { EthHandle.Init.PhyAddress = i; HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ID1_REG, (uint32_t *)&temp); if (temp != 0xFFFF && temp != 0x00) { phy_addr = i; break; } } detected_count++; rt_thread_mdelay(1000); if (detected_count > 10) { LOG_E("No PHY device was detected, please check hardware!"); } } LOG_D("Found a phy, address:0x%02X", phy_addr); // /* RESET PHY */ // LOG_D("RESET PHY!"); // HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK); // rt_thread_mdelay(2000); // HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK); phy_linkchange(); #ifdef PHY_USING_INTERRUPT_MODE /* configuration intterrupt pin */ rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP); rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, eth_phy_isr, (void *)"callbackargs"); rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE); /* enable phy interrupt */ HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK); #if defined(PHY_INTERRUPT_CTRL_REG) HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN); #endif #else /* PHY_USING_INTERRUPT_MODE */ stm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange, NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC); if (!stm32_eth_device.poll_link_timer || rt_timer_start(stm32_eth_device.poll_link_timer) != RT_EOK) { LOG_E("Start link change detection timer failed"); } #endif /* PHY_USING_INTERRUPT_MODE */ } ``` - **修改1-实验结果** ![结果1.png](/uploads/20201120/b18bf5617251d356d16ec170cc0e397e.png) 1. 此时可以发现 100M 半双工 2. BSR(01) = 0x786D; PHY_Status_REG(10) = 0 3. 正常触发中断 4. 可以ping通 - **修改 2 ** 1. 修改配置代码为 自适应 ```C __HAL_RCC_ETH_CLK_ENABLE(); /* ETHERNET Configuration */ EthHandle.Instance = ETH; EthHandle.Init.MACAddr = (rt_uint8_t *)&stm32_eth_device.dev_addr[0]; EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; EthHandle.Init.Speed = ETH_SPEED_100M; EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX; EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE; #ifdef RT_LWIP_USING_HW_CHECKSUM EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; #else EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE; #endif ``` 2. 开启 Rtthread 线程中的Reset 和自适应 ```C static void phy_monitor_thread_entry(void *parameter) { uint8_t phy_addr = 0xFF; uint8_t detected_count = 0; while(phy_addr == 0xFF) { /* phy search */ rt_uint32_t i, temp; for (i = 0; i <= 0x1F; i++) { EthHandle.Init.PhyAddress = i; HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ID1_REG, (uint32_t *)&temp); if (temp != 0xFFFF && temp != 0x00) { phy_addr = i; break; } } detected_count++; rt_thread_mdelay(1000); if (detected_count > 10) { LOG_E("No PHY device was detected, please check hardware!"); } } LOG_D("Found a phy, address:0x%02X", phy_addr); /* RESET PHY */ LOG_D("RESET PHY!"); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK); rt_thread_mdelay(2000); HAL_ETH_WritePHYRegister(&EthHandle, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK); phy_linkchange(); #ifdef PHY_USING_INTERRUPT_MODE /* configuration intterrupt pin */ rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP); rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, eth_phy_isr, (void *)"callbackargs"); rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE); /* enable phy interrupt */ HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK); #if defined(PHY_INTERRUPT_CTRL_REG) HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN); #endif #else /* PHY_USING_INTERRUPT_MODE */ stm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange, NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC); if (!stm32_eth_device.poll_link_timer || rt_timer_start(stm32_eth_device.poll_link_timer) != RT_EOK) { LOG_E("Start link change detection timer failed"); } #endif /* PHY_USING_INTERRUPT_MODE */ } ``` - **修改2 实验结果** ![结果2.png](/uploads/20201120/78b5b879ed6f5bad2df9395fc65869a9.png) 1. 此时可以发现 100M 半双工 2. BSR(01) = 0x786D; PHY_Status_REG(10) = 0 3. 这个时候 **无法触发中断** 4. 这个时候 **不可以ping通** - **后期修改** 1. 我思考了一下,在配置中我已经开启了自适应,后面应该就不需要了呀,我修改了,将Rtthread 线程中,的芯片复位和开启 自适应,可惜实验结果同上,不触发中断无法ping通。 2. 后面我发现只要将配置代码中的 ```C EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; ``` 修改为 ```C EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE; ``` 就可以正常触发中断,正常ping通,无论Rtthread线程中的 phy 寄存器是否配置位自适应。 # 疑问 1. 无论是 8720A 还是 83848,我再读取 PHY_Status_REG() 时为啥都是0;当然8720 寄存器地址是1F;83848 是 10; 2. 8720 无论是否开启自适应都能ping通,正常触发中断,即使是100M,可能是硬件没达标等。 3. 为啥 我的83848 配置中是否开启自适应,会影响最终的联网成功失败。 恳请 各位大佬 各位大神指点。。。。 ###测试环境 1. 计算机发送数据帧,MCU电路板回应,查看发送数与接收数看是否丢包 2. 从左至右分别是 83848 启明开发板;8720A自己画的电路板;8720A EC20Plus 开发板; 3. 测试结果表现为,83848 老是掉线;两块8720A 不掉线,不丢包 恳请 大神 大佬们指点,项目比较急,万分感谢!!!
小鳄鱼
2020-12-05
rt-thread脑残粉
帖子看完了,LAN8720 这块我也翻过车,设计上也是看的原子的原理图,当时手工焊接虚焊的问题,感觉这种以太网不稳的问题,硬件的锅居多。但是也不要放过软件的锅,先对比下网上成熟的同平台的驱动代码,然后检查下硬件,网线短一些测。
撰写答案
登录
注册新账号
关注者
1
被浏览
4.3k
关于作者
zhujie
这家伙很懒,什么也没写!
提问
27
回答
13
被采纳
2
关注TA
发私信
相关问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
如何在master上的BSP中添加配置yml文件
2
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
3
RT-Thread 发布 EtherKit开源以太网硬件!
4
rt-thread使用cherryusb实现虚拟串口
5
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部