This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SK-AM62: High precission PPS input

Part Number: SK-AM62

I have successfully been able to implement a PTP pps out and a pps-gpio based PPS input on a SK-AM62.

If I am not mistaken, a GPIO based PPS has a certain level of inaccuracy due to the time the kernel needs to get to the point where ti timestamps the event.

I believe this can be improved with specific hardware support, and I think the SK-AM62 might have what's needed to do something like this.

I guess I have to somehow use CP_GEMAC_CPTS0_HW1TSPUSH, but I don't know exactly how.

Has anyone done anything like this before in this or any similar platform? Can someone help me understand what I should do to make this happen?

  • Hello Xabier,

    The time sync router configuration that you have already looked at in the previous e2e post is the hardware side of the problem. You'll want to route a hardware signal to come from CP_GEMAC_CPTS0_HW1TSPUSH or CP_GEMAC_CPTS0_HW2TSPUSH, through the time sync router, to one of the CPTS cpts_hwX_push inputs. That way the CPTS can accurately timestamp when the PPS signal arrives (after accounting for the several nanoseconds it takes for the signal to travel from the combinational logic from the pin to the CPTS input).

    From a software standpoint, I am not aware of TI giving an example of CPTS timestamping to be a PPS time receiver instead of a time sender. Some of the documentation links at the bottom of the SDK's PTP documentation look like they may be useful: https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/08_06_00_42/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Network/CPSW-PTP.html#introduction

    For future readers: once AM62x SDK 9.0 is released within the next couple of weeks, please reference the SDK 9.0 version of the docs, NOT the SDK 8.6 version of the docs. We are updating the PPS documentation to be more useful.

    particularly the Linux PPS stuff: https://github.com/redlab-i/pps-tools
    https://docs.kernel.org/driver-api/pps.html

    I will check with some of my team members to see if any of them are aware of specific examples.

    Regards,

    Nick

  • Actually, let me just post the updated documentation here since it might be useful:

    "

    Time stamping external events

    External events can be timestamped by the CPTS module. The CPTS module loads a hardware timestamp
    event to the Event FIFO, whenever the HWx_TS_PUSH inputs are set. Thus, it is possible to
    timestamp events by using the HWx_TS_PUSH inputs to the CPTS module.

    The following example illustrates the process of timestamping an external event. The external
    event in the example corresponds to the rising edge of GENF0 (Timestamp Generator Function).
    This involves using the output of CPSWxG CPTS GENF0 as an input to one of the HWx_TS_PUSH inputs.

    The process of routing the CPSWxG CPTS GENF0 output to any of the HWx_TS_PUSH inputs is achieved
    through the Time Sync Router. The procedure to route the CPSWxG CPTS GENF0 output to HW4_TS_PUSH
    input for example, involves modifying the device-tree node of the Time Sync Router, to map the
    CPWSxG CPTS GENF0 output to HW4_TS_PUSH input.

    The following block shows the Time Sync Router device-tree node with the mapping from CPSWxG CPTS
    GENF0 to HW4_TS_PUSH added.

    #define TS_OFFSET(pa, val) (0x4+(pa)*4) (0x10000 | val)
    &timesync_router {
    pinctrl-names = "default";
    pinctrl-0 = <&cpsw_cpts>;

    /* Example of the timesync routing */
    cpsw_cpts: cpsw-cpts {
    pinctrl-single,pins = <
    /* pps [cpsw cpts genf0] in16 -> out13 [cpsw cpts hw4_push] */
    TS_OFFSET(13, 16)
    >;
    };
    };

    Similar approach can be used for routing the outputs of other timestamp generator functions (GENFy)
    as inputs to other Hardware Timestamping push inputs (HWx_TS_PUSH).

    The Input Sources and their indices, along with the Output Destinations and their indices for the
    Time Sync Router are obtained from the documentation as mentioned below.

    The Input Sources for the Time Sync Router are documented at:

    `Time Sync Router Input Sources for AM62X <software-dl.ti.com/.../interrupt_cfg.html

    The Output Destinations for the Time Sync Router are documented at:

    `Time Sync Router Output Destinations for AM62X <software-dl.ti.com/.../interrupt_cfg.html

    To test that the timestamping feature works with the above changes, execute the following

    # testptp -d /dev/ptpN -p 500000000 -i 0

    # testptp -d /dev/ptpN -e 5 -i 3
    event index 2 at 384.250000025
    event index 2 at 384.750000025
    event index 2 at 385.250000025
    event index 2 at 385.750000025
    event index 2 at 386.250000025

    The first command is used to specify that /dev/ptpN has to be used as the clock, with the output
    period ('p') being 500000000 nanoseconds (500 milliseconds) and the event index 'i' being 0
    (corresponding to GENF0).

    The second command is used to specify that /dev/ptpN has to be used as the clock, with the first
    5 events to be output ('e') , corresponding to the event index 3 ('i'). Event index starts from

    0, due to which, the 3 here corresponds to HW4_TS_PUSH.

    PPS Pulse Per Second support

    The PPS support for |__PART_FAMILY_DEVICE_NAMES__| can be enabled with the following steps:

    1. Route the output of the CPSWxG CPTS timestamp generator function (GENFy) to one of the
    CPSWxG CPTS timestamp generator inputs (HWx_TS_PUSH) using the Time Sync Router, by
    modifying the device-tree node corresponding to the Time Sync Router:

    For example, route CPSWxG CPTS GENF1 output to HW3_TS_PUSH input

    #define TS_OFFSET(pa, val) (0x4+(pa)*4) (0x10000 | val)

    &timesync_router {
    pinctrl-names = "default";

    /* Example of timesync routing */
    cpsw_cpts: cpsw-cpts {
    pinctrl-single,pins = <
    /* pps [cpsw cpts genf1] in17 -> out12 [cpsw cpts hw3_push] */
    TS_OFFSET(12, 17)
    >;
    };
    };

    .. ifconfig:: CONFIG_part_variant in ('AM64X')

    ::

    #define TS_OFFSET(pa, val) (0x4+(pa)*4) (0x10000 | val)
    &timesync_router {
    pinctrl-names = "default";
    pinctrl-0 = <&cpsw_cpts>;

    /* Example of timesync routing */
    cpsw_cpts: cpsw-cpts {
    pinctrl-single,pins =
    /* pps [cpsw cpts genf1] in22 -> out32 [cpsw cpts hw3_push] */
    TS_OFFSET(32, 22)
    >;
    };
    };

    2. Inform the mapping to the CPSWxG driver, by using the "ti,pps" device-tree property
    in the cpts device-tree node present within the CPSWxG device-tree node:

    ::

    &cpswx {
    cpts@3d000 {
    ti,pps = ;
    };
    };

    The property "ti,pps" is of the form , where x and y correspond to the choice of
    HWx_TS_PUSH and GENFy.

    PPS can now be tested using testptp and ppstest tools::

    # ./testptp -d /dev/ptpX -P 1
    pps for system time request okay
    # ./ppstest /dev/pps0
    trying PPS source "/dev/pps0"
    found PPS source "/dev/pps0"
    ok, found 1 source(s), now start fetching data...
    source 0 - assert 198.000000700, sequence: 7 - clear 0.000000000, sequence: 0
    source 0 - assert 199.000000700, sequence: 8 - clear 0.000000000, sequence: 0

    "

  • Hello Nick,

    After an unexpected detour, I'm back working on this. Thank you very much for the provided documentation. I'm still going over it and trying to understand everything, but I'm struggling a little bit.

    There are various thing I'm not sure I see clearly. Let's start with the ones that are easier for me to explain.

    First, and most important: I have been trying to locate the TIMESYNC_EVENT_ROUTER0 indexes for CP_GEMAC_CPTS0_HW1TSPUSH and CP_GEMAC_CPTS0_HW2TSPUSH, and I have been unable to locate them. This means I can't use them in the timesync_router devicetree node. I can see the 8  cpts_hwX_push nodes, but not the CP_GEMAC_CPTS0_HWxTSPUSH nodes.

    I have been searching for those indexes herehere and here

    I guess we need them to do something simmilar to what we did with the SYNC1_OUT node for the PPS out:

    /* pps [cpsw cpts genf1] in17 -> out21 [cpsw cpts SYNC1_OUT] */
    K3_TS_OFFSET(21, 17)
    /* pps [cpsw cpts genf1] in17 -> outXX [cpsw cpts CP_GEMAC_CPTS0_HW1TSPUSH] */
    K3_TS_OFFSET(XX,17)

    Is there somewhere we can find those indexes?

    Moving on, from your last shared documentation extract:

    2. Inform the mapping to the CPSWxG driver, by using the "ti,pps" device-tree property
    in the cpts device-tree node present within the CPSWxG device-tree node:

    ::

    &cpswx {
    cpts@3d000 {
    ti,pps = ;
    };
    };

    The property "ti,pps" is of the form , where x and y correspond to the choice of
    HWx_TS_PUSH and GENFy.

    the example line "ti,pps = ;" is missing something after the "=", isn't it?

    Also, this sentence is hard for me to understand:

    The property "ti,pps" is of the form , where x and y correspond to the choice of
    HWx_TS_PUSH and GENFy.

    Is there also something missing around the "form , where" ?

    Also, in more generic architecture aspects, I'm not sure I understand how this is meant to work. I have been looking at the driver (am65-cpts.c), and it looks to me like there can only be one ti,pps instance per system. Does this mean that a single /dev/pps0 -like device can handle both the PPS out and a PPS in at the same time?

  • Hello Xabier,

    I am going to have to give a short answer today. Feel free to ask followup questions.

    Updated SDK docs are here: https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/09_00_00_03/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Network/CPSW-PTP.html

    For some reason, the TISCI docs do not include signals coming to and from the processor pins. You need to reference the TRM section mentioned in the AM62x FAQ

    Hopefully the other typos are fixed in the updated docs, let me know if not.

    Regards,

    Nick

  • Hello Nick,

    Thank you very much for your continued help! Your short answer was good enough to point me in the right direction, and I am happy to report that I am now able to successfully timestamp outside events with testptp.

    I am busy with a few other things, but I need to keep working on this, because this is still not a pps in device.

    I may need a little bit more help, so let's keep this thread open if it's ok with you. I will post back when I have something more specific to say.

    In the mean time, if you want a detailed description about how I managed to do the external event timestamping, let me know.

    Cheers,

    Xabier.

  • Hello Xabier,

    Sounds good, glad to hear things are working for you! Feel free to comment back on this thread if you have followup questions. If the thread locks after 30 days of inactivity, feel free to create a new thread and just link back to this original thread.

    I do not understand "this is still not a pps in device".

    If you have any suggestions for improving the docs or the code, we would love to hear them! The docs and code are definitely still a work in progress. e.g., I just discovered that our example AM64x SYNC_OUT signal in the AM64x devicetree does not connect to a usable header on the EVM, so we'll need to update that mapping in the next SDK.

    Regards,

    Nick

  • Hi Nick,

    Back at this again, with more news, but first, let me follow up on some of your comments.

    If you have any suggestions for improving the docs or the code, we would love to hear them! The docs and code are definitely still a work in progress. e.g., I just discovered that our example AM64x SYNC_OUT signal in the AM64x devicetree does not connect to a usable header on the EVM, so we'll need to update that mapping in the next SDK.

    Ah, yes... I noticed that. I thought that it may have been removed because maybe my particular usecase didn't fit the overall integration of more products or something simmilar. I will try to be more verbose if I see things that I don't fully understand in the future.

    I do not understand "this is still not a pps in device".

    I meant it in the sense that it is not a /dev/ppsX device in the linux device driver structure. I am still a beginner in this whole clock synchronization world, and I was convinced I needed a /dev/pps device acting as a PPS input device (and not a PPS output device) if I wanted to be able to have a high precission PTP master synchronized to a GPS PPS out device.  It turns out I was wrong, and that's not necessary.

    After enabling the external timestamp channel on the ptp device to use the hardware timestamping facilities of the chip, I was able to sucessfully use the generic profile of ts2phc to keep the phc synchronized to the gps PPS.

    While doing this I discovered something that's looking bad, sadly. It appears that the PPS out we managed to get working on the other thread is not working as expected: changes in the PHC don't get reflected in the PPS out. I don't understand why this is happening. I think I will open a new thread with all the details and maybe we can continue on that thread.

    I would say it would be a good idea to keep this thread open, since we cannot really verify if what I have achieved here is really valid or not until we have a PPS out signal we can trust.

  • Hello Xabier,

    Ahh, thanks for the clarifications!

    I think that the "PPS output not reflecting changes" is a known bug. I have assigned your new thread to the team member who was looking into that behavior, but I will be watching that second thread as well.

    Regards,

    Nick

  • Thanks for your support Nick!

    I was just reviewing the documentation to do some more tests, and I have a couple of thoughts I would like to share with you.

    • In order to route the external events properly in the device tree, I have almost everything I have in the tisci documentation. I am missing only one additional piece:
    • To make life of developers easier it would be SUPER useful if the sdk version on the left panel would be clickable and a list of all available documented releases would be presented to be able to navigate from version to version, in case you are working with an outdated product (not my case at this moment, but could be useful once a product is alredy on the market). This idea would also apply for the Processor SDK Linux for AM62X documentation, and all equivalent documentation.

  • Hello Xabier,

    Turns out I was wrong about the "known bug" comment. I have edited my response on your new thread.

    Yeah, unfortunately the TISCI documentation is generated by a different software team who does not want hardware-specific details in their documentation. The "use TRM" note on the output pin entries was recently added to point people in the right direction, a while back the entries were just blank.

    Easily switching between SDK doc versions is a fair feature request. I'll write it down to discuss with the team who generates the different SDK / TISCI docs. Thanks for the input!

    Regards,

    Nick

  • Just a ping to keep this thread open. I hope I have some information to report in a few days.

  • Hello again Nick,

    I have exciting news on this front. The system is now doing everything I would want it to do.

    I can use both hardware timestamping channels on the ptp device to do high-precission timing activities.

    In my specific usecase I am able to maintain a pretty stable synchronization to a GPS pps device with a jitter lower than 50ns, and I can use the other hardware timestamping channel to have high precission timestamps of outside events.

    I don't know if I will be able to make it, but I am trying to get a few changes approved on linux mainline in order to have the system be able to do this.

    I am working on a set of patches for linux mainline, and I am also doing backports to the kernel on the SDK.

    If you are interested in incorporating these changes in the kernel on the SDK let me know. Otherwise, I am ready to have this thread closed.

  • Hello Xabier,

    That is great! Glad to hear the time sync is working so smoothly for you.

    If you get your patches mainlined, we will pull them in. So no need to specifically incorporate the kernel changes. If you want to get a TI developer to take a peek at your patches, feel free to point me to the patches and I can share the patches with them.

    Regards,

    Nick