The IEEE 1588 standard is known as the Precision Clock Synchronization Protocol for Networked Measurement Control Systems, also known as Precision Time Protocol (PTP). The IEEE 1588 PTP enables clocks to be distributed across an Ethernet network and accurately synchronized using a process where the distributed nodes exchange timestamped messages.

PTP system configuration

Linux PTP implemenation provides some tools to carry out time synchronization:

  • ptp4l: daemon that synchronizes the PTP Hardware Clock (PHC) from the NIC

  • phc2sys: daemon that synchronizes the PHC and the system clock

  • pmc: utility tool to configure ptp4l in run-time

Include these tools in your project with the following change to your conf/local.conf file:

conf/local.conf
IMAGE_INSTALL:append = " linuxptp"
Note the required white space when appending a value to an array variable using the :append override syntax.

Rebuild the project and install the new rootfs on the target.

Kernel configuration

You can enable PTP support through the following kernel configuration.

  • PTP 1588 Clock (CONFIG_PTP_1588_CLOCK)

  • Support for driver to use 1588 PTP framework (CONFIG_PTP_1588_CLOCK_OPTIONAL)

  • PPS (Pulse Per Second) high-precision time reference (CONFIG_PPS)

These options are enabled as built-in on the default ConnectCore MP15 kernel configuration file.

Device tree configuration to generate PPS signal

You can configure your Ethernet controller to generate a pulse-per-second (PPS) signal to synchronize other peripherals.

Check the ConnectCore MP15 Hardware Reference Manual for the pads that multiplex the Ethernet PPS signal.

The following example enables the PPS signal of eth0 interface using pad PG8. On the ConnectCore MP15 Development Kit, this pad is already used by usart3, so this interface must be disabled. To enable the PPS functionality, add the pad to the associated Ethernet node pinctrl.

STM32MP15 device tree
&usart3 {
        pinctrl-names = "default", "sleep", "idle";
        pinctrl-0 = <&ccmp15_usart3_pins>;
        pinctrl-1 = <&ccmp15_usart3_sleep_pins>;
        pinctrl-2 = <&ccmp15_usart3_idle_pins>;
        uart-has-rtscts;
-	status = "okay";
+       status = "disabled";
};

&pinctrl {
	ccmp15_ethernet0_rgmii_pins: rgmii-1 {
                pins1 {
                                 pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
				 ....
                                 <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
                                 <STM32_PINMUX('C', 1, AF11)>, /* ETH_MDC */
+                                <STM32_PINMUX('G', 8, AF11)>; /* ETH_PPS_OUT */
                 };
        };
	ccmp15_ethernet0_rgmii_sleep_pins: rgmii-sleep-1 {
                pins1 {
                        pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
				 ....
                                 <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
                                 <STM32_PINMUX('A', 7, ANALOG)>, /* ETH_RGMII_RX_CTL */
+                                <STM32_PINMUX('G', 8, ANALOG)>; /* ETH_PPS_OUT */
                 };
        };
};

The PPS pin is accessible on connector J37-5 of the ConnectCore MP15 Development Kit.

Rebuild the device tree and deploy it to the target.

PTP testing

Once the target has been updated with the changes and booted successfully, test the local signal.

Use the following commands on the target to verify the PTP:

  • Test the time synchronization between devices on a local network:

    # ptp4l -i eth0 -p /dev/ptp0 -m -2 &
    The command must be executed on each device on the network.

    For more configuration options, type the application name with no parameter.

  • Enable the PPS at a duty cycle of around 50%:

    # echo "0 0 0 1 1" > /sys/class/ptp/ptp0/period

    The syntax of the period configuration is as follows.

    # echo <idx> <ts> <tns> <ps> <pns> > /sys/class/ptp/ptpX/period

    Where:

  • idx is the channel index

  • ts is the start time in seconds (adds up with tsn)

  • tsn is the start time in nanoseconds (adds up with ts)

  • ps is the period time in seconds (adds up with psn)

  • pns is the period time in nanoseconds (adds up with ps)

  • To disable the PPS signal, set all values to zero:

    # echo "0 0 0 0 0" > /sys/class/ptp/ptp0/period