diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2021-11-11 12:20:37 +0100 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2022-07-08 17:21:00 +0200 |
commit | 97b6ecf3f4cbf618967a8610827bf32ab5189423 (patch) | |
tree | c976ec98459c4b8345059a4f070d8250408104f9 | |
parent | 1f77571758839bb2cef9048353e8b728ea188fe5 (diff) | |
download | mbgtools-win-97b6ecf3f4cbf618967a8610827bf32ab5189423.tar.gz mbgtools-win-97b6ecf3f4cbf618967a8610827bf32ab5189423.zip |
Update mbgtools source files
-rw-r--r-- | mbgcmptime/mbgcmptime.c | 102 | ||||
-rw-r--r-- | mbgctrl/mbgctrl.c | 583 | ||||
-rw-r--r-- | mbgfasttstamp/mbgfasttstamp.c | 108 | ||||
-rw-r--r-- | mbggpscap/mbggpscap.c | 354 | ||||
-rw-r--r-- | mbghrtime/mbghrtime.c | 149 | ||||
-rw-r--r-- | mbgirigcfg/mbgirigcfg.c | 95 | ||||
-rw-r--r-- | mbgsetsystime/mbgsetsystime.c | 79 | ||||
-rw-r--r-- | mbgshowsignal/mbgshowsignal.c | 48 | ||||
-rw-r--r-- | mbgstatus/mbgstatus.c | 1124 | ||||
-rw-r--r-- | mbgtcrcal/mbgtcrcal.c | 79 | ||||
-rw-r--r-- | mbgxhrtime/mbgxhrtime.c | 54 |
11 files changed, 1820 insertions, 955 deletions
diff --git a/mbgcmptime/mbgcmptime.c b/mbgcmptime/mbgcmptime.c index 24483c9..5ee8043 100644 --- a/mbgcmptime/mbgcmptime.c +++ b/mbgcmptime/mbgcmptime.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgcmptime.c 1.4 2018/12/14 12:51:29Z martin REL_M $ + * $Id: mbgcmptime.c 1.10 2021/11/08 18:01:08Z martin.burnicki REL_M $ * * Description: * Main file for mbgcmptime program which compares the time on 2 devices @@ -11,7 +11,20 @@ * * ----------------------------------------------------------------------- * $Log: mbgcmptime.c $ - * Revision 1.4 2018/12/14 12:51:29Z martin + * Revision 1.10 2021/11/08 18:01:08Z martin.burnicki + * Account for modified MBG_DEV_FN type. + * Revision 1.9 2021/04/12 21:57:54 martin + * Updated printing of usage information. + * Revision 1.8 2021/03/21 17:39:41 martin + * Updated some comments. + * Revision 1.7 2021/03/12 14:20:13 martin + * Use the new global variable pc_cycles_frequency. + * Revision 1.6 2020/06/17 10:06:48 martin + * New option -R to also print raw (hex) timestamps. + * Workaround for clreol which is unsupported on Windows. + * Revision 1.5 2020/05/11 08:47:01 martin + * Removed erroneous duplicate definition of variable 'cyc_freq'. + * Revision 1.4 2018/12/14 12:51:29 martin * Fixed evaluation of device specification parameters. * Improved error handling. * Revision 1.3 2018/11/15 12:39:28 martin @@ -20,7 +33,7 @@ * New option -a to compensate an initial offset automatically. * New option -C which to append a marker '#' to the output if status changed. * New option -L to specify a time offset limit. If the time offset change - * exceeds the specified limit then a marker '<<' is appended to the output. + * exceeds the specified limit, a marker '<<' is appended to the output. * New option -q for quiet operation, i.e. output lines on the console * are overwritten unless the previous line has a marker appended. * New option -o to specify an output file that provides the full log @@ -38,19 +51,19 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <cmp_time_util.h> #include <mbgdevio.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. #include <str_util.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <math.h> #define MBG_FIRST_COPYRIGHT_YEAR 2013 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgcmptime"; @@ -69,13 +82,15 @@ static int quiet; static const char *log_fn; -MBG_PC_CYCLES_FREQUENCY cyc_freq; // must not be static! - static const char *ref_dev_param; static MBG_DEV_HANDLE dh_ref; static PCPS_DEV dev_info_ref; -static const char term_clreol[] = "\x1B[0K"; // ANSI escape sequence for clreol +#if defined( MBG_TGT_WIN32 ) +static const char term_clreol[] = " "; // ANSI not supported; just print some spaces to highlight end of line. +#else +static const char term_clreol[] = "\x1B[0K"; // ANSI escape sequence for clreol. +#endif @@ -119,21 +134,21 @@ int do_mbgcmptime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( read_fast ) { - rc = chk_fast_tstamp_supp( dh, p_dev, dh_ref, &dev_info_ref, NULL ); //### TODO err_msg_fnc ? + rc = chk_fast_tstamp_supp( dh, p_dev, dh_ref, &dev_info_ref, NULL ); // TODO err_msg_fnc ? if ( mbg_rc_is_error( rc ) ) { if ( rc != MBG_ERR_NOT_SUPP_BY_DEV ) goto done; - //##+++++++++ msg .... + // TODO Show msg ... read_fast = 0; } } - rc = mbg_get_default_cycles_frequency_from_dev( dh, &cyc_freq ); + rc = mbg_init_pc_cycles_frequency( dh ); - if ( mbg_cond_err_msg( rc, "mbg_get_default_cycles_frequency_from_dev" ) ) + if ( mbg_cond_err_msg( rc, "mbg_init_pc_cycles_frequency" ) ) goto done; @@ -247,6 +262,8 @@ int do_mbgcmptime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( this_loops == 0 ) break; + // If this_loops is < 0, loop forever. + prv_htc1 = htc1; prv_htc2 = htc2; prv_delta_t = delta_t; @@ -258,8 +275,7 @@ int do_mbgcmptime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( sleep_usecs ) usleep( sleep_usecs ); - //##++++++ printf( "\n" ); - // if this_loops is < 0 then loop forever + // printf( "\n" ); } done: @@ -281,20 +297,21 @@ void usage( void ) "command line." ); mbg_print_help_options(); - mbg_print_opt_info( "-i dev", "reference device the test card's time shall be compared to" ); - mbg_print_opt_info( "-l limit", "append a marker '*' to the output if delta exceeds limit [us]" ); - mbg_print_opt_info( "-L limit", "append a marker '<<' to the output if delta changes [us]" ); - mbg_print_opt_info( "-C", "append a marker '#' to the output if status changed" ); - mbg_print_opt_info( "-f", "read fast (memory mapped) timestamps" ); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-n num", "run num loops" ); - mbg_print_opt_info( "-r", "read raw time stamps, no cycles" ); - mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" ); - mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" ); - mbg_print_opt_info( "-o file", "also log output to <file>" ); - mbg_print_opt_info( "-q", "quiet, only log errors to console (use -o to specify file for full log)" ); - mbg_print_opt_info( "-a", "auto-compensate initial offset" ); - mbg_print_device_options(); + mbg_print_opt_info( "-i dev", "Reference device to which the time of the device under test shall be compared" ); + mbg_print_opt_info( "-l limit", "Append a marker '*' to the output if delta exceeds limit [us]" ); + mbg_print_opt_info( "-L limit", "Append a marker '<<' to the output if delta changes [us]" ); + mbg_print_opt_info( "-C", "Append a marker '#' to the output if status changed" ); + mbg_print_opt_info( "-f", "Read fast (memory mapped) timestamps" ); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-n num", "Run num loops" ); + mbg_print_opt_info( "-r", "Read raw time stamps, no cycles" ); + mbg_print_opt_info( "-R", "Also display raw timestamps (hex)" ); + mbg_print_opt_info( "-s num", "Sleep num seconds between calls (implies -c)" ); + mbg_print_opt_info( "-u num", "Sleep num microseconds between calls (implies -c)" ); + mbg_print_opt_info( "-o file", "Also log output to <file>" ); + mbg_print_opt_info( "-q", "quiet, Only log errors to console (use -o to specify file for full log)" ); + mbg_print_opt_info( "-a", "Auto-compensate initial offset" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); printf( "\nExamples:\n\n" ); @@ -322,8 +339,8 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters - while ( ( c = getopt( argc, argv, "acCfi:l:L:n:o:qrs:u:h?" ) ) != -1 ) + // Check command line parameters. + while ( ( c = getopt( argc, argv, "acCfi:l:L:n:o:qrRs:u:h?" ) ) != -1 ) { switch ( c ) { @@ -371,6 +388,10 @@ int main( int argc, char *argv[] ) read_raw = 1; break; + case 'R': + print_raw = 1; + break; + case 's': sleep_secs = atoi( optarg ); loops = -1; @@ -384,15 +405,16 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } if ( ref_dev_param == NULL ) { // No ref device specified. - fprintf( stderr, "A reference device has to be specified using the -i parameter.\n\n" ); - must_print_usage = 1; + if ( !must_print_usage ) + fprintf( stderr, "A reference device has to be specified using the -i parameter.\n\n" ); + must_print_usage = true; } if ( must_print_usage ) @@ -411,7 +433,7 @@ int main( int argc, char *argv[] ) return MBG_EXIT_CODE_NOT_SUPP; #endif - if ( quiet ) // make stdout unbuffered + if ( quiet ) // Make stdout unbuffered. setvbuf( stdout, NULL, _IONBF, 0 ); if ( log_fn ) @@ -423,10 +445,10 @@ int main( int argc, char *argv[] ) fclose( fp ); } - // We don't call mbg_open_device_by_param_chk() here since we - // want to print our own error message in case of failure. + // We don't call mbg_open_device_by_param_chk() here because + // we want to print our own error message in case of failure. rc = mbg_open_device_by_param( &dh_ref, ref_dev_param, 0, - ref_dev_fn, sizeof( ref_dev_fn ) ); + ref_dev_fn.s, sizeof( ref_dev_fn.s ) ); if ( mbg_rc_is_error( rc ) ) { @@ -437,7 +459,7 @@ int main( int argc, char *argv[] ) #if defined( DEBUG ) fprintf( stderr, "Ref device %s (%s) opened successfully.\n", - ref_dev_param, ref_dev_fn ); + ref_dev_param, ref_dev_fn.s ); #endif mbg_get_device_info( dh_ref, &dev_info_ref ); diff --git a/mbgctrl/mbgctrl.c b/mbgctrl/mbgctrl.c index 4c3c8bc..6e3334f 100644 --- a/mbgctrl/mbgctrl.c +++ b/mbgctrl/mbgctrl.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgctrl.c 1.27 2018/12/14 12:49:49Z martin REL_M $ + * $Id: mbgctrl.c 1.32 2021/11/08 18:01:31Z martin.burnicki REL_M $ * * Description: * Main file for mbgctrl program which sends commands and @@ -9,7 +9,17 @@ * * ----------------------------------------------------------------------- * $Log: mbgctrl.c $ - * Revision 1.27 2018/12/14 12:49:49Z martin + * Revision 1.32 2021/11/08 18:01:31Z martin.burnicki + * Account for modified MBG_DEV_FN type. + * Revision 1.31 2021/04/12 21:57:56 martin + * Updated printing of usage information. + * Revision 1.30 2021/03/22 17:56:13 martin + * Updated a bunch of comments, and a few output messages. + * Revision 1.29 2021/03/12 11:49:28 martin + * Corrected the wording of some comments. + * Revision 1.28 2020/02/24 11:17:46 martin + * Removed inclusion of obsolete header pcpsutil.h. + * Revision 1.27 2018/12/14 12:49:49 martin * Introduced new command COLDBOOT. * Use new function mbg_open_device_by_param_chk(). * Fixed compiler warnings and doxygen comment. @@ -21,7 +31,7 @@ * Account for renamed library symbols. * Revision 1.23 2017/07/05 19:10:07 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Bugfix: accept parameter keyword only when substring is found at the * start of the parameter string. * Support configuring PTP parameters incl. unicast @@ -62,7 +72,7 @@ * Don't use printf() without format, which migth produce warnings * with newer gcc versions. * Revision 1.13 2008/11/07 10:25:49 martin - * Support modification of a card's ENABLE_FLAGS. + * Support modification of the ENABLE_FLAGS of a device. * Changes due to renamed library function. * Changes due to renamed library function. * Revision 1.12 2008/09/15 14:20:21 martin @@ -84,13 +94,13 @@ * Support configuration of some standard time zones, * also for GPS devices. * Revision 1.5 2003/07/31 13:48:54 martin - * Added function to set COM port parms for GPS clocks. + * Added function to set COM port parms for GPS devices. * Usage shows which parameters are supported by a device. * Revision 1.4 2003/04/25 10:27:58 martin * Use new functions from mbgdevio library. * New program version v2.1. * Revision 1.3 2002/08/22 14:52:49 martin - * Added function to set clock's COM port parameters. + * Added function to set COM port parameters of a device. * Revision 1.2 2001/12/03 16:04:46 martin * New program version 1.2. * Added new function set_event_time(). @@ -99,21 +109,20 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> #include <deviohlp.h> #include <pcpsmktm.h> -#include <pcpsutil.h> #include <cfg_hlp.h> #include <myutil.h> #include <gpsutils.h> #include <cnv_wday.h> -#include <toolutil.h> +#include <toolutil.h> // Common utility functions. #include <ptp_util.h> #include <lan_util.h> #include <str_util.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -122,7 +131,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. #define RC_USAGE 1 @@ -139,7 +148,7 @@ static const char str_spc_wildcard[] = " (wildcard)"; static TZDL tzdl_utc = DEFAULT_TZDL_UTC; static TZDL tzdl_cet_cest = DEFAULT_TZDL_CET_CEST_EN; static TZDL tzdl_eet_eest = DEFAULT_TZDL_EET_EEST_EN; -static long max_tzdl_offs = 0x7FFFFFFFL; // max val for int32_t +static long max_tzdl_offs = 0x7FFFFFFFL; // Max. val for int32_t. static const char tz_info_utc[] = TZ_INFO_UTC; static const char tz_info_cet_cest[] = TZ_INFO_CET_CEST_EN; @@ -172,7 +181,7 @@ static const char no_cab_len[] = "does not support antenna signal delay compensa /** - * @brief A type used to pass print control flags to functions + * @brief A type used to pass print control flags to functions. * * @see ::CTRL_FLAG_MASKS */ @@ -180,7 +189,7 @@ typedef int CTRL_FLAGS; /** - * @brief flag masks used with ::CTRL_FLAGS + * @brief Flag masks used with ::CTRL_FLAGS. * * @see ::CTRL_FLAGS */ @@ -210,20 +219,20 @@ typedef struct OPT_HANDLER_SPEC_S SHOW_FNC *show_fnc; const char *cmd_info; const char *not_supp_msg; - uint32_t flags; ///< see ::OPT_FLAG_MASKS + uint32_t flags; ///< See ::OPT_FLAG_MASKS. } OPT_HANDLER_SPEC; enum OPT_FLAG_BITS { - OPT_SUPP_CMD_IDX_BIT, ///< e.g. COM0=, COM1=, etc. vs. TZ= + OPT_SUPP_CMD_IDX_BIT, ///< E.g. COM0=, COM1=, etc. vs. TZ=. N_OPT_FLAG_BITS }; enum OPT_FLAG_MASKS { - OPT_SUPP_CMD_IDX = ( 1UL << OPT_SUPP_CMD_IDX_BIT ) ///< see ::OPT_SUPP_CMD_IDX_BIT + OPT_SUPP_CMD_IDX = ( 1UL << OPT_SUPP_CMD_IDX_BIT ) ///< See ::OPT_SUPP_CMD_IDX_BIT. }; OPT_HANDLER_SPEC ohs_pout = @@ -310,8 +319,7 @@ static const char *ptp_roles_short[] = PTP_ROLE_STRS_SHORT; static const PTP_CLOCK_ID clock_id_wildcard = PTP_CLOCK_ID_WILDCARD; -//##+++++++++++++++++++ -// If unicast is not supported for a PTP device then the device is definitely +// If unicast is not supported for a PTP device, the device is definitely // a multicast slave, in which case index 0 returns the correct role name. #define _ptp_role_name( _i ) \ ( ( (_i) < N_PTP_ROLES ) ? ptp_roles[_i] : str_unknown ) @@ -328,8 +336,6 @@ static const char pout_name_shift[] = "SHIFT"; - - static /*HDR*/ __attribute__( ( format( printf, 4, 5 ) ) ) int usage_line( const INDENTS *p_ind, const OPT_HANDLER_SPEC *p_opt, @@ -337,15 +343,15 @@ int usage_line( const INDENTS *p_ind, const OPT_HANDLER_SPEC *p_opt, { int n = 0; - // print left margin, if not 0 + // Print left margin, if not 0. if ( p_ind->indent_1 ) n += printf( "%*s", p_ind->indent_1, str_empty ); - // print command name + // Print command name. if ( p_opt ) n += printf( "%s", p_opt->cmd_name ); - // print the command parameters, if specified + // Print the command parameters, if specified. if ( cmd_parm ) { if ( p_opt && ( p_opt->flags & OPT_SUPP_CMD_IDX ) ) @@ -354,13 +360,13 @@ int usage_line( const INDENTS *p_ind, const OPT_HANDLER_SPEC *p_opt, n += printf( "=%s", cmd_parm ); } - // print command comment which can be a format string - // expecting additional parameters + // Print command comment, which can be a format string + // expecting additional parameters. if ( cmd_comment_fmt ) { va_list arg_list; - // indent the comment string + // Indent the comment string. if ( p_ind->indent_2 ) { int w = p_ind->indent_2 - n; @@ -399,7 +405,7 @@ static /*HDR*/ __attribute__( ( format( printf, 2, 3 ) ) ) int usage_note( int indent, const char *fmt, ... ) { - // print left margin, if not 0 + // Print left margin, if not 0. int n = print_indent( indent ); if ( fmt ) @@ -520,14 +526,15 @@ void err_msg( const PCPS_DEV *p_dev, const char *msg ) static /*HDR*/ -int set_tz_code( MBG_DEV_HANDLE dh, PCPS_TZCODE tzcode, const char *s ) +int set_tz_code( MBG_DEV_HANDLE dh, PCPS_TZCODE tzcode, const char *info ) { int rc = mbg_set_tzcode( dh, &tzcode ); if ( mbg_cond_err_msg( rc, "mbg_set_tzcode" ) ) return rc; - printf( "The clock's time zone setting has been set to %s.\n", s ); + if ( info ) + printf( "The time zone configuration of the device has been set to %s.\n", info ); return MBG_SUCCESS; @@ -544,7 +551,7 @@ int set_gps_tzdl( MBG_DEV_HANDLE dh, const TZDL *tzdl, const char *info ) return rc; if ( info ) - printf( "The clock's time zone setting has been set to %s.\n", info ); + printf( "The time zone configuration of the device has been set to %s.\n", info ); return MBG_SUCCESS; @@ -624,7 +631,7 @@ int set_tzdl_offs( MBG_DEV_HANDLE dh, const char *s ) TZDL tzdl = tzdl_utc; long tzdl_offs = atol( s ); - if ( labs( tzdl_offs ) > max_tzdl_offs ) // max val for int32_t + if ( labs( tzdl_offs ) > max_tzdl_offs ) // Max. val for int32_t. { fprintf( stderr, "** Time zone offset %li exceeds range (%li..%li)\n", tzdl_offs, -max_tzdl_offs, max_tzdl_offs ); @@ -830,18 +837,18 @@ int show_ptp_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info ) static /*HDR*/ /** - * @brief Lookup a string in a string table and return the table index + * @brief Lookup a string in a string table and return the table index. * - * @param s The string to be searched for in the string table - * @param tbl A table of strings to be searched - * @param n_entries The number of strings in the string table - * @param supp_mask A string with a given index is only supported if the - * corresponding bit is set in this mask. - * @param info A descriptive name of the parameter which is to be - * set to the index of the searched string + * @param[in] s The string to be searched for in the string table. + * @param[in] tbl A table of strings to be searched. + * @param[in] n_entries The number of strings in the string table. + * @param[in] supp_mask A string with a given index is only supported if the + * corresponding bit is set in this mask. + * @param[in] info A descriptive name of the parameter which is to be + * set to the index of the searched string. * - * @return >=0 A valid, supported table index - * <0 Unknown or unsupported parameter + * @return @b >=0 for a valid, supported table index, or<br> + * @b <0 in case of an unknown or unsupported parameter. */ int get_chk_str_table_idx( const char *s, const char *tbl[], int n_entries, uint32_t supp_mask, const char *info ) @@ -870,15 +877,15 @@ int get_chk_str_table_idx( const char *s, const char *tbl[], int n_entries, static /*HDR*/ /** - * @brief Lookup a parameter in an argument list and check if a colon is appended + * @brief Lookup a parameter in an argument list and check if a colon is appended. * - * @param arg An argument list of the form: "name:val,name:val,..." - * @param id A parameter name searched for in the argument list - * @param p A pointer to a (char *) which is set to the beginning - * of the value part of a parameter string + * @param[in] arg An argument list of the form "name:val,name:val,...". + * @param[in] id A parameter name searched for in the argument list. + * @param[out] p A pointer to a (char *) which is set to the beginning + * of the value part of a parameter string. * - * @return ::MBG_SUCCESS on success. If parameter has been found then - * @p *p is set to the parameter value, else to NULL. + * @return ::MBG_SUCCESS on success. If parameter has been found, + * @p *p is set to the parameter value, else to @a NULL. * ::MBG_ERR_PARM_FMT if syntax error, i.e. missing colon. */ int chk_parm_name( const char *arg, const char *id, char **p ) @@ -896,7 +903,7 @@ int chk_parm_name( const char *arg, const char *id, char **p ) } if ( p ) - *p = cp; // may be NULL + *p = cp; // May be NULL. return MBG_SUCCESS; @@ -906,24 +913,24 @@ int chk_parm_name( const char *arg, const char *id, char **p ) static /*HDR*/ /** - * @brief Lookup a parameter in an argument list and check if the value string is valid + * @brief Lookup a parameter in an argument list and check if the value string is valid. * * This function expects that the parameter value is a known string which can * be found in a table of known strings. A bit mask indicates if a string with * a given table index is supported, or not. * - * @param arg An argument list of the form: "name:val,name:val,..." - * @param id The name of the argument to be checked. - * @param tbl A table of strings with predefined parameter values - * @param n_entries The number of strings in the string table - * @param supp_mask A string with a given index is only supported if the - * corresponding bit is set in this mask. - * @param info A descriptive name of the parameter which is to be - * set to the index of the searched string + * @param[in] arg An argument list of the form "name:val,name:val,...". + * @param[in] id The name of the argument to be checked. + * @param[in] tbl A table of strings with predefined parameter values. + * @param[in] n_entries The number of strings in the string table. + * @param[in] supp_mask A string with a given index is only supported if the + * corresponding bit is set in this mask. + * @param[in] info A descriptive name of the parameter which is to be + * set to the index of the searched string. * - * @return >=0 A valid, supported table index - * -1 Parameter not found - * -2 Unknown or unsupported parameter, or syntax error + * @return @b >=0 A valid, supported table index<br> + * @b -1 Parameter not found<br> + * @b -2 Unknown or unsupported parameter, or syntax error. */ int chk_tbl_parm( const char *arg, const char *id, const char *tbl[], int n_entries, uint32_t supp_mask, const char *info ) @@ -954,17 +961,17 @@ static /*HDR*/ * * Check and save the numeric parameter if in a valid range. * - * @param arg An argument list of the form: "name:val,name:val,..." - * @param id The name of the argument to be checked. - * @param p A pointer to a variable where the parameter value is - * saved if valid - * @param range_min The minimum allowed value for the parameter - * @param range_max The maximum allowed value for the parameter - * @param is_supported A flag indicating if the parameter is actually supported - * @param info A descriptive name of the parameter + * @param[in] arg An argument list of the form "name:val,name:val,..." + * @param[in] id The name of the argument to be checked. + * @param[in] p A pointer to a variable where the parameter value is + * saved if valid. + * @param[in] range_min The minimum allowed value for the parameter. + * @param[in] range_max The maximum allowed value for the parameter. + * @param[in] is_supported A flag indicating if the parameter is actually supported. + * @param[in] info A descriptive name of the parameter. * - * @return >=0 A valid, supported table index - * -1 Parameter not found, or out of range + * @return @b >=0 A valid, supported table index<br> + * @b -1 Parameter not found, or out of range. */ int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_min, int16_t range_max, int is_supported, const char *info ) @@ -972,10 +979,10 @@ int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_m char *cp; int idx = chk_parm_name( arg, id, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. return idx; - if ( cp ) // parameter found + if ( cp ) // Parameter found. { if ( !is_supported ) err_unicast_nsupp = 1; @@ -1020,13 +1027,13 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) const char *err_info = NULL; int rc = mbg_get_all_ptp_cfg_info( dh, &all_ptp_cfg_info ); - if ( rc < 0 ) - return rc; // failed to read current settings and capabilities + if ( mbg_rc_is_error( rc ) ) + return rc; // Failed to read current settings and capabilities. err_unicast_nsupp = 0; - // save a copy of the current settings + // Save a copy of the current settings. prv_all_ptp_cfg_info = all_ptp_cfg_info; p_info = &all_ptp_cfg_info.ptp_cfg_info; @@ -1034,15 +1041,15 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) unicast_supported = ( p_info->supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) != 0; p_uc_limits = &all_ptp_cfg_info.ptp_uc_master_cfg_limits; - // The pointers below need to be updated whenever uc_master_idx is changed + // The pointers below need to be updated whenever uc_master_idx is changed. p_uc_info = &all_ptp_cfg_info.all_ptp_uc_master_info_idx[uc_master_idx].info; p_uc_settings = &p_uc_info->settings; - // Network protocol + // Network protocol. idx = chk_tbl_parm( arg, ptp_name_net, nw_prot_short, N_PTP_NW_PROT, p_info->supp_nw_prot, "network protocol type" ); - if ( idx >= 0 ) // valid parameter found + if ( idx >= 0 ) // Valid parameter found. p_settings->nw_prot = idx; else if ( idx < -1 ) @@ -1051,10 +1058,10 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) goto fail; } - // Delay Mechanism + // Delay Mechanism. idx = chk_tbl_parm( arg, ptp_name_del, delay_mech, N_PTP_DELAY_MECH, p_info->supp_delay_mech, "delay mechanism" ); - if ( idx >= 0 ) // valid parameter found + if ( idx >= 0 ) // Valid parameter found. p_settings->delay_mech = idx; else if ( idx < -1 ) @@ -1067,13 +1074,13 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) // Domain Number idx = chk_parm_name( arg, ptp_name_dom, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = ptp_name_dom; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); // TODO Must check range!! @@ -1084,13 +1091,13 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) // V1 Hardware compatibility flag idx = chk_parm_name( arg, ptp_name_v1, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = ptp_name_v1; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); @@ -1113,11 +1120,11 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) //---- unicast stuff ---- - // PTP role + // PTP role. supp_mask = get_supp_ptp_role_mask( p_info->supp_flags ); idx = chk_tbl_parm( arg, ptp_name_role, ptp_roles_short, N_PTP_ROLES, supp_mask, "PTP role" ); - if ( idx >= 0 ) // valid parameter found + if ( idx >= 0 ) // Valid parameter found. { if ( !unicast_supported ) err_unicast_nsupp = 1; @@ -1125,30 +1132,30 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) p_settings->ptp_role = idx; } else - if ( idx < -1 ) // parameter error + if ( idx < -1 ) // Parameter error. { err_info = ptp_name_role; goto fail; } - // GM Host + // GM Host. idx = chk_parm_name( arg, ptp_name_gmip, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = ptp_name_gmip; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { if ( !unicast_supported ) err_unicast_nsupp = 1; else { - // currently IP addresses are accepted only, so check for - // a valid IPv4 address + // Currently, only IP addresses are accepted, so check for + // a valid IPv4 address. if ( str_to_ip4_addr( &ip4addr, cp ) > 0 ) { snprint_ip4_addr( ws, sizeof( ws ), &ip4addr, NULL ); @@ -1166,16 +1173,16 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } - // GM Clock ID + // GM Clock ID. idx = chk_parm_name( arg, ptp_name_gmid, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = ptp_name_gmid; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { if ( !unicast_supported ) err_unicast_nsupp = 1; @@ -1184,7 +1191,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) PTP_CLOCK_ID gm_clock_id; // Check if specified GM ID is wildcard. - if ( *cp == '*' ) // TODO check if next char is separator + if ( *cp == '*' ) // TODO Check if next char is a separator. { gm_clock_id = clock_id_wildcard; idx = sizeof( gm_clock_id ); @@ -1207,23 +1214,23 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } - // GM Target Port ID + // GM Target Port ID. idx = chk_parm_name( arg, ptp_name_pid, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = ptp_name_pid; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { if ( !unicast_supported ) err_unicast_nsupp = 1; else { // Check if specified Port ID is wildcard. - if ( *cp == '*' ) // TODO check if next char is separator + if ( *cp == '*' ) // TODO Check if next char is separator. p_uc_settings->gm_port_id = PTP_PORT_ID_WILDCARD; else p_uc_settings->gm_port_id = (PTP_PORT_ID) strtoul( cp, NULL, 0 ); @@ -1234,7 +1241,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } - // Sync Message Rate + // Sync Message Rate. idx = chk_int16_parm( arg, ptp_name_smi, ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ? &p_settings->sync_intv : &p_uc_settings->sync_intv, @@ -1247,7 +1254,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } - // Announce Message Rate + // Announce Message Rate. idx = chk_int16_parm( arg, ptp_name_ami, ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ? &p_settings->ann_intv : &p_uc_settings->ann_intv, @@ -1260,7 +1267,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } - // Delay Request Interval Rate + // Delay Request Interval Rate. idx = chk_int16_parm( arg, ptp_name_dri, ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ? &p_settings->delay_req_intv : &p_uc_settings->delay_req_intv, @@ -1274,7 +1281,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) - // Message Duration + // Message Duration. idx = chk_int16_parm( arg, ptp_name_dur, (int16_t *) &p_uc_settings->message_duration, PTP_UC_MSG_DURATION_MIN, PTP_UC_MSG_DURATION_MAX, unicast_supported, "msg. duration" ); @@ -1317,17 +1324,17 @@ int ip4_check_parm( const char *s, IP4_INFO *p ) int n; if ( strncmp( s, p->name, l ) != 0 ) - return 0; // parameter does not match + return 0; // Parameter does not match. if ( s[l] != ':' ) - goto fail; // parameter syntax error: name not followed by colon + goto fail; // Parameter syntax error: name not followed by colon. l++; n = str_to_ip4_addr( p->addr, &s[l] ); if ( n < 0 ) - goto fail; // parameter syntax error: failed to convert numeric address + goto fail; // Parameter syntax error: failed to convert numeric address. l += n; @@ -1375,15 +1382,15 @@ int set_lan_intf( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) { rc = ip4_check_parm( arg, &ip4_info[i] ); - if ( rc == 0 ) // check next + if ( rc == 0 ) // Check next. continue; - if ( rc < 0 ) // error + if ( rc < 0 ) // Error. goto invalid_msg; arg += rc; - if ( *arg == 0 ) // end of parameter string + if ( *arg == 0 ) // End of parameter string. goto done; if ( *arg != ',' ) @@ -1394,29 +1401,29 @@ int set_lan_intf( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) } -done: // now check static configuration - if ( ip4_settings.ip_addr == 0 ) // no IP address specified on the command line - ip4_settings.ip_addr = prv_ip4_settings.ip_addr; // use previous IP address +done: // Now check static configuration. + if ( ip4_settings.ip_addr == 0 ) // No IP address specified on the command line. + ip4_settings.ip_addr = prv_ip4_settings.ip_addr; // Use previous IP address. - if ( ip4_settings.ip_addr == 0 ) // no IP address specified at all + if ( ip4_settings.ip_addr == 0 ) // No IP address specified at all. { printf( "*** Aborting: No IP address specified\n" ); goto invalid; } - if ( ip4_settings.netmask == 0 ) // no network mask specified on the command line - ip4_settings.netmask = prv_ip4_settings.netmask; // use previous network mask + if ( ip4_settings.netmask == 0 ) // No network mask specified on the command line. + ip4_settings.netmask = prv_ip4_settings.netmask; // Use previous network mask. - if ( ip4_settings.netmask == 0 ) // no network mask specified at all + if ( ip4_settings.netmask == 0 ) // No network mask specified at all. { printf( "*** Aborting: No network mask specified\n" ); goto invalid; } - // the default broadcast address is computed from the IP address and the network mask + // The default broadcast address is computed from the IP address and the network mask. default_broad_addr = ip4_settings.ip_addr | ~ip4_settings.netmask; - if ( ip4_settings.broad_addr == 0 ) // no broadcast address specified on the command line + if ( ip4_settings.broad_addr == 0 ) // No broadcast address specified on the command line. ip4_settings.broad_addr = default_broad_addr; else if ( ip4_settings.broad_addr != default_broad_addr ) @@ -1433,7 +1440,7 @@ done: // now check static configuration ip4_settings.gateway = prv_ip4_settings.gateway; ip4_settings.flags = prv_ip4_settings.flags & ~IP4_MSK_DHCP; - // fall through to save: + // Fall through to save: save: rc = mbg_set_ip4_settings( dh, &ip4_settings ); @@ -1446,10 +1453,10 @@ save: invalid_msg: printf( "*** Warning: invalid LAN interface parameter syntax\n" ); - // fall through to invalid: + // Fall through to invalid: invalid: - return MBG_ERR_CFG; // invalid parameter or parameter syntax error + return MBG_ERR_CFG; // Invalid parameter or parameter syntax error. } // set_lan_intf @@ -1491,7 +1498,7 @@ int set_gps_pos( MBG_DEV_HANDLE dh, const char *gp ) if ( mbg_cond_err_msg( rc, "mbg_set_gps_pos_lla" ) ) return rc; - printf( "The clock's receiver position has been set to lat=%+.4f, lon=%+.4f, alt=%.0fm\n", + printf( "The receiver position of the device has been set to lat=%+.4f, lon=%+.4f, alt=%.0fm\n", new_pos_lla[LAT] * r2d, new_pos_lla[LON] * r2d, new_pos_lla[ALT] ); return rc; @@ -1523,7 +1530,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, // Either a date string, a time string, or both // may have been passed to this function. - // If either of them is NULL read the current date/time + // If either of them is NULL, read the current date/time // as default values. if ( sdate == NULL || stime == NULL ) { @@ -1552,7 +1559,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, { rc = sscanf( stime, "%u:%u:%u.%u", &hour, &min, &sec, &sec100 ); - if ( ( rc < 2 ) // at least hours and minutes are required + if ( ( rc < 2 ) // At least hours and minutes are required. || ( hour > 23 ) || ( min > 59 ) || ( sec > 60 ) @@ -1563,35 +1570,35 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, } } - // GPS and non-GPS cards require different API calls which use + // GPS and non-GPS devices require different API calls that require // different structures to set the on-board date and time, // so we have to distinguish. - if ( _pcps_is_gps( p_dev ) ) // is a GPS card + if ( _pcps_is_gps( p_dev ) ) // Is a GPS card. { ttm.channel = -1; - if ( sdate ) // new date + if ( sdate ) // New date. { ttm.tm.year = year; ttm.tm.month = month; ttm.tm.mday = mday; } - else // copy current date as default + else // Copy current date as default. { ttm.tm.year = u.t.year + 2000; ttm.tm.month = u.t.month; ttm.tm.mday = u.t.mday; } - if ( stime ) // new time + if ( stime ) // New time. { ttm.tm.hour = hour; ttm.tm.min = min; ttm.tm.sec = sec; ttm.tm.frac = sec100; } - else // copy current time as default + else // Copy current time as default. { ttm.tm.hour = u.t.hour; ttm.tm.min = u.t.min; @@ -1599,10 +1606,10 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, ttm.tm.frac = u.t.sec100; } - ttm.tm.frac *= 100000; // fracs are in 100 ns units + ttm.tm.frac *= 100000; // Fractions are in 100 ns units. #if 0 - // Existing versions of the GPS cards just take + // Existing versions of the GPS devices just take // TTM.tm as local time without accounting for // the status flags, or UTC offset. // Instead, the TTM.tm time is converted on-board @@ -1618,11 +1625,11 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, if ( mbg_cond_err_msg( rc, "mbg_set_gps_time" ) ) return rc; } - else // is not a GPS card + else // Is not a GPS card. { - if ( sdate ) // new date + if ( sdate ) // New date. { - // determine the day-of-week for the given date + // Determine the day-of-week for the given date. struct tm tm = { 0 }; tm.tm_year = year - 1900; @@ -1638,7 +1645,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, u.stime.wday = _wday_sun06_to_mon17( tm.tm_wday ); } - if ( stime ) // new time + if ( stime ) // New time. { u.stime.hour = hour; u.stime.min = min; @@ -1647,7 +1654,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, } if ( u.stime.wday == 0 ) - u.stime.wday = 1; // dummy + u.stime.wday = 1; // Dummy. rc = mbg_set_time( dh, &u.stime ); @@ -1670,7 +1677,7 @@ int check_setup_receiver_info( MBG_DEV_HANDLE dh, RECEIVER_INFO *p_ri ) // Set up the RECEIVER_INFO structure only if this has not been done // before. Check the ticks_per_sec field to see if the structure - // has already been set up or not. + // has already been set up, or not. if ( p_ri->ticks_per_sec == 0 && p_ri->model_code == 0 ) { rc = mbg_setup_receiver_info( dh, NULL, p_ri ); @@ -1684,7 +1691,20 @@ int check_setup_receiver_info( MBG_DEV_HANDLE dh, RECEIVER_INFO *p_ri ) static /*HDR*/ -// returns a negative error code on failure, or the number of supported COM ports on success +/** + * @brief Read all configuration info of the onboard serial ports. + * + * Check and set up the ::RECEIVER_INFO first, if required. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * @param[out] p_rpcfg Address of a ::RECEIVER_PORT_CFG structure to be set up. + * @param[in] p_dev Address of a ::PCPS_DEV structure associated with the device. + * @param[in,out] p_ri Address of a ::RECEIVER_INFO associated with the device, + * set up first, if required. + * + * @return The (positive) number of onboard COM ports on success, + * or one of the (negative) @ref MBG_ERROR_CODES on error. + */ int check_get_receiver_port_cfg( MBG_DEV_HANDLE dh, RECEIVER_PORT_CFG *p_rpcfg, const PCPS_DEV *p_dev, RECEIVER_INFO *p_ri ) { @@ -1822,7 +1842,7 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char * int flags; int i; - // load current settings and supported settings + // Load current settings and supported settings. rc = mbg_get_serial_settings( dh, p_dev, &rpcfg, p_ri ); if ( mbg_cond_err_msg( rc, "mbg_get_serial_settings" ) ) @@ -1832,30 +1852,30 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char * cp = parm_str; p_ps->parm.baud_rate = strtoul( cp, &p_tail, 10 ); - if ( p_tail == cp ) // no number found + if ( p_tail == cp ) // No number found. goto invalid; cp = p_tail; - if ( *cp++ != ',' ) // separator before framing missing + if ( *cp++ != ',' ) // Separator before framing missing. goto invalid; for ( i = 0; i < sizeof( p_ps->parm.framing ); i++ ) { int c = *cp; - if ( !isalnum( c ) ) // stop copying if non-alpha and non-digit + if ( !isalnum( c ) ) // Stop copying if non-alpha and non-digit. break; p_ps->parm.framing[i] = *cp++; } - p_ps->parm.framing[i] = 0; // force terminating 0 + p_ps->parm.framing[i] = 0; // Force terminating 0. - p_ps->parm.handshake = HS_NONE; // this is the only supported setting + p_ps->parm.handshake = HS_NONE; // This is the only supported setting. - // get optional string type index + // Get optional string type index. if ( *cp++ != ',' ) goto done_parm_str; @@ -1868,7 +1888,7 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char * cp = p_tail; - // get optional string mode index + // Get optional string mode index. if ( *cp++ != ',' ) goto done_parm_str; @@ -1881,16 +1901,16 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char * done_parm_str: - // check if the new parameter set is valid + // Check if the new parameter set is valid. flags = check_valid_port_info( p_pi, rpcfg.stii, p_ri->n_str_type ); - if ( flags ) // parameters not valid + if ( flags ) // Parameters not valid. { print_port_info_errors( "COM", port_num, flags, &rpcfg ); goto invalid; } - // save new parameters + // Save new parameters. rc = mbg_save_serial_settings( dh, p_dev, &rpcfg, port_num ); if ( mbg_cond_err_msg( rc, "mbg_save_serial_settings" ) ) @@ -1898,7 +1918,7 @@ done_parm_str: snprint_port_cfg( ws, sizeof( ws ), port_num, &rpcfg ); - printf( "The clock's COM%u port has been set to %s.\n", port_num, ws ); + printf( "The COM%u port of the device has been set to %s.\n", port_num, ws ); return MBG_SUCCESS; @@ -1912,14 +1932,26 @@ invalid: static /*HDR*/ -// returns a negative error code on failure, or the number of supported programmable pulse outputs on success +/** + * @brief Read all configuration info of the onboard programmable pulse outputs. + * + * Check and set up the ::RECEIVER_INFO first, if required. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * @param[out] api Address of an array of ::ALL_POUT_INFO_IDX structures to be set up. + * @param[in,out] p_ri Address of a ::RECEIVER_INFO associated with the device, + * set up first, if required. + * + * @return The (positive) number of supported programmable pulse outputs on success, + * or one of the (negative) @ref MBG_ERROR_CODES on error. + */ int check_get_pout_cfg( MBG_DEV_HANDLE dh, ALL_POUT_INFO_IDX api, RECEIVER_INFO *p_ri ) { int rc = check_setup_receiver_info( dh, p_ri ); // Set up the ALL_POUT_INFO_IDX structure only if this has not been done - // before. Check whether the number of ports is > 0 and the first port's - // baud rate is still 0 to see if the structure has already been set up. + // before. Check whether the number of ports is > 0 and the baud rate of the + // first port is still 0 to see if the structure has already been set up. if ( ( p_ri->n_prg_out > 0 ) && ( api[0].pout_info.supp_modes == 0 ) ) { @@ -1946,7 +1978,7 @@ int help_pout_arg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, int i; usage_line( p_ind, p_opt, NULL, "Show settings of the programmable output(s)" ); - usage_line( p_ind, p_opt, "MODE:<m>[,LEN:<l>][,INV:<i>][,OIS:<o>][,SHIFT:<s>]", "Configure programmable output <n>" ); // ### TODO + usage_line( p_ind, p_opt, "MODE:<m>[,LEN:<l>][,INV:<i>][,OIS:<o>][,SHIFT:<s>]", " Configure programmable output <n>" ); // TODO Fix indentation. printf( "\n" " where:\n" ); @@ -1973,8 +2005,9 @@ int help_pout_arg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, " <s> is an integer value, in nanoseconds.\n" " The maximum range is %+li to %+li ns,\n" " corresponding to %+li to %+li ms.\n" - " The effective resolution depends on the resolution of the device's internal clock,\n" - " which may be e.g. 10 or 20 ns, depending on the device type. See mbgctrl -?.\n\n", + " The effective resolution depends on the resolution of the internal clock\n" + " of the device, which may be e.g. 10 or 20 ns, depending on the device type.\n" + " See mbgctrl -?.\n\n", (long) DEFAULT_POUT_PULSE_SHIFT_MIN, (long) DEFAULT_POUT_PULSE_SHIFT_MAX, (long) DEFAULT_POUT_PULSE_SHIFT_MIN / 1000L, (long) DEFAULT_POUT_PULSE_SHIFT_MAX / 1000L ); @@ -2003,7 +2036,7 @@ int help_pout_arg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, N_POUT_MODES, pout_mode_names_eng, NULL, 0, ctrl_flags | CTRL_PRINT_IDX, p_ind_detailed ); - // ### TODO evaluate more properties + // TODO Evaluate more properties. usage_note( p_ind_detailed->indent_2, "Output level can%s be inverted.", ( pi->flags & POUT_NOT_INVERTIBLE ) ? str_spc_not : str_empty ); @@ -2038,7 +2071,7 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) RECEIVER_INFO ri = { 0 }; ALL_POUT_INFO_IDX api = { { 0 } }; ALL_POUT_INFO_IDX prv_api; - POUT_INFO *p_pi = &api[inst_num].pout_info; // ### TODO check inst_num range? + POUT_INFO *p_pi = &api[inst_num].pout_info; // TODO check inst_num range? POUT_SETTINGS *p_ps = &p_pi->pout_settings; const char *err_info = NULL; char *cp; @@ -2050,7 +2083,7 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) if ( mbg_cond_err_msg( rc, "check_get_pout_cfg" ) ) return rc; - n_pout = rc; // Contains now the number of programmable pulse outputs + n_pout = rc; // Now contains the number of programmable pulse outputs. // save current settings memcpy( prv_api, api, sizeof( prv_api ) ); @@ -2058,13 +2091,13 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) // Mode idx = chk_parm_name( s, pout_name_mode, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = pout_name_mode; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); @@ -2090,13 +2123,13 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) // Pulse len idx = chk_parm_name( s, pout_name_len, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = pout_name_len; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); @@ -2128,16 +2161,16 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) } - // "Inverted" flag + // "Inverted" flag. idx = chk_parm_name( s, pout_name_inv, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = pout_name_inv; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); @@ -2166,16 +2199,16 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) } - // "Only If Sync" flag + // "Only If Sync" flag. idx = chk_parm_name( s, pout_name_ois, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = pout_name_ois; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { idx = atoi( cp ); @@ -2204,16 +2237,16 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) } - // "Pulse Shift" parameter + // "Pulse Shift" parameter. idx = chk_parm_name( s, pout_name_shift, &cp ); - if ( mbg_rc_is_error( idx ) ) // parameter error + if ( mbg_rc_is_error( idx ) ) // Parameter error. { err_info = pout_name_shift; goto fail; } - if ( cp ) // parameter found + if ( cp ) // Parameter found. { long pulse_shift = atol( cp ); @@ -2269,7 +2302,7 @@ int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num ) if ( memcmp( p_ps, &prv_api[i].pout_info.pout_settings, sizeof( *p_ps ) ) ) { - // settings for this output have changed + // Settings for this output have changed. rc = mbg_set_gps_pout_settings( dh, p_ps, i ); if ( mbg_rc_is_error( rc ) ) @@ -2318,7 +2351,7 @@ int show_pout( MBG_DEV_HANDLE dh, const OPT_HANDLER_SPEC *p_opt, const PCPS_DEV const POUT_INFO *pi = &api[i].pout_info; const POUT_SETTINGS *ps = &pi->pout_settings; - // TODO: Actually the code below only shows the current mode, + // TODO Actually the code below only shows the current mode, // and whether the output signal is inverted, or not. // Full featured code should also display additional parameters // depending the selected mode. @@ -2328,19 +2361,19 @@ int show_pout( MBG_DEV_HANDLE dh, const OPT_HANDLER_SPEC *p_opt, const PCPS_DEV printf( "Output %i: ", i ); printf( "%s", _get_pout_mode_name( ps->mode ) ); - // Print pulse len, if supported by the mode + // Print pulse len, if supported by the mode. if ( _is_supported( ps->mode, POUT_MODES_MODE_PARAM_AS_PULSE_LEN ) ) { - // pulse len is 10 ms units, so multiply by 10 to get ms + // Pulse len is 10 ms units, so multiply by 10 to get ms. printf( ", len %u ms", (unsigned int) ps->mode_param * 10 ); if ( pi->flags & POUT_FIXED_PULSE_LEN ) printf( " (fix)" ); } - // ### FIXME check more mode_param usage, times etc. + // FIXME TODO check more mode_param usage, times etc. - // If outputs can be inverted then this doesn't depend on the current mode + // Whether outputs can be inverted doesn't depend on the current mode. if ( !( pi->flags & POUT_NOT_INVERTIBLE ) ) printf( ", %sinverted", ( ps->flags & POUT_INVERTED ) ? str_empty : str_not_spc ); @@ -2429,15 +2462,15 @@ int ef_check_parm( const char *s, EF_INFO *p ) size_t l = strlen( p->name ); if ( strncmp( s, p->name, l ) != 0 ) - return 0; // parameter does not match + return 0; // Parameter does not match. if ( s[l] != ':' ) - goto fail; // parameter syntax error: name not followed by colon + goto fail; // Parameter syntax error: name not followed by colon. l++; if ( s[l] != '0' && s[l] != '1' ) - goto fail; // parameter syntax error: colon not followed by '0' or '1' + goto fail; // Parameter syntax error: colon not followed by '0' or '1'. *p->flags = ( s[l] == '0' ) ? EF_OFF : p->on_flags; @@ -2472,7 +2505,7 @@ int set_enable_flags( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev if ( mbg_cond_err_msg( rc, "mbg_get_gps_enable_flags" ) ) return rc; - // Scan input parameters + // Scan input parameters. for (;;) { int i; @@ -2481,19 +2514,19 @@ int set_enable_flags( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev { rc = ef_check_parm( arg, &ef_parms[i] ); - if ( rc == 0 ) // check next + if ( rc == 0 ) // Check next. continue; - if ( rc < 0 ) // error + if ( rc < 0 ) // Error. return rc; arg += rc; - if ( *arg == 0 ) // done + if ( *arg == 0 ) // Done. goto save; if ( *arg != ',' ) - return MBG_ERR_CFG; // invalid parameter or parameter syntax error + return MBG_ERR_CFG; // Invalid parameter, or parameter syntax error. arg++; } @@ -2519,7 +2552,7 @@ int send_gps_cmd( MBG_DEV_HANDLE dh, ushort cmd ) if ( mbg_cond_err_msg( rc, "mbg_set_gps_cmd" ) ) return rc; - printf( "NOTE: the command code %u has been sent to the GPS clock.\n", cmd ); + printf( "NOTE: the command code %u has been sent to the device.\n", cmd ); return MBG_SUCCESS; @@ -2567,17 +2600,17 @@ int set_event_time( MBG_DEV_HANDLE dh, const char *s ) PCPS_TIME_STAMP event_ts; int rc; - // set event at current system time + number of seconds + // Set event at current system time + number of seconds. event_time = time( NULL ) + strtol( s, NULL, 10 ); - event_ts.sec = (uint32_t) event_time; // Unix UTC seconds // TODO: check range / conversion - event_ts.frac = 0; // fraction of second, 0xFFFFFFFF == 0.99.. sec + event_ts.sec = (uint32_t) event_time; // POSIX UTC seconds, TODO check range / conversion. + event_ts.frac = 0; // Fraction of second, 0xFFFFFFFF == 0.99.. sec. rc = mbg_set_event_time( dh, &event_ts ); if ( mbg_cond_err_msg( rc, "mbg_set_event_time" ) ) return rc; - mbg_snprint_hr_tstamp( ws, sizeof( ws ), &event_ts, 0, 0 ); // raw timestamp? + mbg_snprint_hr_tstamp( ws, sizeof( ws ), &event_ts, 0, 0 ); // Raw timestamp? printf( "Event time set to UTC %s\n", ws ); return MBG_SUCCESS; @@ -2693,20 +2726,20 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, printf( "Usage: %s cmd [dev]\n" "\n" "where cmd can be one of the following:\n" - " BOOT set GPS clock to warm boot mode, sat info is kept\n" - " COLDBOOT set GPS clock to cold boot mode, all sat info is cleared\n" - " GPSPOS=x.x,y.y,z set GPS position to (lat,lon,alt)\n", + " BOOT Set GPS receiver to warm boot mode, sat info is kept.\n" + " COLDBOOT Set GPS receiver to cold boot mode, all sat info is cleared.\n" + " GPSPOS=x.x,y.y,z Set GPS receiver position to (lat,lon,alt).\n", pname ); - printf( " DATE=yyyy-mm-dd set on-board date to year, month, day-of-month\n" - " TIME=hh:mm:ss.hh set on-board time to hours, mins, secs, hundredths\n" + printf( " DATE=yyyy-mm-dd Set on-board date to year, month, day-of-month.\n" + " TIME=hh:mm:ss.hh Set on-board time to hours, mins, secs, hundredths.\n" ); - printf( " TIMESCALE show clock's time scale setting, if supported\n" - " TIMESCALE=<n> set clock's time scale to scale with index <n>\n" + printf( " TIMESCALE Show time scale of the device, if supported.\n" + " TIMESCALE=<n> Set time scale of the device to scale with index <n>.\n" ); n_time_scale = p_dev ? get_n_time_scale( dh, NULL ) : N_MBG_TIME_SCALE; @@ -2728,21 +2761,21 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, printf( " (Configurable time scales not supported by this device)\n" ); - printf( " TZOFFS show clock's time zone offset, if supported\n" - " TZOFFS=<n> set clock's basic time zone to UTC with additional offset, in seconds\n" + printf( " TZOFFS Show time zone offset of the device, if supported.\n" + " TZOFFS=<n> Set basic time zone of the device to UTC with additional offset, in seconds.\n" ); - printf( " TZ=UTC set time zone code to %s\n" - " TZ=CET set time zone code to %s\n" - " TZ=EET set time zone code to %s\n", + printf( " TZ=UTC Set time zone code to %s.\n" + " TZ=CET Set time zone code to %s.\n" + " TZ=EET Set time zone code to %s.\n", tz_info_utc, tz_info_cet_cest, tz_info_eet_eest ); - printf( " COMPARM show clock's COM port parameters\n" - " COM<n>=<bd>,<f>[,<t>[,<m>]] set parameters of clock's port COM<n>" + printf( " COMPARM Show COM port parameters of the device.\n" + " COM<n>=<bd>,<f>[,<t>[,<m>]] Set parameters of onboard port COM<n>" ); printf( ", where\n" @@ -2755,7 +2788,7 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, for ( i = 0; i < N_MBG_FRAMINGS; i++ ) printf( " %s", mbg_framing_strs[i] ); - printf( "\n <t> optional time string format index" ); + printf( "\n <t> is an optional time string format index" ); if ( p_dev ) { @@ -2769,7 +2802,7 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, } } - printf( "\n <m> optional time string mode index" ); + printf( "\n <m> is an optional time string mode index" ); if ( p_dev ) { @@ -2779,7 +2812,7 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, printf( "\n %u: %s", i, mode_names[i] ); printf( "\n" - " Please note not each baud rate, framing, string format and mode\n" + " Please note that not every baud rate, framing, string format and mode\n" " must necessarily be supported by every individual serial port.\n" ); } @@ -2789,83 +2822,83 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, printf( "\n" ); - printf( " EF show clock's enable flags\n" - " EF=SERIAL:0,PULSES:1,SYNTH:0 modify clock's enable flags\n" + printf( " EF Show enable flags.\n" + " EF=SERIAL:0,PULSES:1,SYNTH:0 Modify enable flags.\n" "\n" - " SERIAL controls the serial port output\n" - " PULSES controls pulse outputs and IRIG timecode output, if available\n" - " SYNTH controls a programmable synthesizer output, if available\n" + " SERIAL Controls the serial port output.\n" + " PULSES Controls pulse outputs and IRIG timecode output, if available.\n" + " SYNTH Controls a programmable synthesizer output, if available.\n" "\n" - " 0 or 1 controls when the corresponding output signals are enabled:\n" - " 0: only after the card has synchronized to its incoming signal\n" - " 1: immediately after power-up\n" + " 0 or 1 Controls when the corresponding output signals are enabled:\n" + " 0: only after the device has synchronized to its incoming signal,\n" + " 1: immediately after power-up.\n" "\n" " Please note that not every device supports enable flags.\n" "\n" ); - printf( " LAN show board's LAN interface settings\n" - " LAN=DHCP set LAN interface to be configured via DHCP\n" - " LAN=IP:<ip>[,NM:<nm>][,BA:<ba>][,GW:<gw>] set LAN interface to given static settings\n" + printf( " LAN Show LAN interface settings of the device.\n" + " LAN=DHCP Set LAN interface to be configured via DHCP.\n" + " LAN=IP:<ip>[,NM:<nm>][,BA:<ba>][,GW:<gw>] Set LAN interface to given static settings.\n" "\n" " where each of <ip>,<nm>,<ba>,<gw> is an IPv4 address of the form aaa.bbb.ccc.ddd, e.g.:\n" - " IP:192.168.1.115 specifies the IP address\n" - " NM:255.255.255.0 specifies the net mask\n" - " BA:192.168.1.255 specifies the broadcast address\n" - " GW:192.168.1.1 specifies the default gateway\n" + " IP:192.168.1.115 Specifies the IP address.\n" + " NM:255.255.255.0 Specifies the net mask.\n" + " BA:192.168.1.255 Specifies the broadcast address.\n" + " GW:192.168.1.1 Specifies the default gateway.\n" "\n" - " If no broadcast address is specified then the default broadcast address\n" + " If no broadcast address is specified, the default broadcast address\n" " is computed from the IP address and the network mask.\n" "\n" " Please note that not every device provides a LAN interface.\n" " Also, the IP values above are examples only. The real values to be used\n" - " depend on the settings of the network to which the card is attached.\n" + " depend on the settings of the network to which the device is attached.\n" "\n" ); - printf( " PTP show board's PTP settings\n" - " PTP=NP:<np>[,DM:<dm>][,DO:<do>][,HW:<hw>] set general PTP protocol parameters\n" + printf( " PTP Show PTP settings of the device.\n" + " PTP=NP:<np>[,DM:<dm>][,DO:<do>][,HW:<hw>] Set general PTP protocol parameters.\n" "\n" " where, e.g. :\n" - " NP:IP4 specifies UDP/IPv4 (Layer 3) as network protocol\n" - " NP:ETH specifies IEEE 802.3 (Layer 2) as network protocol\n" - " DM:E2E specifies end-to-end delay mechanism\n" - " DM:P2P specifies peer-to-peer delay mechanism\n" - " DO:0 specifies PTP domain number [0..255]\n" - " HW:1 specifies if the \"v1 hardware compatibility flag\" shall be set ('1') or disabled ('0')\n" - " (this is usually not required)\n" + " NP:IP4 Specifies UDP/IPv4 (Layer 3) as network protocol.\n" + " NP:ETH Specifies IEEE 802.3 (Layer 2) as network protocol.\n" + " DM:E2E Specifies end-to-end delay mechanism.\n" + " DM:P2P Specifies peer-to-peer delay mechanism.\n" + " DO:0 Specifies PTP domain number [0..255].\n" + " HW:1 Specifies if the \"v1 hardware compatibility flag\" shall be set ('1') or disabled ('0')\n" + " (this is usually not required).\n" "\n" ); - printf( " If the PTP device supports unicast slave mode then the following parameters\n" + printf( " If the PTP device supports unicast slave mode, the following parameters\n" " can be specified to configure a unicast master to be queried:\n" - " PTP=ROLE:<rl>[,GMIP:<ip>][,GMID:<id>][,PID:<po>][,SMI:<sr>][,AMI:<ar>][,DRI:<dr>][,DUR:<du>] set PTP unicast parameters\n" + " PTP=ROLE:<rl>[,GMIP:<ip>][,GMID:<id>][,PID:<po>][,SMI:<sr>][,AMI:<ar>][,DRI:<dr>][,DUR:<du>] Set PTP unicast parameters.\n" "\n" " where, e.g.:\n" - " ROLE:MCS specifies \"Multicast Slave\" PTP role\n" - " ROLE:UCS specifies \"Unicast Slave\" PTP role\n" - " GMIP:192.168.1.115 specifies the IP address of the grandmaster\n" - " GMID:FF:FF:FF:FF:FF:FF:FF:FF specifies the Clock ID of the grandmaster, or '*' as wildcard for all 'FF'\n" - " PID:1 specifies the target Port ID of the grandmaster port to be used, or '*' for wildcard\n" - " SMI:0 specifies the Sync Message Interval requested from the grandmaster in 2^x seconds [-6..6]\n" - " AMI:1 specifies the Announce Message Interval requested from the grandmaster in 2^x seconds [-6..6]\n" - " DRI:1 specifies the Delay Request Interval requested from the grandmaster in 2^x seconds [-6..6]\n" - " DUR:300 specifies the duration in seconds how long the master shall send messages to the slave until a timeout or renewal occurs\n" + " ROLE:MCS Specifies \"Multicast Slave\" PTP role.\n" + " ROLE:UCS Specifies \"Unicast Slave\" PTP role.\n" + " GMIP:192.168.1.115 Specifies the IP address of the grandmaster.\n" + " GMID:FF:FF:FF:FF:FF:FF:FF:FF Specifies the Clock ID of the grandmaster, or '*' as wildcard for all 'FF'.\n" + " PID:1 Specifies the target Port ID of the grandmaster port to be used, or '*' for wildcard.\n" + " SMI:0 Specifies the Sync Message Interval requested from the grandmaster in 2^x seconds [-6..6].\n" + " AMI:1 Specifies the Announce Message Interval requested from the grandmaster in 2^x seconds [-6..6].\n" + " DRI:1 Specifies the Delay Request Interval requested from the grandmaster in 2^x seconds [-6..6].\n" + " DUR:300 Specifies the duration in seconds how long the master shall send messages to the slave until a timeout or renewal occurs.\n" "\n" ); - printf( " ANT_CABLE_LEN show the configured antenna cable length\n" - " ANT_CABLE_LEN=<len> set the antenna cable length to be compensated to <len>, in meters.\n" + printf( " ANT_CABLE_LEN Show the configured antenna cable length.\n" + " ANT_CABLE_LEN=<len> Set the antenna cable length to be compensated to <len>, in meters.\n" "\n" - " Please note note this parameter is only supported with cards which provide\n" - " compensation of the antenna cable signal propagation delay, i.e. GPS cards.\n" + " Please note that this parameter can only be used with devices that support compensation\n" + " of the signal propagation delay of the antenna cable, e.g. with GPS/GNSS receivers.\n" "\n" ); if ( p_dev ) { if ( _pcps_has_event_time( p_dev ) ) - printf( " EVENT=<n> set event time to system time + <n> seconds\n" ); + printf( " EVENT=<n> Set event time to system time + <n> seconds.\n" ); } } // usage @@ -2897,7 +2930,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p int rc = MBG_SUCCESS; int error_occurred = 0; - must_print_usage = 0; + must_print_usage = false; for ( i = 1; i < argc; i++ ) { @@ -2905,7 +2938,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p error_occurred = 1; if ( rc == RC_USAGE ) - must_print_usage = 1; + must_print_usage = true; rc = MBG_SUCCESS; @@ -2913,7 +2946,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p ( strcmp( argv[i], "-h" ) == 0 ) || ( strcmp( argv[i], "--help" ) == 0 ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3006,7 +3039,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( *cp != 0 ) { printf( "** Invalid parameter: %s\n", argv[i] ); - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3039,10 +3072,10 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p port_num = strtoul( cp, &p_tail, 10 ); - if ( p_tail == cp ) // no COM port number specified + if ( p_tail == cp ) // No COM port number specified. { printf( "** Invalid COM port specification: %s\n", argv[i] ); - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3052,14 +3085,14 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p { printf( "** COM port number %lu exceeds maximum %u\n", port_num, p_ri->n_com_ports ); - must_print_usage = 1; + must_print_usage = true; continue; } if ( *cp != '=' ) { printf( "** Invalid COM port specification: %s\n", argv[i] ); - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3090,7 +3123,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p pout_num = strtoul( cp, &p_tail, 10 ); - if ( p_tail == cp ) // no POUT number specified + if ( p_tail == cp ) // No POUT number specified. { show_pout( dh, &ohs_pout, p_dev, "Current programmable outputs settings" ); continue; @@ -3102,14 +3135,14 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p { printf( "** Programmable output number %lu exceeds maximum %lu\n", pout_num, n_pout ); - must_print_usage = 1; + must_print_usage = true; continue; } if ( *cp != '=' ) { printf( "** Invalid programmable output specification: %s\n", argv[i] ); - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3142,7 +3175,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { printf( "*** Warning: invalid enable flag parameter syntax\n" ); - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3175,7 +3208,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3208,7 +3241,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3241,7 +3274,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3274,7 +3307,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3336,7 +3369,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( mbg_rc_is_error( rc ) ) { - must_print_usage = 1; + must_print_usage = true; continue; } @@ -3378,7 +3411,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p else { printf( "** Unknown command: %s\n", argv[i] ); - must_print_usage = 1; + must_print_usage = true; } #endif @@ -3425,14 +3458,14 @@ int main( int argc, char *argv[] ) // pass a device handle, so commands are not evaluated. check_cmd_line( argc, argv, dh, NULL, &ri, &rpcfg ); - rc = mbg_open_device_by_param_chk( &dh, dev_name, 0, tmp_dev_fn, - sizeof( tmp_dev_fn ) ); + rc = mbg_open_device_by_param_chk( &dh, dev_name, 0, tmp_dev_fn.s, + sizeof( tmp_dev_fn.s ) ); if ( mbg_rc_is_error( rc ) ) goto fail; - // get information about the device + // Get information about the device. rc = mbg_get_show_dev_info( dh, NULL, &dev ); if ( mbg_rc_is_error( rc ) ) diff --git a/mbgfasttstamp/mbgfasttstamp.c b/mbgfasttstamp/mbgfasttstamp.c index 4cdb8b2..9b94197 100644 --- a/mbgfasttstamp/mbgfasttstamp.c +++ b/mbgfasttstamp/mbgfasttstamp.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgfasttstamp.c 1.8 2018/11/15 12:12:32Z martin REL_M $ + * $Id: mbgfasttstamp.c 1.12 2021/04/12 21:58:08Z martin REL_M $ * * Description: * Main file for mbgfasttstamp program which demonstrates how to access @@ -9,11 +9,20 @@ * * ----------------------------------------------------------------------- * $Log: mbgfasttstamp.c $ - * Revision 1.8 2018/11/15 12:12:32Z martin + * Revision 1.12 2021/04/12 21:58:08Z martin + * Updated printing of usage information. + * Revision 1.11 2021/03/21 17:53:49 martin + * Updated some comments. + * Revision 1.10 2021/03/12 11:50:14 martin + * Corrected the wording of some comments. + * Revision 1.9 2020/11/04 17:16:24 martin + * Added option -C to support checking the continuity of the timestamps + * and status sequentially read from a device. + * Revision 1.8 2018/11/15 12:12:32 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.7 2017/07/05 18:55:22 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Abort if MM access not supported on the target OS. * Support signal handler to catch CTRL-C. * Added options to sleep between calls. @@ -43,17 +52,18 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. +#include <cmp_time_util.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #define MBG_FIRST_COPYRIGHT_YEAR 2007 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgfasttstamp"; @@ -63,21 +73,31 @@ static const char *pname = "mbgfasttstamp"; static int loops; static int burst_read; static int read_raw; +static int must_check_continuity; +static double max_allowed_delta; static long sleep_secs; static long sleep_usecs; -// The function below reads a number of time stamps and prints -// each timestamp immediately. This is not as fast as possible -// since printing the time stamp takes some time to execute. -// However, this can run continuously forever. - static /*HDR*/ +/** + * @brief Read and immediately print a number of timestamps. + * + * This doesn't read from thedevice as fast as possible + * because printing the timestamp takes some time to execute. + * However, this can run continuously forever. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES. + */ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh ) { int this_loops = loops; - PCPS_TIME_STAMP ts; + PCPS_TIME_STAMP ts = { 0 }; + PCPS_TIME_STAMP prv_ts = { 0 }; + int prv_ts_avail = 0; int32_t hns_latency = 0; for (;;) @@ -88,7 +108,13 @@ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh ) if ( mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp..." ) ) return rc; - mbg_print_hr_timestamp( &ts, hns_latency, NULL, read_raw, 1 ); // raw timestamp? + mbg_print_hr_timestamp( &ts, hns_latency, NULL, read_raw, 1 ); // Raw timestamp? + + if ( prv_ts_avail && must_check_continuity ) + mbg_check_continuity( &ts, &prv_ts, NULL, NULL, max_allowed_delta ); + + prv_ts = ts; + prv_ts_avail = 1; if ( this_loops > 0 ) this_loops--; @@ -96,13 +122,13 @@ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh ) if ( this_loops == 0 ) break; + // If this_loops is < 0, loop forever. + if ( sleep_secs ) sleep( sleep_secs ); else if ( sleep_usecs ) usleep( sleep_usecs ); - - // if this_loops is < 0 then loop forever } return MBG_SUCCESS; @@ -111,14 +137,20 @@ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh ) -// The function below takes a number of time stamps and saves -// them to a buffer. After the time stamps have been read -// a second loop prints the time stamps from the buffer. -// This way the time stamps are read in shorter intervals. -// However, this can not run continuously forever since -// the buffer size is somewhat limited. - static /*HDR*/ +/** + * @brief Read a number of time stamps to a buffer, and print them afterwards. + * + * After the time stamps have been read to the buffer, + * a second loop prints them from the buffer. + * This way the time stamps can be read as fast as possible, + * but this can not run continuously forever because the buffer size + * is somewhat limited. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES. + */ int show_fast_hr_timestamp_burst( MBG_DEV_HANDLE dh ) { PCPS_TIME_STAMP ts[MAX_TS_BURST]; @@ -151,7 +183,7 @@ int show_fast_hr_timestamp_burst( MBG_DEV_HANDLE dh ) for ( i = 0; i < this_loops; i++ ) { PCPS_TIME_STAMP *p_prv_ts = i ? &ts[i - 1] : NULL; - mbg_print_hr_timestamp( &ts[i], hns_latency[i], p_prv_ts, read_raw, 0 ); // raw timestamp? + mbg_print_hr_timestamp( &ts[i], hns_latency[i], p_prv_ts, read_raw, 0 ); // Raw timestamp? } return MBG_SUCCESS; @@ -192,16 +224,17 @@ void usage( void ) "This example program reads fast high resolution time stamps.\n" "\n" "This is done using memory mapped I/O in the kernel driver, so\n" - "this works only with cards which support memory mapped I/O." + "this works only with devices that support memory mapped I/O." ); mbg_print_help_options(); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-n num", "run num loops" ); - mbg_print_opt_info( "-b", "burst read" ); - mbg_print_opt_info( "-r", "read raw time stamps, no cycles" ); - mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" ); - mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-n num", "Run num loops" ); + mbg_print_opt_info( "-b", "Burst read first, then show results" ); + mbg_print_opt_info( "-r", "Read raw time stamps, no cycles" ); + mbg_print_opt_info( "-C val", "Check for continuity, max allowed delta (seconds, with fractions)" ); + mbg_print_opt_info( "-s num", "Sleep num seconds between calls (implies -c)" ); + mbg_print_opt_info( "-u num", "Sleep num microseconds between calls (implies -c)" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -215,8 +248,8 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters - while ( ( c = getopt( argc, argv, "bcn:rs:u:h?" ) ) != -1 ) + // Check command line parameters. + while ( ( c = getopt( argc, argv, "bcn:rC:s:u:h?" ) ) != -1 ) { switch ( c ) { @@ -236,6 +269,11 @@ int main( int argc, char *argv[] ) read_raw = 1; break; + case 'C': + must_check_continuity = 1; + max_allowed_delta = atof( optarg ) * 1E6; + break; + case 's': sleep_secs = atoi( optarg ); loops = -1; @@ -249,7 +287,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } diff --git a/mbggpscap/mbggpscap.c b/mbggpscap/mbggpscap.c index 75f73a6..b6f97fa 100644 --- a/mbggpscap/mbggpscap.c +++ b/mbggpscap/mbggpscap.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbggpscap.c 1.14 2018/11/15 12:12:36Z martin REL_M $ + * $Id: mbggpscap.c 1.19 2021/04/12 21:57:50Z martin REL_M $ * * Description: * Main file for mbggpscap program which demonstrates how to access @@ -13,7 +13,17 @@ * * ----------------------------------------------------------------------- * $Log: mbggpscap.c $ - * Revision 1.14 2018/11/15 12:12:36Z martin + * Revision 1.19 2021/04/12 21:57:50Z martin + * Updated printing of usage information. + * Revision 1.18 2021/03/21 17:56:33 martin + * Updated a bunch of comments. + * Revision 1.17 2021/03/12 11:50:22 martin + * Corrected the wording of some comments. + * Revision 1.16 2020/08/10 15:55:06 martin + * Fixed build with compilers that don't support 'long long'. + * Revision 1.15 2020/02/27 13:21:41Z martin + * New options -u and -Q. + * Revision 1.14 2018/11/15 12:12:36 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.13 2018/01/10 13:36:35 martin * Use current API mbg_get_serial_settings() to check @@ -24,7 +34,7 @@ * Added feature to log capture events to a file. * Revision 1.11 2017/07/05 18:59:14 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Improved code execution paths. * Improved reading capture events arriving at a high rate. * Support validation of capture signals arriving at a constant rate. @@ -66,30 +76,30 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> #include <deviohlp.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. #include <str_util.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <time.h> -#define USLEEP_INTV 10000 // [microseconds] +#define DEFAULT_USLEEP_INTV 10000 // [microseconds] #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbggpscap"; static int continuous; -static double nom_cap_intv; // nominal capture interval to check [s] -static double max_cap_jitter; // max allowed jitter [s] +static double nom_cap_intv; // Nominal capture interval to check, [s]. +static double max_cap_jitter; // Max. allowed jitter, [s]. static int raw; static int force_old_api; static int clear_buffer; @@ -98,21 +108,117 @@ static const char *log_fn; static int has_been_called; static int must_check_intv; static int query_only; -static ulong err_cnt; -static PCPS_HR_TIME prv_ucap; +static int query_continuously; +static int sleep_usecs = DEFAULT_USLEEP_INTV; + +static double delta_ucap; +static int jitter_exceeded; +static uint64_t jitter_exceed_cnt; +static uint64_t cap_overrun_cnt; +static uint64_t buf_overrun_cnt; + + + +static /*HDR*/ +/** + * @brief Show the current and max. number of entries in the capture FIFO buffer. + * + * Retrieve and print information on the maximum number of events that can + * be stored in the onboard FIFO, and the number of events that are currently + * stored. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * @param[out] p_uce Address of a ::PCPS_UCAP_ENTRIES variable to be filled. + * @param[in] info An optional string to be printed before the buffer information, may be @a NULL. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES. + * + * @see ::show_ucap_event + * @see ::mbg_get_ucap_entries + */ +int show_ucap_entries( MBG_DEV_HANDLE dh, PCPS_UCAP_ENTRIES *p_uce, const char *info ) +{ + int rc = mbg_get_ucap_entries( dh, p_uce ); + + if ( mbg_rc_is_success( rc ) ) + { + // Many devices report that they could save one more capture event + // than they actually do save, so adjust the reported value + // for a proper display. + if ( p_uce->max ) + p_uce->max--; + + if ( info ) + printf( "%s", info ); + + printf( "%u of %u entries used\n", + p_uce->used, p_uce->max ); + } + + return rc; + +} // show_ucap_entries static /*HDR*/ /** - * @brief Show a user capture event in ::PCPS_HR_TIME format + * @brief Check if capture events occurred in specified intervals. + * + * Can be used to check if periodic trigger slopes generate + * events according to the trigger intervals. + * + * The parameters ::nom_cap_intv and ::max_cap_jitter can be + * specified on the command line to define a tolerance range. + * + * @param[in] ucap The capture event read from a device. + * + * @return 1 if the specified jitter was exceeded, else 0. + */ +int check_ucap_intv( const PCPS_HR_TIME *ucap ) +{ + static PCPS_HR_TIME prv_ucap; + + jitter_exceeded = 0; + + if ( has_been_called ) + { + double abs_delta; + + delta_ucap = ucap->tstamp.sec - prv_ucap.tstamp.sec; + delta_ucap += ( (double) ucap->tstamp.frac - prv_ucap.tstamp.frac ) / MBG_FRAC32_UNITS_PER_SEC; + + abs_delta = delta_ucap - nom_cap_intv; + + if ( abs_delta < 0.0 ) + abs_delta = -abs_delta; + + if ( abs_delta > max_cap_jitter ) + { + jitter_exceeded = 1; + jitter_exceed_cnt++; + } + } + + prv_ucap = *ucap; + has_been_called = 1; + + return jitter_exceeded; + +} // check_ucap_intv + + + +static /*HDR*/ +/** + * @brief Show a user capture event in ::PCPS_HR_TIME format. * * The current API call ::mbg_get_ucap_event provides * capture events as ::PCPS_HR_TIME structure, but * there may be older devices which only support the * obsolete API call ::mbg_get_gps_ucap. * - * @param[in] ucap The capture event read from a device. + * @param[in] ucap The capture event read from a device. * * @see ::mbg_get_ucap_event * @see ::mbg_get_gps_ucap @@ -124,52 +230,34 @@ void show_ucap_event( const PCPS_HR_TIME *ucap ) char s[400]; int n; - // Print converted date and time to a string: + // Print converted date and time to a string. mbg_snprint_hr_time( ws, sizeof( ws ), ucap, raw ); - // Print the time stamp, ucap->signal contains the channel number: + // Print the timestamp. + // ucap->signal contains the channel number. n = snprintf_safe( s, sizeof( s ), "New capture: CH%i: %s", ucap->signal, ws ); - if ( must_check_intv && has_been_called ) + if ( must_check_intv ) { - int jitter_exceeded; - double abs_delta; - double d = ucap->tstamp.sec - prv_ucap.tstamp.sec; - d += ( (double) ucap->tstamp.frac - prv_ucap.tstamp.frac ) / MBG_FRAC32_UNITS_PER_SEC; - - n += snprintf_safe( &s[n], sizeof( s ) - n, " %+.6f", d ); - - abs_delta = d - nom_cap_intv; - - if ( abs_delta < 0.0 ) - abs_delta = -abs_delta; - - jitter_exceeded = 0; - - if ( abs_delta > max_cap_jitter ) - { - jitter_exceeded = 1; - err_cnt++; - } + n += snprintf_safe( &s[n], sizeof( s ) - n, " %+.7f", delta_ucap ); - if ( err_cnt ) - n += snprintf_safe( &s[n], sizeof( s ) - n, " %lu%s", err_cnt, jitter_exceeded ? " <<" : "" ); + if ( jitter_exceed_cnt ) + n += snprintf_safe( &s[n], sizeof( s ) - n, " %" PRIu64 "%s", jitter_exceed_cnt, jitter_exceeded ? " <<" : "" ); } - // status bit definitions can be found in pcpsdefs.h. + + // Status bit definitions can be found in pcpsdefs.h, + // see @ref PCPS_TIME_STATUS_FLAGS. if ( raw ) n += snprintf_safe( &s[n], sizeof( s ) - n, ", st: 0x%04X", ucap->status ); - if ( ucap->status & PCPS_UCAP_OVERRUN ) // capture events have occurred too fast + if ( ucap->status & PCPS_UCAP_OVERRUN ) // Capture events have occurred too fast. n += snprintf_safe( &s[n], sizeof( s ) - n, " << CAP OVR" ); - if ( ucap->status & PCPS_UCAP_BUFFER_FULL ) // capture buffer has been full, events lost + if ( ucap->status & PCPS_UCAP_BUFFER_FULL ) // Capture buffer was full, events have been lost. n += snprintf_safe( &s[n], sizeof( s ) - n, " << BUF OVR" ); - prv_ucap = *ucap; - has_been_called = 1; - printf( "%s\n", s ); if ( log_fn ) @@ -195,9 +283,9 @@ void show_ucap_event( const PCPS_HR_TIME *ucap ) static /*HDR*/ /** - * @brief Show a user capture event in ::TTM format read from device + * @brief Show a user capture event in ::TTM format read from device. * - * This function is actually obsolete since it shows user + * This function is actually obsolete because it shows user * capture events provided as ::TTM structure, as returned * by the obsolete API call ::mbg_get_gps_ucap. * @@ -205,7 +293,7 @@ static /*HDR*/ * and provides capture events as ::PCPS_HR_TIME structure, * but some very old devices may not support the newer API. * - * @param[in] ucap The capture event read from a device. + * @param[in] ucap The capture event read from a device. * * @see ::mbg_get_ucap_event * @see ::mbg_get_gps_ucap @@ -235,20 +323,20 @@ void show_gps_ucap( const TTM *ucap ) static /*HDR*/ /** - * @brief Check the modes of a device's serial ports + * @brief Check the modes of a serial port of a device. * - * If one of the device's serial ports has been - * configured to send a serial string automatically - * then this is usually to send a capture event string + * If one of the serial ports of the device has been + * configured to send a serial string automatically, + * this is usually to send a capture event string * automatically as soon as an event has occurred. * - * As a consequence, those events are removed from the - * on-board FIFO and aren't available anymore when + * As a consequence, capture events are removed from + * the on-board FIFO and aren't available anymore when * an application tries to read capture events via the * PCI bus, using the API functions ::mbg_get_ucap_event * or ::mbg_get_gps_ucap. * - * So we check and print a warning, if this may be the case. + * So we check and print a warning if this may be the case. * * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. * @param[in] p_dev Pointer do a device info structure for the device. @@ -268,10 +356,10 @@ void check_serial_mode( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( mbg_cond_err_msg( rc, "mbg_setup_receiver_info" ) ) return; - if ( ri.n_com_ports == 0 ) // The device provides no serial port + if ( ri.n_com_ports == 0 ) // The device provides no serial port, return; // so there's nothing to check. - // read the clock's current serial port settings + // Read the current serial port settings from the device. rc = mbg_get_serial_settings( dh, p_dev, &rpcfg, &ri ); if ( mbg_cond_err_msg( rc, "mbg_get_serial_settings" ) ) @@ -292,7 +380,7 @@ void check_serial_mode( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( must_warn ) fprintf( stderr, - "ATTENTION: At least one of the device's serial ports has been\n" + "ATTENTION: At least one of the serial ports of the device has been\n" "configured to send time strings automatically, which can remove\n" "capture events from the on-board FIFO, so they are unavailable\n" "to this application\n" @@ -317,9 +405,10 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) int this_clear_buffer = clear_buffer; must_check_intv = continuous && ( nom_cap_intv != 0 ); + jitter_exceed_cnt = 0; + cap_overrun_cnt = 0; + buf_overrun_cnt = 0; has_been_called = 0; - err_cnt = 0; - if ( !_pcps_has_ucap( p_dev ) && !_pcps_is_gps( p_dev ) ) { @@ -329,40 +418,28 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) check_serial_mode( dh, p_dev ); - printf( "Be sure the card has been properly configured to enable capture inputs.\n" ); + printf( "Be sure the device has been properly configured to enable capture inputs.\n" ); - // There's an older API which has been introduced with the first GPS boards + // There's an older API which has been introduced with the first GPS devices // and uses the TTM structure to return the capture events. However, that // API call is slow and not very flexible, so a new set of API calls has been // introduced to handle capture events. - // The new API calls are supported by all supported by all newer boards which - // provide user capture inputs, and also for older boards with a firmware update. + // The new API calls are supported by all newer devices that provide + // user capture inputs, and also for older devices with a firmware update. - if ( !force_old_api && _pcps_has_ucap( p_dev ) ) // check if the new API is supported + if ( !force_old_api && _pcps_has_ucap( p_dev ) ) // Check if the new API is supported. { - // The new API provides the following functions: - // mbg_clr_ucap_buff() clear the on-board FIFO buffer - // mbg_get_ucap_entries() get the max number of FIFO entries, and the current number of entries - // mbg_get_ucap_event() read one entry from the FIFO - PCPS_UCAP_ENTRIES ucap_entries; + struct timespec prv_t = { 0 }; + int64_t prv_events = 0; + int64_t events = 0; - // retrieve and print information of the maximum number of events that can - // be stored in the on-board FIFO, and the number of events that are currently - // stored - rc = mbg_get_ucap_entries( dh, &ucap_entries ); + // The new API provides the following functions: + // mbg_clr_ucap_buff() Clear the on-board FIFO buffer. + // mbg_get_ucap_entries() Het the max number of FIFO entries, and the current number of entries. + // mbg_get_ucap_event() Read one entry from the FIFO. - if ( rc == MBG_SUCCESS ) - { - // Cards report they could save one more capture event - // than they actually do save, so adjust the reported value - // for a proper display. - if ( ucap_entries.max ) - ucap_entries.max--; - - printf( "\nOn-board FIFO: %u of %u entries used\n\n", - ucap_entries.used, ucap_entries.max ); - } + show_ucap_entries( dh, &ucap_entries, "\nOn-board FIFO: " ); if ( this_clear_buffer ) { @@ -371,12 +448,14 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) this_clear_buffer = 0; } - // If the program is not to run continuously and no - // capture events are available then we're through. + // If the program is not to run continuously, and no + // capture events are available, we're done. if ( query_only || ( !continuous && ucap_entries.used == 0 ) ) return 0; + clock_gettime( CLOCK_MONOTONIC, &prv_t ); + printf( ( ucap_entries.used == 0 ) ? "Waiting for capture events:\n" : "Reading capture events:\n" @@ -384,7 +463,7 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( must_check_intv ) if ( max_cap_jitter == 0.0 ) - max_cap_jitter = 0.1e-6; + max_cap_jitter = 0.5e-6; // Now read out all events from the FIFO and wait // for new events if the FIFO is empty. @@ -397,20 +476,58 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( mbg_cond_err_msg( rc, "mbg_get_ucap_event" ) ) break; // an error has occurred - // If a user capture event has been read then it - // has been removed from the card's FIFO buffer. + // If a time capture event has been read, it has + // been removed from the FIFO buffer onboard device. - // If the time stamp is not 0 then a new capture event has been retrieved. + // If the timestamp is not 0, a new capture event + // has been retrieved. if ( ucap_event.tstamp.sec || ucap_event.tstamp.frac ) { - show_ucap_event( &ucap_event ); - continue; + events++; + + if ( ucap_event.status & PCPS_UCAP_OVERRUN ) + cap_overrun_cnt++; + + if ( ucap_event.status & PCPS_UCAP_BUFFER_FULL ) + buf_overrun_cnt++; + + if ( must_check_intv ) + check_ucap_intv( &ucap_event ); + + if ( !query_continuously ) + show_ucap_event( &ucap_event ); } - usleep( USLEEP_INTV ); // sleep, then try again + if ( query_continuously ) + { + struct timespec t; + + clock_gettime( CLOCK_MONOTONIC, &t ); + + if ( t.tv_sec != prv_t.tv_sec ) // Second has changed. + { + double d = delta_timespec_d_s( &t, &prv_t ); + + printf( "%li evts/s, %" PRIu64 " buf ovr, %" PRIu64 " cap ovr, ", + (long) ( ( events - prv_events ) / d ), + buf_overrun_cnt, cap_overrun_cnt ); + + if ( must_check_intv ) + printf( " %" PRIu64 " jitter ovr., ", jitter_exceed_cnt ); + + show_ucap_entries( dh, &ucap_entries, NULL ); + + prv_t = t; + prv_events = events; + } + } + + if ( ucap_event.tstamp.sec == 0 && ucap_event.tstamp.frac == 0 ) + if ( sleep_usecs ) + usleep( sleep_usecs ); // Sleep, then try again. } } - else // use the old API + else // Use the old API. { printf( "Checking for capture events using the old API:\n" ); @@ -421,14 +538,14 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) rc = mbg_get_gps_ucap( dh, &ucap_ttm ); if ( mbg_cond_err_msg( rc, "mbg_get_gps_ucap" ) ) - break; // an error has occurred + break; // An error has occurred. - // If a user capture event has been read then it - // has been removed from the card's FIFO buffer. + // If a user capture event has been read, it has + // been removed from the FIFO buffer of the device. - // If a new capture event has been available then - // the ucap.tm contains a time stamp. + // If a new capture event has been available, + // ucap.tm contains a timestamp. if ( _pcps_time_is_read( &ucap_ttm.tm ) ) show_gps_ucap( &ucap_ttm ); @@ -438,7 +555,8 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) break; } - usleep( USLEEP_INTV ); // sleep, then try again + if ( sleep_usecs ) + usleep( sleep_usecs ); // Sleep, then try again. } } @@ -455,17 +573,19 @@ void usage( void ) { mbg_print_usage_intro( pname, "This example program reads time capture events from a card.\n" - "This works only with cards which provide time capture inputs." + "This works only with devices that provide time capture inputs." ); mbg_print_help_options(); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-C", "clear capture buffer" ); - mbg_print_opt_info( "-i val", "check interval between captures events [s]" ); - mbg_print_opt_info( "-j val", "max allowed jitter of capture interval [s]" ); - mbg_print_opt_info( "-q", "query FIFO buffer status only" ); - mbg_print_opt_info( "-r", "show raw (hex) timestamp and status)" ); - mbg_print_opt_info( "-o", "force usage of old API (for testing only)" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-u num", "Sleep num microseconds if buffer empty, default %i us (implies -c)", DEFAULT_USLEEP_INTV ); + mbg_print_opt_info( "-C", "Clear capture buffer" ); + mbg_print_opt_info( "-i val", "Check interval between captures events [s]" ); + mbg_print_opt_info( "-j val", "Max. allowed jitter of capture interval [s]" ); + mbg_print_opt_info( "-q", "Query FIFO buffer status only" ); + mbg_print_opt_info( "-Q", "Query continuously once per second, read events as fast as possible" ); + mbg_print_opt_info( "-r", "Show raw (hex) timestamp and status)" ); + mbg_print_opt_info( "-o", "Force usage of old API (for testing only)" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -479,8 +599,8 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters - while ( ( c = getopt( argc, argv, "cCi:j:l:oqrh?" ) ) != -1 ) + // Check command line parameters. + while ( ( c = getopt( argc, argv, "cCi:j:l:oqQru:h?" ) ) != -1 ) { switch ( c ) { @@ -512,14 +632,24 @@ int main( int argc, char *argv[] ) query_only = 1; break; + case 'Q': + query_continuously = 1; + continuous = 1; + break; + case 'r': raw = 1; break; + case 'u': + sleep_usecs = atoi( optarg ); + continuous = 1; + break; + case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } diff --git a/mbghrtime/mbghrtime.c b/mbghrtime/mbghrtime.c index 2fa6b5b..46cb7a4 100644 --- a/mbghrtime/mbghrtime.c +++ b/mbghrtime/mbghrtime.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbghrtime.c 1.13 2018/11/15 12:12:34Z martin REL_M $ + * $Id: mbghrtime.c 1.18 2021/04/12 21:58:02Z martin REL_M $ * * Description: * Main file for mbghrtime program which demonstrates how to access @@ -10,11 +10,23 @@ * * ----------------------------------------------------------------------- * $Log: mbghrtime.c $ - * Revision 1.13 2018/11/15 12:12:34Z martin + * Revision 1.18 2021/04/12 21:58:02Z martin + * Updated printing of usage information. + * Revision 1.17 2021/03/21 17:59:51 martin + * Updated some comments. + * Revision 1.16 2021/03/12 11:50:17 martin + * Corrected the wording of some comments. + * Revision 1.15 2021/01/27 09:44:30 martin + * Don't print a time difference after the first access. With just one + * time stamp it is not possible to calculate a time difference. + * Revision 1.14 2020/11/04 17:16:12 martin + * Added option -C to support checking the continuity of the timestamps + * and status sequentially read from a device. + * Revision 1.13 2018/11/15 12:12:34 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.12 2017/07/05 19:02:13 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Support raw and burst mode. * New options -s, -u, -v. * Parameters -u and -s imply -c. @@ -53,11 +65,12 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. +#include <cmp_time_util.h> -// include system headers +// Include system headers. #include <time.h> #include <stdio.h> #include <stdlib.h> @@ -65,7 +78,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbghrtime"; @@ -75,38 +88,55 @@ static const char *pname = "mbghrtime"; static int loops; static int burst_read; static int read_raw; +static int must_check_continuity; +static double max_allowed_delta; static long sleep_secs; static long sleep_usecs; static int verbose; -// The function below reads a number of time stamps and prints -// each timestamp immediately. This is not as fast as possible -// since printing the time stamp takes some time to execute. -// However, this can run continuously forever. - static /*HDR*/ +/** + * @brief Read timestamps and print them immediately. + * + * Timestamps are read and then displayed in a single loop. + * The device is not accessed as fast as possible because + * printing the timestamp before the next access takes some + * time to execute. + * However, this routine can run continuously forever. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES. + * + * @see ::show_hr_timestamp_burst + */ int show_hr_timestamp( MBG_DEV_HANDLE dh ) { PCPS_HR_TIME ht = { { 0 } }; PCPS_HR_TIME prv_ht = { { 0 } }; - PCPS_TIME_STAMP *p = NULL; + int prv_ht_avail = 0; int32_t hns_latency = 0; int this_loops = loops; + int rc = MBG_SUCCESS; for (;;) { - int rc = read_raw ? mbg_get_hr_time( dh, &ht ) : - mbg_get_hr_time_comp( dh, &ht, &hns_latency ); + rc = read_raw ? + mbg_get_hr_time( dh, &ht ) : + mbg_get_hr_time_comp( dh, &ht, &hns_latency ); if ( mbg_cond_err_msg( rc, "mbg_get_hr_time_..." ) ) - goto fail; + goto out; + + mbg_print_hr_time( &ht, hns_latency, prv_ht_avail ? &prv_ht.tstamp : NULL, read_raw, verbose, verbose ); - mbg_print_hr_time( &ht, hns_latency, p, read_raw, verbose, verbose ); + if ( prv_ht_avail && must_check_continuity ) + mbg_check_continuity( &ht.tstamp, &prv_ht.tstamp, &ht.status, &prv_ht.status, max_allowed_delta ); prv_ht = ht; - p = &prv_ht.tstamp; + prv_ht_avail = 1; if ( this_loops > 0 ) this_loops--; @@ -114,59 +144,65 @@ int show_hr_timestamp( MBG_DEV_HANDLE dh ) if ( this_loops == 0 ) break; + // If this_loops is < 0, loop forever. + if ( sleep_secs ) sleep( sleep_secs ); else if ( sleep_usecs ) usleep( sleep_usecs ); - - // if this_loops is < 0 then loop forever } - return 0; - -fail: - return -1; +out: + return rc; } // show_hr_timestamp -// The function below takes a number of time stamps and saves -// them to a buffer. After the time stamps have been read -// a second loop prints the time stamps from the buffer. -// This way the time stamps are read in shorter intervals. -// However, this can not run continuously forever since -// the buffer size is somewhat limited. - static /*HDR*/ +/** + * @brief Read a number of timestamps in a fast loop. + * + * A number of timestamps are read to a buffer in a + * very fast loop. After all timestamps have been read, + * a second loop prints the timestamps from the buffer. + * + * This routine reads the timestamps as fast as possible. + * However, this can not run continuously forever because + * the buffer size is somewhat limited. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES. + * + * @see ::show_hr_timestamp + */ int show_hr_timestamp_burst( MBG_DEV_HANDLE dh ) { PCPS_HR_TIME ht[MAX_TS_BURST] = { { { 0 } } }; int32_t hns_latency[MAX_TS_BURST]; - int this_loops; + int this_loops = ( loops && ( loops < MAX_TS_BURST ) ) ? loops : MAX_TS_BURST; int i; - - this_loops = ( loops && ( loops < MAX_TS_BURST ) ) ? loops : MAX_TS_BURST; - + int rc = MBG_SUCCESS; if ( read_raw ) { for ( i = 0; i < this_loops; i++ ) { - int rc = mbg_get_hr_time( dh, &ht[i] ); + rc = mbg_get_hr_time( dh, &ht[i] ); if ( mbg_cond_err_msg( rc, "mbg_get_hr_time" ) ) - goto fail; + goto out; } } else for ( i = 0; i < this_loops; i++ ) { - int rc = mbg_get_hr_time_comp( dh, &ht[i], &hns_latency[i] ); + rc = mbg_get_hr_time_comp( dh, &ht[i], &hns_latency[i] ); if ( mbg_cond_err_msg( rc, "mbg_get_hr_time_comp" ) ) - goto fail; + goto out; } for ( i = 0; i < this_loops; i++ ) @@ -175,11 +211,8 @@ int show_hr_timestamp_burst( MBG_DEV_HANDLE dh ) mbg_print_hr_time( &ht[i], hns_latency[i], &p_prv_ht->tstamp, read_raw, verbose, verbose ); } - return 0; - - -fail: - return -1; +out: + return rc; } // show_hr_timestamp_burst @@ -223,14 +256,15 @@ void usage( void ) "This works only for devices which support high resolution time (HR time)." ); mbg_print_help_options(); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-n num", "run num loops" ); - mbg_print_opt_info( "-b", "burst read" ); - mbg_print_opt_info( "-r", "read raw time stamps, no cycles" ); - mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" ); - mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" ); - mbg_print_opt_info( "-v", "increase verbosity" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-n num", "Run num loops" ); + mbg_print_opt_info( "-b", "Burst read first, then show results" ); + mbg_print_opt_info( "-r", "Read raw time stamps, no cycles" ); + mbg_print_opt_info( "-C val", "Check for continuity, max allowed delta (seconds, with fractions)" ); + mbg_print_opt_info( "-s num", "Sleep num seconds between calls (implies -c)" ); + mbg_print_opt_info( "-u num", "Sleep num microseconds between calls (implies -c)" ); + mbg_print_opt_info( "-v", "Increase verbosity" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -244,8 +278,8 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters - while ( ( c = getopt( argc, argv, "bcn:rs:u:vh?" ) ) != -1 ) + // Check command line parameters. + while ( ( c = getopt( argc, argv, "bcn:rC:s:u:vh?" ) ) != -1 ) { switch ( c ) { @@ -265,6 +299,11 @@ int main( int argc, char *argv[] ) read_raw = 1; break; + case 'C': + must_check_continuity = 1; + max_allowed_delta = atof( optarg ) * 1E6; + break; + case 's': sleep_secs = atoi( optarg ); loops = -1; @@ -282,7 +321,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } diff --git a/mbgirigcfg/mbgirigcfg.c b/mbgirigcfg/mbgirigcfg.c index 72ad3a0..0437184 100644 --- a/mbgirigcfg/mbgirigcfg.c +++ b/mbgirigcfg/mbgirigcfg.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgirigcfg.c 1.14 2018/11/15 12:12:34Z martin REL_M $ + * $Id: mbgirigcfg.c 1.17 2021/04/12 21:57:44Z martin REL_M $ * * Description: * Main file for the mbgirigcfg program which can be used to configure @@ -10,7 +10,13 @@ * * ----------------------------------------------------------------------- * $Log: mbgirigcfg.c $ - * Revision 1.14 2018/11/15 12:12:34Z martin + * Revision 1.17 2021/04/12 21:57:44Z martin + * Updated printing of usage information. + * Revision 1.16 2021/03/21 18:03:09 martin + * Updated some comments, and a few output messages. + * Revision 1.15 2021/03/12 11:50:19 martin + * Corrected the wording of some comments. + * Revision 1.14 2018/11/15 12:12:34 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.13 2018/01/15 15:16:00 martin * Let snprint_hours_mins() return an int value. @@ -18,7 +24,7 @@ * Fixed error handling. * Revision 1.11 2017/07/05 19:05:27 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * New parameter -i to let incoming TFOM flag be ignored. * Accept parameter -? to print usage. * Use getopt() for option processing. @@ -59,16 +65,16 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> #include <mbgutil.h> #include <mbgtime.h> #include <pcpsmktm.h> #include <pcpslstr.h> #include <myutil.h> -#include <toolutil.h> +#include <toolutil.h> // Common utility functions. -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -76,7 +82,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2003 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char pname[] = "mbgirigcfg"; @@ -113,8 +119,8 @@ static const char *icode_rx_descr[N_ICODE_RX] = DEFAULT_ICODE_RX_DESCRIPTIONS_EN static const char *icode_tx_names[N_ICODE_TX] = DEFAULT_ICODE_TX_NAMES; static const char *icode_tx_descr[N_ICODE_TX] = DEFAULT_ICODE_TX_DESCRIPTIONS_ENG; -static char str_ref_offs_min[16]; // need to be snprint_hours_mins'ed with -MBG_REF_OFFS_MAX -static char str_ref_offs_max[16]; // need to be snprint_hours_mins'ed with +MBG_REF_OFFS_MAX +static char str_ref_offs_min[16]; // Need to be snprint_hours_mins'ed with -MBG_REF_OFFS_MAX. +static char str_ref_offs_max[16]; // Need to be snprint_hours_mins'ed with +MBG_REF_OFFS_MAX. @@ -242,29 +248,29 @@ void set_new_ref_offs( char *s ) char *cp = s; int is_negative = 0; - // expected format: [-]hh[:mm] + // Expected format: [-]hh[:mm] - // In case of e.g. "-0:30" conversion of the first part "-0" would yield - // 0 and thus the sign would get lost, so we check the sign explicitly. + // In case of e.g. "-0:30", conversion of the first part "-0" would yield + // 0 and thus the sign would get lost, so we check the sign explicitly. if ( *cp == '-' ) is_negative = 1; new_ref_offs = strtol( cp, &cp, 10 ); - if ( cp == s ) // no number found at beginning + if ( cp == s ) // No number found at beginning. goto invalid; new_ref_offs *= MINS_PER_HOUR; - if ( *cp++ == ':' ) // offset minutes seem to follow + if ( *cp++ == ':' ) // Offset minutes seem to follow. { long tmp = strtol( cp, &cp, 10 ); - // the value behind the colon should always be positive + // The value behind the colon should always be positive. if ( tmp < 0 || tmp >= MINS_PER_HOUR ) goto invalid; - // apply the minutes offset according to the sign + // Apply the minutes offset according to the sign. new_ref_offs += is_negative ? -tmp : tmp; } @@ -306,7 +312,7 @@ void set_new_str_utc( char *s ) int this_cfg_err; if ( !( opt_info.supp_flags & MBG_OPT_FLAG_STR_UTC ) ) - return; // not supported + return; // Not supported. this_cfg_err = 0; @@ -454,7 +460,8 @@ void check_cmd_line( int argc, char *argv[], const PCPS_DEV *p_dev ) { int c; - // force checking all parameters since this may be called several times + // Force checking all parameters because this function + // may be called several times. optind = 1; while ( ( c = getopt( argc, argv, "h?" "r:o:u:i:X" "t:l:s:" ) ) != -1 ) @@ -463,51 +470,51 @@ void check_cmd_line( int argc, char *argv[], const PCPS_DEV *p_dev ) { case '?': case 'h': - must_print_usage = 1; + must_print_usage = true; break; - // IRIG receiver options + // IRIG receiver options. - case 'r': // IRIG RX code frame + case 'r': // IRIG RX code frame. if ( chk_dev_rx( p_dev ) ) set_new_icode_rx( optarg ); break; - case 'o': // incoming time offset from UTC + case 'o': // Incoming time offset from UTC. if ( chk_dev_rx( p_dev ) ) set_new_ref_offs( optarg ); break; - case 'u': // option flag: serial output is always UTC + case 'u': // Option flag: serial output is always UTC. if ( chk_dev_rx( p_dev ) ) set_new_str_utc( optarg ); break; - case 'i': // option flag: ignore incoming TFOM flag, alway sync + case 'i': // Option flag: ignore incoming TFOM flag, alway sync. if ( chk_dev_rx( p_dev ) ) set_new_tfom_flag( optarg, &irig_rx_info.settings, &changed_cfg_rx, &cfg_err_rx ); break; - case 'X': // set UTC ref_offs to "not configured" + case 'X': // Set UTC ref_offs to "not configured". if ( chk_dev_rx( p_dev ) ) set_ref_offs_not_cfgd(); break; - // IRIG output options + // IRIG output options. - case 't': // IRIG TX code frame + case 't': // IRIG TX code frame. if ( chk_dev_tx( p_dev ) ) set_new_icode_tx( optarg ); break; - case 'l': // option flag: transmit local time, not UTC + case 'l': // Option flag: transmit local time, not UTC. if ( chk_dev_tx( p_dev ) ) set_new_irig_tx_local( optarg ); break; - case 's': // option flag: send TFOM as always "sync" + case 's': // Option flag: always send TFOM as "sync". if ( chk_dev_tx( p_dev ) ) set_new_tfom_flag( optarg, &irig_tx_info.settings, &changed_cfg_tx, &cfg_err_tx ); break; @@ -544,7 +551,7 @@ void usage( void ) ); printf( - " -r code specifies the IRIG receiver code format, where \"code\" \n" + " -r code Specifies the IRIG receiver code format, where \"code\" \n" " can be one a number according to the table below:\n" ); @@ -554,7 +561,7 @@ void usage( void ) printf( "\n" ); printf( - " -o offs specifies the IRIG input time offset from UTC, in hours and optional minute,\n" + " -o offs Specifies the IRIG input time offset from UTC, in hours and optional minute,\n" " where \"offs\" can be a value in the range %s .. %s.\n" " When the device is shipped this parameter is set to \"not configured\"\n" " to prevent the receiver from synchronizing to an IRIG input signal with\n" @@ -565,14 +572,14 @@ void usage( void ) ); printf( - " -X set the IRIG input time offset from UTC to \"not configured\".\n" + " -X Set the IRIG input time offset from UTC to \"not configured\".\n" " See also the -o option.\n" "\n" ); printf( - " -u flag determines whether the time string sent via the\n" - " board's serial output contains always UTC time\n" + " -u flag Determines whether the time string sent via the\n" + " serial output of the device contains always UTC time\n" " or the same time as received from the IRIG input\n" " signal. \"flag\" can be \"1\" for always UTC,\n" " or \"0\" for IRIG time.\n" @@ -580,8 +587,8 @@ void usage( void ) ); printf( - " -i flag If \"flag\" is set to \"1\" then the TFOM qualifier in the\n" - " incoming IRIG signal is ignored, i.e. the receiver even synchronizes\n" + " -i flag If \"flag\" is set to \"1\", the TFOM qualifier in the incoming\n" + " time code signal is ignored, i.e. the receiver even synchronizes\n" " to an input signal if the TFOM codes says the generator is freewheeling.\n" " Please note that most IRIG codes do not support a TFOM qualifier.\n" "\n" @@ -594,7 +601,7 @@ void usage( void ) ); printf( - " -t code specifies the IRIG transmitter code format, where \"code\" \n" + " -t code Specifies the IRIG transmitter code format, where \"code\" \n" " can be one a number according to the table below:\n" ); @@ -604,23 +611,23 @@ void usage( void ) printf( "\n" ); printf( - " -l flag determines whether IRIG output shall contain local\n" + " -l flag Determines whether IRIG output shall contain local\n" " time, or UTC. \"flag\" must be \"1\" for local time,\n" " or \"0\" for UTC.\n" "\n" ); printf( - " -s flag If \"flag\" is set to \"1\" then the TFOM qualifier in the\n" - " IRIG output is always set to \"synchronized\". If it is \"0\" \n" - " then the qualifier reflects the current status of the input signal.\n" + " -s flag If \"flag\" is set to \"1\", the TFOM qualifier in the outgoing\n" + " time code signal is always set to \"synchronized\". If it is \"0\",\n" + " the qualifier reflects the current status of the input signal.\n" " Please note that most IRIG codes do not support a TFOM qualifier.\n" "\n" ); printf( - "If no parameters are given the program reports the current settings.\n" + "If no parameters are given, the program reports the current settings.\n" "Please note that not all IRIG codes must be supported by all devices.\n" ); @@ -687,7 +694,7 @@ int do_mbgirigcfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) goto done; } } - else // RX cfg not changed + else // RX cfg not changed. if ( _pcps_is_irig_rx( p_dev ) ) print_cfg_rx( info_curr, msg_rx ); @@ -735,7 +742,7 @@ int main( int argc, char *argv[] ) } - // We work with copies of the arguments here since the arguments + // We work with copies of the arguments here because the arguments // are evaluated once more for each device. glb_argc = argc; glb_argv = argv; diff --git a/mbgsetsystime/mbgsetsystime.c b/mbgsetsystime/mbgsetsystime.c index 319e3f8..1ed3743 100644 --- a/mbgsetsystime/mbgsetsystime.c +++ b/mbgsetsystime/mbgsetsystime.c @@ -1,12 +1,12 @@ /************************************************************************** * - * $Id: mbgsetsystime.c 1.12 2018/11/15 12:12:35Z martin REL_M $ + * $Id: mbgsetsystime.c 1.17 2021/04/12 21:57:46Z martin REL_M $ * * Description: * Main file for mbgsetsystime program which reads the current date * and time from a Meinberg device and sets the system time accordingly. - * The program returns 0 if successfull, otherwise a value greater + * The program returns 0 if successful, otherwise a value greater * than 0. * * Be careful if using this program while (x)ntpd is running because @@ -14,6 +14,16 @@ * * ----------------------------------------------------------------------- * $Log: mbgsetsystime.c $ + * Revision 1.17 2021/04/12 21:57:46Z martin + * Updated printing of usage information. + * Revision 1.16 2021/03/21 22:40:08 martin + * Updated some comments. + * Revision 1.15 2021/03/12 12:32:41 martin + * Updated some comments. + * Revision 1.14 2020/02/27 13:29:20 martin + * Account for enhanced library functions. + * Revision 1.13 2019/07/19 14:23:03 martin + * Removed obsolete conditional code. * Revision 1.12 2018/11/15 12:12:35Z martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.11 2018/10/30 14:49:55 martin @@ -23,7 +33,7 @@ * Account for renamed library symbol NSEC_PER_SEC. * Revision 1.9 2017/07/05 18:24:44 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Use high resolution time if the device supports it. * Use codes and inline functions from mbgerror.h. * Use functions from new module timeutil. @@ -53,16 +63,15 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> #include <pcpsmktm.h> -#include <pcpsutil.h> -#include <toolutil.h> +#include <toolutil.h> // Common utility functions. #include <timeutil.h> #include <str_util.h> #include <mbgerror.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> @@ -70,7 +79,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgsetsystime"; @@ -82,7 +91,7 @@ int sn_printf_timespec( char *s, size_t max_len, const struct timespec *p_ts ) struct tm tm = { 0 }; int rc = mbg_gmtime( &tm, &p_ts->tv_sec ); - if ( mbg_rc_is_error( rc ) ) // conversion failed + if ( mbg_rc_is_error( rc ) ) // Conversion failed. return sn_cpy_str_safe( s, max_len, "(invalid time)" ); return snprintf_safe( s, max_len, "%04i-%02i-%02i %02i:%02i:%02i.%09li UTC", @@ -99,15 +108,11 @@ int set_system_time( const struct timespec *p_ts ) { char ws[100]; -#if defined( MBG_TGT_WIN32 ) - #define clock_settime mbg_clock_settime //### TODO cleanup -#endif - int rc = clock_settime( CLOCK_REALTIME, p_ts ); sn_printf_timespec( ws, sizeof( ws ), p_ts ); - if ( rc < 0 ) // usually 0 on success, -1 on error + if ( rc < 0 ) // Usually 0 on success, -1 on error. { rc = mbg_get_last_error( NULL ); @@ -127,25 +132,23 @@ static /*HDR*/ int set_system_time_from_pcps_time( const PCPS_TIME *p_t ) { struct tm tm = { 0 }; - time_t t_rev; - time_t t; - int rc; + MBG_TIME64_T t_rev; + MBG_TIME64_T t; - t = pcps_mktime( p_t ); + int rc = pcps_mktime64( &t, p_t, 1970 ); - if ( t == (time_t) -1 ) // error + if ( mbg_rc_is_error( rc ) ) { - fprintf( stderr, "Failed to convert %02u.%02u.%02u %02u:%02u:%02u.%02u (UTC%+02ih) to system time\n", + fprintf( stderr, "Failed to convert %02u.%02u.%02u %02u:%02u:%02u.%02u (UTC%+02ih) to system time: %s\n", p_t->mday, p_t->month, p_t->year, p_t->hour, p_t->min, p_t->sec, p_t->sec100, - p_t->offs_utc - ); - return MBG_ERR_OVERFLOW; + p_t->offs_utc, mbg_strerror( rc ) ); + return rc; } t_rev = t + p_t->offs_utc * SECS_PER_HOUR; - rc = mbg_gmtime( &tm, &t_rev ); + rc = mbg_gmtime64( &tm, &t_rev ); if ( mbg_rc_is_error( rc ) ) return rc; @@ -217,12 +220,12 @@ int set_system_time_from_pcps_time( const PCPS_TIME *p_t ) return MBG_SUCCESS; } - #else // assuming POSIX + #else // Assuming POSIX. { struct timespec ts; ts.tv_sec = t; - ts.tv_nsec = (long) p_t->sec100 * ( NSEC_PER_SEC / 100 ); // convert to nanoseconds + ts.tv_nsec = (long) p_t->sec100 * ( NSEC_PER_SEC / 100 ); // Convert to nanoseconds. return set_system_time( &ts ); } @@ -244,9 +247,9 @@ int do_set_system_time_from_pcps_time( MBG_DEV_HANDLE dh ) if ( t.status & PCPS_INVT ) { - // This may happen if the radio clock's battery + // This may happen if the battery onboard the device // has been discharged or disconnected. - printf( "Radio clock has no valid date/time.\n" ); + printf( "The device has no valid date/time.\n" ); return MBG_ERR_INV_TIME; } @@ -271,9 +274,9 @@ int do_set_system_time_from_pcps_hr_time( MBG_DEV_HANDLE dh ) if ( ht.status & PCPS_INVT ) { - // This may happen if the radio clock's battery + // This may happen if the battery onboard the device // has been discharged or disconnected. - printf( "Radio clock has no valid date/time.\n" ); + printf( "The device has no valid date/time.\n" ); return MBG_ERR_INV_TIME; } @@ -321,12 +324,12 @@ static /*HDR*/ void usage( void ) { mbg_print_usage_intro( pname, - "This program can be used to set the system time to the card's time.\n" + "This program can be used to set the system time to the time of a device.\n" "This should be done only at boot time, before the NTP daemon is started.\n" "Please *don't* run this program while ntpd is already active." ); mbg_print_help_options(); - mbg_print_device_options(); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -340,7 +343,7 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters + // Check command line parameters. while ( ( c = getopt( argc, argv, "h?" ) ) != -1 ) { switch ( c ) @@ -348,7 +351,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } @@ -361,13 +364,13 @@ int main( int argc, char *argv[] ) // Handle each of the specified devices. rc = mbg_handle_devices( argc, argv, optind, do_mbgsetsystime, 0 ); - // determine the exit code based on the return code + // Determine the exit code based on the return code. if ( mbg_rc_is_success( rc ) ) - return MBG_EXIT_CODE_SUCCESS; // success + return MBG_EXIT_CODE_SUCCESS; // Success. if ( rc == MBG_ERR_INV_TIME ) - return MBG_EXIT_CODE_INV_TIME; // device has no valid time to set the system time with + return MBG_EXIT_CODE_INV_TIME; // Device has no valid time to set the system time with. - return MBG_EXIT_CODE_FAIL; // any error occurred + return MBG_EXIT_CODE_FAIL; // Any error occurred. } diff --git a/mbgshowsignal/mbgshowsignal.c b/mbgshowsignal/mbgshowsignal.c index eb02e9c..b2e3813 100644 --- a/mbgshowsignal/mbgshowsignal.c +++ b/mbgshowsignal/mbgshowsignal.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgshowsignal.c 1.11 2019/03/19 16:43:51Z martin REL_M $ + * $Id: mbgshowsignal.c 1.15 2021/04/12 21:57:52Z martin REL_M $ * * Description: * Main file for mbgshowsignal program which demonstrates how to @@ -10,13 +10,22 @@ * * ----------------------------------------------------------------------- * $Log: mbgshowsignal.c $ - * Revision 1.11 2019/03/19 16:43:51Z martin + * Revision 1.15 2021/04/12 21:57:52Z martin + * Updated printing of usage information. + * Revision 1.14 2021/03/21 22:40:19 martin + * Updated some comments. + * Revision 1.13 2021/03/12 12:32:22 martin + * Updated some comments. + * Revision 1.12 2020/02/27 13:30:35 martin + * mbg_show_pzf_corr_info() now just prints the correlation info, + * but doesn't read it from the device, so we read it here. + * Revision 1.11 2019/03/19 16:43:51 martin * Support force reading status port even if device provides no modulation signal. * Revision 1.10 2018/11/15 12:12:36 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.9 2017/07/05 18:31:14 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Update modulation status continuously. * Show PZF correlation state. * Use codes and inline functions from mbgerror.h. @@ -46,18 +55,18 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <time.h> #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgshowsignal"; @@ -70,18 +79,18 @@ int show_modulation( MBG_DEV_HANDLE dh ) { static time_t prv_sys_t; time_t sys_t; - PCPS_STATUS_PORT status_port; // current value of the clock's status port + PCPS_STATUS_PORT status_port; // Current value of the status port of the device. PCPS_TIME t; int signal; bool dev_has_pzf = mbg_chk_dev_has_pzf( dh ) == MBG_SUCCESS; - int rc = mbg_get_status_port( dh, &status_port ); // read status port + int rc = mbg_get_status_port( dh, &status_port ); // Read status port. if ( mbg_cond_err_msg( rc, "mbg_get_status_port" ) ) return rc; - // show signal only once per second + // Show signal only once per second. sys_t = time( NULL ); if ( sys_t != prv_sys_t ) @@ -109,7 +118,14 @@ int show_modulation( MBG_DEV_HANDLE dh ) printf( " Signal: %u%% ", signal * 100 / PCPS_SIG_MAX ); if ( dev_has_pzf ) - rc = mbg_show_pzf_corr_info( dh, 1 ); + { + CORR_INFO ci; + + rc = mbg_get_corr_info( dh, &ci ); + + if ( mbg_rc_is_success( rc ) ) + mbg_show_pzf_corr_info( &ci, 1 ); + } printf( " " ); @@ -165,12 +181,12 @@ static /*HDR*/ void usage( void ) { mbg_print_usage_intro( pname, - "This program displays the modulation signal of cards which receive\n" + "This program displays the modulation signal of devices which receive\n" "a slowly modulated input signal, e.g. the longwave signal from DCF77.\n" ); mbg_print_help_options(); - mbg_print_opt_info( "-F", "force reading status port even if signal not supported" ); - mbg_print_device_options(); + mbg_print_opt_info( "-F", "Force reading status port even if signal not supported" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -184,7 +200,7 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters + // Check command line parameters. while ( ( c = getopt( argc, argv, "Fh?" ) ) != -1 ) { switch ( c ) @@ -196,7 +212,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } diff --git a/mbgstatus/mbgstatus.c b/mbgstatus/mbgstatus.c index 6663a70..9159e49 100644 --- a/mbgstatus/mbgstatus.c +++ b/mbgstatus/mbgstatus.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgstatus.c 1.20 2019/04/02 15:15:45Z martin REL_M $ + * $Id: mbgstatus.c 1.32 2021/11/08 21:50:59Z martin.burnicki REL_M $ * * Description: * Main file for mbgstatus program which demonstrates how to @@ -10,11 +10,41 @@ * * ----------------------------------------------------------------------- * $Log: mbgstatus.c $ - * Revision 1.20 2019/04/02 15:15:45Z martin + * Revision 1.32 2021/11/08 21:50:59Z martin.burnicki + * Show SYN1588-specific info, if appropriate. + * Revision 1.31 2021/05/27 20:57:38 martin + * Refactured printing of GPS/UTC time offset and + * leap second announcement. + * Revision 1.30 2021/04/29 15:05:49 martin + * Support reading device CPU info. + * Revision 1.29 2021/04/12 21:58:05 martin + * Updated printing of usage information. + * Revision 1.28 2021/04/12 21:37:18 martin + * Use global year_limit. + * Revision 1.27 2021/03/21 22:40:31 martin + * Updated a bunch of comments. + * Revision 1.26 2021/03/12 12:32:20 martin + * Updated some comments. + * Revision 1.25 2020/08/17 16:08:14 martin + * If no device could be found, call a specific new function + * to print associated information. + * Revision 1.24 2020/03/31 08:18:34 martin + * Modified condition under which true GPS LS week number is displayed. + * Revision 1.23 2020/02/28 14:08:25 martin + * Enhanced display of UTC parameters / leap second + * information as well as BVAR status. + * Revision 1.22 2020/02/27 13:15:26 martin + * Fixed unprintable prefix in snprint_dms() in case the position is uninitialized. + * Started cleanup. First collect all information, then print it. + * UTC message says 'Last leap second probably' instead of 'eventually'. + * Print 'BVAR' status in verbose mode. + * Changed year limit to 1970. + * Fixed a typo in an earlier log message. + * Revision 1.20 2019/04/02 15:15:45 martin * Also print raw GPS time in verbose mode. * Removed obsolete debug code. * Revision 1.19 2019/03/11 16:10:24 martin - * Als print memory mapped timestamp in verbose mode. + * Also print memory mapped timestamp in verbose mode. * Revision 1.18 2019/02/08 11:08:47 martin * Also print EPLD name in verbose mode. * Revision 1.17 2018/11/15 12:12:37 martin @@ -28,7 +58,7 @@ * Improved displaying of UTC/leap second parameters. * Revision 1.14 2017/07/05 18:34:46 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Show many more details, at different verbosity levels. * Use more functions from common library modules. * Use codes and inline functions from mbgerror.h. @@ -79,32 +109,32 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> #include <mbgutil.h> -#include <mbgtime.h> +#include <mbgtimex.h> #include <pcpslstr.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. #include <lan_util.h> #include <deviohlp.h> #include <timeutil.h> #include <str_util.h> #include <nanotime.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #define MBG_FIRST_COPYRIGHT_YEAR 2001 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use current year by default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgstatus"; static int loops; -static int list_only; // list only which devices are installed -static int list_only_unique_names; // list only the unique names of all devices +static int list_only; // List only which devices are installed. +static int list_only_unique_names; // List only the unique names of all devices. static long sleep_secs; static long sleep_usecs; static unsigned int verbose; @@ -113,11 +143,12 @@ static const char *ref_name[N_PCPS_REF]= PCPS_REF_NAMES_ENG; static const char *icode_rx_names[N_ICODE_RX] = DEFAULT_ICODE_RX_NAMES; static const char *osc_name[N_GPS_OSC] = DEFAULT_GPS_OSC_NAMES; -static int year_limit = 1990; - static int max_ref_offs_h = MBG_REF_OFFS_MAX / MINS_PER_HOUR; static int invt_reason; +#define STR_INDENT " " +static const char str_indent[] = STR_INDENT; + static const char *wdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; LANGUAGE language; @@ -125,6 +156,124 @@ CTRY ctry; +typedef struct +{ + bool has_receiver_info; + bool has_gps_data; + bool has_generic_io; + bool has_asic_version; + bool has_asic_features; + bool has_xmr; + bool is_isa; + bool is_mca; + bool is_pci; + bool is_pci_express; + bool is_usb; + bool is_gps; + bool is_gnss; + bool is_dcf; + bool has_pzf; + bool is_msf; + bool is_wwvb; + bool is_jjy; + bool is_lwr; + bool is_tcr; + bool has_lan_intf; + bool has_ptp; + bool has_ptp_unicast; + bool has_hr_time; + bool has_fast_hr_timestamp; + bool has_time_scale; + bool has_event_time; + bool has_ucap; + bool can_clr_ucap_buff; + bool has_tzdl; + bool has_pcps_tzdl; + bool has_tzcode; + bool has_tz; + bool has_irig; + bool has_irig_rx; + bool has_irig_tx; + bool has_irig_ctrl_bits; + bool has_raw_irig_data; + bool has_irig_time; + bool has_signal; + bool has_mod; + bool has_sync_time; + bool has_rcvr_pos; + bool has_bvar_stat; + bool has_ttm_time; + bool has_serial; + bool has_serial_hs; + bool has_synth; + bool has_gpio; + bool has_cab_len; + bool has_ref_offs; + bool has_opt_flags; + bool has_utc_parm; + bool has_corr_info; + bool has_tr_distance; + bool has_debug_status; + bool has_evt_log; + bool has_dac_ctrl; + + + PCPS_DEV dev_info; + RECEIVER_INFO ri; + + PCPS_TIME t; + bool pcps_time_avail; + + PCPS_HR_TIME ht; + bool hr_time_avail; + + PCPS_TIME_STAMP ts; + bool fast_hr_timestamp_avail; + + TTM ttm; + bool ttm_time_avail; + + PCPS_TIME sync_time; + bool sync_time_avail; + + CORR_INFO corr_info; + bool corr_info_avail; + + IRIG_INFO irig_rx_info; + bool irig_rx_info_avail; + + MBG_REF_OFFS ref_offs; + bool ref_offs_avail; + + PCPS_IRIG_TIME it; + bool irig_time_avail; + + BVAR_STAT bvar_stat; + bool bvar_stat_avail; + + POS rcvr_pos; + bool rcvr_pos_avail; + + ALL_GNSS_INFO agi; + bool agi_avail; + + UTC utc_info; + bool utc_info_avail; + + MBG_IRIG_CTRL_BITS irig_ctrl_bits; + bool irig_ctrl_bits_avail; + + MBG_RAW_IRIG_DATA raw_irig_data; + bool raw_irig_data_avail; + + bool is_syn1588; + uint32_t syn1588_ptp_syn_status; + bool syn1588_ptp_syn_status_avail; + +} DEVICE_STATUS; + + + static /*HDR*/ void show_invt_reason( void ) { @@ -149,6 +298,56 @@ void show_invt_reason( void ) static /*HDR*/ +void show_dev_cpu_info( MBG_DEV_HANDLE dh ) +{ + static const char * const cpu_type_names[N_MBG_DEV_CPU_TYPES] = MBG_DEV_CPU_TYPE_NAMES; + + PCPS_CPU_INFO cpu_info = { 0 }; + char s[80]; + const char *cp = NULL; + + int rc = mbg_get_pcps_cpu_info( dh, &cpu_info ); + + if ( mbg_rc_is_error( rc ) ) + goto fail; + + + // An unspecified processor type is only displayed + // in very verbose mode. + if ( verbose < 3 ) + if ( cpu_info.cpu_type == MBG_DEV_CPU_TYPE_UNSPEC ) + goto out; + + // If the processor type is known, print the name + // from the list. + if ( cpu_info.cpu_type < N_MBG_DEV_CPU_TYPES ) + { + cp = cpu_type_names[cpu_info.cpu_type]; + goto out; + } + + // The processor type is beyond the range + // of known processors. + snprintf_safe( s, sizeof( s ), "unknown code %u", cpu_info.cpu_type ); + cp = s; + + +out: + if ( cp ) + printf( "Processor type: %s\n", cp ); + + return; + + +fail: + fprintf( stderr, "Failed to get device CPU info: %s (%i)\n", + mbg_strerror( rc ), rc ); + +} // show_dev_cpu_info + + + +static /*HDR*/ void print_pcps_time( const char *s, const PCPS_TIME *tp, const char *tail ) { const char *fmt = "%s"; @@ -157,7 +356,7 @@ void print_pcps_time( const char *s, const PCPS_TIME *tp, const char *tail ) if ( s ) printf( fmt, s ); - printf( fmt, pcps_date_time_str( ws, sizeof( ws ), tp, year_limit, + printf( fmt, pcps_date_time_str( ws, sizeof( ws ), tp, mbg_exp_year_limit, pcps_tz_name( tp, PCPS_TZ_NAME_FORCE_UTC_OFFS, 0 ) ) ); if ( ( verbose > 0 ) && _pcps_time_is_read( tp ) ) @@ -175,9 +374,17 @@ void print_dms( const char *s, const DMS *p, const char *tail ) { const char *fmt = "%s"; + // If the position is unknown / uninitialized, + // the prefix character can be invalid, so print + // a space character in this case. + char prefix = (char) p->prefix; + + if ( ( prefix < ' ' ) || ( prefix >= '\x7F' ) ) + prefix = ' '; + printf( "%s %c %3i deg %02i min %06.3f sec", s, - p->prefix, + prefix, p->deg, p->min, p->sec @@ -207,15 +414,15 @@ void print_position( const char *s, const POS *p, const char *tail ) if ( verbose > 1 ) { - printf( " x: %.0fm y: %.0fm z: %.0fm", + printf( STR_INDENT "x: %.0fm y: %.0fm z: %.0fm", p->xyz[XP], p->xyz[YP], p->xyz[ZP] ); if ( tail ) printf( fmt, tail ); } - // LLA latitude and longitude are in radians, convert to degrees - printf( " lat: %+.4f lon: %+.4f alt: %.0fm", + // LLA latitude and longitude are in radians, convert to degrees. + printf( STR_INDENT "lat: %+.4f, lon: %+.4f, alt: %.0fm", p->lla[LAT] * r2d, p->lla[LON] * r2d, p->lla[ALT] ); if ( tail ) @@ -223,8 +430,8 @@ void print_position( const char *s, const POS *p, const char *tail ) if ( verbose ) { - print_dms( " latitude: ", &p->latitude, tail ); - print_dms( " longitude:", &p->longitude, tail ); + print_dms( STR_INDENT "latitude: ", &p->latitude, tail ); + print_dms( STR_INDENT "longitude:", &p->longitude, tail ); } } // print_position @@ -232,28 +439,23 @@ void print_position( const char *s, const POS *p, const char *tail ) static /*HDR*/ -void show_signal( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, int signal ) +void show_signal( const DEVICE_STATUS *p_ds, int signal ) { + const PCPS_DEV *p_dev = &p_ds->dev_info; int ref_type; - int rc; - ref_type = _pcps_ref_type( pdev ); + ref_type = _pcps_ref_type( p_dev ); if ( ref_type >= N_PCPS_REF ) ref_type = PCPS_REF_NONE; printf( "Signal: %u%% (%s", signal * 100 / PCPS_SIG_MAX, ref_name[ref_type] ); - if ( _pcps_is_irig_rx( pdev ) ) + if ( p_ds->has_irig_rx ) { - IRIG_INFO irig_rx_info; - MBG_REF_OFFS ref_offs; - - rc = mbg_get_irig_rx_info( dh, &irig_rx_info ); - - if ( rc == MBG_SUCCESS ) + if ( p_ds->irig_rx_info_avail ) { - int idx = irig_rx_info.settings.icode; + int idx = p_ds->irig_rx_info.settings.icode; if ( idx < N_ICODE_RX ) { @@ -261,26 +463,22 @@ void show_signal( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, int signal ) if ( !( MSK_ICODE_RX_HAS_TZI & ( 1UL << idx ) ) ) { - if ( _pcps_has_ref_offs( pdev ) ) + if ( p_ds->ref_offs_avail ) { - rc = mbg_get_ref_offs( dh, &ref_offs ); + int ref_offs_h = p_ds->ref_offs / MINS_PER_HOUR; - if ( rc == MBG_SUCCESS ) - { - int ref_offs_h = ref_offs / MINS_PER_HOUR; - - if ( abs( ref_offs_h ) > max_ref_offs_h ) - printf( ", ** UTC offs not configured **" ); - else - printf( ", UTC%+ih", ref_offs_h ); - } + if ( abs( ref_offs_h ) > max_ref_offs_h ) + printf( ", ** UTC offs not configured **" ); + else + printf( ", UTC%+ih", ref_offs_h ); } + } } } } else - if ( _pcps_has_pzf( pdev ) ) + if ( _pcps_has_pzf( p_dev ) ) printf( "/PZF" ); printf( ")\n" ); @@ -290,85 +488,62 @@ void show_signal( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, int signal ) static /*HDR*/ -void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *tail ) +void show_time_and_status( const DEVICE_STATUS *p_ds ) { + static const char tail[] = "\n"; // TODO + + const PCPS_DEV *p_dev = &p_ds->dev_info; + const char status_fmt[] = "Status info: %s%s\n"; const char status_err[] = "*** "; const char status_ok[] = ""; - const char *info_err = ( _pcps_is_gps( pdev ) || _pcps_is_lwr( pdev ) ) ? + const char *info_err = ( _pcps_is_gps( p_dev ) || _pcps_is_lwr( p_dev ) ) ? "ANTENNA FAULTY" : "NO INPUT SIGNAL"; const char info_ok[] = "Input signal available"; - PCPS_TIME t; + char ws[80]; PCPS_STATUS_STRS strs; + PCPS_TIME_STATUS_X status_x = 0; int signal; int i; - int rc = mbg_get_time( dh, &t ); - if ( mbg_cond_err_msg( rc, "mbg_get_time" ) ) - return; - - - print_pcps_time( "Date/time: ", &t, tail ); + if ( p_ds->pcps_time_avail ) + print_pcps_time( "Date/time: ", &p_ds->t, tail ); - if ( ( verbose > 0 ) && _pcps_has_hr_time( pdev ) ) + if ( p_ds->hr_time_avail ) { - PCPS_HR_TIME ht = { { 0 } }; - char ws[80]; - - rc = mbg_get_hr_time( dh, &ht ); - if ( mbg_cond_err_msg( rc, "mbg_get_hr_time" ) ) - return; - - mbg_snprint_hr_time( ws, sizeof( ws ), &ht, 0 ); // raw timestamp? + mbg_snprint_hr_time( ws, sizeof( ws ), &p_ds->ht, 0 ); // Raw timestamp? printf( "Local HR time: %s", ws ); if ( verbose > 0 ) - printf( ", st: 0x%04lX", (ulong) ht.status ); + printf( ", st: 0x%04lX", (ulong) p_ds->ht.status ); printf( "%s", tail ); } - if ( ( verbose > 1 ) && _pcps_has_fast_hr_timestamp( pdev ) ) + if ( p_ds->fast_hr_timestamp_avail ) { - PCPS_TIME_STAMP ts; - char ws[80]; - - rc = mbg_get_fast_hr_timestamp( dh, &ts ); - - if ( mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp" ) ) - return; - - mbg_snprint_hr_tstamp( ws, sizeof( ws ), &ts, 0, 0 ); + mbg_snprint_hr_tstamp( ws, sizeof( ws ), &p_ds->ts, 0, 0 ); printf( "Fast MM time: %s", ws ); printf( "%s", tail ); } - if ( ( verbose > 1 ) && _pcps_is_gps( pdev ) ) + if ( p_ds->ttm_time_avail ) { - TTM ttm = { 0 }; - char ws[80]; - int n; - - rc = mbg_get_gps_time( dh, &ttm ); - - if ( mbg_cond_err_msg( rc, "mbg_get_gps_time" ) ) - return; - - n = pcps_str_tm_gps_date_time( ws, sizeof( ws ), &ttm.tm ); - n += snprint_utc_offs( &ws[n], sizeof( ws ) - n, " UTC", ttm.tm.offs_from_utc ); + int n = pcps_str_tm_gps_date_time( ws, sizeof( ws ), &p_ds->ttm.tm ); + n += snprint_utc_offs( &ws[n], sizeof( ws ) - n, " UTC", p_ds->ttm.tm.offs_from_utc ); printf( "TTM time: %s", ws ); - printf( ", TTM st: 0x%04X", ttm.tm.status ); + printf( ", TTM st: 0x%04X", p_ds->ttm.tm.status ); printf( "%s", tail ); - printf( "Raw GPS time: wn %u|%06lu.%07lu s", (unsigned) ttm.t.wn, - (ulong) ttm.t.sec, (ulong) ttm.t.tick ); + printf( "Raw GPS time: wn %u|%06lu.%07lu s", (unsigned) p_ds->ttm.t.wn, + (ulong) p_ds->ttm.t.sec, (ulong) p_ds->ttm.t.tick ); printf( "%s", tail ); } - signal = t.signal - PCPS_SIG_BIAS; + signal = p_ds->t.signal - PCPS_SIG_BIAS; // TODO or from hr time? if ( signal < 0 ) signal = 0; @@ -376,122 +551,215 @@ void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char * if ( signal > PCPS_SIG_MAX ) signal = PCPS_SIG_MAX; - if ( _pcps_has_signal( pdev ) ) - show_signal( dh, pdev, signal ); + if ( _pcps_has_signal( p_dev ) ) // TODO + show_signal( p_ds, signal ); - if ( _pcps_has_pzf( pdev ) ) + if ( p_ds->corr_info_avail ) { - mbg_show_pzf_corr_info( dh, 0 ); + mbg_show_pzf_corr_info( &p_ds->corr_info, 0 ); printf( "\n" ); } - if ( verbose && _pcps_has_irig_time( pdev ) ) - { - PCPS_IRIG_TIME it; - - rc = mbg_get_irig_time( dh, &it ); - - if ( !mbg_cond_err_msg( rc, "mbg_get_irig_time" ) ) - printf( "Raw IRIG time: yday %u, %02u:%02u:%02u\n", - it.yday, it.hour, it.min, it.sec ); - } + if ( p_ds->irig_time_avail ) + printf( "Raw IRIG time: yday %u, %02u:%02u:%02u\n", + p_ds->it.yday, p_ds->it.hour, p_ds->it.min, p_ds->it.sec ); printf( status_fmt, ( signal < PCPS_SIG_ERR ) ? status_err : status_ok, ( signal < PCPS_SIG_ERR ) ? info_err : info_ok ); + + // FIXME TODO What if no status is available? + + if ( p_ds->hr_time_avail ) + status_x = p_ds->ht.status; + else + if ( p_ds->pcps_time_avail ) + status_x = p_ds->t.status; + // Evaluate the status code and setup status messages. - pcps_status_strs( t.status, _pcps_time_is_read( &t ), - _pcps_is_gps( pdev ), &strs ); + pcps_status_strs( status_x, 1, p_ds->is_gps, &strs ); // TODO ref_type instead of GPS yes/no? // Print the status messages. for ( i = 0; i < N_PCPS_STATUS_STR; i++ ) { PCPS_STATUS_STR *pstr = &strs.s[i]; + if ( pstr->cp ) printf( status_fmt, pstr->is_err ? status_err : status_ok, pstr->cp ); } + invt_reason = 0; - if ( _pcps_is_irig_rx( pdev ) && ( t.status & PCPS_INVT ) ) + if ( p_ds->has_irig_rx && ( status_x & PCPS_INVT ) ) { - MBG_REF_OFFS ref_offs; + if ( p_ds->ref_offs_avail && _pcps_ref_offs_out_of_range( p_ds->ref_offs ) ) + invt_reason = 2; + else + invt_reason = 1; + } - rc = mbg_get_ref_offs( dh, &ref_offs ); +} // show_time_and_status - if ( !mbg_cond_err_msg( rc, "mbg_get_ref_offs" ) ) - { - if ( _pcps_ref_offs_out_of_range( ref_offs ) ) - invt_reason = 2; - else - invt_reason = 1; - } + + +static /*HDR*/ +int collect_time_and_status( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + int rc; + + _pcps_time_set_unread( &p_ds->t ); + + rc = mbg_get_time( dh, &p_ds->t ); + p_ds->pcps_time_avail = !mbg_cond_err_msg( rc, "mbg_get_time" ); + + + if ( p_ds->has_hr_time && ( ( verbose > 0 ) || !_pcps_time_is_read( &p_ds->t ) ) ) + { + rc = mbg_get_hr_time( dh, &p_ds->ht ); + p_ds->hr_time_avail = !mbg_cond_err_msg( rc, "mbg_get_hr_time" ); } -} // show_time_and_status + + if ( p_ds->has_fast_hr_timestamp && ( verbose > 1 ) ) + { + rc = mbg_get_fast_hr_timestamp( dh, &p_ds->ts ); + p_ds->fast_hr_timestamp_avail = !mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp" ); + } + + + if ( p_ds->has_ttm_time && ( verbose > 1 ) ) + { + rc = mbg_get_ttm_time( dh, &p_ds->ttm ); + p_ds->ttm_time_avail = !mbg_cond_err_msg( rc, "mbg_get_ttm_time" ); + } + + return MBG_SUCCESS; // TODO + +} // collect_time_and_status static /*HDR*/ -void show_sync_time( MBG_DEV_HANDLE dh, const char *tail ) +int collect_irig_status( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) { - PCPS_TIME t; - int rc = mbg_get_sync_time( dh, &t ); + int rc; + + if ( p_ds->has_irig_rx ) + { + rc = mbg_get_irig_rx_info( dh, &p_ds->irig_rx_info ); + p_ds->irig_rx_info_avail = !mbg_cond_err_msg( rc, "mbg_get_irig_rx_info" ); + } + + + if ( p_ds->has_ref_offs ) + { + rc = mbg_get_ref_offs( dh, &p_ds->ref_offs ); + p_ds->ref_offs_avail = !mbg_cond_err_msg( rc, "mbg_get_ref_offs" ); + } - if ( mbg_cond_err_msg( rc, "mbg_get_sync_time" ) ) - return; - print_pcps_time( "Last sync: ", &t, tail ); + if ( p_ds->has_irig_time && verbose ) + { + rc = mbg_get_irig_time( dh, &p_ds->it ); + p_ds->irig_time_avail = !mbg_cond_err_msg( rc, "mbg_get_irig_time" ); + } + + + return MBG_SUCCESS; // TODO + +} // collect_irig_status + + + +static /*HDR*/ +void show_sync_time( const DEVICE_STATUS *p_ds ) +{ + if ( p_ds->sync_time_avail ) + print_pcps_time( "Last sync: ", &p_ds->sync_time, "\n" ); } // show_sync_time static /*HDR*/ -void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *tail ) +void collect_sync_time( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) { - const char *fmt = "%s"; - RECEIVER_INFO ri = { 0 }; - ALL_GNSS_INFO agi = { { 0 } }; - GNSS_SAT_INFO *p_gsi; - char ws[80]; - const char *cp; - int i; int rc; - // first collect all information + if ( p_ds->has_sync_time ) + { + rc = mbg_get_sync_time( dh, &p_ds->sync_time ); + p_ds->sync_time_avail = !mbg_cond_err_msg( rc, "mbg_get_sync_time" ); + } - rc = mbg_setup_receiver_info( dh, p_dev, &ri ); +} // collect_sync_time - if ( mbg_cond_err_msg( rc, "mbg_setup_receiver_info" ) ) + + +/*HDR*/ +void print_bvar_stat( const BVAR_STAT *p ) +{ + static const char *bvar_flag_names[N_BVAR_BIT] = BVAR_FLAG_NAMES_SHORT; + + int printed; + int i; + + printf( "0x%04X ", *p ); + + if ( *p == 0 ) + { + printf( "(all OK)\n" ); return; + } + + printf( "(incomplete: " ); + + printed = 0; - if ( mbg_rc_is_success( mbg_chk_dev_is_gps( dh ) ) ) + for ( i = 0; i < N_BVAR_BIT; i++ ) { - rc = mbg_chk_get_all_gnss_info( dh, &agi ); + if ( (*p) & ( 1UL << i ) ) + { + if ( printed ) + printf( ", " ); + else + printed = 1; - if ( mbg_cond_err_msg( rc, "mbg_chk_get_gnss_info" ) ) - return; + printf( "%s", bvar_flag_names[i] ); + } } - // now print information + printf( ")\n" ); + +} // print_bvar_stat + + + +static /*HDR*/ +void show_ext_stat_info( const DEVICE_STATUS *p_ds ) +{ + const PCPS_DEV *p_dev = &p_ds->dev_info; + const RECEIVER_INFO *p_ri = &p_ds->ri; + char ws[80]; + const char *cp; if ( verbose ) { - printf( "Feature mask: 0x%08lX\n", (ulong) ri.features ); + printf( "Feature mask: 0x%08lX\n", (ulong) p_ri->features ); if ( verbose > 2 ) - printf( "EPLD name: \"%s\"\n", ri.epld_name ); + printf( "EPLD name: \"%s\"\n", p_ri->epld_name ); } if ( _pcps_has_stat_info( p_dev ) ) { if ( _pcps_has_stat_info_mode( p_dev ) ) { - switch ( agi.stat_info.mode ) + switch ( p_ds->agi.stat_info.mode ) { case AUTO_166: cp = "Normal Operation"; break; case WARM_166: cp = "Warm Boot"; break; @@ -499,7 +767,7 @@ void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *t default: // This should never happen! snprintf_safe( ws, sizeof( ws ), "%s mode of operation: %02Xh", - str_unknown, agi.stat_info.mode ); + str_unknown, p_ds->agi.stat_info.mode ); cp = ws; } // switch @@ -508,25 +776,29 @@ void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *t } } - if ( agi.n_gnss_supp ) + if ( p_ds->agi.n_gnss_supp ) { - #if defined( DEBUG ) // TODO + int i; + + #if 0 && defined( DEBUG ) // FIXME TODO int must_print_sv_list = _pcps_has_stat_info_svs( p_dev ) && verbose; #else int must_print_sv_list = _pcps_is_gnss( p_dev ) && verbose; #endif - int print_multi_lines = ( agi.n_gnss_supp > 1 ) || must_print_sv_list; + int print_multi_lines = ( p_ds->agi.n_gnss_supp > 1 ) || must_print_sv_list; - // print multiple lines - // otherwise append to line + // Print multiple lines, + // or append to line. printf( print_multi_lines ? ":\n" : ", " ); - for ( i = 0; i < agi.n_gnss_supp; i++ ) + for ( i = 0; i < p_ds->agi.n_gnss_supp; i++ ) { static const char * const gnss_type_names[N_GNSS_TYPES] = GNSS_TYPE_STRS; + + const GNSS_SAT_INFO *p_gsi; int gnss_type; - p_gsi = &agi.gnss_sat_info_idx[i].gnss_sat_info; + p_gsi = &p_ds->agi.gnss_sat_info_idx[i].gnss_sat_info; gnss_type = p_gsi->gnss_type; if ( gnss_type >= N_GNSS_TYPES ) @@ -540,7 +812,7 @@ void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *t if ( print_multi_lines ) printf( " " ); - if ( agi.gnss_mode_info.settings.gnss_set & ( 1UL << gnss_type ) ) + if ( p_ds->agi.gnss_mode_info.settings.gnss_set & ( 1UL << gnss_type ) ) { printf( "%i %s sats tracked, %i expected to be visible\n", p_gsi->good_svs, cp, p_gsi->svs_in_view ); @@ -560,7 +832,7 @@ void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *t printf( "%s%i", ( sat_idx == 0 ) ? " Sats: " : ", ", sat_num ); } - if ( sat_idx ) // the satellite list has been printed + if ( sat_idx ) // The satellite list has been printed. printf( "\n" ); } } @@ -569,118 +841,223 @@ void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *t } } + + if ( p_ds->bvar_stat_avail && ( p_ds->bvar_stat || verbose ) ) + { + printf( "BVAR stat: " ); + print_bvar_stat( &p_ds->bvar_stat ); + } + + if ( verbose ) { - printf( "Osc type: %s", osc_name[( ri.osc_type < N_GPS_OSC ) ? ri.osc_type : GPS_OSC_UNKNOWN] ); + printf( "Osc type: %s", osc_name[( p_ri->osc_type < N_GPS_OSC ) ? p_ri->osc_type : GPS_OSC_UNKNOWN] ); if ( _pcps_has_stat_info( p_dev ) ) { printf( ", DAC cal: %+i, fine: %+i", - (int) ( agi.stat_info.dac_cal - OSC_DAC_BIAS ), - (int) ( agi.stat_info.dac_val - OSC_DAC_BIAS ) ); + (int) ( p_ds->agi.stat_info.dac_cal - OSC_DAC_BIAS ), + (int) ( p_ds->agi.stat_info.dac_val - OSC_DAC_BIAS ) ); } puts( "" ); } - if ( tail ) - printf( fmt, tail ); - } // show_ext_stat_info static /*HDR*/ -void show_gps_pos( MBG_DEV_HANDLE dh, const char *tail ) +int collect_ext_stat_info( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) { - POS pos = { { 0 } }; - int rc = mbg_get_gps_pos( dh, &pos ); + int rc; - if ( mbg_cond_err_msg( rc, "mbg_get_gps_pos" ) ) - return; + if ( p_ds->is_gps ) + { + rc = mbg_chk_get_all_gnss_info( dh, &p_ds->agi ); + p_ds->agi_avail = !mbg_cond_err_msg( rc, "mbg_chk_get_all_gnss_info" ); + } - print_position( "Receiver Position:", &pos, tail ); + // We always read the bvar_stat, if supported, and we + // decide later if we print the values, or not. + if ( p_ds->has_bvar_stat ) + { + rc = mbg_get_gps_bvar_stat( dh, &p_ds->bvar_stat ); + p_ds->bvar_stat_avail = !mbg_cond_err_msg( rc, "mbg_get_gps_bvar_stat" ); + } + + return MBG_SUCCESS; -} // show_gps_pos +} // collect_ext_stat_info static /*HDR*/ -void show_utc_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) +void show_syn1588_info( const DEVICE_STATUS *p_ds ) { - UTC utc = { 0 }; - struct tm tm = { 0 }; - char tmp_str[80]; - long t_ls_long; - time_t t_ls; + if ( verbose ) + { + printf( "PTP Sync Status: " ); - int rc = mbg_get_utc_parm( dh, &utc ); + if ( p_ds->syn1588_ptp_syn_status_avail ) + { + printf( "0x%08lX", (ulong) p_ds->syn1588_ptp_syn_status ); + + if ( p_ds->syn1588_ptp_syn_status == 0 ) + printf( " (unknown, Stack not running?)"); + } + else + printf( "%s", str_not_avail ); + + printf( "\n" ); + } + +} // show_syn1588_info + + + +static /*HDR*/ +void collect_syn1588_info( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + int rc = mbg_get_syn1588_ptp_sync_status( dh, &p_ds->syn1588_ptp_syn_status ); + p_ds->syn1588_ptp_syn_status_avail = !mbg_cond_err_msg( rc, "mbg_get_syn1588_ptp_sync_status" ); + +} // collect_syn1588_info - if ( mbg_cond_err_msg( rc, "mbg_get_utc_parm" ) ) - return; - if ( !utc.valid ) +static /*HDR*/ +void show_rcvr_pos( const DEVICE_STATUS *p_ds ) +{ + if ( p_ds->rcvr_pos_avail ) + print_position( "Receiver Position:", &p_ds->rcvr_pos, "\n" ); + +} // show_rcvr_pos + + + +static /*HDR*/ +int collect_rcvr_pos( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + int rc; + + if ( p_ds->has_rcvr_pos ) { - puts( "** UTC parameters not valid" ); - goto out; + rc = mbg_get_gps_pos( dh, &p_ds->rcvr_pos ); + p_ds->rcvr_pos_avail = !mbg_cond_err_msg( rc, "mbg_get_gps_pos" ); } - t_ls_long = (long) utc.WNlsf * SECS_PER_WEEK - + (long) utc.DNt * SECS_PER_DAY - + GPS_SEC_BIAS - 1; - t_ls = cvt_to_time_t( t_ls_long ); + return MBG_SUCCESS; + +} // collect_rcvr_pos - rc = mbg_gmtime( &tm, &t_ls ); - if ( mbg_rc_is_success( rc ) ) - mbg_snprintf( tmp_str, sizeof( tmp_str ), "at UTC midnight at the end of %s, %04i-%02i-%02i", - wdays[tm.tm_wday], tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday ); - else - snprint_gmtime_error( tmp_str, sizeof( tmp_str ), rc, t_ls, __func__ ); + +static /*HDR*/ +void show_utc_info( const DEVICE_STATUS *p_ds ) +{ + MBG_LS_INFO lsi; + GPS_WNUM true_wn_ls; + struct tm tm = { 0 }; + char tmp_str[80]; + const char *cp; + int rc; + + if ( !p_ds->utc_info_avail ) + goto out; + + // Try to evaluate the UTC parameter set and determine + // the date of the nearest leap second. + rc = mbg_set_ls_info_from_gps_utc( &lsi, &p_ds->utc_info, &true_wn_ls ); if ( verbose > 1 ) { printf( "UTC correction parameters:\n" ); - printf( " CSUM: %04X, valid: %04X\n", utc.csum, utc.valid ); - printf( " t0t: %u|%u.%07u, A0: %g A1: %g\n", - utc.t0t.wn, utc.t0t.sec, utc.t0t.tick, - utc.A0, utc.A1 ); - printf( " WNlsf: %u, DN: %u, offs: %i/%i\n", - utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf ); + printf( STR_INDENT "CSUM: %04X, valid: %04X\n", p_ds->utc_info.csum, p_ds->utc_info.valid ); + printf( STR_INDENT "t0t: %u|%u.%07u, A0: %g A1: %g\n", + p_ds->utc_info.t0t.wn, p_ds->utc_info.t0t.sec, p_ds->utc_info.t0t.tick, + p_ds->utc_info.A0, p_ds->utc_info.A1 ); + printf( STR_INDENT "WNlsf: %u", p_ds->utc_info.WNlsf ); + + // Under certain conditions, the week number read from GPS receivers + // can be ambiguous, and the evaluation function called above may have + // determined and returned the true week number, so we show it here. + if ( mbg_rc_is_success( rc ) && p_ds->utc_info.WNlsf && lsi.valid ) + printf( " (true: %u)", true_wn_ls ); + + printf( ", DN: %u, offs: %i/%i\n", + p_ds->utc_info.DNt, p_ds->utc_info.delta_tls, p_ds->utc_info.delta_tlsf ); } - if ( utc.delta_tls != utc.delta_tlsf ) + if ( ( p_ds->utc_info.WNlsf == 0 ) && ( p_ds->utc_info.DNt == 0 ) ) { - // A leap second is currently being announced - printf( "GPS/UTC offset transition from %is to %is due to leap second\n" - "%s %s.\n", - utc.delta_tls, utc.delta_tlsf, - ( utc.delta_tls < utc.delta_tlsf ) ? "insertion" : "deletion", - tmp_str - ); + if ( verbose ) + printf( "Leap second information not set\n" ); + goto out; } - if ( ( utc.WNlsf == 0 ) && ( utc.DNt == 0 ) ) + // Check once more if the evaluation above was successful. + if ( mbg_rc_is_error( rc ) ) + { + if ( rc == MBG_ERR_INV_PARM ) + puts( "** UTC parameters not valid" ); + else + fprintf( stderr, "** Failed to evaluate GNSS UTC parameters: %s\n", + mbg_strerror( rc ) ); + goto out; + } + + // Evaluation was successful, now check if valid data + // could be determined. + if ( !lsi.valid ) { if ( verbose ) - printf( "Leap second information not set\n" ); + puts( "UTC parameters could not be evaluated" ); goto out; } + // A valid UTC timestamp of the second *after* the nearest leap second + // could be determined. We display the time associated with that + // timestamp because we may not be able to figure out whether the + // leap second is or was a positive one (second 60 inserted), or a + // negative one (second 59 deleted). + rc = mbg_gmtime64( &tm, &lsi.t64_ls_utc ); - if ( verbose ) + if ( mbg_rc_is_success( rc ) ) { - printf( "Last leap second eventually %s\n", tmp_str ); - goto out; + snprintf_safe( tmp_str, sizeof( tmp_str ), "UTC midnight on %s, %04i-%02i-%02i", + wdays[tm.tm_wday], tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday ); + cp = tmp_str; } + else // Timestamp conversion failed, which is unlikely, but ... + cp = "unknown point in time"; + // Now print information, depending on whether a leap second is being + // announced, or not, and whether we want verbose output, or not. + if ( lsi.ls_step ) // A leap second is currently being announced. + { + printf( "%s of a leap second is announced!\n", + ( lsi.ls_step < 0 ) ? "Deletion" : "Insertion" ); + + printf( "%sThe GPS/UTC offset steps from %i s to %i s\n", + verbose ? str_indent : str_empty, + p_ds->utc_info.delta_tls, p_ds->utc_info.delta_tlsf ); + + printf( "%sat %s.\n", verbose ? str_indent : str_empty, cp ); + } + else // No leapsecond currently announced. + { + printf( "Current GPS/UTC offset: %i s, no leap second announced.\n", + lsi.offs_gps_utc ); + + if ( verbose ) + printf( "Nearest leap second just before %s.\n", cp ); + } - printf( "GPS/UTC offset parameter: %is, no leap second announced.\n", utc.delta_tls ); out: return; @@ -690,24 +1067,55 @@ out: static /*HDR*/ -void show_irig_ctrl_bits( MBG_DEV_HANDLE dh ) +int collect_utc_info( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) { - MBG_IRIG_CTRL_BITS irig_ctrl_bits; + const PCPS_DEV *p_dev = &p_ds->dev_info; + int rc; - int rc = mbg_get_irig_ctrl_bits( dh, &irig_ctrl_bits ); + if ( p_ds->has_utc_parm && ( _pcps_is_gps( p_dev ) || ( verbose > 0 ) ) ) + { + rc = mbg_get_utc_parm( dh, &p_ds->utc_info ); + p_ds->utc_info_avail = !mbg_cond_err_msg( rc, "mbg_get_utc_parm" ); + } - if ( mbg_cond_err_msg( rc, "mbg_get_irig_ctrl_bits" ) ) - return; + return MBG_SUCCESS; + +} // collect_utc_info - printf( "IRIG control bits: %08lX (hex, LSB first)", (ulong) irig_ctrl_bits ); - printf( ", TFOM: 0x%X", _pcps_tfom_from_irig_ctrl_bits( &irig_ctrl_bits ) ); - printf( "\n" ); + + +static /*HDR*/ +void show_irig_ctrl_bits( const DEVICE_STATUS *p_ds ) +{ + if ( p_ds->irig_ctrl_bits_avail ) + { + printf( "IRIG control bits: %08lX (hex, LSB first)", (ulong) p_ds->irig_ctrl_bits ); + printf( ", TFOM: 0x%X", _pcps_tfom_from_irig_ctrl_bits( &p_ds->irig_ctrl_bits ) ); + printf( "\n" ); + } } // show_irig_ctrl_bits static /*HDR*/ +int collect_irig_ctrl_bits( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + int rc; + + if ( p_ds->has_irig_ctrl_bits && verbose ) + { + rc = mbg_get_irig_ctrl_bits( dh, &p_ds->irig_ctrl_bits ); + p_ds->irig_ctrl_bits_avail = !mbg_cond_err_msg( rc, "mbg_get_irig_ctrl_bits" ); + } + + return MBG_SUCCESS; + +} // collect_irig_ctrl_bits + + + +static /*HDR*/ char *str_raw_irig_utc_offs_hours( char *s, size_t max_len, const MBG_RAW_IRIG_DATA *p ) { size_t n; @@ -728,26 +1136,40 @@ char *str_raw_irig_utc_offs_hours( char *s, size_t max_len, const MBG_RAW_IRIG_D static /*HDR*/ -void show_raw_irig_data( MBG_DEV_HANDLE dh ) +void show_raw_irig_data( const DEVICE_STATUS *p_ds ) { - MBG_RAW_IRIG_DATA raw_irig_data; - char ws[80]; - int i; + if ( p_ds->raw_irig_data_avail ) + { + char ws[80]; + int i; - int rc = mbg_get_raw_irig_data( dh, &raw_irig_data ); + printf( "Raw IRIG data:" ); - if ( mbg_cond_err_msg( rc, "mbg_get_raw_irig_data" ) ) - return; + for ( i = 0; i < sizeof( p_ds->raw_irig_data ); i++ ) + printf( " %02X", p_ds->raw_irig_data.data_bytes[i] ); + + printf( " (hex)" ); + printf( ", TFOM: 0x%X", _pcps_tfom_from_raw_irig_data( &p_ds->raw_irig_data ) ); + printf( ", UTC offs: %sh", str_raw_irig_utc_offs_hours( ws, sizeof( ws ), &p_ds->raw_irig_data ) ); + printf( "\n" ); + } - printf( "Raw IRIG data:" ); +} // show_raw_irig_data - for ( i = 0; i < sizeof( raw_irig_data ); i++ ) - printf( " %02X", raw_irig_data.data_bytes[i] ); - printf( " (hex)" ); - printf( ", TFOM: 0x%X", _pcps_tfom_from_raw_irig_data( &raw_irig_data ) ); - printf( ", UTC offs: %sh", str_raw_irig_utc_offs_hours( ws, sizeof( ws ), &raw_irig_data ) ); - printf( "\n" ); + +static /*HDR*/ +int collect_raw_irig_data( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + int rc; + + if ( p_ds->has_raw_irig_data && verbose ) + { + rc = mbg_get_raw_irig_data( dh, &p_ds->raw_irig_data ); + p_ds->raw_irig_data_avail = !mbg_cond_err_msg( rc, "mbg_get_raw_irig_data" ); + } + + return MBG_SUCCESS; } // show_raw_irig_data @@ -850,7 +1272,7 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) return; - // set up some flags controlling which information to be shown + // Set up some flags controlling which information to be shown. must_show_slave_mode_info = ( verbose > 1 ) || ( ( ( 1UL << ptp_info.settings.ptp_role ) & PTP_ROLE_MSK_SLAVES ) != 0 ); @@ -868,7 +1290,7 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) any_mode_active = slave_mode_active || master_mode_active; - // PTP role and port state + // PTP role and port state. printf( "PTP port state:\n" ); @@ -895,7 +1317,7 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) { printf( " PTP protocol: " ); - // If not fully synchronized then not all fields of the PTP_STATE + // If not fully synchronized, not all fields of the PTP_STATE // structure may have been filled, so we show configuration settings // in this case. @@ -948,16 +1370,16 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) } - // PTP time scale + // PTP time scale. cp = NULL; - if ( ptp_state.flags & PTP_FLAG_MSK_TIMESCALE_IS_PTP ) // this is the default + if ( ptp_state.flags & PTP_FLAG_MSK_TIMESCALE_IS_PTP ) // This is the default. { if ( must_show_master_mode_info || verbose ) cp = "TAI (standard)"; } - else // unusual case, print info if available + else // Unusual case, print info if available. if ( any_mode_active ) cp = "arbitrary (non-standard)"; @@ -965,14 +1387,14 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) printf( " PTP time scale: %s\n", cp ); - // UTC offset and leap second status + // UTC offset and leap second status. utc_offset_valid = ( ptp_state.flags & PTP_FLAG_MSK_UTC_VALID ) != 0; printf( " PTP UTC offset: " ); if ( !utc_offset_valid ) - printf( " %s", str_unknown ); // UTC offset not valid + printf( " %s", str_unknown ); // UTC offset not valid. if ( utc_offset_valid || ( verbose > 1 ) ) { @@ -980,9 +1402,9 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) printf( "%+i s", ptp_state.utc_offset ); - if ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN ) // leap second is announced + if ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN ) // Leap second is announced. { - // distinguish between leap second insertion and deletion + // Distinguish between leap second insertion and deletion. printf( ", leap second %s scheduled", ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN_NEG ) ? "deletion" : "insertion" ); } @@ -1027,21 +1449,39 @@ void show_ptp_state( MBG_DEV_HANDLE dh ) printf( "\n" ); } - - } // show_ptp_state static /*HDR*/ -int check_irq_unsafe( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) +/*HDR*/ +/** + * @brief Read the version code of the on-board PCI/PCIe interface ASIC. + * + * The API call ::mbg_chk_dev_has_asic_version checks whether + * this call is supported by a device. + * + * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device. + * @param[out] p_dev Pointer to a ::PCI_ASIC_VERSION type to be filled up. + * + * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES + * + * @see ::mbg_chk_dev_has_asic_version + */ +int check_irq_safe( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) { PCPS_IRQ_STAT_INFO irq_stat_info; - int ret_val = 0; int rc = mbg_get_irq_stat_info( dh, &irq_stat_info ); + if ( rc == MBG_ERR_NOT_SUPP_BY_DEV || rc == MBG_ERR_UNSPEC ) + { + // Not supported by device, so no need to check. + rc = MBG_SUCCESS; + goto out; + } + if ( mbg_cond_err_msg( rc, "mbg_get_irq_stat_info" ) ) - return rc; + goto out; if ( irq_stat_info & PCPS_IRQ_STAT_UNSAFE ) { @@ -1068,61 +1508,185 @@ int check_irq_unsafe( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) { printf( "**\n" - "** Interrupts are currently enabled for this card (NTP daemon running?)\n" + "** Interrupts are currently enabled for this device (NTP daemon running?)\n" "** so other access is inhibited to prevent the system from hanging.\n" ); - ret_val = -1; + rc = MBG_ERR_IRQ_UNSAFE; } puts( warn_line ); puts( "" ); } - return ret_val; +out: + return rc; -} // check_irq_unsafe +} // check_irq_safe + + + +static /*HDR*/ +int check_all_device_features( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds, + const PCPS_DEV *p_dev, bool is_syn1588 ) +{ + int rc = MBG_SUCCESS; + + memset( p_ds, 0, sizeof( *p_ds ) ); + + p_ds->dev_info = *p_dev; + + p_ds->is_syn1588 = is_syn1588; + + rc = mbg_setup_receiver_info( dh, p_dev, &p_ds->ri ); + + if ( mbg_cond_err_msg( rc, "mbg_setup_receiver_info" ) ) + goto out; + + + // p_ds->has_receiver_info = mbg_rc_is_success( ( dh ) ); + // p_ds->has_gps_data = mbg_rc_is_success( ( dh ) ); + // p_ds->has_generic_io = mbg_rc_is_success( ( dh ) ); + // p_ds->has_asic_version = mbg_rc_is_success( ( dh ) ); + // p_ds->has_asic_features = mbg_rc_is_success( ( dh ) ); + // p_ds->has_xmr = mbg_rc_is_success( ( dh ) ); + // p_ds->is_isa = mbg_rc_is_success( ( dh ) ); + // p_ds->is_mca = mbg_rc_is_success( ( dh ) ); + // p_ds->is_pci = mbg_rc_is_success( ( dh ) ); + // p_ds->is_pci_express = mbg_rc_is_success( ( dh ) ); + // p_ds->is_usb = mbg_rc_is_success( ( dh ) ); + p_ds->is_gps = mbg_rc_is_success( mbg_chk_dev_is_gps( dh ) ); + // p_ds->is_gnss = mbg_rc_is_success( ( dh ) ); + // p_ds->is_dcf = mbg_rc_is_success( ( dh ) ); + // p_ds->has_pzf = mbg_rc_is_success( ( dh ) ); + // p_ds->is_msf = mbg_rc_is_success( ( dh ) ); + // p_ds->is_wwvb = mbg_rc_is_success( ( dh ) ); + // p_ds->is_jjy = mbg_rc_is_success( ( dh ) ); + // p_ds->is_lwr = mbg_rc_is_success( ( dh ) ); + // p_ds->is_tcr = mbg_rc_is_success( ( dh ) ); + // p_ds->has_lan_intf = mbg_rc_is_success( ( dh ) ); + // p_ds->has_ptp = mbg_rc_is_success( ( dh ) ); + // p_ds->has_ptp_unicast = mbg_rc_is_success( ( dh ) ); + p_ds->has_hr_time = mbg_rc_is_success( mbg_chk_dev_has_hr_time( dh ) ); + p_ds->has_fast_hr_timestamp = mbg_rc_is_success( mbg_chk_dev_has_fast_hr_timestamp( dh ) ); + // p_ds->has_time_scale = mbg_rc_is_success( ( dh ) ); + // p_ds->has_event_time = mbg_rc_is_success( ( dh ) ); + // p_ds->has_ucap = mbg_rc_is_success( ( dh ) ); + // p_ds->can_clr_ucap_buff = mbg_rc_is_success( ( dh ) ); + // p_ds->has_tzdl = mbg_rc_is_success( ( dh ) ); + // p_ds->has_pcps_tzdl = mbg_rc_is_success( ( dh ) ); + // p_ds->has_tzcode = mbg_rc_is_success( ( dh ) ); + // p_ds->has_tz = mbg_rc_is_success( ( dh ) ); + // p_ds->has_irig = mbg_rc_is_success( ( dh ) ); + p_ds->has_irig_rx = mbg_rc_is_success( mbg_chk_dev_is_tcr( dh ) ); + // p_ds->has_irig_tx = mbg_rc_is_success( ( dh ) ); + // p_ds->has_irig_ctrl_bits = mbg_rc_is_success( ( dh ) ); + // p_ds->has_raw_irig_data = mbg_rc_is_success( ( dh ) ); + p_ds->has_irig_time = mbg_rc_is_success( mbg_chk_dev_has_irig_time( dh ) ); + // p_ds->has_signal = mbg_rc_is_success( ( dh ) ); + // p_ds->has_mod = mbg_rc_is_success( ( dh ) ); + p_ds->has_sync_time = mbg_rc_is_success( mbg_chk_dev_has_sync_time( dh ) ); + p_ds->has_rcvr_pos = mbg_rc_is_success( mbg_chk_dev_has_rcvr_pos( dh ) ); + p_ds->has_bvar_stat = mbg_rc_is_success( mbg_chk_dev_has_bvar_stat( dh ) ); + p_ds->has_ttm_time = mbg_rc_is_success( mbg_chk_dev_has_ttm_time( dh ) ); + // p_ds->has_serial = mbg_rc_is_success( ( dh ) ); + // p_ds->has_serial_hs = mbg_rc_is_success( ( dh ) ); + // p_ds->has_synth = mbg_rc_is_success( ( dh ) ); + // p_ds->has_gpio = mbg_rc_is_success( ( dh ) ); + // p_ds->has_cab_len = mbg_rc_is_success( ( dh ) ); + p_ds->has_ref_offs = mbg_rc_is_success( mbg_chk_dev_has_ref_offs( dh ) ); + // p_ds->has_opt_flags = mbg_rc_is_success( ( dh ) ); + p_ds->has_utc_parm = mbg_rc_is_success( mbg_chk_dev_has_utc_parm( dh ) ); + // p_ds->has_corr_info = mbg_rc_is_success( ( dh ) ); + // p_ds->has_tr_distance = mbg_rc_is_success( ( dh ) ); + // p_ds->has_debug_status = mbg_rc_is_success( ( dh ) ); + // p_ds->has_evt_log = mbg_rc_is_success( ( dh ) ); + // p_ds->has_dac_ctrl = mbg_rc_is_success( ( dh ) ); + +out: + return rc; + +} // check_all_device_features + + + +static /*HDR*/ +int collect_all_device_status( MBG_DEV_HANDLE dh, DEVICE_STATUS *p_ds ) +{ + if ( p_ds->is_syn1588 ) + collect_syn1588_info( dh, p_ds ); + else + collect_ext_stat_info( dh, p_ds ); + + collect_time_and_status( dh, p_ds ); + collect_irig_status( dh, p_ds ); + collect_sync_time( dh, p_ds ); + collect_rcvr_pos( dh, p_ds ); + collect_utc_info( dh, p_ds ); + collect_irig_ctrl_bits( dh, p_ds ); + collect_raw_irig_data( dh, p_ds ); + + return MBG_SUCCESS; + +} // collect_all_device_status + + + +static /*HDR*/ +void print_all_device_status( const DEVICE_STATUS *p_ds ) +{ + if ( p_ds->is_syn1588 ) + show_syn1588_info( p_ds ); + else + show_ext_stat_info( p_ds ); + + show_time_and_status( p_ds ); + show_sync_time( p_ds ); + show_rcvr_pos( p_ds ); + show_utc_info( p_ds ); + show_irig_ctrl_bits( p_ds ); + show_raw_irig_data( p_ds ); + +} // print_all_device_status static /*HDR*/ int do_mbgstatus( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) { + DEVICE_STATUS device_status; + DEVICE_STATUS *p_ds = &device_status; int ret_val = 0; - if ( check_irq_unsafe( dh, p_dev ) < 0 ) - goto done; - - if ( list_only ) - goto done; + // SYN1588 devices are somewhat different ... + bool is_syn1588 = mbg_rc_is_success( mbg_chk_dev_is_syn1588_type( dh ) ); - for (;;) + if ( !is_syn1588 ) { - if ( _pcps_has_gps_data( p_dev ) ) - show_ext_stat_info( dh, p_dev, NULL ); - - show_time_and_status( dh, p_dev, "\n" ); - show_sync_time( dh, "\n" ); + if ( mbg_rc_is_error( check_irq_safe( dh, p_dev ) ) ) + goto done; - if ( _pcps_is_gps( p_dev ) ) - show_gps_pos( dh, "\n" ); + if ( verbose ) + show_dev_cpu_info( dh ); + } - if ( _pcps_has_utc_parm( p_dev ) && ( _pcps_is_gps( p_dev ) || ( verbose > 0 ) ) ) - show_utc_info( dh, p_dev ); + if ( list_only ) + goto done; - if ( verbose && _pcps_has_irig_ctrl_bits( p_dev ) ) - show_irig_ctrl_bits( dh ); + check_all_device_features( dh, p_ds, p_dev, is_syn1588 ); - if ( verbose && ( mbg_chk_dev_has_raw_irig_data( dh ) == MBG_SUCCESS ) ) - show_raw_irig_data( dh ); + for (;;) + { + collect_all_device_status( dh, p_ds ); + print_all_device_status( p_ds ); if ( verbose && _pcps_is_irig_rx( p_dev ) ) show_irig_debug_status( dh ); - if ( mbg_chk_dev_has_lan_intf( dh ) == MBG_SUCCESS ) + if ( mbg_rc_is_success( mbg_chk_dev_has_lan_intf( dh ) ) ) show_lan_intf_state( dh ); - if ( _pcps_has_ptp( p_dev ) ) + if ( mbg_rc_is_success( mbg_chk_dev_has_ptp( dh ) ) ) show_ptp_state( dh ); show_invt_reason(); @@ -1139,9 +1703,9 @@ int do_mbgstatus( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( sleep_usecs ) usleep( sleep_usecs ); - printf( "\n" ); + // If this_loops is < 0, loop forever. - // if this_loops is < 0 then loop forever + printf( "\n" ); } done: @@ -1162,14 +1726,14 @@ void usage( void ) "The displayed information depends on the type of the card." ); mbg_print_help_options(); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-l", "list devices only" ); - mbg_print_opt_info( "-L", "list unique names of all devices" ); - mbg_print_opt_info( "-n num", "run num loops" ); - mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" ); - mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" ); - mbg_print_opt_info( "-v", "increase verbosity" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-l", "List devices only" ); + mbg_print_opt_info( "-L", "List unique names of all devices" ); + mbg_print_opt_info( "-n num", "Run num loops" ); + mbg_print_opt_info( "-s num", "Sleep num seconds between calls (implies -c)" ); + mbg_print_opt_info( "-u num", "Sleep num microseconds between calls (implies -c)" ); + mbg_print_opt_info( "-v", "Increase verbosity" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -1188,7 +1752,7 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters + // Check command line parameters. while ( ( c = getopt( argc, argv, "clLn:s:u:vh?" ) ) != -1 ) { switch ( c ) @@ -1226,7 +1790,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } @@ -1252,7 +1816,7 @@ int main( int argc, char *argv[] ) printf( " %s\n", pos->dev_name ); } else - printf( "No device found.\n" ); + mbg_print_no_device_found(); mbg_free_device_name_list( list_head ); printf( "\n" ); diff --git a/mbgtcrcal/mbgtcrcal.c b/mbgtcrcal/mbgtcrcal.c index da4dd5b..1d3a625 100644 --- a/mbgtcrcal/mbgtcrcal.c +++ b/mbgtcrcal/mbgtcrcal.c @@ -1,15 +1,24 @@ /************************************************************************** * - * $Id: mbgtcrcal.c 1.13 2018/12/14 13:04:53Z martin REL_M $ + * $Id: mbgtcrcal.c 1.17 2021/04/12 21:58:03Z martin REL_M $ * * Description: * Main file for mbgtcrcal program which can be used to calibrate - * the IRIG input of some TCR cards. + * the IRIG input of some TCR devices. * * ----------------------------------------------------------------------- * $Log: mbgtcrcal.c $ - * Revision 1.13 2018/12/14 13:04:53Z martin + * Revision 1.17 2021/04/12 21:58:03Z martin + * Updated printing of usage information. + * Revision 1.16 2021/03/21 22:40:47 martin + * Updated a bunch of comments. + * Revision 1.15 2021/03/12 12:32:55 martin + * Updated some comments. + * Revision 1.14 2020/10/20 10:46:54 martin + * Use function mbg_has_admin_rights() to determine + * if the program runs with admin rights. + * Revision 1.13 2018/12/14 13:04:53 martin * Unified usage output. * Use predefined macros to check return codes. * Revision 1.12 2018/12/11 16:15:39 martin @@ -29,7 +38,7 @@ * Revision 1.5 2016/07/22 09:53:54 martin * Use new, safe library functions. * Revision 1.4 2013/12/04 10:00:14 martin - * Fixed build under Windows. + * Fixed build on Windows. * Revision 1.3 2013/07/22 16:26:42Z martin * Updated a comment. * Revision 1.2 2013/07/11 08:28:44 martin @@ -39,12 +48,12 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <irig_cal.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. #include <str_util.h> -// include system headers +// Include system headers. #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -52,7 +61,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2012 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgtcrcal"; @@ -64,7 +73,7 @@ static const char *irig_comp_names[N_IRIG_RX_COMP] = DEFAULT_IRIG_RX_COMP_NAMES; static double cal_val; // [microseconds] static int must_set_cal_val; -static size_t max_label_len; // determined at runtime +static size_t max_label_len; // Determined at runtime. @@ -124,7 +133,7 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) int curr_group_idx; - // check if this device provides an IRIG input + // Check if this device provides an IRIG input. if ( !_pcps_is_irig_rx( p_dev ) ) { printf( "This device does not provide an IRIG input.\n" ); @@ -132,7 +141,7 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) } - // read the current IRIG input configuration + // Read the current IRIG input configuration. rc = mbg_get_irig_rx_info( dh, &irig_rx_info ); if ( mbg_rc_is_error( rc ) ) @@ -142,7 +151,7 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) } - // check if the currently configured IRIG code is supported by this program + // Check if the currently configured IRIG code is supported by this program. if ( irig_rx_info.settings.icode >= N_ICODE_RX ) { printf( "IRIG code %i configured on this device exceeds the maximum code supported by this program (%i)!\n", @@ -150,7 +159,7 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) goto done; } - // determine the compensation code group for the current IRIG code + // Determine the compensation code group for the current IRIG code. curr_group_idx = mbg_icode_rx_to_group_idx( irig_rx_info.settings.icode ); if ( curr_group_idx < 0 ) @@ -168,7 +177,7 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) } - // read current compensation settings + // Read current compensation settings. rc = mbg_get_cal_rec_irig_rx_num_rec( dh, &num_rec ); #if defined( DEBUG ) @@ -187,19 +196,19 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) } - // do some plausibility checks + // Do some plausibility checks. if ( curr_group_idx >= num_rec ) { printf( "** Warning: the compensation group index for the current IRIG code (%i)\n" - "exceeds the number of records supported by the card (%i).\n", + "exceeds the number of records supported by the device (%i).\n", curr_group_idx, num_rec - 1 ); } if ( num_rec > N_IRIG_RX_COMP ) { - printf( "** The number of calibration records actually supported by the card (%i)\n" + printf( "** The number of calibration records actually supported by the device (%i)\n" "exceeds the number of records supported by this program (%i).\n", num_rec, N_IRIG_RX_COMP ); num_rec = N_IRIG_RX_COMP; @@ -208,12 +217,12 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( num_rec == 0 ) { - printf( "** This card does not support any IRIG RX calibration records\n" ); + printf( "** This device does not support any IRIG RX calibration records.\n" ); goto done; } - // determine the maximum length of the group names to be displayed later + // Determine the maximum length of the group names to be displayed later. for ( idx = 0; idx < num_rec; idx++ ) { size_t l = strlen( irig_comp_names[idx] ); @@ -263,11 +272,11 @@ int do_mbgtcrcal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) printf( "\n" ); - // save new calibration setting effective for the current IRIG code + // Save new calibration setting effective for the current IRIG code. p = &cal_rec_comp[curr_group_idx]; - p->hdr.type = CAL_REC_TYPE_IRIG_RX_COMP; // just to be sure + p->hdr.type = CAL_REC_TYPE_IRIG_RX_COMP; // Just to be sure. memset( &p->comp_data, 0, sizeof( p->comp_data ) ); - p->comp_data.c[0] = (int16_t) ( cal_val * 10 ); // us to hns + p->comp_data.c[0] = (int16_t) ( cal_val * 10 ); // us to hns. rc = mbg_set_cal_rec_irig_rx_comp( dh, p ); @@ -301,17 +310,17 @@ void usage( void ) "Show or set IRIG RX calibration parameters of devices which support this." ); mbg_print_help_options(); - mbg_print_opt_info( "-c val", "set calibration value \'val\'" ); - mbg_print_opt_info( "-v", "increase verbosity" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c val", "Set calibration value \'val\'" ); + mbg_print_opt_info( "-v", "Increase verbosity" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); printf( "Example usage:\n" "\n" - "%s print current settings of the default device\n" - "%s [dev] print current settings of specific device [dev]\n" - "%s -c 10 compensate +10.0 us on default device\n" - "%s -c -12.1 [dev] compensate -12.1 us on specific device [dev]\n" + "%s Print current settings of the default device\n" + "%s [dev] Print current settings of specific device [dev]\n" + "%s -c 10 Compensate +10.0 us on default device\n" + "%s -c -12.1 [dev] Compensate -12.1 us on specific device [dev]\n" "\n", pname, pname, pname, pname ); printf( "New settings become effective for a group of IRIG codes with similar characteristics\n" "to which the currently configured IRIG RX code belongs. Calibration values are\n" @@ -331,7 +340,7 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters + // Check command line parameters. while ( ( c = getopt( argc, argv, "c:vh?" ) ) != -1 ) { switch ( c ) @@ -348,14 +357,12 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } - #if defined( MBG_TGT_POSIX ) - if ( geteuid() != 0 ) - must_print_usage = 1; - #endif + if ( !mbg_has_admin_rights() ) + must_print_usage = true; if ( must_print_usage ) { @@ -364,7 +371,7 @@ int main( int argc, char *argv[] ) if ( !must_print_usage ) printf( "(Built with DEBUG, so resuming anyway)\n" ); #else - must_print_usage = 1; + must_print_usage = true; #endif printf( "\n" ); } diff --git a/mbgxhrtime/mbgxhrtime.c b/mbgxhrtime/mbgxhrtime.c index 150dab1..e79471b 100644 --- a/mbgxhrtime/mbgxhrtime.c +++ b/mbgxhrtime/mbgxhrtime.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgxhrtime.c 1.7 2018/11/15 12:12:35Z martin REL_M $ + * $Id: mbgxhrtime.c 1.10 2021/04/12 21:57:48Z martin REL_M $ * * Description: * Main file for mbgxhrtime program which demonstrates how to retrieve @@ -19,11 +19,11 @@ * * Notes: * - * 1.) This approach works / makes sense only with cards which support - * high resolution time stamps (HR time). If a card doesn't support - * that then this program prints a warning. + * 1.) This approach works / makes sense only with devices that support + * high resolution time stamps (HR time). If a device doesn't support + * this, the program prints a warning. * - * 2.) Under Linux extrapolation is done using the time stamp counter + * 2.) On Linux, extrapolation is done using the time stamp counter * (TSC) registers provided by Pentium CPUs and newer/compatible * types as the cycles counter. On SMP / multicore CPUs those * counters may not be synchronized, so this works only correctly @@ -32,20 +32,26 @@ * the first CPU at program start, which means all threads of this * process are executed only on that CPU. * - * 3.) Under Linux there's no easy way to find the accurate clock + * 3.) On Linux there's no easy way to find the accurate clock * frequency of the cycles counter, so the polling thread computes * the frequency from the time differences of 2 subsequent polls * of the PCI card. If the time extrapolation function is called - * before the cycles clock frequency has been determined the + * before the cycles clock frequency has been determined, the * returned time stamp is always 0. * * ----------------------------------------------------------------------- * $Log: mbgxhrtime.c $ - * Revision 1.7 2018/11/15 12:12:35Z martin + * Revision 1.10 2021/04/12 21:57:48Z martin + * Updated printing of usage information. + * Revision 1.9 2021/03/21 22:40:58 martin + * Updated some comments. + * Revision 1.8 2021/03/12 12:32:08 martin + * Updated some comments. + * Revision 1.7 2018/11/15 12:12:35 martin * Individual MBG_MICRO_VERSION codes are now obsolete. * Revision 1.6 2017/07/05 18:38:18 martin * New way to maintain version information. - * Support build under Windows. + * Support build on Windows. * Use more functions from common library modules. * Use codes and inline functions from mbgerror.h. * Proper return codes and exit codes. @@ -64,11 +70,11 @@ * **************************************************************************/ -// include Meinberg headers +// Include Meinberg headers. #include <mbgdevio.h> -#include <toolutil.h> // common utility functions +#include <toolutil.h> // Common utility functions. -// include system headers +// Include system headers. #include <time.h> #include <stdio.h> #include <stdlib.h> @@ -89,7 +95,7 @@ #define MBG_FIRST_COPYRIGHT_YEAR 2008 -#define MBG_LAST_COPYRIGHT_YEAR 0 // use default +#define MBG_LAST_COPYRIGHT_YEAR 0 // Use default. static const char *pname = "mbgxhrtime"; @@ -230,8 +236,8 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) has_printed_msg = 0; } - // get an extrapolated time stamp bracketed by - // mbg_get_pc_cycles() calls to compute the latency + // Get an extrapolated time stamp bracketed by + // mbg_get_pc_cycles() calls to compute the latency. mbg_get_pc_cycles( &cyc_1 ); rc = mbg_get_xhrt_time_as_pcps_hr_time( &poll_thread_info.xhrt_info, &hrt ); mbg_get_pc_cycles( &cyc_2 ); @@ -239,11 +245,11 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( rc != MBG_SUCCESS ) goto fail; - // compute the latency + // Compute the latency. latency = ( (double) cyc_2 - (double) cyc_1 ) / (double) (int64_t) freq_hz * 1E6; - // convert to human readable date and time - mbg_snprint_hr_time( ws, sizeof( ws ), &hrt, 0 ); // raw timestamp? + // Convert to human readable date and time. + mbg_snprint_hr_time( ws, sizeof( ws ), &hrt, 0 ); // Raw timestamp? printf( "t: %s (%.3f us)\n", ws, latency ); if ( this_loops > 0 ) @@ -252,7 +258,7 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev ) if ( this_loops == 0 ) break; - // if this_loops is < 0 then loop forever + // If this_loops is < 0, loop forever. } goto done; @@ -287,9 +293,9 @@ void usage( void ) "This works only for devices which support high resolution time (HR time)." ); mbg_print_help_options(); - mbg_print_opt_info( "-c", "run continuously" ); - mbg_print_opt_info( "-n num", "run num loops" ); - mbg_print_device_options(); + mbg_print_opt_info( "-c", "Run continuously" ); + mbg_print_opt_info( "-n num", "Run num loops" ); + mbg_print_device_options( DEV_OPT_PRINT_BUS_LEVEL ); puts( "" ); } // usage @@ -303,7 +309,7 @@ int main( int argc, char *argv[] ) mbg_print_program_info( pname, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR ); - // check command line parameters + // Check command line parameters. while ( ( c = getopt( argc, argv, "cn:h?" ) ) != -1 ) { switch ( c ) @@ -319,7 +325,7 @@ int main( int argc, char *argv[] ) case 'h': case '?': default: - must_print_usage = 1; + must_print_usage = true; } } |