Hello everyone,
I am pretty new to this, so I'll try to provide as much info as possible. We are using an i.MX8M Mini based board (the Nitrogen8mm) and we are looking into time synchronization using a combination of NTP and PTP.
Essentially, we need to input a PPS signal to discipline the system time and get a PPS output signal so that we can use it to synchronize other components. These two signals must be highly synchronized, which is why we want to make use of the PTP ports. According to the Reference Manual, the I2C2_SCL and I2C2_SDA can be set for ENET1_1588_EVENT1_IN and ENET1_1588_EVENT1_OUT respectively.
We currently have managed to get the output PPS signal by adding the following lines in the FEC pinctrl of the device tree and disabling all other I2C2 declarations.
MX8MM_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT 0x00000116
MX8MM_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN 0x00000136
Also, in the fec_ptp.c driver, we modified the FEC Channel to 1, since the hardcoded value only allowed output in the EVENT0_OUT pin.
#define FEC_CHANNLE_0 1
#define DEFAULT_PPS_CHANNEL FEC_CHANNLE_0
Now I'm attempting to get the input and output signal to be synchronized. I tried testing the input signal by using the testptp tool, however, when running the command below to set up PPS input, I get the error PTP_PIN_SETFUNC: Invalid argument.
testptp -d /dev/ptp0 -L 0,1
Likewise, when probing with the command below, I get the error PTP_EXTTS_REQUEST: Invalid argument.
testptp -d /dev/ptp0 -e 1000
Furthermore, using ethtool and testptp for getting the device capabilities I get the following results.
Time stamping parameters for end0:
Capabilities:
hardware-transmit
software-transmit
hardware-receive
software-receive
software-system-clock
hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off
on
Hardware Receive Filter Modes:
none
all
capabilities:
250000000 maximum frequency adjustment (ppb)
0 programmable alarms
0 external time stamp channels
1 programmable periodic signals
1 pulse per second
0 programmable pins
0 cross timestamping
0 adjust_phase
0 maximum phase adjustment (ns)
From what I've been able to gather, this is a reference to something in the kernel's ptp driver going wrong. Some more research pointed out that the culprit may be the fec_ptp.c driver. There seems to be no implementation of a PPS input event, only PPS out, and that may be causing a conflict between the PTP kernel driver and the Ethernet controller PTP driver.
So my question is, are there any missing pieces I have not considered? Is the driver not compatible with the tools and is doing synchronization of the signals under the hood?
Thank you in advance for any info and advice you can give!
Hello,
You can refer pdf and patch in this knowledge base as they have similiar ethernet IP
https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX8-serials-IEEE1588-1pps-test-procedu...
Best Regards,
Zhiming
Just to further the discussion, I saw a recent thread in the kernel's mailing list (Re: [PATCH v1 4/4] arm64: dts: imx8-ss-conn: add PPS channel to the FEC nodes - Frank Li). In here it is mentioned that there is a situation with the routing at the SoC level that only allows to use one of the channels for PPS in the i.MX8X.
With this being the case, is there a similar situation in the i.MX8 M Mini?
To clarify, I have been able to produce pulses in both EVENT0_OUT and EVENT1_OUT, but I would like confirmation that using either one of these channels as an output (or potentially as an input) does not affect the SoC internally.
Thank you.
Hello,
Since the 8mm and 8mp are similar in many internal design aspects, including the pps here, I used the 8mp to verify this. I have finished the ptp test based on i.MX8MP EVK , due to EVK limitation, we can easily test ptp on i.MX8MP EVK. I am using EVENT0_IN , EVENT0_OUT , /dev/ptp0 and eth0(fec).
Here are steps:
gPTP.cfg
[global]
gmCapable 1
priority1 246
priority2 248
logAnnounceInterval 0
logSyncInterval -3
syncReceiptTimeout 3
neighborPropDelayThresh 800
min_neighbor_prop_delay -20000000
assume_two_step 1
path_trace_enabled 1
follow_up_info 1
transportSpecific 0x1
ptp_dst_mac 01:80:C2:00:00:0E
network_transport L2
delay_mechanism P2P
step_threshold 0.00002
Master setup steps, set the correct time with timedatectl and phc_ctl, otherwise the phc2sys can't set the CLOCK_REALTIME.
timedatectl set-ntp false
timedatectl set-time "2024-12-12 10:36:00“
hwclock --systohc
phc_ctl /dev/ptp0 set
phc_ctl /dev/ptp0 get
vi gPTP.cfg
sed -i 's/priority1.*248/priority1\t\t246/g' ./gPTP.cfg
ptp4l -i eth0 -p /dev/ptp0 -f ./gPTP.cfg -m > /var/log/ptp4l.log 2>&1 &
phc2sys -s eth0 -O 0 -S 0.00002 -m > /var/log/phc2sys.log 2>&1 &
Slave
timedatectl set-ntp false
vi gPTP.cfg
ptp4l -i eth0 -p /dev/ptp0 -f ./gPTP.cfg -m > /var/log/ptp4l.log 2>&1 &
phc2sys -s eth0 -O 0 -S 0.00002 -m > /var/log/phc2sys.log 2>&1 &
hwstamp_ctl -i eth0 -r 1
tail -f /var/log/ptp4l.log
tail -f /var/log/phc2sys.log
The slave can sync time with master and output pps signal at same time.
Results:
/* SALVE 1 pps output*/
Best Regards,
Zhiming
Hello Zhiming,
Thank you for getting back to me. I have tried reproducing as closely as possible your tests, however got different results. Sorry if I'm misunderstanding, but the test that you propose consists of the following:
Doing this will have a PPS output through EVENT0_OUT whose pulses will match with physical seconds and time coming from PTP.
In my current setup there is no PTP grandmaster, at least at this moment. I have a GNSS receiver with a PPS output. We intend to use this PPS output to connect to EVENT1_IN so that it disciplines the physical clock by using ts2phc, making the PPS coming from EVENT1_OUT to be synchronized.
Could you help me clear out if the test you propose is using the EVENT0_IN to get a generic input PPS and you are synchronizing the PPS output?
---
Here are my results from the test.
I have used EVENT1 since my board does not have physical access to EVENT0_IN, other than that I have used the same configuration values for gPTP.cfg.
Running ptp4l and phc2sys after setting up datetime.
Output of phc2sys.log
/var/log/phc2sys.log
root@nitrogen8mm:/etc# tail -f /var/log/ptp4l.log
ptp4l[415.279]: selected /dev/ptp0 as PTP clock
ptp4l[415.332]: port 1 (end0): INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[415.333]: port 0 (/var/run/ptp4l): INITIALIZING to LISTENING on INIT_COMPL ETE
ptp4l[415.333]: port 0 (/var/run/ptp4lro): INITIALIZING to LISTENING on INIT_COM PLETE
ptp4l[418.812]: port 1 (end0): LISTENING to MASTER on ANNOUNCE_RECEIPT_TIMEOUT_E XPIRES
ptp4l[418.813]: selected local clock 0019b8.fffe.103cbc as best master
ptp4l[418.813]: port 1 (end0): assuming the grand master role
EOF
Extract of output from phc2sys.log:
root@nitrogen8mm:/etc# tail -f /var/log/phc2sys.log
phc2sys[499.316]: CLOCK_REALTIME phc offset -16307 s2 freq -16308 delay 17 50
phc2sys[500.317]: CLOCK_REALTIME phc offset 6 s2 freq -4887 delay 17 50
phc2sys[501.317]: CLOCK_REALTIME phc offset 4926 s2 freq +35 delay 17 50
phc2sys[502.318]: CLOCK_REALTIME phc offset 4877 s2 freq +1464 delay 17 50
phc2sys[503.319]: CLOCK_REALTIME phc offset 3372 s2 freq +1422 delay 17 50
phc2sys[504.319]: CLOCK_REALTIME phc offset 1985 s2 freq +1046 delay 17 50
phc2sys[505.320]: CLOCK_REALTIME phc offset 938 s2 freq +595 delay 17 50
phc2sys[506.320]: CLOCK_REALTIME phc offset 367 s2 freq +305 delay 17 50
phc2sys[507.321]: CLOCK_REALTIME phc offset 42 s2 freq +90 delay 17 50
phc2sys[508.322]: CLOCK_REALTIME phc offset -68 s2 freq -7 delay 17 50
phc2sys[509.322]: CLOCK_REALTIME phc offset -51 s2 freq -10 delay 17 50
phc2sys[510.323]: CLOCK_REALTIME phc offset -41 s2 freq -16 delay 17 50
phc2sys[511.324]: CLOCK_REALTIME phc offset -20 s2 freq -7 delay 17 50
phc2sys[512.324]: CLOCK_REALTIME phc offset -28 s2 freq -21 delay 17 50
phc2sys[513.325]: CLOCK_REALTIME phc offset -7 s2 freq -8 delay 17 50
phc2sys[514.325]: CLOCK_REALTIME phc offset -19 s2 freq -23 delay 17 50
phc2sys[515.326]: CLOCK_REALTIME phc offset 9 s2 freq -0 delay 17 50
phc2sys[516.327]: CLOCK_REALTIME phc offset 29 s2 freq +22 delay 17 50
phc2sys[517.327]: CLOCK_REALTIME phc offset -18 s2 freq -16 delay 17 50
phc2sys[518.328]: CLOCK_REALTIME phc offset 8 s2 freq +5 delay 17 50
phc2sys[519.328]: CLOCK_REALTIME phc offset 8 s2 freq +7 delay 17 50
phc2sys[520.329]: CLOCK_REALTIME phc offset 16 s2 freq +18 delay 17 50
phc2sys[521.330]: CLOCK_REALTIME phc offset -32 s2 freq -26 delay 17 50
I assume my log from ptp4l is not getting populated because I am not connected to a GM who is serving me time through the network. My PPS output is produced normally from EVENT1_OUT, however I am unable to change the period of the signal.
Thanks,
Hello,
Here's the testing we've been able to accomplish on our end so far, based on two EVKs. The test is based on below diagram.
The original test steps are based on eth1 and /dev/ptp1, using EVENT0_IN to synchronize the system time to match the PHC clock, not use EVENT0_IN on EVK B to synchronize the EVENT0_OUT on EVK B.
At least from current log you shared, you can synchronize pps from GNSS and system time, but can't synchronize pps from GNSS and EVENT1_OUT.
Can you share your ts2phc command and CONFIGURATION FILE?
Best Regards,
Zhiming
Hi Zhiming,
Thank you for clarifying about your setup. To be on the same page, I have also included a diagram of my setup.
This is where the issues start. The basic ts2phc command with default configuration
ts2phc -c /dev/ptp0 -s generic
Provides the error:
failed to initialize PPS sinks
According to the documentation, the -c option selects the clock I'm attempting to sync, while -s just points to a generic PPS signal that will be used for synchronization with no ToD data.
Then, applying the following configuration and command:
[global]
first_step_threshold 0.0
free_running 1
[end0]
ts2phc.channel 1
ts2phc.extts_correction 0
ts2phc.extts_polarity rising
ts2phc.master 0
ts2phc.pin_index 1
EOF
ts2phc -c /dev/ptp0 -s generic -f /tsconfig.cfg
Running this command yields the following error:
failed to initialize PPS sinks[ 1023.242923] kauditd_printk_skb: 75 callbacks suppressed
free(): double free detected in[ 1023.242934] audit: type=1701 audit(1734128410.948:30): auid=4294967295 uid=0 gid=0 ses=4294967295 subj=unconfined pid=500 comm="ts2phc" exe="/usr/sbin/ts2phc" sig=6 res=1
I changed the channel and pin_index to 1 to accommodate for the changes of the channel I made in the fec_ptp.c driver, as mentioned in the original post.
---
To answer your other question, yes. There is an error when changing the period.
root@nitrogen8mm:/etc# phc_ctl /dev/ptp0 get
phc_ctl[1609.888]: clock time is 1596.147362420 or Thu Jan 1 00:26:36 1970
root@nitrogen8mm:/etc# echo "0 2000 0 1 1" > /sys/class/ptp/ptp0/period
-sh: echo: write error: Operation not supported
When using testptp
testptp -d /dev/ptp0 -p 1000000000
PTP_PEROUT_REQUEST: Operation not supported
This operation is successful when using channel 0.
Thanks
Hello,
The same operation is also not supported on channel0, and further research revealed that this is a driver-level limitation and there is no corresponding function to handle ts2phc requests. There is no programmable pins in driver. In addition, we did not tested the application of ts2phc. If you search ptp_perout_request in kernel, you will find that some external PHY could support that feature, but at least it can't be supported on EVK board.
Best Regards,
Zhiming
Hello,
Let me build similiar test environment and then give you an update.
Best Regards,
Zhiming
Hi Zhiming,
Thank you for the reference. I initially consulted the test procedure you suggested and it was helpful for obtaining a PPS output, however, my current issue is enabling the PPS input, since I want to synchronize the PHC so that the output pulse is synced to an incoming PPS.
Would you happen to have any information on this?