2024 Update: This works out of the box on the Compute Module 5. See comment.
I've been following the issue CM4 is missing IEEE1588-2008 support through BCM54210PE since I heard about IEEE1588-2008 support on the Compute Module 4 last year.
Apparently the little NIC included on every Compute Module 4—the BCM54210PE
, which is different than the NIC on the Pi 4 model B (a BCM54213PE
)—includes support for a feature called PTP, or Precision Time Protocol.
Update: I also posted a video about PTP on the CM4 on my YouTube channel: It's About Time (PTP on the Raspberry Pi CM4).
If you thought NTP was great, with its millisecond-level accuracy when synchronizing clocks over a network, you'll love PTP—it can sync down to nanoseconds, or in some cases even picoseconds!
PTP is more prevalent in HFT (High Frequency Trading) in finance, scientific research, and distributed databases that need highly accurate timings.
But with a tiny Compute Module 4 able to control hardware timestamps—plus the plethora of available high-quality GPS HATs for the Pi—maybe highly-accurate time could be more democratized!
Getting PTP and PPS
The Compute Module 4 IO Board comes with two pins (8 and 9 on J2) labeled SYNC_IN and SYNC_OUT. Those pins are supposedly wired to the PHY with 1.8v signalling (see the CM4 datasheet)—but through a bunch of experimentation, it seems only pin 9 is wired correctly.
So on the Compute Module 4, you can get a PPS input or output through pin 9, but not both at the same time—at least when using the official CM4 IO Board.
The PPS is helpful for debug purposes, and if you need to distribute a PPS to any equipment that uses a PPS input for time sync. Otherwise, PTP is useful for synchronizing time over the Pi's Ethernet connection to any 'slave' devices on the same network.
I'll have more on this in an upcoming video, but I wanted to post instructions for how to set up a CM4 as a PTP master / time server.
Patches were only recently added to the Pi OS kernel fork, for example:
And the same patchset is already upstream in later versions of the Linux kernel (yay!). But to get these running on a Pi today, you need to run sudo rpi-update
to get the latest kernel version (which is not yet installed when running sudo apt upgrade
).
Once you do that and reboot, you should see a new ptp
device:
$ ls /dev/ptp*
/dev/ptp0
$ cat /sys/class/ptp/ptp0/clock_name
bcm_phy_ptp
And then you should see its hardware timestamping capabilities listed using ethtool
:
$ ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
hardware-transmit
hardware-receive
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
onestep-sync
onestep-p2p
Hardware Receive Filter Modes:
none
ptpv2-event
And for a final test, assuming you have an oscilloscope hooked to pin 9 and a ground pin, you can enable PPS output and monitor it on a scope:
$ sudo ./testptp -d /dev/ptp0 -L0,2
set pin function okay
$ sudo ./testptp -d /dev/ptp0 -p 1000000000
periodic output request okay
What's next?
Well, remember the open source Time Card I mentioned last year? Well, using it—or something similar, with GPS and a better oscillator, like temperature-controlled oscillator (TCXO) or a chip-scale atomic clock, you could build a very competent (and relatively inexpensive) master clock / stratum-1 time server for both PTP and NTP.
This can be useful for the aforementioned database, HFT, and scientific projects... but it could also bring better timings to other applications as well. Programming changes a bit when you can guarantee you're within nanoseconds of UTC—assuming you have a good GPS chip and decent time holdover for GPS dropouts.
On two Compute Module 4s, using ptp4l
, I'm able to sync two Compute Module 4's on a LAN to within about 10-15 nanoseconds of each other (that's a 10ns/division time scale in the above picture).
The commands I ran to set up and test PTP were:
# Run this on the 'master' Pi:
sudo ptp4l -i eth0 --masterOnly 1 -m --tx_timestamp_timeout 200
# Run this on any 'slave' Pis:
sudo ptp4l -i eth0 --slaveOnly 1 -m --tx_timestamp_timeout 200
Thanks especially to Ahmad Byagowi and his team over at Meta spearheading the Time Appliances Project, and to Lasse Johnsen at Timebeat for their help in getting this moving. It seemed like things were stuck for a while, but they were able to work with engineers at Raspberry Pi and Broadcom to get the necessary patches written and tested!
I'll cover more on PTP/IEEE1588 and PPS on the CM4 in my upcoming video on my YouTube channel, so subscribe if you want to see that. I will also continue to publish my findings with the Time Card in this GitHub issue.
Comments
Is there any trick to get "testptp"?
Followed the instructions, but testptp cant be found.
If it cannot be found you can just find it in a kernel source tree for your particular distribution and compile it using make.
https://github.com/torvalds/linux/blob/master/tools/testing/selftests/p…
gcc testptp.c -o testptp
Thank you for the link! Just in case somebody runs into the same problems as me, it seems that the latest version does not compile readily anymore (error: 'PTP_MASK_CLEAR_ALL' undeclared), however if you go one commit back, it still does. Try the following link.
https://github.com/torvalds/linux/blob/3cf119ad5dc2b5c11385106d6d0ba86f…
Is anyone aware of other single board computers that support IEEE-1588? While I’d love to use a CM4, I’m not willing to pay a scalper and supply doesn’t seem to get any better (as of early 2023).
Unfortunately none of the other SBCs I've used do, though many will work with the PTP support built into a PCIe card like one of Intel's NICs.
As far as i know, BeagleBone Black and BeagleBoneAI64 support PTP
Any recommendations for a low/moderate cost 8 port switch that supports IEEE 1588 hardware time stamping? Is hardware time stamping part of AVB (Audio Video Bridging)?
I am trying to set up a PTP lab using the TimeBeat CM4 GPS module. My understanding is that a subnet of PTP servers requires hardware time stamping to get ultra precise time synchronization.
This is part of a project to use a CM4 to provide all of the network infrastructure services like PTP, DHCP, DNS and IGMP required for the new SMPTE ST 2110 media over IP suite of protocols using ansible and docker.
PS, my TimeBeat CM4 GPS module arrived yesterday. Yea!!!
PPS, SMPTE, Society of Motion Picture and Television Engineers.
I just bought the IES3110-8TF from FS. The cheaper one with 1GbE uplink is backordered.
Dear Jeff
Exceptional work. I would like to thank you and all the contributing people for the development of the driver set. I would like report a case which you might find interesting. While the case you outlined works for 64-bit OS, it does not for 32-bit OS. In case of 32-bit OS,
all the test results are fine including "ethtool -T eth0". However when we use ptp4l in master and slave form, both sides give errors. Master side gives "sync failed", "time-out while polling", "Faulty to listening" errors. Slave side gives HWTSTAMP error. It seems that there is a driver problem in 32-bit OS (bullseye, Debian:11, Kernel:5.15).
Yeah, thats because we prepared the driver based on the 64-bit OS. We can look into the 32-bit OS if you have a serious use case for it
32-bit OS is used by many already and migration to 64-bit is not straightforward since there is no guarantee for any smooth transition or performance. It would be good if we have the same functionality in 32-bit OS if there is no loss in time accuracy.
Hi Jeff - great work on this topic! I've found SYNC_OUT to be operating at 3.3V as opposed to the 1.8V levels advertised in the CM4 datasheet. Have you found the same? I tested this simply by running the testptp program as you showed above to generate a PPS signal. I also measured a 4 microsecond pulse. Do you know if SYNC_OUT can tolerate 3.3V when configured as an input? Thanks!
Honestly I forget... I'd have to check the range on my recorded footage of the scope.
Weird but I got 2V out of one module and 3.3V out of another! Both connected to Raspberry Pi Compute Module 4 IO Boards
When running
sudo ./testptp -d /dev/ptp0 -p 1000000000
I continuously get the error that: "clock_gettime: Connection timed out" Does anyone know why this is happening or what it means? It seems to be random when it says periodic output function okay. I am not sure what is going on and any feedback would be helpful!I am also getting the same error Olivia. I am attempting to solve this as well.
When running testptp.c, I query for ptp clock time (sudo ./testptp -d /dev/ptp0 -g) and the output says "clock_gettime: Connection timed out". Do I need to hook up my CM4 to a network in order to get a time reference? Currently, I do not have wifi nor any ethernet connection which allows the CM4 to be hooked up to the internet/network.
Hi,
thanks for this tutorial! I am currently experimenting with the Compute Module.
The PTP capability is great. However I wonder how I can use the SYNC_IN signal. According to the schematics of the Compute Module IO Board, the SYNC_IN pin is definitely connected to the Raspberry Pi connector.
I have a GPS Module that provides 1PPS signals, so it would make a lot of sense to connect the GPS module to SYNC_IN! But when I do that, how can I tell ptp4l to use the 1PPS signal from SYNC_IN?
"but through a bunch of experimentation, it seems only pin 9 is wired correctly". My measurements show that this is right no matter what the schematics show. I have a timebeat module and with a) the CM4 disconnected, b) dip switch 1-3on, I should be able to see the pin 8 of IO board's J2, connected to pin 6 of timebeat's IC1. This isn't the case. Out of a few minutes of search I can't find many mentions of this fact. Just the sad news that CM5 won't have any SYNC pins because they use smaller package for the Ethernet interface
I just ordered my Raspberry Pi CM5 Development Kit. I read that it has the same Phy (BCM54213PE). Could i assume that i can use this methodology out of the box for Raspberry Pi CM5 as well?
Yes, should work the same! I just checked on my CM5, and I don't have to update anything—the latest OS version works like this:
And testing with
testptp
:Hi! I couldn't find testptp so I cloned it from the git repo and build it with make. Then after running the testptp command in the CM4 configured as slave and having my osciloscope connected to pin 9 I can't see any signal, even though the testptp output says "set pin function okay" and "periodic output request okay". Any idea what I may be missing?
The pin might be configured as an input rather than output... I would need to grab out my IO board and do some testing, but check on GitHub or on Pi Forums for more docs on it!