Line data Source code
1 1 : /* 2 : * Copyright (c) 2018 Intel Corporation. 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : /** 8 : * @file 9 : * @brief Public functions for the Precision Time Protocol time specification. 10 : * 11 : * References are to version 2019 of IEEE 1588, ("PTP") 12 : * and version 2020 of IEEE 802.1AS ("gPTP"). 13 : */ 14 : 15 : #ifndef ZEPHYR_INCLUDE_NET_PTP_TIME_H_ 16 : #define ZEPHYR_INCLUDE_NET_PTP_TIME_H_ 17 : 18 : /** 19 : * @brief Precision Time Protocol time specification 20 : * @defgroup ptp_time PTP time 21 : * @since 1.13 22 : * @version 0.8.0 23 : * @ingroup networking 24 : * @{ 25 : */ 26 : 27 : #include <zephyr/net/net_core.h> 28 : #include <zephyr/net/net_time.h> 29 : #include <zephyr/toolchain.h> 30 : 31 : #ifdef __cplusplus 32 : extern "C" { 33 : #endif 34 : 35 : /** 36 : * @brief (Generalized) Precision Time Protocol Timestamp format. 37 : * 38 : * @details This structure represents a timestamp according to the Precision 39 : * Time Protocol standard ("PTP", IEEE 1588, section 5.3.3), the Generalized 40 : * Precision Time Protocol standard ("gPTP", IEEE 802.1AS, section 6.4.3.4), or 41 : * any other well-defined context in which precision structured timestamps are 42 : * required on network messages in Zephyr. 43 : * 44 : * Seconds are encoded as a 48 bits unsigned integer. Nanoseconds are encoded 45 : * as a 32 bits unsigned integer. 46 : * 47 : * In the context of (g)PTP, @em timestamps designate the time, relative to a 48 : * local clock ("LocalClock") at which the message timestamp point passes a 49 : * reference plane marking the boundary between the PTP Instance and the network 50 : * medium (IEEE 1855, section 7.3.4.2; IEEE 802.1AS, section 8.4.3). 51 : * 52 : * The exact definitions of the <em>message timestamp point</em> and 53 : * <em>reference plane</em> depends on the network medium and use case. 54 : * 55 : * For (g)PTP the media-specific message timestamp points and reference planes 56 : * are defined in the standard. In non-PTP contexts specific to Zephyr, 57 : * timestamps are measured relative to the same local clock but with a 58 : * context-specific message timestamp point and reference plane, defined below 59 : * per use case. 60 : * 61 : * A @em "LocalClock" is a freerunning clock, embedded into a well-defined 62 : * entity (e.g. a PTP Instance) and provides a common time to that entity 63 : * relative to an arbitrary epoch (IEEE 1855, section 3.1.26, IEEE 802.1AS, 64 : * section 3.16). 65 : * 66 : * In Zephyr, the local clock is usually any instance of a kernel system clock 67 : * driver, counter driver, RTC API driver or low-level counter/timer peripheral 68 : * (e.g. an ethernet peripheral with hardware timestamp support or a radio 69 : * timer) with sufficient precision for the context in which it is used. 70 : * 71 : * See IEEE 802.1AS, Annex B for specific performance requirements regarding 72 : * conformance of local clocks in the gPTP context. See IEEE 1588, Annex A, 73 : * section A5.4 for general performance requirements regarding PTP local clocks. 74 : * See IEEE 802.15.4-2020, section 15.7 for requirements in the context of 75 : * ranging applications and ibid., section 6.7.6 for the relation between guard 76 : * times and clock accuracy which again influence the precision required for 77 : * subprotocols like CSL, TSCH, RIT, etc. 78 : * 79 : * Applications that use timestamps across different subsystems or media must 80 : * ensure that they understand the definition of the respective reference planes 81 : * and interpret timestamps accordingly. Applications must further ensure that 82 : * timestamps are either all referenced to the same local clock or convert 83 : * between clocks based on sufficiently precise conversion algorithms. 84 : * 85 : * Timestamps may be measured on ingress (RX timestamps) or egress (TX 86 : * timestamps) of network messages. Timestamps can also be used to schedule a 87 : * network message to a well-defined point in time in the future at which it is 88 : * to be sent over the medium (timed TX). A future timestamp and a duration, 89 : * both referenced to the local clock, may be given to specify a time window at 90 : * which a network device should expect incoming messages (RX window). 91 : * 92 : * In Zephyr this timestamp structure is currently used in the following 93 : * contexts: 94 : * * gPTP for Full Duplex Point-to-Point IEEE 802.3 links (IEEE 802.1AS, 95 : * section 11): the reference plane and message timestamp points are as 96 : * defined in the standard. 97 : * * IEEE 802.15.4 timed TX and RX: Timestamps designate the point in time at 98 : * which the end of the last symbol of the start-of-frame delimiter (SFD) (or 99 : * equivalently, the start of the first symbol of the PHY header) is at the 100 : * local antenna. The standard also refers to this as the "RMARKER" (IEEE 101 : * 802.15.4-2020, section 6.9.1) or "symbol boundary" (ibid., section 6.5.2), 102 : * depending on the context. In the context of beacon timestamps, the 103 : * difference between the timestamp measurement plane and the reference plane 104 : * is defined by the MAC PIB attribute "macSyncSymbolOffset", ibid., section 105 : * 8.4.3.1, table 8-94. 106 : * 107 : * If further use cases are added to Zephyr using this timestamp structure, 108 : * their clock performance requirements, message timestamp points and reference 109 : * plane definition SHALL be added to the above list. 110 : */ 111 1 : struct net_ptp_time { 112 : /** Seconds encoded on 48 bits. */ 113 : union { 114 : 115 : /** @cond INTERNAL_HIDDEN */ 116 : struct { 117 : #ifdef CONFIG_LITTLE_ENDIAN 118 : uint32_t low; 119 : uint16_t high; 120 : uint16_t unused; 121 : #else 122 : uint16_t unused; 123 : uint16_t high; 124 : uint32_t low; 125 : #endif 126 : } _sec; 127 : /** @endcond */ 128 : 129 : /** Second value. */ 130 1 : uint64_t second; 131 1 : }; 132 : 133 : /** Nanoseconds. */ 134 1 : uint32_t nanosecond; 135 : }; 136 : 137 : #ifdef __cplusplus 138 : } 139 : #endif 140 : 141 : /** 142 : * @brief Generalized Precision Time Protocol Extended Timestamp format. 143 : * 144 : * @details This structure represents an extended timestamp according to the 145 : * Generalized Precision Time Protocol standard (IEEE 802.1AS), see section 146 : * 6.4.3.5. 147 : * 148 : * Seconds are encoded as 48 bits unsigned integer. Fractional nanoseconds are 149 : * encoded as 48 bits, their unit is 2*(-16) ns. 150 : * 151 : * A precise definition of PTP timestamps and their uses in Zephyr is given in 152 : * the description of @ref net_ptp_time. 153 : */ 154 1 : struct net_ptp_extended_time { 155 : /** Seconds encoded on 48 bits. */ 156 : union { 157 : 158 : /** @cond INTERNAL_HIDDEN */ 159 : struct { 160 : #ifdef CONFIG_LITTLE_ENDIAN 161 : uint32_t low; 162 : uint16_t high; 163 : uint16_t unused; 164 : #else 165 : uint16_t unused; 166 : uint16_t high; 167 : uint32_t low; 168 : #endif 169 : } _sec; 170 : /** @endcond */ 171 : 172 : /** Second value. */ 173 1 : uint64_t second; 174 1 : }; 175 : 176 : /** Fractional nanoseconds on 48 bits. */ 177 : union { 178 : 179 : /** @cond INTERNAL_HIDDEN */ 180 : struct { 181 : #ifdef CONFIG_LITTLE_ENDIAN 182 : uint32_t low; 183 : uint16_t high; 184 : uint16_t unused; 185 : #else 186 : uint16_t unused; 187 : uint16_t high; 188 : uint32_t low; 189 : #endif 190 : } _fns; 191 : /** @endcond */ 192 : 193 : /** Fractional nanoseconds value. */ 194 1 : uint64_t fract_nsecond; 195 1 : }; 196 : } __packed; 197 : 198 : /** 199 : * @brief Convert a PTP timestamp to a nanosecond precision timestamp, both 200 : * related to the local network reference clock. 201 : * 202 : * @note Only timestamps representing up to ~290 years can be converted to 203 : * nanosecond timestamps. Larger timestamps will return the maximum 204 : * representable nanosecond precision timestamp. 205 : * 206 : * @param ts the PTP timestamp 207 : * 208 : * @return the corresponding nanosecond precision timestamp 209 : */ 210 1 : static inline net_time_t net_ptp_time_to_ns(struct net_ptp_time *ts) 211 : { 212 : if (!ts) { 213 : return 0; 214 : } 215 : 216 : if (ts->second >= NET_TIME_SEC_MAX) { 217 : return NET_TIME_MAX; 218 : } 219 : 220 : return ((int64_t)ts->second * NSEC_PER_SEC) + ts->nanosecond; 221 : } 222 : 223 : /** 224 : * @brief Convert a nanosecond precision timestamp to a PTP timestamp, both 225 : * related to the local network reference clock. 226 : * 227 : * @param nsec a nanosecond precision timestamp 228 : * 229 : * @return the corresponding PTP timestamp 230 : */ 231 1 : static inline struct net_ptp_time ns_to_net_ptp_time(net_time_t nsec) 232 : { 233 : struct net_ptp_time ts; 234 : 235 : __ASSERT_NO_MSG(nsec >= 0); 236 : 237 : ts.second = nsec / NSEC_PER_SEC; 238 : ts.nanosecond = nsec % NSEC_PER_SEC; 239 : return ts; 240 : } 241 : 242 : /** 243 : * @} 244 : */ 245 : 246 : #endif /* ZEPHYR_INCLUDE_NET_PTP_TIME_H_ */