[STM32H7] STM32H745 以太网硬件 PTP 卸载功能问题

[复制链接]
27|11
咚了个咚 发表于 2026-7-4 11:31 | 显示全部楼层 |阅读模式
想在项目中实现 PTP 精确时钟协议功能。选用 STM32H745 的原因是该芯片以太网 MAC 内置硬件 PTP 模块,支持硬件时间戳卸载。
研读参考手册后编写了如下初始化代码:
uint32_t SubSecondValue = 43;
                        #define ADJ_FREQ_BASE_ADDEND 0x35455A81
                        // Mask the Timestamp Trigger interrupt by clearing bit 12 of Interrupt enable register (ETH_MACIER).
                        heth->Instance->MACIER &= ~(ETH_MACIER_TSIE);
                        // Set bit 0 of Timestamp control Register (ETH_MACTSCR) to enable timestamping.
                        //heth->Instance->MACTSCR |= 1;                        // Done at the END! :)
                        //Program Subsecond increment register (ETH_MACSSIR) based on the PTP clock frequency.
                        heth->Instance->MACSSIR = (SubSecondValue<<16);
                        // if you use the Fine Correction method, program Timestamp addend register (ETH_MACTSAR) and set bit 5 of Timestamp control Register (ETH_MACTSCR)
                        heth->Instance->MACTSAR = ADJ_FREQ_BASE_ADDEND;
                        heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG;
                        /* Poll the Time stamp control register until bit 5 is cleared. */
                        while(ETH_GetPTPFlagStatus(heth, ETH_PTP_FLAG_TSARU) == SET);
                        /* Enable the PTP Fine Update method Fine*/
                        heth->Instance->MACTSCR |= ETH_MACTSCR_TSCFUPDT;
                        /* Program the Time stamp high update and Time stamp low update registers
                        * with the appropriate time value. */
                        /* Set the PTP Time Update High Register */
                        heth->Instance->MACSTSUR = 0;
                        /* Set the PTP Time Update Low Register with sign */
                        heth->Instance->MACSTNUR = ETH_PTP_PositiveTime | 0;
                        /* Set Time stamp control register bit 2 (Time stamp init). */
                        heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT;
                        /* Set PPS frequency to 128 Hz */
                        heth->Instance->MACPPSCR = 7;
                        // Source: RM0399 Page 3039
                        // 1. Program SNAPTYPSEL, TSMSTRENA and TSEVNTENA fields of Timestamp control Register (ETH_MACTSCR) to 0, 0, and 1 respectively.
                        heth->Instance->MACTSCR &= ~((0b00)<<16);         // Clear SNAPTYPSEL
                        heth->Instance->MACTSCR &= ~((0b0)<<15);         // Clear TSMSTRENA
                        heth->Instance->MACTSCR |= (1 << 14);                        // Set TSEVNTENA
                        // 2. Program the PTOEN bit and DN field of PTP Offload control register (ETH_MACPOCR) to enable PTP Offload feature and domain Number to match with ingress PTP Sync message and send in egress PTP Delay_Req message.
                        heth->Instance->MACPOCR &= ~((0b00000000)<<8); // Set Domain number to 0
                        heth->Instance->MACPOCR |= 4; // Set APDREQEN
                        // 3. Program the 80-bit Source Port Identity in PTP Source Port Identity 0 Register (ETH_MACSPI0R), PTP Source port identity 1 register (ETH_MACSPI1R) and PTP Source port identity 2 register (ETH_MACSPI2R) to match with ingress PTP Sync message and send in egress PTP Delay_Req message.
                        heth->Instance->MACSPI0R = 0x57ffec79;
                        heth->Instance->MACSPI1R = 0xfe81d0c8;
                        heth->Instance->MACSPI2R = 0x0001;
                        // 4. Program the DRSYNCR field in Log message interval register (ETH_MACLMIR) to indicate one PTP Delay_Req message is generated in response to how many received PTP Sync messages.
                        heth->Instance->MACLMIR |= (2<<24);
                        heth->Instance->MACPOCR |= 1; // Set PTOEN
这段代码在以太网底层初始化low_level_init函数返回前执行。
开发目标是实现 PTP 从设备,依靠硬件卸载机制自动响应主时钟的 PTP 报文、同步硬件内部时间计数器,尽量减少软件干预。
遇到的问题是Wireshark 抓包看不到 STM32 向 PTP 主时钟发出任何报文;外部专用 PTP 主时钟设备正常持续发送 SYNC、Follow Up 报文。请问代码哪里存在错误?

狄克爱老虎油 发表于 2026-7-4 18:53 | 显示全部楼层
配置ETH_MACTSCR时,记得清除TSIE位,再设置TS位。检查ETH_MACTSAR是否正确配置,特别是TSAR5位。
公羊子丹 发表于 2026-7-5 13:19 | 显示全部楼层
我先留意到你代码里MACTSCR使能时间戳那句被注释了!硬件PTP不打开全局时间戳,卸载功能根本不会触发,主钟发sync芯片也不会自动回Delay_Req,你先把这行注释取消再测抓包。
周半梅 发表于 2026-7-5 13:20 | 显示全部楼层
大概率是ETH发送DMA或者MAC发送使能没开,很多人只配PTP寄存器忘了底层MACCR的TE位,MAC发不出任何帧,Wireshark自然看不到STM32的PTP应答报文。
帛灿灿 发表于 2026-7-5 13:21 | 显示全部楼层
提醒下交换机这块坑很大,普通交换机默认屏蔽PTP组播,你可以直接把主钟和单片机直连网线测试,排除交换机组播转发拦截报文的问题。
童雨竹 发表于 2026-7-5 13:23 | 显示全部楼层
看你MACPOCR配置顺序有点怪,标准流程是先设域号、源端口ID,最后再置PTOEN位,你颠倒顺序可能寄存器写入不生效,硬件卸载直接没激活。
万图 发表于 2026-7-5 13:24 | 显示全部楼层
踩过同款坑!HAL库老版本ETH底层low_level_init有时序bug,PTP寄存器初始化放在ETH初始化前会失效,建议把这段PTP配置挪到ETH链路建立完成后执行。
Wordsworth 发表于 2026-7-5 13:25 | 显示全部楼层
好奇问下你PHY链路状态读了吗?如果网线没协商成功、link没起来,MAC接收不到主钟sync,硬件PTP卸载逻辑不会触发响应报文发送。
Bblythe 发表于 2026-7-5 13:26 | 显示全部楼层
你MACLMIR设置2代表收2个sync才回1个Delay_Req,调试阶段建议先改成1,缩短应答间隔,方便Wireshark快速抓到报文判断模块是否工作。
Pulitzer 发表于 2026-7-5 13:30 | 显示全部楼层
怀疑源端口ID三组寄存器配置不匹配主钟报文里的端口标识,硬件卸载会校验匹配才自动回复,参数对不上直接丢弃sync不生成应答帧。
Uriah 发表于 2026-7-5 13:31 | 显示全部楼层
别光盯PTP寄存器,先单独测以太网收发,随便发个ping包看抓包有没有回复,先确认ETH底层通路正常,再排查1588硬件卸载相关配置。
Clyde011 发表于 2026-7-5 13:32 | 显示全部楼层
补充个小排查技巧:调试时实时读MACPOCR、MACTSCR寄存器值,看写入的配置有没有被硬件自动清零,寄存器写不进去就是初始化时序冲突了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

165

主题

174

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0