arch/arm/stm32: implement PTP hardware clock driver (/dev/ptp0) - #20180
Open
daniel-p-carvalho wants to merge 6 commits into
Open
daniel-p-carvalho wants to merge 6 commits into
daniel-p-carvalho wants to merge 6 commits into
Conversation
daniel-p-carvalho
requested review from
fjpanag and
xiaoxiang781216
as code owners
September 17, 2026 20:36
acassis
previously approved these changes
Sep 17, 2026
daniel-p-carvalho
force-pushed
the
feat/stm32-ptp-posix
branch
from
September 18, 2026 01:51
24e4b0e to
ac9b7c6
Compare
xiaoxiang781216
previously approved these changes
Sep 18, 2026
jerpelea
previously approved these changes
Sep 18, 2026
Contributor
|
please fix: |
daniel-p-carvalho
dismissed stale reviews from jerpelea and xiaoxiang781216
via
September 18, 2026 11:45
a85ba40
daniel-p-carvalho
force-pushed
the
feat/stm32-ptp-posix
branch
from
September 18, 2026 11:45
ac9b7c6 to
a85ba40
Compare
xiaoxiang781216
previously approved these changes
Sep 18, 2026
daniel-p-carvalho
force-pushed
the
feat/stm32-ptp-posix
branch
from
September 18, 2026 14:06
a85ba40 to
3995fb2
Compare
Every other timer driver block in this Make.defs sets TMRDEPPATH and TMRVPATH so DEPPATH/VPATH include this directory. CONFIG_PTP_CLOCK and CONFIG_PTP_CLOCK_DUMMY were the only two missing it, leaving ptp_clock.c/ptp_clock_dummy.c unreachable via VPATH and without a generated dependency file when no other timer driver in this file is also selected. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com> (cherry picked from commit 6d38122)
stm32_receive() called pkt_input() before stm32_eth_ptp_convert_rxtime(), so every packet handed to a packet socket carried the previous frame's RX timestamp instead of its own in dev->d_rxtime. Reorder so the timestamp is converted first. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com> (cherry picked from commit 9bfa20d)
Set ETH_MACCR_ROD unconditionally when configuring the MAC. In half-duplex mode the MAC otherwise reflects every frame it transmits back to its own receiver, flooding the receive path with our own traffic right as a genuine reply arrives. The bit has no effect in full-duplex (confirmed on our hardware: fduplex=1), so setting it unconditionally is safe and changes nothing observable for boards already running full-duplex. The sibling stm32f7 driver has the same gap (ETH_MACCR_ROD cleared but never set) and stm32h7's equivalent ETH_MACCR_DO bit has the same issue; both are left out of scope here since only m3m4_v1 hardware was available to validate against. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com> (cherry picked from commit 41536cb)
xiaoxiang781216
previously approved these changes
Sep 19, 2026
The MAC hardware counter is the PTP clock reference. Delivering its raw timestamp directly (instead of synthesizing one against CLOCK_REALTIME, which starts at an arbitrary boot-time phase) lets the PTP daemon close the feedback loop and phase-lock the MAC counter - and therefore the physical PPS output - to the master. Assisted-by: Gemini:gemini-3.8-flash-medium Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Implement lower-half PTP hardware clock operations (struct ptp_lowerhalf_s and struct ptp_ops_s) in the STM32 Ethernet driver and register it with the generic PTP clock framework (drivers/timers/ptp_clock.c) to expose /dev/ptp0. Supported operations: - adjfine: adjust PTP clock frequency in parts per billion (ppb) - adjphase: adjust PTP clock phase via hardware TSSTU - adjtime: shift PTP clock time by signed delta in nanoseconds - gettime: atomic double-read of hardware timestamp registers - settime: initialize hardware timestamp counter via TSSTI - getres: return 1 ns clock resolution Also fix a sign bug in stm32_eth_ptp_adjust() where uint64_t addend promoted negative ppb adjustments to unsigned, corrupting frequency trim for crystals running faster than nominal. Follow-up to apache#20148 per review recommendation to use the standard POSIX /dev/ptp0 character driver instead of custom socket ioctls. Assisted-by: Gemini:gemini-3.8-pro Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Variable conn is declared and initialized in append_timestamping() but never referenced, triggering -Wunused-variable compiler warning. Assisted-by: Gemini:gemini-3.8-pro Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
daniel-p-carvalho
force-pushed
the
feat/stm32-ptp-posix
branch
from
September 19, 2026 14:58
3995fb2 to
ea45d16
Compare
acassis
approved these changes
Sep 19, 2026
acassis
approved these changes
Sep 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements lower-half PTP hardware clock operations (
struct ptp_lowerhalf_sandstruct ptp_ops_s) in the STM32 Ethernet driver (arch/arm/src/common/stm32/stm32_eth_m3m4_v1.c) and registers it with the generic PTP clock framework (drivers/timers/ptp_clock.c) to expose the standard POSIX character driver/dev/ptp0.Supported operations:
adjfine: adjust PTP clock frequency in parts per billion (ppb) via the addend register (PTPTSAR)adjphase: adjust PTP clock phase via hardwareTSSTUadjtime: shift PTP clock time by signed delta in nanosecondsgettime: atomic double-read of hardware timestamp counter with second rollover handlingsettime: initialize/jump hardware timestamp counter viaTSSTIgetres: report 1 ns clock resolutionIt also includes necessary fixes to support hardware PTP clock operation:
d_rxtimestampso the PTP servo can close the feedback loop against the master clock.stm32_eth_ptp_convert_rxtime()runs beforepkt_input().stm32_eth_ptp_adjust()whereuint64_t addendpromoted negative ppb adjustments to unsigned, corrupting frequency trim for crystals running fast.TMRDEPPATH/TMRVPATHfor PTP clock drivers indrivers/timers/Make.defs.ETH_MACCR_RODto disable reception of self-transmitted frames.Follow-up to #20148 per @xiaoxiang781216's review suggestion to replace custom socket ioctls (
SIOCS_PTP_ADJFREQ,SIOCS_PTP_ADJPHASE) with the standard POSIX character driver/dev/ptp0. Hardware transmit timestamping will follow in a separate PR aligned with #20161 (SO_TIMESTAMPING).Impact
Enables standard POSIX hardware clock disciplining via
clock_adjtime()on/dev/ptp0on STM32 Ethernet interfaces. Fully compatible withptpd -p /dev/ptp0.Testing
Tested on real hardware (
stm32f4discovery-ext:ethraw/ STM32F407) connected via L2 Ethernet P2P to a GNSS-referenced PTP Grandmaster (IEC/IEEE 61850-9-3 profile):Running
ptpd -2 -s -p /dev/ptp0 -B -H -P -i eth0:Phase locked to -383 ns residual error with crystal drift disciplined at -82636 ppb.