summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2011-04-18 12:00:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2011-04-18 12:00:00 +0200
commitf8f66e249cd7246b3f7d864748e8a49dbda105d7 (patch)
tree45946e5a40924f6050d70720dc0b328d121fc0ef
parent65232611c8d9151691909912345435f05ad28e77 (diff)
downloadgpsxmple-f8f66e249cd7246b3f7d864748e8a49dbda105d7.tar.gz
gpsxmple-f8f66e249cd7246b3f7d864748e8a49dbda105d7.zip
Feature updatesgpsxmple-2.3-dos-win
Optionally poll for user capture events. Update library functions, e.g. mbgextio_get_ucap() has been modified to account for different device behaviour.
-rwxr-xr-xdos/gpsxmple.exebin68080 -> 68752 bytes
-rw-r--r--[-rwxr-xr-x]dos/gpsxmple.prjbin8433 -> 8433 bytes
-rw-r--r--gpsxmple.c168
-rw-r--r--mbglib/common/gpsdefs.h912
-rw-r--r--mbglib/common/gpsserio.h222
-rw-r--r--mbglib/common/mbg_tgt.h1
-rw-r--r--mbglib/common/mbg_tmo.c64
-rw-r--r--mbglib/common/mbg_tmo.h317
-rw-r--r--mbglib/common/mbgextio.c52
-rw-r--r--mbglib/common/mbgextio.h14
-rw-r--r--mbglib/common/mbgmutex.h239
-rw-r--r--mbglib/common/mbgserio.c960
-rw-r--r--mbglib/common/mbgserio.h213
-rw-r--r--mbglib/common/pcpsdefs.h1273
-rw-r--r--mbglib/common/use_pack.h18
-rw-r--r--mbglib/common/words.h61
-rw-r--r--[-rwxr-xr-x]windows/gpsxmple.dsp0
-rw-r--r--[-rwxr-xr-x]windows/gpsxmple.dsw0
18 files changed, 4143 insertions, 371 deletions
diff --git a/dos/gpsxmple.exe b/dos/gpsxmple.exe
index adaeb77..ac3dcc9 100755
--- a/dos/gpsxmple.exe
+++ b/dos/gpsxmple.exe
Binary files differ
diff --git a/dos/gpsxmple.prj b/dos/gpsxmple.prj
index f349f0a..f349f0a 100755..100644
--- a/dos/gpsxmple.prj
+++ b/dos/gpsxmple.prj
Binary files differ
diff --git a/gpsxmple.c b/gpsxmple.c
index e6e4893..f5ab204 100644
--- a/gpsxmple.c
+++ b/gpsxmple.c
@@ -1,14 +1,14 @@
/**************************************************************************
*
- * $Id: gpsxmple.c 1.7 2009/10/02 14:18:08Z martin REL_M $
- * $Name: GPSXMPLE_2_2 $
+ * $Id: gpsxmple.c 1.8 2011/04/15 13:04:14Z martin REL_M $
+ * $Name: GPSXMPLE_2_3 $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * Sample program demonstrating how to access Meinberg GPS receivers
- * via the binary data protocol.
+ * Sample program demonstrating how to access Meinberg devices
+ * using the binary data protocol.
*
* Depending on the target operating system this program works
* either via serial port (the default) or via a network socket
@@ -24,14 +24,17 @@
* QNX 6.x / gcc (socket only)
* DOS / BC3.1 (serial only)
*
- * For makefiles and build environment setups check the associated
- * subdirectories.
+ * For makefiles and build environment setups check the
+ * corresponding subdirectories.
*
- * Please send changes required for other operating systems
+ * Please send changes required for other operating systems
* or build to <support@meinberg.de>
*
* -----------------------------------------------------------------------
* $Log: gpsxmple.c $
+ * Revision 1.8 2011/04/15 13:04:14Z martin
+ * Optionally poll for user capture events.
+ * Under Unix catch signals to terminate properly.
* Revision 1.7 2009/10/02 14:18:08Z martin
* Changes due to renamed library functions.
* Optionally force connection.
@@ -67,10 +70,15 @@
#include <string.h>
#include <ctype.h>
+#if defined( MBG_TGT_UNIX )
+ #include <signal.h>
+#endif
+
#if defined( MBG_TGT_DOS )
#include <conio.h>
+ #define done kbhit()
#else
- #define kbhit() 0
+ static int done;
#endif
@@ -96,6 +104,7 @@ MBG_MSG_CTL mctl =
#define N_STR_TYPE_MAX 20 // max. number of string types
#define N_POUT_MAX 3 // max. number of programmable outputs
+#define IDLE_SLEEP_MS 200
#define _log_msg_0( _lvl, _fmt ) \
@@ -116,6 +125,7 @@ static const char *target;
static int is_socket;
static int must_force_connection;
static int must_send_auto;
+static int must_poll_ucap;
static RECEIVER_INFO receiver_info;
static const char *feature_names[] = DEFAULT_GPS_FEATURE_NAMES;
@@ -146,10 +156,28 @@ static const char *dow_str[] =
static /*HDR*/
+void mbg_sleep_msec( long msec )
+{
+ #if defined( MBG_TGT_UNIX )
+ usleep( msec * 1000 );
+ #elif defined( MBG_TGT_WIN32 )
+ Sleep( msec );
+ #elif defined( MBG_TGT_DOS )
+ delay( msec );
+ #endif
+
+} // mbg_sleep_msec
+
+
+
+static /*HDR*/
int check_rc( int rc )
{
const char *cp = NULL;
+ if ( done )
+ return 0; // we are going to exit
+
switch ( rc )
{
case TR_COMPLETE:
@@ -330,14 +358,16 @@ void check_receiver_info( RECEIVER_INFO *p, int log )
if ( p->model_code == GPS_MODEL_UNKNOWN )
{
- _log_msg_0( LOG_ERR, "Refclock model_code not set: maybe receiver_info has not been received correctly" );
+ _log_msg_0( LOG_ERR, "Refclock model_code not set: maybe receiver_info "
+ "has not been received correctly" );
}
else
if ( log )
{
if ( p->model_code >= N_GPS_MODEL )
{
- _log_msg_2( LOG_WARNING, "Unsupported refclock model_code %u (name: %s)", p->model_code, p->model_name );
+ _log_msg_2( LOG_WARNING, "Unsupported refclock model_code %u (name: %s)",
+ p->model_code, p->model_name );
}
}
@@ -397,6 +427,7 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
printf( " %02X", p->sw_rev.name[i] );
#endif
}
+
printf( ", S/N: %s", p->sernum );
printf( "\n" );
@@ -864,12 +895,51 @@ void show_port_settings( MBG_MSG_CTL *pmctl )
/*HDR*/ static
-void exit_gpsxmple( void )
+int check_ucap_poll( void )
+{
+ int rc;
+
+
+ printf( "Polling for user capture events:\n" );
+
+ do
+ {
+ TTM ttm;
+ memset( &ttm, 0, sizeof( ttm ) );
+ rc = mbgextio_get_ucap( &mctl, &ttm );
+
+ if ( _ttm_time_is_avail( &ttm ) )
+ {
+ printf( "CAP%i: %04u-%02u-%02u %02u:%02u:%02u.%07u",
+ ttm.channel, ttm.tm.year, ttm.tm.month, ttm.tm.mday,
+ ttm.tm.hour,ttm.tm.min, ttm.tm.sec, ttm.tm.frac );
+ printf( ", Status: %04X (hex)", ttm.tm.status );
+ printf( "\n" );
+ }
+ else
+ {
+ // No capture event available. We wait some time
+ // and then retry.
+ mbg_sleep_msec( IDLE_SLEEP_MS );
+ }
+
+ } while ( !done );
+
+ return 0;
+
+} // check_ucap_poll
+
+
+
+/*HDR*/ static
+void exit_close_connection( void )
{
mbgextio_close_connection( &mctl );
- printf( "\n\n" );
-} /* exit_gpsxmple */
+ printf( "Connection closed.\n" );
+ printf( "\n" );
+
+} /* exit_close_connection */
@@ -878,11 +948,47 @@ void exit_auto_off( void )
{
mbgextio_xmt_cmd( &mctl, GPS_AUTO_OFF );
+ #if defined( DEBUG )
+ printf( "AUTO mode turned off.\n" );
+ #endif
+
} /* exit_auto_off */
-// Do a very simple processing of command line parameters:
+/*HDR*/ static
+void set_auto_mode( void )
+{
+ mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
+
+ #if defined( DEBUG )
+ printf( "AUTO mode turned on.\n" );
+ #endif
+
+ atexit( exit_auto_off );
+
+} // set_auto_mode
+
+
+
+#if defined( MBG_TGT_UNIX )
+
+static /*HDR*/
+void sighandler( int sig )
+{
+ #if defined( DEBUG )
+ printf( "Caught signal %i, exiting.\n", sig );
+ #endif
+
+ done = 1;
+
+} // sighandler
+
+#endif
+
+
+
+// Do a very simple processing of command line parameters:
static /*HDR*/
int check_command_line( int argc, char *argv[] )
@@ -898,6 +1004,12 @@ int check_command_line( int argc, char *argv[] )
continue;
}
+ if ( strcmp( argv[i], "-u" ) == 0 )
+ {
+ must_poll_ucap = 1;
+ continue;
+ }
+
if ( strcmp( argv[i], "-?" ) == 0 )
{
must_print_usage = 1;
@@ -989,14 +1101,16 @@ int check_command_line( int argc, char *argv[] )
"\n"
"Options\n"
" -? or -h Print this usage\n"
+ " -a Set auto mode\n"
+ " -u Poll user capture events\n"
#if _USE_SOCKET_IO
" -n Connect to network target, not serial port\n"
" -p passwd Use specified password to connect\n"
#endif
#if _USE_SERIAL_IO
- " -b speed serial port baud rate, default: %lu\n"
- " -f xxx serial port framing, default: %s\n"
- " -F force serial connection to %lu/%s\n"
+ " -b speed Serial port baud rate, default: %lu\n"
+ " -f xxx Serial port framing, default: %s\n"
+ " -F Force serial connection to %lu/%s\n"
#endif
"\n"
"Example:\n"
@@ -1034,10 +1148,9 @@ int check_command_line( int argc, char *argv[] )
int main( int argc, char *argv[] )
{
- int str_mode_0;
int rc;
- printf( "\n\n\nExample Program Accessing Meinberg GPS Receiver\n" );
+ printf( "\n\n\nExample Program Accessing a Meinberg Device via Binary Protocol\n" );
baudrate = default_baudrate;
framing = default_framing;
@@ -1045,6 +1158,10 @@ int main( int argc, char *argv[] )
if ( check_command_line( argc, argv ) < 0 )
return 1;
+ #if defined( MBG_TGT_UNIX )
+ signal( SIGTERM, sighandler );
+ signal( SIGINT, sighandler );
+ #endif
#if _USE_SOCKET_IO
if ( is_socket )
@@ -1097,7 +1214,7 @@ int main( int argc, char *argv[] )
doit:
- atexit( exit_gpsxmple );
+ atexit( exit_close_connection );
// now start communication with whichever device has been opened above:
@@ -1111,14 +1228,13 @@ doit:
show_pos( &mctl );
show_tzdl( &mctl );
show_port_settings( &mctl );
- str_mode_0 = mctl.rcv.pmb->u.msg_data.port_parm.mode[0];
show_synth( &mctl );
// set_synth();
// set_pout_mode();
- if ( str_mode_0 != STR_PER_SEC )
- return 0; // device will not send time automatically
+ if ( must_poll_ucap )
+ return check_ucap_poll();
if ( !must_send_auto )
return 0;
@@ -1132,8 +1248,7 @@ doit:
mbgextio_set_char_rcv_timeout( &mctl, 2000 ); // [msec]
mbgextio_set_msg_rcv_timeout( &mctl, 2000 ); // [msec]
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
- atexit( exit_auto_off );
+ set_auto_mode();
do
{
@@ -1163,6 +1278,7 @@ doit:
{
mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
mbgextio_xmt_cmd( &mctl, GPS_STAT_INFO );
+ mbgextio_xmt_cmd( &mctl, GPS_UCAP );
}
break;
@@ -1172,7 +1288,7 @@ doit:
} /* switch */
- } while ( !kbhit() );
+ } while ( !done );
return 0;
diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h
index 0745a54..03d867c 100644
--- a/mbglib/common/gpsdefs.h
+++ b/mbglib/common/gpsdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsdefs.h 1.80 2009/09/28 14:55:53Z martin REL_M $
+ * $Id: gpsdefs.h 1.91 2011/01/31 11:23:56Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -13,7 +13,52 @@
*
* -----------------------------------------------------------------------
* $Log: gpsdefs.h $
- * Revision 1.80 2009/09/28 14:55:53Z martin
+ * Revision 1.91 2011/01/31 11:23:56Z martin
+ * Added model type name definitions for GPS180PEX and TCR180PEX.
+ * Introduced synthesizer mode for programmable outputs.
+ * Added IRIG-RX code TXC-101 DTR-6.
+ * Fixed missing comma bugs in DEFAULT_GPS_MODEL_NAMES.
+ * Fixed missing comma bugs in some IRIG string initializers.
+ * Fixed AFNOR notation.
+ * Modified some comments for doxygen.
+ * Revision 1.90 2010/10/15 11:47:53 martin
+ * Added definitions POUT_TIMEBASE_UTC and POUT_SUPP_DCF77_UTC.
+ * Added receiver info feature GPS_FEAT_RAW_IRIG_TIME.
+ * Support IRIG format C37.118.
+ * Added initializers for short IRIG code names.
+ * Cleaned up IRIG definitions and comments.
+ * Revision 1.89 2010/09/06 07:40:02Z martin
+ * Picked up Daniel's definitions for multi GNSS support.
+ * Moved MBG_IRIG_CTRL_BITS, MBG_RAW_IRIG_DATA and related definitions
+ * from pcpsdefs.h here.
+ * Added macros _pcps_tfom_from_irig_ctrl_bits()
+ * and _pcps_tfom_from_raw_irig_data().
+ * Added RI_FEATURES type.
+ * Revision 1.88 2010/04/21 13:47:54 daniel
+ * Added support for new model GLN170.
+ * Revision 1.87 2010/03/10 11:29:37Z martin
+ * Added definitions for GPS180.
+ * Added multiref source 1 PPS plus associated string.
+ * Revision 1.86 2010/02/17 14:16:42 martin
+ * Added definitions for PZF600 and TCR600.
+ * Revision 1.85 2010/02/15 11:34:36 martin
+ * Changed definition of PTP_TABLE::name to const char *.
+ * Added definitions to support new model JJY511.
+ * Revision 1.84 2010/02/01 13:20:50 martin
+ * Support programmable outputs being disabled when sync. is lost.
+ * Revision 1.83 2010/01/28 09:15:50 martin
+ * Added new POUT mode DCF77_M59 and associated definitions.
+ * Revision 1.82 2010/01/07 09:04:55 martin
+ * Added XMR status bit XMRS_BIT_NOT_PHASE_LOCKED.
+ * Revision 1.81 2009/11/09 09:08:24 martin
+ * New TM_GPS status bit TM_INVT.
+ * Added definitions to support VLAN.
+ * Changed DEFAULT_PTP_DELAY_MECH_MASK to include also
+ * PTP_DELAY_MECH_MSK_P2P.
+ * There is now only one type of TCXO supported which matches the former
+ * TCXO HQ, so the default name for TCXO HQ has been changed to TCXO.
+ * TCXO LQ and MQ names are still supported for backward compatibility.
+ * Revision 1.80 2009/09/28 14:55:53 martin
* Support IRIG formats G002/G142 and G006/G146.
* Modified IRIG format description strings.
* Revision 1.79 2009/08/12 14:12:38 daniel
@@ -228,7 +273,7 @@
* Added initializer for oscillator names.
* Added initializer for oscillator list ordered by quality.
* Revision 1.13 2002/05/08 08:16:03 MARTIN
- * Added GPS_OSC_CFG_SUPP for RECEIVER_INFO.flags.
+ * Added GPS_OSC_CFG_SUPP for RECEIVER_INFO::flags.
* Fixed some comments.
* Revision 1.12 2002/03/14 13:45:56 MARTIN
* Changed type CSUM from short to ushort.
@@ -334,23 +379,29 @@ typedef uint16_t IOD; /* Issue-Of-Data code */
#endif
-/**
- The type which is used to pass a cmd code via serial port, or bus.
- The cmd codes are defined in gpsserio.h and pcpsdefs.h.
-*/
+/**
+ * @brief The type of a GPS command code
+ *
+ * These command codes can be passed via
+ * @ref gps_cmds_serial "serial port" (see @file gpsserio.h), or
+ * @ref gps_cmds_bus "system bus" (see @file pcpsdefs.h).
+ */
typedef uint16_t GPS_CMD;
#define _mbg_swab_gps_cmd( _p ) _mbg_swab16( _p )
-/**
- A struct used to hold the software revision information
- */
+/**
+ * @brief Software revision information
+ *
+ * Contains a software revision code, plus an optional
+ * identifier for a customized version.
+ */
typedef struct
{
- uint16_t code; /**< e.g. 0x0120 means rev. 1.20 */
- char name[GPS_ID_STR_SIZE]; /**< used to identify customized versions */
- uint8_t reserved; /**< yield even structure size */
+ uint16_t code; /**< Version number, e.g. 0x0120 means v1.20 */
+ char name[GPS_ID_STR_SIZE]; /**< Optional string identifying a customized version */
+ uint8_t reserved; /**< Reserved field to yield even structure size */
} SW_REV;
#define _mbg_swab_sw_rev( _p ) \
@@ -360,14 +411,31 @@ typedef struct
-typedef uint16_t BVAR_STAT; /**< holds status of battery buffered vars */
+/**
+ * @defgroup bvar_stat BVAR_STAT status of buffered GPS data
+ *
+ * Status word, associated bit numbers and bit masks indicating
+ * whether certain data from the GPS satellites are
+ * available and valid.
+ *
+ * These bits defined are set in ::BVAR_STAT if the corresponding
+ * parameters are NOT valid and complete.
+ *
+ * @{ */
+
+/**
+ * @brief Status flags of battery buffered data received
+ * from GPS satellites.
+ *
+ * All '0' means OK, single bits set to '1' indicate
+ * the associated type of GPS data is not available.
+ */
+typedef uint16_t BVAR_STAT;
#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) )
-/**
- The bits defined below are set in BVAR_STAT if the corresponding
- parameters are NOT valid and complete:
-*/
+
+/** @brief Enumeration of bits used with BVAR_STAT */
enum
{
BVAR_BIT_CFGH_INVALID,
@@ -375,22 +443,25 @@ enum
BVAR_BIT_UTC_INVALID,
BVAR_BIT_IONO_INVALID,
BVAR_BIT_RCVR_POS_INVALID,
- N_BVAR_BIT // number of defined bits
+ N_BVAR_BIT /**< @brief number of defined ::BVAR_STAT bits */
};
-#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID )
-#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE )
-#define BVAR_UTC_INVALID ( 1UL << BVAR_BIT_UTC_INVALID )
-#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID )
-#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID )
+#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID ) /**< @brief ::CFGH not valid*/
+#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ) /**< @brief ::ALM not complete */
+#define BVAR_UTC_INVALID ( 1UL << BVAR_BIT_UTC_INVALID ) /**< @brief UTC data not valid */
+#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID ) /**< @brief IONO data not valid */
+#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID ) /**< @brief ::POS not valid */
-/**< bit mask for all defined bits */
-#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 )
+#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) /**< @brief Bit mask for all defined bits */
+/** @} */
-/* a struct used to hold a fixed frequency value */
-/* frequ[kHz] = khz_val * 10^range */
+
+/**
+ A structure used to hold a fixed frequency value.
+ frequ[kHz] = khz_val * 10^range
+*/
typedef struct
{
@@ -405,6 +476,8 @@ typedef struct
}
+typedef uint32_t RI_FEATURES; // type of RECEIVER_INFO::features field
+
/*
* The following code defines features and properties
@@ -426,7 +499,7 @@ typedef struct
char epld_name[GPS_EPLD_STR_SIZE]; /**< ASCIIZ, file name of EPLD image */
uint8_t n_channels; /**< number of sats to be tracked simultaneously */
uint32_t ticks_per_sec; /**< resolution of fractions of seconds */
- uint32_t features; /**< optional features, see below */
+ RI_FEATURES features; /**< optional features, see below */
FIXED_FREQ_INFO fixed_freq; /**< optional non-standard fixed frequency */
uint8_t osc_type; /**< type of installed oscillator, see below */
uint8_t osc_flags; /**< oscillator flags, see below */
@@ -480,6 +553,13 @@ enum
GPS_MODEL_TCR170PEX,
GPS_MODEL_WWVB511,
GPS_MODEL_MGR170,
+ GPS_MODEL_JJY511,
+ GPS_MODEL_PZF600,
+ GPS_MODEL_TCR600,
+ GPS_MODEL_GPS180,
+ GPS_MODEL_GLN170,
+ GPS_MODEL_GPS180PEX,
+ GPS_MODEL_TCR180PEX,
N_GPS_MODEL
/* If new model codes are added then care must be taken
* to update the associated string initializers below
@@ -521,6 +601,13 @@ enum
#define GPS_MODEL_NAME_TCR170PEX "TCR170PEX"
#define GPS_MODEL_NAME_WWVB511 "WWVB511"
#define GPS_MODEL_NAME_MGR170 "MGR170"
+#define GPS_MODEL_NAME_JJY511 "JJY511"
+#define GPS_MODEL_NAME_PZF600 "PZF600"
+#define GPS_MODEL_NAME_TCR600 "TCR600"
+#define GPS_MODEL_NAME_GPS180 "GPS180"
+#define GPS_MODEL_NAME_GLN170 "GLN170"
+#define GPS_MODEL_NAME_GPS180PEX "GPS180PEX"
+#define GPS_MODEL_NAME_TCR180PEX "TCR180PEX"
/*
@@ -557,7 +644,14 @@ enum
GPS_MODEL_NAME_GEN170, \
GPS_MODEL_NAME_TCR170PEX, \
GPS_MODEL_NAME_WWVB511, \
- GPS_MODEL_NAME_MGR170 \
+ GPS_MODEL_NAME_MGR170, \
+ GPS_MODEL_NAME_JJY511, \
+ GPS_MODEL_NAME_PZF600, \
+ GPS_MODEL_NAME_TCR600, \
+ GPS_MODEL_NAME_GPS180, \
+ GPS_MODEL_NAME_GLN170, \
+ GPS_MODEL_NAME_GPS180PEX, \
+ GPS_MODEL_NAME_TCR180PEX \
}
@@ -614,12 +708,16 @@ enum
#define _mbg_rcvr_is_msf( _p_ri ) \
( strstr( (_p_ri)->model_name, "MSF" ) )
+#define _mbg_rcvr_is_jjy( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "JJY" ) )
+
#define _mbg_rcvr_is_msf_plug_in( _p_ri ) \
( _mbg_rcvr_is_msf( _p_ri ) && \
_mbg_rcvr_is_plug_in( _p_ri ) )
#define _mbg_rcvr_is_glonass( _p_ri ) \
- ( strstr( (_p_ri)->model_name, "GRC" ) )
+ ( strstr( (_p_ri)->model_name, "GRC" ) || \
+ ( strstr( (_p_ri)->model_name, "GLN" ) )
#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \
( _mbg_rcvr_is_glonass( _p_ri ) && \
@@ -664,7 +762,7 @@ enum
{ \
"[unknown]", \
"TCXO LQ", \
- "TCXO HQ", \
+ "TCXO", \
"OCXO LQ", \
"OCXO MQ", \
"OCXO HQ", \
@@ -710,25 +808,27 @@ enum
*/
enum
{
- GPS_FEAT_PPS, /**< has pulse per second output */
- GPS_FEAT_PPM, /**< has pulse per minute output */
- GPS_FEAT_SYNTH, /**< has programmable synthesizer output */
- GPS_FEAT_DCFMARKS, /**< has DCF77 compatible time mark output */
- GPS_FEAT_IRIG_TX, /**< has on-board IRIG output */
- GPS_FEAT_IRIG_RX, /**< has on-board IRIG input */
- GPS_FEAT_LAN_IP4, /**< has LAN IPv4 interface */
- GPS_FEAT_MULTI_REF, /**< has multiple input sources with priorities */
- GPS_FEAT_RCV_TIMEOUT, /**< timeout after GPS reception has stopped */
- GPS_FEAT_IGNORE_LOCK, /**< supports "ignore lock", alternatively */
- /**< MBG_OPT_BIT_EMU_SYNC may be supported */
- GPS_FEAT_5_MHZ, /**< output 5 MHz rather than 100 kHz */
- GPS_FEAT_XMULTI_REF, /**< has extended multiple input source configuration */
- GPS_FEAT_OPT_SETTINGS, /**< supports MBG_OPT_SETTINGS */
- GPS_FEAT_TIME_SCALE, /**< supports configurable time scale (UTC, TAI, GPS, ...) */
- GPS_FEAT_IRIG_CTRL_BITS, /**< supports IRIG control bits */
- GPS_FEAT_PTP, /**< has PTP support */
+ GPS_FEAT_PPS, /**< has pulse per second output */
+ GPS_FEAT_PPM, /**< has pulse per minute output */
+ GPS_FEAT_SYNTH, /**< has programmable synthesizer output */
+ GPS_FEAT_DCFMARKS, /**< has DCF77 compatible time mark output */
+ GPS_FEAT_IRIG_TX, /**< has on-board IRIG output */
+ GPS_FEAT_IRIG_RX, /**< has on-board IRIG input */
+ GPS_FEAT_LAN_IP4, /**< has LAN IPv4 interface */
+ GPS_FEAT_MULTI_REF, /**< has multiple input sources with priorities */
+ GPS_FEAT_RCV_TIMEOUT, /**< timeout after GPS reception has stopped */
+ GPS_FEAT_IGNORE_LOCK, /**< supports "ignore lock", alternatively */
+ /**< MBG_OPT_BIT_EMU_SYNC may be supported */
+ GPS_FEAT_5_MHZ, /**< output 5 MHz rather than 100 kHz */
+ GPS_FEAT_XMULTI_REF, /**< has extended multiple input source configuration */
+ GPS_FEAT_OPT_SETTINGS, /**< supports MBG_OPT_SETTINGS */
+ GPS_FEAT_TIME_SCALE, /**< supports configurable time scale (UTC, TAI, GPS, ...) */
+ GPS_FEAT_IRIG_CTRL_BITS, /**< supports IRIG control bits */
+ GPS_FEAT_PTP, /**< has PTP support */
GPS_FEAT_NAV_ENGINE_SETTINGS, /**< supports navigation engine configuration */
- N_GPS_FEATURE /**< the number of valid features */
+ GPS_FEAT_RAW_IRIG_DATA, /**< supports reading raw IRIG input data */
+ GPS_FEAT_RAW_IRIG_TIME, /**< supports reading decoded IRIG time */
+ N_GPS_FEATURE /**< the number of valid features */
};
@@ -746,11 +846,13 @@ enum
"Ignore Lock", \
"5 MHz Output", \
"Ext. Multiple Ref. Src. Cfg.", \
- "Supp. Optional Settings", \
+ "Optional Settings", \
"Configurable Time Scale", \
- "Irig Control Bits", \
+ "IRIG Control Bits", \
"PTP/IEEE1588", \
- "Supp. Nav. Engine Settings" \
+ "Nav. Engine Settings", \
+ "Raw IRIG Data", \
+ "Raw IRIG Time" \
}
@@ -758,25 +860,27 @@ enum
* Bit masks used with RECEIVER_INFO.features
* (others are reserved):
*/
-#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS )
-#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM )
-#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH )
-#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS )
-#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX )
-#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX )
-#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 )
-#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF )
-#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT )
-#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK )
-#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ )
-#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF )
-#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS )
-#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE )
-#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS )
-#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP )
+#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS )
+#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM )
+#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH )
+#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS )
+#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX )
+#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX )
+#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 )
+#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF )
+#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT )
+#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK )
+#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ )
+#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF )
+#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS )
+#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE )
+#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS )
+#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP )
#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS )
+#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA )
+#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME )
-#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX
+#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX
/*
@@ -793,7 +897,7 @@ enum
/*
- * Codes to be used with RECEIVER_INFO.flags:
+ * Codes to be used with RECEIVER_INFO::flags:
*/
#define GPS_OSC_CFG_SUPP 0x0001 // GPS_OSC_CFG supported
#define GPS_IRIG_FO_IN 0x0002 // IRIG input via fiber optics
@@ -872,26 +976,27 @@ typedef struct
}
-/* Local date and time computed from GPS time. The current number */
-/* of leap seconds have to be added to get UTC from GPS time. */
-/* Additional corrections could have been made according to the */
-/* time zone/daylight saving parameters (TZDL, see below) defined */
-/* by the user. The status field can be checked to see which corrections */
-/* have been applied. */
-
+/**
+ Local date and time computed from GPS time. The current number
+ of leap seconds have to be added to get UTC from GPS time.
+ Additional corrections could have been made according to the
+ time zone/daylight saving parameters (TZDL, see below) defined
+ by the user. The status field can be checked to see which corrections
+ have been applied.
+*/
typedef struct
{
- int16_t year; /* 0..9999 */
- int8_t month; /* 1..12 */
- int8_t mday; /* 1..31 */
- int16_t yday; /* 1..366 */
- int8_t wday; /* 0..6 == Sun..Sat */
- int8_t hour; /* 0..23 */
- int8_t min; /* 0..59 */
- int8_t sec; /* 0..59 */
- int32_t frac; /* fractions of a second; scale: 1/GPS_TICKS_PER_SEC*/
- int32_t offs_from_utc; /* local time's offset from UTC */
- uint16_t status; /* flags */
+ int16_t year; /**< year number, 0..9999 */
+ int8_t month; /**< month, 1..12 */
+ int8_t mday; /**< day of month, 1..31 */
+ int16_t yday; /**< day of year, 1..366 */
+ int8_t wday; /**< day of week, 0..6 == Sun..Sat */
+ int8_t hour; /**< hours, 0..23 */
+ int8_t min; /**< minutes, 0..59 */
+ int8_t sec; /**< seconds, 0..59 */
+ int32_t frac; /**< fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
+ int32_t offs_from_utc; /**< local time's offset from UTC */
+ uint16_t status; /**< status flags */
} TM_GPS;
#define _mbg_swab_tm_gps( _p ) \
@@ -915,9 +1020,9 @@ enum
TM_BIT_LS_ANN, /* leap second will be inserted */
TM_BIT_LS_ENB, /* current second is leap second */
TM_BIT_LS_ANN_NEG, /* set in addition to TM_LS_ANN if leap sec negative */
- /* Bit 7 is reserved and not used, yet. */
+ TM_BIT_INVT, /* invalid time, e.g. if RTC battery empty */
- TM_BIT_EXT_SYNC = 8, /* sync'd externally */
+ TM_BIT_EXT_SYNC, /* sync'd externally */
TM_BIT_HOLDOVER, /* holdover mode after previous sync. */
TM_BIT_ANT_SHORT, /* antenna cable short circuited */
TM_BIT_NO_WARM, /* OCXO has not warmed up */
@@ -949,6 +1054,7 @@ enum
#define TM_LS_ANN ( 1UL << TM_BIT_LS_ANN )
#define TM_LS_ENB ( 1UL << TM_BIT_LS_ENB )
#define TM_LS_ANN_NEG ( 1UL << TM_BIT_LS_ANN_NEG )
+#define TM_INVT ( 1UL << TM_BIT_INVT )
#define TM_EXT_SYNC ( 1UL << TM_BIT_EXT_SYNC )
#define TM_HOLDOVER ( 1UL << TM_BIT_HOLDOVER )
@@ -1877,46 +1983,74 @@ enum
/**
- @defgroup group_icode Irig Codes
+ @defgroup group_icode IRIG Codes
The following definitions are used to configure an optional
- on-board IRIG input or output.
+ on-board IRIG input or output. Which frame types are supported
+ by a device depends on the device type, and may eventually
+ depend on the device's firmware version.
- A GPS device can generate an IRIG output signal if the bit
- #GPS_HAS_IRIG_TX is set in the RECEIVER_INFO.features field.
- If a device has an optional IRIG input then the bit
- #GPS_HAS_IRIG_RX is set.
+ All IRIG frames transport the day-of-year number plus the time-of-day,
+ and include a control field segment which can transport user defined
+ information.
+ Some newer IRIG frames are compatible with older frame types but support
+ well defined extensions like the year number, local time offset, DST status,
+ etc., in the control fields:
- Supported IRIG signal code types:
- - \b A002: 1000 bps, DC shift, time-of-year
- - \b A003: 1000 bps, DC shift, time-of-year, SBS
+ - \b A002: 1000 bps, DCLS, time-of-year
+ - \b A003: 1000 bps, DCLS, time-of-year, SBS
- \b A132: 1000 bps, 10 kHz carrier, time-of-year
- \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
- - \b B002: 100 bps, DC shift, time-of-year
- - \b B003: 100 bps, DC shift, time-of-year, SBS
+ - \b B002: 100 bps, DCLS, time-of-year
+ - \b B003: 100 bps, DCLS, time-of-year, SBS
- \b B122: 100 bps, 1 kHz carrier, time-of-year
- \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
+ - \b B006: 100 bps, DCLS, complete date
+ - \b B007: 100 bps, DCLS, complete date, SBS
+ - \b B126: 100 bps, 1 kHz carrier, complete date
+ - \b B127: 100 bps, 1 kHz carrier, complete date, SBS
+ - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions
+ - \b B222: 100 bps, DCLS, manchester encoded, time-of-year
+ - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS
+ - \b G002: 10 kbps, DCLS, time-of-year
+ - \b G142: 10 kbps, 100 kHz carrier, time-of-year
+ - \b G006: 10 kbps, DCLS, complete date
+ - \b G146: 10 kbps, 100 kHz carrier, complete date
- \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
- - <b> AFNOR DC:</b> 100 bps, DC shift, SBS, complete date
+ - <b> AFNOR DC:</b> 100 bps, DCLS, SBS, complete date
- \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE1344 extensions (B120)
- - <b> IEEE1344 DC:</b> 100 bps, DC shift, time-of-year, SBS, IEEE1344 extensions (B000)
- - \b B220/1344: 100 bps, DC shift, manchester encoded, IEEE1344 extensions
- - \b B222: 100 bps, DC shift, manchester encoded, time-of-year
- - \b B223: 100 bps, DC shift, manchester encoded, time-of-year, SBS
-
+ - <b> IEEE1344 DC:</b> 100 bps, DCLS, time-of-year, SBS, IEEE1344 extensions (B000)
+ - \b C37.118: like IEEE1344, but UTC offset with reversed sign
+ - \b C37.118 DC: like IEEE1344 DC, but UTC offset with reversed sign
+
- time-of-year: day-of-year, hours, minutes, seconds
+ - complete date: time-of-year plus year number
- SBS: straight binary seconds, second-of-day
- - IEEE1344 extensions: time zone info
- - AFNOR: french standard AFNOR NFS-87500
-
+
+ AFNOR codes are based on the french standard AFNOR NF S87-500
+
+ IEEE1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible
+ with B002/B122 but provides some welldefined extensions in the control field which
+ include a quality indicator (time figure of merit, TFOM), year number, DST and leap
+ second status, and local time offset from UTC.
+
+ C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version
+ of the IEEE1344 standard from 1995. These codes provide the same extensions as IEEE1344
+ but unfortunately define the UTC offset with reversed sign.
+
+ <b>ATTENTION:</b> There are 3rd party IRIG devices out there which apply the UTC offset
+ as specified in C37.118, but claim to be compatible with IEEE1344. So if local time is
+ transmitted in the IRIG signal then care must be taken that the UTC offset is evaluated
+ by the IRIG receiver in the same way as output by the IRIG generator. Otherwise the UTC
+ time computed by the receiver may be wrong.
@{
*/
/**
- * Definitions used with IRIG transmitters which generate
- * the same IRIG code both with and without carrier signal
- * at the same time. */
+ * Definitions used with IRIG transmitters which usually output both
+ * the unmodulated and the modulated IRIG signals at the same time: */
enum
{
ICODE_TX_B002_B122,
@@ -1925,13 +2059,14 @@ enum
ICODE_TX_A003_A133,
ICODE_TX_AFNOR,
ICODE_TX_IEEE1344,
- ICODE_TX_B220_1344,
- ICODE_TX_B222,
- ICODE_TX_B223,
+ ICODE_TX_B2201344, // DCLS only
+ ICODE_TX_B222, // DCLS only
+ ICODE_TX_B223, // DCLS only
ICODE_TX_B006_B126,
ICODE_TX_B007_B127,
ICODE_TX_G002_G142,
ICODE_TX_G006_G146,
+ ICODE_TX_C37118,
N_ICODE_TX /**< number of code types */
};
@@ -1945,35 +2080,60 @@ enum
"B003+B123", \
"A002+A132", \
"A003+A133", \
- "AFNOR NFS-87500", \
+ "AFNOR NF S87-500", \
"IEEE1344", \
- "B220/1344+IEEE1344", \
- "B222+B122", \
- "B223+B123", \
+ "B220(1344) DCLS", \
+ "B222 DCLS", \
+ "B223 DCLS", \
"B006+B126", \
"B007+B127", \
"G002+G142", \
- "G006+G146" \
+ "G006+G146", \
+ "C37.118" \
}
/**
+ * Initializers for short name strings which must not
+ * be longer than 10 printable characters.
+ */
+#define DEFAULT_ICODE_TX_NAMES_SHORT \
+{ \
+ "B002+B122", \
+ "B003+B123", \
+ "A002+A132", \
+ "A003+A133", \
+ "AFNOR NF-S", \
+ "IEEE1344", \
+ "B220/1344", \
+ "B222 DC", \
+ "B223 DC", \
+ "B006+B126", \
+ "B007+B127", \
+ "G002+G142", \
+ "G006+G146", \
+ "C37.118" \
+}
+
+
+/**
* Initializers for English format description strings.
*/
#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \
{ \
- "100 bps, DC or 1 kHz carrier", \
- "100 bps, DC or 1 kHz carrier, SBS", \
- "1000 bps, DC or 10 kHz carrier", \
- "1000 bps, DC or 10 kHz carrier, SBS", \
- "100 bps, DC or 1 kHz carrier, SBS, complete date", \
- "100 bps, DC or 1 kHz carrier, SBS, complete date, time zone info", \
- "100 bps, DC manchester enc. or 1 kHz carrier, SBS, complete date, time zone info", \
- "100 bps, DC manchester enc. or 1 kHz carrier", \
- "100 bps, DC manchester enc. or 1 kHz carrier, SBS", \
- "100 bps, DC or 1 kHz carrier, complete date", \
- "100 bps, DC or 1 kHz carrier, complete date, SBS", \
- "10 kbps, DC or 100 kHz carrier", \
- "10 kbps, DC or 100 kHz carrier, complete date" \
+ "100 bps, DCLS or 1 kHz carrier", \
+ "100 bps, DCLS or 1 kHz carrier, SBS", \
+ "1000 bps, DCLS or 10 kHz carrier", \
+ "1000 bps, DCLS or 10 kHz carrier, SBS", \
+ "100 bps, DCLS or 1 kHz carrier, SBS, complete date", \
+ "100 bps, DCLS or 1 kHz carrier, SBS, complete date, time zone info", \
+ "100 bps, Manchester enc., DCLS only, SBS, complete date, time zone info", \
+ "100 bps, Manchester enc., DCLS only", \
+ "100 bps, Manchester enc., DCLS only, SBS", \
+ "100 bps, DCLS or 1 kHz carrier, complete date", \
+ "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \
+ "10 kbps, DCLS or 100 kHz carrier", \
+ "10 kbps, DCLS or 100 kHz carrier, complete date", \
+ "like IEEE1344, but UTC offset with reversed sign" \
}
/*
@@ -1987,21 +2147,22 @@ enum
#define MSK_ICODE_TX_A003_A133 ( 1UL << ICODE_TX_A003_A133 )
#define MSK_ICODE_TX_AFNOR ( 1UL << ICODE_TX_AFNOR )
#define MSK_ICODE_TX_IEEE1344 ( 1UL << ICODE_TX_IEEE1344 )
-#define MSK_ICODE_TX_B220_1344 ( 1UL << ICODE_TX_B220_1344 )
+#define MSK_ICODE_TX_B2201344 ( 1UL << ICODE_TX_B2201344 )
#define MSK_ICODE_TX_B222 ( 1UL << ICODE_TX_B222 )
#define MSK_ICODE_TX_B223 ( 1UL << ICODE_TX_B223 )
#define MSK_ICODE_TX_B006_B126 ( 1UL << ICODE_TX_B006_B126 )
#define MSK_ICODE_TX_B007_B127 ( 1UL << ICODE_TX_B007_B127 )
#define MSK_ICODE_TX_G002_G142 ( 1UL << ICODE_TX_G002_G142 )
#define MSK_ICODE_TX_G006_G146 ( 1UL << ICODE_TX_G006_G146 )
+#define MSK_ICODE_TX_C37118 ( 1UL << ICODE_TX_C37118 )
/**
* A mask of IRIG formats with manchester encoded DC output:
*/
#define MSK_ICODE_TX_DC_MANCH \
( \
- MSK_ICODE_TX_B220_1344 | \
- MSK_ICODE_TX_B222 | \
+ MSK_ICODE_TX_B2201344 | \
+ MSK_ICODE_TX_B222 | \
MSK_ICODE_TX_B223 \
)
@@ -2014,11 +2175,12 @@ enum
MSK_ICODE_TX_B003_B123 | \
MSK_ICODE_TX_AFNOR | \
MSK_ICODE_TX_IEEE1344 | \
- MSK_ICODE_TX_B220_1344 | \
+ MSK_ICODE_TX_B2201344 | \
MSK_ICODE_TX_B222 | \
MSK_ICODE_TX_B223 | \
MSK_ICODE_TX_B006_B126 | \
- MSK_ICODE_TX_B007_B127 \
+ MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_C37118 \
)
/**
@@ -2049,7 +2211,8 @@ enum
MSK_ICODE_TX_AFNOR | \
MSK_ICODE_TX_IEEE1344 | \
MSK_ICODE_TX_B006_B126 | \
- MSK_ICODE_TX_B007_B127 \
+ MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_C37118 \
)
/**
@@ -2075,7 +2238,8 @@ enum
*/
#define MSK_ICODE_TX_HAS_TFOM \
( \
- MSK_ICODE_TX_IEEE1344 \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_C37118 \
)
/**
@@ -2083,7 +2247,8 @@ enum
*/
#define MSK_ICODE_TX_HAS_TZI \
( \
- MSK_ICODE_TX_IEEE1344 \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_C37118 \
)
/**
@@ -2105,23 +2270,27 @@ enum
/**
* Definitions used with IRIG receivers which decode
- * two similar IRIG codes
+ * two similar IRIG codes (with or without SBS)
* at the same time.
*/
enum
{
- ICODE_RX_B122_B123,
- ICODE_RX_A132_A133,
- ICODE_RX_B002_B003,
- ICODE_RX_A002_A003,
- ICODE_RX_AFNOR,
- ICODE_RX_AFNOR_DC,
- ICODE_RX_IEEE1344,
- ICODE_RX_IEEE1344_DC,
- ICODE_RX_B126_B127,
- ICODE_RX_B006_B007,
- ICODE_RX_G142_G146,
- ICODE_RX_G002_G006,
+ ICODE_RX_B122_B123, // modulated
+ ICODE_RX_A132_A133, // modulated
+ ICODE_RX_B002_B003, // DCLS
+ ICODE_RX_A002_A003, // DCLS
+ ICODE_RX_AFNOR, // modulated
+ ICODE_RX_AFNOR_DC, // DCLS
+ ICODE_RX_IEEE1344, // modulated
+ ICODE_RX_IEEE1344_DC, // DCLS
+ ICODE_RX_B126_B127, // modulated
+ ICODE_RX_B006_B007, // DCLS
+ ICODE_RX_G142_G146, // modulated
+ ICODE_RX_G002_G006, // DCLS
+ ICODE_RX_C37118, // modulated
+ ICODE_RX_C37118_DC, // DCLS
+ ICODE_RX_TXC_101, // modulated
+ ICODE_RX_TXC_101_DC, // DCLS
N_ICODE_RX /* the number of valid signal code types */
};
@@ -2132,35 +2301,68 @@ enum
{ \
"B122/B123", \
"A132/A133", \
- "B002/B003 (DC)", \
- "A002/A003 (DC)", \
- "AFNOR NFS-87500", \
- "AFNOR NFS-87500 (DC)", \
+ "B002/B003 (DCLS)", \
+ "A002/A003 (DCLS)", \
+ "AFNOR NF S87-500", \
+ "AFNOR NF S87-500 (DCLS)", \
"IEEE1344", \
- "IEEE1344 (DC)", \
+ "IEEE1344 (DCLS)", \
"B126/B127", \
- "B006/B007 (DC)", \
+ "B006/B007 (DCLS)", \
"G142/G146", \
- "G002/G006 (DC)" \
+ "G002/G006 (DCLS)", \
+ "C37.118", \
+ "C37.118 (DCLS)", \
+ "TXC-101 DTR-6", \
+ "TXC-101 DTR-6 (DCLS)" \
}
/**
+ * Initializers for short name strings which must not
+ * be longer than 11 printable characters.
+ */
+#define DEFAULT_ICODE_RX_NAMES_SHORT \
+{ \
+ "B122/B123", \
+ "A132/A133", \
+ "B002/B003", \
+ "A002/A003", \
+ "AFNOR NF-S", \
+ "AFNOR DC", \
+ "IEEE1344", \
+ "IEEE1344 DC", \
+ "B126/B127", \
+ "B006/B007", \
+ "G142/G146", \
+ "G002/G006", \
+ "C37.118", \
+ "C37.118 DC", \
+ "TXC-101", \
+ "TXC-101 DC" \
+}
+
+
+/**
* Initializers for English format description strings.
*/
#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
{ \
"100 bps, 1 kHz carrier, SBS optionally", \
"1000 bps, 10 kHz carrier, SBS optionally", \
- "100 bps, DC shift, SBS optionally", \
- "1000 bps, DC shift, SBS optionally", \
+ "100 bps, DCLS, SBS optionally", \
+ "1000 bps, DCLS, SBS optionally", \
"100 bps, 1 kHz carrier, SBS, complete date", \
- "100 bps, DC shift, SBS, complete date", \
+ "100 bps, DCLS, SBS, complete date", \
"100 bps, 1 kHz carrier, SBS, time zone info", \
- "100 bps, DC shift, SBS, time zone info", \
+ "100 bps, DCLS, SBS, time zone info", \
"100 bps, 1 kHz carrier, complete date, SBS optionally", \
- "100 bps, DC shift, complete date, SBS optionally", \
+ "100 bps, DCLS, complete date, SBS optionally", \
"10 kbps, 100 kHz carrier, complete date optionally", \
- "10 kbps, DC shift, complete date optionally" \
+ "10 kbps, DCLS, complete date optionally", \
+ "like IEEE1344, but UTC offset with reversed sign", \
+ "like IEEE1344 DC, but UTC offset with reversed sign", \
+ "code from TV time sync device TXC-101 DTR-6", \
+ "DC code from TV time sync device TXC-101 DTR-6" \
}
/*
@@ -2178,18 +2380,23 @@ enum
#define MSK_ICODE_RX_B006_B007 ( 1UL << ICODE_RX_B006_B007 )
#define MSK_ICODE_RX_G142_G146 ( 1UL << ICODE_RX_G142_G146 )
#define MSK_ICODE_RX_G002_G006 ( 1UL << ICODE_RX_G002_G006 )
+#define MSK_ICODE_RX_C37118 ( 1UL << ICODE_RX_C37118 )
+#define MSK_ICODE_RX_C37118_DC ( 1UL << ICODE_RX_C37118_DC )
+#define MSK_ICODE_RX_TXC_101 ( 1UL << ICODE_RX_TXC_101 )
+#define MSK_ICODE_RX_TXC_101_DC ( 1UL << ICODE_RX_TXC_101_DC )
/**
- * A mask of IRIG formats which have DC shift:
+ * A mask of IRIG DCLS formats:
*/
-#define MSK_ICODE_RX_DC \
-( \
- MSK_ICODE_RX_B002_B003 | \
- MSK_ICODE_RX_A002_A003 | \
- MSK_ICODE_RX_AFNOR_DC | \
- MSK_ICODE_RX_IEEE1344_DC | \
- MSK_ICODE_RX_B006_B007 | \
- MSK_ICODE_RX_G002_G006 \
+#define MSK_ICODE_RX_DC \
+( \
+ MSK_ICODE_RX_B002_B003 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B006_B007 | \
+ MSK_ICODE_RX_G002_G006 | \
+ MSK_ICODE_RX_C37118_DC \
)
/**
@@ -2200,7 +2407,8 @@ enum
MSK_ICODE_RX_B122_B123 | \
MSK_ICODE_RX_AFNOR | \
MSK_ICODE_RX_IEEE1344 | \
- MSK_ICODE_RX_B126_B127 \
+ MSK_ICODE_RX_B126_B127 | \
+ MSK_ICODE_RX_C37118 \
)
/**
@@ -2224,14 +2432,16 @@ enum
*/
#define MSK_ICODE_RX_100BPS \
( \
- MSK_ICODE_RX_B122_B123 | \
- MSK_ICODE_RX_B002_B003 | \
- MSK_ICODE_RX_AFNOR | \
- MSK_ICODE_RX_AFNOR_DC | \
- MSK_ICODE_RX_IEEE1344 | \
- MSK_ICODE_RX_IEEE1344_DC | \
- MSK_ICODE_RX_B126_B127 | \
- MSK_ICODE_RX_B006_B007 \
+ MSK_ICODE_RX_B122_B123 | \
+ MSK_ICODE_RX_B002_B003 | \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B126_B127 | \
+ MSK_ICODE_RX_B006_B007 | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
)
/**
@@ -2256,17 +2466,21 @@ enum
*/
#define MSK_ICODE_RX_HAS_TFOM \
( \
- MSK_ICODE_RX_IEEE1344 | \
- MSK_ICODE_RX_IEEE1344_DC \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
)
/**
* A mask of IRIG formats which support time zone information:
*/
-#define MSK_ICODE_RX_HAS_TZI \
-( \
- MSK_ICODE_RX_IEEE1344 | \
- MSK_ICODE_RX_IEEE1344_DC \
+#define MSK_ICODE_RX_HAS_TZI \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
)
/**
@@ -2286,6 +2500,8 @@ enum
#endif
/** @} */
+
+
/**
* The structure below is used to configure an optional
* on-board IRIG output:
@@ -2304,7 +2520,7 @@ typedef struct
/**
- @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS.flags
+ @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS::flags
(others are reserved)
* @{
@@ -2314,11 +2530,19 @@ typedef struct
#define IFLAGS_MASK 0x0003 /**< flags above or'ed */
+// Note: the presence or absence of the IFLAGS_DISABLE_TFOM flag for the IRIG RX
+// settings of some PCI cards may not be evaluated correctly by some firmware
+// versions for those cards, even if an IRIG code has been configured which supports
+// this flag. See the comments near the declaration of the _pcps_incoming_tfom_ignored()
+// macro in pcpsdev.h for details.
+
/** @} */
/**
- * The structure is used to query the IRIG configuration
- * plus the supported codes:
+ * @brief Current IRIG settings and supported codes
+ *
+ * Used to query the IRIG current IRIG settings
+ * plus a mask of supported codes.
*/
typedef struct
{
@@ -2449,6 +2673,50 @@ enum
#define MBG_OPT_FLAG_EMU_SYNC ( 1UL << MBG_OPT_BIT_EMU_SYNC )
+
+// bit coded return type for PCPS_GET_IRIG_CTRL_BITS
+typedef uint32_t MBG_IRIG_CTRL_BITS;
+
+#define _mbg_swab_irig_ctrl_bits( _p ) _mbg_swab32( _p )
+
+
+// The following macro extracts the 4 bit TFOM code from the
+// IRIG control bits read from a card. This only works if the received
+// IRIG code is a code which supports TFOM, this is currently
+// only IEEE1344.
+#define _pcps_tfom_from_irig_ctrl_bits( _p ) \
+ ( ( ( *(_p) ) >> 24 ) & 0x0F )
+
+
+
+#define RAW_IRIG_SIZE 16
+
+/**
+ The buffer below can be used to get the raw data bits
+ from the IRIG decoder. A maximum number of RAW_IRIG_SIZE
+ bytes can be filled. If less bytes are used then the rest
+ of the bytes are filled with zeros.
+
+ The first IRIG bit received from the transmitter is saved
+ in the MSB (bit 7) of data_bytes[0], etc.
+*/
+typedef struct
+{
+ uint8_t data_bytes[RAW_IRIG_SIZE];
+} MBG_RAW_IRIG_DATA;
+
+// The following macro extracts the 4 bit TFOM code from the raw
+// data bits read from a card. This only works if the received
+// IRIG code is a code which supports TFOM, this is currently
+// only IEEE1344.
+#define _pcps_tfom_from_raw_irig_data( _p ) \
+ ( ( ( (_p)->data_bytes[9] >> 2 ) & 0x08 ) \
+ | ( ( (_p)->data_bytes[9] >> 4 ) & 0x04 ) \
+ | ( ( (_p)->data_bytes[9] >> 6 ) & 0x02 ) \
+ | ( ( (_p)->data_bytes[8] & 0x01 ) ) )
+
+
+
/**
@defgroup group_scale Time Scale Configuration
@@ -2649,6 +2917,8 @@ enum
POUT_TIMECODE, /**< IRIG/AFNOR DCLS output */
POUT_TIMESTR, /**< COM port number in pulse_len field */
POUT_10MHZ, /**< 10 MHz fixed frequency */
+ POUT_DCF77_M59, /**< DCF77-like signal with 500 ms pulse in 59th second */
+ POUT_SYNTH, /**< programmable synthesizer frequency */
N_POUT_MODES
};
@@ -2671,6 +2941,8 @@ enum
#define ENG_POUT_NAME_TIMECODE "DCLS Time Code"
#define ENG_POUT_NAME_TIMESTR "COM Time String"
#define ENG_POUT_NAME_10MHZ "10 MHz Frequency"
+#define ENG_POUT_NAME_DCF77_M59 "DCF77-like M59"
+#define ENG_POUT_NAME_SYNTH "Synthesizer Frequency"
#define DEFAULT_ENG_POUT_NAMES \
{ \
@@ -2687,7 +2959,9 @@ enum
ENG_POUT_NAME_ALL_SYNC, \
ENG_POUT_NAME_TIMECODE, \
ENG_POUT_NAME_TIMESTR, \
- ENG_POUT_NAME_10MHZ \
+ ENG_POUT_NAME_10MHZ, \
+ ENG_POUT_NAME_DCF77_M59, \
+ ENG_POUT_NAME_SYNTH \
}
@@ -2705,6 +2979,8 @@ enum
#define ENG_POUT_HINT_TIMECODE "Duplicate IRIG time code signal"
#define ENG_POUT_HINT_TIMESTR "Duplicate serial time string of specified port"
#define ENG_POUT_HINT_10MHZ "10 MHz fixed output frequency"
+#define ENG_POUT_HINT_DCF77_M59 "DCF77 time marks with 500 ms pulse in 59th second"
+#define ENG_POUT_HINT_SYNTH "Frequency generated by programmable synthesizer"
#define DEFAULT_ENG_POUT_HINTS \
{ \
@@ -2721,7 +2997,9 @@ enum
ENG_POUT_HINT_ALL_SYNC, \
ENG_POUT_HINT_TIMECODE, \
ENG_POUT_HINT_TIMESTR, \
- ENG_POUT_HINT_10MHZ \
+ ENG_POUT_HINT_10MHZ, \
+ ENG_POUT_HINT_DCF77_M59, \
+ ENG_POUT_HINT_SYNTH \
}
@@ -2744,12 +3022,16 @@ enum
#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE )
#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR )
#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ )
+#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 )
+#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH )
/*
- * The codes below are used with POUT_SETTINGS.flags:
+ * The codes below are used with POUT_SETTINGS::flags:
*/
-#define POUT_INVERTED 0x0001
+#define POUT_INVERTED 0x0001 // invert output level
+#define POUT_IF_SYNC_ONLY 0x0002 // disable in holdover mode
+#define POUT_TIMEBASE_UTC 0x0004 // use UTC, only applicable for DCF77 output
/**
@@ -2786,7 +3068,7 @@ typedef struct
uint8_t timestr_ports; /**< bit mask of COM ports supported for POUT_TIMESTR */
uint8_t reserved_0; /**< reserved for future use, currently 0 */
uint16_t reserved_1; /**< reserved for future use, currently 0 */
- uint32_t flags; /**< reserved for future use, currently 0 */
+ uint32_t flags; /**< see below */
} POUT_INFO;
#define _mbg_swab_pout_info( _p ) \
@@ -2801,6 +3083,14 @@ typedef struct
/** The max number of COM ports that can be handled by POUT_INFO::timestr_ports */
#define MAX_POUT_TIMESTR_PORTS 8
+
+/*
+ * The codes below are used with POUT_INFO::flags:
+ */
+#define POUT_SUPP_IF_SYNC_ONLY 0x0001 // supports disabling outputs in holdover mode
+#define POUT_SUPP_DCF77_UTC 0x0002 // supports UTC output in DCF77 mode
+
+
/**
The structure below adds an index number to the structure
above to allow addressing of several instances:
@@ -2840,7 +3130,8 @@ enum
MULTI_REF_PTP, // Precision Time Protocol (PTP, IEEE1588)
MULTI_REF_PTP_E1, // PTP over E1
MULTI_REF_FREQ, // fixed frequency
- N_MULTI_REF // the number of defined sources
+ MULTI_REF_PPS_STRING, // 1 PPS in addition to string
+ N_MULTI_REF // the number of defined sources
};
@@ -2857,7 +3148,8 @@ enum
"NTP", \
"PTP (IEEE1588)", \
"PTP over E1", \
- "Fixed Freq. in" \
+ "Fixed Freq. in", \
+ "PPS plus string" \
}
@@ -2873,6 +3165,7 @@ enum
#define HAS_MULTI_REF_PTP ( 1UL << MULTI_REF_PTP )
#define HAS_MULTI_REF_PTP_E1 ( 1UL << MULTI_REF_PTP_E1 )
#define HAS_MULTI_REF_FREQ ( 1UL << MULTI_REF_FREQ )
+#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING )
/*
@@ -2893,12 +3186,12 @@ enum
/**
- The structure below is used to configure the priority of
+ The structure below is used to configure the priority of
the supported ref sources.
-
- The number stored in prio[0] of the array indicates the ref time
- source with highest priority. If that source fails, the device
- falls back to the source indicated by prio[1]. Each field of
+
+ The number stored in prio[0] of the array indicates the ref time
+ source with highest priority. If that source fails, the device
+ falls back to the source indicated by prio[1]. Each field of
the prio[] array must be set to one of the values 0..N_MULTI_REF-1,
or to -1 (0xFF) if the value is not assigned.
*/
@@ -3062,26 +3355,28 @@ typedef struct
*/
enum
{
- XMRS_BIT_NOT_SUPP, /* ref type cfg'd for this level is not supported */
- XMRS_BIT_NO_CONN, /* input signal is disconnected */
- XMRS_BIT_NO_SIGNAL, /* no input signal */
- XMRS_BIT_IS_MASTER, /* reference is master source */
- XMRS_BIT_IS_LOCKED, /* locked to input signal */
- XMRS_BIT_IS_ACCURATE, /* oscillator control has reached full accuracy */
- XMRS_BIT_NOT_SETTLED, /* reference time signal not settled */
+ XMRS_BIT_NOT_SUPP, /* ref type cfg'd for this level is not supported */
+ XMRS_BIT_NO_CONN, /* input signal is disconnected */
+ XMRS_BIT_NO_SIGNAL, /* no input signal */
+ XMRS_BIT_IS_MASTER, /* reference is master source */
+ XMRS_BIT_IS_LOCKED, /* locked to input signal */
+ XMRS_BIT_IS_ACCURATE, /* oscillator control has reached full accuracy */
+ XMRS_BIT_NOT_SETTLED, /* reference time signal not settled */
+ XMRS_BIT_NOT_PHASE_LOCKED, /* oscillator not phase locked to PPS */
N_XMRS_BITS
};
/* bit masks corresponding to the flag bits above */
-#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP )
-#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN )
-#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL )
-#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER )
-#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED )
-#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE )
-#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED )
+#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP )
+#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN )
+#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL )
+#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER )
+#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED )
+#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE )
+#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED )
+#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED )
@@ -3250,6 +3545,106 @@ typedef struct
#define OSC_DAC_BIAS ( OSC_DAC_RANGE / 2 )
+
+/*
+ The enumeration below lists all
+ known satellite navigation systems
+*/
+enum
+{
+ GNSS_TYPE_GPS,
+ GNSS_TYPE_GLONASS,
+ GNSS_TYPE_BEIDOU,
+ GNSS_TYPE_GALILEO,
+ N_GNSS_TYPES
+};
+
+
+
+#define GNSS_TYPE_STRS \
+{ \
+ "GPS", \
+ "GLONASS", \
+ "BEIDOU" , \
+ "GALILEO" \
+}
+
+
+
+#define MBG_GNSS_TYPE_MSK_GPS ( 1UL << GNSS_TYPE_GPS )
+#define MBG_GNSS_TYPE_MSK_GLONASS ( 1UL << GNSS_TYPE_GLONASS )
+#define MBG_GNSS_TYPE_MSK_BEIDOU ( 1UL << GNSS_TYPE_BEIDOU )
+#define MBG_GNSS_TYPE_MSK_GALILEO ( 1UL << GNSS_TYPE_GALILEO )
+
+
+#define N_GNSS_MODE_PRIO 8
+
+typedef struct
+{
+ uint32_t gnss_set; /**< current set of GNSS types */
+ uint8_t prio[N_GNSS_MODE_PRIO]; /**< index 0 for highest priority, use GNSS enumeration above, init with 0xFF if not supported */
+ uint32_t flags; /**< see below */
+} MBG_GNSS_MODE_SETTINGS;
+
+#define _mbg_swab_mbg_gnss_mode_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->gnss_set ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+typedef struct
+{
+ MBG_GNSS_MODE_SETTINGS settings; /**< current GNSS mode settings */
+ uint32_t supp_gnss_types; /**< bit masks of supported GNSS types */
+ uint32_t flags; /**< indicates which of the defined flags are supported by the device */
+} MBG_GNSS_MODE_INFO;
+
+#define _mbg_swab_mbg_gnss_mode_info( _p ) \
+{ \
+ _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_gnss_types ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/* Flags used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags: */
+
+enum
+{
+ MBG_GNSS_FLAG_EXCLUSIVE, /**< (read only) only one of the supported GNSS systems can be used at the same time */
+ MBG_GNSS_FLAG_HAS_PRIORITY, /**< (read only) priority can be configured using the MBG_GNSS_MODE_SETTINGS::prio field */
+ N_MBG_GNSS_FLAGS
+};
+
+#define MBG_GNSS_FLAG_MSK_EXCLUSIVE ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE )
+#define MBG_GNSS_FLAG_MSK_HAS_PRIORITY ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY )
+
+
+
+#define MAX_USED_SATS 32
+
+/*
+ The structure below allos to transfer
+ SV information from a certain GNSS type.
+*/
+typedef struct
+{
+ uint8_t gnss_type; /**< GNSS type from the enumeration above */
+ uint8_t reserved;
+ uint16_t good_svs;
+ uint16_t svs_in_view;
+ uint8_t svs[MAX_USED_SATS];
+} GNSS_SAT_INFO;
+
+#define _mbg_swab_gnss_sat_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->good_svs ); \
+ _mbg_swab16( &(_p)->svs_in_view ); \
+}
+
+
#ifndef _IDENT_DEFINED
typedef union
@@ -3300,7 +3695,8 @@ typedef struct
IP4_ADDR netmask;
IP4_ADDR broad_addr;
IP4_ADDR gateway;
- uint32_t flags; /* see below */
+ uint16_t flags; /* see below */
+ uint16_t vlan_cfg; /* see below */
} IP4_SETTINGS;
@@ -3310,10 +3706,40 @@ typedef struct
_mbg_swab_ip4_addr( &(_p)->netmask ); \
_mbg_swab_ip4_addr( &(_p)->broad_addr ); \
_mbg_swab_ip4_addr( &(_p)->gateway ); \
- _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->vlan_cfg ); \
}
+// IP4_SETTINGS::vlan_cfg contains a combination of
+// a VLAN ID number plus a VLAN priiority code.
+// Definitions used with IP4_SETTINGS::vlan_cfg:
+
+#define VLAN_ID_BITS 12 // number of bits to hold the ID
+#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) // number of ID values
+#define MIN_VLAN_ID 0 // minimum ID value
+#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) // maximum ID value
+
+// vlan_id = ( vlan_cfg >> VLAN_ID_SHIFT ) & VLAN_ID_MSK
+#define VLAN_ID_SHIFT 0
+#define VLAN_ID_MSK ( ( 1 << VLAN_ID_BITS ) - 1 )
+
+
+#define VLAN_PRIORITY_BITS 3 // number of bits to hold priority
+#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) // number of priority values
+#define MIN_VLAN_PRIORITY 0 // minimum priority
+#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) // maximum priority
+
+// vlan_priority = ( vlan_cfg >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK
+#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( uint16_t ) ) - VLAN_PRIORITY_BITS )
+#define VLAN_PRIORITY_MSK ( ( 1 << VLAN_PRIORITY_BITS ) - 1 )
+
+// The macros below can be used to encode/decode packed vlan_cfg variables:
+#define _decode_vlan_id( _cfg ) ( ( (_cfg) >> VLAN_ID_SHIFT ) & VLAN_ID_MSK )
+#define _decode_vlan_priority( _cfg ) ( ( (_cfg) >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK )
+#define _encode_vlan_cfg( _id, _prty ) ( ( (_id) << VLAN_ID_SHIFT ) | ( (_prty) << VLAN_PRIORITY_SHIFT ) )
+
+
#if 0 //##++ currently not used
/* Misc configuration */
@@ -3351,16 +3777,18 @@ typedef struct
uint16_t ver_code; /* high byte.low byte, in hex */
char ver_str[GPS_ID_STR_SIZE];
char sernum[GPS_ID_STR_SIZE];
- uint32_t rsvd; /* reserved, currently always 0 */
- uint32_t flags; /* reserved, currently always 0 */
+ uint32_t rsvd_0; /* reserved, currently always 0 */
+ uint16_t flags; /* see below */
+ uint16_t rsvd_1; /* reserved, currently always 0 */
} LAN_IF_INFO;
#define _mbg_swab_lan_if_info( _p ) \
{ \
_mbg_swab16( &(_p)->type ); \
_mbg_swab16( &(_p)->ver_code ); \
- _mbg_swab32( &(_p)->rsvd ); \
- _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->rsvd_0 ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->rsvd_1 ); \
}
@@ -3379,13 +3807,15 @@ enum
enum
{
- IP4_BIT_DHCP,
- IP4_BIT_LINK, // used only to report state
+ IP4_BIT_DHCP, // DHCP supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
+ IP4_BIT_LINK, // used only in IP4_SETTINGS to report link state
+ IP4_BIT_VLAN, // VLAN supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
N_IP4_BIT
};
#define IP4_MSK_DHCP ( 1UL << IP4_BIT_DHCP )
#define IP4_MSK_LINK ( 1UL << IP4_BIT_LINK )
+#define IP4_MSK_VLAN ( 1UL << IP4_BIT_VLAN )
enum
@@ -3458,7 +3888,7 @@ enum
typedef struct
{
uint8_t value;
- char *name;
+ const char *name;
} PTP_TABLE;
@@ -3473,7 +3903,7 @@ enum
#define PTP_DELAY_MECH_MSK_P2P ( 1UL << PTP_DELAY_MECH_BIT_P2P )
#if !defined( DEFAULT_PTP_DELAY_MECH_MASK )
- #define DEFAULT_PTP_DELAY_MECH_MASK ( PTP_DELAY_MECH_MSK_E2E )
+ #define DEFAULT_PTP_DELAY_MECH_MASK ( PTP_DELAY_MECH_MSK_E2E | PTP_DELAY_MECH_MSK_P2P )
#endif
#define PTP_DELAY_MECH_NAMES \
@@ -3678,7 +4108,7 @@ typedef struct
uint32_t lower_bound; // [ns] sync state set to true if below this limit
uint32_t reserved_3; // currently always 0
- uint32_t flags; // (see below)
+ uint32_t flags; // (see below)
} PTP_CFG_SETTINGS;
@@ -3840,20 +4270,20 @@ typedef struct
/**
- UTC correction parameters
+ @brief GPS UTC correction parameters
*/
typedef struct
{
- CSUM csum; /**< Checksum of the remaining bytes */
- int16_t valid; /**< Flag indicating UTC parameters are valid */
+ CSUM csum; /**< Checksum of the remaining bytes */
+ int16_t valid; /**< Flag indicating UTC parameters are valid */
- T_GPS t0t; /**< Reference Time UTC Parameters [sec] */
- double A0; /**< +- Clock Correction Coefficient 0 [sec] */
- double A1; /**< +- Clock Correction Coefficient 1 [sec/sec] */
+ T_GPS t0t; /**< Reference Time UTC Parameters [wn|sec] */
+ double A0; /**< +- Clock Correction Coefficient 0 [sec] */
+ double A1; /**< +- Clock Correction Coefficient 1 [sec/sec] */
- uint16_t WNlsf; /**< Week number of nearest leap second */
- int16_t DNt; /**< The day number at the end of which leap second is inserted */
- int8_t delta_tls; /**< Current UTC offset to GPS system time [sec] */
+ uint16_t WNlsf; /**< Week number of nearest leap second */
+ int16_t DNt; /**< The day number at the end of which a leap second occurs */
+ int8_t delta_tls; /**< Current UTC offset to GPS system time [sec] */
int8_t delta_tlsf; /**< Future UTC offset to GPS system time after next leap second transition [sec] */
} UTC;
diff --git a/mbglib/common/gpsserio.h b/mbglib/common/gpsserio.h
index b6473b9..de5fa04 100644
--- a/mbglib/common/gpsserio.h
+++ b/mbglib/common/gpsserio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsserio.h 1.32 2009/08/26 09:02:21Z daniel REL_M $
+ * $Id: gpsserio.h 1.34 2011/04/15 13:12:02Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -31,7 +31,13 @@
*
* -----------------------------------------------------------------------
* $Log: gpsserio.h $
- * Revision 1.32 2009/08/26 09:02:21Z daniel
+ * Revision 1.34 2011/04/15 13:12:02Z martin
+ * Added initializer for command name table.
+ * Unified mutex stuff using macros from mbgmutex.h.
+ * Revision 1.33 2010/09/07 07:18:08 daniel
+ * New codes and structures for multi GNSS support.
+ * Defines to support reading raw IRIG data.
+ * Revision 1.32 2009/08/26 09:02:21 daniel
* Added new commands GPS_NAV_ENG_SETTINGS and
* GPS_GLNS_ALM.
* Revision 1.31 2009/08/24 13:32:33Z martin
@@ -163,9 +169,9 @@
#include <use_pack.h>
-/*
- * The following macros control parts of the build process.
- * The default values are suitable for most cases but can be
+/*
+ * The following macros control parts of the build process.
+ * The default values are suitable for most cases but can be
* overridden by global definitions, if required.
*/
@@ -173,67 +179,20 @@
// This handle type in not used by the firmware.
// However, we define it to avoid build errors.
typedef int MBG_HANDLE;
-#else
- #if defined( MBG_TGT_WIN32 )
-
- #ifndef _USE_MUTEX
- #define _USE_MUTEX 1
- #endif
-
- #if _USE_MUTEX
-
- #include <windows.h>
- typedef HANDLE MBG_MUTEX_HANDLE;
-
- #define _mbg_mutex_init( _m ) \
- _m = CreateMutex( NULL, FALSE, NULL )
-
- #define _mbg_mutex_lock( _m ) \
- WaitForSingleObject( _m, INFINITE )
+#endif
- #define _mbg_mutex_unlock( _m ) \
- ReleaseMutex( _m )
-
- #define _mbg_mutex_destroy( _m ) \
- CloseHandle( _m )
- #endif
+#ifndef _USE_MUTEX
+ #if defined( MBG_TGT_WIN32 )
+ #define _USE_MUTEX 1
#elif defined( MBG_TGT_UNIX )
-
- #ifndef _USE_MUTEX
- #define _USE_MUTEX 1
- #endif
-
- #if _USE_MUTEX
-
- #include <pthread.h>
-
- typedef pthread_mutex_t MBG_MUTEX_HANDLE;
-
- // Mutex types:
- // PTHREAD_MUTEX_INITIALIZER /* Fast */
- // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP /* Recursive */
- // PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* Errorcheck */
- #define _mbg_mutex_init( _m ) \
- pthread_mutex_init( &(_m), NULL )
-
- #define _mbg_mutex_lock( _m ) \
- pthread_mutex_lock( &(_m) )
-
- #define _mbg_mutex_unlock( _m ) \
- pthread_mutex_unlock( &(_m) )
-
- #define _mbg_mutex_destroy( _m ) \
- pthread_mutex_destroy( &(_m) )
- #endif
-
- #endif
-
- #ifndef _USE_MUTEX
- #define _USE_MUTEX 0
+ #define _USE_MUTEX 1
#endif
+#endif
+#ifndef _USE_MUTEX
+ #define _USE_MUTEX 0 // not used by default
#endif
@@ -266,18 +225,15 @@
#endif
#endif
-#if _USE_SERIAL_IO
- #include <mbgserio.h>
-#endif
-
/* Control inclusion of pcpsdefs.h */
#ifndef _USE_PCPSDEFS
#if _IS_MBG_FIRMWARE
// for firmware depend on the target system
- #define _USE_PCPSDEFS \
- ( \
- defined( _CC51 ) \
- )
+ #if defined( _CC51 )
+ #define _USE_PCPSDEFS 1
+ #else
+ #define _USE_PCPSDEFS 0
+ #endif
#else
// otherwise include it by default
#define _USE_PCPSDEFS 1
@@ -293,9 +249,21 @@
/* Control inclusion of function prototypes */
#ifndef _USE_GPSSERIO_FNC
/* by default don't include if building a firmware */
- #define _USE_GPSSERIO_FNC ( ! _IS_MBG_FIRMWARE )
+ #define _USE_GPSSERIO_FNC ( !_IS_MBG_FIRMWARE )
#endif
+#ifndef _USE_RCV_TSTAMP
+ #define _USE_RCV_TSTAMP ( !_IS_MBG_FIRMWARE )
+#endif
+
+
+#if _USE_MUTEX
+ #include <mbgmutex.h>
+#endif
+
+#if _USE_SERIAL_IO
+ #include <mbgserio.h>
+#endif
#if _USE_SOCKET_IO
#if defined( MBG_TGT_UNIX )
@@ -316,6 +284,10 @@
#include <gpspriv.h>
#endif
+#if _USE_RCV_TSTAMP
+ #include <mbg_tmo.h>
+#endif
+
#ifdef __cplusplus
@@ -365,9 +337,11 @@ extern "C" {
#define GPS_CTRL_MSK 0xF000 /* masks control code from command */
-/* The codes below specify commands/types of data to be supplied to */
-/* the GPS receiver: */
-
+/**< @defgroup gps_cmds_serial GPS commands passed via serial port
+ *
+ * These codes specify commands/types of data to be supplied to
+ * the GPS receiver:
+ */
/* clock auto-message to host */
/* | host request, clock response */
/* | | host download to clock */
@@ -419,7 +393,8 @@ enum /* | | | */
GPS_OPT_INFO, /* | | X | | MBG_OPT_INFO, (only if GPS_HAS_OPT_SETTINGS) */
GPS_CLR_UCAP_BUFF, /* | | X | | command only, no data */
GPS_TIME_SCALE, /* | | X | X | MBG_TIME_SCALE_{SETTINGS|INFO}, (only if GPS_HAS_TIME_SCALE) */
- GPS_NAV_ENG_SETTINGS, /* | | X | X | NAV_ENGINE_SETTINGS, (only if GPS_HAS_NAV_ENGINE_SETTINGS) */
+ GPS_NAV_ENG_SETTINGS, /* | | X | X | NAV_ENGINE_SETTINGS, (only if GPS_HAS_NAV_ENGINE_SETTINGS) */
+ GPS_RAW_IRIG_DATA, /* | | X | | MBG_RAW_IRIG_DATA, (only if GPS_HAS_RAW_IRIG_DATA) */
/* GPS data */
GPS_CFGH = 0x100, /* | | X | X | CFGH, SVs' configuration and health codes */
@@ -431,6 +406,8 @@ enum /* | | | */
/* Glonass data */
GPS_GLNS_ALM = 0x200, /* | | X | X | ** preliminary ** */ //##++
+ GPS_GNSS_SAT_INFO, /* | | X | | GNSS_SAT_INFO, request SVs */
+ GPS_GNSS_MODE, /* | | X | X | MBG_GNSS_MODE_{SETTINGS|INFO}, GNSS operation mode */
/* Misc data */
GPS_IP4_SETTINGS = 0x800, /* | X | X | IP4_SETTINGS, cfg of optional LAN interface */
@@ -461,6 +438,95 @@ enum /* | | | */
*/
+typedef struct
+{
+ GPS_CMD cmd_code;
+ const char *cmd_name;
+} GPS_CMD_NAME_TABLE_ENTRY;
+
+#define GPS_CMD_NAME_TABLE_ENTRIES \
+{ \
+ { GPS_AUTO_ON, "GPS_AUTO_ON" }, \
+ { GPS_AUTO_OFF, "GPS_AUTO_OFF" }, \
+ { GPS_SW_REV, "GPS_SW_REV" }, \
+ { GPS_BVAR_STAT, "GPS_BVAR_STAT" }, \
+ { GPS_TIME, "GPS_TIME" }, \
+ { GPS_POS_XYZ, "GPS_POS_XYZ" }, \
+ { GPS_POS_LLA, "GPS_POS_LLA" }, \
+ { GPS_TZDL, "GPS_TZDL" }, \
+ { GPS_PORT_PARM, "GPS_PORT_PARM" }, \
+ { GPS_SYNTH, "GPS_SYNTH" }, \
+ { GPS_ANT_INFO, "GPS_ANT_INFO" }, \
+ { GPS_UCAP, "GPS_UCAP" }, \
+ { GPS_ENABLE_FLAGS, "GPS_ENABLE_FLAGS" }, \
+ { GPS_STAT_INFO, "GPS_STAT_INFO" }, \
+ { GPS_SWITCH_PARMS, "GPS_SWITCH_PARMS" }, \
+ { GPS_STRING_PARMS, "GPS_STRING_PARMS" }, \
+ { GPS_ANT_CABLE_LENGTH, "GPS_ANT_CABLE_LENGTH" }, \
+ { GPS_SYNC_OUTAGE_DELAY, "GPS_SYNC_OUTAGE_DELAY" }, \
+ { GPS_PULSE_INFO, "GPS_PULSE_INFO" }, \
+ { GPS_OPT_FEATURES, "GPS_OPT_FEATURES" }, \
+ { GPS_IRIG_TX_SETTINGS, "GPS_IRIG_TX_SETTINGS" }, \
+ { GPS_RECEIVER_INFO, "GPS_RECEIVER_INFO" }, \
+ { GPS_STR_TYPE_INFO_IDX, "GPS_STR_TYPE_INFO_IDX" }, \
+ { GPS_PORT_INFO_IDX, "GPS_PORT_INFO_IDX" }, \
+ { GPS_PORT_SETTINGS_IDX, "GPS_PORT_SETTINGS_IDX" }, \
+ { GPS_POUT_INFO_IDX, "GPS_POUT_INFO_IDX" }, \
+ { GPS_POUT_SETTINGS_IDX, "GPS_POUT_SETTINGS_IDX" }, \
+ { GPS_IRIG_TX_INFO, "GPS_IRIG_TX_INFO" }, \
+ { GPS_MULTI_REF_SETTINGS, "GPS_MULTI_REF_SETTINGS" }, \
+ { GPS_MULTI_REF_INFO, "GPS_MULTI_REF_INFO" }, \
+ { GPS_ROM_CSUM, "GPS_ROM_CSUM" }, \
+ { GPS_MULTI_REF_STATUS, "GPS_MULTI_REF_STATUS" }, \
+ { GPS_RCV_TIMEOUT, "GPS_RCV_TIMEOUT" }, \
+ { GPS_IGNORE_LOCK, "GPS_IGNORE_LOCK" }, \
+ { GPS_IRIG_RX_SETTINGS, "GPS_IRIG_RX_SETTINGS" }, \
+ { GPS_IRIG_RX_INFO, "GPS_IRIG_RX_INFO" }, \
+ { GPS_REF_OFFS, "GPS_REF_OFFS" }, \
+ { GPS_DEBUG_STATUS, "GPS_DEBUG_STATUS" }, \
+ { GPS_XMR_SETTINGS_IDX, "GPS_XMR_SETTINGS_IDX" }, \
+ { GPS_XMR_INFO_IDX, "GPS_XMR_INFO_IDX" }, \
+ { GPS_XMR_STATUS_IDX, "GPS_XMR_STATUS_IDX" }, \
+ { GPS_OPT_SETTINGS, "GPS_OPT_SETTINGS" }, \
+ { GPS_OPT_INFO, "GPS_OPT_INFO" }, \
+ { GPS_CLR_UCAP_BUFF, "GPS_CLR_UCAP_BUFF" }, \
+ { GPS_TIME_SCALE, "GPS_TIME_SCALE" }, \
+ { GPS_NAV_ENG_SETTINGS, "GPS_NAV_ENG_SETTINGS" }, \
+ { GPS_RAW_IRIG_DATA, "GPS_RAW_IRIG_DATA" }, \
+ \
+ /* GPS data */ \
+ { GPS_CFGH, "GPS_CFGH" }, \
+ { GPS_ALM, "GPS_ALM" }, \
+ { GPS_EPH, "GPS_EPH" }, \
+ { GPS_UTC, "GPS_UTC" }, \
+ { GPS_IONO, "GPS_IONO" }, \
+ { GPS_ASCII_MSG, "GPS_ASCII_MSG" }, \
+ \
+ /* Glonass data */ \
+ { GPS_GLNS_ALM, "GPS_GLNS_ALM" }, \
+ { GPS_GNSS_SAT_INFO, "GPS_GNSS_SAT_INFO" }, \
+ { GPS_GNSS_MODE, "GPS_GNSS_MODE" }, \
+ \
+ /* Misc data */ \
+ { GPS_IP4_SETTINGS, "GPS_IP4_SETTINGS" }, \
+ { GPS_LAN_IF_INFO, "GPS_LAN_IF_INFO" }, \
+ \
+ { GPS_CRYPTED_PACKET, "GPS_CRYPTED_PACKET" }, \
+ { GPS_CRYPTED_RAW_PACKET, "GPS_CRYPTED_RAW_PACKET" }, \
+ \
+ { GPS_SECU_INFO, "GPS_SECU_INFO" }, \
+ { GPS_SECU_SETTINGS, "GPS_SECU_SETTINGS" }, \
+ { GPS_SECU_PUBLIC_KEY, "GPS_SECU_PUBLIC_KEY" }, \
+ \
+ /* PZF data */ \
+ { PZF_PCPS_TIME, "PZF_PCPS_TIME" }, \
+ { PZF_TR_DISTANCE, "PZF_TR_DISTANCE" }, \
+ { PZF_TZCODE, "PZF_TZCODE" }, \
+ { PZF_CORR_INFO, "PZF_CORR_INFO" }, \
+ { 0, NULL } \
+}
+
+
/* A structure holding the number of a SV and the SV's almanac. */
typedef struct
@@ -553,6 +619,10 @@ typedef union
MBG_TIME_SCALE_INFO time_scale_info;
MBG_TIME_SCALE_SETTINGS time_scale_settings;
NAV_ENGINE_SETTINGS nav_engine_settings;
+ MBG_RAW_IRIG_DATA raw_irig_data;
+ GNSS_SAT_INFO gnss_sat_info; //##++++++
+ MBG_GNSS_MODE_INFO gnss_mode_info; //##++++++
+ MBG_GNSS_MODE_SETTINGS gnss_mode_settings; //##++++++
/* GPS system data */
CFGH cfgh;
@@ -672,7 +742,9 @@ typedef struct
uint8_t *cur; /* points to current pos inside receive buffer */
int cnt; /* the number of bytes to receive */
ulong flags; /* flags if header already completed */
-
+ #if _USE_RCV_TSTAMP
+ MBG_TMO_TIME tstamp;
+ #endif
#if _USE_CHK_TSTR
void (*chk_tstr_fnc)( char c, TIMESTR_CHECK *arg ); /* optional handler for normal, non-protocol data */
TIMESTR_CHECK *chk_tstr_arg;
@@ -708,7 +780,7 @@ typedef struct
int xfer_mode;
#if _USE_MUTEX
- MBG_MUTEX_HANDLE xmt_mutex;
+ MBG_MUTEX xmt_mutex;
#endif
} MBG_MSG_XMT_CTL;
diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h
index f10f53f..06e9a86 100644
--- a/mbglib/common/mbg_tgt.h
+++ b/mbglib/common/mbg_tgt.h
@@ -13,6 +13,7 @@
* $Log: mbg_tgt.h $
* Revision 1.22 2009/10/01 08:20:50Z martin
* Fixed inline code support with different BC versions.
+ * Revision 1.1 2009/11/20 12:24:05 philipp
* Revision 1.21 2009/09/01 10:34:23Z martin
* Don't define __mbg_inline for CVI and undefined targets.
* Revision 1.20 2009/08/18 15:14:26 martin
diff --git a/mbglib/common/mbg_tmo.c b/mbglib/common/mbg_tmo.c
new file mode 100644
index 0000000..b62231b
--- /dev/null
+++ b/mbglib/common/mbg_tmo.c
@@ -0,0 +1,64 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_tmo.c 1.2 2009/09/01 10:36:45Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Functions to implement portable timeout handling.
+ * These functions are normally implemented as inline functions, or
+ * as preprocessor macros, if inline code is not supported.
+ *
+ * However, due to their nature the functions below can not be
+ * implemented as macros, so they need to be implemented as normal
+ * functions for targets which do not support inline functions.
+ *
+ * This currently applies only to the CVI build environment.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_tmo.c $
+ * Revision 1.2 2009/09/01 10:36:45Z martin
+ * Implement legacy functions only if __mbg_inline is not defined.
+ * Revision 1.1 2009/08/25 11:28:47 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _MBG_TMO
+ #include <mbg_tmo.h>
+#undef _MBG_TMO
+
+
+#if !defined( __mbg_inline )
+
+
+int mbg_tmo_curr_time_is_after( const MBG_TMO_TIME *tmo )
+{
+ MBG_TMO_TIME t_now;
+
+ mbg_tmo_get_time( &t_now );
+
+ return mbg_tmo_time_is_after( &t_now, tmo );
+
+} // mbg_tmo_curr_time_is_after
+
+
+
+// The function below can be used to set up a timeout for select().
+
+#if defined( MBG_TGT_CVI )
+
+void mbgserio_msec_to_timeval( ulong msec, struct timeval *tv )
+{
+ tv->tv_sec = msec / 1000;
+ tv->tv_usec = ( msec % 1000 ) * 1000;
+
+} // mbgserio_msec_to_timeval
+
+#endif // defined( MBG_TGT_CVI )
+
+
+#endif // !defined( __mbg_inline )
+
+
diff --git a/mbglib/common/mbg_tmo.h b/mbglib/common/mbg_tmo.h
new file mode 100644
index 0000000..60399b9
--- /dev/null
+++ b/mbglib/common/mbg_tmo.h
@@ -0,0 +1,317 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_tmo.h 1.4 2011/01/26 16:55:33Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Inline functions for portable timeout handling.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_tmo.h $
+ * Revision 1.4 2011/01/26 16:55:33Z martin
+ * Fixed compiler warnings with gcc/Linux.
+ * Revision 1.3 2010/06/02 12:29:44 daniel
+ * Excluded mbgserio_msec_to_timeval() from build under WIN32 targets.
+ * Revision 1.2 2009/09/01 10:38:21Z martin
+ * Cleanup for CVI and other targets which don't support inline code.
+ * Revision 1.1 2009/08/24 13:08:56 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBG_TMO_H
+#define _MBG_TMO_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+#include <words.h>
+
+#ifdef _MBG_TMO
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( MBG_TGT_UNIX )
+
+ #include <stdlib.h>
+ #include <sys/time.h>
+
+ typedef struct timeval MBG_TMO_TIME;
+
+#elif defined( MBG_TGT_WIN32 )
+
+ typedef union
+ {
+ FILETIME ft;
+ uint64_t u64;
+
+ } MBG_TMO_TIME;
+
+#else // DOS, ...
+
+ #include <time.h>
+
+ #define MBG_TMO_TIME clock_t
+
+#endif
+
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+void mbg_tmo_get_time( MBG_TMO_TIME *t )
+{
+ #if defined( MBG_TGT_UNIX )
+
+ gettimeofday( t, NULL );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ GetSystemTimeAsFileTime( &t->ft );
+
+ #else // DOS, ...
+
+ *t = clock();
+
+ #endif
+
+} // mbg_tmo_get_time
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_get_time( _t ) \
+ GetSystemTimeAsFileTime( &(_t)->ft )
+
+#else // DOS, ...
+
+ #define mbg_tmo_get_time( _t ) \
+ *(_t) = clock();
+
+#endif
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+int mbg_tmo_time_is_set( const MBG_TMO_TIME *t )
+{
+ #if defined( MBG_TGT_UNIX )
+
+ return ( t->tv_sec != 0 ) || ( t->tv_usec != 0 );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return ( t->u64 != 0 );
+
+ #else // DOS, ...
+
+ return ( *t != 0 );
+
+ #endif
+
+} // mbg_tmo_time_is_set
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_time_is_set( _t ) \
+ ( (_t)->u64 != 0 )
+
+#else // DOS, ...
+
+ #define mbg_tmo_time_is_set( _t ) \
+ ( *(_t) != 0 )
+
+#endif
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec )
+{
+ mbg_tmo_get_time( t_tmo );
+
+ #if defined( MBG_TGT_UNIX )
+
+ t_tmo->tv_usec += msec * 1000;
+
+ while ( t_tmo->tv_usec > 1000000L )
+ {
+ t_tmo->tv_usec -= 1000000L;
+ t_tmo->tv_sec++;
+ }
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ t_tmo->u64 += ( (uint64_t) msec ) * 10000;
+
+ #else // DOS, ...
+
+ *t_tmo += (clock_t) ( ( (double) msec * CLOCKS_PER_SEC ) / 1000 );
+
+ #endif
+
+} // mbg_tmo_set_timeout
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_set_timeout_ms( _t, _msec ) \
+ mbg_tmo_get_time( (_t) ); \
+ (_t)->u64 += ( (uint64_t) (_msec) ) * 10000
+
+#else // DOS, ...
+
+ #define mbg_tmo_set_timeout_ms( _t, _msec ) \
+ mbg_tmo_get_time( (_t) ); \
+ *(_t) += (clock_t) ( ( (double) (_msec) * CLOCKS_PER_SEC ) / 1000 );
+#endif
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+long mbg_tmo_time_diff_ms( const MBG_TMO_TIME *t, const MBG_TMO_TIME *t0 )
+{
+ #if defined( MBG_TGT_UNIX )
+
+ return ( t->tv_sec - t0->tv_sec ) * 1000
+ + ( t->tv_usec - t0->tv_usec ) / 1000;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return (long) ( ( t->u64 - t0->u64 ) / 10000 );
+
+ #else // DOS, ...
+
+ return (long) ( (double) ( ( *t - *t0 ) * 1000 ) / CLOCKS_PER_SEC );
+
+ #endif
+
+} // mbg_tmo_time_diff_ms
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_time_diff_ms( _t, _t0 ) \
+ (long) ( ( (_t)->u64 - (_t0)->u64 ) / 10000 )
+
+#else // DOS, ...
+
+ #define mbg_tmo_time_diff_ms( _t, _t0 ) \
+ (long) ( (double) ( ( *(_t) - *(_t0) ) * 1000 ) / CLOCKS_PER_SEC );
+
+#endif
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+int mbg_tmo_time_is_after( const MBG_TMO_TIME *t_now, const MBG_TMO_TIME *tmo )
+{
+ #if defined( MBG_TGT_UNIX )
+
+ return ( ( t_now->tv_sec > tmo->tv_sec ) ||
+ ( ( t_now->tv_sec == tmo->tv_sec ) && ( t_now->tv_usec > tmo->tv_usec ) ) );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return ( t_now->u64 > tmo->u64 );
+
+ #else // DOS, ...
+
+ return ( *t_now > *tmo );
+
+ #endif
+
+} // mbg_tmo_time_is_after
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_time_is_after( _t, _tmo ) \
+ ( (_t)->u64 > (_tmo)->u64 )
+
+#else // DOS, ...
+
+ #define mbg_tmo_time_is_after( _t, _tmo ) \
+ ( *(_t) > *(_tmo) )
+
+#endif
+
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+int mbg_tmo_curr_time_is_after( const MBG_TMO_TIME *tmo )
+{
+ MBG_TMO_TIME t_now;
+
+ mbg_tmo_get_time( &t_now );
+
+ return mbg_tmo_time_is_after( &t_now, tmo );
+
+} // mbg_tmo_curr_time_is_after
+
+#else
+
+ // needs to be implemented as non-inline function in mbg_tmo.c
+ int mbg_tmo_curr_time_is_after( const MBG_TMO_TIME *tmo );
+
+#endif
+
+
+
+// The function below can be used to set up a timeout for select().
+
+// check for CVI first since this is a special case of WIN32
+#if defined( MBG_TGT_CVI )
+
+ // needs to be implemented as non-inline function in mbg_tmo.c
+ void mbgserio_msec_to_timeval( ulong msec, struct timeval *tv );
+
+#elif defined( MBG_TGT_UNIX )
+
+static __mbg_inline
+void mbgserio_msec_to_timeval( ulong msec, struct timeval *tv )
+{
+ tv->tv_sec = msec / 1000;
+ tv->tv_usec = ( msec % 1000 ) * 1000;
+
+} // mbgserio_msec_to_timeval
+
+#endif // defined( MBG_TGT_UNIX ) || defined( MBG_TGT_WIN32 )
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+/* (no header definitions found) */
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBG_TMO_H */
diff --git a/mbglib/common/mbgextio.c b/mbglib/common/mbgextio.c
index 4623e32..17322b0 100644
--- a/mbglib/common/mbgextio.c
+++ b/mbglib/common/mbgextio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgextio.c 1.9 2009/10/02 14:19:05Z martin REL_M $
+ * $Id: mbgextio.c 1.11 2011/04/15 13:17:14Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,12 @@
*
* -----------------------------------------------------------------------
* $Log: mbgextio.c $
- * Revision 1.9 2009/10/02 14:19:05Z martin
+ * Revision 1.11 2011/04/15 13:17:14Z martin
+ * Use common mutex support macros from mbgmutex.h.
+ * Revision 1.10 2011/04/08 11:28:24 martin
+ * Modified mbgextio_get_ucap() to account for different device behaviour.
+ * Added missing braces.
+ * Revision 1.9 2009/10/02 14:19:05 martin
* Added a bunch of missing functions.
* Revision 1.8 2009/10/01 11:10:51 martin
* Added functions to set/retrieve char and msg rcv timeout.
@@ -246,7 +251,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
#endif
#if _USE_MUTEX
- _mbg_mutex_init( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_init( &pmctl->xmt.xmt_mutex );
#endif
return rc;
@@ -277,7 +282,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char
mbgserio_set_parms( &pmctl->st.serio, baud_rate, framing );
#if _USE_MUTEX
- _mbg_mutex_init( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_init( &pmctl->xmt.xmt_mutex );
#endif
return 0;
@@ -315,7 +320,7 @@ _MBG_API_ATTR void _MBG_API mbgextio_close_connection( MBG_MSG_CTL *pmctl )
}; // switch
#if _USE_MUTEX
- _mbg_mutex_destroy( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_destroy( &pmctl->xmt.xmt_mutex );
#endif
} // mbgextio_close_connection
@@ -419,7 +424,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
#if _USE_MUTEX
- _mbg_mutex_lock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
#endif
pmb = pmctl->xmt.pmb;
@@ -432,7 +437,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
xmt_tbuff( pmctl );
#if _USE_MUTEX
- _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_release( &pmctl->xmt.xmt_mutex );
#endif
if ( cmd & GPS_REQACK )
@@ -445,7 +450,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK )
return -3;
- if ( !pmctl->rcv.pmb->hdr.cmd & GPS_ACK )
+ if ( !(pmctl->rcv.pmb->hdr.cmd & GPS_ACK) )
return -4;
}
@@ -601,13 +606,13 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
int rc;
#if _USE_MUTEX
- _mbg_mutex_lock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
#endif
rc = xmt_cmd( pmctl, cmd );
#if _USE_MUTEX
- _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_release( &pmctl->xmt.xmt_mutex );
#endif
return rc;
@@ -622,13 +627,13 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
int rc;
#if _USE_MUTEX
- _mbg_mutex_lock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
#endif
rc = xmt_cmd_us( pmctl, cmd, us );
#if _USE_MUTEX
- _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ _mbg_mutex_release( &pmctl->xmt.xmt_mutex );
#endif
return rc;
@@ -968,9 +973,26 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
// Attention: Older firmware versions may reply with GPS_TIME
// messages instead of GPS_UCAP messages, and may not send a reply
// at all if no capture event is available in the on-board FIFO.
- rc = mbgextio_rcv_msg( pmctl, GPS_UCAP );
+ for (;;)
+ {
+ rc = mbgextio_rcv_msg( pmctl, -1 );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( rc < 0 )
+ break;
+
+ if ( rc != TR_COMPLETE )
+ continue;
+
+ if ( pmctl->rcv.pmb->hdr.cmd == GPS_UCAP )
+ break;
+
+ if ( pmctl->rcv.pmb->hdr.cmd == GPS_TIME )
+ if ( pmctl->rcv.pmb->hdr.len > 0 )
+ if ( pmctl->rcv.pmb->u.msg_data.ttm.channel >= 0 )
+ break;
+ }
+
+ if ( p )
{
// If the length of the msg header is 0 then the capture buffer
// is empty. This is indicated with 0xFF in the seconds field of
@@ -978,7 +1000,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
if ( pmctl->rcv.pmb->hdr.len > 0 )
*p = pmctl->rcv.pmb->u.msg_data.ttm;
else
- p->tm.sec = (int8_t) 0xFF; // no capture event available
+ _ttm_time_set_unavail( p ); // no capture event available
}
return rc;
diff --git a/mbglib/common/mbgextio.h b/mbglib/common/mbgextio.h
index 5696e23..53a21e6 100644
--- a/mbglib/common/mbgextio.h
+++ b/mbglib/common/mbgextio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgextio.h 1.7 2009/10/02 14:21:08Z martin REL_M $
+ * $Id: mbgextio.h 1.8 2011/04/08 11:26:09Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: mbgextio.h $
- * Revision 1.7 2009/10/02 14:21:08Z martin
+ * Revision 1.8 2011/04/08 11:26:09Z martin
+ * New macros _ttm_time_set_unavail() and _ttm_time_is_avail().
+ * Revision 1.7 2009/10/02 14:21:08 martin
* Updated function prototypes.
* Revision 1.6 2009/10/01 11:13:42Z martin
* Updated function prototypes.
@@ -50,6 +52,14 @@
/* Start of header body */
+// The macros below can be used to set a TTM variable to a state
+// indicating "time not available", and to check this state.
+// This can be used for example to indicate if a capture event
+// could have been read from a device, or not.
+#define _ttm_time_set_unavail( _t ) do { (_t)->tm.sec = (uint8_t) 0xFF; } while ( 0 )
+#define _ttm_time_is_avail( _t ) ( (uint8_t) (_t)->tm.sec != (uint8_t) 0xFF )
+
+
#if _USE_SERIAL_IO
#if !defined( DEFAULT_DEV_NAME )
#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS )
diff --git a/mbglib/common/mbgmutex.h b/mbglib/common/mbgmutex.h
new file mode 100644
index 0000000..0a35494
--- /dev/null
+++ b/mbglib/common/mbgmutex.h
@@ -0,0 +1,239 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgmutex.h 1.1 2011/04/15 12:26:59Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Portable macros to deal with spinlocks, mutexes,
+ * and critical sections.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgmutex.h $
+ * Revision 1.1 2011/04/15 12:26:59Z martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBGMUTEX_H
+#define _MBGMUTEX_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+#include <words.h>
+
+#ifdef _MBGMUTEX
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( MBG_TGT_KERNEL ) // definitions used in kernel space
+
+ #if defined( MBG_TGT_WIN32 ) // Windows kernel space
+
+ typedef KSPIN_LOCK MBG_SPINLOCK;
+ #define _mbg_spin_lock_init( _spl ) KeInitializeSpinLock( _spl )
+ #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
+ #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLockAtDpcLevel( _spl )
+ #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLockFromDpcLevel( _spl )
+
+ #define MBG_SPINLOCK_DEFINED 1
+
+
+ typedef FAST_MUTEX MBG_MUTEX;
+ #define _mbg_mutex_init( _pmtx ) ExInitializeFastMutex( _pmtx )
+ #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc()
+ #define _mbg_mutex_acquire( _pmtx ) ExAcquireFastMutex( _pmtx )
+ #define _mbg_mutex_release( _pmtx ) ExReleaseFastMutex( _pmtx )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ #elif defined( MBG_TGT_LINUX ) // Linux kernel space
+
+ #include <linux/spinlock.h>
+ #include <asm/semaphore.h>
+
+ typedef spinlock_t MBG_SPINLOCK;
+ #define _mbg_spin_lock_init( _spl ) spin_lock_init( _spl )
+ #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
+ #define _mbg_spin_lock_acquire( _spl ) spin_lock( _spl )
+ #define _mbg_spin_lock_release( _spl ) spin_unlock( _spl )
+
+ #define MBG_SPINLOCK_DEFINED 1
+
+
+ typedef struct semaphore MBG_MUTEX;
+ #define _mbg_mutex_init( _pmtx ) sema_init( _pmtx, 1 )
+ #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc()
+ #define _mbg_mutex_acquire( _pmtx ) down_interruptible( _pmtx )
+ #define _mbg_mutex_release( _pmtx ) up( _pmtx )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ #elif defined( MBG_TGT_FREEBSD ) // FreeBSD kernel space
+
+ #include <sys/mutex.h>
+
+ typedef struct mtx MBG_SPINLOCK;
+ #define _mbg_spin_lock_init( _spl ) mtx_init( _spl, "mbg_spin_lock", NULL, MTX_SPIN )
+ #define _mbg_spin_lock_destroy( _spl ) mtx_destroy( _spl )
+ #define _mbg_spin_lock_acquire( _spl ) mtx_lock_spin( _spl )
+ #define _mbg_spin_lock_release( _spl ) mtx_unlock_spin( _spl )
+
+ #define MBG_SPINLOCK_DEFINED 1
+
+
+ typedef struct mtx MBG_MUTEX;
+ #define _mbg_mutex_init( _pmtx ) mtx_init( _pmtx, "mbg_mutex", NULL, MTX_DEF )
+ #define _mbg_mutex_destroy( _pmtx ) mtx_destroy( _pmtx )
+ #define _mbg_mutex_acquire( _pmtx ) mtx_lock( _pmtx )
+ #define _mbg_mutex_release( _pmtx ) mtx_unlock( _pmtx )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ #elif defined( MBG_TGT_NETBSD )
+
+ #include <sys/mutex.h>
+
+ // The API used below has been introduced in NetBSD 5.0
+ // For earlier NetBSD versions see 'man 9 lockinit'.
+
+ typedef kmutex_t MBG_SPINLOCK;
+ #define _mbg_spin_lock_init( _spl ) mutex_init( _spl, MUTEX_DEFAULT, IPL_HIGH )
+ #define _mbg_spin_lock_destroy( _spl ) mutex_destroy( _spl )
+ #define _mbg_spin_lock_acquire( _spl ) mutex_spin_enter( _spl )
+ #define _mbg_spin_lock_release( _spl ) mutex_spin_exit( _spl )
+
+ #define MBG_SPINLOCK_DEFINED 1
+
+
+ typedef kmutex_t MBG_MUTEX;
+ #define _mbg_mutex_init( _pmtx ) mutex_init( _pmtx, MUTEX_DEFAULT, IPL_NONE )
+ #define _mbg_mutex_destroy( _spl ) mutex_destroy( _spl )
+ #define _mbg_mutex_acquire( _pmtx ) mutex_enter( _pmtx )
+ #define _mbg_mutex_release( _pmtx ) mutex_exit( _pmtx )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ #endif
+
+#else // user space applications
+
+ #if defined( MBG_TGT_WIN32 ) // Windows user space
+
+ #include <windows.h>
+
+ // definitions used with mutexes
+ typedef HANDLE MBG_MUTEX;
+ #define _mbg_mutex_init( _pm ) *(_pm) = CreateMutex( NULL, FALSE, NULL )
+ #define _mbg_mutex_destroy( _pm ) CloseHandle( *(_pm) ); *(_pm) = INVALID_HANDLE_VALUE
+ #define _mbg_mutex_acquire( _pm ) WaitForSingleObject( *(_pm), INFINITE )
+ #define _mbg_mutex_release( _pm ) ReleaseMutex( *(_pm) )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ // definitions used with critical sections
+ typedef CRITICAL_SECTION MBG_CRIT_SECT;
+ #define _mbg_crit_sect_init( _pcs ) InitializeCriticalSection( (_pcs) )
+ #define _mbg_crit_sect_destroy( _pcs ) DeleteCriticalSection( (_pcs) )
+ #define _mbg_crit_sect_enter( _pcs ) EnterCriticalSection( (_pcs) )
+ #define _mbg_crit_sect_leave( _pcs ) LeaveCriticalSection( (_pcs) )
+
+ #define _MBG_CRIT_SECT_DEFINED 1
+
+ #elif defined( MBG_TGT_UNIX ) // Unix user space use pthread library
+
+ #include <pthread.h>
+
+ // Mutex types:
+ // PTHREAD_MUTEX_INITIALIZER /* Fast */
+ // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP /* Recursive */
+ // PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* Errorcheck */
+ typedef pthread_mutex_t MBG_MUTEX;
+ #define _mbg_mutex_init( _pm ) pthread_mutex_init( (_pm), NULL )
+ #define _mbg_mutex_destroy( _pm ) pthread_mutex_destroy( (_pm) )
+ #define _mbg_mutex_acquire( _pm ) pthread_mutex_lock( (_pm) )
+ #define _mbg_mutex_release( _pm ) pthread_mutex_unlock( (_pm) )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ // For critical sections use defaults specified below
+
+ #endif
+
+#endif
+
+
+#if !defined( MBG_SPINLOCK_DEFINED )
+
+ #define _mbg_spin_lock_init( _spl ) _nop_macro_fnc()
+ #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
+ #define _mbg_spin_lock_acquire( _spl ) _nop_macro_fnc()
+ #define _mbg_spin_lock_release( _spl ) _nop_macro_fnc()
+
+#endif
+
+
+#if !defined( _MBG_MUTEX_DEFINED )
+
+ #define _MBG_MUTEX_DEFINED 1
+
+ typedef MBG_CRIT_SECT MBG_MUTEX;
+
+ #define _mbg_mutex_init( _pm ) _nop_macro_fnc()
+ #define _mbg_mutex_destroy( _pm ) _nop_macro_fnc()
+ #define _mbg_mutex_acquire( _pm ) _nop_macro_fnc()
+ #define _mbg_mutex_release( _pm ) _nop_macro_fnc()
+
+#endif
+
+
+#if !defined( _MBG_CRIT_SECT_DEFINED )
+
+ // use mutex by default, e.g. with the pthread library
+
+ #define _MBG_CRIT_SECT_DEFINED 1
+
+ typedef MBG_MUTEX MBG_CRIT_SECT;
+ #define _mbg_crit_sect_init _mbg_mutex_init
+ #define _mbg_crit_sect_destroy _mbg_mutex_destroy
+ #define _mbg_crit_sect_enter _mbg_mutex_acquire
+ #define _mbg_crit_sect_leave _mbg_mutex_release
+
+#endif
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+/* (no header definitions found) */
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGMUTEX_H */
diff --git a/mbglib/common/mbgserio.c b/mbglib/common/mbgserio.c
new file mode 100644
index 0000000..04dc045
--- /dev/null
+++ b/mbglib/common/mbgserio.c
@@ -0,0 +1,960 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgserio.c 1.3 2009/09/01 10:49:30Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg serial I/O functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgserio.c $
+ * Revision 1.3 2009/09/01 10:49:30Z martin
+ * Cleanup for CVI.
+ * Use new portable timeout functions from mbg_tmo.h.
+ * Timeouts are now specified in milliseconds.
+ * Set DOS/v24tools low level receive timeout to minimum on open.
+ * Let functions return predefined codes.
+ * Revision 1.2 2008/09/04 15:34:18Z martin
+ * Moved support for different target environments from other files here.
+ * Added mbgserio_set_parms() and don't set parms when opening a port.
+ * Fixed bugs in timeout calculations in mbgserio_read_wait().
+ * Preliminary support for port device lists.
+ * Revision 1.1 2007/11/12 16:48:02 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _MBGSERIO
+ #include <mbgserio.h>
+
+ //##++ The following lines are required
+ // until mbgserio becomes a DLL:
+ #undef _MBG_API_ATTR
+ #define _MBG_API_ATTR
+
+#undef _MBGSERIO
+
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#if defined( MBG_TGT_UNIX )
+ #include <unistd.h>
+ #include <fcntl.h>
+#endif
+
+
+
+#if defined( _USE_V24TOOLS )
+
+/*------------------------------------------------------------------------
+ * The definitions in this block and all v24...() functions are part of a
+ * third-party library called V.24 Tools Plus by Langner Expertensysteme.
+ *
+ * This library may no be distributed freely, so the v24..() functions
+ * must be replaced by user-written functions or some library available
+ * to the user of this demo.
+ *-----------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int v24open( char *portname, int mode );
+/* Open a port with specified name (e.g. "COM1"). The functions return a
+ * handle to be used with the other functions. If the handle is < 0, the
+ * port could not be opened.
+ */
+
+#define O_DIRECT 0x0100 /* Schnittstelle fuer direkten Hardware-Zugriff oeffnen */
+#define O_HIGHPRIO 0x2000 /* Schnittstelle mit hoher Prioritaet oeffnen (fastopen) */
+
+#define OPEN_MODE ( O_DIRECT | O_HIGHPRIO )
+
+
+int v24setparams( int port, long speed, int dbits, int parity, int stopbits );
+/* Set the port's transmission speed, number of data bits, parity and
+ * number of stop bits. Returns 0 on success.
+ */
+
+int v24qempty( int port, int which );
+/* Returns 1 if the receive buffer is empty, 0 if it is not, or an other
+ * value on error.
+ */
+
+int v24getch( int port );
+/* Return a character from the receive buffer.
+ */
+
+int v24putc( int port, char c );
+/* Write a character to the port.
+ */
+
+int v24close( int port );
+/* Close the port
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // defined( _USE_V24TOOLS )
+
+/*------------------------------------------------------------------------*/
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev )
+{
+ MBG_PORT_HANDLE port_handle;
+
+ #if defined( MBG_TGT_CVI )
+ {
+ int data_bits = 8; //##++
+ int parity_code = 0;
+ int baud_rate = 19200;
+ int stop_bits = 1;
+ int i;
+ int len;
+ int rc;
+
+ // Under CVI the port handle passed to OpenComConfig and used furtheron
+ // corresponds to the COM port number, e.g. 1 for COM1, so we extract
+ // the number from the device name passed as parameter.
+ port_handle = 0;
+ len = strlen( dev );
+
+ for ( i = 0; i < len; i++ )
+ {
+ char c = dev[i];
+ if ( c >= '0' && c <= '9' )
+ break;
+ }
+
+ if ( i == len )
+ return MBGSERIO_INV_CFG; // no numeric substring found
+
+
+ port_handle = atoi( &dev[i] );
+
+ rc = OpenComConfig (port_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024); //##++
+ if ( rc < 0 )
+ goto fail;
+
+ pst->port_handle = port_handle;
+
+ SetComTime( port_handle, 1.0 ); //##++
+ SetXMode( port_handle, 0 );
+ }
+ #elif defined( MBG_TGT_WIN32 )
+ {
+ static const char *prefix = "\\\\.\\";
+
+ COMMTIMEOUTS commtimeouts;
+ int len = strlen( prefix ) + strlen( dev ) + 1;
+ char *tmp_name = (char *) malloc( len );
+
+ if ( tmp_name == NULL ) // unable to allocate memory
+ goto fail;
+
+
+ strcpy( tmp_name, prefix );
+ strcat( tmp_name, dev );
+
+ port_handle = CreateFile( tmp_name, GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
+ NULL );
+
+ free( tmp_name );
+
+ if ( port_handle == INVALID_HANDLE_VALUE )
+ goto fail;
+
+
+ pst->port_handle = port_handle;
+
+ // save original settings
+ pst->old_dcb.DCBlength = sizeof( pst->old_dcb );
+ GetCommState( port_handle, &pst->old_dcb );
+ GetCommTimeouts( port_handle, &pst->old_commtimeouts );
+
+ // configure our settings
+ memset( &commtimeouts, 0, sizeof( commtimeouts ) );
+ SetCommTimeouts( port_handle, &commtimeouts );
+
+ #if defined( MBGSERIO_IN_BUFFER_SIZE ) && defined( MBGSERIO_OUT_BUFFER_SIZE )
+ SetupComm( port_handle, MBGSERIO_IN_BUFFER_SIZE, MBGSERIO_OUT_BUFFER_SIZE );
+ #endif
+
+ PurgeComm( port_handle, PURGE_TXABORT|PURGE_TXCLEAR );
+ PurgeComm( port_handle, PURGE_RXABORT|PURGE_RXCLEAR );
+
+ //##++ mbgextio_set_console_control_handler();
+ }
+ #elif defined( MBG_TGT_UNIX )
+ {
+ // Open as not controlling TTY to prevent from being
+ // killed if CTRL-C is received.
+ // O_NONBLOCK is the same as O_NDELAY.
+ port_handle = _mbg_open( dev, O_RDWR | O_NOCTTY | O_NONBLOCK );
+
+ //##++ TODO: Under Unix a serial port can by default be opened
+ // by several processes. However, we don't want that, so we
+ // should care about this using a lock file for the device
+ // and/or setting the TIOCEXCL flag (which unfortunately
+ // is not an atomic operation with open()).
+
+ if ( port_handle < 0 ) // check errno for the reason
+ goto fail;
+
+
+ pst->port_handle = port_handle;
+
+ /* save current device settings */
+ tcgetattr( port_handle, &pst->oldtio );
+
+ // atexit( port_deinit );
+
+ fflush( stdout ); //##++
+ setvbuf( stdout, NULL, _IONBF, 0 );
+ }
+ #elif defined( MBG_TGT_DOS )
+ #if defined( _USE_V24TOOLS )
+ {
+ port_handle = v24open( (char *) dev, OPEN_MODE );
+
+ if ( port_handle < 0 )
+ goto fail;
+
+ pst->port_handle = port_handle;
+ v24settimeout( port_handle, 1 );
+ }
+ #else
+
+ #error Target DOS requires v24tools for serial I/O.
+
+ #endif
+
+ #else
+
+ #error This target OS is not supported.
+
+ #endif
+
+ return 0;
+
+
+fail:
+ pst->port_handle = MBG_INVALID_PORT_HANDLE;
+ return MBGSERIO_FAIL;
+
+} // mbgserio_open
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst )
+{
+ if ( pst->port_handle != MBG_INVALID_PORT_HANDLE )
+ {
+ MBG_PORT_HANDLE port_handle = pst->port_handle;
+
+ #if defined( MBG_TGT_CVI )
+
+ CloseCom( port_handle );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ SetCommState( port_handle, &pst->old_dcb );
+ SetCommTimeouts( port_handle, &pst->old_commtimeouts );
+ CloseHandle( port_handle );
+
+ #elif defined( MBG_TGT_UNIX )
+
+ tcsetattr( port_handle, TCSANOW, &pst->oldtio );
+ close( port_handle );
+
+ #elif defined( MBG_TGT_DOS )
+ #if defined( _USE_V24TOOLS )
+
+ v24close( port_handle );
+
+ #else
+
+ #error Target DOS requires v24tools for serial I/O.
+
+ #endif
+
+ #else
+
+ #error This target OS is not supported.
+
+ #endif
+
+ pst->port_handle = MBG_INVALID_PORT_HANDLE;
+ }
+
+ return 0;
+
+} // mbgserio_close
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, int max_devs )
+{
+ MBG_STR_LIST *list_head;
+ int n = 0;
+ int i = 0;
+
+ (*list) = (MBG_STR_LIST *) malloc( sizeof( **list ) );
+ memset( (*list), 0, sizeof( **list ) );
+
+ list_head = (*list);
+
+ for ( i = 0; i < max_devs; i++ )
+ {
+ SERIAL_IO_STATUS iost;
+ char dev_name[100] = { 0 };
+ int rc;
+
+ #if defined( MBG_TGT_WIN32 )
+ sprintf( dev_name, "COM%i", i + 1 );
+ #elif defined( MBG_TGT_LINUX )
+ sprintf( dev_name, "/dev/ttyS%i", i );
+ #endif
+
+ rc = mbgserio_open( &iost, dev_name );
+
+ if ( rc < 0 )
+ continue;
+
+ mbgserio_close( &iost );
+
+ (*list)->s = (char *) malloc( strlen( dev_name ) + 1 );
+ strcpy( (*list)->s, dev_name );
+
+ (*list)->next = (MBG_STR_LIST *) malloc( sizeof( **list ) );
+ (*list) = (*list)->next;
+
+ memset( (*list), 0, sizeof( **list ) );
+ n++;
+
+// if ( ++i >= MBG_MAX_DEVICES )
+// break;
+ }
+
+ if ( n == 0 )
+ {
+ free( *list );
+ list_head = NULL;
+ }
+
+ *list = list_head;
+
+ return n;
+
+} // mbgserio_setup_port_str_list
+
+
+
+/*HDR*/
+_MBG_API_ATTR void _MBG_API _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list )
+{
+ int i = 0;
+
+ while ( i < 1000 ) //##++
+ {
+ if ( list )
+ {
+ if ( list->s )
+ {
+ free( list->s );
+ list->s = NULL;
+ }
+
+ if ( list->next )
+ {
+ MBG_STR_LIST *next = list->next;
+ free( list );
+ list = next;
+ }
+ else
+ {
+ if ( list )
+ {
+ free( list );
+ list = NULL;
+ }
+ break;
+ }
+ }
+ else
+ break;
+
+ i++;
+ }
+
+} // mbgserio_free_str_list
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
+ uint32_t baud_rate, const char *framing )
+{
+ MBG_PORT_HANDLE port_handle = pst->port_handle;
+ const char *cp;
+
+ #if defined( MBG_TGT_CVI )
+ {
+ int data_bits = 8;
+ int parity_code = 0;
+ int stop_bits = 1;
+ int rc;
+
+ // setup framing.
+ for ( cp = framing; *cp; cp++ )
+ {
+ char c = toupper( *cp );
+
+ switch ( c )
+ {
+ case '7':
+ case '8':
+ data_bits = c - '0';
+ break;
+
+ case 'N':
+ parity_code = 0;
+ break;
+
+ case 'E':
+ parity_code = 2;
+ break;
+
+ case 'O':
+ parity_code = 1;
+ break;
+
+ case '1':
+ case '2':
+ stop_bits = c - '0';
+ break;
+
+ default:
+ return MBGSERIO_INV_CFG; // invalid framing string
+ }
+ }
+
+ rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code,
+ data_bits, stop_bits, 8192, 1024 );
+ if ( rc < 0 )
+ return rc;
+
+ SetComTime( port_handle, 1.0 ); //##++
+ SetXMode( port_handle, 0 );
+ }
+ #elif defined( MBG_TGT_WIN32 )
+ {
+ DCB dcb;
+
+ dcb.DCBlength = sizeof( DCB ) ;
+ GetCommState( port_handle, &dcb ) ;
+ dcb.BaudRate = baud_rate;
+
+
+ // setup framing.
+ for ( cp = framing; *cp; cp++ )
+ {
+ char c = toupper( *cp );
+
+ switch ( c )
+ {
+ case '7':
+ case '8':
+ dcb.ByteSize = c - '0';
+ break;
+
+ case 'N':
+ dcb.Parity = NOPARITY;
+ break;
+
+ case 'E':
+ dcb.Parity = EVENPARITY;
+ break;
+
+ case 'O':
+ dcb.Parity = ODDPARITY;
+ break;
+
+ case '1':
+ dcb.StopBits = ONESTOPBIT;
+ break;
+
+ case '2':
+ dcb.StopBits = TWOSTOPBITS;
+ break;
+
+ default:
+ return MBGSERIO_INV_CFG; // invalid framing string
+ }
+ }
+
+
+ dcb.fOutxCtsFlow = FALSE; // CTS output flow control
+ dcb.fOutxDsrFlow = FALSE; // DSR output flow control
+ dcb.fDtrControl = DTR_CONTROL_ENABLE; // enable DTR for C28COM
+ dcb.fDsrSensitivity = FALSE; // don't require DSR input active
+ //##++ more missing here
+ dcb.fRtsControl = RTS_CONTROL_ENABLE; // enable RTS for C28COM
+ dcb.fOutX = FALSE;
+
+ SetCommState ( port_handle, &dcb );
+ }
+ #elif defined( MBG_TGT_UNIX )
+ {
+ tcflag_t c_cflag = 0;
+ struct termios tio;
+
+ tcgetattr( port_handle, &tio );
+
+ // setup transmission speed
+ switch( baud_rate )
+ {
+ case 300: c_cflag = B300; break;
+ case 600: c_cflag = B600; break;
+ case 1200: c_cflag = B1200; break;
+ case 2400: c_cflag = B2400; break;
+ case 4800: c_cflag = B4800; break;
+ case 9600: c_cflag = B9600; break;
+ case 19200: c_cflag = B19200; break;
+ case 38400: c_cflag = B38400; break;
+ case 57600: c_cflag = B57600; break;
+
+ default: return MBGSERIO_INV_CFG; // invalid
+ }
+
+ #if 0 //##++ This should be used preferably for portability reasons
+ int cfsetispeed( struct termios *termios_p, speed_t speed );
+ int cfsetospeed( struct termios *termios_p, speed_t speed );
+ #endif
+
+ // setup framing.
+ for ( cp = framing; *cp; cp++ )
+ {
+ switch ( _toupper( *cp ) )
+ {
+ case '7': c_cflag |= CS7; break;
+ case '8': c_cflag |= CS8; break;
+
+ case 'N': break;
+ case 'E': c_cflag |= PARENB; break;
+ case 'O': c_cflag |= PARENB | PARODD; break;
+
+ case '1': break;
+ case '2': c_cflag |= CSTOPB; break;
+
+ default: return MBGSERIO_INV_CFG; // invalid framing string
+ }
+ }
+
+
+ // Setup control flags. The following flags are defined:
+ // CBAUD (not in POSIX) Baud speed mask (4+1 bits).
+ // CBAUDEX (not in POSIX) Extra baud speed mask (1 bit), included in CBAUD.
+ // (POSIX says that the baud speed is stored in the termios structure
+ // without specifying where precisely, and provides cfgetispeed() and
+ // cfsetispeed() for getting at it. Some systems use bits selected
+ // by CBAUD in c_cflag, other systems use separate fields,
+ // e.g. sg_ispeed and sg_ospeed.)
+ // CSIZE Character size mask. Values are CS5, CS6, CS7, or CS8.
+ // CSTOPB Set two stop bits, rather than one.
+ // CREAD Enable receiver.
+ // PARENB Enable parity generation on output and parity checking for input.
+ // PARODD Parity for input and output is odd.
+ // HUPCL Lower modem control lines after last process closes the device (hang up).
+ // CLOCAL Ignore modem control lines.
+ // LOBLK (not in POSIX) Block output from a noncurrent shell layer.
+ // (For use by shl)
+ // CIBAUD (not in POSIX) Mask for input speeds. The values for the CIBAUD bits are
+ // the same as the values for the CBAUD bits, shifted left IBSHIFT bits.
+ // CRTSCTS (not in POSIX) Enable RTS/CTS (hardware) flow control.
+
+ // local connection, no modem control (CLOCAL)
+ // no flow control (no CRTSCTS)
+ // enable receiving
+ tio.c_cflag = c_cflag | CLOCAL | CREAD;
+
+
+ // Setup input flags. The following flags are defined:
+ // IGNBRK Ignore BREAK condition on input
+ // BRKINT If IGNBRK is set, a BREAK is ignored. If it is not set
+ // but BRKINT is set, then a BREAK causes the input and output
+ // queues to be flushed, and if the terminal is the controlling
+ // terminal of a foreground process group, it will cause a
+ // SIGINT to be sent to this foreground process group. When
+ // neither IGNBRK nor BRKINT are set, a BREAK reads as a NUL
+ // character, except when PARMRK is set, in which case it reads
+ // as the sequence \377 \0 \0.
+ // IGNPAR Ignore framing errors and parity errors.
+ // PARMRK If IGNPAR is not set, prefix a character with a parity error
+ // framing error with \377 \0. If neither IGNPAR nor PARMRK or
+ // is set, read a character with a parity error or framing error as \0.
+ // INPCK Enable input parity checking.
+ // ISTRIP Strip off eighth bit.
+ // INLCR Translate NL to CR on input.
+ // IGNCR Ignore carriage return on input.
+ // ICRNL Translate carriage return to newline on input (unless IGNCR is set).
+ // IUCLC (not in POSIX) Map uppercase characters to lowercase on input.
+ // IXON Enable XON/XOFF flow control on output.
+ // IXANY (not in POSIX.1; XSI) Enable any character to restart output.
+ // IXOFF Enable XON/XOFF flow control on input.
+ // IMAXBEL (not in POSIX) Ring bell when input queue is full. Linux does not
+ // implement this bit, and acts as if it is always set.
+ tio.c_iflag = 0;
+
+ #if 0 //##++
+ if ( c_cflag & PARENB )
+ tio.c_iflag |= IGNPAR; //##++ this also ignores framing errors
+ #endif
+
+
+ // Setup output flags. The following flags are defined:
+ // OPOST Enable implementation-defined output processing.
+ // The remaining c_oflag flag constants are defined in POSIX 1003.1-2001,
+ // unless marked otherwise.
+ // OLCUC (not in POSIX) Map lowercase characters to uppercase on output.
+ // ONLCR (XSI) Map NL to CR-NL on output.
+ // OCRNL Map CR to NL on output.
+ // ONOCR Don't output CR at column 0.
+ // ONLRET Don't output CR.
+ // OFILL Send fill characters for a delay, rather than using a timed delay.
+ // OFDEL (not in POSIX) Fill character is ASCII DEL (0177). If unset,
+ // fill character is ASCII NUL.
+ // NLDLY Newline delay mask. Values are NL0 and NL1.
+ // CRDLY Carriage return delay mask. Values are CR0, CR1, CR2, or CR3.
+ // TABDLY Horizontal tab delay mask. Values are TAB0, TAB1, TAB2, TAB3
+ // (or XTABS). A value of TAB3, that is, XTABS, expands tabs to
+ // spaces (with tab stops every eight columns).
+ // BSDLY Backspace delay mask. Values are BS0 or BS1.
+ // (Has never been implemented.)
+ // VTDLY Vertical tab delay mask. Values are VT0 or VT1.
+ // FFDLY Form feed delay mask. Values are FF0 or FF1.
+ tio.c_oflag = 0;
+
+
+ // Setup local mode flags. The following flags are defined:
+ // ISIG When any of the characters INTR, QUIT, SUSP, or DSUSP are
+ // received, generate the corresponding signal.
+ // ICANON Enable canonical mode. This enables the special characters
+ // EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, and
+ // WERASE, and buffers by lines.
+ // XCASE (not in POSIX; not supported under Linux) If ICANON is also
+ // set, terminal is uppercase only. Input is converted to
+ // lowercase, except for characters preceded by \. On output,
+ // uppercase characters are preceded by \ and lowercase
+ // characters are converted to uppercase.
+ // ECHO Echo input characters.
+ // ECHOE If ICANON is also set, the ERASE character erases the preceding
+ // input character, and WERASE erases the preceding word.
+ // ECHOK If ICANON is also set, the KILL character erases the current line.
+ // ECHONL If ICANON is also set, echo the NL character even if ECHO is not set.
+ // ECHOCTL (not in POSIX) If ECHO is also set, ASCII control signals
+ // other than TAB, NL, START, and STOP are echoed as ^X, where
+ // X is the character with ASCII code 0x40 greater than the control
+ // signal. For example, character 0x08 (BS) is echoed as ^H.
+ // ECHOPRT (not in POSIX) If ICANON and IECHO are also set, characters are
+ // printed as they are being erased.
+ // ECHOKE (not in POSIX) If ICANON is also set, KILL is echoed by erasing
+ // each character on the line, as specified by ECHOE and ECHOPRT.
+ // DEFECHO (not in POSIX) Echo only when a process is reading.
+ // FLUSHO (not in POSIX; not supported under Linux) Output is being flushed.
+ // This flag is toggled by typing the DISCARD character.
+ // NOFLSH Disable flushing the input and output queues when generating the
+ // SIGINT, SIGQUIT and SIGSUSP signals.
+ // TOSTOP Send the SIGTTOU signal to the process group of a background
+ // process which tries to write to its controlling terminal.
+ // PENDIN (not in POSIX; not supported under Linux) All characters in the
+ // input queue are reprinted when the next character is read.
+ // (bash handles typeahead this way.)
+ // IEXTEN Enable implementation-defined input processing. This flag, as
+ // well as ICANON must be enabled for the special characters EOL2,
+ // LNEXT, REPRINT, WERASE to be interpreted, and for the IUCLC flag
+ // to be effective.
+ tio.c_lflag = 0;
+
+
+ // VINTR (003, ETX, Ctrl-C, or also 0177, DEL, rubout) Interrupt character.
+ // Send a SIGINT signal. Recognized when ISIG is set, and then not
+ // passed as input.
+ // VQUIT (034, FS, Ctrl-\) Quit character. Send SIGQUIT signal. Recognized
+ // when ISIG is set, and then not passed as input.
+ // VERASE (0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) Erase character.
+ // This erases the previous not-yet-erased character, but does not erase
+ // past EOF or beginning-of-line. Recognized when ICANON is set,
+ // and then not passed as input.
+ // VKILL (025, NAK, Ctrl-U, or Ctrl-X, or also @) Kill character. This erases
+ // the input since the last EOF or beginning-of-line. Recognized when
+ // ICANON is set, and then not passed as input.
+ // VEOF (004, EOT, Ctrl-D) End-of-file character. More precisely: this
+ // character causes the pending tty buffer to be sent to the waiting
+ // user program without waiting for end-of-line. If it is the first
+ // character of the line, the read() in the user program returns 0,
+ // which signifies end-of-file. Recognized when ICANON is set, and
+ // then not passed as input.
+ // VMIN Minimum number of characters for non-canonical read.
+ // VEOL (0, NUL) Additional end-of-line character. Recognized when ICANON is set.
+ // VTIME Timeout in deciseconds for non-canonical read.
+ // VEOL2 (not in POSIX; 0, NUL) Yet another end-of-line character.
+ // Recognized when ICANON is set.
+ // VSWTCH (not in POSIX; not supported under Linux; 0, NUL) Switch character.
+ // (Used by shl only.)
+ // VSTART (021, DC1, Ctrl-Q) Start character. Restarts output stopped by the Stop
+ // character. Recognized when IXON is set, and then not passed as input.
+ // VSTOP (023, DC3, Ctrl-S) Stop character. Stop output until Start character
+ // typed. Recognized when IXON is set, and then not passed as input.
+ // VSUSP (032, SUB, Ctrl-Z) Suspend character. Send SIGTSTP signal. Recognized
+ // when ISIG is set, and then not passed as input.
+ // VDSUSP (not in POSIX; not supported under Linux; 031, EM, Ctrl-Y) Delayed
+ // suspend character: send SIGTSTP signal when the character is read by
+ // the user program. Recognized when IEXTEN and ISIG are set, and the
+ // system supports job control, and then not passed as input.
+ // VLNEXT (not in POSIX; 026, SYN, Ctrl-V) Literal next. Quotes the next input
+ // character, depriving it of a possible special meaning. Recognized
+ // when IEXTEN is set, and then not passed as input.
+ // VWERASE (not in POSIX; 027, ETB, Ctrl-W) Word erase. Recognized when ICANON
+ // and IEXTEN are set, and then not passed as input.
+ // VREPRINT (not in POSIX; 022, DC2, Ctrl-R) Reprint unread characters. Recognized
+ // when ICANON and IEXTEN are set, and then not passed as input.
+ // VDISCARD (not in POSIX; not supported under Linux; 017, SI, Ctrl-O) Toggle:
+ // start/stop discarding pending output. Recognized when IEXTEN is set,
+ // and then not passed as input.
+ // VSTATUS (not in POSIX; not supported under Linux; status request: 024, DC4, Ctrl-T).
+
+
+ // Setting up c_cc[VMIN] and c_cc[VTIME]:
+ // If MIN > 0 and TIME = 0, MIN sets the number of characters to receive before
+ // the read is satisfied. As TIME is zero, the timer is not used.
+ // If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will be
+ // satisfied if a single character is read, or TIME is exceeded
+ // (t = TIME *0.1 s). If TIME is exceeded, no character will be
+ // returned.
+ // If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The
+ // read will be satisfied if MIN characters are received, or the
+ // time between two characters exceeds TIME. The timer is restarted
+ // every time a character is received and only becomes active after
+ // the first character has been received.
+ // If MIN = 0 and TIME = 0, read will be satisfied immediately. The number of
+ // characters currently available, or the number of characters
+ // requested will be returned. You could issue a
+ // fcntl(fd, F_SETFL, FNDELAY); before reading to get the same result.
+
+ // setup control characters for non-blocking read
+ tio.c_cc[VMIN] = 0;
+ tio.c_cc[VTIME] = 0;
+
+ // now clean the modem line and activate the settings for modem
+ tcflush( port_handle, TCIFLUSH );
+ tcsetattr( port_handle, TCSANOW, &tio );
+
+ fflush( stdout );
+ setvbuf( stdout, NULL, _IONBF, 0 );
+ }
+ #elif defined( MBG_TGT_DOS )
+ #if defined( _USE_V24TOOLS )
+ {
+ int datab = 8;
+ char parity = 'N';
+ int stopb = 1;
+
+ // setup framing.
+ for ( cp = framing; *cp; cp++ )
+ {
+ char c = toupper( *cp );
+
+ switch ( c )
+ {
+ case '7':
+ case '8':
+ datab = c - '0';
+ break;
+
+ case 'N':
+ case 'E':
+ case 'O':
+ parity = *cp;
+ break;
+
+ case '1':
+ case '2':
+ stopb = c - '0';
+ break;
+
+ default:
+ return MBGSERIO_INV_CFG; // invalid framing string
+ }
+ }
+
+ v24setparams( port_handle, baud_rate, datab, parity, stopb );
+ }
+ #else
+
+ #error This has to be modified for DOS without v24tools.
+
+ #endif
+
+ #else
+
+ #error This target OS is not supported.
+
+ #endif
+
+ return 0;
+
+} // mbgserio_set_parms
+
+
+
+#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI )
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, unsigned int count )
+{
+ BOOL fReadStat;
+ COMSTAT ComStat;
+ DWORD dwErrorFlags;
+ DWORD dwLength;
+
+ ClearCommError( h, &dwErrorFlags, &ComStat );
+
+ if ( dwErrorFlags ) // transmission error (parity, framing, etc.)
+ return MBGSERIO_FAIL;
+
+
+ dwLength = min( (DWORD) count, ComStat.cbInQue );
+
+ if ( dwLength )
+ {
+ fReadStat = ReadFile( h, buffer, dwLength, &dwLength, NULL );
+
+ if ( !fReadStat )
+ return MBGSERIO_FAIL;
+ }
+
+ return dwLength;
+
+} // mbgserio_read
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count )
+{
+ BOOL fWriteStat;
+ COMSTAT ComStat;
+ DWORD dwErrorFlags;
+ DWORD dwThisBytesWritten;
+ DWORD dwTotalBytesWritten = 0;
+
+ while ( dwTotalBytesWritten < (DWORD) count )
+ {
+ dwThisBytesWritten = 0;
+
+ fWriteStat = WriteFile( h, ( (char *) buffer ) + dwTotalBytesWritten,
+ count - dwTotalBytesWritten,
+ &dwThisBytesWritten, NULL );
+ if ( !fWriteStat )
+ {
+ #if defined( _DEBUG )
+ DWORD dw = GetLastError();
+ #endif
+ break; //##++ Error: Unable to write
+ }
+
+ dwTotalBytesWritten += dwThisBytesWritten;
+
+ ClearCommError( h, &dwErrorFlags, &ComStat );
+
+ if ( dwErrorFlags )
+ break; //#++ Error: Check flags
+ }
+
+ return dwTotalBytesWritten;
+
+} // mbgserio_write
+
+#endif // defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI )
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
+ uint count, ulong char_timeout )
+{
+ int n_bytes;
+
+ #if _USE_SELECT_FOR_SERIAL_IO
+
+ struct timeval tv_char_timeout;
+ fd_set fds;
+ int rc;
+
+ mbgserio_msec_to_timeval( char_timeout, &tv_char_timeout );
+
+ FD_ZERO( &fds );
+ FD_SET( h, &fds );
+
+ rc = select( h + 1, &fds, NULL, NULL, &tv_char_timeout );
+
+ if ( rc < 0 ) // error
+ goto fail;
+
+ if ( rc == 0 ) // timeout
+ goto timeout;
+
+ // data is available
+ n_bytes = _mbgserio_read( h, buffer, count );
+
+ #else
+ MBG_TMO_TIME tmo;
+
+ mbg_tmo_set_timeout_ms( &tmo, char_timeout );
+
+ for (;;) // wait to read one new char
+ {
+ n_bytes = _mbgserio_read( h, buffer, count );
+
+ if ( n_bytes > 0 ) // new char(s) received
+ break;
+
+ if ( n_bytes < 0 ) // error
+ goto fail;
+
+ if ( mbg_tmo_curr_time_is_after( &tmo ) )
+ goto timeout;
+
+ #if defined( MBG_TGT_UNIX )
+ usleep( 10 * 1000 );
+ #endif
+ }
+ #endif
+
+ return n_bytes;
+
+timeout:
+ return MBGSERIO_TIMEOUT;
+
+fail:
+ return MBGSERIO_FAIL;
+
+} // mbgserio_read_wait
+
+
+
diff --git a/mbglib/common/mbgserio.h b/mbglib/common/mbgserio.h
new file mode 100644
index 0000000..28afa96
--- /dev/null
+++ b/mbglib/common/mbgserio.h
@@ -0,0 +1,213 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgserio.h 1.4 2009/09/01 10:54:29Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for mbgserio.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgserio.h $
+ * Revision 1.4 2009/09/01 10:54:29Z martin
+ * Include mbg_tmo.h for the new portable timeout functions.
+ * Added symbols for return codes in case of an error.
+ * Code cleanup.
+ * Revision 1.3 2009/04/01 14:17:31 martin
+ * Cleanup for CVI.
+ * Revision 1.2 2008/09/04 15:11:36Z martin
+ * Preliminary support for device lists.
+ * Updated function prototypes.
+ * Revision 1.1 2007/11/12 16:48:02 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBGSERIO_H
+#define _MBGSERIO_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tmo.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined( MBG_TGT_UNIX )
+ #include <termios.h>
+#endif
+
+#if _USE_CHK_TSTR
+ #include <chk_tstr.h>
+#endif
+
+#if !defined( _USE_SELECT_FOR_SERIAL_IO )
+ #if defined( MBG_TGT_UNIX )
+ #define _USE_SELECT_FOR_SERIAL_IO 1
+ #else
+ #define _USE_SELECT_FOR_SERIAL_IO 0
+ #endif
+#endif
+
+
+#ifdef _MBGSERIO
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#define MBGSERIO_FAIL -1 // Generic I/O error
+#define MBGSERIO_TIMEOUT -2 // timeout
+#define MBGSERIO_INV_CFG -3 // invalid configuration parameters
+
+
+#if !defined( DEFAULT_DEV_NAME )
+ #if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS )
+ #define DEFAULT_DEV_NAME "COM1"
+ #elif defined( MBG_TGT_LINUX )
+ #define DEFAULT_DEV_NAME "/dev/ttyS0"
+ #endif
+#endif
+
+
+/*
+ * The following macros control parts of the build process.
+ * The default values are suitable for most cases but can be
+ * overridden by global definitions, if required.
+ */
+
+#if _IS_MBG_FIRMWARE
+
+ // This handle type in not used by the firmware.
+ // However, we define it to avoid build errors.
+ typedef int MBG_HANDLE;
+
+#else
+
+ #if defined( MBG_TGT_CVI )
+
+ #include <rs232.h>
+
+ #define _mbg_open _open
+ #define _mbg_close _close
+ #define _mbg_read _read
+ #define _mbg_write _write
+
+ #define _mbgserio_write( _dh, _p, _sz ) \
+ ComWrt( _dh, (char *) (_p), _sz )
+
+ #define _mbgserio_read( _dh, _p, _sz ) \
+ ComRd( _dh, (char *) (_p), _sz )
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #include <windows.h>
+ #include <io.h>
+
+ #define _mbg_open _open
+ #define _mbg_close _close
+ #define _mbg_read _read
+ #define _mbg_write _write
+
+ #define _mbgserio_write mbgserio_write
+ #define _mbgserio_read mbgserio_read
+
+ #elif defined( MBG_TGT_UNIX )
+
+ #include <unistd.h>
+
+ #define _mbg_open open
+ #define _mbg_close close
+ #define _mbg_read read
+ #define _mbg_write write
+
+ #elif defined( MBG_TGT_DOS )
+
+ #if defined( _USE_V24TOOLS )
+ #include <v24tools.h>
+
+ #define _mbgserio_open v24open
+ #define _mbgserio_read v24read
+ #define _mbgserio_write v24write
+ #endif
+
+ #endif
+
+ #if !defined( _mbgserio_open )
+ #define _mbgserio_open _mbg_open
+ #endif
+ #if !defined( _mbgserio_write )
+ #define _mbgserio_write _mbg_write
+ #endif
+ #if !defined( _mbgserio_read )
+ #define _mbgserio_read _mbg_read
+ #endif
+
+#endif
+
+
+
+typedef struct _MBG_STR_LIST
+{
+ char *s;
+ struct _MBG_STR_LIST *next;
+
+} MBG_STR_LIST;
+
+
+
+typedef struct
+{
+ MBG_PORT_HANDLE port_handle; // the handle that will be used for the device
+
+ #if defined( MBG_TGT_WIN32 )
+ DCB old_dcb;
+ COMMTIMEOUTS old_commtimeouts;
+ #endif
+ #if defined( MBG_TGT_UNIX )
+ struct termios oldtio;
+ //##++ struct termios newtio;
+ #endif
+
+} SERIAL_IO_STATUS;
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ _MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, int max_devs ) ;
+ _MBG_API_ATTR void _MBG_API _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, uint32_t baud_rate, const char *framing ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, unsigned int count ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count ) ;
+ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer, uint count, ulong char_timeout ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGSERIO_H */
diff --git a/mbglib/common/pcpsdefs.h b/mbglib/common/pcpsdefs.h
new file mode 100644
index 0000000..c30bffd
--- /dev/null
+++ b/mbglib/common/pcpsdefs.h
@@ -0,0 +1,1273 @@
+
+/**************************************************************************
+ *
+ * $Id: pcpsdefs.h 1.46 2011/01/13 11:44:29Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * General definitions for Meinberg plug-in radio clocks
+ *
+ * -----------------------------------------------------------------------
+ * $Log: pcpsdefs.h $
+ * Revision 1.46 2011/01/13 11:44:29Z martin
+ * Moved status port register definitions here.
+ * Revision 1.45 2010/09/06 07:36:24 martin
+ * Support GPS180PEX and TCR180PEX.
+ * Moved some IRIG related definitions to gpsdefs.h.
+ * Revision 1.44 2010/06/30 11:09:49 martin
+ * Added definitions for JJY longwave transmitter.
+ * Renamed MBG_RAW_IRIG_DATA::data field to data_bytes
+ * since "data" is a reserved word for C51 architecture.
+ * Revision 1.43 2010/02/09 11:20:17Z martin
+ * Renamed yet unused CORR_INFO::flags field to signal and updated comments.
+ * Revision 1.42 2010/01/12 14:02:37 daniel
+ * Added definitions to support reading the raw IRIG data bits.
+ * Revision 1.41 2009/06/19 12:16:42Z martin
+ * Added PCPS_GIVE_IRIG_TIME command and associated definitions.
+ * Revision 1.40 2009/06/08 19:29:11 daniel
+ * Support PTP configuration.
+ * Support LAN_IF configuration
+ * Added definition of PCPS_CMD_INFO.
+ * Revision 1.39 2009/03/19 08:58:09 martin
+ * Added PCPS_GET_IRIG_CTRL_BITS cmd and associated data type.
+ * Revision 1.38 2009/03/10 17:07:09 martin
+ * Support configurable time scales and GPS UTC parameters.
+ * Added ext. status flag for time scales, and PCPS_LS_ANN_NEG.
+ * Added bit mask PCPS_SCALE_MASK.
+ * Revision 1.37 2008/12/05 16:01:37Z martin
+ * Added ref types PTP, FRC, and WWVB.
+ * Added ref names MSF, PTP, FRC, and WWVB.
+ * Added device codes TCR170PEX, PTP270PEX, and FRC511PEX.
+ * Added macros to convert the endianess of structures.
+ * Moved definitions of PCPS_HRT_FRAC_SCALE and
+ * PCPS_HRT_FRAC_SCALE_FMT here.
+ * Added definitions of PCPS_HRT_FRAC_CONVERSION_TYPE
+ * and PCPS_HRT_BIN_FRAC_SCALE.
+ * Escaped '<' and '>' characters for doxygen.
+ * Modified comments for PCPS_TZDL.
+ * Removed trailing spaces and obsolete comments.
+ * Revision 1.36 2008/01/17 09:20:25Z daniel
+ * Added new REF type PCPS_REF_MSF.
+ * Revision 1.35 2008/01/17 09:18:46Z daniel
+ * Made comments compatible for doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.34 2007/07/17 08:22:47Z martin
+ * Added support for TCR511PEX and GPS170PEX.
+ * Revision 1.33 2007/05/20 21:39:51Z martin
+ * Added support for PEX511.
+ * Added PCPS_GET_STATUS_PORT cmd code for devices
+ * that do not support a hardware status port.
+ * Revision 1.32 2007/03/29 12:57:32Z martin
+ * Renamed some TZCODE numbers for unique naming conventions.
+ * Added definitions of the older symbols for compatibility.
+ * Revision 1.31 2007/03/26 15:42:31Z martin
+ * Replaced PCPS_REF_OFFS and associated definitions by MBG_REF_OFFS, etc.,
+ * which are defined in gpsdefs.h.
+ * Added PCPS_GET_DEBUG_STATUS code.
+ * Revision 1.30 2006/06/29 10:13:13 martin
+ * Added some descriptive comments.
+ * Revision 1.29 2006/06/14 12:59:12Z martin
+ * Added support for TCR511PCI.
+ * Revision 1.28 2006/05/18 09:45:16 martin
+ * Added data types used with PZF receivers.
+ * Revision 1.27 2006/05/03 10:19:14Z martin
+ * Added initializers for reference source names.
+ * Revision 1.26 2006/03/10 10:24:45Z martin
+ * New definitions for PCI511.
+ * Added command codes to configure programmable pulse outputs.
+ * Revision 1.25 2005/11/03 15:05:16Z martin
+ * New definitions for GPS170PCI.
+ * New types PCPS_TIME_STATUS and PCPS_TIME_STATUS_X.
+ * Removed obsolete enumeration of PCPS_TIME fields.
+ * Revision 1.24 2005/05/03 07:56:55Z martin
+ * Added command PCPS_GET_SYNTH_STATE.
+ * Revision 1.23 2005/03/29 12:51:10Z martin
+ * New cmd code PCPS_GENERIC_IO.
+ * Revision 1.22 2004/12/09 11:03:37Z martin
+ * Support configuration of on-board frequency synthesizer.
+ * Revision 1.21 2004/11/09 12:55:32Z martin
+ * Redefined interface data types using C99 fixed-size definitions.
+ * Added workaround macros for some structure sizes because the C166
+ * compiler always reports an even structure size even if the structure
+ * size is in fact odd, which might lead to different sizes in C166 and
+ * other environments.
+ * Modifications were required in order to be able to configure IRIG
+ * settings of cards which provide both IRIG input and output.
+ * The existing codes have been renamed with .._RX.. and are used to
+ * configure the IRIG receiver (input). New codes have been defined
+ * used to configure the IRIG transmitter.
+ * Renamed PC_GPS_STAT to PC_GPS_BVAR_STAT.
+ * Use more specific data types than generic types.
+ * Revision 1.20 2004/10/14 15:01:23 martin
+ * Added support for TCR167PCI.
+ * Revision 1.19 2004/06/16 12:46:33Z martin
+ * Moved OPT_SETTINGS related definitions to gpsdefs.h,
+ * and renamed symbols from PCPS_.. to to MBG_...
+ * Revision 1.18 2004/04/26 14:27:08Z martin
+ * Added union PCPS_TIME_UNION.
+ * Revision 1.17 2003/05/27 08:50:35Z MARTIN
+ * New commands PCPS_GIVE_UCAP_ENTRIES, PCPS_GIVE_UCAP_EVENT
+ * and associated definitions which allow faster reading of
+ * user capture events and monitoring of the capture buffer
+ * fill level.
+ * Revision 1.16 2003/04/03 10:48:53 martin
+ * Support for PCI510, GPS169PCI, and TCR510PCI.
+ * New codes PCPS_GET_REF_OFFS, PCPS_SET_REF_OFFS
+ * and related structures.
+ * New codes PCPS_GET_OPT_INFO, PCPS_SET_OPT_SETTINGS
+ * and related structures.
+ * New codes PCPS_GET_IRIG_INFO, PCPS_SET_IRIG_SETTINGS.
+ * Preliminary PCPS_TZDL structure and cmd codes
+ * to read/write that structure.
+ * Revision 1.15 2002/08/08 13:24:03 MARTIN
+ * Moved definition of ref time sources here.
+ * Added new ref time source IRIG.
+ * Added new cmd to clear time capture buffer.
+ * Fixed some comments.
+ * Revision 1.14 2002/01/31 13:39:38 MARTIN
+ * Added new GPS data type codes for RECEIVER_INFO, etc.
+ * New PCPS_HR_TIME status flag PCPS_IO_BLOCKED.
+ * Moved REV_NUMs defining special features to pcpsdev.h.
+ * Removed obsolete initializer for framing string table.
+ * Updated some comments.
+ * Removed obsolete code.
+ * Revision 1.13 2001/12/03 16:15:14 martin
+ * Introduced PCPS_TIME_STAMP which allows to handle high precision
+ * time stamps.
+ * Replaced the sec/frac fields in PCPS_HR_TIME by PCPS_TIME_STAMP.
+ * This is compatible on byte level but may require source code
+ * modifications.
+ * Introduced new command PCPS_SET_EVENT_TIME which is used
+ * EXCLUSIVELY with a custom GPS firmware.
+ * Revision 1.12 2001/10/16 10:07:42 MARTIN
+ * Defined PCI509 firmware revision number which supports
+ * baud rate higher than standard.
+ * Revision 1.11 2001/03/30 13:02:39 MARTIN
+ * Control alignment of structures from new file use_pack.h.
+ * Defined initializers with valid framing parameters.
+ * Revision 1.10 2001/02/28 15:39:25 MARTIN
+ * Modified preprocessor syntax.
+ * Revision 1.9 2001/02/16 11:32:05 MARTIN
+ * Renamed "PROM" or "EPROM" in comments or and names to
+ * "FW" or firmware.
+ * This includes the cmd codes PCPS_GIVE_PROM_ID_... which have
+ * been renamed to PCPS_GIVE_FW_ID_...
+ * Renamed structure PCPS_TIME_SET to PCPS_STIME.
+ * Renamed return code PCPS_ERR_NONE to PCPS_SUCCESS.
+ * Modified some comments.
+ * Revision 1.8 2000/10/11 09:17:09 MARTIN
+ * Cleaned up comment syntax.
+ * Revision 1.7 2000/07/21 14:16:30 MARTIN
+ * Modified some comments.
+ * Added PCI definitions.
+ * Renamed PCPS_GET_GPS_DATA to PCPS_READ_GPS_DATA.
+ * Renamed PCPS_SET_GPS_DATA to PCPS_WRITE_GPS_DATA.
+ * New types PCPS_SERIAL and PCPS_TZCODE.
+ * Removed PCPS_SERIAL_BYTES and PCPS_TZCODE_BYTES, may use sizeof()
+ * the types instead.
+ * New type PCPS_TIME_SET which can be used to write date and time
+ * to the clock.
+ * Revision 1.6 2000/06/07 12:09:31 MARTIN
+ * renamed PCPS_SERIAL_GROUP to PCPS_CFG_GROUP
+ * renamed PCPS_ERR_SERIAL to PCPS_ERR_CFG
+ * modified definitions for baud rate, framing, and mode
+ * added PCPS_SN_... definitions
+ * added PCPS_GET_TZCODE and PCPS_SET_TZCODE definitions
+ * added PC_GPS_ANT_CABLE_LEN definition
+ * added RCS keywords
+ * updated some comments
+ *
+ * -----------------------------------------------------------------------
+ * Changes before put under RCS control:
+ *
+ * Revision 1.5 2000/03/24
+ * Introduced PCPS_GIVE_SERNUM
+ * Cleaned up for definitions for serial parameter byte
+ * Reviewed and updated comments.
+ *
+ * 1998/07/22
+ * Introduced PCPS_HR_TIME.
+ * Rearranged order of definitions.
+ * Reviewed and updated comments.
+ *
+ * 1997/06/12
+ * GPS definitions added.
+ *
+ * 1996/01/25
+ * PCPS_TIME redefined from an array of bytes to a structure.
+ *
+ **************************************************************************/
+
+#ifndef _PCPSDEFS_H
+#define _PCPSDEFS_H
+
+
+/* Other headers to be included */
+
+#include <words.h>
+#include <use_pack.h>
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+/**
+ * The following codes enumerate the ref time sources
+ * from which the clocks receive the reference time.
+ */
+enum
+{
+ PCPS_REF_NONE, /**< (unknown or not defined) */
+ PCPS_REF_DCF, /**< see http://www.meinberg.de/english/info/dcf77.htm */
+ PCPS_REF_GPS, /**< see http://www.meinberg.de/english/info/gps.htm */
+ PCPS_REF_IRIG, /**< see http://www.meinberg.de/english/info/irig.htm */
+ PCPS_REF_MSF, /**< MSF Receiver (UK) */
+ PCPS_REF_PTP, /**< PTP Timestamp card */
+ PCPS_REF_FRC, /**< Free Running Clock */
+ PCPS_REF_WWVB, /**< WWVB Receiver (US) */
+ PCPS_REF_JJY, /**< JJY Receiver (Japan) */
+ N_PCPS_REF /**< number of valid ref time sources */
+};
+
+
+/* Initializers for the reference source names */
+
+#define PCPS_REF_NAME_NONE_ENG "unknown"
+#define PCPS_REF_NAME_NONE_GER "nicht bekannt"
+#define PCPS_REF_NAME_DCF "DCF77"
+#define PCPS_REF_NAME_GPS "GPS"
+#define PCPS_REF_NAME_IRIG "IRIG"
+#define PCPS_REF_NAME_MSF "MSF"
+#define PCPS_REF_NAME_PTP "PTP"
+#define PCPS_REF_NAME_FRC "FRC"
+#define PCPS_REF_NAME_WWVB "WWVB"
+#define PCPS_REF_NAME_JJY "JJY"
+
+
+#define PCPS_REF_NAMES_ENG \
+{ \
+ PCPS_REF_NAME_NONE_ENG, \
+ PCPS_REF_NAME_DCF, \
+ PCPS_REF_NAME_GPS, \
+ PCPS_REF_NAME_IRIG, \
+ PCPS_REF_NAME_MSF, \
+ PCPS_REF_NAME_PTP, \
+ PCPS_REF_NAME_FRC, \
+ PCPS_REF_NAME_WWVB, \
+ PCPS_REF_NAME_JJY \
+}
+
+
+#define PCPS_REF_NAMES_LSTR \
+{ \
+ { PCPS_REF_NAME_NONE_ENG, PCPS_REF_NAME_NONE_GER }, \
+ { PCPS_REF_NAME_DCF, NULL }, \
+ { PCPS_REF_NAME_GPS, NULL }, \
+ { PCPS_REF_NAME_IRIG, NULL }, \
+ { PCPS_REF_NAME_MSF, NULL }, \
+ { PCPS_REF_NAME_PTP, NULL }, \
+ { PCPS_REF_NAME_FRC, NULL }, \
+ { PCPS_REF_NAME_WWVB, NULL }, \
+ { PCPS_REF_NAME_JJY, NULL } \
+}
+
+
+
+/**
+ PCI vendor ID number (assigned by PCI SIG)
+*/
+#define PCI_VENDOR_MEINBERG 0x1360
+
+/* PCI device ID numbers (assigned by Meinberg) *
+ * High byte: type of ref time source
+ * Low Byte: enumeration of device types
+ */
+#define PCI_DEV_PCI32 ( ( PCPS_REF_DCF << 8 ) | 0x01 )
+#define PCI_DEV_PCI509 ( ( PCPS_REF_DCF << 8 ) | 0x02 )
+#define PCI_DEV_PCI510 ( ( PCPS_REF_DCF << 8 ) | 0x03 )
+#define PCI_DEV_PCI511 ( ( PCPS_REF_DCF << 8 ) | 0x04 )
+#define PCI_DEV_PEX511 ( ( PCPS_REF_DCF << 8 ) | 0x05 )
+
+#define PCI_DEV_GPS167PCI ( ( PCPS_REF_GPS << 8 ) | 0x01 )
+#define PCI_DEV_GPS168PCI ( ( PCPS_REF_GPS << 8 ) | 0x02 )
+#define PCI_DEV_GPS169PCI ( ( PCPS_REF_GPS << 8 ) | 0x03 )
+#define PCI_DEV_GPS170PCI ( ( PCPS_REF_GPS << 8 ) | 0x04 )
+#define PCI_DEV_GPS170PEX ( ( PCPS_REF_GPS << 8 ) | 0x05 )
+#define PCI_DEV_GPS180PEX ( ( PCPS_REF_GPS << 8 ) | 0x06 )
+
+#define PCI_DEV_TCR510PCI ( ( PCPS_REF_IRIG << 8 ) | 0x01 )
+#define PCI_DEV_TCR167PCI ( ( PCPS_REF_IRIG << 8 ) | 0x02 )
+#define PCI_DEV_TCR511PCI ( ( PCPS_REF_IRIG << 8 ) | 0x03 )
+#define PCI_DEV_TCR511PEX ( ( PCPS_REF_IRIG << 8 ) | 0x04 )
+#define PCI_DEV_TCR170PEX ( ( PCPS_REF_IRIG << 8 ) | 0x05 )
+#define PCI_DEV_TCR180PEX ( ( PCPS_REF_IRIG << 8 ) | 0x06 )
+
+#define PCI_DEV_PTP270PEX ( ( PCPS_REF_PTP << 8 ) | 0x01 )
+
+#define PCI_DEV_FRC511PEX ( ( PCPS_REF_FRC << 8 ) | 0x01 )
+
+
+
+// definitions used for the status port register
+// (not to be intermixed with PCPS_TIME_STATUS)
+typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */
+
+/** @defgroup group_status_port Bit masks of PCPS_STATUS_PORT
+
+ Bit definitions used with the #PCPS_STATUS_PORT register.
+
+ The flags #PCPS_ST_SEC and #PCPS_ST_MIN are cleared whenever the clock
+ is read, so they are not very reliable in multitasking environments.
+
+ <b>NOTE</b>: The PCPS_ST_IRQF flag originates from old ISA cards.
+ Some PCI cards also support this, but in case of PCI cards the
+ associated flag of the PCI interface chip should be checked to see
+ if a certain card has generated an IRQ on the PC bus.
+
+ The macro _pcps_ddev_has_gen_irq() cares about this and should be used
+ to determine in a portable way whether a card has generated an IRQ.
+
+ * @{
+ */
+
+#define PCPS_ST_BUSY 0x01 /**< the clock is busy filling the output FIFO */
+#define PCPS_ST_IRQF 0x02 /**< the clock has generated an IRQ on the PC bus (ISA only)*/
+#define PCPS_ST_MOD 0x20 /**< the raw demodulated DCF77 signal */
+#define PCPS_ST_SEC 0x40 /**< seconds have changed since last reading */
+#define PCPS_ST_MIN 0x80 /**< minutes have changed since last reading */
+
+/** @} */
+
+
+
+/** @defgroup group_cmd_bytes Command bytes used to access the device
+
+ The commands described below can be used to access the Meinberg
+ computer peripherals. However, some of the commands have not been
+ implemented with older clock models, or firmware versions.
+
+ The device driver library contains functions which detect the clocks
+ and check which features are supported by a given clock model/firmware
+ The header files pcpsdev.h and pcpsdrvr.h contain macros which can be
+ used to query whether a detected clock supports a feature.
+ If checking is required, the name of the macro is given in the
+ comments below.
+
+ Some commands expect parameters to be passed to the board. In that
+ case, the board returns the number of parameter bytes expected when
+ the command code is passed. Every parameter byte has to be supplied
+ to the board exactly like a command byte.
+ Refer to function pcps_write_data() and the macro _pcps_write_var()
+ for details.
+
+
+ - #PCPS_GIVE_TIME<br>
+ Return a PCPS_TIME structure with current date,
+ time and status. Supported by all clocks.
+
+ - #PCPS_GIVE_TIME_NOCLEAR<br>
+ Same as #PCPS_GIVE_TIME but the bits #PCPS_ST_SEC
+ and #PCPS_ST_MIN (see pcpsdev.h) of the status
+ port are not cleared.
+ Supported by all clocks except PC31/PS31 with
+ firmware version older than v3.0.
+ This is mainly used by the DOS TSR and should
+ not be used in other environments.
+
+ - #PCPS_GIVE_SYNC_TIME<br>
+ Return a ::PCPS_TIME structure with date and time
+ of last synchronization of the clock or
+ the last time set via the interface.
+ _pcps_has_sync_time() checks whether supported.
+
+ - #PCPS_GIVE_HR_TIME<br>
+ Return a PCPS_HR_TIME structure with current
+ date, time and status. This command should be
+ used to read the clock with higher resolution.
+ _pcps_has_hr_time() checks whether supported.
+
+ - #PCPS_GIVE_IRIG_TIME<br>
+ Return a PCPS_IRIG_TIME structure with day-of-year,
+ time and status as decoded from the IRIG signal.
+ _pcps_has_irig_time() checks whether supported.
+
+ - #PCPS_SET_TIME<br>
+ Set the board date, time and status. This
+ command expects sizeof( ::PCPS_STIME ) parameter
+ bytes.
+ _pcps_can_set_time() checks whether supported.
+
+ - #PCPS_SET_EVENT_TIME<br>
+ Send a high resolution time stamp to the clock to
+ configure a UTC time when the clock shall generate
+ some event. This command expects a PCPS_TIME_STAMP
+ parameter.
+ _pcps_has_event_time() checks whether supported.
+ (requires custom GPS CERN firmware)
+
+ - #PCPS_IRQ_NONE<br>
+ Disable the board's hardware IRQ<br>
+ - #PCPS_IRQ_1_SEC<br>
+ Enable hardware IRQs once per second<br>
+ - #PCPS_IRQ_1_MIN<br>
+ Enable hardware IRQs once per minute<br>
+ - #PCPS_IRQ_10_MIN<br>
+ Enable hardware IRQs once per 10 minutes<br>
+ - #PCPS_IRQ_30_MIN<br>
+ Enable hardware IRQs once per 30 minutes<br>
+
+ - #PCPS_GET_SERIAL<br>
+ #PCPS_SET_SERIAL<br>
+ These commands read or set the configuration
+ of a clock's serial port COM0. The commands
+ expect PCPS_SERIAL_BYTES parameter bytes and
+ should be used preferably with the DCF77
+ clocks which have only one COM port.
+ _pcps_has_serial() checks whether supported.
+ Recent GPS clocks' COM ports should be cfg'd
+ using the structures RECEIVER_INFO, PORT_INFO,
+ and STR_TYPE_INFO.
+ _pcps_has_receiver_info() checks whether
+ these are supported. If they are not, then
+ the code #PC_GPS_PORT_PARM together with the
+ #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
+ commands should be used.
+
+ - #PCPS_GET_TZCODE<br>
+ #PCPS_SET_TZCODE<br>
+ These commands read or set a DCF77 clock's
+ time zone code and should be used preferably
+ with the newer DCF77 clocks which have limited
+ support of different time zones.
+ _pcps_has_tzcode() checks whether supported.
+ A GPS clock's time zone must be cfg'd using
+ the code #PC_GPS_TZDL together with the
+ #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
+ commands.
+
+ - #PCPS_GET_PCPS_TZDL<br>
+ #PCPS_SET_PCPS_TZDL<br>
+ These commands read or set a DCF77 clock's
+ time zone / daylight saving configuration.
+ _pcps_has_pcps_tzdl() checks whether supported.
+ A GPS clock's time zone must be cfg'd using
+ the code #PC_GPS_TZDL together with the
+ #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
+ commands.
+
+ - #PCPS_GET_REF_OFFS<br>
+ #PCPS_SET_REF_OFFS<br>
+ These commands can be used to configure the
+ reference time offset from UTC for clocks
+ which can't determine the offset automatically,
+ e.g. from an IRIG input signal.
+ _pcps_has_ref_offs() checks whether supported.
+
+ - #PCPS_GET_OPT_INFO<br>
+ #PCPS_SET_OPT_SETTINGS<br>
+ These commands can be used to configure some
+ optional settings, controlled by flags.
+ When reading, the clock returns a MBG_OPT_INFO
+ structure which contains the supported values,
+ plus the current settings.
+ When writing, clocks accepts a MBG_OPT_SETTINGS
+ structure only which contain the desired settings
+ of the supported flags only.
+ _pcps_has_opt_flags() checks whether supported.
+
+ - #PCPS_GET_IRIG_RX_INFO<br>
+ #PCPS_SET_IRIG_RX_SETTINGS<br>
+ #PCPS_GET_IRIG_TX_INFO<br>
+ #PCPS_SET_IRIG_TX_SETTINGS<br>
+ These commands can be used to configure IRIG
+ inputs and outputs.<br>
+ When reading, the clock returns an IRIG_INFO
+ structure which contains the supported values,
+ plus the current settings.<br>
+ When writing, clocks accepts an IRIG_SETTINGS
+ structure only which contain the desired settings
+ only. _pcps_is_irig_rx() and _pcps_is_irig_tx()
+ check whether supported.
+
+ - #PCPS_GET_IRIG_CTRL_BITS<br>
+ This command can be used to retrieve the control function
+ bits of the latest IRIG input frame. Those bits may carry
+ some well-known information as in the IEEE1344 code, but
+ may also contain some customized information, depending on
+ the IRIG frame type and the configuration of the IRIG generator.
+ So these bits are returned as-is and must be interpreted
+ by the application.
+ _pcps_has_irig_ctrl_bits() checks whether supported.
+
+ - #PCPS_GET_SYNTH<br>
+ #PCPS_SET_SYNTH<br>
+ #PCPS_GET_SYNTH_STATE<br>
+ These commands can be used to configure an on-board
+ frequency synthesizer and query the synthesizer
+ status. The commands are only supported if the board
+ supports the RECEIVER_INFO structure and the flag
+ #GPS_HAS_SYNTH is set in the RECEIVER_INFO::features.
+ _pcps_has_synth() checks whether supported.
+ The structures SYNTH and SYNTH_STATE used with these
+ commands are defined in gpsdefs.h.
+
+ - #PCPS_GIVE_FW_ID_1<br>
+ #PCPS_GIVE_FW_ID_2<br>
+ Returns the first/second block of PCPS_FIFO_SIZE
+ characters of the firmware ID string. These
+ commands can be used to check if the board
+ responds properly. This is done by the clock
+ detection functions.
+
+ - #PCPS_GIVE_SERNUM<br>
+ Returns PCPS_FIFO_SIZE characters of the
+ clock's serial number.
+ _pcps_has_sernum() checks whether supported.
+
+ - #PCPS_GENERIC_IO<br>
+ Generic I/O read and write. Can be used to query
+ specific data, e.g. a selected element of an array.
+ _pcps_has_generic_io() checks whether supported.
+
+ - #PCPS_GET_DEBUG_STATUS<br>
+ This command reads a MBG_DEBUG_STATUS structure
+ which represents the internal status of the
+ IRIG decoder and some additional debug info.
+ _pcps_has_debug_status() checks whether supported.
+
+ - #PCPS_READ_GPS_DATA<br>
+ #PCPS_WRITE_GPS_DATA<br>
+ These commands are used by the functions
+ pcps_read_gps_data() and pcps_write_gps_data()
+ to read or write large data structures to
+ Meinberg GPS plug-in clocks.
+ _pcps_is_gps() checks whether supported.
+
+ - #PCPS_CLR_UCAP_BUFF<br>
+ Clear a clock's time capture buffer.
+ _pcps_can_clr_ucap_buff() checks whether
+ supported.
+
+ - #PCPS_GIVE_UCAP_ENTRIES<br>
+ Read a PCPS_UCAP_ENTRIES structure which
+ reports the max number of entries and the
+ currently used number of entries in the
+ user capture buffer.
+ _pcps_has_ucap() checks whether supported.
+
+ - #PCPS_GIVE_UCAP_EVENT<br>
+ Read capture events using a PCPS_HR_TIME
+ structure. This is faster than reading using the
+ GPS command #PC_GPS_UCAP. If no capture event is
+ available then the structure is filled with 0s.
+ _pcps_has_ucap() checks whether supported.
+
+ - #PCPS_FORCE_RESET<br>
+ Resets the microprocessor on the radio clock
+ board. This is for debug purposes only and
+ should not be used by standard applications.
+
+ The command codes listed above are defined below. The commands are
+ grouped for bytes having the same high nibble:
+ @{
+*/
+#define PCPS_GIVE_TIME_GROUP 0x00
+#define PCPS_SET_TIME_GROUP 0x10
+#define PCPS_IRQ_GROUP 0x20
+#define PCPS_CFG_GROUP 0x30
+#define PCPS_GIVE_DATA_GROUP 0x40
+#define PCPS_GPS_DATA_GROUP 0x50
+#define PCPS_CTRL_GROUP 0x60
+#define PCPS_CFG2_GROUP 0x70
+
+
+/* PCPS_GIVE_TIME_GROUP */
+#define PCPS_GIVE_TIME ( PCPS_GIVE_TIME_GROUP | 0x0 )
+#define PCPS_GIVE_TIME_NOCLEAR ( PCPS_GIVE_TIME_GROUP | 0x1 )
+#define PCPS_GIVE_SYNC_TIME ( PCPS_GIVE_TIME_GROUP | 0x2 ) // only supported if _pcps_has_sync_time()
+#define PCPS_GIVE_HR_TIME ( PCPS_GIVE_TIME_GROUP | 0x3 ) // only supported if _pcps_has_hr_time()
+#define PCPS_GIVE_IRIG_TIME ( PCPS_GIVE_TIME_GROUP | 0x4 ) // only supported if _pcps_has_irig_time()
+
+
+/* PCPS_SET_TIME_GROUP */
+#define PCPS_SET_TIME ( PCPS_SET_TIME_GROUP | 0x0 )
+/* on error, return PCPS_ERR_STIME */
+
+/* Attention: The code below can be used EXCLUSIVELY */
+/* with a GPS167PCI with customized CERN firmware !! */
+/* _pcps_has_event_time() checks whether supported. */
+#define PCPS_SET_EVENT_TIME ( PCPS_SET_TIME_GROUP | 0x4 )
+
+
+/* PCPS_IRQ_GROUP */
+#define PCPS_IRQ_NONE ( PCPS_IRQ_GROUP | 0x0 )
+#define PCPS_IRQ_1_SEC ( PCPS_IRQ_GROUP | 0x1 )
+#define PCPS_IRQ_1_MIN ( PCPS_IRQ_GROUP | 0x2 )
+#define PCPS_IRQ_10_MIN ( PCPS_IRQ_GROUP | 0x4 )
+#define PCPS_IRQ_30_MIN ( PCPS_IRQ_GROUP | 0x8 )
+
+
+/* PCPS_CFG_GROUP */
+
+#define PCPS_GET_SERIAL ( PCPS_CFG_GROUP | 0x0 )
+#define PCPS_SET_SERIAL ( PCPS_CFG_GROUP | 0x1 )
+/* on error, return PCPS_ERR_CFG */
+
+typedef uint8_t PCPS_SERIAL;
+
+
+#define PCPS_GET_TZCODE ( PCPS_CFG_GROUP | 0x2 )
+#define PCPS_SET_TZCODE ( PCPS_CFG_GROUP | 0x3 )
+/* on error, return PCPS_ERR_CFG */
+
+typedef uint8_t PCPS_TZCODE;
+
+/* the following codes are used with the PCPS_TZCODE parameter: */
+enum
+{
+ PCPS_TZCODE_CET_CEST, /* default as broadcasted by DCF77 (UTC+1h/UTC+2h) */
+ PCPS_TZCODE_CET, /* always CET (UTC+1h), discard DST */
+ PCPS_TZCODE_UTC, /* always UTC */
+ PCPS_TZCODE_EET_EEST, /* East European Time, CET/CEST + 1h */
+ N_PCPS_TZCODE /* the number of valid codes */
+};
+
+/* the definitions below are for compatibily only: */
+#define PCPS_TZCODE_MEZMESZ PCPS_TZCODE_CET_CEST
+#define PCPS_TZCODE_MEZ PCPS_TZCODE_CET
+#define PCPS_TZCODE_OEZ PCPS_TZCODE_EET_EEST
+
+
+#define PCPS_GET_PCPS_TZDL ( PCPS_CFG_GROUP | 0x4 )
+#define PCPS_SET_PCPS_TZDL ( PCPS_CFG_GROUP | 0x5 )
+/* on error, return PCPS_ERR_CFG */
+
+/**
+ * The structures below can be used to configure a clock's
+ * time zone/daylight saving setting. This structure is shorter
+ * than the TZDL structure used with GPS clocks.
+ */
+typedef struct
+{
+ // The year_or_wday field below contains the full year number
+ // or 0..6 == Sun..Sat if the DL_AUTO_FLAG is set; see below.
+ uint16_t year_or_wday;
+ uint8_t month;
+ uint8_t mday;
+ uint8_t hour;
+ uint8_t min;
+} PCPS_DL_ONOFF;
+
+#define _mbg_swab_pcps_dl_onoff( _p ) \
+{ \
+ _mbg_swab16( &(_p)->year_or_wday ); \
+}
+
+/**
+ * If the field year_or_wday is or'ed with the constant DL_AUTO_FLAG
+ * defined below then this means that start and end of daylight saving
+ * time shall be computed automatically for each year. In this case
+ * the remaining bits represent the day-of-week after the specified
+ * mday/month at which the change shall occur. If that flag is not set
+ * then the field contains the full four-digit year number and the
+ * mday/month values specify the exact date of that year.
+ */
+#define DL_AUTO_FLAG 0x8000 // also defined in gpsdefs.h
+
+typedef struct
+{
+ int16_t offs; /**< offset from UTC to local time [min] */
+ int16_t offs_dl; /**< additional offset if DST enabled [min] */
+ PCPS_DL_ONOFF tm_on; /**< date/time when daylight saving starts */
+ PCPS_DL_ONOFF tm_off; /**< date/time when daylight saving ends */
+} PCPS_TZDL;
+
+#define _mbg_swab_pcps_tzdl( _p ) \
+{ \
+ _mbg_swab16( &(_p)->offs ); \
+ _mbg_swab16( &(_p)->offs_dl ); \
+ _mbg_swab_pcps_dl_onoff( &(_p)->tm_on ); \
+ _mbg_swab_pcps_dl_onoff( &(_p)->tm_off ); \
+}
+
+
+
+#define PCPS_GET_REF_OFFS ( PCPS_CFG_GROUP | 0x6 )
+#define PCPS_SET_REF_OFFS ( PCPS_CFG_GROUP | 0x7 )
+/* on error, return PCPS_ERR_CFG */
+
+/* The associated type MBG_REF_OFFS is defined in gpsdefs.h. */
+
+
+#define PCPS_GET_OPT_INFO ( PCPS_CFG_GROUP | 0x8 )
+#define PCPS_SET_OPT_SETTINGS ( PCPS_CFG_GROUP | 0x9 )
+/* on error, return PCPS_ERR_CFG */
+
+/* The associated structures MBG_OPT_INFO and MBG_OPT_SETTINGS
+ are defined in gpsdefs.h. */
+
+
+#define PCPS_GET_IRIG_RX_INFO ( PCPS_CFG_GROUP | 0xA )
+#define PCPS_SET_IRIG_RX_SETTINGS ( PCPS_CFG_GROUP | 0xB )
+/* on error, return PCPS_ERR_CFG */
+
+#define PCPS_GET_IRIG_TX_INFO ( PCPS_CFG_GROUP | 0xC )
+#define PCPS_SET_IRIG_TX_SETTINGS ( PCPS_CFG_GROUP | 0xD )
+/* on error, return PCPS_ERR_CFG */
+
+/* The associated structures IRIG_INFO and IRIG_SETTINGS
+ are defined in gpsdefs.h. */
+
+
+#define PCPS_GET_SYNTH ( PCPS_CFG_GROUP | 0xE )
+#define PCPS_SET_SYNTH ( PCPS_CFG_GROUP | 0xF )
+/* on error, return PCPS_ERR_CFG */
+
+/* The associated structure SYNTH is defined in gpsdefs.h. */
+
+
+
+/* PCPS_GIVE_DATA_GROUP */
+#define PCPS_GIVE_FW_ID_1 ( PCPS_GIVE_DATA_GROUP | 0x0 )
+#define PCPS_GIVE_FW_ID_2 ( PCPS_GIVE_DATA_GROUP | 0x1 )
+#define PCPS_GIVE_SERNUM ( PCPS_GIVE_DATA_GROUP | 0x2 )
+#define PCPS_GENERIC_IO ( PCPS_GIVE_DATA_GROUP | 0x3 )
+#define PCPS_GET_SYNTH_STATE ( PCPS_GIVE_DATA_GROUP | 0x4 )
+#define PCPS_GET_IRIG_CTRL_BITS ( PCPS_GIVE_DATA_GROUP | 0x5 )
+#define PCPS_GET_RAW_IRIG_DATA ( PCPS_GIVE_DATA_GROUP | 0x6 )
+
+
+
+#define PCPS_GET_STATUS_PORT ( PCPS_GIVE_DATA_GROUP | 0xB )
+#define PCPS_GET_DEBUG_STATUS ( PCPS_GIVE_DATA_GROUP | 0xC )
+// expects sizeof( MBG_DEBUG_STATUS ) chars
+
+// PCPS_GIVE_DATA_GROUP codes 0x0D, 0x0E, and 0x0F are reserved.
+
+
+/* PCPS_GPS_DATA_GROUP */
+#define PCPS_READ_GPS_DATA ( PCPS_GPS_DATA_GROUP | 0x0 )
+#define PCPS_WRITE_GPS_DATA ( PCPS_GPS_DATA_GROUP | 0x1 )
+
+
+/* PCPS_CTRL_GROUP */
+#define PCPS_CLR_UCAP_BUFF ( PCPS_CTRL_GROUP | 0x0 )
+#define PCPS_GIVE_UCAP_ENTRIES ( PCPS_CTRL_GROUP | 0x1 )
+#define PCPS_GIVE_UCAP_EVENT ( PCPS_CTRL_GROUP | 0x2 )
+
+typedef struct
+{
+ uint32_t used; /**< the number of saved capture events */
+ uint32_t max; /**< capture buffer size */
+} PCPS_UCAP_ENTRIES;
+
+#define _mbg_swab_pcps_ucap_entries( _p ) \
+{ \
+ _mbg_swab32( &(_p)->used ); \
+ _mbg_swab32( &(_p)->max ); \
+}
+
+
+
+/**
+ special -- use with care !
+*/
+#define PCPS_FORCE_RESET 0x80
+
+/** @} */
+
+/* Codes returned when commands with parameters have been passed */
+/* to the board */
+#define PCPS_SUCCESS 0 /**< OK, no error */
+#define PCPS_ERR_STIME -1 /**< invalid date/time/status passed */
+#define PCPS_ERR_CFG -2 /**< invalid parms with a PCPS_CFG_GROUP cmd */
+
+
+
+#ifndef BITMASK
+ #define BITMASK( b ) ( ( 1 << b ) - 1 )
+#endif
+
+
+/** The size of the plug-in radio clock's on-board FIFO: */
+#define PCPS_FIFO_SIZE 16
+
+typedef int8_t PCPS_BUFF[PCPS_FIFO_SIZE];
+
+
+#define PCPS_ID_SIZE ( 2 * PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
+typedef char PCPS_ID_STR[PCPS_ID_SIZE];
+
+
+#define PCPS_SN_SIZE ( PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
+typedef char PCPS_SN_STR[PCPS_SN_SIZE];
+
+
+/**
+ * The structure has been introduced to be able to handle
+ * high resolution time stamps.
+ */
+typedef struct
+{
+ uint32_t sec; /**< seconds since 1970 (UTC) */
+ uint32_t frac; /**< fractions of second ( 0xFFFFFFFF == 0.9999.. sec) */
+} PCPS_TIME_STAMP;
+
+#define _mbg_swab_pcps_time_stamp( _p ) \
+{ \
+ _mbg_swab32( &(_p)->sec ); \
+ _mbg_swab32( &(_p)->frac ); \
+}
+
+
+
+// Depending on the target environment define a data type
+// which can be used to convert binary fractions without
+// range overflow.
+#if defined( MBG_TGT_UNIX )
+ #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
+#elif defined( MBG_TGT_WIN32 )
+ #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
+#elif defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
+ #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
+#else
+ #define PCPS_HRT_FRAC_CONVERSION_TYPE double
+#endif
+
+// Max value of PCPS_TIME_STAMP::frac + 1 used for scaling
+#define PCPS_HRT_BIN_FRAC_SCALE ( (PCPS_HRT_FRAC_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000
+
+
+// The scale and format to be used to print the fractions
+// of a second as returned in the PCPS_TIME_STAMP structure.
+// The function frac_sec_from_bin() can be used for
+// the conversion.
+#ifndef PCPS_HRT_FRAC_SCALE
+ #define PCPS_HRT_FRAC_SCALE 10000000UL
+#endif
+
+#ifndef PCPS_HRT_FRAC_SCALE_FMT
+ #define PCPS_HRT_FRAC_SCALE_FMT "%07lu"
+#endif
+
+
+
+typedef uint16_t PCPS_TIME_STATUS_X; /**< extended status */
+
+#define _mbg_swab_pcps_time_status_x( _p ) _mbg_swab16( _p )
+
+
+/**
+ * The structure has been introduced to be able to read the
+ * current time with higher resolution of fractions of seconds and
+ * more detailed information on the time zone and status.
+ * The structure is returned if the new command #PCPS_GIVE_HR_TIME
+ * is written to the board.
+ * _pcps_has_hr_time() checks whether supported.
+ *
+ * Newer GPS boards also accept the #PCPS_GIVE_UCAP_EVENT command
+ * to return user capture event times using this format. In this
+ * case, the "signal" field contains the number of the capture
+ * input line, e.g. 0 or 1.
+ * _pcps_has_ucap() checks whether supported.
+ */
+typedef struct
+{
+ PCPS_TIME_STAMP tstamp; /**< High resolution time stamp (UTC) */
+ int32_t utc_offs; /**< UTC offs [sec] (loc_time = UTC + utc_offs) */
+ PCPS_TIME_STATUS_X status; /**< status flags as defined below */
+ uint8_t signal; /**< for normal time, the relative RF signal level, for ucap, the channel number */
+} PCPS_HR_TIME;
+
+#define _mbg_swab_pcps_hr_time( _p ) \
+{ \
+ _mbg_swab_pcps_time_stamp( &(_p)->tstamp ); \
+ _mbg_swab32( &(_p)->utc_offs ); \
+ _mbg_swab_pcps_time_status_x( &(_p)->status ); \
+}
+
+
+typedef uint8_t PCPS_TIME_STATUS;
+
+/**
+ The standard structure used to read times from the board.
+ The time has a resultion of 10 ms.
+*/
+typedef struct PCPS_TIME_s
+{
+ uint8_t sec100; /**< hundredths of seconds, 0..99 */
+ uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
+ uint8_t min; /**< minutes, 0..59 */
+ uint8_t hour; /**< hours, 0..23 */
+
+ uint8_t mday; /**< day of month, 0..31 */
+ uint8_t wday; /**< day of week, 1..7, 1 = Monday */
+ uint8_t month; /**< month, 1..12 */
+ uint8_t year; /**< year of the century, 0..99 */
+
+ PCPS_TIME_STATUS status; /**< status bits, see below */
+ uint8_t signal; /**< relative signal strength, range depends on device type */
+ int8_t offs_utc; /**< [hours], 0 if !_pcps_has_utc_offs() */
+} PCPS_TIME;
+
+
+/**
+ The structure is passed as parameter with the PCPS_SET_TIME cmd
+*/
+typedef struct PCPS_STIME_s
+{
+ uint8_t sec100; /**< hundredths of seconds, 0..99 */
+ uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
+ uint8_t min; /**< minutes, 0..59 */
+ uint8_t hour; /**< hours, 0..23 */
+
+ uint8_t mday; /**< day of month, 0..31 */
+ uint8_t wday; /**< day of week, 1..7, 1 = Monday */
+ uint8_t month; /**< month, 1..12 */
+ uint8_t year; /**< year of the century, 0..99 */
+
+ PCPS_TIME_STATUS status; /**< status bits, see below */
+} PCPS_STIME;
+
+#ifdef _C166
+ // This is a workaround to specify some structure sizes. The C166 compiler
+ // always reports an even structure size although the structure size may
+ // be odd due to the number of bytes. This might lead to errors between
+ // the C166 and other build environments.
+ #define sizeof_PCPS_TIME ( sizeof( PCPS_TIME ) - 1 )
+ #define sizeof_PCPS_STIME ( sizeof( PCPS_STIME ) - 1 )
+#else
+ #define sizeof_PCPS_TIME sizeof( PCPS_TIME )
+ #define sizeof_PCPS_STIME sizeof( PCPS_STIME )
+#endif
+
+typedef union
+{
+ PCPS_TIME t;
+ PCPS_STIME stime;
+} PCPS_TIME_UNION;
+
+
+
+/**
+ The structure below can be used to read the raw IRIG time
+ from an IRIG receiver card, if the card supports this.
+ See the #PCPS_GIVE_IRIG_TIME command.
+
+ The granularity of the value in the .frac field depends on
+ the update interval of the structure as implementation
+ in the firmware. I.e. if the raw IRIG time is updated
+ only once per second, the .frac value can always be 0.
+*/
+typedef struct PCPS_IRIG_TIME_s
+{
+ PCPS_TIME_STATUS_X status; /**< status bits, see below */
+ int16_t offs_utc; /**< [minutes] */
+ uint16_t yday; /**< day of year, 1..365/366 */
+ uint16_t frac; /**< fractions of seconds, 0.1 ms units */
+ uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
+ uint8_t min; /**< minutes, 0..59 */
+ uint8_t hour; /**< hours, 0..23 */
+ uint8_t year; /**< 2 digit year number, 0xFF if year not supp. by the IRIG code */
+ uint8_t signal; /**< relative signal strength, range depends on device type */
+ uint8_t reserved; /**< currently not used, always 0 */
+} PCPS_IRIG_TIME;
+
+#define _mbg_swab_pcps_irig_time( _p ) \
+{ \
+ _mbg_swab_pcps_time_status_x( &(_p)->status ); \
+ _mbg_swab16( &(_p)->offs_utc ); \
+ _mbg_swab16( &(_p)->yday ); \
+ _mbg_swab16( &(_p)->frac ); \
+}
+
+
+
+
+/* Bit masks used with both PCPS_TIME_STATUS and PCPS_TIME_STATUS_X */
+
+#define PCPS_FREER 0x01 /**< DCF77 clock running on xtal */
+ /**< GPS receiver has not verified its position */
+
+#define PCPS_DL_ENB 0x02 /**< daylight saving enabled */
+
+#define PCPS_SYNCD 0x04 /**< clock has sync'ed at least once after pwr up */
+
+#define PCPS_DL_ANN 0x08 /**< a change in daylight saving is announced */
+
+#define PCPS_UTC 0x10 /**< a special UTC firmware is installed */
+
+#define PCPS_LS_ANN 0x20 /**< leap second announced */
+ /**< (requires firmware rev. REV_PCPS_LS_ANN_...) */
+
+#define PCPS_IFTM 0x40 /**< the current time was set via PC */
+ /**< (requires firmware rev. REV_PCPS_IFTM_...) */
+
+#define PCPS_INVT 0x80 /**< invalid time because battery was disconn'd */
+
+
+/* Bit masks used only with PCPS_TIME_STATUS_X */
+
+#define PCPS_LS_ENB 0x0100 /**< current second is leap second */
+#define PCPS_ANT_FAIL 0x0200 /**< antenna failure */
+#define PCPS_LS_ANN_NEG 0x0400 /**< announced leap second is negative */
+#define PCPS_SCALE_GPS 0x0800 /**< time stamp is GPS scale */
+#define PCPS_SCALE_TAI 0x1000 /**< time stamp is TAI scale */
+
+/* The next two bits are used only if the structure */
+/* PCPS_HR_TIME contains a user capture event */
+#define PCPS_UCAP_OVERRUN 0x2000 /**< events interval too short */
+#define PCPS_UCAP_BUFFER_FULL 0x4000 /**< events read too slow */
+
+/**
+ * Immediately after a clock has been accessed, subsequent accesses
+ * are blocked for up to 1.5 msec to give the clock's microprocessor
+ * some time to decode the incoming time signal.
+ * The flag below is set if a program tries to read the PCPS_HR_TIME
+ * during this interval. In this case the read function returns the
+ * proper time stamp which is taken if the command byte is written,
+ * however, the read function returns with delay.
+ * This flag is not supported by all clocks.
+ */
+#define PCPS_IO_BLOCKED 0x8000
+
+/**
+ This bit mask can be used to extract the time scale information out
+ of a PCPS_TIME_STATUS_X value.
+*/
+#define PCPS_SCALE_MASK ( PCPS_SCALE_TAI | PCPS_SCALE_GPS )
+
+
+/**
+ * Some DCF77 clocks have a serial interface that can be controlled
+ * using the commands PCPS_SET_SERIAL and PCPS_GET_SERIAL. Both commands
+ * use a parameter byte describing transmission speed, framing and mode
+ * of operation. The parameter byte can be build using the constants
+ * defined below, by or'ing one of the constants of each group, shifted
+ * to the right position. PCPS_GET_SERIAL expects that parameter byte
+ * and PCPS_GET_SERIAL returns the current configuration from the board.
+ * _pcps_has_serial() checks whether supported.
+ * For GPS clocks, please refer to the comments for the PCPS_GET_SERIAL
+ * command.
+ */
+
+/**
+ * Baud rate indices. The values below are obsolete and should
+ * be replaced by the codes named MBG_BAUD_RATE_... which are
+ * defined in gpsdefs.h. The resulting index numbers, however,
+ * have not changed.
+ */
+enum
+{
+ PCPS_BD_300,
+ PCPS_BD_600,
+ PCPS_BD_1200,
+ PCPS_BD_2400,
+ PCPS_BD_4800,
+ PCPS_BD_9600,
+ PCPS_BD_19200,
+ N_PCPS_BD /* number of codes */
+};
+
+#define PCPS_BD_BITS 4 /* field with in the cfg byte */
+#define PCPS_BD_SHIFT 0 /* num of bits to shift left */
+
+/*
+ * Initializers for a table of all baud rate strings
+ * and values can be found in gpsdefs.h.
+ */
+
+
+/**
+ * Unfortunately, the framing codes below can not simply be
+ * replaced by the newer MBG_FRAMING_... definitions since
+ * the order of indices does not match.
+ */
+enum
+{
+ PCPS_FR_8N1,
+ PCPS_FR_7E2,
+ PCPS_FR_8N2,
+ PCPS_FR_8E1,
+ N_PCPS_FR_DCF /* number of valid codes */
+};
+
+#define PCPS_FR_BITS 2 /* field with in the cfg byte */
+#define PCPS_FR_SHIFT PCPS_BD_BITS /* num of bits to shift left */
+
+/*
+ * An initializer for a table of framing strings is only defined for
+ * the new MBG_FRAMING_... definitions. For editing the serial port
+ * configuration, the old codes above should be translated to the new
+ * codes to unify handling inside the edit functions.
+ */
+
+/**
+ Modes of operation
+
+ * Indices for modes of operation. The values below are obsolete
+ * and should be replaced by the codes named STR_... which are
+ * defined in gpsdefs.h. The resulting index numbers, however,
+ * have not changed.
+ */
+enum
+{
+ PCPS_MOD_REQ, /* time string on request '?' only */
+ PCPS_MOD_SEC, /* time string once per second */
+ PCPS_MOD_MIN, /* time string once per minute */
+ PCPS_MOD_RSVD, /* reserved */
+ N_PCPS_MOD_DCF /* number of possible codes */
+};
+
+#define PCPS_MOD_BITS 2 /* field with in the cfg byte */
+#define PCPS_MOD_SHIFT ( PCPS_BD_BITS + PCPS_FR_BITS )
+ /* num of bits to shift left */
+
+/**
+ * The fixed-length standard time string being sent on the serial
+ * output is described below:
+ *
+ * \<STX\>D:dd.mm.yy;T:d;U:hh.mm.ss;uvwx\<ETX\>
+ *
+ * where \<STX\> and \<ETX\> represent the ASCII codes 0x02 and 0x03,
+ * 'dd.mm.yy' is the format of the current date, 'd' is the current
+ * day of week (1..7, 1 == Monday ) and 'hh.mm.ss' is the format of
+ * the current time. The characters 'uvwx' reflect the clock's status:
+ *
+ * u clock status character:
+ * '#' clock has not synchronized after reset
+ * ' ' (space, 20h) clock has synchronized after reset
+ *
+ * v clock status character, different for DCF77 or GPS receivers:
+ * '*' DCF77 clock currently runs on XTAL
+ * GPS receiver has not checked its position
+ * ' ' (space, 20h):
+ * DCF77 clock is syncronized with transmitter
+ * GPS receiver has determined its position
+ *
+ * x time zone indicator:
+ * 'U' UTC Universal Time, Coordinated
+ * ' ' MEZ European Standard Time, daylight saving disabled
+ * 'S' MESZ European Summertime, daylight saving enabled
+ *
+ * y anouncement of discontinuity of time, enabled during last hour
+ * before discontinuity comes in effect:
+ * '!' announcement of start or end of daylight saving
+ * 'A' announcement of leap second insertion
+ * ' ' (space, 20h): nothing announced
+ */
+
+
+
+/**
+ * Some definitions used with PZF receivers
+ */
+
+/* receiver distance from transmitter [km] */
+typedef uint16_t TR_DISTANCE;
+
+/* correlation status info */
+typedef struct
+{
+ uint8_t val; /**< correlation value, or check count if status == PZF_CORR_CHECK */
+ uint8_t status; /**< status codes, see below */
+ char corr_dir; /**< space, '<', or '>' */
+ uint8_t signal; /**< signal level, may always be 0 for devices which do not support this */
+} CORR_INFO;
+
+/** Codes used with CORR_INFO::status: */
+enum
+{
+ PZF_CORR_RAW, /**< trying raw correlation, combi receivers running in AM mode */
+ PZF_CORR_CHECK, /**< raw correlation achieved, doing plausibility checks */
+ PZF_CORR_FINE, /**< fine correlation achieved */
+ N_PZF_CORR_STATE
+};
+
+
+/**
+ * @defgroup gps_cmds_bus GPS commands passed via the system bus
+ *
+ * This enumeration defines the various types of data that can be read
+ * from or written to Meinberg bus level devices which support this.
+ * Access should be done using the functions ::pcps_read_gps_data()
+ * and ::pcps_write_gps_data() since the size of some of the structures
+ * exceeds the size of the devices's I/O buffer and must therefore be
+ * accessed in several portions.
+ *
+ * The structures to be used are defined in gpsdefs.h. Not all structures
+ * are supportet, yet. Check the R/W indicators for details.
+ */
+enum
+{ // R/W data type description
+ // system data -----------------------------------------------
+ PC_GPS_TZDL = 0, // R/W TZDL time zone / daylight saving
+ PC_GPS_SW_REV, // R/- SW_REV software revision
+ PC_GPS_BVAR_STAT, // R/- BVAR_STAT status of buffered variables
+ PC_GPS_TIME, // R/W TTM curr. time
+ PC_GPS_POS_XYZ, // -/W XYZ curr. pos. in ECEF coords
+ PC_GPS_POS_LLA, // -/W LLA curr. pos. in geogr. coords
+ PC_GPS_PORT_PARM, // R/W PORT_PARM param. of the serial ports
+ PC_GPS_ANT_INFO, // R/- ANT_INFO time diff after ant. disconn.
+ PC_GPS_UCAP, // R/- TTM user capture
+ PC_GPS_ENABLE_FLAGS, // R/W ENABLE_FLAGS controls when to enable outp.
+ PC_GPS_STAT_INFO, // R/- GPS_STAT_INFO
+ PC_GPS_CMD, // -/W GPS_CMD commands as described below
+ PC_GPS_IDENT, // R/- GPS_IDENT serial number
+ PC_GPS_POS, // R/- POS position XYZ, LLA, and DMS
+ PC_GPS_ANT_CABLE_LEN, // R/W ANT_CABLE_LEN used to compensate delay
+ // The codes below are supported by new GPS receiver boards:
+ PC_GPS_RECEIVER_INFO, // R/- RECEIVER_INFO rcvr model info
+ PC_GPS_ALL_STR_TYPE_INFO, // R/- n*STR_TYPE_INFO_IDX all string types
+ PC_GPS_ALL_PORT_INFO, // R/- n*PORT_INFO_IDX all port info
+ PC_GPS_PORT_SETTINGS_IDX, // -/W PORT_SETTINGS_IDX port settings only
+ PC_GPS_ALL_POUT_INFO, // R/- n*POUT_INFO_IDX all pout info
+ PC_GPS_POUT_SETTINGS_IDX, // -/W POUT_SETTINGS_IDX pout settings only
+ PC_GPS_TIME_SCALE, // R/W MBG_TIME_SCALE_{SETTINGS|INFO}, only if PCPS_HAS_TIME_SCALE
+ PC_GPS_LAN_IF_INFO, // R/- LAN_IF_INFO LAN interface info, only if PCPS_HAS_LAN_INTF
+ PC_GPS_IP4_STATE, // R/- IP4_SETTINGS LAN interface state, only if PCPS_HAS_LAN_INTF
+ PC_GPS_IP4_SETTINGS, // R/W IP4_SETTINGS LAN interface configuration, only if PCPS_HAS_LAN_INTF
+ PC_GPS_PTP_STATE, // R/- PTP_STATE, only if PCPS_HAS_PTP
+ PC_GPS_PTP_CFG, // R/W PTP_CFG_{SETTINGS|INFO}, only if PCPS_HAS_PTP
+
+ // GPS data
+ PC_GPS_CFGH = 0x80, // -/- CFGH SVs' config. and health codes
+ PC_GPS_ALM, // -/- SV_ALM one SV's num and almanac
+ PC_GPS_EPH, // -/- SV_EPH one SV's num and ephemeris
+ PC_GPS_UTC, // R/W UTC UTC corr. param., only if PCPS_HAS_UTC_PARM
+ PC_GPS_IONO, // -/- IONO ionospheric corr. param.
+ PC_GPS_ASCII_MSG // -/- ASCII_MSG the GPS ASCII message
+};
+
+
+/** codes used with PC_GPS_CMD */
+enum
+{
+ PC_GPS_CMD_BOOT = 1, /**< force the clock to boot mode */
+ PC_GPS_CMD_INIT_SYS, /**< let the clock clear its system variables */
+ PC_GPS_CMD_INIT_USER, /**< reset the clock's user parameters to defaults */
+ PC_GPS_CMD_INIT_DAC, /**< initialize the oscillator disciplining values */
+ N_PC_GPS_CMD /**< no command, just the number of known commands */
+};
+
+// The type below can be used to store an unambiguous command code.
+// In case of the standard PCPS_... commands the lower byte contains
+// the command code and the upper byte is 0.
+// In case of a GPS command the lower byte contains PCPS_READ_GPS_DATA
+// or PCPS_WRITE_GPS_DATA, as appropriate, and the upper byte contains
+// the associated PC_GPS_... type code.
+typedef uint16_t PCPS_CMD_INFO;
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+#endif /* _PCPSDEFS_H */
+
diff --git a/mbglib/common/use_pack.h b/mbglib/common/use_pack.h
index b162014..16950fa 100644
--- a/mbglib/common/use_pack.h
+++ b/mbglib/common/use_pack.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: use_pack.h 1.2 2002/02/25 08:50:33Z Andre REL_M $
+ * $Id: use_pack.h 1.3 2011/01/26 10:01:41Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,9 @@
*
* -----------------------------------------------------------------------
* $Log: use_pack.h $
- * Revision 1.2 2002/02/25 08:50:33Z Andre
+ * Revision 1.3 2011/01/26 10:01:41Z martin
+ * Provided a way to suppress packing of structures on a project base.
+ * Revision 1.2 2002/02/25 08:50:33 Andre
* query __ARM added, __SH2 removed
* Revision 1.1 2001/03/30 08:54:33Z MARTIN
* Initial revision
@@ -21,8 +23,16 @@
#ifndef _USE_PACK_H
#define _USE_PACK_H
-#if ( !defined( _C166 ) && !defined( _CC51 ) && !defined( __ARM ) )
- #define _USE_PACK
+#if ( !defined( _C166 ) && \
+ !defined( _CC51 ) && \
+ !defined( __ARM ) )
+
+ // _NO_USE_PACK can be defined for specific projects
+ // to avoid packing of structures.
+ #if ( !defined( _NO_USE_PACK ) )
+ #define _USE_PACK
+ #endif
+
#endif
#endif /* _USE_PACK_H */
diff --git a/mbglib/common/words.h b/mbglib/common/words.h
index 6ec5eaf..cdb8ab3 100644
--- a/mbglib/common/words.h
+++ b/mbglib/common/words.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: words.h 1.21 2009/10/01 14:00:17Z martin REL_M $
+ * $Id: words.h 1.26 2011/04/06 10:23:03Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,20 @@
*
* -----------------------------------------------------------------------
* $Log: words.h $
- * Revision 1.21 2009/10/01 14:00:17Z martin
+ * Revision 1.26 2011/04/06 10:23:03Z martin
+ * Added FBYTE_OF() and FWORD_OF() macros.
+ * Modifications required for *BSD.
+ * Revision 1.25 2010/11/17 10:23:09 martin
+ * Define _BIT_REDEFINED if bit type is redefined.
+ * Revision 1.24 2010/11/17 08:44:56Z martin
+ * If supported, use type "bool" to implement "bit".
+ * Revision 1.23 2010/05/27 08:54:30Z martin
+ * Support fixed size data types with Keil RealView compiler for ARM.
+ * Keil RealView ARM targets are always considered as firmware.
+ * Revision 1.22 2009/10/21 07:53:55 martin
+ * Undid changes introduced in 1.21 since they were not consistent
+ * across glibc and/or Linux kernel header versions.
+ * Revision 1.21 2009/10/01 14:00:17 martin
* Conditionally define ulong and friends also for Linux/glibc.
* Revision 1.20 2009/07/02 15:38:12 martin
* Added new macro _wswap32().
@@ -71,7 +84,8 @@
#if defined( _C166 ) || \
defined( _CC51 ) || \
- defined( __ARM )
+ defined( __ARM ) || \
+ defined( __ARMCC_VERSION )
#define _IS_MBG_FIRMWARE 1
#else
#define _IS_MBG_FIRMWARE 0
@@ -82,8 +96,6 @@
#if !_IS_MBG_FIRMWARE
#include <mbg_tgt.h>
-
- typedef unsigned char bit;
#endif
@@ -97,6 +109,14 @@
/* Start of header body */
+// The compilers below support native bit types.
+
+#if defined( _C166 ) || defined( _CC51 )
+ #define _BIT_DEFINED 1
+#endif
+
+
+
// Check whether the target system supports C99 fixed-size types.
#if defined( MBG_TGT_LINUX ) // any Linux target
@@ -116,6 +136,10 @@
#define _C99_BIT_TYPES_DEFINED 1
+ // avoid inclusion of stdbool.h later
+ #define bit int
+ #define _BIT_DEFINED 1
+
#elif defined( MBG_TGT_QNX ) // QNX 4.x or QNX 6.x
#if defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino) with gcc
@@ -129,6 +153,7 @@
#endif
+
// If it's not yet clear whether fixed-size types are supported,
// check the build environment which may be multi-platform.
@@ -157,6 +182,11 @@
#define _C99_BIT_TYPES_DEFINED 1
#endif
+ #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
+ #include <stdint.h>
+ #define _C99_BIT_TYPES_DEFINED 1
+ #endif
+
#endif
@@ -214,9 +244,7 @@
typedef unsigned char uchar;
-#if !defined( MBG_TGT_LINUX ) || !defined( __USE_MISC )
- // The glibc headers define the types below if __USE_MISC is
- // defined, otherwise we need to define them here.
+#if !defined( MBG_TGT_LINUX ) && !( defined ( MBG_TGT_NETBSD ) && defined ( MBG_TGT_KERNEL ) )
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
@@ -229,6 +257,20 @@ typedef unsigned short word;
typedef unsigned long longword;
typedef unsigned long dword;
+#if !defined( _BIT_DEFINED )
+
+ #if _C99_BIT_TYPES_DEFINED
+ #include <stdbool.h>
+
+ typedef bool bit;
+ #else
+ typedef int bit;
+ #endif
+
+ #define _BIT_REDEFINED 1
+
+#endif
+
#define HI_BYTE( _x ) ( (_x) >> 8 )
#define LO_BYTE( _x ) ( (_x) & 0xFF )
@@ -241,6 +283,9 @@ typedef unsigned long dword;
#define BYTE_OF( _v, _n ) *( ( (uint8_t *) &(_v) ) + (_n) )
#define WORD_OF( _v, _n ) *( ( (uint16_t *) &(_v) ) + (_n) )
+#define FBYTE_OF( _v, _n ) *( ( (uint8_t far *) &(_v) ) + (_n) )
+#define FWORD_OF( _v, _n ) *( ( (uint16_t far *) &(_v) ) + (_n) )
+
// same as above, but taking pointers
#define BYTE_OF_P( _p, _n ) *( ( (uint8_t *) (_p) ) + (_n) )
#define WORD_OF_P( _p, _n ) *( ( (uint16_t *) (_p) ) + (_n) )
diff --git a/windows/gpsxmple.dsp b/windows/gpsxmple.dsp
index 13579dd..13579dd 100755..100644
--- a/windows/gpsxmple.dsp
+++ b/windows/gpsxmple.dsp
diff --git a/windows/gpsxmple.dsw b/windows/gpsxmple.dsw
index 6c6ca62..6c6ca62 100755..100644
--- a/windows/gpsxmple.dsw
+++ b/windows/gpsxmple.dsw