| /* |
| * Copyright (c) 2018 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief Public functions for the Precision Time Protocol time specification. |
| * |
| * References are to version 2019 of IEEE 1588, ("PTP") |
| * and version 2020 of IEEE 802.1AS ("gPTP"). |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_NET_PTP_TIME_H_ |
| #define ZEPHYR_INCLUDE_NET_PTP_TIME_H_ |
| |
| /** |
| * @brief Precision Time Protocol time specification |
| * @defgroup ptp_time PTP time |
| * @ingroup networking |
| * @{ |
| */ |
| |
| #include <zephyr/net/net_core.h> |
| #include <zephyr/net/net_time.h> |
| #include <zephyr/toolchain.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @brief (Generalized) Precision Time Protocol Timestamp format. |
| * |
| * @details This structure represents a timestamp according to the Precision |
| * Time Protocol standard ("PTP", IEEE 1588, section 5.3.3), the Generalized |
| * Precision Time Protocol standard ("gPTP", IEEE 802.1AS, section 6.4.3.4), or |
| * any other well-defined context in which precision structured timestamps are |
| * required on network messages in Zephyr. |
| * |
| * Seconds are encoded as a 48 bits unsigned integer. Nanoseconds are encoded |
| * as a 32 bits unsigned integer. |
| * |
| * In the context of (g)PTP, @em timestamps designate the time, relative to a |
| * local clock ("LocalClock") at which the message timestamp point passes a |
| * reference plane marking the boundary between the PTP Instance and the network |
| * medium (IEEE 1855, section 7.3.4.2; IEEE 802.1AS, section 8.4.3). |
| * |
| * The exact definitions of the <em>message timestamp point</em> and |
| * <em>reference plane</em> depends on the network medium and use case. |
| * |
| * For (g)PTP the media-specific message timestamp points and reference planes |
| * are defined in the standard. In non-PTP contexts specific to Zephyr, |
| * timestamps are measured relative to the same local clock but with a |
| * context-specific message timestamp point and reference plane, defined below |
| * per use case. |
| * |
| * A @em "LocalClock" is a freerunning clock, embedded into a well-defined |
| * entity (e.g. a PTP Instance) and provides a common time to that entity |
| * relative to an arbitrary epoch (IEEE 1855, section 3.1.26, IEEE 802.1AS, |
| * section 3.16). |
| * |
| * In Zephyr, the local clock is usually any instance of a kernel system clock |
| * driver, counter driver, RTC API driver or low-level counter/timer peripheral |
| * (e.g. an ethernet peripheral with hardware timestamp support or a radio |
| * timer) with sufficient precision for the context in which it is used. |
| * |
| * See IEEE 802.1AS, Annex B for specific performance requirements regarding |
| * conformance of local clocks in the gPTP context. See IEEE 1588, Annex A, |
| * section A5.4 for general performance requirements regarding PTP local clocks. |
| * See IEEE 802.15.4-2020, section 15.7 for requirements in the context of |
| * ranging applications and ibid., section 6.7.6 for the relation between guard |
| * times and clock accuracy which again influence the precision required for |
| * subprotocols like CSL, TSCH, RIT, etc. |
| * |
| * Applications that use timestamps across different subsystems or media must |
| * ensure that they understand the definition of the respective reference planes |
| * and interpret timestamps accordingly. Applications must further ensure that |
| * timestamps are either all referenced to the same local clock or convert |
| * between clocks based on sufficiently precise conversion algorithms. |
| * |
| * Timestamps may be measured on ingress (RX timestamps) or egress (TX |
| * timestamps) of network messages. Timestamps can also be used to schedule a |
| * network message to a well-defined point in time in the future at which it is |
| * to be sent over the medium (timed TX). A future timestamp and a duration, |
| * both referenced to the local clock, may be given to specify a time window at |
| * which a network device should expect incoming messages (RX window). |
| * |
| * In Zephyr this timestamp structure is currently used in the following |
| * contexts: |
| * * gPTP for Full Duplex Point-to-Point IEEE 802.3 links (IEEE 802.1AS, |
| * section 11): the reference plane and message timestamp points are as |
| * defined in the standard. |
| * * IEEE 802.15.4 timed TX and RX: Timestamps designate the point in time at |
| * which the end of the last symbol of the start-of-frame delimiter (SFD) (or |
| * equivalently, the start of the first symbol of the PHY header) is at the |
| * local antenna. The standard also refers to this as the "RMARKER" (IEEE |
| * 802.15.4-2020, section 6.9.1) or "symbol boundary" (ibid., section 6.5.2), |
| * depending on the context. In the context of beacon timestamps, the |
| * difference between the timestamp measurement plane and the reference plane |
| * is defined by the MAC PIB attribute "macSyncSymbolOffset", ibid., section |
| * 8.4.3.1, table 8-94. |
| * |
| * If further use cases are added to Zephyr using this timestamp structure, |
| * their clock performance requirements, message timestamp points and reference |
| * plane definition SHALL be added to the above list. |
| */ |
| struct net_ptp_time { |
| /** Seconds encoded on 48 bits. */ |
| union { |
| struct { |
| #ifdef CONFIG_LITTLE_ENDIAN |
| uint32_t low; |
| uint16_t high; |
| uint16_t unused; |
| #else |
| uint16_t unused; |
| uint16_t high; |
| uint32_t low; |
| #endif |
| } _sec; |
| uint64_t second; |
| }; |
| |
| /** Nanoseconds. */ |
| uint32_t nanosecond; |
| }; |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /** |
| * @brief Generalized Precision Time Protocol Extended Timestamp format. |
| * |
| * @details This structure represents an extended timestamp according to the |
| * Generalized Precision Time Protocol standard (IEEE 802.1AS), see section |
| * 6.4.3.5. |
| * |
| * Seconds are encoded as 48 bits unsigned integer. Fractional nanoseconds are |
| * encoded as 48 bits, their unit is 2*(-16) ns. |
| * |
| * A precise definition of PTP timestamps and their uses in Zephyr is given in |
| * the description of @ref net_ptp_time. |
| */ |
| struct net_ptp_extended_time { |
| /** Seconds encoded on 48 bits. */ |
| union { |
| struct { |
| #ifdef CONFIG_LITTLE_ENDIAN |
| uint32_t low; |
| uint16_t high; |
| uint16_t unused; |
| #else |
| uint16_t unused; |
| uint16_t high; |
| uint32_t low; |
| #endif |
| } _sec; |
| uint64_t second; |
| }; |
| |
| /** Fractional nanoseconds on 48 bits. */ |
| union { |
| struct { |
| #ifdef CONFIG_LITTLE_ENDIAN |
| uint32_t low; |
| uint16_t high; |
| uint16_t unused; |
| #else |
| uint16_t unused; |
| uint16_t high; |
| uint32_t low; |
| #endif |
| } _fns; |
| uint64_t fract_nsecond; |
| }; |
| } __packed; |
| |
| /** |
| * @brief Convert a PTP timestamp to a nanosecond precision timestamp, both |
| * related to the local network reference clock. |
| * |
| * @note Only timestamps representing up to ~290 years can be converted to |
| * nanosecond timestamps. Larger timestamps will return the maximum |
| * representable nanosecond precision timestamp. |
| * |
| * @param ts the PTP timestamp |
| * |
| * @return the corresponding nanosecond precision timestamp |
| */ |
| static inline net_time_t net_ptp_time_to_ns(struct net_ptp_time *ts) |
| { |
| if (!ts) { |
| return 0; |
| } |
| |
| if (ts->second >= NET_TIME_SEC_MAX) { |
| return NET_TIME_MAX; |
| } |
| |
| return ((int64_t)ts->second * NSEC_PER_SEC) + ts->nanosecond; |
| } |
| |
| /** |
| * @brief Convert a nanosecond precision timestamp to a PTP timestamp, both |
| * related to the local network reference clock. |
| * |
| * @param nsec a nanosecond precision timestamp |
| * |
| * @return the corresponding PTP timestamp |
| */ |
| static inline struct net_ptp_time ns_to_net_ptp_time(net_time_t nsec) |
| { |
| struct net_ptp_time ts; |
| |
| __ASSERT_NO_MSG(nsec >= 0); |
| |
| ts.second = nsec / NSEC_PER_SEC; |
| ts.nanosecond = nsec % NSEC_PER_SEC; |
| return ts; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* ZEPHYR_INCLUDE_NET_PTP_TIME_H_ */ |