diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2022-07-06 17:56:23 +0200 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2022-07-06 17:56:23 +0200 |
commit | f4fd0d2a3374af0923c58b7af9934bd5ff1fc397 (patch) | |
tree | 619280a7ca431956c691eb4d2c9c450c2ccfee34 | |
parent | 57a8fcb42afa1feb7b63bb8b352a4ebe4b0389dc (diff) | |
download | mbgtools-lx-f4fd0d2a3374af0923c58b7af9934bd5ff1fc397.tar.gz mbgtools-lx-f4fd0d2a3374af0923c58b7af9934bd5ff1fc397.zip |
Support SYN1588 insync range boundary codes in some library files
-rw-r--r-- | mbglib/common/mbg_syn1588_defs.h | 80 | ||||
-rw-r--r-- | mbglib/common/mbg_syn1588_util.c | 113 | ||||
-rw-r--r-- | mbglib/common/mbg_syn1588_util.h | 90 | ||||
-rw-r--r-- | mbglib/syn1588/src/basictypes.h | 63 | ||||
-rw-r--r-- | mbglib/syn1588/src/libs/syn1588_ifc.h | 4 |
5 files changed, 250 insertions, 100 deletions
diff --git a/mbglib/common/mbg_syn1588_defs.h b/mbglib/common/mbg_syn1588_defs.h index 524676d..44cd08b 100644 --- a/mbglib/common/mbg_syn1588_defs.h +++ b/mbglib/common/mbg_syn1588_defs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_syn1588_defs.h 1.1 2022/05/31 13:41:42 martin.burnicki REL_M $ + * $Id: mbg_syn1588_defs.h 1.2 2022/07/06 15:09:08 martin.burnicki REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -17,6 +17,8 @@ * * ----------------------------------------------------------------------- * $Log: mbg_syn1588_defs.h $ + * Revision 1.2 2022/07/06 15:09:08 martin.burnicki + * Support SYN1588 insync range boundary code instead of the original enum. * Revision 1.1 2022/05/31 13:41:42 martin.burnicki * Initial revision. * @@ -89,8 +91,8 @@ typedef uint32_t SYN1588_PTP_SYNC_STATUS; #define DEF_PSS_BITMASK_PTP_STATE 0x00007800 ///< Bitfield mask for the field representing the PTP State, see ::PSS_BITMASK_PTP_STATE #define DEF_PSS_SHIFT_PTP_STATE 11 ///< Shift offset for the field representing the PTP State, see ::PSS_SHIFT_PTP_STATE #define DEF_PSS_BIT_PTP_INSYNC 0x00008000 ///< Bit signalling that the PTP Stack is in-sync, see ::PSS_BIT_PTP_INSYNC -#define DEF_PSS_BITMASK_PTP_INSYNC_BOUNDARY 0x003F0000 ///< Bitfield mask for the field representing in sync boundary, see ::Boundaries_e and see ::PSS_BITMASK_PTP_INSYNC_BOUNDARY -#define DEF_PSS_SHIFT_PTP_INSYNC_BOUNDARY 16 ///< Shift offset for the field representing the in sync boundary, see ::PSS_SHIFT_PTP_INSYNC_BOUNDARY +#define DEF_PSS_BITMASK_PTP_INSYNC_BND_CODE 0x003F0000 ///< Bitfield mask for the code indicating the insync boundary, see ::PTP_STATE_RANGE_TABLE_INIT and::PSS_BITMASK_PTP_INSYNC_BND_CODE +#define DEF_PSS_SHIFT_PTP_INSYNC_BND_CODE 16 ///< Shift offset for the field representing the in sync boundary, see ::PSS_SHIFT_PTP_INSYNC_BND_CODE #define DEF_PSS_BIT_PTP_TIMESCALE 0x00400000 ///< Bit signalling the current PTP Timescale ('1' = PTP, '0' = ARB), see ::PSS_BIT_PTP_TIMESCALE #define DEF_PSS_BIT_LSYNC_RUNNING 0x40000000 ///< Bit signalling that lSync is active, see ::LSS_BIT_LSYNC_RUNNING #define DEF_PSS_BIT_VALID 0x80000000 ///< Bit signalling that the register content is valid, see ::PSS_BIT_VALID @@ -145,78 +147,6 @@ enum SYN1588_PTP_STATES } - -/** - * @brief Enumeration of in sync boundary ranges. - * - * See ::Boundaries_e for the original enumeration. - * - * @see ::SYN1588_BOUNDARY_STRS - * @see ::Boundaries_e - * @see ::DEF_PSS_BITMASK_PTP_INSYNC_BOUNDARY - */ -enum SYN1588_INSYNC_BOUNDARIES -{ - MBG_EOver10s = 0, - MBG_EWithin10s, - MBG_EWithin1s, - MBG_EWithin250ms, - MBG_EWithin100ms, - MBG_EWithin25ms, - MBG_EWithin10ms, - MBG_EWithin2_5ms, - MBG_EWithin1ms, - MBG_EWithin250us, - MBG_EWithin100us, - MBG_EWithin25us, - MBG_EWithin10us, - MBG_EWithin2_5us, - MBG_EWithin1us, - MBG_EWithin250ns, - MBG_EWithin100ns, - MBG_EWithin50ns, - MBG_EWithin25ns, - MBG_EWithin10ns, - N_MBG_EMaxBoundary ///< The number of distinguished boundary ranges. -}; - - -/** - * @brief Initializer for a string array of in sync boundary ranges. - * - * See ::SYN1588_INSYNC_BOUNDARIES for the associated enumeration, where - * ::N_MBG_EMaxBoundary reflects the number of required table entries. - * - * @see ::mbg_syn1588_get_boundary_str - * @see ::Boundaries_e - * @see ::DEF_PSS_BITMASK_PTP_INSYNC_BOUNDARY - */ -#define SYN1588_BOUNDARY_STRS \ -{ \ - "none", /* EOver10s */ \ - "10 s", /* EWithin10s */ \ - "1 s", /* EWithin1s */ \ - "250 ms", /* EWithin250ms */ \ - "100 ms", /* EWithin100ms */ \ - "25 ms", /* EWithin25ms */ \ - "10 ms", /* EWithin10ms */ \ - "2.5 ms", /* EWithin2_5ms */ \ - "1 ms", /* EWithin1ms */ \ - "250 us", /* EWithin250us */ \ - "100 us", /* EWithin100us */ \ - "25 us", /* EWithin25us */ \ - "10 us", /* EWithin10us */ \ - "2.5 us", /* EWithin2_5us */ \ - "1 us", /* EWithin1us */ \ - "250 ns", /* EWithin250ns */ \ - "100 ns", /* EWithin100ns */ \ - "50 ns", /* EWithin50ns */ \ - "25 ns", /* EWithin25ns */ \ - "10 ns" /* EWithin10ns */ \ -} - - - #ifdef __cplusplus } #endif diff --git a/mbglib/common/mbg_syn1588_util.c b/mbglib/common/mbg_syn1588_util.c index e1e39a3..19cf41a 100644 --- a/mbglib/common/mbg_syn1588_util.c +++ b/mbglib/common/mbg_syn1588_util.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_syn1588_util.c 1.1 2022/05/31 13:41:42 martin.burnicki REL_M $ + * $Id: mbg_syn1588_util.c 1.2 2022/07/06 15:09:08 martin.burnicki REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -9,6 +9,8 @@ * * ----------------------------------------------------------------------- * $Log: mbg_syn1588_util.c $ + * Revision 1.2 2022/07/06 15:09:08 martin.burnicki + * Support SYN1588 insync range boundary code instead of the original enum. * Revision 1.1 2022/05/31 13:41:42 martin.burnicki * Initial revision. * @@ -18,9 +20,22 @@ #include <mbg_syn1588_util.h> #undef _MBG_SYN1588_UTIL +#include <str_util.h> + + + +/** + * @brief Insync boundary code indicating out-of-bounds. + * + * This insync boundary code is the maximum possible value + * that can be stored in the ::PTP_SYNC_STATUS word. + * It should be used to indicate that the boundary is out of + * the well-defined limits, similar to ::EOver10s. + */ +#define PTP_STATE_RANGE_MAX_CODE 0x3F + static const char *ptp_state_strs[N_SYN1588_PTP_STATES] = SYN1588_PTP_STATE_STRS; -static const char *ptp_boundary_strs[N_MBG_EMaxBoundary] = SYN1588_BOUNDARY_STRS; /*HDR*/ @@ -44,19 +59,97 @@ const char *mbg_syn1588_chk_get_ptp_state_str( uint state ) /*HDR*/ /** - * @brief Retrieve a string representing PTP in sync boundary. + * @brief Write the decoded value of an insync range boundary code to a string buffer. * - * @param[in] range_idx The range index, see ::SYN1588_INSYNC_BOUNDARIES. + * @param[out] s Pointer to the output buffer. + * @param[in] max_len Size of the output buffer. + * @param[in] code The insync range boundary code, see ::PTP_STATE_RANGE_TABLE_INIT. + * @param[in] check_max If @a true, ::PTP_STATE_RANGE_MAX_CODE causes special string. * - * @return One of the strings defined in ::SYN1588_BOUNDARY_STRS. + * @return The number of characters written to the output buffer, + * except the terminating 0. */ -const char *mbg_syn1588_get_boundary_str( uint range_idx ) +int mbg_syn1588_snprint_insync_boundary_code( char *s, size_t max_len, + uint code, bool check_max ) { - if ( range_idx < N_MBG_EMaxBoundary ) - return ptp_boundary_strs[range_idx]; + #define N_PREFIXES 4 + + static const char *unit_prefixes[N_PREFIXES] = + { + "p", + "n", + "u", + "m" + }; + + div_t dt; + int range_idx; + int range_mul; + #if DEBUG_INSYNC_BOUNDARY + int range_mul_raw; + #endif + long m; + long l; + int i; + int n = 0; + + if ( check_max && ( code >= PTP_STATE_RANGE_MAX_CODE ) ) + return snprintf_safe( s, max_len, "(out of bounds)" ); + + dt = div( code, 12 ); + + range_idx = dt.quot; + range_mul = dt.rem / 4; + + if ( dt.quot > N_PREFIXES ) + range_mul += ( dt.quot - 2 ); // TODO + + #if DEBUG_INSYNC_BOUNDARY + range_mul_raw = range_mul; + #endif + + if ( ( dt.rem % 4 ) == 0 ) + range_mul--; + + #if DEBUG_INSYNC_BOUNDARY + printf( "%2i", dt.quot ); + printf( " %2i", dt.rem ); + printf( " %2i", range_mul_raw ); + printf( " %2i", range_mul ); + #endif + + m = syn1588_insync_boundary_mantissa( code ); + + // Take care of scale range boundaries. + l = ( m == 0 ) ? 100 : ( m * 25 ); + + for ( i = 0; i < range_mul; i++ ) + l *= 10; + + for ( i = range_mul; i < 0; i++ ) + l /= 10; + + #if OMIT_INSYNC_BOUNDARY_FRAC + n = snprintf_safe( s, max_len, "%li %ss", l, ( range_idx < N_PREFIXES ) ? + unit_prefixes[range_idx] : "" ); + #else + { + ldiv_t ldt = ldiv( l, 10 ); + + n = snprintf_safe( s, max_len, "%li", ldt.quot ); + + #if !PRINT_INSYNC_BOUNDARY_FRAC + if ( ldt.rem ) + #endif + n += snprintf_safe( &s[n], max_len - n, ".%li", ldt.rem ); + + n += snprintf_safe( &s[n], max_len - n, " %ss", ( range_idx < N_PREFIXES ) ? + unit_prefixes[range_idx] : "" ); + } + #endif - return "unknown range"; + return n; -} // mbg_syn1588_get_boundary_str +} // mbg_syn1588_snprint_insync_boundary_code diff --git a/mbglib/common/mbg_syn1588_util.h b/mbglib/common/mbg_syn1588_util.h index b667e21..f279bf9 100644 --- a/mbglib/common/mbg_syn1588_util.h +++ b/mbglib/common/mbg_syn1588_util.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_syn1588_util.h 1.1 2022/05/31 13:41:41 martin.burnicki REL_M $ + * $Id: mbg_syn1588_util.h 1.2 2022/07/06 15:09:08 martin.burnicki REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -9,6 +9,8 @@ * * ----------------------------------------------------------------------- * $Log: mbg_syn1588_util.h $ + * Revision 1.2 2022/07/06 15:09:08 martin.burnicki + * Support SYN1588 insync range boundary code instead of the original enum. * Revision 1.1 2022/05/31 13:41:41 martin.burnicki * Initial revision. * @@ -31,6 +33,27 @@ #include <stdio.h> +#if !defined( PRINT_INSYNC_BOUNDARY_FRAC ) + // If not 0, fractions of insync boundary values are + // always printed, even if they are 0. + // Useful for debugging, but output is prettier + // without this. + #define PRINT_INSYNC_BOUNDARY_FRAC 0 +#endif + +#if !defined( DEBUG_INSYNC_BOUNDARY ) + // If not 0, print intermediate values to stdout. + // Just for debugging, should be 0 otherwise. + #define DEBUG_INSYNC_BOUNDARY 0 +#endif + +#if !defined( OMIT_INSYNC_BOUNDARY_FRAC ) + // If not 0, print values * 10, without fractions. + // Just for debugging, should be 0 otherwise. + #define OMIT_INSYNC_BOUNDARY_FRAC 0 +#endif + + #ifdef _MBG_SYN1588_UTIL #define _ext #define _DO_INIT @@ -88,13 +111,13 @@ static __mbg_inline /*HDR*/ * @brief Check if the PTP stack is in sync. * * This is the case if the determined time offset is inside - * a specified boundary. See ::syn1588_get_in_sync_boundary_idx. + * a specified boundary. See ::syn1588_get_in_sync_boundary_code. * * @param[in] ptp_sync_status The sync status word read from a device. * * @return @a true, if in sync, else @a false. * - * @see ::syn1588_get_in_sync_boundary_idx + * @see ::syn1588_get_in_sync_boundary_code */ bool syn1588_ptp_in_sync( SYN1588_PTP_SYNC_STATUS ptp_sync_status ) { @@ -139,11 +162,11 @@ static __mbg_inline /*HDR*/ * * @see ::syn1588_ptp_in_sync */ -uint syn1588_get_in_sync_boundary_idx( SYN1588_PTP_SYNC_STATUS ptp_sync_status ) +uint syn1588_get_in_sync_boundary_code( SYN1588_PTP_SYNC_STATUS ptp_sync_status ) { - return ( ptp_sync_status & DEF_PSS_BITMASK_PTP_INSYNC_BOUNDARY ) >> DEF_PSS_SHIFT_PTP_INSYNC_BOUNDARY; + return ( ptp_sync_status & DEF_PSS_BITMASK_PTP_INSYNC_BND_CODE ) >> DEF_PSS_SHIFT_PTP_INSYNC_BND_CODE; -} // syn1588_get_in_sync_boundary_idx +} // syn1588_get_in_sync_boundary_code @@ -277,6 +300,47 @@ bool syn1588_lsync_running( SYN1588_PTP_SYNC_STATUS ptp_sync_status ) +static __mbg_inline /*HDR*/ +/** + * @brief Get the exponent from an insync range boundary code. + * + * @param[in] code The insync range boundary code to be decoded, see ::PTP_STATE_RANGE_TABLE_INIT. + * + * @return The decoded exponent, scaled to shift results to a useful range. + * + * @see ::syn1588_insync_boundary_mantissa + * @see ::mbg_syn1588_snprint_insync_boundary_code + */ +int syn1588_insync_boundary_exponent( int code ) +{ + return ( code >> 2 ) - 11; + +} // syn1588_insync_boundary_exponent + + + +static __mbg_inline /*HDR*/ +/** + * @brief Get the mantissa from an insync range boundary code. + * + * The decoded mantissa still needs special handling on range boundaries, + * see implementation in ::mbg_syn1588_snprint_insync_boundary_code. + * + * @param[in] code The insync range boundary code to be decoded, see ::PTP_STATE_RANGE_TABLE_INIT. + * + * @return The decoded mantissa. + * + * @see ::syn1588_insync_boundary_mantissa + * @see ::mbg_syn1588_snprint_insync_boundary_code + */ +int syn1588_insync_boundary_mantissa( int code ) +{ + return code & 0x03; + +} // syn1588_insync_boundary_mantissa + + + /* function prototypes: */ /* ----- function prototypes begin ----- */ @@ -294,13 +358,17 @@ bool syn1588_lsync_running( SYN1588_PTP_SYNC_STATUS ptp_sync_status ) const char *mbg_syn1588_chk_get_ptp_state_str( uint state ) ; /** - * @brief Retrieve a string representing PTP in sync boundary. + * @brief Write the decoded value of an insync range boundary code to a string buffer. * - * @param[in] range_idx The range index, see ::SYN1588_INSYNC_BOUNDARIES. + * @param[out] s Pointer to the output buffer. + * @param[in] max_len Size of the output buffer. + * @param[in] code The insync range boundary code, see ::PTP_STATE_RANGE_TABLE_INIT. + * @param[in] check_max If @a true, ::PTP_STATE_RANGE_MAX_CODE causes special string. * - * @return One of the strings defined in ::SYN1588_BOUNDARY_STRS. + * @return The number of characters written to the output buffer, + * except the terminating 0. */ - const char *mbg_syn1588_get_boundary_str( uint range_idx ) ; + int mbg_syn1588_snprint_insync_boundary_code( char *s, size_t max_len, uint code, bool check_max ) ; /* ----- function prototypes end ----- */ @@ -384,7 +452,7 @@ void syn1588_decode_sync_status( SYN1588_PTP_SYNC_STATUS ptp_sync_status, PCPS_H uint32_t ptp_state = syn1588_ptp_state_from_sync_status( ptp_sync_status ); bool ptp_in_sync = syn1588_ptp_in_sync( ptp_sync_status ); - uint32_t in_sync_boundary_idx = syn1588_get_in_sync_boundary_idx( ptp_sync_status ); + uint32_t in_sync_boundary_idx = syn1588_get_in_sync_boundary_code( ptp_sync_status ); bool timescale_is_ptp = ( ptp_sync_status & DEF_PSS_BIT_PTP_TIMESCALE ) != 0; diff --git a/mbglib/syn1588/src/basictypes.h b/mbglib/syn1588/src/basictypes.h index 58daba2..51d360f 100644 --- a/mbglib/syn1588/src/basictypes.h +++ b/mbglib/syn1588/src/basictypes.h @@ -242,8 +242,8 @@ enum Return_e {EErr, ENoErr}; /// @brief Boundaries used in the PTP-applications /// -/// Those boundaries should be used when boundaries are needed. -/// @note this enumeration shall be sorted from the biggest to the smallest value. +/// These boundaries should be used when boundaries are needed. +/// @note This enumeration shall be sorted from the biggest to the smallest value. /// @ingroup datatypes enum Boundaries_e { EOver10s = 0, @@ -269,6 +269,65 @@ enum Boundaries_e { EMaxBoundary }; + +/// @brief An insync range boundary code indicating out-of-bounds. +/// +/// This insync range boundary code is the maximum possible value +/// that can be stored in the ::PSS_BITMASK_PTP_INSYNC_BND_CODE +/// of the ::PTP_SYNC_STATUS word. +/// It should be used to indicate that the boundary is out of +/// the well-defined limits, similar to ::EOver10s. +/// +/// @see ::PTP_STATE_RANGE_TABLE_INIT +#define PTP_STATE_RANGE_MAX_CODE 0x3F + +/// @brief Codes for the ::PSS_BITMASK_PTP_INSYNC_BND_CODE field +/// +/// An initializer for a table to convert the enum values in ::Boundaries_e +/// to a code for the ::PSS_BITMASK_PTP_INSYNC_BND_CODE field in the +/// ::PTP_SYNC_STATUS register. +/// +/// Using these codes instead of the index values from ::Boundaries_e makes +/// it easier to keep the meaning of the ::PSS_BITMASK_PTP_INSYNC_BND_CODE +/// field consistent, even if new values are inserted in the middle of the enum, +/// as long as this initializer is updated accordingly. +/// +/// Of the 6 available bits, the 2 LSBs are used to define a kind of mantissa, +/// in steps of 0.1, 0.25. 0.50, 0.75 associated to the 4 possible binary values. +/// The 4 MSBs are interpreted as an exponent to base 10, to which a constant +/// offset has to be applied to map the resulting values to a range that is +/// useful for PTP, which is here 1 ps for code 0x00 up to 5000 s for +/// the highest code 0x3E. In addition there is code 0x3F, which would map +/// to 7500 s, but is used here as an exception to indicate that the maximum +/// range is exceeded, like ::EOver10s. +/// +/// @see ::PSS_BITMASK_PTP_INSYNC_BND_CODE +/// @see ::PTP_STATE_RANGE_MAX_CODE +#define PTP_STATE_RANGE_TABLE_INIT \ +{ \ + PTP_STATE_RANGE_MAX_CODE, /* EOver10s */ \ + 0x34, /* EWithin10s */ \ + 0x30, /* EWithin1s */ \ + 0x2D, /* EWithin250ms */ \ + 0x2C, /* EWithin100ms */ \ + 0x29, /* EWithin25ms */ \ + 0x28, /* EWithin10ms */ \ + 0x25, /* EWithin2_5ms */ \ + 0x24, /* EWithin1ms */ \ + 0x21, /* EWithin250us */ \ + 0x20, /* EWithin100us */ \ + 0x1D, /* EWithin25us */ \ + 0x1C, /* EWithin10us */ \ + 0x19, /* EWithin2_5us */ \ + 0x18, /* EWithin1us */ \ + 0x15, /* EWithin250ns */ \ + 0x14, /* EWithin100ns */ \ + 0x12, /* EWithin50ns */ \ + 0x11, /* EWithin25ns */ \ + 0x10 /* EWithin10ns */ \ +} + + extern int64_t CBoundariesInScaledNS[]; #ifndef __cplusplus diff --git a/mbglib/syn1588/src/libs/syn1588_ifc.h b/mbglib/syn1588/src/libs/syn1588_ifc.h index 9d52082..4698c8b 100644 --- a/mbglib/syn1588/src/libs/syn1588_ifc.h +++ b/mbglib/syn1588/src/libs/syn1588_ifc.h @@ -762,8 +762,8 @@ class Syn1588Ifc { static const uint32_t PSS_BITMASK_PTP_STATE = 0x00007800; ///< bitfield mask for the field representing the PTP State static const uint32_t PSS_SHIFT_PTP_STATE = 11; ///< shift offset for the field representing the PTP State static const uint32_t PSS_BIT_PTP_INSYNC = 0x00008000; ///< bit signalling that the PTP Stack is in-sync - static const uint32_t PSS_BITMASK_PTP_INSYNC_BOUNDARY = 0x003F0000; ///< bitfield mask for the field representing the insync boundary, see ::Boundaries_e - static const uint32_t PSS_SHIFT_PTP_INSYNC_BOUNDARY = 16; ///< shift offset for the field representing the insync boundary + static const uint32_t PSS_BITMASK_PTP_INSYNC_BND_CODE = 0x003F0000; ///< bitfield mask for the code indicating the insync boundary, see ::PTP_STATE_RANGE_TABLE_INIT + static const uint32_t PSS_SHIFT_PTP_INSYNC_BND_SHIFT = 16; ///< shift offset for the code indicating the insync boundary static const uint32_t PSS_BIT_PTP_TIMESCALE = 0x00400000; ///< bit signalling the current PTP Timescale ('1' = PTP, '0' = ARB) static const uint32_t PSS_BIT_LSYNC_RUNNING = LSS_BIT_LSYNC_RUNNING; ///< only writeable via LSYNC STATUS register static const uint32_t PSS_BIT_VALID = 0x80000000; ///< bit signalling that the register content is valid |