summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2009-10-07 13:00:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2009-10-07 13:00:00 +0200
commitcb75c0b4534db39d8d5a337795dac8e4a7ec5c19 (patch)
treeff1b65eaa046b62836ab0233928d223352312643
parentc351e44698427238658702ed6a00b0bf0c8f791b (diff)
downloadgpsxmple-cb75c0b4534db39d8d5a337795dac8e4a7ec5c19.tar.gz
gpsxmple-cb75c0b4534db39d8d5a337795dac8e4a7ec5c19.zip
Feature updatesgpsxmple-2.2-unix
Changes due to renamed library functions. Optionally force connection. Read global RECEIVER_INFO after startup. Read string type info and port info, if supported. Fixed a typo for passwd parameter in usage(). Show SVs and DAC. Optionally loop and wait for automatic messages. Added a bunch of missing functions to mbgextio.c. Use mbgserio.c.
-rw-r--r--gpsxmple.c404
-rw-r--r--mbglib/common/aes128.c401
-rw-r--r--mbglib/common/aes128.h20
-rw-r--r--mbglib/common/gpsdefs.h2483
-rw-r--r--mbglib/common/gpsserio.c132
-rw-r--r--mbglib/common/gpsserio.h343
-rw-r--r--mbglib/common/mbg_tgt.h214
-rw-r--r--mbglib/common/mbg_tmo.c64
-rw-r--r--mbglib/common/mbg_tmo.h312
-rw-r--r--mbglib/common/mbgextio.c1287
-rw-r--r--mbglib/common/mbgextio.h82
-rw-r--r--mbglib/common/mbggeo.h52
-rw-r--r--mbglib/common/mbgserio.c960
-rw-r--r--mbglib/common/mbgserio.h213
-rw-r--r--mbglib/common/pcpsdefs.h1222
-rw-r--r--mbglib/common/words.h242
-rw-r--r--unix/Makefile11
17 files changed, 7093 insertions, 1349 deletions
diff --git a/gpsxmple.c b/gpsxmple.c
index 3f0470a..f493d2e 100644
--- a/gpsxmple.c
+++ b/gpsxmple.c
@@ -1,21 +1,21 @@
/**************************************************************************
*
- * $Id: gpsxmple.c 1.6 2006/10/25 12:31:54 martin REL_M $
- * $Name: GPSXMPLE_2_1 $
+ * $Id: gpsxmple.c 1.7 2009/10/02 14:18:08 martin REL_M $
+ * $Name: GPSXMPLE_2_2 $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * Sample program demonstrating how to access Meinberg GPS receivers
+ * Sample program demonstrating how to access Meinberg GPS receivers
* via the binary data protocol.
*
- * Depending on the target operating system this program works
- * either via serial port (the default) or via a network socket
+ * Depending on the target operating system this program works
+ * either via serial port (the default) or via a network socket
* connection.
*
* Other modules needed to build the executable:
- * mbgextio.c, gpsserio.c, gpsutils.c
+ * mbgextio.c, mbgserio.c, gpsserio.c, gpsutils.c
* optionally aes128.c, if network socket I/O is used
*
* Supported target environments:
@@ -24,14 +24,23 @@
* QNX 6.x / gcc (socket only)
* DOS / BC3.1 (serial only)
*
- * For makefiles and build environment setups check the associated
+ * For makefiles and build environment setups check the associated
* subdirectories.
*
- * Please send changes required for other OSs to <support@meinberg.de>
+ * Please send changes required for other operating systems
+ * or build to <support@meinberg.de>
*
* -----------------------------------------------------------------------
* $Log: gpsxmple.c $
- * Revision 1.6 2006/10/25 12:31:54 martin
+ * Revision 1.7 2009/10/02 14:18:08 martin
+ * Changes due to renamed library functions.
+ * Optionally force connection.
+ * Read global receiver_info after startup.
+ * Read string type info and port info, if supported.
+ * Fixed a typo for passwd parameter in usage().
+ * Show SVs and DAC.
+ * Optionally loop and wait for automatic messages.
+ * Revision 1.6 2006/10/25 12:31:54Z martin
* Support serial I/O under Windows.
* Check return codes of API functions and print associated
* messages in case of error.
@@ -66,6 +75,7 @@
+// the variables below are required for communication
MBG_MSG_BUFF rbuff;
MBG_MSG_BUFF tbuff;
@@ -76,8 +86,38 @@ MBG_MSG_CTL mctl =
};
+// Define the minimum number of some resource types
+// required by the software
+#define N_COM_MIN 1 // minimum number of COM ports
+
+// Define the maximum number of some resource types
+// supported by the software
+#define N_COM_MAX 4 // max. number of COM ports
+#define N_STR_TYPE_MAX 20 // max. number of string types
+#define N_POUT_MAX 3 // max. number of programmable outputs
+
+
+
+#define _log_msg_0( _lvl, _fmt ) \
+ printf( _fmt ); printf( "\n" )
+
+#define _log_msg_1( _lvl, _fmt, _v1 ) \
+ printf( _fmt, _v1 ); printf( "\n" )
+
+#define _log_msg_2( _lvl, _fmt, _v1, _v2 ) \
+ printf( _fmt, _v1, _v2 ); printf( "\n" )
+
+#define _log_msg_3( _lvl, _fmt, _v1, _v2, _v3 ) \
+ printf( _fmt, _v1, _v2, _v3 ); printf( "\n" )
+
+
+
static const char *target;
static int is_socket;
+static int must_force_connection;
+static int must_send_auto;
+static RECEIVER_INFO receiver_info;
+static const char *feature_names[] = DEFAULT_GPS_FEATURE_NAMES;
#if !defined( DEFAULT_DEV_NAME )
#define DEFAULT_DEV_NAME NULL
@@ -86,8 +126,10 @@ static int is_socket;
static const char *default_target = DEFAULT_DEV_NAME;
#if _USE_SERIAL_IO
- static long baudrate = 19200L;
- static const char *framing = "8N1";
+ static uint32_t default_baudrate = 19200L;
+ static const char *default_framing = "8N1";
+ static uint32_t baudrate;
+ static const char *framing;
#endif
#if _USE_SOCKET_IO
@@ -222,7 +264,7 @@ void print_stat_info( STAT_INFO *p )
default: cp = "INVALID MODE";
};
- printf( "\r%s, %u/%u SVs, DAC: %+li/%+li\n",
+ printf( "%s, %u/%u SVs, DAC: %+li/%+li\n",
cp,
p->good_svs,
p->svs_in_view,
@@ -257,17 +299,127 @@ void print_time( TTM *p )
+static /*HDR*/
+void check_receiver_info( RECEIVER_INFO *p, int log )
+{
+ const char *fmt_min = "Number of %s from device (%u) is less than number required (%u)";
+ const char *fmt_max = "Number of %s from device (%u) exceeds number supported by the software (%u)";
+
+ // Check if numbers of resources provided by the device
+ // don't exceed numbers of resources supported by the software
+
+ #define _check_min( _n, _min, _info ) \
+ { \
+ if ( (_n) < (_min) ) \
+ { \
+ if ( log ) \
+ _log_msg_3( LOG_ERR, fmt_min, _info, _n, _min ); \
+ } \
+ }
+
+ #define _check_max( _n, _max, _info ) \
+ { \
+ if ( (_n) > (_max) ) \
+ { \
+ if ( log ) \
+ _log_msg_3( LOG_WARNING, fmt_max, _info, _n, _max ); \
+ \
+ _n = _max; \
+ } \
+ }
+
+ 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" );
+ }
+ 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 );
+ }
+ }
+
+ _check_min( p->n_com_ports, N_COM_MIN, "COM ports" );
+ _check_max( p->n_com_ports, N_COM_MAX, "COM ports" );
+ _check_max( p->n_str_type, N_STR_TYPE_MAX, "string types" );
+ _check_max( p->n_prg_out, N_POUT_MAX, "progr. outputs" );
+
+} // check_receiver_info
+
+
+
/*HDR*/
int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
{
- int rc = mbgextio_get_receiver_info( &mctl, p );
+ int rc;
+ int i;
+ int l;
+
+ printf( fmt, "Receiver info:" );
+
+ rc = mbgextio_get_receiver_info( &mctl, p );
if ( rc != TR_COMPLETE )
{
- printf( "Failed to read receiver info: " );
check_rc( rc );
+
+ if ( rc == TR_TIMEOUT )
+ {
+ printf( "If you are using a very old GPS model then reading the\n"
+ "receiver info structure may not be supported.\n" );
+ }
+
+ return rc;
+ }
+
+ printf( "%s v%X.%02X",
+ p->model_name,
+ p->sw_rev.code >> 8,
+ p->sw_rev.code & 0xFF
+ );
+
+ l = strlen( p->sw_rev.name );
+
+ if ( l )
+ {
+ // skip trailing spaces
+ for ( i = l - 1; i > 0; i-- )
+ if ( p->sw_rev.name[i] != ' ' )
+ break;
+
+ if ( i != 0 )
+ printf( " \"%s\"", p->sw_rev.name );
+
+ #if 0 // hex output for testing
+ for ( i= 0; i < l; i++ )
+ printf( " %02X", p->sw_rev.name[i] );
+ #endif
+ }
+ printf( ", S/N: %s", p->sernum );
+ printf( "\n" );
+
+ // print features
+ printf( fmt, "" );
+ printf( "Features: 0x%08lX\n", (long) p->features );
+
+ for ( i = 0; i < 8 * sizeof( p->features ); i++ )
+ {
+ if ( p->features & (1UL << i) )
+ {
+ printf( fmt, "" );
+ printf( " - " );
+
+ if ( i < N_GPS_FEATURE )
+ printf( "%s\n", feature_names[i] );
+ else
+ printf( "Unknown feature flag 0x%08lX\n", (1UL << i) );
+ }
}
+ printf( "\n" );
+
return rc;
} // get_receiver_info
@@ -301,7 +453,7 @@ void show_sw_rev( MBG_MSG_CTL *pmctl )
/*HDR*/
-void show_stat( MBG_MSG_CTL *pmctl )
+void show_bvar_stat( MBG_MSG_CTL *pmctl )
{
BVAR_STAT bvar_stat;
int rc;
@@ -318,7 +470,29 @@ void show_stat( MBG_MSG_CTL *pmctl )
printf( "%04X\n", bvar_stat );
-} /* show_stat */
+} /* show_bvar_stat */
+
+
+
+/*HDR*/
+void show_stat_info( MBG_MSG_CTL *pmctl )
+{
+ STAT_INFO stat_info;
+ int rc;
+
+ printf( fmt, "Receiver status:" );
+
+ rc = mbgextio_get_stat_info( pmctl, &stat_info );
+
+ if ( rc != TR_COMPLETE )
+ {
+ check_rc( rc );
+ return;
+ }
+
+ print_stat_info( &stat_info );
+
+} /* show_stat_info */
@@ -454,17 +628,9 @@ void show_synth( MBG_MSG_CTL *pmctl )
/*HDR*/
void set_synth( void )
{
- RECEIVER_INFO receiver_info;
SYNTH synth = { 0 };
int rc;
- // First read receiver info to see whether the device
- // provides a synthesizer.
- rc = get_receiver_info( &mctl, &receiver_info );
-
- if ( rc < 0 )
- return; // error msg has already been printed
-
if ( !( receiver_info.features & GPS_HAS_SYNTH ) )
{
printf( "The device doesn't provide a synthesizer.\n" );
@@ -474,7 +640,7 @@ void set_synth( void )
// In this example we set the synthesizer frequency to
// 1 kHz, and the phase to 180 degrees.
// The effective frequency is: (freq/10)*(10^^range)
-
+
synth.freq = 1000; // base frequency value in 1/10 Hz Units
synth.range = 1; // multiplier 10^^range
synth.phase = 1800; // phase in 1/10 degrees
@@ -495,18 +661,10 @@ void set_synth( void )
/*HDR*/
void set_pout_mode( void )
{
- RECEIVER_INFO receiver_info;
POUT_INFO_IDX pout_info_idx;
POUT_SETTINGS pout_settings = { 0 }; // new settings, init'd to 0
uint16_t pout_idx = 0; // index of the programmable output
int rc;
-
- // First read receiver info to see whether programmable pulse outputs
- // are supported by the device.
- rc = get_receiver_info( &mctl, &receiver_info );
-
- if ( rc < 0 )
- return; // error msg has already been printed
if ( receiver_info.n_prg_out == 0 )
{
@@ -516,7 +674,7 @@ void set_pout_mode( void )
// valid pout_idx numbers include 0..receiver_info.n_prg_out-1
- if ( pout_idx >= receiver_info.n_prg_out )
+ if ( pout_idx >= receiver_info.n_prg_out )
{
printf( "Programmable output index %u out of range (%u..%u)\n",
pout_idx, 0, receiver_info.n_prg_out - 1 );
@@ -572,8 +730,6 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
int i;
- printf( fmt, "Serial ports:" );
-
rc = mbgextio_get_port_parm( pmctl, &port_parm );
if ( rc != TR_COMPLETE )
@@ -610,6 +766,102 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
+/*HDR*/
+void show_port_settings( MBG_MSG_CTL *pmctl )
+{
+ const char *mode_names[N_STR_MODE] = DEFAULT_ENG_MODE_NAMES;
+ STR_TYPE_INFO sti[N_STR_TYPE_MAX];
+ STR_TYPE_INFO_IDX stii;
+ PORT_INFO_IDX pii;
+ PORT_SETTINGS *p;
+ int rc;
+ int i;
+
+ printf( fmt, "Serial ports:" );
+
+ if ( receiver_info.model_code == GPS_MODEL_UNKNOWN )
+ {
+ // This may be an old GPS model which does not provide
+ // a receiver info structure.
+ show_port_parm( pmctl );
+ return;
+ }
+
+ // The number of serial ports and time string formats supported
+ // by this device is specified in the receiver info structure.
+
+ // Read time string information
+
+ for ( i = 0; i < receiver_info.n_str_type; i++ )
+ {
+ rc = mbgextio_get_str_type_info_idx( pmctl, &stii, (uint16_t) i );
+
+ if ( rc != TR_COMPLETE )
+ {
+ check_rc( rc );
+ return;
+ }
+
+ if ( stii.idx != i )
+ {
+ printf( "** Info for string type %i requested, but for %i received.\n",
+ stii.idx, i );
+ return;
+ }
+
+ sti[i] = stii.str_type_info;
+ }
+
+
+ // Read and print port settings
+
+ for ( i = 0; ; )
+ {
+ rc = mbgextio_get_port_info_idx( pmctl, &pii, (uint16_t) i );
+
+ if ( rc != TR_COMPLETE )
+ {
+ check_rc( rc );
+ return;
+ }
+
+ if ( pii.idx != i )
+ {
+ printf( "** Info for port %i requested, but for %i received.\n",
+ pii.idx, i );
+ return;
+ }
+
+ p = &pii.port_info.port_settings;
+
+ printf( "COM%i: %5lu Baud, %s",
+ i,
+ (ulong) p->parm.baud_rate,
+ p->parm.framing
+ );
+
+ // Make sure indices received from the device do not exceed
+ // maximum numbers supported by this program.
+
+ if ( p->str_type >= N_STR_TYPE_MAX )
+ printf( " (string type exceeds max)" );
+ else
+ if ( p->mode >= N_STR_MODE )
+ printf( " (string mode exceeds max)" );
+ else
+ printf( ", \"%s\" string %s", sti[p->str_type].long_name, mode_names[p->mode] );
+
+ printf( "\n" );
+
+ if ( ++i >= receiver_info.n_com_ports )
+ break;
+
+ printf( fmt, "" );
+ }
+
+} /* show_port_settings */
+
+
/*HDR*/ static
void exit_gpsxmple( void )
@@ -640,6 +892,12 @@ int check_command_line( int argc, char *argv[] )
for ( i = 1; i < argc; i++ )
{
+ if ( strcmp( argv[i], "-a" ) == 0 )
+ {
+ must_send_auto = 1;
+ continue;
+ }
+
if ( strcmp( argv[i], "-?" ) == 0 )
{
must_print_usage = 1;
@@ -696,6 +954,14 @@ int check_command_line( int argc, char *argv[] )
}
#endif
+ #if _USE_SERIAL_IO
+ if ( strcmp( argv[i], "-F" ) == 0 )
+ {
+ must_force_connection = 1;
+ continue;
+ }
+ #endif
+
if ( argv[i][0] != '-' )
target = argv[i];
else
@@ -722,21 +988,20 @@ int check_command_line( int argc, char *argv[] )
#endif
"\n"
"Options\n"
- " -? or -h Print this usage\n"
+ " -? or -h Print this usage\n"
#if _USE_SOCKET_IO
" -n Connect to network target, not serial port\n"
- " -n passwd Use specified password to connect\n"
- #endif
- #if _USE_SERIAL_IO
- " -b speed serial port baud rate, default: 19200\n"
+ " -p passwd Use specified password to connect\n"
#endif
#if _USE_SERIAL_IO
- " -f xxx serial port framing, default: 8N1\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"
#if _USE_SERIAL_IO
- " %s Connect to serial port using 19200/8N1\n"
+ " %s Connect to serial port %s using %lu/%s\n"
#endif
#if _USE_SOCKET_IO
" %s -n -p secret 172.16.1.1 Connect to the specified network host\n"
@@ -744,7 +1009,14 @@ int check_command_line( int argc, char *argv[] )
"\n",
argv[0]
#if _USE_SERIAL_IO
+ , (long) default_baudrate
+ , framing
+ , (long) default_baudrate
+ , framing
, argv[0]
+ , default_target
+ , (long) default_baudrate
+ , framing
#endif
#if _USE_SOCKET_IO
, argv[0]
@@ -767,6 +1039,9 @@ int main( int argc, char *argv[] )
printf( "\n\n\nExample Program Accessing Meinberg GPS Receiver\n" );
+ baudrate = default_baudrate;
+ framing = default_framing;
+
if ( check_command_line( argc, argv ) < 0 )
return 1;
@@ -790,8 +1065,17 @@ int main( int argc, char *argv[] )
}
#endif
-
#if _USE_SERIAL_IO
+ if ( must_force_connection )
+ {
+ printf( "Trying to force connection to 19200/8N1 ..." );
+ mbgextio_force_connection( target );
+ printf( "\n" );
+
+ baudrate = default_baudrate;
+ framing = default_framing;
+ }
+
rc = mbgextio_open_serial( &mctl, target, baudrate, framing );
if ( rc < 0 )
@@ -801,7 +1085,7 @@ int main( int argc, char *argv[] )
}
printf( " (Using %s with %li baud, %s)\n\n",
- target, baudrate, framing );
+ target, (long) baudrate, framing );
goto doit;
#endif
@@ -817,29 +1101,37 @@ doit:
// now start communication with whichever device has been opened above:
+ get_receiver_info( &mctl, &receiver_info );
+ check_receiver_info( &receiver_info, 1 );
+
/* display system specific values */
show_sw_rev( &mctl );
-
- show_stat( &mctl );
-
+ show_bvar_stat( &mctl );
+ show_stat_info( &mctl );
show_pos( &mctl );
-
show_tzdl( &mctl );
-
- show_port_parm( &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();
+// set_synth();
+// set_pout_mode();
if ( str_mode_0 != STR_PER_SEC )
return 0; // device will not send time automatically
+ if ( !must_send_auto )
+ return 0;
+
printf( "\n" );
+ // We will start to wait for automatically transmitted messages
+ // which require a longer timeout than we have used by default
+ // to wait for replies to dedicated request messages.
+ 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 );
@@ -847,9 +1139,9 @@ doit:
{
MBG_MSG_BUFF *pmb;
MSG_DATA *p;
-
- rc = mbgextio_get_data( &mctl, -1 );
+
+ rc = mbgextio_rcv_msg( &mctl, -1 );
if ( rc != TR_COMPLETE )
{
diff --git a/mbglib/common/aes128.c b/mbglib/common/aes128.c
index 6a48d24..542467b 100644
--- a/mbglib/common/aes128.c
+++ b/mbglib/common/aes128.c
@@ -1,109 +1,122 @@
-
-/*
- * FIPS-197 compliant AES implementation
+/**************************************************************************
+ *
+ * $Id: aes128.c 1.2 2009/10/01 14:03:09 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * FIPS-197 compliant AES implementation
*
+ * -----------------------------------------------------------------------
+ * $Log: aes128.c $
+ * Revision 1.2 2009/10/01 14:03:09 martin
+ * Added standard file header.
+ * Fixed compiler warnings.
+ * Support prototype generation by makehdr tool.
+ * Use standard fixed-size data types.
+ * Code cleanup.
+ * Revision 1.1 2004/05/25 12:36:21 andre
+ * Initial revision.
*
- */
+ **************************************************************************/
+
+#define _AES128
+ #include <aes128.h>
+#undef _AES128
-#include "aes128.h"
#include <string.h>
#include <stdio.h>
-typedef unsigned char uchar;
-typedef unsigned long ulong;
+
/* forward S-box & tables */
-ulong FSb[256];
-ulong FT0[256];
-ulong FT1[256];
-ulong FT2[256];
-ulong FT3[256];
+#define FTABLE_ENTRIES 256
+static ulong FSb[FTABLE_ENTRIES];
+static ulong FT0[FTABLE_ENTRIES];
+static ulong FT1[FTABLE_ENTRIES];
+static ulong FT2[FTABLE_ENTRIES];
+static ulong FT3[FTABLE_ENTRIES];
-/* round constants */
-ulong RCON[10];
+/* rounding constants */
+#define RCON_TABLE_ENTRIES 10
+ulong RCON[RCON_TABLE_ENTRIES];
/* tables generation flag */
-
-int do_init = 1;
+static int initialized;
-#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \
- ( ( x & 0xFFFFFFFF ) >> 8 ) )
+#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFFUL ) | \
+ ( ( x & 0xFFFFFFFFUL ) >> 8 ) )
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
#define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 )
+
+/*HDR*/
void aes_gen_tables( void )
{
- int i;
- uchar x, y;
- uchar pow[256];
- uchar log[256];
-
- do_init = 0;
-
- /* compute pow and log tables over GF(2^8) */
-
- for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) )
- {
- pow[i] = x;
- log[x] = i;
- }
-
- /* calculate the round constants */
+ int i;
+ uint8_t x, y;
+ uint8_t pow[FTABLE_ENTRIES];
+ uint8_t log[FTABLE_ENTRIES];
- for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) )
- {
- RCON[i] = (ulong) x << 24;
- }
+ /* compute pow and log tables over GF(2^8) */
- /* generate the forward and reverse S-boxes */
+ for ( i = 0, x = 1; i < FTABLE_ENTRIES; i++, x ^= XTIME( x ) )
+ {
+ pow[i] = x;
+ log[x] = i;
+ }
- FSb[0x00] = 0x63;
+ /* calculate the round constants */
- for( i = 1; i < 256; i++ )
- {
- x = pow[255 - log[i]];
+ for ( i = 0, x = 1; i < RCON_TABLE_ENTRIES; i++, x = XTIME( x ) )
+ RCON[i] = (ulong) x << 24;
- y = x; y = ( y << 1 ) | ( y >> 7 );
- x ^= y; y = ( y << 1 ) | ( y >> 7 );
- x ^= y; y = ( y << 1 ) | ( y >> 7 );
- x ^= y; y = ( y << 1 ) | ( y >> 7 );
- x ^= y ^ 0x63;
+ /* generate the forward and reverse S-boxes */
- FSb[i] = x;
- }
+ FSb[0x00] = 0x63;
- /* generate the forward and reverse tables */
+ for ( i = 1; i < FTABLE_ENTRIES; i++ )
+ {
+ x = pow[255 - log[i]];
- for( i = 0; i < 256; i++ )
- {
+ y = x; y = ( y << 1 ) | ( y >> 7 );
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
+ x ^= y ^ 0x63;
- x = FSb[i];
- y = XTIME( x );
+ FSb[i] = x;
+ }
- FT0[i] = (ulong) ( x ^ y ) ^
- ( (ulong) x << 8 ) ^
- ( (ulong) x << 16 ) ^
- ( (ulong) y << 24 );
+ /* generate the forward and reverse tables */
- FT0[i] &= 0xFFFFFFFF;
+ for ( i = 0; i < FTABLE_ENTRIES; i++ )
+ {
+ x = (uint8_t) FSb[i];
+ y = XTIME( x );
- FT1[i] = ROTR8( FT0[i] );
- FT2[i] = ROTR8( FT1[i] );
- FT3[i] = ROTR8( FT2[i] );
+ FT0[i] = (ulong) ( x ^ y ) ^
+ ( (ulong) x << 8 ) ^
+ ( (ulong) x << 16 ) ^
+ ( (ulong) y << 24 );
- }
-}/*aes_gen_tables*/
+ FT0[i] &= 0xFFFFFFFFUL;
+ FT1[i] = ROTR8( FT0[i] );
+ FT2[i] = ROTR8( FT1[i] );
+ FT3[i] = ROTR8( FT2[i] );
+ }
+} /* aes_gen_tables */
@@ -119,144 +132,153 @@ void aes_gen_tables( void )
#define PUT_ulong(n,b,i) \
{ \
- (b)[(i) ] = (uchar) ( (n) >> 24 ); \
- (b)[(i) + 1] = (uchar) ( (n) >> 16 ); \
- (b)[(i) + 2] = (uchar) ( (n) >> 8 ); \
- (b)[(i) + 3] = (uchar) ( (n) ); \
+ (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (uint8_t) ( (n) ); \
}
+
+
+
/* decryption key schedule tables */
+
/* AES key scheduling routine */
-int aes128_set_key( aes128_context *ctx, unsigned char *key )
+/*HDR*/
+int aes128_set_key( aes128_context *ctx, uint8_t *key )
{
- int i;
- ulong *RK;
+ int i;
+ ulong *RK;
- if ( do_init ){
- aes_gen_tables();
- do_init = 0;
- }
+ if ( !initialized )
+ {
+ aes_gen_tables();
+ initialized = 1;
+ }
- RK = ctx->erk;
+ RK = ctx->erk;
- for( i = 0; i < 4; i++ ){
- GET_ulong( RK[i], key, i * 4 );
- }
+ for ( i = 0; i < 4; i++ )
+ GET_ulong( RK[i], key, i * 4 );
- /* setup encryption round keys */
- for( i = 0; i < 10; i++, RK += 4 )
- {
- RK[4] = RK[0] ^ RCON[i] ^
- ( FSb[ (uchar) ( RK[3] >> 16 ) ] << 24 ) ^
- ( FSb[ (uchar) ( RK[3] >> 8 ) ] << 16 ) ^
- ( FSb[ (uchar) ( RK[3] ) ] << 8 ) ^
- ( FSb[ (uchar) ( RK[3] >> 24 ) ] );
-
- RK[5] = RK[1] ^ RK[4];
- RK[6] = RK[2] ^ RK[5];
- RK[7] = RK[3] ^ RK[6];
- }
+ /* setup encryption round keys */
+ for ( i = 0; i < RCON_TABLE_ENTRIES; i++, RK += 4 )
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8_t) ( RK[3] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8_t) ( RK[3] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8_t) ( RK[3] ) ] << 8 ) ^
+ ( FSb[ (uint8_t) ( RK[3] >> 24 ) ] );
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+
+ return 0;
+
+} /* aes128_set_key */
- return( 0 );
-}/*aes128_set_key*/
/* AES 128-bit block encryption routine */
-void aes128_encrypt( aes128_context *ctx, uchar input[16], uchar output[16] )
+static /*HDR*/
+void aes128_encrypt( aes128_context *ctx, uint8_t input[16], uint8_t output[16] )
{
- ulong *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+ ulong *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
- RK = ctx->erk;
+ RK = ctx->erk;
- GET_ulong( X0, input, 0 ); X0 ^= RK[0];
- GET_ulong( X1, input, 4 ); X1 ^= RK[1];
- GET_ulong( X2, input, 8 ); X2 ^= RK[2];
- GET_ulong( X3, input, 12 ); X3 ^= RK[3];
+ GET_ulong( X0, input, 0 ); X0 ^= RK[0];
+ GET_ulong( X1, input, 4 ); X1 ^= RK[1];
+ GET_ulong( X2, input, 8 ); X2 ^= RK[2];
+ GET_ulong( X3, input, 12 ); X3 ^= RK[3];
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
-{ \
+ #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+ { \
RK += 4; \
\
- X0 = RK[0] ^ FT0[ (uchar) ( Y0 >> 24 ) ] ^ \
- FT1[ (uchar) ( Y1 >> 16 ) ] ^ \
- FT2[ (uchar) ( Y2 >> 8 ) ] ^ \
- FT3[ (uchar) ( Y3 ) ]; \
+ X0 = RK[0] ^ FT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \
+ FT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \
+ FT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \
+ FT3[ (uint8_t) ( Y3 ) ]; \
\
- X1 = RK[1] ^ FT0[ (uchar) ( Y1 >> 24 ) ] ^ \
- FT1[ (uchar) ( Y2 >> 16 ) ] ^ \
- FT2[ (uchar) ( Y3 >> 8 ) ] ^ \
- FT3[ (uchar) ( Y0 ) ]; \
+ X1 = RK[1] ^ FT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \
+ FT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \
+ FT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \
+ FT3[ (uint8_t) ( Y0 ) ]; \
\
- X2 = RK[2] ^ FT0[ (uchar) ( Y2 >> 24 ) ] ^ \
- FT1[ (uchar) ( Y3 >> 16 ) ] ^ \
- FT2[ (uchar) ( Y0 >> 8 ) ] ^ \
- FT3[ (uchar) ( Y1 ) ]; \
+ X2 = RK[2] ^ FT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \
+ FT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \
+ FT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \
+ FT3[ (uint8_t) ( Y1 ) ]; \
\
- X3 = RK[3] ^ FT0[ (uchar) ( Y3 >> 24 ) ] ^ \
- FT1[ (uchar) ( Y0 >> 16 ) ] ^ \
- FT2[ (uchar) ( Y1 >> 8 ) ] ^ \
- FT3[ (uchar) ( Y2 ) ]; \
-}
+ X3 = RK[3] ^ FT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \
+ FT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \
+ FT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \
+ FT3[ (uint8_t) ( Y2 ) ]; \
+ }
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
- /* last round */
+ /* last round */
- RK += 4;
+ RK += 4;
- X0 = RK[0] ^ ( FSb[ (uchar) ( Y0 >> 24 ) ] << 24 ) ^
- ( FSb[ (uchar) ( Y1 >> 16 ) ] << 16 ) ^
- ( FSb[ (uchar) ( Y2 >> 8 ) ] << 8 ) ^
- ( FSb[ (uchar) ( Y3 ) ] );
+ X0 = RK[0] ^ ( FSb[ (uint8_t) ( Y0 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8_t) ( Y1 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8_t) ( Y2 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8_t) ( Y3 ) ] );
- X1 = RK[1] ^ ( FSb[ (uchar) ( Y1 >> 24 ) ] << 24 ) ^
- ( FSb[ (uchar) ( Y2 >> 16 ) ] << 16 ) ^
- ( FSb[ (uchar) ( Y3 >> 8 ) ] << 8 ) ^
- ( FSb[ (uchar) ( Y0 ) ] );
+ X1 = RK[1] ^ ( FSb[ (uint8_t) ( Y1 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8_t) ( Y2 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8_t) ( Y3 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8_t) ( Y0 ) ] );
- X2 = RK[2] ^ ( FSb[ (uchar) ( Y2 >> 24 ) ] << 24 ) ^
- ( FSb[ (uchar) ( Y3 >> 16 ) ] << 16 ) ^
- ( FSb[ (uchar) ( Y0 >> 8 ) ] << 8 ) ^
- ( FSb[ (uchar) ( Y1 ) ] );
+ X2 = RK[2] ^ ( FSb[ (uint8_t) ( Y2 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8_t) ( Y3 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8_t) ( Y0 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8_t) ( Y1 ) ] );
- X3 = RK[3] ^ ( FSb[ (uchar) ( Y3 >> 24 ) ] << 24 ) ^
- ( FSb[ (uchar) ( Y0 >> 16 ) ] << 16 ) ^
- ( FSb[ (uchar) ( Y1 >> 8 ) ] << 8 ) ^
- ( FSb[ (uchar) ( Y2 ) ] );
+ X3 = RK[3] ^ ( FSb[ (uint8_t) ( Y3 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8_t) ( Y0 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8_t) ( Y1 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8_t) ( Y2 ) ] );
- PUT_ulong( X0, output, 0 );
- PUT_ulong( X1, output, 4 );
- PUT_ulong( X2, output, 8 );
- PUT_ulong( X3, output, 12 );
+ PUT_ulong( X0, output, 0 );
+ PUT_ulong( X1, output, 4 );
+ PUT_ulong( X2, output, 8 );
+ PUT_ulong( X3, output, 12 );
-}/*aes128_encrypt*/
+} /* aes128_encrypt */
/* buffer size must be an integer multiple of 16 */
-int aes_encrypt_buff ( unsigned char *p_data,
- unsigned char *p_key,
- unsigned char *p_init,
- int n ){
-
+/*HDR*/
+int aes_encrypt_buff( uint8_t *p_data,
+ uint8_t *p_key,
+ uint8_t *p_init,
+ int n )
+{
aes128_context ctx;
- unsigned char block_key[32];
+ uint8_t block_key[32];
if ( n % 16 != 0 )
- return ( -1 );
+ return -1;
memcpy ( block_key, p_init, 16 );
@@ -264,78 +286,73 @@ int aes_encrypt_buff ( unsigned char *p_data,
aes128_set_key( &ctx, p_key );
aes128_encrypt( &ctx, block_key, block_key );
- while ( n ){
-
+ while ( n )
+ {
// cipher feedback mode
{
int j;
- for( j = 0; j < 16; j++ )
- *( ( char * ) ( p_data + j ) ) ^= block_key[j];
+ for ( j = 0; j < 16; j++ )
+ *( (char *) ( p_data + j ) ) ^= block_key[j];
}
// encrypt 16 byte block
aes128_encrypt( &ctx, p_data, block_key );
p_data += 16;
- n-=16;
+ n -= 16;
}
- return ( 0 );
+ return 0;
-}/*aes_encrypt_buff*/
+} /* aes_encrypt_buff */
-/* buffer size must be an integer multiple of 16 */
-int aes_decrypt_buff ( unsigned char *p_data,
- unsigned char *p_key,
- unsigned char *p_init,
- int n ){
+/* buffer size must be an integer multiple of 16 */
+/*HDR*/
+int aes_decrypt_buff ( uint8_t *p_data,
+ uint8_t *p_key,
+ uint8_t *p_init,
+ int n )
+{
aes128_context ctx;
- unsigned char block_key[32];
- unsigned char p_tmp[32];
+ uint8_t block_key[32];
+ uint8_t p_tmp[32];
if ( n % 16 != 0 )
- return ( -1 );
+ return -1;
- memcpy ( block_key, p_init, 16 );
+ memcpy( block_key, p_init, 16 );
// setup the 1st. block key
aes128_set_key( &ctx, p_key );
aes128_encrypt( &ctx, block_key, block_key );
- while ( n ){
+ while ( n )
+ {
int j;
// decrypt first block and save encrypted
// block for new block key calculation
- for( j = 0; j < 16; j++ ){
- p_tmp[j] = *( ( char * ) ( p_data + j ) );
- *( ( char * ) ( p_data + j ) ) ^= block_key[j];
+ for ( j = 0; j < 16; j++ )
+ {
+ p_tmp[j] = *( (char *) ( p_data + j ) );
+ *( (char *) ( p_data + j ) ) ^= block_key[j];
}
// calculate new block key
aes128_encrypt( &ctx, p_tmp, block_key );
p_data += 16;
- n-=16;
+ n -= 16;
}
- return ( 0 );
-
-}/*aes_decrypt_buff*/
-
-
-
-
-
-
-
-
+ return 0;
+} /* aes_decrypt_buff */
diff --git a/mbglib/common/aes128.h b/mbglib/common/aes128.h
index 10cd0c3..c2fe912 100644
--- a/mbglib/common/aes128.h
+++ b/mbglib/common/aes128.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: aes128.h 1.2 2006/08/22 15:28:11 martin REL_M $
+ * $Id: aes128.h 1.3 2009/10/01 14:04:52 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: aes128.h $
- * Revision 1.2 2006/08/22 15:28:11 martin
+ * Revision 1.3 2009/10/01 14:04:52 martin
+ * Code cleanup.
+ * Updated function prototypes.
+ * Revision 1.2 2006/08/22 15:28:11Z martin
* Added standard file header.
* Added definition for AES_BLOCK_SIZE.
*
@@ -21,7 +24,10 @@
/* Other headers to be included */
-#ifdef _GPSUTILS
+#include <words.h>
+
+
+#ifdef _AES128
#define _ext
#define _DO_INIT
#else
@@ -51,10 +57,10 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
-void aes_gen_tables( void );
-int aes128_set_key( aes128_context *ctx, unsigned char *key );
-int aes_encrypt_buff ( unsigned char *p_data, unsigned char *p_key, unsigned char *p_init, int n );
-int aes_decrypt_buff ( unsigned char *p_data, unsigned char *p_key, unsigned char *p_init, int n );
+ void aes_gen_tables( void ) ;
+ int aes128_set_key( aes128_context *ctx, uint8_t *key ) ;
+ int aes_encrypt_buff( uint8_t *p_data, uint8_t *p_key, uint8_t *p_init, int n ) ;
+ int aes_decrypt_buff ( uint8_t *p_data, uint8_t *p_key, uint8_t *p_init, int n ) ;
/* ----- function prototypes end ----- */
diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h
index 47dd267..abc3977 100644
--- a/mbglib/common/gpsdefs.h
+++ b/mbglib/common/gpsdefs.h
@@ -1,15 +1,124 @@
/**************************************************************************
*
- * $Id: gpsdefs.h 1.51 2006/10/23 15:31:27 martin REL_M $
+ * $Id: gpsdefs.h 1.80 2009/09/28 14:55:53 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * General definitions to be used with Meinberg GPS clocks.
+ * General definitions to be used with Meinberg clocks.
+ * These definitions have initially be used with GPS devices only.
+ * However, more and more Meinberg non-GPS devices also use some of
+ * these definitions.
*
* -----------------------------------------------------------------------
* $Log: gpsdefs.h $
+ * 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
+ * Added definitions to support new model MGR170.
+ * Added definitions and commands to support configuration
+ * of navigation engine (currently supported by u-blox
+ * receivers only).
+ * Renamed simulation values in PTP_SETTINGS to reserved.
+ * Added "UNINITIALIZED" to PTP port state.
+ * Removed obsolete braces in initializer.
+ * Revision 1.78 2009/06/25 15:49:05Z martin
+ * Added macro _nano_time_negative().
+ * Revision 1.77 2009/06/08 19:22:32Z daniel
+ * Added feature GPS_HAS_PTP.
+ * Added preliminary structures and definitions for PTP
+ * configuration and state.
+ * Added IP4_ADDR type.
+ * Added Bitmask IP4_MSK_DHCP.
+ * Added byte swapper macros for LAN and PTP structures.
+ * Moved LAN interface configuration definitions here.
+ * Moved DAC_VAL definition here.
+ * Changed type iof FPGA_INFO::start_addr for non-firmware applications.
+ * Revision 1.76 2009/04/08 08:26:56 daniel
+ * Added feature GPS_FEAT_IRIG_CTRL_BITS.
+ * Revision 1.75 2009/03/19 14:06:39Z martin
+ * Modified string initializer for unknown oscillator type.
+ * Revision 1.74 2009/03/18 13:45:53 daniel
+ * Added missing commas in
+ * MBG_DEBUG_STATUS_STRS initializer.
+ * Adjusted some comments for doxygen parser.
+ * Revision 1.73 2009/03/10 16:55:33Z martin
+ * Support configurable time scales GPS and TAI.
+ * Defined extended TM status type and associated flags.
+ * Added definition TM_MSK_TIME_VALID.
+ * Added some macros to swap endianess of structures.
+ * Revision 1.72 2008/11/28 09:26:21Z daniel
+ * Added definitions to support WWVB511
+ * Revision 1.71 2008/10/31 14:31:44Z martin
+ * Added definitions for TCR170PEX.
+ * Revision 1.70 2008/09/18 11:14:39 martin
+ * Added definitions to support GEN170.
+ * Revision 1.69 2008/09/15 14:16:17 martin
+ * Added more macros to convert the endianess of structures.
+ * Added N_COM_HS to the enumeration of handshake modes.
+ * Added MBG_PS_... codes.
+ * Revision 1.68 2008/08/25 10:51:13 martin
+ * Added definitions for PTP270PEX and FRC511PEX.
+ * Revision 1.67 2008/07/17 08:54:52Z martin
+ * Added macros to convert the endianess of structures.
+ * Added multiref fixed frequency source.
+ * Revision 1.66 2008/05/19 14:49:07 daniel
+ * Renamed s_addr to start_addr in FPGA_INFO.
+ * Revision 1.65 2008/05/19 09:00:01Z martin
+ * Added definitions for GPS162.
+ * Added FPGA_INFO and GPS_HAS_FPGA.
+ * Added FPGA_START_INFO and associated definitions.
+ * Added new XMRS status XMRS_..._NOT_SETTLED.
+ * Added initializer XMULTI_REF_STATUS_INVALID.
+ * Revision 1.64 2008/01/17 11:50:33Z daniel
+ * Made IGNORE_LOCK bit maskable.
+ * Revision 1.63 2008/01/17 11:42:09Z daniel
+ * Made comments compatible for Doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.62 2007/11/15 13:23:33Z martin
+ * Decide whether other Meinberg headers are to be included depending on whether
+ * CLOCK_MEINBERG is defined (as with NTP) or not. Previous versions checked
+ * for "PACKAGE" which is also defined by the Borland C++ build environment, though.
+ * Revision 1.61 2007/11/13 13:28:54 daniel
+ * Added definitions to support GPS170PEX.
+ * Revision 1.60 2007/09/13 12:37:35Z martin
+ * Modified and added initializers for TZDL.
+ * Added multiref source PTP over E1.
+ * Added codes for MSF511 and GRC170 devices.
+ * Modified XMULTI_REF_SETTINGS and XMULTI_REF_STATUS structures.
+ * Avoid inclusion of other Meinberg headers in non-Meinberg projects.
+ * Added device classification macros _mbg_rcvr_is_...().
+ * Modified feature name string initializer for non-GPS devices.
+ * Updated some comments.
+ * Removed some obsolete comments.
+ * Revision 1.59 2007/07/19 07:41:56Z martin
+ * Added symbol MBG_REF_OFFS_NOT_CFGD.
+ * Revision 1.58 2007/05/21 15:46:44Z martin
+ * Fixed a typo.
+ * Revision 1.57 2007/03/29 12:20:43 martin
+ * Fixed some TZDL initializers.
+ * Revision 1.56 2007/02/14 14:17:10Z andre
+ * bug fixed in mask XMRS_MSK_NO_CONN
+ * Revision 1.55 2007/02/06 16:23:18Z martin
+ * Added definitions for AM511.
+ * Made SVNO unsigned.
+ * Added support for OPT_SETTINGS.
+ * Added XMULTI_REF_... definitions.
+ * Added string initializer DEFAULT_FREQ_RANGES.
+ * Revision 1.54 2007/01/04 11:39:39Z martin
+ * Added definitions for TCR511.
+ * Added definition GPS_FEAT_5_MHZ.
+ * Updated some comments related to duplicate features/options
+ * IGNORE_LOCK and EMU_SYNC.
+ * Revision 1.53 2006/12/13 09:31:49 martin
+ * Added feature flag for ignore_lock.
+ * Revision 1.52 2006/12/12 15:47:18 martin
+ * Added MBG_DEBUG_STATUS type and associated definitions.
+ * Added definition GPS_HAS_REF_OFFS.
+ * Moved PCPS_REF_OFFS and associated definitions from pcpsdefs.h here
+ * and renamed them to MBG_REF_OFFS, etc.
* Revision 1.51 2006/10/23 15:31:27 martin
* Added definitions for GPS170.
* Added definitions for new multi_ref sources IRIG, NTP, and PTP.
@@ -69,7 +178,7 @@
* Revision 1.31 2004/07/08 08:30:36Z martin
* Added feature GPS_FEAT_RCV_TIMEOUT.
* Revision 1.30 2004/06/21 13:38:42 martin
- * New flag MBG_OPT_BIT_EMU_SYNC/MBG_OPT_BIT_EMU_SYNC
+ * New flag MBG_OPT_BIT_EMU_SYNC/MBG_OPT_FLAG_EMU_SYNC
* lets the receicer emulate/pretend to be always synchronized.
* Revision 1.30 2004/06/21 13:35:46Z martin
* Revision 1.29 2004/06/16 12:47:53Z martin
@@ -160,8 +269,18 @@
/* Other headers to be included */
-#include <words.h>
-#include <use_pack.h>
+#if defined( HAVE_CONFIG_H )
+ // this is mainly to simplify usage in non-Meinberg projects
+ #include <config.h>
+#endif
+
+// CLOCK_MEINBERG is defined in NTP's config.h if configured
+// to support Meinberg clocks.
+#if !defined( CLOCK_MEINBERG )
+ // avoid having to use these headers in non-Meinberg projects
+ #include <words.h>
+ #include <use_pack.h>
+#endif
#if defined( _USE_PACK ) // set byte alignment
@@ -199,7 +318,7 @@
#endif
-typedef int16_t SVNO; /* the number of a SV */
+typedef uint16_t SVNO; /* the number of a SV */
typedef uint16_t HEALTH; /* a SV's health code */
typedef uint16_t CFG; /* a SV's configuration code */
typedef uint16_t IOD; /* Issue-Of-Data code */
@@ -210,30 +329,45 @@ typedef uint16_t IOD; /* Issue-Of-Data code */
#ifndef _CSUM_DEFINED
typedef uint16_t CSUM;
#define _CSUM_DEFINED
+
+ #define _mbg_swab_csum( _p ) _mbg_swab16( _p )
#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.
+/**
+ 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.
+*/
typedef uint16_t GPS_CMD;
+#define _mbg_swab_gps_cmd( _p ) _mbg_swab16( _p )
-/* a struct used to hold the software revision information */
+/**
+ A struct used to hold the software revision information
+ */
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; /**< 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 */
} SW_REV;
+#define _mbg_swab_sw_rev( _p ) \
+{ \
+ _mbg_swab16( &(_p)->code ); \
+}
-typedef uint16_t BVAR_STAT; /* holds status of battery buffered vars */
-// The bits defined below are set in BVAR_STAT if the corresponding
-// parameters are NOT valid and complete:
+typedef uint16_t BVAR_STAT; /**< holds status of battery buffered vars */
+#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:
+*/
enum
{
BVAR_BIT_CFGH_INVALID,
@@ -250,7 +384,7 @@ enum
#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID )
#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID )
-// bit mask for all defined bits
+/**< bit mask for all defined bits */
#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 )
@@ -264,6 +398,12 @@ typedef struct
int16_t range; /* an optional base 10 exponent */
} FIXED_FREQ_INFO;
+#define _mbg_swab_fixed_freq_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->khz_val ); \
+ _mbg_swab16( &(_p)->range ); \
+}
+
/*
@@ -273,32 +413,42 @@ typedef struct
* this, or may not support this at all.
*/
-/*
+/**
* The structure is ordered in a way that all fields
* except chars or arrays of chars are word-aligned.
*/
typedef struct
{
- uint16_t model_code; /* identifier for receiver model */
- SW_REV sw_rev; /* software revision and ID */
- char model_name[GPS_ID_STR_SIZE]; /* ASCIIZ, name of receiver model */
- char sernum[GPS_ID_STR_SIZE]; /* ASCIIZ, serial number */
- 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 */
- 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 */
- uint8_t n_ucaps; /* number of user time capture inputs */
- uint8_t n_com_ports; /* number of on-board serial ports */
- uint8_t n_str_type; /* max num of string types supported by any port */
- uint8_t n_prg_out; /* number of programmable pulse outputs */
- uint16_t flags; /* additional information, see below */
+ uint16_t model_code; /**< identifier for receiver model */
+ SW_REV sw_rev; /**< software revision and ID */
+ char model_name[GPS_ID_STR_SIZE]; /**< ASCIIZ, name of receiver model */
+ char sernum[GPS_ID_STR_SIZE]; /**< ASCIIZ, serial number */
+ 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 */
+ 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 */
+ uint8_t n_ucaps; /**< number of user time capture inputs */
+ uint8_t n_com_ports; /**< number of on-board serial ports */
+ uint8_t n_str_type; /**< max num of string types supported by any port */
+ uint8_t n_prg_out; /**< number of programmable pulse outputs */
+ uint16_t flags; /**< additional information, see below */
} RECEIVER_INFO;
+#define _mbg_swab_receiver_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->model_code ); \
+ _mbg_swab_sw_rev( &(_p)->sw_rev ); \
+ _mbg_swab16( &(_p)->ticks_per_sec ); \
+ _mbg_swab32( &(_p)->features ); \
+ _mbg_swab_fixed_freq_info( &(_p)->fixed_freq ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
-/*
+
+/**
* Valid codes for RECEIVER_INFO.model_code:
*/
enum
@@ -318,10 +468,28 @@ enum
GPS_MODEL_GPS170PCI,
GPS_MODEL_PZF511,
GPS_MODEL_GPS170,
+ GPS_MODEL_TCR511,
+ GPS_MODEL_AM511,
+ GPS_MODEL_MSF511,
+ GPS_MODEL_GRC170,
+ GPS_MODEL_GPS170PEX,
+ GPS_MODEL_GPS162,
+ GPS_MODEL_PTP270PEX,
+ GPS_MODEL_FRC511PEX,
+ GPS_MODEL_GEN170,
+ GPS_MODEL_TCR170PEX,
+ GPS_MODEL_WWVB511,
+ GPS_MODEL_MGR170,
N_GPS_MODEL
+ /* If new model codes are added then care must be taken
+ * to update the associated string initializers below
+ * accordingly, and to check whether the classification macros
+ * also cover the new model names. */
};
+
+
/*
* String initializers for each of the GPS
* receiver models enum'ed above:
@@ -341,6 +509,18 @@ enum
#define GPS_MODEL_NAME_GPS170PCI "GPS170PCI"
#define GPS_MODEL_NAME_PZF511 "PZF511"
#define GPS_MODEL_NAME_GPS170 "GPS170"
+#define GPS_MODEL_NAME_TCR511 "TCR511"
+#define GPS_MODEL_NAME_AM511 "AM511"
+#define GPS_MODEL_NAME_MSF511 "MSF511"
+#define GPS_MODEL_NAME_GRC170 "GRC170"
+#define GPS_MODEL_NAME_GPS170PEX "GPS170PEX"
+#define GPS_MODEL_NAME_GPS162 "GPS162"
+#define GPS_MODEL_NAME_PTP270PEX "PTP270PEX"
+#define GPS_MODEL_NAME_FRC511PEX "FRC511PEX"
+#define GPS_MODEL_NAME_GEN170 "GEN170"
+#define GPS_MODEL_NAME_TCR170PEX "TCR170PEX"
+#define GPS_MODEL_NAME_WWVB511 "WWVB511"
+#define GPS_MODEL_NAME_MGR170 "MGR170"
/*
@@ -365,11 +545,95 @@ enum
GPS_MODEL_NAME_GPS164, \
GPS_MODEL_NAME_GPS170PCI, \
GPS_MODEL_NAME_PZF511, \
- GPS_MODEL_NAME_GPS170 \
+ GPS_MODEL_NAME_GPS170, \
+ GPS_MODEL_NAME_TCR511, \
+ GPS_MODEL_NAME_AM511, \
+ GPS_MODEL_NAME_MSF511, \
+ GPS_MODEL_NAME_GRC170, \
+ GPS_MODEL_NAME_GPS170PEX, \
+ GPS_MODEL_NAME_GPS162, \
+ GPS_MODEL_NAME_PTP270PEX, \
+ GPS_MODEL_NAME_FRC511PEX, \
+ GPS_MODEL_NAME_GEN170, \
+ GPS_MODEL_NAME_TCR170PEX, \
+ GPS_MODEL_NAME_WWVB511, \
+ GPS_MODEL_NAME_MGR170 \
}
/*
+ * The macros below can be used to classify a receiver,
+ * e.g. depending on the time source and/or depending on
+ * whether it's a plug-in card or an external device.
+ */
+
+#define _mbg_rcvr_is_plug_in( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "PC" ) || \
+ ( strstr( (_p_ri)->model_name, "PEX" ) )
+
+#define _mbg_rcvr_is_gps( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "GPS" ) || \
+ ( strstr( (_p_ri)->model_name, "MGR" ) )
+
+#define _mbg_rcvr_is_mobile_gps( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "MGR" ) )
+
+#define _mbg_rcvr_is_gps_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_gps( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_irig( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "TCR" ) )
+
+#define _mbg_rcvr_is_irig_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_irig( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_dcf77_am( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "AM" ) )
+
+#define _mbg_rcvr_is_dcf77_am_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_am( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_dcf77_pzf( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "PZF" ) )
+
+#define _mbg_rcvr_is_dcf77_pzf_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_pzf( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_any_dcf77( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_am( _p_ri ) || \
+ _mbg_rcvr_is_dcf77_pzf( _p_ri ) )
+
+#define _mbg_rcvr_is_any_dcf77_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_any_dcf77( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_msf( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "MSF" ) )
+
+#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" ) )
+
+#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_glonass( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_wwvb( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "WWVB" ) )
+
+#define _mbg_rcvr_is_wwvb_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_wwvb( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+
+/**
* The classification codes for oscillators below
* are used with RECEIVER_INFO.osc_type. New codes
* must be appended to the enumeration, so the sequence
@@ -398,7 +662,7 @@ enum
*/
#define DEFAULT_GPS_OSC_NAMES \
{ \
- "- unknown -", \
+ "[unknown]", \
"TCXO LQ", \
"TCXO HQ", \
"OCXO LQ", \
@@ -440,22 +704,31 @@ enum
*/
-/*
+/**
* The codes below enumerate some features which may be
* supported by a given clock, or not.
*/
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 */
- N_GPS_FEATURE /* the number of valid features */
+ 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 */
};
@@ -469,7 +742,15 @@ enum
"IRIG In", \
"IPv4 LAN Interface", \
"Multiple Ref. Sources", \
- "GPS receive timeout" \
+ "Receive Timeout", \
+ "Ignore Lock", \
+ "5 MHz Output", \
+ "Ext. Multiple Ref. Src. Cfg.", \
+ "Supp. Optional Settings", \
+ "Configurable Time Scale", \
+ "Irig Control Bits", \
+ "PTP/IEEE1588", \
+ "Supp. Nav. Engine Settings" \
}
@@ -477,15 +758,26 @@ 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_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_REF_OFFS GPS_HAS_IRIG_RX
+
/*
* The features below are supported by default by older
@@ -505,22 +797,79 @@ enum
*/
#define GPS_OSC_CFG_SUPP 0x0001 // GPS_OSC_CFG supported
#define GPS_IRIG_FO_IN 0x0002 // IRIG input via fiber optics
+#define GPS_HAS_FPGA 0x0004 // device provides on-board FPGA
+
+
+/*
+ * If the GPS_HAS_FPGA flag is set in RECEIVER_INFO::flags then the card
+ * provides an FPGA and the following information about the FPGA is available:
+ */
+#define FPGA_NAME_LEN 31 // max name length
+#define FPGA_NAME_SIZE ( FPGA_NAME_LEN + 1 ) // size including trailing 0
+
+#define FPGA_INFO_SIZE 128
+
+typedef union
+{
+ struct
+ {
+ CSUM csum;
+ uint32_t fsize;
+ #if _IS_MBG_FIRMWARE
+ uint32_t start_addr;
+ #else
+ uint8_t *start_addr;
+ #endif
+ char name[FPGA_NAME_SIZE];
+ } hdr;
+
+ char b[FPGA_INFO_SIZE];
+
+} FPGA_INFO;
-/* Date and time referred to the linear time scale defined by GPS. */
-/* GPS time is defined by the number of weeks since midnight from */
-/* January 5, 1980 to January 6, 1980 plus the number of seconds of */
-/* the current week plus fractions of a second. GPS time differs from */
-/* UTC because UTC is corrected with leap seconds while GPS time scale */
-/* is continuous. */
+/*
+ * The definitions below are used to specify where a FPGA image is located
+ * in the flash memory:
+ */
typedef struct
{
- uint16_t wn; /* the week number since GPS has been installed */
- uint32_t sec; /* the second of that week */
- uint32_t tick; /* fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
+ CSUM csum;
+ uint16_t fpga_start_seg; // Number of the 4k block where an FPGA image is located
+} FPGA_START_INFO;
+
+#define DEFAULT_FPGA_START_SEG 0x60
+
+#define DEFAULT_FPGA_START_INFO \
+{ \
+ 0x1234 + DEFAULT_FPGA_START_SEG, \
+ DEFAULT_FPGA_START_SEG \
+}
+
+
+
+/**
+ Date and time referred to the linear time scale defined by GPS.
+ GPS time is defined by the number of weeks since midnight from
+ January 5, 1980 to January 6, 1980 plus the number of seconds of
+ the current week plus fractions of a second. GPS time differs from
+ UTC because UTC is corrected with leap seconds while GPS time scale
+ is continuous.
+*/
+typedef struct
+{
+ uint16_t wn; /**< the week number since GPS has been installed */
+ uint32_t sec; /**< the second of that week */
+ uint32_t tick; /**< fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
} T_GPS;
+#define _mbg_swab_t_gps( _p ) \
+{ \
+ _mbg_swab16( &(_p)->wn ); \
+ _mbg_swab32( &(_p)->sec ); \
+ _mbg_swab32( &(_p)->tick ); \
+}
/* Local date and time computed from GPS time. The current number */
@@ -545,6 +894,15 @@ typedef struct
uint16_t status; /* flags */
} TM_GPS;
+#define _mbg_swab_tm_gps( _p ) \
+{ \
+ _mbg_swab16( &(_p)->year ); \
+ _mbg_swab16( &(_p)->yday ); \
+ _mbg_swab32( &(_p)->frac ); \
+ _mbg_swab32( &(_p)->offs_from_utc ); \
+ _mbg_swab16( &(_p)->status ); \
+}
+
/* status flag bits used with conversion from GPS time to local time */
@@ -569,36 +927,61 @@ enum
TM_BIT_NO_POS /* position actually not verified, LOCK LED off */
};
+// Type of an extended TM status which is mainly used by the firmware.
+typedef uint32_t TM_STATUS_EXT; // extended status, mainly used by the firmware
+
+// The lower 16 bits of the TM_STATUS_X type correspond to those defined above,
+// and the upper bits are defined below:
+enum
+{
+ TM_BIT_SCALE_GPS = 16,
+ TM_BIT_SCALE_TAI
+ // the remaining bits are reserved
+};
+
/* bit masks corresponding to the flag bits above */
-#define TM_UTC ( 1U << TM_BIT_UTC )
-#define TM_LOCAL ( 1U << TM_BIT_LOCAL )
-#define TM_DL_ANN ( 1U << TM_BIT_DL_ANN )
-#define TM_DL_ENB ( 1U << TM_BIT_DL_ENB )
-#define TM_LS_ANN ( 1U << TM_BIT_LS_ANN )
-#define TM_LS_ENB ( 1U << TM_BIT_LS_ENB )
-#define TM_LS_ANN_NEG ( 1U << TM_BIT_LS_ANN_NEG )
+#define TM_UTC ( 1UL << TM_BIT_UTC )
+#define TM_LOCAL ( 1UL << TM_BIT_LOCAL )
+#define TM_DL_ANN ( 1UL << TM_BIT_DL_ANN )
+#define TM_DL_ENB ( 1UL << TM_BIT_DL_ENB )
+#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_EXT_SYNC ( 1U << TM_BIT_EXT_SYNC )
-#define TM_HOLDOVER ( 1U << TM_BIT_HOLDOVER )
-#define TM_ANT_SHORT ( 1U << TM_BIT_ANT_SHORT )
-#define TM_NO_WARM ( 1U << TM_BIT_NO_WARM )
-#define TM_ANT_DISCONN ( 1U << TM_BIT_ANT_DISCONN )
-#define TM_SYN_FLAG ( 1U << TM_BIT_SYN_FLAG )
-#define TM_NO_SYNC ( 1U << TM_BIT_NO_SYNC )
-#define TM_NO_POS ( 1U << TM_BIT_NO_POS )
+#define TM_EXT_SYNC ( 1UL << TM_BIT_EXT_SYNC )
+#define TM_HOLDOVER ( 1UL << TM_BIT_HOLDOVER )
+#define TM_ANT_SHORT ( 1UL << TM_BIT_ANT_SHORT )
+#define TM_NO_WARM ( 1UL << TM_BIT_NO_WARM )
+#define TM_ANT_DISCONN ( 1UL << TM_BIT_ANT_DISCONN )
+#define TM_SYN_FLAG ( 1UL << TM_BIT_SYN_FLAG )
+#define TM_NO_SYNC ( 1UL << TM_BIT_NO_SYNC )
+#define TM_NO_POS ( 1UL << TM_BIT_NO_POS )
+// The following bits are only used with the TM_STATUS_X type:
+#define TM_SCALE_GPS ( 1UL << TM_BIT_SCALE_GPS )
+#define TM_SCALE_TAI ( 1UL << TM_BIT_SCALE_TAI )
-/* a struct used to transmit information on date and time */
+#define TM_MSK_TIME_VALID ( TM_UTC | TM_SCALE_GPS | TM_SCALE_TAI )
+/**
+ This structure is used to transmit information on date and time
+ */
typedef struct
{
- int16_t channel; /* -1: the current time; 0, 1: capture 0, 1 */
- T_GPS t; /* time in GPS format */
- TM_GPS tm; /* that time converted to local time */
+ int16_t channel; /**< -1: the current time; 0, 1: capture 0, 1 */
+ T_GPS t; /**< time in GPS format */
+ TM_GPS tm; /**< that time converted to local time */
} TTM;
+#define _mbg_swab_ttm( _p ) \
+{ \
+ _mbg_swab16( &(_p)->channel ); \
+ _mbg_swab_t_gps( &(_p)->t ); \
+ _mbg_swab_tm_gps( &(_p)->tm ); \
+}
+
typedef struct
@@ -607,6 +990,16 @@ typedef struct
int32_t secs; // [seconds]
} NANO_TIME;
+#define _mbg_swab_nano_time( _p ) \
+{ \
+ _mbg_swab32( &(_p)->nano_secs ); \
+ _mbg_swab32( &(_p)->secs ); \
+}
+
+// The macro below checks if a NANO_TIME value is negative.
+#define _nano_time_negative( _nt ) \
+ ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) )
+
/* Two types of variables used to store a position. Type XYZ is */
@@ -619,53 +1012,61 @@ typedef struct
/* sequence and number of components of a cartesian position */
enum { XP, YP, ZP, N_XYZ };
- /* a type of array holding a cartesian position */
- typedef double XYZ[N_XYZ]; /* values are in [m] */
+ /** a type of array holding a cartesian position */
+ typedef double XYZ[N_XYZ]; /**< values are in [m] */
#define _XYZ_DEFINED
#endif
+#define _mbg_swab_xyz( _p ) _mbg_swab_doubles( _p, N_XYZ )
+
#ifndef _LLA_DEFINED
/* sequence and number of components of a geographic position */
enum { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
- /* a type of array holding a geographic position */
- typedef double LLA[N_LLA]; /* lon, lat in [rad], alt in [m] */
+ /** a type of array holding a geographic position */
+ typedef double LLA[N_LLA]; /**< lon, lat in [rad], alt in [m] */
#define _LLA_DEFINED
#endif
+#define _mbg_swab_lla( _p ) _mbg_swab_doubles( _p, N_LLA )
-/* Synthesizer parameters. Synthesizer frequency is expressed as a */
-/* four digit decimal number (freq) to be multiplied by 0.1 Hz and an */
-/* base 10 exponent (range). If the effective frequency is less than */
-/* 10 kHz its phase is synchronized corresponding to the variable phase. */
-/* Phase may be in a range from -360 deg to +360 deg with a resolution */
-/* of 0.1 deg, so the resulting numbers to be stored are in a range of */
-/* -3600 to +3600. */
+/**
+ @defgroup group_synth Synthesizer parameters
-/* Example: */
-/* Assume the value of freq is 2345 (decimal) and the value of phase is 900. */
-/* If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg. */
-/* If range == 1 the synthesizer will generate a 2345 Hz output frequency */
-/* and so on. */
+ Synthesizer frequency is expressed as a
+ four digit decimal number (freq) to be multiplied by 0.1 Hz and an
+ base 10 exponent (range). If the effective frequency is less than
+ 10 kHz its phase is synchronized corresponding to the variable phase.
+ Phase may be in a range from -360 deg to +360 deg with a resolution
+ of 0.1 deg, so the resulting numbers to be stored are in a range of
+ -3600 to +3600.
-/* Limitations: */
-/* If freq == 0 the synthesizer is disabled. If range == 0 the least */
-/* significant digit of freq is limited to 0, 3, 5 or 6. The resulting */
-/* frequency is shown in the examples below: */
-/* freq == 1230 --> 123.0 Hz */
-/* freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz) */
-/* freq == 1235 --> 123.5 Hz */
-/* freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz) */
+ Example:<br>
+ Assume the value of freq is 2345 (decimal) and the value of phase is 900.
+ If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg.
+ If range == 1 the synthesizer will generate a 2345 Hz output frequency
+ and so on.
-/* If range == MAX_RANGE the value of freq must not exceed 1000, so the */
-/* output frequency is limited to 10 MHz. */
+ Limitations:<br>
+ If freq == 0 the synthesizer is disabled. If range == 0 the least
+ significant digit of freq is limited to 0, 3, 5 or 6. The resulting
+ frequency is shown in the examples below:
+ - freq == 1230 --> 123.0 Hz
+ - freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz)
+ - freq == 1235 --> 123.5 Hz
+ - freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz)
-#define N_SYNTH_FREQ_DIGIT 4 /* number of digits to edit */
-#define MAX_SYNTH_FREQ 1000 /* if range == MAX_SYNTH_RANGE */
+ If range == MAX_RANGE the value of freq must not exceed 1000, so the
+ output frequency is limited to 10 MHz.
+ @{
+*/
+
+#define N_SYNTH_FREQ_DIGIT 4 /**< number of digits to edit */
+#define MAX_SYNTH_FREQ 1000 /**< if range == MAX_SYNTH_RANGE */
#define MIN_SYNTH_RANGE 0
#define MAX_SYNTH_RANGE 5
@@ -675,177 +1076,306 @@ typedef struct
#define MAX_SYNTH_PHASE 3600
-#define MAX_SYNTH_FREQ_EDIT 9999 /* max sequence of digits when editing */
+#define MAX_SYNTH_FREQ_EDIT 9999 /**< max sequence of digits when editing */
-/* The maximum frequency that can be configured for the synthesizer */
-#define MAX_SYNTH_FREQ_VAL 10000000UL /* 10 MHz */
+/** The maximum frequency that can be configured for the synthesizer */
+#define MAX_SYNTH_FREQ_VAL 10000000UL /**< 10 MHz */
/* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */
-/* The synthesizer phase will only be synchronized if the frequency */
-/* is below this limit: */
-#define SYNTH_PHASE_SYNC_LIMIT 10000UL /* 10 kHz */
+/**
+ The synthesizer phase will only be synchronized if the frequency
+ is below this limit: */
+#define SYNTH_PHASE_SYNC_LIMIT 10000UL /**< 10 kHz */
-/* the position of the decimal point if the frequency is */
-/* printed as 4 digit value */
+/**
+ the position of the decimal point if the frequency is
+ printed as 4 digit value */
#define _synth_dp_pos_from_range( _r ) \
( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 )
+/**
+ An initializer for commonly displayed synthesizer frequency units
+ (N_SYNTH_RANGE strings) */
+#define DEFAULT_FREQ_RANGES \
+{ \
+ "Hz", \
+ "kHz", \
+ "kHz", \
+ "kHz", \
+ "MHz", \
+ "MHz", \
+}
+
typedef struct
{
- int16_t freq; /* four digits used; scale: 0.1; e.g. 1234 -> 123.4 Hz */
- int16_t range; /* scale factor for freq; 0..MAX_SYNTH_RANGE */
- int16_t phase; /* -MAX_SYNTH_PHASE..+MAX_SYNTH_PHASE; >0 -> pulses later */
+ int16_t freq; /**< four digits used; scale: 0.1; e.g. 1234 -> 123.4 Hz */
+ int16_t range; /**< scale factor for freq; 0..MAX_SYNTH_RANGE */
+ int16_t phase; /**< -MAX_SYNTH_PHASE..+MAX_SYNTH_PHASE; >0 -> pulses later */
} SYNTH;
+#define _mbg_swab_synth( _p ) \
+{ \
+ _mbg_swab16( &(_p)->freq ); \
+ _mbg_swab16( &(_p)->range ); \
+ _mbg_swab16( &(_p)->phase ); \
+}
-/* The definitions below can be used to query the
- * current synthesizer state.
+
+/**
+ The definitions below can be used to query the
+ current synthesizer state.
*/
enum
{
- SYNTH_DISABLED, /* disbled by cfg, i.e. freq == 0.0 */
- SYNTH_OFF, /* not enabled after power-up */
- SYNTH_FREE, /* enabled, but not synchronized */
- SYNTH_DRIFTING, /* has initially been sync'd, but now running free */
- SYNTH_SYNC, /* fully synchronized */
- N_SYNTH_STATE /* the number of known states */
+ SYNTH_DISABLED, /**< disbled by cfg, i.e. freq == 0.0 */
+ SYNTH_OFF, /**< not enabled after power-up */
+ SYNTH_FREE, /**< enabled, but not synchronized */
+ SYNTH_DRIFTING, /**< has initially been sync'd, but now running free */
+ SYNTH_SYNC, /**< fully synchronized */
+ N_SYNTH_STATE /**< the number of known states */
};
typedef struct
{
- uint8_t state; /* state code as enumerated above */
- uint8_t flags; /* reserved, currently always 0 */
+ uint8_t state; /**< state code as enumerated above */
+ uint8_t flags; /**< reserved, currently always 0 */
} SYNTH_STATE;
+#define _mbg_swab_synth_state( _p ) _nop_macro_fnc()
+
#define SYNTH_FLAG_PHASE_IGNORED 0x01
+/** @} */ // endgroup
-/* Time zone/daylight saving parameters. */
+/**
+ @defgroup group_tzdl Time zone/daylight saving parameters
-/* the name of a time zone, 5 characters plus trailing zero */
+ Example: <br>
+ For automatic daylight saving enable/disable in Central Europe,
+ the variables are to be set as shown below: <br>
+ - offs = 3600L one hour from UTC
+ - offs_dl = 3600L one additional hour if daylight saving enabled
+ - tm_on = first Sunday from March 25, 02:00:00h ( year |= DL_AUTO_FLAG )
+ - tm_off = first Sunday from October 25, 03:00:00h ( year |= DL_AUTO_FLAG )
+ - name[0] == "CET " name if daylight saving not enabled
+ - name[1] == "CEST " name if daylight saving is enabled
+ @{
+*/
+
+/** the name of a time zone, 5 characters plus trailing zero */
typedef char TZ_NAME[6];
typedef struct
{
- int32_t offs; /* offset from UTC to local time [sec] */
- int32_t offs_dl; /* additional offset if daylight saving enabled [sec] */
- TM_GPS tm_on; /* date/time when daylight saving starts */
- TM_GPS tm_off; /* date/time when daylight saving ends */
- TZ_NAME name[2]; /* names without and with daylight saving enabled */
+ int32_t offs; /**< offset from UTC to local time [sec] */
+ int32_t offs_dl; /**< additional offset if daylight saving enabled [sec] */
+ TM_GPS tm_on; /**< date/time when daylight saving starts */
+ TM_GPS tm_off; /**< date/time when daylight saving ends */
+ TZ_NAME name[2]; /**< names without and with daylight saving enabled */
} TZDL;
-/* The constant below is defined beginning with software rev. 1.29. */
-/* If the year in tzdl.tm_on and tzdl.tm_off is or'ed with that constant, */
-/* the receiver automatically generates daylight saving year by year. */
-/* See GPSLIB.TXT for more information. */
+#define _mbg_swab_tzdl( _p ) \
+{ \
+ _mbg_swab32( &(_p)->offs ); \
+ _mbg_swab32( &(_p)->offs_dl ); \
+ _mbg_swab_tm_gps( &(_p)->tm_on ); \
+ _mbg_swab_tm_gps( &(_p)->tm_off ); \
+}
+
+/**
+ If the year in tzdl.tm_on and tzdl.tm_off is or'ed with that constant,
+ the receiver automatically generates daylight saving year by year.
+ */
#define DL_AUTO_FLAG 0x8000
-/* Example: */
-/* For automatic daylight saving enable/disable in Central Europe, */
-/* the variables are to be set as shown below: */
-/* offs = 3600L one hour from UTC */
-/* offs_dl = 3600L one additional hour if daylight saving enabled */
-/* tm_on = first Sunday from March 25, 02:00:00h ( year |= DL_AUTO_FLAG ) */
-/* tm_off = first Sunday from October 25, 03:00:00h ( year |= DL_AUTO_FLAG ) */
-/* name[0] == "CET " name if daylight saving not enabled */
-/* name[1] == "CEST " name if daylight saving is enabled */
// Below there are some initializers for commonly used TZDL configurations:
+#define DEFAULT_TZDL_AUTO_YEAR ( 2007 | DL_AUTO_FLAG )
+
+#define DEFAULt_TZDL_OFFS_DL 3600L /**< usually DST is +1 hour */
+
+
+/**
+ The symbol below can be used to initialize both the tm_on
+ and tm_off fields for time zones which do not switch to DST:
+ */
+#define DEFAULT_TZDL_TM_ON_OFF_NO_DST \
+ { DEFAULT_TZDL_AUTO_YEAR, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+
+// Settings used with UTC:
+
#define TZ_INFO_UTC "UTC (Universal Time, Coordinated)"
-#define DEFAULT_TZDL_UTC \
-{ \
- 0L, /* offs */ \
- 0L, /* offs_dl */ \
- { 1994 | DL_AUTO_FLAG, 1, 1, 0, 0, 0, 0, 0, 0L, 0L, 0 }, /* tm_on */ \
- { 1994 | DL_AUTO_FLAG, 1, 1, 0, 0, 0, 0, 0, 0L, 0L, 0 }, /* tm_off */ \
- { "UTC ", "UTC " } /* name[] */ \
+
+#define DEFAULT_TZDL_NAMES_UTC { "UTC ", "UTC " }
+
+#define DEFAULT_TZDL_UTC \
+{ \
+ 0L, /**< offs */ \
+ 0L, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_UTC /**< name[] */ \
}
-#define TZ_INFO_CET "CET/CEST (Central Europe)"
-#define DEFAULT_TZDL_CET \
-{ \
- 3600L, /* offs */ \
- 3600L, /* offs_dl */ \
- { 1994 | DL_AUTO_FLAG, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 }, /* tm_on */ \
- { 1990 | DL_AUTO_FLAG, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }, /* tm_off */ \
- { "CET ", "CEST " } /* name[] */ \
+
+/**
+ The symbols below specify beginning and end of DST for
+ Central Europe, as constituted by the European Parliament:
+ */
+
+#define DEFAULT_TZDL_TM_ON_CET_CEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 }
+
+#define DEFAULT_TZDL_TM_OFF_CET_CEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
+
+
+// Settings used with Central European Time:
+
+#define TZ_INFO_CET_CEST_EN "CET/CEST (Central Europe)"
+#define TZ_INFO_CET_CEST_DE "MEZ/MESZ (Mitteleuropa)"
+
+#define DEFAULT_TZDL_NAMES_CET_CEST_EN { "CET ", "CEST " }
+#define DEFAULT_TZDL_NAMES_CET_CEST_DE { "MEZ ", "MESZ " }
+
+#define DEFAULT_TZDL_OFFS_CET 3600L
+
+#define DEFAULT_TZDL_CET_CEST_EN \
+{ \
+ DEFAULT_TZDL_OFFS_CET, /**< offs */ \
+ DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_EN /**< name[] */ \
}
+#define DEFAULT_TZDL_CET_CEST_DE \
+{ \
+ DEFAULT_TZDL_OFFS_CET, /**< offs */ \
+ DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_DE /**< name[] */ \
+}
+
+
+// The symbols below specify beginning and end of DST for
+// Easter Europe, as constituted by the European Parliament:
+
+#define DEFAULT_TZDL_TM_ON_EET_EEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
+
+#define DEFAULT_TZDL_TM_OFF_EET_EEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 4, 0, 0, 0L, 0L, 0 }
+
+
+// Settings used with Eastern European Time:
+
+#define TZ_INFO_EET_EEST_EN "EET/EEST (East Europe)"
+#define TZ_INFO_EET_EEST_DE "OEZ/OEST (Osteuropa)"
+
+#define DEFAULT_TZDL_NAMES_EET_EEST_EN { "EET ", "EEST " }
+#define DEFAULT_TZDL_NAMES_EET_EEST_DE { "OEZ ", "OESZ " }
-#define TZ_INFO_EET "EET/EEST (Easter Europe)"
-#define DEFAULT_TZDL_EET \
-{ \
- 7200L, /* offs */ \
- 3600L, /* offs_dl */ \
- { 1994 | DL_AUTO_FLAG, 3, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }, /* tm_on */ \
- { 1990 | DL_AUTO_FLAG, 10, 25, 0, 0, 4, 0, 0, 0L, 0L, 0 }, /* tm_off */ \
- { "EET ", "EEST " } /* name[] */ \
+#define DEFAULT_TZDL_OFFS_EET 7200L
+
+#define DEFAULT_TZDL_EET_EEST_EN \
+{ \
+ DEFAULT_TZDL_OFFS_EET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_EN /* name[] */ \
}
+#define DEFAULT_TZDL_EET_EEST_DE \
+{ \
+ DEFAULT_TZDL_OFFS_EET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_DE /* name[] */ \
+}
+/** @} */ // endgroup
-/*
- * The structure below was defined wit GPS166 v1.31. It reflects the
- * status of the antenna, the times of last disconnect/reconnect,
- * and the board's clock offset after disconnection interval.
+/**
+ * The structure below reflects the status of the antenna,
+ * the times of last disconnect/reconnect, and the board's
+ * clock offset after the disconnection interval.
*/
typedef struct
{
- int16_t status; /* current status of antenna */
- TM_GPS tm_disconn; /* time of antenna disconnect */
- TM_GPS tm_reconn; /* time of antenna reconnect */
- int32_t delta_t; /* clock offs. at reconn. time in GPS_TICKS_PER_SEC */
+ int16_t status; /**< current status of antenna */
+ TM_GPS tm_disconn; /**< time of antenna disconnect */
+ TM_GPS tm_reconn; /**< time of antenna reconnect */
+ int32_t delta_t; /**< clock offs. at reconn. time in #GPS_TICKS_PER_SEC */
} ANT_INFO;
+#define _mbg_swab_ant_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->status ); \
+ _mbg_swab_tm_gps( &(_p)->tm_disconn ); \
+ _mbg_swab_tm_gps( &(_p)->tm_reconn ); \
+ _mbg_swab32( &(_p)->delta_t ); \
+}
-
-/* The status field may be set to one of the values below: */
-
+/**
+ The status field may be set to one of the values below:
+*/
enum
{
- ANT_INVALID, /* struct not set yet because ant. has not been disconn. */
- ANT_DISCONN, /* ant. now disconn., tm_reconn and delta_t not set */
- ANT_RECONN /* ant. has been disconn. and reconn., all fields valid */
+ ANT_INVALID, /**< struct not set yet because ant. has not been disconn. */
+ ANT_DISCONN, /**< ant. now disconn., tm_reconn and delta_t not set */
+ ANT_RECONN /**< ant. has been disconn. and reconn., all fields valid */
};
+/* Defines used with ENABLE_FLAGS */
+#define EF_OFF 0x00 /**< outputs off until sync'd */
+#define EF_SERIAL_BOTH 0x03 /**< both serial ports on */
+#define EF_PULSES_BOTH 0x03 /**< both pulses P_SEC and P_MIN on */
+#define EF_FREQ_ALL 0x07 /**< all fixed freq. outputs on */
+#define EF_SYNTH 0x01 /**< synth. on */
-/* The structure below was defined in rev. 1.47. It holds some flags */
-/* which let the corresponding outputs be disabled after power-up until */
-/* the receiver has synchronized (flag == 0x00, the default) or force */
-/* the outputs to be enabled immediately after power-up. The fixed */
-/* frequency output is hard-wired to be enabled immediately after */
-/* power-up, so the code for freq must always be 0x03. */
-
-#define EF_OFF 0x00 /* outputs off until sync'd */
-
-#define EF_SERIAL_BOTH 0x03 /* both serial ports on */
-#define EF_PULSES_BOTH 0x03 /* both pulses P_SEC and P_MIN on */
-#define EF_FREQ_ALL 0x07 /* all fixed freq. outputs on */
-#define EF_SYNTH 0x01 /* synth. on */
-
+/**
+ The structure holds some flags which let
+ the corresponding outputs be disabled after power-up until
+ the receiver has synchronized (flag == 0x00, the default) or force
+ the outputs to be enabled immediately after power-up. The fixed
+ frequency output is hard-wired to be enabled immediately after
+ power-up, so the code for freq must always be 0x03.
+*/
typedef struct
{
- uint16_t serial; /* EF_OFF or EF_SERIAL_ON_BOTH */
- uint16_t pulses; /* EF_OFF or EF_PULSES_ON_BOTH */
- uint16_t freq; /* always EF_FREQ_ON_ALL */
- uint16_t synth; /* EF_OFF or EF_SYNTH_ON */
+ uint16_t serial; /**< #EF_OFF or #EF_SERIAL_BOTH */
+ uint16_t pulses; /**< #EF_OFF or #EF_PULSES_BOTH */
+ uint16_t freq; /**< always #EF_FREQ_ALL */
+ uint16_t synth; /**< #EF_OFF or #EF_SYNTH */
} ENABLE_FLAGS;
+#define _mbg_swab_enable_flags( _p ) \
+{ \
+ _mbg_swab16( &(_p)->serial ); \
+ _mbg_swab16( &(_p)->pulses ); \
+ _mbg_swab16( &(_p)->freq ); \
+ _mbg_swab16( &(_p)->synth ); \
+}
/* A struct used to hold the settings of a serial port: */
#ifndef _COM_HS_DEFINED
/* types of handshake */
- enum { HS_NONE, HS_XONXOFF, HS_RTSCTS };
+ enum { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
#define _COM_HS_DEFINED
#endif
@@ -865,6 +1395,13 @@ typedef struct
#define _COM_PARM_DEFINED
#endif
+#define _mbg_swab_baud_rate( _p ) _mbg_swab32( _p )
+
+#define _mbg_swab_com_parm( _p ) \
+{ \
+ _mbg_swab_baud_rate( &(_p)->baud_rate ); \
+ _mbg_swab16( &(_p)->handshake ); \
+}
/*
@@ -1055,6 +1592,57 @@ typedef struct
uint32_t flags; /* reserved for future use, currently 0 */
} PORT_SETTINGS;
+#define _mbg_swab_port_settings( _p ) \
+{ \
+ _mbg_swab_com_parm( &(_p)->parm ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/*
+ * The definitions below can be used to mark specific fields of a
+ * PORT_SETTINGS structure, e.g. when editing build a mask indicating
+ * which of the fields have changed or which are not valid.
+ */
+enum
+{
+ MBG_PS_BIT_BAUD_RATE_OVR_SW, /* Baud rate index exceeds num supp by driver SW */
+ MBG_PS_BIT_BAUD_RATE_OVR_DEV, /* Baud rate index exceeds num supp by device */
+ MBG_PS_BIT_BAUD_RATE, /* Baud rate not supp by given port */
+ MBG_PS_BIT_FRAMING_OVR_SW, /* Framing index exceeds num supp by driver SW */
+ MBG_PS_BIT_FRAMING_OVR_DEV, /* Framing index exceeds num supp by device */
+ MBG_PS_BIT_FRAMING, /* Framing not supp by given port */
+ MBG_PS_BIT_HS_OVR_SW, /* Handshake index exceeds num supp by driver SW */
+ MBG_PS_BIT_HS, /* Handshake mode not supp by given port */
+ MBG_PS_BIT_STR_TYPE_OVR_SW, /* String type index exceeds num supp by driver SW */
+ MBG_PS_BIT_STR_TYPE_OVR_DEV, /* String type index exceeds num supp by device */
+ MBG_PS_BIT_STR_TYPE, /* String type not supp by given port */
+ MBG_PS_BIT_STR_MODE_OVR_SW, /* String mode index exceeds num supp by driver SW */
+ MBG_PS_BIT_STR_MODE_OVR_DEV, /* String mode index exceeds num supp by device */
+ MBG_PS_BIT_STR_MODE, /* String mode not supp by given port and string type */
+ MBG_PS_BIT_FLAGS_OVR_SW, /* Flags not supp by driver SW */
+ MBG_PS_BIT_FLAGS, /* Flags not supp by device */
+ N_MBG_PS_BIT
+};
+
+#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW )
+#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV )
+#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE )
+#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW )
+#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV )
+#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING )
+#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW )
+#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS )
+#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW )
+#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV )
+#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE )
+#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW )
+#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV )
+#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE )
+#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW )
+#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS )
+
+
/*
* The structure below adds an index number to the structure
@@ -1066,6 +1654,12 @@ typedef struct
PORT_SETTINGS port_settings;
} PORT_SETTINGS_IDX;
+#define _mbg_swab_port_settings_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_port_settings( &(_p)->port_settings ); \
+}
+
/*
* The structure below holds the current settings
@@ -1084,6 +1678,16 @@ typedef struct
uint32_t flags; /* reserved for future use, currently 0 */
} PORT_INFO;
+#define _mbg_swab_port_info( _p ) \
+{ \
+ _mbg_swab_port_settings( &(_p)->port_settings ); \
+ _mbg_swab32( &(_p)->supp_baud_rates ); \
+ _mbg_swab32( &(_p)->supp_framings ); \
+ _mbg_swab32( &(_p)->supp_str_types ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
/*
* The structure below adds an index number to the structure
@@ -1095,6 +1699,12 @@ typedef struct
PORT_INFO port_info;
} PORT_INFO_IDX;
+#define _mbg_swab_port_info_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_port_info( &(_p)->port_info ); \
+}
+
/*
* The structure below keeps information for a given
@@ -1109,6 +1719,13 @@ typedef struct
uint16_t flags; /* reserved, currently always 0 */
} STR_TYPE_INFO;
+#define _mbg_swab_str_type_info( _p ) \
+{ \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
+
+
/*
* The structure below adds an index number to the structure
@@ -1120,6 +1737,12 @@ typedef struct
STR_TYPE_INFO str_type_info;
} STR_TYPE_INFO_IDX;
+#define _mbg_swab_str_type_info_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_str_type_info( &(_p)->str_type_info ); \
+}
+
/*
* The codes below define valid modes for time strings,
@@ -1200,7 +1823,7 @@ enum
-/*
+/**
* The number of serial ports which were available
* with all GPS receiver models:
*/
@@ -1214,16 +1837,26 @@ enum
#define N_COM DEFAULT_N_COM
#endif
-/*
- * The structure used to store the modes of both serial ports:
- * (now obsolete)
+/**
+ * The structure used to store the modes of both serial ports:<br>
+ * <b>(now obsolete)</b>
*/
typedef struct
{
- COM_PARM com[DEFAULT_N_COM]; /* COM0 and COM1 settings */
- uint8_t mode[DEFAULT_N_COM]; /* COM0 and COM1 output mode */
+ COM_PARM com[DEFAULT_N_COM]; /**< COM0 and COM1 settings */
+ uint8_t mode[DEFAULT_N_COM]; /**< COM0 and COM1 output mode */
} PORT_PARM;
+#define _mbg_swab_port_parm( _p ) \
+{ \
+ int i; \
+ for ( i = 0; i < DEFAULT_N_COM; i++ ) \
+ { \
+ _mbg_swab_com_parm( &(_p)->com[i] ); \
+ /* no need to swap mode byte */ \
+ } \
+}
+
/*
* The codes below were used with the obsolete
@@ -1243,44 +1876,47 @@ enum
-/*
- * The following definitions are used to configure an optional
- * on-board IRIG input or output.
- * 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.
- */
+/**
+ @defgroup group_icode Irig Codes
-/*
- * Supported IRIG signal code types:
- * A002 1000 bps, DC shift, time-of-year
- * A003 1000 bps, DC shift, time-of-year, SBS
- * A132 1000 bps, 10 kHz carrier, time-of-year
- * A133 1000 bps, 10 kHz carrier, time-of-year, SBS
- * B002 100 bps, DC shift, time-of-year
- * B003 100 bps, DC shift, time-of-year, SBS
- * B122 100 bps, 1 kHz carrier, time-of-year
- * B123 100 bps, 1 kHz carrier, time-of-year, SBS
- * AFNOR 100 bps, 1 kHz carrier, SBS, complete date
- * AFNOR DC 100 bps, DC shift, SBS, complete date
- * IEEE1344 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE1344 extensions (B120)
- * IEEE1344 DC 100 bps, DC shift, time-of-year, SBS, IEEE1344 extensions (B000)
- * B220/1344 100 bps, DC shift, manchester encoded, IEEE1344 extensions
- * B222 100 bps, DC shift, manchester encoded, time-of-year
- * B223 100 bps, DC shift, manchester encoded, time-of-year, SBS
- *
- * time-of-year: day-of-year, hours, minutes, seconds
- * SBS: straight binary seconds, second-of-day
- * IEEE1344 extensions: time zone info
- * AFNOR: french standard AFNOR NFS-87500
+ The following definitions are used to configure an optional
+ on-board IRIG input or output.
+
+ 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.
+
+
+ - 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 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 B122: 100 bps, 1 kHz carrier, time-of-year
+ - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
+ - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
+ - <b> AFNOR DC:</b> 100 bps, DC shift, 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
+
+ - time-of-year: day-of-year, hours, minutes, seconds
+ - SBS: straight binary seconds, second-of-day
+ - IEEE1344 extensions: time zone info
+ - AFNOR: french standard AFNOR NFS-87500
+
+ @{
*/
-/*
+/**
* Definitions used with IRIG transmitters which generate
* the same IRIG code both with and without carrier signal
- * at the same time.
- */
+ * at the same time. */
enum
{
ICODE_TX_B002_B122,
@@ -1293,12 +1929,14 @@ enum
ICODE_TX_B222,
ICODE_TX_B223,
ICODE_TX_B006_B126,
- ICODE_TX_B007_B127,
- N_ICODE_TX /* number of code types */
+ ICODE_TX_B007_B127,
+ ICODE_TX_G002_G142,
+ ICODE_TX_G006_G146,
+ N_ICODE_TX /**< number of code types */
};
-/*
+/**
* Initializers for format name strings.
*/
#define DEFAULT_ICODE_TX_NAMES \
@@ -1313,25 +1951,29 @@ enum
"B222+B122", \
"B223+B123", \
"B006+B126", \
- "B007+B127" \
+ "B007+B127", \
+ "G002+G142", \
+ "G006+G146" \
}
-/*
+/**
* 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, time zone info", \
- "100 bps, DC manchester enc. or 1kHz carrier, SBS, time zone info", \
- "100 bps, DC manchester enc. or 1kHz carrier, time-of-year", \
- "100 bps, DC manchester enc. or 1kHz carrier, time-of-year, SBS", \
- "100 bps, DC or 1 kHz carrier, complete date", \
- "100 bps, DC or 1 kHz carrier, complete date, SBS" \
+#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" \
}
/*
@@ -1350,8 +1992,10 @@ enum
#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 )
-/*
+/**
* A mask of IRIG formats with manchester encoded DC output:
*/
#define MSK_ICODE_TX_DC_MANCH \
@@ -1361,7 +2005,7 @@ enum
MSK_ICODE_TX_B223 \
)
-/*
+/**
* A mask of IRIG formats with 1 kHz carrier:
*/
#define MSK_ICODE_TX_1KHZ \
@@ -1377,7 +2021,7 @@ enum
MSK_ICODE_TX_B007_B127 \
)
-/*
+/**
* A mask of IRIG formats with 10 kHz carrier:
*/
#define MSK_ICODE_TX_10KHZ \
@@ -1386,7 +2030,16 @@ enum
MSK_ICODE_TX_A003_A133 \
)
-/*
+/**
+ * A mask of IRIG formats with 100 kHz carrier:
+ */
+#define MSK_ICODE_TX_100KHZ \
+( \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
* A mask of IRIG formats with 100 bps data rate:
*/
#define MSK_ICODE_TX_100BPS \
@@ -1399,7 +2052,7 @@ enum
MSK_ICODE_TX_B007_B127 \
)
-/*
+/**
* A mask of IRIG formats with 1000 bps data rate:
*/
#define MSK_ICODE_TX_1000BPS \
@@ -1408,7 +2061,16 @@ enum
MSK_ICODE_TX_A003_A133 \
)
-/*
+/**
+ * A mask of IRIG formats with 10 kbps data rate:
+ */
+#define MSK_ICODE_TX_10000BPS \
+( \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
* A mask of IRIG formats which support TFOM:
*/
#define MSK_ICODE_TX_HAS_TFOM \
@@ -1416,7 +2078,7 @@ enum
MSK_ICODE_TX_IEEE1344 \
)
-/*
+/**
* A mask of IRIG formats which support time zone information:
*/
#define MSK_ICODE_TX_HAS_TZI \
@@ -1424,7 +2086,7 @@ enum
MSK_ICODE_TX_IEEE1344 \
)
-/*
+/**
* The default mask of IRIG formats supported by
* IRIG transmitters:
*/
@@ -1441,7 +2103,7 @@ enum
-/*
+/**
* Definitions used with IRIG receivers which decode
* two similar IRIG codes
* at the same time.
@@ -1458,10 +2120,12 @@ enum
ICODE_RX_IEEE1344_DC,
ICODE_RX_B126_B127,
ICODE_RX_B006_B007,
+ ICODE_RX_G142_G146,
+ ICODE_RX_G002_G006,
N_ICODE_RX /* the number of valid signal code types */
};
-/*
+/**
* Initializers for format name strings.
*/
#define DEFAULT_ICODE_RX_NAMES \
@@ -1475,10 +2139,12 @@ enum
"IEEE1344", \
"IEEE1344 (DC)", \
"B126/B127", \
- "B006/B007 (DC)" \
+ "B006/B007 (DC)", \
+ "G142/G146", \
+ "G002/G006 (DC)" \
}
-/*
+/**
* Initializers for English format description strings.
*/
#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
@@ -1492,7 +2158,9 @@ enum
"100 bps, 1 kHz carrier, SBS, time zone info", \
"100 bps, DC shift, SBS, time zone info", \
"100 bps, 1 kHz carrier, complete date, SBS optionally", \
- "100 bps, DC shift, complete date, SBS optionally" \
+ "100 bps, DC shift, complete date, SBS optionally", \
+ "10 kbps, 100 kHz carrier, complete date optionally", \
+ "10 kbps, DC shift, complete date optionally" \
}
/*
@@ -1508,8 +2176,10 @@ enum
#define MSK_ICODE_RX_IEEE1344_DC ( 1UL << ICODE_RX_IEEE1344_DC )
#define MSK_ICODE_RX_B126_B127 ( 1UL << ICODE_RX_B126_B127 )
#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 )
-/*
+/**
* A mask of IRIG formats which have DC shift:
*/
#define MSK_ICODE_RX_DC \
@@ -1518,10 +2188,11 @@ enum
MSK_ICODE_RX_A002_A003 | \
MSK_ICODE_RX_AFNOR_DC | \
MSK_ICODE_RX_IEEE1344_DC | \
- MSK_ICODE_RX_B006_B007 \
+ MSK_ICODE_RX_B006_B007 | \
+ MSK_ICODE_RX_G002_G006 \
)
-/*
+/**
* A mask of IRIG formats with 1 kHz carrier:
*/
#define MSK_ICODE_RX_1KHZ \
@@ -1532,7 +2203,7 @@ enum
MSK_ICODE_RX_B126_B127 \
)
-/*
+/**
* A mask of IRIG formats with 10 kHz carrier:
*/
#define MSK_ICODE_RX_10KHZ \
@@ -1540,7 +2211,15 @@ enum
MSK_ICODE_RX_A132_A133 \
)
-/*
+/**
+ * A mask of IRIG formats with 100 kHz carrier:
+ */
+#define MSK_ICODE_RX_100KHZ \
+( \
+ MSK_ICODE_RX_G142_G146 \
+)
+
+/**
* A mask of IRIG formats with 100 bps data rate:
*/
#define MSK_ICODE_RX_100BPS \
@@ -1555,7 +2234,7 @@ enum
MSK_ICODE_RX_B006_B007 \
)
-/*
+/**
* A mask of IRIG formats with 1000 bps data rate:
*/
#define MSK_ICODE_RX_1000BPS \
@@ -1564,7 +2243,15 @@ enum
MSK_ICODE_RX_A002_A003 \
)
-/*
+/**
+ * A mask of IRIG formats with 10 kbps data rate:
+ */
+#define MSK_ICODE_RX_10000BPS \
+( \
+ MSK_ICODE_RX_G142_G146 \
+)
+
+/**
* A mask of IRIG formats which support TFOM:
*/
#define MSK_ICODE_RX_HAS_TFOM \
@@ -1573,7 +2260,7 @@ enum
MSK_ICODE_RX_IEEE1344_DC \
)
-/*
+/**
* A mask of IRIG formats which support time zone information:
*/
#define MSK_ICODE_RX_HAS_TZI \
@@ -1582,7 +2269,7 @@ enum
MSK_ICODE_RX_IEEE1344_DC \
)
-/*
+/**
* The default mask of IRIG formats supported by
* IRIG receivers:
*/
@@ -1597,53 +2284,161 @@ enum
MSK_ICODE_RX_AFNOR_DC \
)
#endif
+/** @} */
-
-/*
+/**
* The structure below is used to configure an optional
* on-board IRIG output:
*/
typedef struct
{
- uint16_t icode; /* IRIG signal code, as enumerated above */
- uint16_t flags; /* (codes defined below) */
+ uint16_t icode; /**< IRIG signal code, see \ref group_icode */
+ uint16_t flags; /**< see \ref group_irig_flags */
} IRIG_SETTINGS;
+#define _mbg_swab_irig_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->icode ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
+
-/* bit masks used with IRIG_SETTINGS.flags (others are reserved): */
+/**
+ @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS.flags
-#define IFLAGS_DISABLE_TFOM 0x0001 /* RX ignore/TX don't gen TFOM */
-#define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /* gen local time, not UTC */
+ (others are reserved)
+* @{
+ */
+#define IFLAGS_DISABLE_TFOM 0x0001 /**< RX ignore/TX don't gen TFOM */
+#define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /**< gen local time, not UTC */
-#define IFLAGS_MASK 0x0003 /* flags above or'ed */
+#define IFLAGS_MASK 0x0003 /**< flags above or'ed */
+/** @} */
-/*
- * The structure below is used to query the IRIG configuration
+/**
+ * The structure is used to query the IRIG configuration
* plus the supported codes:
*/
typedef struct
{
IRIG_SETTINGS settings;
- uint32_t supp_codes; /* bit mask of supported codes */
+ uint32_t supp_codes; /**< bit mask of supported codes */
} IRIG_INFO;
+#define _mbg_swab_irig_info( _p ) \
+{ \
+ _mbg_swab_irig_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_codes ); \
+}
+
+
+// The type below is used to read the board's debug status
+// which also include IRIG decoder status:
+typedef uint32_t MBG_DEBUG_STATUS;
+
+// The debug status is bit coded as defined below:
+enum
+{
+ MBG_IRIG_BIT_WARMED_UP, /**< Osc has warmed up */
+ MBG_IRIG_BIT_PPS_ACTIVE, /**< PPS output is active */
+ MBG_IRIG_BIT_INV_CONFIG, /**< Invalid config, e.g. data csum error */
+ MBG_IRIG_BIT_MSG_DECODED, /**< IRIG msg could be decoded */
+ MBG_IRIG_BIT_MSG_INCONSISTENT, /**< IRIG msg contains inconsistent data */
+ MBG_IRIG_BIT_LOOP_LOCKED, /**< Decoder control loop is locked */
+ MBG_IRIG_BIT_JITTER_TOO_LARGE, /**< Phase jitter too large */
+ MBG_IRIG_BIT_INV_REF_OFFS, /**< UTC ref offset not configured */
+
+ MBG_SYS_BIT_INV_TIME, /**< Internal time not valid/set */
+ MBG_SYS_BIT_TIME_SET_VIA_API, /**< On board time set externally */
+ MBG_SYS_BIT_INV_RTC, /**< On board RTC invalid */
+ MBG_SYS_BIT_CPU_PLL_FAILED, /**< The CPU's PLL watchdog */
+
+ N_MBG_DEBUG_BIT
+};
+
+/*
+ * Initializers for IRIG status bit strings.
+ */
+#define MBG_DEBUG_STATUS_STRS \
+{ \
+ "Osc has warmed up", \
+ "PPS output is active", \
+ "Config set to default", \
+ "IRIG msg decoded", \
+ "IRIG msg not consistent", \
+ "Decoder control loop locked", \
+ "Phase jitter too large", \
+ "Invalid ref offset", \
+ \
+ "Internal time not valid", \
+ "On board time set via API", \
+ "On board RTC invalid", \
+ "CPU PLL failure, needs restart" \
+}
+
+
+
+#define MBG_IRIG_MSK_WARMED_UP ( 1UL << MBG_IRIG_BIT_WARMED_UP )
+#define MBG_IRIG_MSK_PPS_ACTIVE ( 1UL << MBG_IRIG_BIT_PPS_ACTIVE )
+#define MBG_IRIG_MSK_INV_CONFIG ( 1UL << MBG_IRIG_BIT_INV_CONFIG )
+#define MBG_IRIG_MSK_MSG_DECODED ( 1UL << MBG_IRIG_BIT_MSG_DECODED )
+#define MBG_IRIG_MSK_MSG_INCONSISTENT ( 1UL << MBG_IRIG_BIT_MSG_INCONSISTENT )
+#define MBG_IRIG_MSK_LOOP_LOCKED ( 1UL << MBG_IRIG_BIT_LOOP_LOCKED )
+#define MBG_IRIG_MSK_JITTER_TOO_LARGE ( 1UL << MBG_IRIG_BIT_JITTER_TOO_LARGE )
+#define MBG_IRIG_MSK_INV_REF_OFFS ( 1UL << MBG_IRIG_BIT_INV_REF_OFFS )
+
+#define MBG_SYS_MSK_INV_TIME ( 1UL << MBG_SYS_BIT_INV_TIME )
+#define MBG_SYS_MSK_TIME_SET_VIA_API ( 1UL << MBG_SYS_BIT_TIME_SET_VIA_API )
+#define MBG_SYS_MSK_INV_RTC ( 1UL << MBG_SYS_BIT_INV_RTC )
+#define MBG_SYS_MSK_CPU_PLL_FAILED ( 1UL << MBG_SYS_BIT_CPU_PLL_FAILED )
+
+
+
+typedef int16_t MBG_REF_OFFS; /**< -MBG_REF_OFFS_MAX..MBG_REF_OFFS_MAX */
+
+#define _mbg_swab_mbg_ref_offs( _p ) _mbg_swab16( (_p) )
+
+
+/** the maximum allowed positive / negative offset */
+#define MBG_REF_OFFS_MAX ( ( 12L * 60 ) + 30 ) // [minutes]
+
+/**
+ * the following value is used to indicate that the ref offset
+ * value has not yet been configured
+ */
+#define MBG_REF_OFFS_NOT_CFGD 0x8000
+
typedef struct
{
uint32_t flags;
} MBG_OPT_SETTINGS;
+#define _mbg_swab_mbg_opt_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
typedef struct
{
MBG_OPT_SETTINGS settings;
uint32_t supp_flags;
} MBG_OPT_INFO;
+#define _mbg_swab_mbg_opt_info( _p ) \
+{ \
+ _mbg_swab_mbg_opt_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+}
+
+
enum
{
- MBG_OPT_BIT_STR_UTC, // serial string contains UTC time
- MBG_OPT_BIT_EMU_SYNC, // emulate/pretend to be synchronized
+ MBG_OPT_BIT_STR_UTC, /**< serial string contains UTC time */
+ MBG_OPT_BIT_EMU_SYNC, /**< emulate/pretend to be synchronized, */
+ /**< alternatively GPS_FEAT_IGNORE_LOCK may be supported */
N_MBG_OPT_BIT
};
@@ -1654,6 +2449,76 @@ enum
#define MBG_OPT_FLAG_EMU_SYNC ( 1UL << MBG_OPT_BIT_EMU_SYNC )
+/**
+ @defgroup group_scale Time Scale Configuration
+
+ The structures and defines can be used to configure the GPS receiver's
+ basic time scale. By default this is UTC which can optionally
+ be converted to some local time. However, some applications
+ prefer TAI or pure GPS time. This can be configured using the
+ structures below if the GPS_HAS_TIME_SCALE flag is set in
+ RECEIVER_INFO::features.
+ @{
+*/
+
+enum
+{
+ MBG_TIME_SCALE_DEFAULT, /**< UTC or local time, t_gps - deltat_ls */
+ MBG_TIME_SCALE_GPS, /**< GPS time, monotonical */
+ MBG_TIME_SCALE_TAI, /**< TAI, t_gps + GPS_TAI_OFFSET seconds */
+ N_MBG_TIME_SCALE
+};
+
+#define MBG_TIME_SCALE_MSK_DEFAULT ( 1UL << MBG_TIME_SCALE_DEFAULT )
+#define MBG_TIME_SCALE_MSK_GPS ( 1UL << MBG_TIME_SCALE_GPS )
+#define MBG_TIME_SCALE_MSK_TAI ( 1UL << MBG_TIME_SCALE_TAI )
+
+// See also the extended status bits TM_SCALE_GPS and TM_SCALE_TAI
+// indicating the active time scale setting.
+
+
+#define MBG_TIME_SCALE_STRS \
+{ \
+ "UTC/local", \
+ "GPS", \
+ "TAI" \
+}
+
+
+
+/**
+ The fixed time offset between the GPS and TAI time scales, in seconds
+*/
+#define GPS_TAI_OFFSET 19 /**< [s], TAI = GPS + GPS_TAI_OFFSET */
+
+
+typedef struct
+{
+ uint8_t scale; /**< current time scale code from the enum above */
+ uint8_t flags; /**< reserved, currently always 0 */
+} MBG_TIME_SCALE_SETTINGS;
+
+#define _mbg_swab_mbg_time_scale_settings( _p ) \
+ _nop_macro_fnc()
+
+
+typedef struct
+{
+ MBG_TIME_SCALE_SETTINGS settings; /**< current settings */
+ MBG_TIME_SCALE_SETTINGS max_settings; /**< numb. of scales, all supported flags */
+ uint32_t supp_scales; /**< bit masks of supported scales */
+} MBG_TIME_SCALE_INFO;
+
+#define _mbg_swab_mbg_time_scale_info( _p ) \
+{ \
+ _mbg_swab_mbg_time_scale_settings( &(_p)->settings ); \
+ _mbg_swab_mbg_time_scale_settings( &(_p)->max_settings ); \
+ _mbg_swab32( &(_p)->supp_scales ); \
+}
+
+/** @} */ // endgroup
+
+
/*
* The structures below are required to setup the programmable
* pulse outputs which are provided by some GPS receivers.
@@ -1661,8 +2526,8 @@ enum
* receiver is reported in the RECEIVER_INFO.n_str_type field.
*/
-/*
- * The structure below is used to define a date of year:
+/**
+ * The structure is used to define a date of year:
*/
typedef struct
{
@@ -1671,9 +2536,14 @@ typedef struct
uint16_t year; /* including century */
} MBG_DATE;
+#define _mbg_swab_mbg_date( _p ) \
+{ \
+ _mbg_swab16( &(_p)->year ); \
+}
-/*
- * The structure below is used to define a time of day:
+
+/**
+ * The structure is used to define a time of day:
*/
typedef struct
{
@@ -1683,9 +2553,12 @@ typedef struct
uint8_t sec100; /* reserved, currently always 0 */
} MBG_TIME;
+#define _mbg_swab_mbg_time( _p ) \
+ _nop_macro_fnc() // nothing to swap
-/*
- * The structure below defines a single date and time
+
+/**
+ * The structure defines a single date and time
* for switching operations:
*/
typedef struct
@@ -1696,9 +2569,15 @@ typedef struct
uint8_t flags; /* reserved, currently 0 */
} MBG_DATE_TIME;
+#define _mbg_swab_mbg_date_time( _p ) \
+{ \
+ _mbg_swab_mbg_date( &(_p)->d ); \
+ _mbg_swab_mbg_time( &(_p)->t ); \
+}
+
-/*
- * The structure below defines times and dates
+/**
+ * The structure defines times and dates
* for an on/off cycle:
*/
typedef struct
@@ -1707,50 +2586,69 @@ typedef struct
MBG_DATE_TIME off; /* time and date to switch off */
} POUT_TIME;
+#define _mbg_swab_pout_time( _p ) \
+{ \
+ _mbg_swab_mbg_date_time( &(_p)->on ); \
+ _mbg_swab_mbg_date_time( &(_p)->off ); \
+}
-/*
+
+/**
* The number of POUT_TIMEs for each programmable pulse output
*/
#define N_POUT_TIMES 3
-/*
- * The structure below is used to configure a single programmable
+/**
+ * The structure is used to configure a single programmable
* pulse output.
*/
typedef struct
{
- uint16_t mode; /* mode of operation, codes defined below */
- uint16_t pulse_len; /* 10 msec units, or COM port number */
- uint16_t timeout; /* [min], for dcf_mode */
- uint16_t flags; /* see below */
- POUT_TIME tm[N_POUT_TIMES]; /* switching times */
+ uint16_t mode; /**< mode of operation, codes defined below */
+ uint16_t pulse_len; /**< 10 msec units, or COM port number */
+ uint16_t timeout; /**< [min], for dcf_mode */
+ uint16_t flags; /**< see below */
+ POUT_TIME tm[N_POUT_TIMES]; /**< switching times */
} POUT_SETTINGS;
-#define MAX_POUT_PULSE_LEN 1000 // 10 secs, in 10 msec units
-#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) // 48 hours, in minutes
+#define _mbg_swab_pout_settings( _p ) \
+{ \
+ int i; \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->pulse_len ); \
+ _mbg_swab32( &(_p)->timeout ); \
+ _mbg_swab16( &(_p)->flags ); \
+ \
+ for ( i = 0; i < N_POUT_TIMES; i++ ) \
+ _mbg_swab_pout_time( &(_p)->tm[i] ); \
+}
-/*
- * The codes below are defined for POUT_SETTINGS.mode to setup
+#define MAX_POUT_PULSE_LEN 1000 /**< 10 secs, in 10 msec units */
+#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) /**< 48 hours, in minutes */
+
+
+/**
+ * These codes are defined for POUT_SETTINGS.mode to setup
* the basic mode of operation for a single programmable pulse
* output:
*/
enum
{
- POUT_IDLE, /* always off, or on if POUT_INVERTED */
- POUT_TIMER, /* switch on/off at configured times */
- POUT_SINGLE_SHOT, /* pulse at time POUT_SETTINGS.tm[0].on */
- POUT_CYCLIC_PULSE, /* pulse every POUT_SETTINGS.tm[0].on.t interval */
- POUT_PER_SEC, /* pulse if second changes */
- POUT_PER_MIN, /* pulse if minute changes */
- POUT_PER_HOUR, /* pulse if hour changes */
- POUT_DCF77, /* emulate DCF77 signal */
- POUT_POS_OK, /* on if pos. OK (nav_solved) */
- POUT_TIME_SYNC, /* on if time sync (time_syn) */
- POUT_ALL_SYNC, /* on if pos. OK and time sync */
- POUT_TIMECODE, /* IRIG/AFNOR DCLS output */
- POUT_TIMESTR, /* COM port number in pulse_len field */
- POUT_10MHZ, /* 10 MHz fixed frequency */
+ POUT_IDLE, /**< always off, or on if POUT_INVERTED */
+ POUT_TIMER, /**< switch on/off at configured times */
+ POUT_SINGLE_SHOT, /**< pulse at time POUT_SETTINGS.tm[0].on */
+ POUT_CYCLIC_PULSE, /**< pulse every POUT_SETTINGS.tm[0].on.t interval */
+ POUT_PER_SEC, /**< pulse if second changes */
+ POUT_PER_MIN, /**< pulse if minute changes */
+ POUT_PER_HOUR, /**< pulse if hour changes */
+ POUT_DCF77, /**< emulate DCF77 signal */
+ POUT_POS_OK, /**< on if pos. OK (nav_solved) */
+ POUT_TIME_SYNC, /**< on if time sync (time_syn) */
+ POUT_ALL_SYNC, /**< on if pos. OK and time sync */
+ POUT_TIMECODE, /**< IRIG/AFNOR DCLS output */
+ POUT_TIMESTR, /**< COM port number in pulse_len field */
+ POUT_10MHZ, /**< 10 MHz fixed frequency */
N_POUT_MODES
};
@@ -1854,50 +2752,70 @@ enum
#define POUT_INVERTED 0x0001
-/*
- * Since a clock may support more than one programmable
- * pulse output, setup tools must use the structure below
- * to read/set pulse output configuration.
- * The number of outputs supported by a receiver model
- * can be queried using the RECEIVER_INFO structure.
+/**
+ Since a clock may support more than one programmable
+ pulse output, setup tools must use the structure below
+ to read/set pulse output configuration.
+ The number of outputs supported by a receiver model
+ can be queried using the RECEIVER_INFO structure.
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_prg_out-1 */
+ uint16_t idx; /**< 0..RECEIVER_INFO.n_prg_out-1 */
POUT_SETTINGS pout_settings;
} POUT_SETTINGS_IDX;
+#define _mbg_swab_pout_settings_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings( &(_p)->pout_settings ); \
+}
-/*
- * The structure below holds the current settings
- * for a programmable pulse output, plus additional
- * informaton on the output's capabilities.
- * This can be read by setup programs to allow setup
- * of supported features only.
+
+/**
+ The structure below holds the current settings
+ for a programmable pulse output, plus additional
+ informaton on the output's capabilities.
+ This can be read by setup programs to allow setup
+ of supported features only.
*/
typedef struct
{
POUT_SETTINGS pout_settings;
- uint32_t supp_modes; /* bit mask of modes supp. by this output */
- 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 supp_modes; /**< bit mask of modes supp. by this output */
+ 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 */
} POUT_INFO;
-/* The max number of COM ports that can be handled by POUT_INFO::timestr_ports */
+#define _mbg_swab_pout_info( _p ) \
+{ \
+ _mbg_swab_pout_settings( &(_p)->pout_settings ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/** The max number of COM ports that can be handled by POUT_INFO::timestr_ports */
#define MAX_POUT_TIMESTR_PORTS 8
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+/**
+ The structure below adds an index number to the structure
+ above to allow addressing of several instances:
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_prg_out-1 */
+ uint16_t idx; /**< 0..RECEIVER_INFO.n_prg_out-1 */
POUT_INFO pout_info;
} POUT_INFO_IDX;
+#define _mbg_swab_pout_info_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_info( &(_p)->pout_info ); \
+}
/*
@@ -1912,13 +2830,16 @@ typedef struct
*/
enum
{
- MULTI_REF_GPS, // standard GPS
+ MULTI_REF_NONE = -1, // nothing, undefined
+ MULTI_REF_GPS = 0, // standard GPS
MULTI_REF_10MHZ, // 10 MHz input frequency
MULTI_REF_PPS, // 1 PPS input signal
MULTI_REF_10MHZ_PPS, // combined 10 MHz plus PPS
MULTI_REF_IRIG, // IRIG input
MULTI_REF_NTP, // Network Time Protocol (NTP)
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
};
@@ -1934,7 +2855,9 @@ enum
"10 MHz + PPS in", \
"IRIG", \
"NTP", \
- "PTP (IEEE1588)" \
+ "PTP (IEEE1588)", \
+ "PTP over E1", \
+ "Fixed Freq. in" \
}
@@ -1948,23 +2871,36 @@ enum
#define HAS_MULTI_REF_IRIG ( 1UL << MULTI_REF_IRIG )
#define HAS_MULTI_REF_NTP ( 1UL << MULTI_REF_NTP )
#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 )
/*
- * Up to this number of prioritizable ref input sources are supported
+ * There are 2 different ways to configure multi ref support
+ * provided by some devices.
+ *
+ * Newer devices which have the GPS_FEAT_XMULTI_REF flag set
+ * in RECEIVER_INFO::features support the newer XMULTI_REF_...
+ * structures which provide a more flexible interface.
+ *
+ * Older devices which have the GPS_FEAT_MULTI_REF flag set
+ * support these MULTI_REF_... structures below where
+ * the number of supported input sources and priorities
+ * is limited to N_MULTI_REF_PRIO.
*/
+
#define N_MULTI_REF_PRIO 4
-/*
- * 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 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.
+/**
+ 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 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.
*/
typedef struct
{
@@ -1972,10 +2908,9 @@ typedef struct
} MULTI_REF_SETTINGS;
-
-/*
- * The structure below is used to query the MULTI_REF configuration,
- * plus the supported ref sources.
+/**
+ The structure below is used to query the MULTI_REF configuration,
+ plus the supported ref sources.
*/
typedef struct
{
@@ -1986,19 +2921,17 @@ typedef struct
} MULTI_REF_INFO;
-
/*
* The type below is used to query the MULTI_REF status information,
*/
typedef uint16_t MULTI_REF_STATUS; /* flag bits as defined below */
-/*
+/*
* The bits and associated bit masks below are used with the
* MULTI_REF_STATUS type. Each bit is set if the associated
* condition is true and is reset if the condition is not true:
*/
-
enum
{
WRN_MODULE_MODE, /* selected input mode was invalid, set to default */
@@ -2025,6 +2958,147 @@ enum
+/*
+ * If the RECEIVER_INFO::features flag GPS_FEAT_XMULTI_REF is set
+ * then the following XMULTI_REF_... data structures must be used
+ * instead of the older MULTI_REF_... structures above.
+ *
+ * Those devices support a number of priority levels addressed by
+ * the priority index, starting at 0 for highest priority. A single
+ * reference time source from the set of supported sources can be
+ * assigned to each priority level.
+ *
+ * The structures below are used to configure the individual
+ * time source for each priority level, and retrieve the status
+ * of the time source at each priority level.
+ */
+
+typedef struct
+{
+ uint8_t type; /* 0..N_MULTI_REF-1 from the enum above */
+ uint8_t instance; /* reserved, currently always 0 */
+} XMULTI_REF_ID;
+
+typedef struct
+{
+ XMULTI_REF_ID id; /* time source identifier */
+ uint16_t flags; /* reserved, currently always 0 */
+ NANO_TIME bias; /* time bias, e.g. path delay */
+ NANO_TIME precision; /* precision of the time source */
+ uint32_t fine_limit; /* smooth control if below this limit */
+} XMULTI_REF_SETTINGS;
+
+
+/*
+ * The structure below is used to retrieve or configure the time source
+ * for a specific priority level.
+ * After configuring, a structure with idx == 0xFFFF (-1) must be sent
+ * to let the changes become effective.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_SETTINGS settings; /* the settings configured for this level */
+
+} XMULTI_REF_SETTINGS_IDX;
+
+
+/*
+ * The structure below contains the XMULTI_REF configuration
+ * for a single priority level, plus information on supported
+ * ref time sources, and the number of supported priority levels.
+ */
+typedef struct
+{
+ XMULTI_REF_SETTINGS settings; /* current settings */
+ uint32_t supp_ref; /* supp. HAS_MULTI_REF_... codes or'ed */
+ uint8_t n_supp_ref; /* number of supported ref time sources */
+ uint8_t n_prio; /* number of supported priority levels */
+ uint16_t flags; /* reserved, currently 0, e.g. multiple instance support */
+
+} XMULTI_REF_INFO;
+
+
+/*
+ * The structure below is used to retrieve the XMULTI_REF configuration
+ * information for a specific priority level.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_INFO info;
+
+} XMULTI_REF_INFO_IDX;
+
+
+/*
+ * The structure below contains status information on a single
+ * ref time source.
+ */
+typedef struct
+{
+ XMULTI_REF_ID id; /* time source identifier */
+ uint16_t status; /* flag bits as defined below */
+ NANO_TIME offset; /* time offset from main time base */
+ uint32_t reserved; /* reserved, currently always 0 */
+
+} XMULTI_REF_STATUS;
+
+
+/*
+ * The structure below is used to retrieve the the status information
+ * of the time source at a specific priority level.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_STATUS status;
+
+} XMULTI_REF_STATUS_IDX;
+
+
+/*
+ * Bits used with XMULTI_REF_STATUS.
+ */
+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 */
+ 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 )
+
+
+
+/*
+ * An initializer for a XMULTI_REF_STATUS variable
+ * with status invalid / not used
+ */
+#define XMULTI_REF_STATUS_INVALID \
+{ \
+ { (uint8_t) MULTI_REF_NONE, 0 }, /* id; instance 0 ? */ \
+ XMRS_MSK_NO_CONN | XMRS_MSK_NO_SIGNAL, /* status */ \
+ { 0 }, /* offset */ \
+ 0 /* reserved */ \
+}
+
+
+
/*------------------------------------------------------------------------*/
/*
@@ -2033,8 +3107,36 @@ enum
typedef uint16_t ROM_CSUM; /* The ROM checksum */
typedef uint16_t RCV_TIMEOUT; /* [min] (only if HAS_RCV_TIMEOUT) */
-typedef uint16_t IGNORE_LOCK; /* if != 0 always claim to be sync */
+typedef uint16_t IGNORE_LOCK; /* (only if GPS_HAS_IGNORE_LOCK) */
+/*
+ * Originally IGNORE_LOG above has been a boolean value (equal or
+ * not equal 0) which was evaluated the same way for all ports.
+ *
+ * Due to special firmware requirements it has been changed to a
+ * bit maskable property in order to be able to specify the behaviour
+ * for individual ports.
+ *
+ * In order to keep compatibility with older versions the LSB is used
+ * to specify ignore_lock for all ports. The next higher bits are used
+ * to specify ignore_lock for an individual port, where the bit position
+ * depends on the port number, e.g. 0x02 for COM0, 0x04 for COM1, etc.
+ * The macros below can be used to simplify the code:
+ */
+
+/* return a bit mask depending on the port number */
+#define IGNORE_LOCK_FOR_ALL_PORTS 0x01
+
+#define _ignore_lock_for_all_ports() ( IGNORE_LOCK_FOR_ALL_PORTS )
+
+#define _ignore_lock_for_port( _n ) ( 0x02 << (_n) )
+
+/* check if all ports are ignore_lock'ed */
+#define _is_ignore_lock_all_ports( _il ) ( (_il) & IGNORE_LOCK_FOR_ALL_PORTS )
+
+/* check if a specific port is ignore_lock'ed */
+#define _is_ignore_lock_for_port( _il, _n ) \
+ ( (_il) & ( _ignore_lock_for_port(_n) | IGNORE_LOCK_FOR_ALL_PORTS ) )
/*------------------------------------------------------------------------*/
@@ -2043,7 +3145,7 @@ typedef uint16_t IGNORE_LOCK; /* if != 0 always claim to be sync */
* The structures below are used with the SCU multiplexer board
* in a redundant system:
*/
-
+
typedef struct
{
uint32_t hw_id; // hardware identification
@@ -2074,7 +3176,7 @@ typedef struct
#define MSK_EPLD_STAT_ACO 0x4000 // Access control override bit
#define MSK_EPLD_STAT_WDOG_OK 0x8000 // WDT_OK set to zero if watchdog expired
-
+
#define MSK_EPLD_CNTL_SEL_REM 0x0800 // remote select for output MUX ( clk_1 = 0 )
#define MSK_EPLD_CNTL_DIS_REM 0x1000 // remote disable for output MUX
#define MSK_EPLD_CNTL_REMOTE 0x2000 // must be set to enable remote operation
@@ -2116,18 +3218,37 @@ enum
#define UPDA_166 ( 0x08 | BOOT )
#define UPDA_BC ( 0x09 | REMOTE | BOOT )
+
+
+typedef int16_t DAC_VAL;
+
+#define _mbg_swab_dac_val( _p ) \
+ _mbg_swab16( _p );
+
+
+
typedef struct
{
- uint16_t mode;
- uint16_t good_svs;
- uint16_t svs_in_view;
- int16_t dac_val;
- int16_t dac_cal;
+ uint16_t mode; /**< Mode of operation */
+ uint16_t good_svs; /**< Numb. of satellites that can currently be received and used */
+ uint16_t svs_in_view; /**< Numb. of satellites that should be in view according to the almanac data */
+ DAC_VAL dac_val; /**< Oscillator fine DAC value */
+ DAC_VAL dac_cal; /**< Oscillator calibration DAC value ( see #OSC_DAC_RANGE, #OSC_DAC_BIAS ) */
} STAT_INFO;
+#define _mbg_swab_stat_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->good_svs ); \
+ _mbg_swab16( &(_p)->svs_in_view ); \
+ _mbg_swab_dac_val( &(_p)->dac_val ); \
+ _mbg_swab_dac_val( &(_p)->dac_cal ); \
+}
+
+
#define OSC_DAC_RANGE 4096UL
#define OSC_DAC_BIAS ( OSC_DAC_RANGE / 2 )
-
+
#ifndef _IDENT_DEFINED
@@ -2141,13 +3262,491 @@ typedef struct
#define _IDENT_DEFINED
#endif
+#define _mbg_swab_ident( _p ) \
+{ \
+ int i; \
+ for ( i = 0; i < 4; i++ ) \
+ _mbg_swab32( &(_p)->lw[i] ); \
+}
-/*
+/**
* The type below is used to configure the length of the
- * antenna cable:
+ * antenna cable in [m]:
*/
typedef uint16_t ANT_CABLE_LEN;
+#define _mbg_swab_ant_cable_len( _p ) _mbg_swab16( _p )
+
+
+
+/* Configuration data for an optional LAN interface.
+ *
+ * This is only supported if the flag GPS_HAS_LAN_IP4
+ * is set in RECEIVER_INFO::features.
+ */
+
+
+/* Basic network settings */
+
+typedef uint32_t IP4_ADDR;
+
+#define _mbg_swab_ip4_addr( _p ) \
+ _mbg_swab32( _p );
+
+
+typedef struct
+{
+ IP4_ADDR ip_addr;
+ IP4_ADDR netmask;
+ IP4_ADDR broad_addr;
+ IP4_ADDR gateway;
+ uint32_t flags; /* see below */
+
+} IP4_SETTINGS;
+
+#define _mbg_swab_ip4_settings( _p ) \
+{ \
+ _mbg_swab_ip4_addr( &(_p)->ip_addr ); \
+ _mbg_swab_ip4_addr( &(_p)->netmask ); \
+ _mbg_swab_ip4_addr( &(_p)->broad_addr ); \
+ _mbg_swab_ip4_addr( &(_p)->gateway ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+#if 0 //##++ currently not used
+
+/* Misc configuration */
+
+typedef struct
+{
+ uint16_t id; /* service ID, see below */
+ uint16_t index; /* used if several same svcs must be cfg'd, e.g. DNS */
+ char host[50]; /* see below */
+
+} IP_CFG;
+
+
+
+/* Description of a service running on a device */
+
+typedef struct
+{
+ uint16_t id; /* service ID, see below */
+ uint16_t socket; /* the socket on which the service is listening */
+ uint32_t flags; /* see below */
+
+} IP_SERVICE;
+
+#endif // 0
+
+
+
+/* LAN interface information */
+
+typedef struct
+{
+ uint16_t type; /* codes see below */
+ uint8_t mac_addr[6]; /* MAC address */
+ 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 */
+} 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 ); \
+}
+
+
+
+/* codes used with LAN_IF_INFO::type: */
+
+enum
+{
+ LAN_IF_TYPE_XPORT,
+ LAN_IF_TYPE_PTP,
+ N_LAN_IF_TYPE
+};
+
+
+/* Flags used with IP4_SETTINGS::flags and LAN_IF_INFO::flags: */
+
+enum
+{
+ IP4_BIT_DHCP,
+ IP4_BIT_LINK, // used only to report state
+ N_IP4_BIT
+};
+
+#define IP4_MSK_DHCP ( 1UL << IP4_BIT_DHCP )
+#define IP4_MSK_LINK ( 1UL << IP4_BIT_LINK )
+
+
+enum
+{
+ PTP_NW_PROT_BIT_RESERVED,
+ PTP_NW_PROT_BIT_UDP_IPV4,
+ PTP_NW_PROT_BIT_UDP_IPV6,
+ PTP_NW_PROT_BIT_IEEE_802_3,
+ PTP_NW_PROT_BIT_DEVICE_NET,
+ PTP_NW_PROT_BIT_CONTROL_NET,
+ PTP_NW_PROT_BIT_PROFINET,
+ N_PTP_NW_PROT
+};
+
+#define PTP_NW_PROT_MSK_RESERVED ( 1UL << PTP_NW_PROT_BIT_RESERVED )
+#define PTP_NW_PROT_MSK_UDP_IPV4 ( 1UL << PTP_NW_PROT_BIT_UDP_IPV4 )
+#define PTP_NW_PROT_MSK_UDP_IPV6 ( 1UL << PTP_NW_PROT_BIT_UDP_IPV6 )
+#define PTP_NW_PROT_MSK_IEEE_802_3 ( 1UL << PTP_NW_PROT_BIT_IEEE_802_3 )
+#define PTP_NW_PROT_MSK_DEVICE_NET ( 1UL << PTP_NW_PROT_BIT_DEVICE_NET )
+#define PTP_NW_PROT_MSK_CONTROL_NET ( 1UL << PTP_NW_PROT_BIT_CONTROL_NET )
+#define PTP_NW_PROT_MSK_PROFINET ( 1UL << PTP_NW_PROT_BIT_PROFINET )
+
+#if !defined( DEFAULT_PTP_NW_PROT_MASK )
+ #define DEFAULT_PTP_NW_PROT_MASK ( PTP_NW_PROT_MSK_UDP_IPV4 | PTP_NW_PROT_MSK_IEEE_802_3 )
+#endif
+
+#define PTP_NW_PROT_STRS \
+{ \
+ "Reserved", \
+ "UDP/IPv4", \
+ "UDP/IPv6", \
+ "IEEE 802.3", \
+ "DeviceNet", \
+ "ControlNet", \
+ "PROFINET" \
+}
+
+
+
+enum
+{
+ PTP_PORT_STATE_UNINITIALIZED,
+ PTP_PORT_STATE_INITIALIZING,
+ PTP_PORT_STATE_FAULTY,
+ PTP_PORT_STATE_DISABLED,
+ PTP_PORT_STATE_LISTENING,
+ PTP_PORT_STATE_PRE_MASTER,
+ PTP_PORT_STATE_MASTER,
+ PTP_PORT_STATE_PASSIVE,
+ PTP_PORT_STATE_UNCALIBRATED,
+ PTP_PORT_STATE_SLAVE,
+ N_PTP_PORT_STATE
+};
+
+#define PTP_PORT_STATE_STRS \
+{ \
+ "UNINITIALIZED", \
+ "INITIALIZING", \
+ "FAULTY", \
+ "DISABLED", \
+ "LISTENING", \
+ "PRE_MASTER", \
+ "MASTER", \
+ "PASSIVE", \
+ "UNCALIBRATED", \
+ "SLAVE" \
+}
+
+
+typedef struct
+{
+ uint8_t value;
+ char *name;
+} PTP_TABLE;
+
+
+enum
+{
+ PTP_DELAY_MECH_BIT_E2E, // in PTP2 specs: 0x01
+ PTP_DELAY_MECH_BIT_P2P, // in PTP2 specs: 0x02
+ N_PTP_DELAY_MECH // additionally the specs define 0xFE for disabled
+};
+
+#define PTP_DELAY_MECH_MSK_E2E ( 1UL << PTP_DELAY_MECH_BIT_E2E )
+#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 )
+#endif
+
+#define PTP_DELAY_MECH_NAMES \
+{ \
+ "E2E", \
+ "P2P" \
+}
+
+
+
+#define PTP_CLOCK_ACCURACY_RESERVED_OFFSET 0x20
+
+enum
+{
+ PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_RESERVED_OFFSET,
+ PTP_CLOCK_ACCURACY_100ns,
+ PTP_CLOCK_ACCURACY_250ns,
+ PTP_CLOCK_ACCURACY_1us,
+ PTP_CLOCK_ACCURACY_2_5us,
+ PTP_CLOCK_ACCURACY_10us,
+ PTP_CLOCK_ACCURACY_25us,
+ PTP_CLOCK_ACCURACY_100us,
+ PTP_CLOCK_ACCURACY_250us,
+ PTP_CLOCK_ACCURACY_1ms,
+ PTP_CLOCK_ACCURACY_2_5ms,
+ PTP_CLOCK_ACCURACY_10ms,
+ PTP_CLOCK_ACCURACY_25ms,
+ PTP_CLOCK_ACCURACY_100ms,
+ PTP_CLOCK_ACCURACY_250ms,
+ PTP_CLOCK_ACCURACY_1s,
+ PTP_CLOCK_ACCURACY_10s,
+ PTP_CLOCK_ACCURACY_MORE_10s,
+ PTP_CLOCK_ACCURACY_RESERVED_1,
+ PTP_CLOCK_ACCURACY_RESERVED_2,
+ PTP_CLOCK_ACCURACY_RESERVED_3,
+ PTP_CLOCK_ACCURACY_RESERVED_4,
+ N_PTP_CLOCK_ACCURACY
+};
+
+
+// Attention: Substract offset of PTP_CLOCK_ACCURACY_RESERVED_OFFSET when
+// using the enum above as index for the initializer below!
+#define PTP_CLOCK_ACCURACY_STRS \
+{ \
+ "< 25 ns", \
+ "< 100 ns", \
+ "< 250 ns", \
+ "< 1 us", \
+ "< 2.5 us", \
+ "< 10 us", \
+ "< 25 us", \
+ "< 100 us", \
+ "< 250 us", \
+ "< 1 ms", \
+ "< 2.5 ms", \
+ "< 10 ms", \
+ "< 25 ms", \
+ "< 100 ms", \
+ "< 250 ms", \
+ "< 1 s", \
+ "< 10 s", \
+ "more than 10 s", \
+ "reserved_1", \
+ "reserved_2", \
+ "reserved_3", \
+ "reserved_4" \
+}
+
+
+
+#define PTP_TIME_SOURCE_ATOMIC_CLOCK 0x10
+#define PTP_TIME_SOURCE_GPS 0x20
+#define PTP_TIME_SOURCE_TERRESTRIAL_RADIO 0x30
+#define PTP_TIME_SOURCE_PTP 0x40
+#define PTP_TIME_SOURCE_NTP 0x50
+#define PTP_TIME_SOURCE_HAND_SET 0x60
+#define PTP_TIME_SOURCE_OTHER 0x90
+#define PTP_TIME_SOURCE_INTERNAL_OSCILLATOR 0xA0
+
+
+
+#define PTP_TIME_SOURCE_TABLE \
+{ \
+ { PTP_TIME_SOURCE_ATOMIC_CLOCK, "Atomic Clock" }, \
+ { PTP_TIME_SOURCE_GPS, "GPS" }, \
+ { PTP_TIME_SOURCE_TERRESTRIAL_RADIO, "Terrestrial Radio" }, \
+ { PTP_TIME_SOURCE_PTP, "PTP" }, \
+ { PTP_TIME_SOURCE_NTP, "NTP" }, \
+ { PTP_TIME_SOURCE_HAND_SET, "HAND SET" }, \
+ { PTP_TIME_SOURCE_OTHER, "OTHER" }, \
+ { PTP_TIME_SOURCE_INTERNAL_OSCILLATOR, "Internal Oscillator" }, \
+ { 0, NULL } \
+}
+
+
+
+
+/* PTP configuration stuff */
+
+typedef struct
+{
+ uint8_t b[8];
+} PTP_CLOCK_IDENTITY;
+
+
+
+typedef struct
+{
+ uint16_t network_protocol; // enum
+ uint8_t ptp_proto_version; // PTP v1 or v2
+ uint8_t port_state; // enum
+ uint32_t flags;
+ NANO_TIME offset;
+ NANO_TIME path_delay;
+ NANO_TIME mean_path_delay;
+ NANO_TIME delay_asymmetry;
+
+ PTP_CLOCK_IDENTITY gm_identity;
+
+ uint16_t clock_offset_scaled_log_variance;
+ uint8_t clock_class;
+ uint8_t clock_accuracy; // enum
+
+ uint32_t num_clients;
+ uint32_t num_masters;
+
+ uint8_t domain_number;
+ uint8_t time_source; // enum
+ uint8_t delay_mech;
+ int8_t log_delay_req_intv;
+
+ int16_t utc_offset;
+ DAC_VAL osc_dac_cal;
+
+ uint32_t reserved;
+} PTP_STATE;
+
+#define _mbg_swab_ptp_state( _p ) \
+{ \
+ _mbg_swab16( &(_p)->network_protocol ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab_nano_time( &(_p)->offset ); \
+ _mbg_swab_nano_time( &(_p)->path_delay ); \
+ _mbg_swab_nano_time( &(_p)->mean_path_delay ); \
+ _mbg_swab_nano_time( &(_p)->delay_asymmetry ); \
+ _mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \
+ _mbg_swab32( &(_p)->num_clients ); \
+ _mbg_swab32( &(_p)->num_masters ); \
+ _mbg_swab32( &(_p)->utc_offset ); \
+ _mbg_swab_dac_val( &(_p)->osc_dac_cal ); \
+}
+
+
+enum
+{
+ PTP_FLAG_BIT_SLAVE_ONLY,
+ PTP_FLAG_BIT_IS_SLAVE,
+ PTP_FLAG_BIT_TIMESCALE_IS_PTP,
+ PTP_FLAG_BIT_LS_ANN,
+ PTP_FLAG_BIT_LS_ANN_NEG,
+ N_PTP_FLAG_BIT
+};
+
+#define PTP_FLAG_MSK_SLAVE_ONLY ( 1UL << PTP_FLAG_BIT_SLAVE_ONLY )
+#define PTP_FLAG_MSK_IS_SLAVE ( 1UL << PTP_FLAG_BIT_IS_SLAVE )
+#define PTP_FLAG_MSK_TIMESCALE_IS_PTP ( 1UL << PTP_FLAG_BIT_TIMESCALE_IS_PTP )
+#define PTP_FLAG_MSK_LS_ANN ( 1UL << PTP_FLAG_BIT_LS_ANN )
+#define PTP_FLAG_MSK_LS_ANN_NEG ( 1UL << PTP_FLAG_BIT_LS_ANN_NEG )
+
+
+#define PTP_SYNC_INTERVAL_MIN -6
+#define PTP_SYNC_INTERVAL_MAX 6
+
+#define PTP_DELAY_REQ_INTERVAL_MIN -6
+#define PTP_DELAY_REQ_INTERVAL_MAX 6
+
+
+typedef struct
+{
+ uint16_t network_protocol; // enum, only 1 or 3
+ uint8_t profile; // currently only 0 = default
+ uint8_t domain_number; // 0:3
+
+ uint8_t delay_mechanism; // 0 (E2E) or 1 (P2P), unless disabled
+ uint8_t reserved_0;
+ uint8_t priority_1;
+ uint8_t priority_2;
+
+ uint8_t dflt_clk_class_unsync_cold; // 6:255
+ uint8_t dflt_clk_class_unsync_warm; // 6:255
+ uint8_t dflt_clk_class_sync_cold; // 6:255
+ uint8_t dflt_clk_class_sync_warm; // 6:255
+
+ uint8_t reserved_1; // currently always 0
+ uint8_t reserved_2; // currently always 0
+ int16_t sync_interval; // log 2
+
+ int16_t announce_interval; // log 2
+ int16_t delay_request_interval; // log 2
+
+ uint32_t upper_bound; // [ns] sync state set to false if above this limit
+ 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)
+
+} PTP_CFG_SETTINGS;
+
+#define _mbg_swab_ptp_cfg_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->network_protocol ); \
+ _mbg_swab16( &(_p)->sync_interval ); \
+ _mbg_swab16( &(_p)->announce_interval ); \
+ _mbg_swab16( &(_p)->delay_request_interval ); \
+ _mbg_swab32( &(_p)->upper_bound ); \
+ _mbg_swab32( &(_p)->lower_bound ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+typedef struct
+{
+ PTP_CFG_SETTINGS settings;
+
+ uint8_t ptp_proto_version; // PTP v1 or v2
+ uint8_t reserved_1; // currently always 0
+ uint16_t reserved_2; // currently always 0
+
+ int16_t sync_interval_min; // log 2
+ int16_t sync_interval_max; // log 2
+ int16_t announce_interval_min; // log 2
+ int16_t announce_interval_max; // log 2
+ int16_t delay_request_interval_min; // log 2
+ int16_t delay_request_interval_max; // log 2
+
+ uint32_t supported_flags; // (see below)
+ uint32_t supported_network_protocols;
+ uint32_t supported_profiles;
+ uint32_t supported_delay_mechanisms;
+
+} PTP_CFG_INFO;
+
+#define _mbg_swab_ptp_cfg_info( _p ) \
+{ \
+ _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \
+ _mbg_swab16( &(_p)->sync_interval_min ); \
+ _mbg_swab16( &(_p)->sync_interval_max ); \
+ _mbg_swab16( &(_p)->announce_interval_min ); \
+ _mbg_swab16( &(_p)->announce_interval_max ); \
+ _mbg_swab16( &(_p)->delay_request_interval_min ); \
+ _mbg_swab16( &(_p)->delay_request_interval_max ); \
+ _mbg_swab32( &(_p)->supported_flags ); \
+ _mbg_swab32( &(_p)->supported_profiles ); \
+ _mbg_swab32( &(_p)->supported_delay_mechanisms ); \
+}
+
+
+
+// flags used with PTP_CFG_SETTINGS::flags and PTP_CFG_INFO::supported_flags:
+// possibly also: can be master (i.e not slave only), v1 hw compat, ...
+enum
+{
+ PTP_CFG_BIT_TIME_SCALE_IS_PTP, // time scale is PTP/TAI, else arbitrary
+ PTP_CFG_BIT_V1_HW_COMPAT,
+ N_PTP_CFG_BIT
+};
+
+#define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_BIT_TIME_SCALE_IS_PTP )
+#define PTP_CFG_MSK_V1_HW_COMPAT ( 1UL << PTP_CFG_BIT_V1_HW_COMPAT )
+
+
/*------------------------------------------------------------------------*/
@@ -2240,23 +3839,35 @@ typedef struct
-/* UTC correction parameters */
-
+/**
+ UTC correction parameters
+*/
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data 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 [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 LS is inserted */
- int8_t delta_tls; /* */
- int8_t delta_tlsf; /* */
+ 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] */
+ int8_t delta_tlsf; /**< Future UTC offset to GPS system time after next leap second transition [sec] */
} UTC;
+#define _mbg_swab_utc_parm( _p ) \
+{ \
+ _mbg_swab_csum( &(_p)->csum ); \
+ _mbg_swab16( &(_p)->valid ); \
+ _mbg_swab_t_gps( &(_p)->t0t ); \
+ _mbg_swab_double( &(_p)->A0 ); \
+ _mbg_swab_double( &(_p)->A1 ); \
+ _mbg_swab16( &(_p)->WNlsf ); \
+ _mbg_swab16( &(_p)->DNt ); \
+}
+
/* Ionospheric correction parameters */
@@ -2289,6 +3900,78 @@ typedef struct
} ASCII_MSG;
+
+enum
+{
+ GPS_PLATFORM_PORTABLE,
+ GPS_PLATFORM_FIXED,
+ GPS_PLATFORM_STATIONARY,
+ GPS_PLATFORM_PEDESTRIAN,
+ GPS_PLATFORM_AUTOMOTIVE,
+ GPS_PLATFORM_SEA,
+ GPS_PLATFORM_AIRBORNE_1G,
+ GPS_PLATFORM_AIRBORNE_2G,
+ GPS_PLATFORM_AIRBORNE_4G,
+ N_GPS_PLATFORMS
+};
+
+
+#define GPS_PLATFORM_STRS \
+{ \
+ "Portable ", \
+ "Fixed ", \
+ "Stationary ", \
+ "Pedestrian ", \
+ "Automotive ", \
+ "Sea ", \
+ "Airborne <1G", \
+ "Airborne <2G", \
+ "Airborne <4G" \
+}
+
+
+
+enum
+{
+ TIME_MODE_DISABLED,
+ TIME_MODE_SURVEY_IN,
+ TIME_MODE_FIXED
+};
+
+
+
+typedef struct
+{
+ uint32_t time_mode;
+ uint32_t survey_in_duration;
+ uint32_t survey_in_pos_var;
+ int32_t fixedPosX; // cm
+ int32_t fixedPosY; // cm
+ int32_t fixedPosZ; // cm
+ uint32_t fixedPosVar; // cm
+ uint32_t flags; // currently 0
+ uint32_t reserved; // currently 0
+} NAV_TIME_MODE_SETTINGS;
+
+
+/**
+ Navigation Engine settings to set configuration
+ parameters of a dynamic platform model.
+*/
+typedef struct
+{
+ uint8_t dynamic_platform;
+ uint8_t fix_mode;
+ int8_t min_elevation;
+ uint8_t static_hold_threshold;
+ int32_t fixed_altitude;
+ uint32_t fixed_altitude_variance;
+ uint32_t flags; // currently 0
+ uint32_t reserved; // currently 0
+ NAV_TIME_MODE_SETTINGS nav_time_mode_settings;
+} NAV_ENGINE_SETTINGS;
+
+
/* End of header body */
diff --git a/mbglib/common/gpsserio.c b/mbglib/common/gpsserio.c
index 56a0892..15cc808 100644
--- a/mbglib/common/gpsserio.c
+++ b/mbglib/common/gpsserio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsserio.c 1.6 2006/10/25 12:24:01 martin REL_M $
+ * $Id: gpsserio.c 1.9 2009/09/01 09:51:56 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,17 @@
*
* -----------------------------------------------------------------------
* $Log: gpsserio.c $
- * Revision 1.6 2006/10/25 12:24:01 martin
+ * Revision 1.9 2009/09/01 09:51:56 martin
+ * Removed obsolete includes.
+ * Revision 1.8 2009/03/10 16:58:09 martin
+ * Fixed compiler warnings.
+ * Revision 1.7 2008/09/03 15:22:40 martin
+ * Decryption with wrong password yields garbage, still needs to be fixed.
+ * In xmt_tbuff() use MBG_PORT_HANDLE for serial connections.
+ * Some cleanup in check_transfer().
+ * Fixed a VC6 compiler warning.
+ * Moved low level serial I/O routines to mbgserio.c.
+ * Revision 1.6 2006/10/25 12:24:01Z martin
* Support serial I/O under Windows.
* Removed obsolete code.
* Revision 1.5 2006/08/24 12:57:41Z martin
@@ -43,7 +53,7 @@
#if defined( MBG_TGT_UNIX )
#include <unistd.h>
- #include <sys/time.h>
+//##++++ #include <sys/time.h>
#endif
#if _USE_ENCRYPTION
@@ -175,8 +185,6 @@ int chk_data_csum( MBG_MSG_BUFF *pmb )
#else
- #include <sys/time.h>
-
static
void randomize( void )
{
@@ -255,7 +263,7 @@ int decrypt_message( MBG_MSG_CTL *pmctl )
if ( pmb->hdr.len < AES_BLOCK_SIZE )
return 0;
- rc = aes_decrypt_buff( (char *) &pcmd->enc_msg,
+ rc = aes_decrypt_buff( (unsigned char *) &pcmd->enc_msg,
pmctl->aes_keyvect,
pcmd->aes_initvect,
pmb->hdr.len - sizeof( pcmd->aes_initvect )
@@ -270,6 +278,13 @@ int decrypt_message( MBG_MSG_CTL *pmctl )
/* packet decrypted successfully. */
prctl->flags |= MBG_MSG_RCV_CTL_DECRYPTED;
+ // If the wrong password has been used for decryption
+ // then decryption may have been formally successful,
+ // but the decrypted message contains garbage.
+ // So we must check whether the decrypted packet
+ // also contains a valid header and data part.
+ //##+++ TODO
+
/* copy the decrypted message to head of the buffer */
memcpy( pmb, &pcmd->enc_msg, pcmd->enc_msg.enc_hdr.len + sizeof( pcmd->enc_msg.enc_hdr ) );
@@ -288,7 +303,7 @@ int decrypt_message( MBG_MSG_CTL *pmctl )
/*HDR*/
-void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, uint8_t *key )
+void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, const char *key )
{
int i;
@@ -366,7 +381,7 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl )
#if _USE_SERIAL_IO
case MBG_CONN_TYPE_SERIAL:
{
- MBG_HANDLE port_handle = pmctl->st.serio.port_handle;
+ MBG_PORT_HANDLE port_handle = pmctl->st.serio.port_handle;
// Note: encrypted msgs over serial are not yet supported.
@@ -500,8 +515,8 @@ int xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us )
/*HDR*/
int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
{
- MBG_MSG_BUFF *pmb;
- MSG_HDR *pmh;
+ MBG_MSG_BUFF *pmb = prctl->pmb;
+ MSG_HDR *pmh = &pmb->hdr;
if ( prctl->cnt == 0 ) /* not receiving yet */
{
@@ -509,10 +524,7 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
return TR_WAITING; /* ignore this character */
/* initialize receiving */
- pmb = prctl->pmb;
- pmh = &pmb->hdr;
- prctl->pmb = pmb;
- prctl->cur = (uint8_t *) pmh; /* first byte of header */
+ prctl->cur = (uint8_t *) pmb; /* first byte of buffer */
prctl->cnt = sizeof( *pmh ); /* prepare to rcv msg header */
prctl->flags = 0;
@@ -522,10 +534,7 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
/* SOH has already been received */
- pmb = prctl->pmb;
- pmh = &pmb->hdr;
-
- if ( prctl->cur < &( (uint8_t *) prctl->pmb )[prctl->buf_size] )
+ if ( prctl->cur < &prctl->pmb->u.bytes[prctl->buf_size] )
{
*prctl->cur = c; /* save incoming character */
prctl->cur++;
@@ -544,7 +553,7 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
if ( !( prctl->flags & MBG_MSG_RCV_CTL_RCVD_HDR ) ) /* header complete now */
{
- int data_len;
+ unsigned int data_len;
if ( chk_hdr_csum( pmh ) < 0 ) /* error */
{
@@ -585,88 +594,3 @@ msg_complete:
-#if defined( MBG_TGT_WIN32 )
-
-/*HDR*/
-int mbgserio_close( MBG_HANDLE h )
-{
- CloseHandle( h );
-
- return 0;
-
-} // mbgserio_close
-
-
-
-/*HDR*/
-int mbgserio_read( MBG_HANDLE h, void *buffer, unsigned int count )
-{
- BOOL fReadStat;
- COMSTAT ComStat;
- DWORD dwErrorFlags, dwLength;
-
- ClearCommError( h, &dwErrorFlags, &ComStat );
-
- if ( dwErrorFlags )
- return 0;
-
-
- dwLength = min( (DWORD) count, ComStat.cbInQue );
-
- if ( dwLength > 0 )
- {
- fReadStat = ReadFile( h, buffer, dwLength, &dwLength, NULL );
-
- if ( !fReadStat )
- {
- // some other error occurred
- dwLength = 0 ;
- return 0;
- }
- }
-
- return dwLength;
-
-} // mbgserio_read
-
-
-
-/*HDR*/
-int mbgserio_write( MBG_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 )
- {
- #ifdef _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 )
-
diff --git a/mbglib/common/gpsserio.h b/mbglib/common/gpsserio.h
index 6033d40..a07b47c 100644
--- a/mbglib/common/gpsserio.h
+++ b/mbglib/common/gpsserio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsserio.h 1.21 2006/10/25 12:25:35 martin REL_M $
+ * $Id: gpsserio.h 1.32 2009/08/26 09:02:21 daniel REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -31,7 +31,50 @@
*
* -----------------------------------------------------------------------
* $Log: gpsserio.h $
- * Revision 1.21 2006/10/25 12:25:35 martin
+ * 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
+ * Renamed symbol MBGEXTIO_TIMEOUT_SOCKET to MBGEXTIO_RCV_TIMEOUT_SOCKET.
+ * Support new timeout handling distinguishing between character timeout
+ * and message timeout. Timeout values are now expected in milliseconds.
+ * Revision 1.30 2009/07/02 09:19:31 martin
+ * Moved definitions related to LAN interface configuration to gpsdefs.h.
+ * Revision 1.29 2009/03/10 17:00:29 martin
+ * Support configurable time scales.
+ * Don't pack structure MBG_MSG_CTL but use default alignment.
+ * Revision 1.28 2008/09/04 12:47:10Z martin
+ * Moved generic serial I/O stuff to mbgserio.h.
+ * Preliminarily support chk_tstr.
+ * Revision 1.27 2008/04/07 10:49:13Z martin
+ * Added cmd GPS_CLR_UCAP_BUFF.
+ * Revision 1.26 2007/02/27 09:51:45 martin
+ * Modified mutex macros for Windows.
+ * Added type TZCODE which is used by the binary protocol but
+ * has a different size than PCPS_TZCODE.
+ * Now _USE_PCPSDEFS by default for non-firmware apps.
+ * Fixed comments on GPS_OPT_SETTINGS and GPS_OPT_INFO.
+ * Revision 1.25 2007/02/06 16:31:04Z martin
+ * Modified comment for PZF_PCPS_TIME which can now also
+ * be sent to a device.
+ * Added mutex support.
+ * Added SVNO to the buffer union.
+ * Added support for OPT_SETTINGS.
+ * Added XMULTI_REF_... definitions.
+ * Modified some comments.
+ * Revision 1.24 2006/12/21 10:54:14Z martin
+ * Moved macro _IS_MBG_FIRMWARE to words.h.
+ * Cleaned up definitions of default I/O macros.
+ * Revision 1.23 2006/12/12 15:53:58 martin
+ * Added structure LAN_IF_INFO and associated codes.
+ * Added cmd codes GPS_IRIG_RX_SETTINGS and GPS_IRIG_RX_INFO.
+ * Added new member irig_rx_info to union MSG_DATA.
+ * Added cmd code GPS_REF_OFFS and associated definitions.
+ * Added cmd code GPS_DEBUG_STATUS.
+ * Define MBG_HANDLE for DOS even without v24tools.
+ * Revision 1.22 2006/11/02 08:57:56 martin
+ * Added a typedef to avoid firmware build errors.
+ * Revision 1.21 2006/10/25 12:25:35Z martin
* Support serial I/O under Windows.
* Removed obsolete definitions.
* Updated function prototypes.
@@ -126,73 +169,86 @@
* overridden by global definitions, if required.
*/
-#define _IS_MBG_FIRMWARE \
-( \
- defined( _C166 ) || \
- defined( _CC51 ) || \
- defined( __ARM ) || \
- defined( _USE_GPS163 ) \
-)
-
-#if !_IS_MBG_FIRMWARE
- #include <mbg_tgt.h> // determine the target OS
-
+#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_WIN32 )
- #include <windows.h>
- #include <io.h>
- #define _mbg_open _open
- #define _mbg_close _close
- #define _mbg_read _read
- #define _mbg_write _write
+ #ifndef _USE_MUTEX
+ #define _USE_MUTEX 1
+ #endif
- #define _mbgserio_close mbgserio_close
- #define _mbgserio_write mbgserio_write
- #define _mbgserio_read mbgserio_read
+ #if _USE_MUTEX
- #elif defined( MBG_TGT_UNIX )
- #include <unistd.h>
+ #include <windows.h>
- #define _mbg_open open
- #define _mbg_close close
- #define _mbg_read read
- #define _mbg_write write
- #endif
+ typedef HANDLE MBG_MUTEX_HANDLE;
- #if defined( _USE_V24TOOLS )
- #include <v24tools.h>
+ #define _mbg_mutex_init( _m ) \
+ _m = CreateMutex( NULL, FALSE, NULL )
- typedef int MBG_HANDLE;
+ #define _mbg_mutex_lock( _m ) \
+ WaitForSingleObject( _m, INFINITE )
- #define _mbgserio_open v24open
- #define _mbgserio_close v24close
- #define _mbgserio_read v24read
- #define _mbgserio_write v24write
- #else
- #if !defined( _mbgserio_open )
- #define _mbgserio_open _mbg_open
- #endif
- #if !defined( _mbgserio_close )
- #define _mbgserio_close _mbg_close
+ #define _mbg_mutex_unlock( _m ) \
+ ReleaseMutex( _m )
+
+ #define _mbg_mutex_destroy( _m ) \
+ CloseHandle( _m )
#endif
- #if !defined( _mbgserio_write )
- #define _mbgserio_write _mbg_write
+
+ #elif defined( MBG_TGT_UNIX )
+
+ #ifndef _USE_MUTEX
+ #define _USE_MUTEX 1
#endif
- #if !defined( _mbgserio_read )
- #define _mbgserio_read _mbg_read
+
+ #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
#endif
+
#endif
/* Control whether network socket communication shall be supported */
#ifndef _USE_SOCKET_IO
- #define _USE_SOCKET_IO 0 // not supported by default
+ #define _USE_SOCKET_IO 0 // not supported by default
#endif
/* Control whether serial port communication shall be supported */
#ifndef _USE_SERIAL_IO
- #define _USE_SERIAL_IO 1 // supported by default
+ #if _IS_MBG_FIRMWARE
+ #define _USE_SERIAL_IO 0 // Firmware provides its own serial I/O functions
+ #else
+ #define _USE_SERIAL_IO 1 // supported by default
+ #endif
#endif
/* Control inclusion of secudefs.h */
@@ -210,12 +266,22 @@
#endif
#endif
+#if _USE_SERIAL_IO
+ #include <mbgserio.h>
+#endif
+
/* Control inclusion of pcpsdefs.h */
#ifndef _USE_PCPSDEFS
- #define _USE_PCPSDEFS \
- ( \
- defined( _CC51 ) \
- )
+ #if _IS_MBG_FIRMWARE
+ // for firmware depend on the target system
+ #define _USE_PCPSDEFS \
+ ( \
+ defined( _CC51 ) \
+ )
+ #else
+ // otherwise include it by default
+ #define _USE_PCPSDEFS 1
+ #endif
#endif
/* Control inclusion of non-public declarations */
@@ -237,12 +303,6 @@
#endif
#endif
-#if _USE_SERIAL_IO
- #if defined( MBG_TGT_UNIX )
- #include <termios.h>
- #endif
-#endif
-
#if _USE_ENCRYPTION
#include <secudefs.h>
#include <aes128.h>
@@ -348,6 +408,18 @@ enum /* | | | */
GPS_MULTI_REF_STATUS, /* | | X | | MULTI_REF_STATUS, (only if HAS_MULTI_REF) */
GPS_RCV_TIMEOUT, /* | | X | X | RCV_TIMEOUT, [min] (only if HAS_RCV_TIMEOUT) */
GPS_IGNORE_LOCK, /* | | X | X | IGNORE_LOCK, if != 0 always claim to be sync */
+ GPS_IRIG_RX_SETTINGS, /* | | X | X | IRIG_SETTINGS, (only if GPS_HAS_IRIG_RX) */
+ GPS_IRIG_RX_INFO, /* | | X | | IRIG_INFO, (only if GPS_HAS_IRIG_RX) */
+ GPS_REF_OFFS, /* | | X | X | MBG_REF_OFFS, (only if GPS_HAS_REF_OFFS) */
+ GPS_DEBUG_STATUS, /* | | X | | MBG_DEBUG_STATUS, (only if GPS_HAS_DEBUG_STATUS) */
+ GPS_XMR_SETTINGS_IDX, /* | | X | X | XMULTI_REF_SETTINGS_IDX, (only if GPS_HAS_XMULTI_REF) */
+ GPS_XMR_INFO_IDX, /* | | X | | XMULTI_REF_INFO_IDX, (only if GPS_HAS_XMULTI_REF) */
+ GPS_XMR_STATUS_IDX, /* | | X | | XMULTI_REF_STATUS_IDX, (only if GPS_HAS_XMULTI_REF) */
+ GPS_OPT_SETTINGS, /* | | X | X | MBG_OPT_SETTINGS, (only if GPS_HAS_OPT_SETTINGS) */
+ 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 data */
GPS_CFGH = 0x100, /* | | X | X | CFGH, SVs' configuration and health codes */
@@ -357,8 +429,12 @@ enum /* | | | */
GPS_IONO, /* | | X | X | IONO, GPS ionospheric correction parameters */
GPS_ASCII_MSG, /* | | X | | ASCII_MSG, the GPS ASCII message */
+ /* Glonass data */
+ GPS_GLNS_ALM = 0x200, /* | | X | X | ** preliminary ** */ //##++
+
/* Misc data */
GPS_IP4_SETTINGS = 0x800, /* | X | X | IP4_SETTINGS, cfg of optional LAN interface */
+ GPS_LAN_IF_INFO, /* | X | | LAN_IF_INFO, LAN interface info */
GPS_CRYPTED_PACKET = 0x880, /* | X | X | X | encrypted binary packet */
GPS_CRYPTED_RAW_PACKET, /* | X | X | X | encrypted binary raw packet */
@@ -368,17 +444,21 @@ enum /* | | | */
GPS_SECU_PUBLIC_KEY, /* | | | | settings and password for LAN interface */
/* PZF data */
- PZF_PCPS_TIME = 0xA00, /* | | X | | PCPS_TIME, date/time/status */
+ PZF_PCPS_TIME = 0xA00, /* | | X | X | PCPS_TIME, date/time/status */
PZF_TR_DISTANCE, /* | | X | X | TR_DISTANCE, dist. from transmitter [km] */
PZF_TZCODE, /* | | X | X | TZCODE, time zone code */
PZF_CORR_INFO /* | | X | | CORR_INFO, correlation info */
};
-
-/* Caution: If almanac or ephemeris data are requested from the GPS rcvr */
-/* an uint16_t parameter must be supplied specifying the number of the SV */
-/* whose data is to be returned. The SV number may be 0 or MIN_SVNO to */
-/* MAX_SVNO, if the number is 0, ALL almanacs (32) are sent. */
+/*
+ * Caution: If GPS_ALM, GPS_EPH or a code named ..._IDX is sent to retrieve
+ * some data from a device then an uint16_t parameter must be also supplied
+ * in order to specify the index number of the data set to be returned.
+ * The valid index range depends on the command code.
+ *
+ * For GPS_ALM and GPS_EPH the index is the SV number which may be 0 or
+ * MIN_SVNO to MAX_SVNO. If the number is 0, ALL almanacs (32) are returned.
+ */
/* A structure holding the number of a SV and the SV's almanac. */
@@ -401,48 +481,12 @@ typedef struct
-/* Configuration data for an optional LAN interface.
- *
- * This is only supported if the flag GPS_HAS_LAN_IP4
- * is set in RECEIVER_INFO::features.
- */
-
-
-/* Basic network settings */
-
-typedef struct
-{
- uint32_t ip_addr;
- uint32_t netmask;
- uint32_t broad_addr;
- uint32_t gateway;
- uint32_t flags; /* reserved, currently 0 */
-
-} IP4_SETTINGS;
-
-
-
-/* Misc configuration */
-
-typedef struct
-{
- uint16_t id; /* service ID, see below */
- uint16_t index; /* used if several same svcs must be cfg'd, e.g. DNS */
- char host[50]; /* see below */
-
-} IP_CFG;
-
-
-
-/* Description of a service running on a device */
+#if _USE_PCPSDEFS
-typedef struct
-{
- uint16_t id; /* service ID, see below */
- uint16_t socket; /* the socket on which the service is listening */
- uint32_t flags; /* see below */
+/* Attention: this differs from PCPS_TZCODE defined in pcpsdefs.h */
+typedef uint16_t TZCODE;
-} IP_SERVICE;
+#endif
@@ -467,6 +511,7 @@ typedef union
/* common types */
uint16_t us;
double d;
+ SVNO svno;
/* user data */
SW_REV sw_rev;
@@ -496,6 +541,18 @@ typedef union
MULTI_REF_STATUS multi_ref_status;
RCV_TIMEOUT rcv_timeout;
IGNORE_LOCK ignore_lock;
+ IRIG_SETTINGS irig_rx_settings;
+ IRIG_INFO irig_rx_info;
+ MBG_REF_OFFS ref_offs;
+ MBG_DEBUG_STATUS debug_status;
+ XMULTI_REF_SETTINGS_IDX xmulti_ref_settings_idx;
+ XMULTI_REF_INFO_IDX xmulti_ref_info_idx;
+ XMULTI_REF_STATUS_IDX xmulti_ref_status_idx;
+ MBG_OPT_SETTINGS opt_settings;
+ MBG_OPT_INFO opt_info;
+ MBG_TIME_SCALE_INFO time_scale_info;
+ MBG_TIME_SCALE_SETTINGS time_scale_settings;
+ NAV_ENGINE_SETTINGS nav_engine_settings;
/* GPS system data */
CFGH cfgh;
@@ -507,11 +564,12 @@ typedef union
/* Misc data */
IP4_SETTINGS ip4_settings;
+ LAN_IF_INFO lan_if_info;
#if _USE_PCPSDEFS
PCPS_TIME pcps_time;
TR_DISTANCE tr_distance;
- PCPS_TZCODE tzcode;
+ TZCODE tzcode;
CORR_INFO corr_info;
#endif
@@ -546,12 +604,14 @@ typedef union
typedef struct
{
MSG_HDR hdr;
+
#if _USE_ENCRYPTION
uint8_t aes_initvect[AES_BLOCK_SIZE];
#else
// In this case this structure is just a dummy to avoid
// a compiler error with the function prototypes.
#endif
+
} CRYPT_MSG_PREFIX;
@@ -561,15 +621,19 @@ typedef struct
typedef struct
{
uint8_t aes_initvect[AES_BLOCK_SIZE];
+
struct
{
MSG_HDR enc_hdr;
+
union
{
uint8_t bytes[MAX_MSG_DATA_SIZE];
MSG_DATA msg_data;
} enc_msg;
+
} enc_msg;
+
} CRYPT_MSG_DATA;
#endif
@@ -592,6 +656,7 @@ typedef struct
#if _USE_ENCRYPTION
CRYPT_MSG_DATA crypt_msg_data;
#endif
+
} u;
} MBG_MSG_BUFF;
@@ -607,6 +672,12 @@ 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_CHK_TSTR
+ void (*chk_tstr_fnc)( char c, TIMESTR_CHECK *arg ); /* optional handler for normal, non-protocol data */
+ TIMESTR_CHECK *chk_tstr_arg;
+ #endif
+
} MBG_MSG_RCV_CTL;
@@ -636,6 +707,10 @@ typedef struct
int buf_size;
int xfer_mode;
+ #if _USE_MUTEX
+ MBG_MUTEX_HANDLE xmt_mutex;
+ #endif
+
} MBG_MSG_XMT_CTL;
@@ -652,8 +727,8 @@ enum
#if _USE_SOCKET_IO
-#if !defined ( MBGEXTIO_TIMEOUT_SOCKET )
- #define MBGEXTIO_TIMEOUT_SOCKET 2
+#if !defined ( MBGEXTIO_RCV_TIMEOUT_SOCKET )
+ #define MBGEXTIO_RCV_TIMEOUT_SOCKET 2000 // [ms]
#endif
#define LAN_XPT_PORT 10001
@@ -666,6 +741,7 @@ typedef struct
{
int sockfd;
struct sockaddr_in addr;
+
} SOCKET_IO_STATUS;
#endif // _USE_SOCKET_IO
@@ -673,23 +749,15 @@ typedef struct
#if _USE_SERIAL_IO
-#if !defined ( MBGEXTIO_TIMEOUT_SERIAL )
- #define MBGEXTIO_TIMEOUT_SERIAL 3
-#endif
+#endif // _USE_SERIAL_IO
-typedef struct
-{
- MBG_HANDLE port_handle; // the handle that will be used for the device
- #if defined( MBG_TGT_UNIX )
- struct termios oldtio;
- struct termios newtio;
- #endif
-} SERIAL_IO_STATUS;
-
-#endif // _USE_SERIAL_IO
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+// For the next structure we can and should use native alignment:
typedef struct
{
@@ -698,7 +766,8 @@ typedef struct
int conn_type;
int io_error;
- int timeout;
+ ulong msg_rcv_timeout; // binary message receive timeout [ms]
+ ulong char_rcv_timeout; // serial character receive timeout [ms]
#if _USE_ENCRYPTION
uint8_t aes_initvect[AES_BLOCK_SIZE];
@@ -709,16 +778,18 @@ typedef struct
SECU_SETTINGS secu_settings;
#endif
- union
- {
- #if _USE_SOCKET_IO
- SOCKET_IO_STATUS sockio;
- #endif
-
- #if _USE_SERIAL_IO
- SERIAL_IO_STATUS serio;
- #endif
- } st;
+ #if _USE_SERIAL_IO || _USE_SOCKET_IO
+ union
+ {
+ #if _USE_SOCKET_IO
+ SOCKET_IO_STATUS sockio;
+ #endif
+
+ #if _USE_SERIAL_IO
+ SERIAL_IO_STATUS serio;
+ #endif
+ } st;
+ #endif
} MBG_MSG_CTL;
@@ -750,14 +821,11 @@ enum
int chk_data_csum( MBG_MSG_BUFF *pmb ) ;
int encrypt_message( MBG_MSG_CTL *pmctl, CRYPT_MSG_PREFIX *pcmp, MBG_MSG_BUFF *pmb ) ;
int decrypt_message( MBG_MSG_CTL *pmctl ) ;
- void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, uint8_t *key ) ;
+ void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, const char *key ) ;
int xmt_tbuff( MBG_MSG_CTL *pmctl ) ;
int xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd ) ;
int xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us ) ;
int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c ) ;
- int mbgserio_close( MBG_HANDLE h ) ;
- int mbgserio_read( MBG_HANDLE h, void *buffer, unsigned int count ) ;
- int mbgserio_write( MBG_HANDLE h, const void *buffer, unsigned int count ) ;
/* ----- function prototypes end ----- */
@@ -768,11 +836,6 @@ enum
#undef _ext
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
-#endif
-
-
#ifdef __cplusplus
}
#endif
diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h
index f8559fe..d5aba94 100644
--- a/mbglib/common/mbg_tgt.h
+++ b/mbglib/common/mbg_tgt.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_tgt.h 1.8 2006/10/25 12:20:45 martin REL_M $
+ * $Id: mbg_tgt.h 1.22 2009/10/01 08:20:50 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,48 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_tgt.h $
- * Revision 1.8 2006/10/25 12:20:45 martin
+ * Revision 1.22 2009/10/01 08:20:50 martin
+ * Fixed inline code support with different BC versions.
+ * 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
+ * Defined default MBG_INVALID_PORT_HANDLE for non-Windows targets.
+ * Revision 1.19 2009/06/09 10:03:58 daniel
+ * Preliminary support for ARM architecture.
+ * Revision 1.18 2009/04/01 14:10:55 martin
+ * Cleanup for CVI.
+ * Revision 1.17 2009/03/19 15:21:07Z martin
+ * Conditionally define DWORD_PTR type for old MS C compilers.
+ * Revision 1.16 2008/12/08 16:42:30 martin
+ * Defined _GNU_SOURCE for Linux.
+ * Revision 1.15 2008/11/19 15:31:49 martin
+ * Added symbol MBG_ARCH_I386.
+ * Revision 1.14 2008/09/03 15:06:04 martin
+ * Support DOS protected mode target.
+ * Support SUN SPARC architecture.
+ * Specified handle types for common host environments.
+ * Added macro MBG_USE_MM_IO_FOR_PCI.
+ * Added macro _nop_macro_fnc().
+ * Revision 1.13 2008/01/30 15:52:22 martin
+ * Modified checking for availability of wchar_t.
+ * Revision 1.13 2008/01/29 15:18:07Z martin
+ * Recognize DOS target under Watcom compilers.
+ * Flag Watcom C always supports wchar_t.
+ * Revision 1.12 2008/01/17 09:38:50Z daniel
+ * Added macros to determine whether C language extensions
+ * (e.g. C94, C99) are supported by the target environment.
+ * Added macro to check whether wchar_t and friends are
+ * supported, and some compatibility stuff.
+ * Revision 1.11 2007/10/31 16:58:03 martin
+ * Fixed __mbg_inline for Borland C (DOS).
+ * Revision 1.10 2007/09/25 08:10:27Z martin
+ * Support CVI target environment.
+ * Added MBG_PORT_HANDLE type for serial ports.
+ * Added macros for unified inline code syntax.
+ * Revision 1.9 2006/12/08 12:45:54Z martin
+ * Under Windows include ntddk.h rather than windows.h
+ * if building kernel driver .
+ * Revision 1.8 2006/10/25 12:20:45Z martin
* Initial support for FreeBSD, NetBSD, and OpenBSD.
* Added definitions for generic handle types.
* Revision 1.7 2006/08/23 13:43:55 martin
@@ -38,6 +79,8 @@
/* Other headers to be included */
+#include <stddef.h>
+
#ifdef _MBG_TGT
#define _ext
#else
@@ -47,7 +90,12 @@
/* Start of header body */
-#if defined( _WIN32_WINNT )
+#if defined( _CVI ) || defined( _CVI_ )
+
+ #define MBG_TGT_WIN32
+ #define MBG_TGT_CVI
+
+#elif defined( _WIN32_WINNT )
// MS platform SDK
// WinNT 4.0 and above
@@ -82,6 +130,11 @@
// MS Visual C++
#define MBG_TGT_WIN32
+#elif defined( __WINDOWS_386__ )
+
+ // Watcom C/C++ for target Win32
+ #define MBG_TGT_WIN32
+
#elif defined( __NETWARE_386__ )
// Watcom C/C++ for target NetWare
@@ -96,6 +149,7 @@
// GCC for target Linux
#define MBG_TGT_LINUX
+ #define _GNU_SOURCE 1
#elif defined( __FreeBSD__ )
@@ -122,11 +176,78 @@
#define MBG_TGT_QNX_NTO
#endif
-#elif defined( __MSDOS__ )
+#elif defined( __MSDOS__ ) || defined( __DOS__ )
// any compiler for target DOS
#define MBG_TGT_DOS
+ #if defined( __WATCOMC__ ) && defined( __386__ )
+
+ #define MBG_TGT_DOS_PM // protected mode DOS
+
+ #endif
+
+#endif
+
+// Some definitions which depend on the type of compiler ...
+
+#if defined( __GNUC__ )
+
+ #define __mbg_inline __inline__
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+
+ #if defined( __sparc__ )
+
+ #define MBG_ARCH_SPARC
+ #define _MBG_ARCH_DEFINED
+
+ #elif defined( __arm__ )
+
+ #define MBG_ARCH_ARM
+ #define _MBG_ARCH_DEFINED
+
+ #endif
+
+#elif defined( _MSC_VER )
+
+ #define __mbg_inline __forceinline
+
+ #define MBG_TGT_HAS_WCHAR_T 1
+
+#elif defined( _CVI ) || defined( _CVI_ )
+
+ // Inline code is not supported.
+
+ #define MBG_TGT_HAS_WCHAR_T 0
+
+#elif defined( __BORLANDC__ )
+
+ #if defined( __cplusplus )
+ #define __mbg_inline inline // standard C++ syntax
+ #elif ( __BORLANDC__ > 0x410 ) // BC3.1 defines 0x410 !
+ #define __mbg_inline __inline // newer BC versions support this for C
+ #else
+ #define __mbg_inline // up to BC3.1 not supported for C
+ #endif
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+
+#elif defined( __WATCOMC__ )
+
+ #define __mbg_inline _inline
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+
+#endif
+
+
+
+// Currently we support only Sparc and i386/x86_64 architectures,
+// so unless we have explicitely found sparc we assume i386.
+
+#if !defined( _MBG_ARCH_DEFINED )
+ #define MBG_ARCH_I386
#endif
@@ -156,6 +277,33 @@
#define WIN32_FLAVOR "ia64"
#endif
+ #if defined( _KDD_ )
+ #include <ntddk.h>
+ #else
+ // This must not be used for kernel drivers.
+ #include <windows.h>
+ typedef HANDLE MBG_HANDLE;
+
+ #define MBG_INVALID_HANDLE INVALID_HANDLE_VALUE
+
+ #if defined( MBG_TGT_CVI )
+ // CVI uses an own set of functions to support serial ports
+ typedef int MBG_PORT_HANDLE;
+ #define MBG_INVALID_PORT_HANDLE -1
+ #else
+ typedef HANDLE MBG_PORT_HANDLE;
+ #endif
+
+ // The DWORD_PTR type is not defined in the headers shipping
+ // with VC6. However, if the SDK is installed then the SDK's
+ // headers may declare this type. This is at least the case
+ // in the Oct 2001 SDK which also defines the symbol _W64.
+ #if !defined( _W64 )
+ typedef DWORD DWORD_PTR;
+ #endif
+
+ #endif
+
#define _MBG_API WINAPI
#if defined( MBG_LIB_EXPORT )
@@ -164,31 +312,71 @@
#define _MBG_API_ATTR __declspec( dllimport )
#endif
+#elif defined( MBG_TGT_UNIX )
+
+ typedef int MBG_HANDLE;
+ typedef int MBG_PORT_HANDLE;
+
+ #define MBG_INVALID_HANDLE -1
+
#else
- #define _MBG_API
- #define _MBG_API_ATTR
+ typedef int MBG_HANDLE;
+ typedef int MBG_PORT_HANDLE;
+
+ #define MBG_INVALID_HANDLE -1
#endif
+#if !defined( _MBG_API )
+ #define _MBG_API
+#endif
-#if defined( MBG_TGT_WIN32 )
+#if !defined( _MBG_API_ATTR )
+ #define _MBG_API_ATTR
+#endif
- #include <windows.h>
+#if !defined( MBG_INVALID_PORT_HANDLE )
+ #define MBG_INVALID_PORT_HANDLE MBG_INVALID_HANDLE
+#endif
- typedef HANDLE MBG_HANDLE;
+#if !defined( MBG_USE_MM_IO_FOR_PCI )
+ #if ( 0 || defined( MBG_ARCH_SPARC ) )
+ #define MBG_USE_MM_IO_FOR_PCI 1
+ #else
+ #define MBG_USE_MM_IO_FOR_PCI 0
+ #endif
+#endif
- #define MBG_INVALID_HANDLE INVALID_HANDLE_VALUE
-#elif defined( MBG_TGT_UNIX )
+#if !defined( _nop_macro_fnc )
+ #define _nop_macro_fnc() do {} while (0)
+#endif
- typedef int MBG_HANDLE;
- #define MBG_INVALID_HANDLE -1
+// The macros below are defined in order to be able to check if
+// certain C language extensions are available on the target system:
+#define MBG_TGT_C94 ( defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199409L ) )
+#define MBG_TGT_C99 ( defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) )
+// Check if wchar_t is supported
+#if !defined( MBG_TGT_HAS_WCHAR_T )
+ #define MBG_TGT_HAS_WCHAR_T ( MBG_TGT_C94 || defined( WCHAR_MAX ) )
#endif
+#if !MBG_TGT_HAS_WCHAR_T
+ // Even if wchar_t is not natively supported by the target platform
+ // there may already be a compatibility define (e.g. BC3.1)
+ // However, some functions may be missing (e.g. snwprintf()).
+ #if !defined( _WCHAR_T ) /* BC3.1 */ \
+ && !defined( _WCHAR_T_DEFINED_ ) /* WC11 */
+ //##++ #define _WCHAR_T
+ #define wchar_t char
+ #endif
+#endif
+
+
/* End of header body */
diff --git a/mbglib/common/mbg_tmo.c b/mbglib/common/mbg_tmo.c
new file mode 100644
index 0000000..cec9943
--- /dev/null
+++ b/mbglib/common/mbg_tmo.c
@@ -0,0 +1,64 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_tmo.c 1.2 2009/09/01 10:36:45 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:45 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..daf4a25
--- /dev/null
+++ b/mbglib/common/mbg_tmo.h
@@ -0,0 +1,312 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_tmo.h 1.2 2009/09/01 10:38:21 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Inline functions for portable timeout handling.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_tmo.h $
+ * Revision 1.2 2009/09/01 10:38:21 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 <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 > 1000000UL )
+ {
+ t_tmo->tv_usec -= 1000000UL;
+ 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 ) || defined( MBG_TGT_WIN32 )
+
+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 214266b..088066b 100644
--- a/mbglib/common/mbgextio.c
+++ b/mbglib/common/mbgextio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgextio.c 1.2 2006/10/25 12:18:31 martin REL_M $
+ * $Id: mbgextio.c 1.9 2009/10/02 14:19:05 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,6 +11,41 @@
*
* -----------------------------------------------------------------------
* $Log: mbgextio.c $
+ * 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.
+ * Revision 1.7 2009/09/01 10:44:58 martin
+ * Cleanup for CVI.
+ * Use new portable timeout functions from mbg_tmo.h.
+ * Timeouts are now specified in milliseconds.
+ * Distinguish between character timeout and message timeout.
+ * Only fetch one character at a time to prevent received characters
+ * from being discarded after the end of one message.
+ * Revision 1.6 2009/03/10 17:02:08Z martin
+ * Added support for configurable time scales.
+ * Added mbgextio_get_time() call.
+ * Fixed some compiler warnings.
+ * Revision 1.5 2008/09/04 14:35:50Z martin
+ * Fixed opening COM port under CVI.
+ * Moved generic serial I/O stuff to mbgserio.c and mbgserio.h.
+ * Restart reception if received msg does not match expected cmd code.
+ * Fixed timeout value for Windows.
+ * New symbol _MBGEXTIO_DIRECT_RC controls whether the return code of the
+ * mbgextio_set_...() functions is evaluated or returned as-is.
+ * New functions mbgextio_set_time(), mbgextio_set_tzdl().
+ * Added mbgextio_get_ucap(). This may not work with older firmware,
+ * see the comments in mbgextio_get_ucap().
+ * Conditionally support checking of time strings.
+ * Revision 1.4 2007/02/27 10:35:19Z martin
+ * Added mutex for transmit buffer to make transmission thread-safe.
+ * Fixed timeout handling for serial reception.
+ * Renamed mbgextio_get_data() to mbgextio_rcv_msg().
+ * Added some new functions.
+ * Temp. changes for parameter setting functions.
+ * Added comments on POSIX flags used when opening serial port.
+ * Revision 1.3 2006/12/21 10:56:17 martin
+ * Added function mbgextio_set_port_parm.
* Revision 1.2 2006/10/25 12:18:31 martin
* Support serial I/O under Windows.
* Revision 1.1 2006/08/24 12:40:37Z martin
@@ -19,9 +54,15 @@
**************************************************************************/
#define _MBGEXTIO
- #include <mbgextio.h>
+ #include <mbgextio.h>
+
+ //##++ The following lines are required
+ // until mbgextio becomes a DLL:
+ #undef _MBG_API_ATTR
+ #define _MBG_API_ATTR
#undef _MBGEXTIO
+#include <mbgserio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,75 +71,27 @@
#if defined( MBG_TGT_UNIX )
#include <unistd.h>
#include <fcntl.h>
- #include <sys/time.h>
+#else
+ typedef int ssize_t;
#endif
-#if _USE_SERIAL_IO
- #include <ctype.h>
+#if !defined( MBGEXTIO_DIRECT_RC )
+ #define _MBGEXTIO_DIRECT_RC 0 //##++ 1
#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" {
+// default serial message timeout
+#if !defined ( MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL )
+ #define MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL 3000 // [ms]
#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
-}
+// default serial single character timeout
+#if !defined ( MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL )
+ #define MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL 200 // [ms]
#endif
-#endif // defined( _USE_V24TOOLS )
-
-/*------------------------------------------------------------------------*/
-
-
-#if defined MBG_TGT_WIN32
+#if defined( MBG_TGT_WIN32 ) && _USE_SOCKET_IO
static /*HDR*/
BOOL WINAPI mbgextio_on_console_event( DWORD dwCtrlType )
@@ -124,7 +117,7 @@ void mbgextio_set_console_control_handler( void )
{
static int has_been_set;
- if ( !has_been_set )
+ if ( !has_been_set )
{
SetConsoleCtrlHandler( mbgextio_on_console_event, TRUE );
has_been_set = 1;
@@ -157,9 +150,9 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host )
// so try to initialize now.
WORD wVersionRequested;
WSADATA wsaData;
-
+
wVersionRequested = MAKEWORD( 2, 2 );
-
+
rc = WSAStartup( wVersionRequested, &wsaData );
// If initialization has succeeded, try again.
@@ -210,7 +203,9 @@ int comm_init( MBG_MSG_CTL *pmctl, const char *passwd )
strncpy( pss->password, passwd, sizeof( pss->password ) );
pmctl->conn_type = MBG_CONN_TYPE_SOCKET;
- pmctl->timeout = MBGEXTIO_TIMEOUT_SOCKET;
+ pmctl->msg_rcv_timeout = MBGEXTIO_RCV_TIMEOUT_SOCKET;
+ // pmctl->char_rcv_timeout is not used with sockets
+
set_encryption_mode( pmctl, MBG_XFER_MODE_ENCRYTED, pss->password );
pmb = pmctl->xmt.pmb;
@@ -219,7 +214,7 @@ int comm_init( MBG_MSG_CTL *pmctl, const char *passwd )
pmb->hdr.len = sizeof( pmb->u.msg_data.secu_settings );
xmt_tbuff( pmctl );
- rc = mbgextio_get_data( pmctl, GPS_SECU_SETTINGS );
+ rc = mbgextio_rcv_msg( pmctl, GPS_SECU_SETTINGS );
if ( rc != TR_COMPLETE )
return -1; /* connection refused */
@@ -245,11 +240,15 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
return rc;
comm_init( pmctl, passwd );
-
- #if defined MBG_TGT_WIN32
+
+ #if defined( MBG_TGT_WIN32 )
mbgextio_set_console_control_handler();
#endif
+ #if _USE_MUTEX
+ _mbg_mutex_init( pmctl->xmt.xmt_mutex );
+ #endif
+
return rc;
} // mbgextio_open_socket
@@ -264,347 +263,237 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
_MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char *dev,
uint32_t baud_rate, const char *framing )
{
- MBG_HANDLE port_handle;
- const char *cp;
+ int rc;
pmctl->conn_type = MBG_CONN_TYPE_SERIAL;
- pmctl->timeout = MBGEXTIO_TIMEOUT_SERIAL;
-
- #if defined( MBG_TGT_DOS )
- #if defined( _USE_V24TOOLS )
- {
- int datab = 8;
- char parity = 'N';
- int stopb = 1;
+ pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL;
+ pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL;
- port_handle = v24open( (char *) dev, OPEN_MODE );
+ rc = mbgserio_open( &pmctl->st.serio, dev );
- if ( port_handle < 0 )
- return -1;
+ if ( rc < 0 ) //##++
+ return rc;
- pmctl->st.serio.port_handle = port_handle;
+ mbgserio_set_parms( &pmctl->st.serio, baud_rate, framing );
- // setup framing.
- for ( cp = framing; *cp; cp++ )
- {
- char c = toupper( *cp );
+ #if _USE_MUTEX
+ _mbg_mutex_init( pmctl->xmt.xmt_mutex );
+ #endif
- 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 -1; // invalid framing string
- }
- }
+ return 0;
- v24setparams( port_handle, baud_rate, datab, parity, stopb );
+} // mbgextio_open_serial
- return port_handle;
- }
- #else
+#endif
- #error This has to be rewritten for DOS without v24tools.
- #endif
- #elif defined( MBG_TGT_WIN32 )
+/*HDR*/
+_MBG_API_ATTR void _MBG_API mbgextio_close_connection( MBG_MSG_CTL *pmctl )
+{
+ switch ( pmctl->conn_type )
{
- DCB dcb;
- COMMTIMEOUTS commtimeouts;
-
- port_handle = CreateFile( dev, GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
- NULL );
-
- if ( port_handle == INVALID_HANDLE_VALUE )
- return -1;
-
-
- pmctl->st.serio.port_handle = port_handle;
-
- // initialize comport buffer
- 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 )
+ #if _USE_SERIAL_IO
+ case MBG_CONN_TYPE_SERIAL:
{
- 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;
+ #if defined( MBG_TGT_UNIX )
+ tcsetattr( pmctl->st.serio.port_handle, TCSANOW, &pmctl->st.serio.oldtio );
+ #endif
- case '2':
- dcb.StopBits = TWOSTOPBITS;
- break;
+ mbgserio_close( &pmctl->st.serio );
+ } break;
+ #endif // _USE_SERIAL_IO
- default:
- return -1; // invalid framing string
- }
- }
+ #if _USE_SOCKET_IO
+ case MBG_CONN_TYPE_SOCKET:
+ {
+ _mbg_close( pmctl->st.sockio.sockfd );
+ pmctl->st.sockio.sockfd = 0;
+ } break;
+ #endif // _USE_SOCKET_IO
+ }; // switch
- 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;
+ #if _USE_MUTEX
+ _mbg_mutex_destroy( pmctl->xmt.xmt_mutex );
+ #endif
- SetCommState ( port_handle, &dcb );
+} // mbgextio_close_connection
- 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 );
+#if _USE_SERIAL_IO
- mbgextio_set_console_control_handler();
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_force_connection( const char *dev )
+{
+ static const char *cmd_str = "\nDFC\n"; //##++
- return 0;
- }
- #elif defined( MBG_TGT_UNIX )
+ MBG_MSG_CTL mctl =
{
- tcflag_t c_cflag;
+ { NULL, 0 },
+ { NULL, 0 }
+ };
- // open as not controlling TTY to prevent from being
- // killed if CTRL-C is received
- port_handle = _mbg_open( dev, O_RDWR | O_NOCTTY );
+ int i;
+ int j;
+ int len = strlen( cmd_str );
- if ( port_handle < 0 )
- return -1;
+ for ( i = 0; i < N_MBG_BAUD_RATES; i++ )
+ {
+ for ( j = 0; j < N_MBG_FRAMINGS; j++ )
+ {
+ uint32_t baud_rate = mbg_baud_rates[i];
+ const char *framing = mbg_framing_strs[j];
+ int rc = mbgextio_open_serial( &mctl, dev, baud_rate, framing );
- pmctl->st.serio.port_handle = port_handle;
+ if ( rc != 0 ) // failed to open port
+ return -1;
- /* save current device settings */
- tcgetattr( port_handle, &pmctl->st.serio.oldtio );
+ _mbgserio_write( mctl.st.serio.port_handle, cmd_str, len );
- // atexit( port_deinit );
+ #if defined( MBG_TGT_UNIX )
+ tcdrain( mctl.st.serio.port_handle );
+ #elif defined( MBG_TGT_CVI )
+ //##++++
+ #elif defined( MBG_TGT_WIN32 )
+ FlushFileBuffers( mctl.st.serio.port_handle );
+ #endif
- // 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 -1; // invalid
+ mbgextio_close_connection( &mctl );
}
+ }
+ return 0;
- // setup framing.
- for ( cp = framing; *cp; cp++ )
- {
- switch ( _toupper( *cp ) )
- {
- case '7': c_cflag |= CS7; break;
- case '8': c_cflag |= CS8; break;
+} // mbgextio_force_connection
- case 'N': break;
- case 'E': c_cflag |= PARENB; break;
- case 'O': c_cflag |= PARENB | PARODD; break;
+#endif // _USE_SERIAL_IO
- case '1': break;
- case '2': c_cflag |= CSTOPB; break;
- default: return -1; // invalid framing string
- }
- }
- // setup termios control flags:
- // local connection, no modem control (CLOCAL)
- // no flow control (no CRTSCTS)
- // enable receiving
- pmctl->st.serio.newtio.c_cflag = c_cflag | CLOCAL | CREAD;
+/*HDR*/
+_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+{
+ pmctl->char_rcv_timeout = new_timeout;
+} // mbgextio_set_char_rcv_timeout
- // setup input flags:
- // make terminal raw and dumb (no ICRNL)
- // if parity is enabled, ignore bytes with parity errors (IGNPAR)
- pmctl->st.serio.newtio.c_iflag = 0;
- if ( c_cflag & PARENB )
- pmctl->st.serio.newtio.c_iflag |= IGNPAR;
+/*HDR*/
+_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl )
+{
+ return pmctl->char_rcv_timeout;
- // setup output flags:
- // raw output (no flags)
- pmctl->st.serio.newtio.c_oflag = 0;
+} // mbgextio_get_char_rcv_timeout
- // setup local mode flags:
- // don't echo characters
- // don't generate signals to the calling program
- pmctl->st.serio.newtio.c_lflag = 0;
+/*HDR*/
+_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+{
+ pmctl->msg_rcv_timeout = new_timeout;
- // setup control characters:
- // blocking read until 1 char arrives
- pmctl->st.serio.newtio.c_cc[VMIN] = 0;
- pmctl->st.serio.newtio.c_cc[VTIME] = 0;
+} // mbgextio_set_msg_rcv_timeout
- // now clean the modem line and activate the settings for modem
- tcflush( port_handle, TCIFLUSH );
- tcsetattr( port_handle, TCSANOW, &pmctl->st.serio.newtio );
- fflush( stdout );
- setvbuf( stdout, NULL, _IONBF, 0 );
- #if 0
- tcgetattr( STDOUT_FILENO, &oldstdtio );
- newstdtio = oldstdtio;
- printf( "\nTermio Structure:\n" );
- printf( "c_iflag = %X\n", newstdtio.c_iflag );
- printf( "c_oflag = %X\n", newstdtio.c_oflag );
- printf( "c_cflag = %X\n", newstdtio.c_cflag );
- printf( "c_lflag = %X\n", newstdtio.c_lflag );
+/*HDR*/
+_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl )
+{
+ return pmctl->msg_rcv_timeout;
- //for (i = 0;i < NCCS;i++)
- // printf("c_cc[%d] = %X\n", i, newstdtio.c_cc[i]);
+} // mbgextio_get_msg_rcv_timeout
- newstdtio.c_lflag &= ~ICANON;
- tcsetattr( STDOUT_FILENO, TCSANOW, &newstdtio );
- #endif
- return 0;
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
+ const void *p, int n_bytes )
+{
+ MBG_MSG_BUFF *pmb;
- }
- #else
+ if ( n_bytes > sizeof( pmb->u.msg_data ) )
+ return -1; // bytes to send exceed buffer size
- #error This target OS is not supported.
+ #if _USE_MUTEX
+ _mbg_mutex_lock( pmctl->xmt.xmt_mutex );
#endif
-} // mbgextio_open_serial
+ pmb = pmctl->xmt.pmb;
-#endif
+ if ( p && n_bytes )
+ memcpy( pmb->u.bytes, p, n_bytes );
+ pmb->hdr.len = n_bytes;
+ pmb->hdr.cmd = cmd;
+ xmt_tbuff( pmctl );
+ #if _USE_MUTEX
+ _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ #endif
-/*HDR*/
-_MBG_API_ATTR void _MBG_API mbgextio_close_connection( MBG_MSG_CTL *pmctl )
-{
- switch ( pmctl->conn_type )
+ if ( cmd & GPS_REQACK )
{
- #if _USE_SERIAL_IO
- case MBG_CONN_TYPE_SERIAL:
- {
- #if defined( MBG_TGT_UNIX )
- tcsetattr( pmctl->st.serio.port_handle, TCSANOW, &pmctl->st.serio.oldtio );
- #endif
+ int rc = mbgextio_rcv_msg( pmctl, (GPS_CMD) ( cmd & ~GPS_CTRL_MSK ) );
- _mbgserio_close( pmctl->st.serio.port_handle );
+ if ( rc != TR_COMPLETE )
+ return -2;
- pmctl->st.serio.port_handle = 0;
- } break;
- #endif // _USE_SERIAL_IO
-
- #if _USE_SOCKET_IO
- case MBG_CONN_TYPE_SOCKET:
- {
- _mbg_close( pmctl->st.sockio.sockfd );
- pmctl->st.sockio.sockfd = 0;
- } break;
- #endif // _USE_SOCKET_IO
-
- }; // switch
-
-} // mbgextio_close_connection
+ if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK )
+ return -3;
+ if ( !pmctl->rcv.pmb->hdr.cmd & GPS_ACK )
+ return -4;
+ }
-/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
-{
- return xmt_cmd( pmctl, cmd );
+ return 0;
-} // mbgextio_xmt_cmd
+} // mbgextio_xmt_msg
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
+_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
{
MBG_MSG_RCV_CTL *prctl;
MBG_MSG_BUFF *pmb;
+ MBG_TMO_TIME msg_timeout;
char buff[MBGEXTIO_READ_BUFFER_SIZE];
- int n_bytes;
+ ssize_t n_bytes;
int rc;
int i;
+ mbg_tmo_set_timeout_ms( &msg_timeout, pmctl->msg_rcv_timeout );
+
for (;;) // loop until complete msg received
{
n_bytes = 0;
+ if ( mbg_tmo_curr_time_is_after( &msg_timeout ) )
+ return TR_TIMEOUT;
+
#if _USE_SOCKET_IO
if ( pmctl->conn_type == MBG_CONN_TYPE_SOCKET )
{
- struct timeval tv;
+ struct timeval tv_timeout;
fd_set fds;
if ( pmctl->io_error )
return TR_IO_ERR;
- // set timeout value
- tv.tv_sec = 1;
- tv.tv_usec = 0;
+ mbgserio_msec_to_timeval( pmctl->msg_rcv_timeout, &tv_timeout );
FD_ZERO( &fds );
FD_SET( pmctl->st.sockio.sockfd, &fds );
- rc = select( pmctl->st.sockio.sockfd + 1, &fds, NULL, NULL, &tv );
+ rc = select( pmctl->st.sockio.sockfd + 1, &fds, NULL, NULL, &tv_timeout );
+
+ if ( rc == 0 ) // timeout
+ return TR_TIMEOUT;
if ( rc < 0 ) // error
{
@@ -612,15 +501,11 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
return TR_IO_ERR;
}
- if ( rc == 0 ) // timeout
- return TR_TIMEOUT;
-
-
// data is available
n_bytes = recv( pmctl->st.sockio.sockfd, buff, sizeof( buff ), 0 );
- if ( n_bytes < 0 )
+ if ( n_bytes < 0 )
{
pmctl->io_error = 1;
return TR_IO_ERR;
@@ -631,22 +516,16 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
#if _USE_SERIAL_IO
if ( pmctl->conn_type == MBG_CONN_TYPE_SERIAL )
{
- clock_t clk_now;
- clock_t clk_start = clock();
- clock_t clk_timeout = clk_start + pmctl->timeout * CLOCKS_PER_SEC;
+ n_bytes = mbgserio_read_wait( pmctl->st.serio.port_handle, &buff[0],
+ sizeof( buff[0] ), pmctl->char_rcv_timeout );
- for (;;) // wait to read one new char
+ if ( n_bytes < 0 )
{
- n_bytes = _mbgserio_read( pmctl->st.serio.port_handle,
- &buff[0], sizeof( buff[0] ) );
-
- if ( n_bytes > 0 )
- break; // new char has been received
-
- clk_now = clock();
+ if ( n_bytes == MBGSERIO_TIMEOUT )
+ return TR_TIMEOUT;
- if ( clk_now > clk_timeout ) // error: timeout
- return TR_TIMEOUT;
+ pmctl->io_error = 1;
+ return TR_IO_ERR;
}
}
#endif // _USE_SERIAL_IO
@@ -656,14 +535,22 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
for ( i = 0; i < n_bytes; i++ )
{
+ char c = buff[i];
+
/* check if the new char belongs to a data transfer sequence */
- rc = check_transfer( prctl, buff[i] );
+ rc = check_transfer( prctl, c );
switch ( rc )
{
case TR_WAITING: /* no data transfer sequence in progress */
- case TR_RECEIVING: /* data transfer sequence in progress */
- continue; /* keep waiting */
+ #if _USE_CHK_TSTR
+ if ( prctl->chk_tstr_fnc ) /* optionally handle normal, non-protocol data */
+ prctl->chk_tstr_fnc( c, prctl->chk_tstr_arg );
+ #endif
+ // intentional fall-through
+
+ case TR_RECEIVING: /* data transfer sequence in progress, keep waiting */
+ continue;
case TR_COMPLETE:
{
@@ -691,6 +578,9 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
/* not waiting for a specific packet, so return if any packet is complete */
if ( cmd == (uint16_t) -1 )
return TR_COMPLETE;
+
+ //##++ received a msg which does not match the expected code
+ prctl->cnt = 0; /* restart receiving */
}
break;
@@ -701,7 +591,49 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
}
}
-} // mbgextio_get_data
+} // mbgextio_rcv_msg
+
+
+
+/*HDR*/
+_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 );
+ #endif
+
+ rc = xmt_cmd( pmctl, cmd );
+
+ #if _USE_MUTEX
+ _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ #endif
+
+ return rc;
+
+} // mbgextio_xmt_cmd
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us )
+{
+ int rc;
+
+ #if _USE_MUTEX
+ _mbg_mutex_lock( pmctl->xmt.xmt_mutex );
+ #endif
+
+ rc = xmt_cmd_us( pmctl, cmd, us );
+
+ #if _USE_MUTEX
+ _mbg_mutex_unlock( pmctl->xmt.xmt_mutex );
+ #endif
+
+ return rc;
+
+} // mbgextio_xmt_cmd_us
@@ -710,13 +642,24 @@ _MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
{
xmt_cmd( pmctl, cmd ); /* request a set of data */
- return mbgextio_get_data( pmctl, cmd );
+ return mbgextio_rcv_msg( pmctl, cmd );
} // mbgextio_req_data
/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t idx )
+{
+ xmt_cmd_us( pmctl, cmd, idx ); /* request a set of data */
+
+ return mbgextio_rcv_msg( pmctl, cmd );
+
+} // mbgextio_req_data_idx
+
+
+
+/*HDR*/
_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
{
int rc = mbgextio_req_data( pmctl, GPS_RECEIVER_INFO );
@@ -759,6 +702,51 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, BVAR_STAT
/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, TTM *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_TIME );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.ttm;
+
+ return rc;
+
+} // mbgextio_get_time
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl, const TTM *p )
+{
+ GPS_CMD cmd = GPS_TIME;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_time
+
+
+
+/*HDR*/
_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, LLA lla )
{
int rc = mbgextio_req_data( pmctl, GPS_POS_LLA );
@@ -784,6 +772,37 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, LLA lla )
/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl, const LLA lla )
+{
+ GPS_CMD cmd = GPS_POS_LLA;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) lla, sizeof( LLA ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) lla, sizeof( LLA ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_pos_lla
+
+
+
+/*HDR*/
_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, TZDL *p )
{
int rc = mbgextio_req_data( pmctl, GPS_TZDL );
@@ -798,6 +817,89 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, TZDL *p )
/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, const TZDL *p )
+{
+ GPS_CMD cmd = GPS_TZDL;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_get_tzdl
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_PORT_PARM );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.port_parm;
+
+ return rc;
+
+} // mbgextio_get_port_parm
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, const PORT_PARM *p )
+{
+ GPS_CMD cmd = GPS_PORT_PARM;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+
+ MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
+ int rc;
+
+ pmb->u.msg_data.port_parm = *p;
+
+ pmb->hdr.len = sizeof( pmb->u.msg_data.port_parm );
+ pmb->hdr.cmd = cmd | GPS_REQACK;
+ xmt_tbuff( pmctl );
+
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_port_parm
+
+
+
+/*HDR*/
_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, SYNTH *p )
{
int rc = mbgextio_req_data( pmctl, GPS_SYNTH );
@@ -814,17 +916,17 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, SYNTH *p )
/*HDR*/
_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, const SYNTH *p )
{
- MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
GPS_CMD cmd = GPS_SYNTH;
- int rc;
- pmb->u.msg_data.synth = *p;
+#if _MBGEXTIO_DIRECT_RC
- pmb->hdr.len = sizeof( pmb->u.msg_data.synth );
- pmb->hdr.cmd = cmd | GPS_REQACK;
- xmt_tbuff( pmctl );
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
- rc = mbgextio_get_data( pmctl, cmd );
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
{
@@ -833,24 +935,430 @@ _MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, const SYNTH *
// transmitted before, an automatic frame (current time, capture)
// has been sent before the acknowledge code.
}
-
+
return 0;
+#endif
+
} // mbgextio_set_synth
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p )
+_MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, ANT_INFO *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_PORT_PARM );
+ int rc = mbgextio_req_data( pmctl, GPS_ANT_INFO );
if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.port_parm;
+ *p = pmctl->rcv.pmb->u.msg_data.ant_info;
return rc;
-} // mbgextio_get_port_parm
+} // mbgextio_get_ant_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
+{
+ int rc;
+
+ xmt_cmd( pmctl, GPS_UCAP ); /* request a set of data */
+
+ // 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 );
+
+ if ( ( rc == TR_COMPLETE ) && 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
+ // the GPS time structure.
+ 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
+ }
+
+ return rc;
+
+} // mbgextio_get_ucap
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, ENABLE_FLAGS *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_ENABLE_FLAGS );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.enable_flags;
+
+ return rc;
+
+} // mbgextio_get_enable_flags
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, const ENABLE_FLAGS *p )
+{
+ GPS_CMD cmd = GPS_ENABLE_FLAGS;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_enable_flags
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, STAT_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_STAT_INFO );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.stat_info;
+
+ return rc;
+
+} // mbgextio_get_stat_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, ANT_CABLE_LEN *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_ANT_CABLE_LENGTH );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.ant_cable_len;
+
+ return rc;
+
+} // mbgextio_get_ant_cable_len
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, const ANT_CABLE_LEN *p )
+{
+ GPS_CMD cmd = GPS_ANT_CABLE_LENGTH;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_ant_cable_len
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_IRIG_TX_INFO );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.irig_tx_info;
+
+ return rc;
+
+} // mbgextio_get_irig_tx_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_IRIG_TX_SETTINGS;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_irig_tx_settings
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_IRIG_RX_INFO );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.irig_rx_info;
+
+ return rc;
+
+} // mbgextio_get_irig_rx_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_IRIG_RX_SETTINGS;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_irig_rx_settings
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl, MBG_REF_OFFS *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_REF_OFFS );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.ref_offs;
+
+ return rc;
+
+} // mbgextio_get_ref_offs
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, const MBG_REF_OFFS *p )
+{
+ GPS_CMD cmd = GPS_REF_OFFS;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_ref_offs
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, MBG_DEBUG_STATUS *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_DEBUG_STATUS );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.debug_status;
+
+ return rc;
+
+} // mbgextio_get_debug_status
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl, MBG_OPT_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, GPS_OPT_INFO );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.opt_info;
+
+ return rc;
+
+} // mbgextio_get_opt_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, const MBG_OPT_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_OPT_SETTINGS;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+ int rc;
+
+ rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_opt_settings
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl,
+ STR_TYPE_INFO_IDX *p, uint16_t idx )
+{
+ int rc;
+
+ xmt_cmd_us( pmctl, GPS_STR_TYPE_INFO_IDX, idx );
+
+ rc = mbgextio_rcv_msg( pmctl, GPS_STR_TYPE_INFO_IDX );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.str_type_info_idx;
+
+ return rc;
+
+} // mbgextio_get_str_type_info_idx
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl,
+ PORT_INFO_IDX *p, uint16_t idx )
+{
+ int rc;
+
+ xmt_cmd_us( pmctl, GPS_PORT_INFO_IDX, idx );
+
+ rc = mbgextio_rcv_msg( pmctl, GPS_PORT_INFO_IDX );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.port_info_idx;
+
+ return rc;
+
+} // mbgextio_get_port_info_idx
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl,
+ const PORT_SETTINGS *p, uint16_t idx )
+{
+ GPS_CMD cmd = GPS_PORT_SETTINGS_IDX;
+ MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
+ int rc;
+
+ pmb->u.msg_data.port_settings_idx.port_settings = *p;
+ pmb->u.msg_data.port_settings_idx.idx = idx;
+
+ pmb->hdr.len = sizeof( pmb->u.msg_data.port_settings_idx );
+ pmb->hdr.cmd = cmd | GPS_REQACK;
+ rc = xmt_tbuff( pmctl );
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return rc;
+
+#else
+
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_port_settings_idx
@@ -862,7 +1370,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl,
xmt_cmd_us( pmctl, GPS_POUT_INFO_IDX, idx );
- rc = mbgextio_get_data( pmctl, GPS_POUT_INFO_IDX );
+ rc = mbgextio_rcv_msg( pmctl, GPS_POUT_INFO_IDX );
if ( ( rc == TR_COMPLETE ) && p )
*p = pmctl->rcv.pmb->u.msg_data.pout_info_idx;
@@ -877,8 +1385,8 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl,
_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl,
const POUT_SETTINGS *p, uint16_t idx )
{
- MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
GPS_CMD cmd = GPS_POUT_SETTINGS_IDX;
+ MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
int rc;
pmb->u.msg_data.pout_settings_idx.pout_settings = *p;
@@ -886,9 +1394,15 @@ _MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl,
pmb->hdr.len = sizeof( pmb->u.msg_data.pout_settings_idx );
pmb->hdr.cmd = cmd | GPS_REQACK;
- xmt_tbuff( pmctl );
+ rc = xmt_tbuff( pmctl );
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return rc;
- rc = mbgextio_get_data( pmctl, cmd );
+#else
+
+ rc = mbgextio_rcv_msg( pmctl, cmd );
if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
{
@@ -897,9 +1411,78 @@ _MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl,
// transmitted before, an automatic frame (current time, capture)
// has been sent before the acknowledge code.
}
-
+
return 0;
+#endif
+
} // mbgextio_set_pout_settings_idx
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl )
+{
+ return mbgextio_xmt_cmd( pmctl, GPS_CLR_UCAP_BUFF );
+
+} // mbgextio_clr_ucap_buff
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl,
+ MBG_TIME_SCALE_INFO *p )
+{
+ int rc;
+
+ xmt_cmd( pmctl, GPS_TIME_SCALE );
+
+ rc = mbgextio_rcv_msg( pmctl, GPS_TIME_SCALE );
+
+ if ( ( rc == TR_COMPLETE ) && p )
+ *p = pmctl->rcv.pmb->u.msg_data.time_scale_info;
+
+ return rc;
+
+} // mbgextio_get_time_scale_info
+
+
+
+/*HDR*/
+_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmctl,
+ const MBG_TIME_SCALE_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_TIME_SCALE;
+
+#if _MBGEXTIO_DIRECT_RC
+
+ return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+
+#else
+
+ MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
+ int rc;
+
+ pmb->u.msg_data.time_scale_settings = *p;
+
+ pmb->hdr.len = sizeof( pmb->u.msg_data.time_scale_settings );
+ pmb->hdr.cmd = cmd | GPS_REQACK;
+ xmt_tbuff( pmctl );
+
+ rc = mbgextio_rcv_msg( pmctl, cmd );
+
+ if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ {
+ return -1; // no ack packet received
+ // data has not been set or, if GPS_AUTO_ON has been
+ // transmitted before, an automatic frame (current time, capture)
+ // has been sent before the acknowledge code.
+ }
+
+ return 0;
+
+#endif
+
+} // mbgextio_set_time_scale_settings
+
+
diff --git a/mbglib/common/mbgextio.h b/mbglib/common/mbgextio.h
index 98262e7..dca0454 100644
--- a/mbglib/common/mbgextio.h
+++ b/mbglib/common/mbgextio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgextio.h 1.1 2006/08/24 12:40:37 martin REL_M $
+ * $Id: mbgextio.h 1.7 2009/10/02 14:21:08 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,21 @@
*
* -----------------------------------------------------------------------
* $Log: mbgextio.h $
+ * 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.
+ * Revision 1.5 2009/03/10 17:03:09Z martin
+ * Updated function prototypes.
+ * Revision 1.4 2008/09/04 14:13:19Z martin
+ * Added macro _mbgextio_xmt_msg().
+ * Updated function prototypes.
+ * Removed obsolete code.
+ * Revision 1.3 2007/02/27 10:30:06Z martin
+ * Added some global variables.
+ * Updated function prototypes.
+ * Revision 1.2 2006/12/21 10:56:35 martin
+ * Updated function prototypes.
* Revision 1.1 2006/08/24 12:40:37 martin
* Initial revision.
*
@@ -24,11 +39,6 @@
#include <gpsserio.h>
#include <time.h>
-#if defined( MBG_TGT_WIN32 )
- #include <windows.h>
-#endif
-
-
#ifdef _MBGEXTIO
#define _ext
#define _DO_INIT
@@ -60,6 +70,25 @@
#endif
+_ext uint32_t mbg_baud_rates[N_MBG_BAUD_RATES]
+#ifdef _DO_INIT
+ = MBG_BAUD_RATES
+#endif
+;
+
+_ext const char *mbg_baud_rate_strs[N_MBG_BAUD_RATES]
+#ifdef _DO_INIT
+ = MBG_BAUD_STRS
+#endif
+;
+
+_ext const char *mbg_framing_strs[N_MBG_FRAMINGS]
+#ifdef _DO_INIT
+ = MBG_FRAMING_STRS
+#endif
+;
+
+
/* function prototypes: */
@@ -75,19 +104,54 @@ extern "C" {
_MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl, const char *host, const char *passwd ) ;
_MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char *dev, uint32_t baud_rate, const char *framing ) ;
_MBG_API_ATTR void _MBG_API mbgextio_close_connection( MBG_MSG_CTL *pmctl ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_force_connection( const char *dev ) ;
+ _MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ;
+ _MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl ) ;
+ _MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ;
+ _MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd, const void *p, int n_bytes ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd ) ;
_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd ) ;
- _MBG_API_ATTR int _MBG_API mbgextio_get_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us ) ;
_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t idx ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, SW_REV *p ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, BVAR_STAT *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, TTM *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl, const TTM *p ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, LLA lla ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl, const LLA lla ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, TZDL *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, const TZDL *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, const PORT_PARM *p ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, SYNTH *p ) ;
_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, const SYNTH *p ) ;
- _MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, ANT_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, ENABLE_FLAGS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, const ENABLE_FLAGS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, STAT_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, ANT_CABLE_LEN *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, const ANT_CABLE_LEN *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl, MBG_REF_OFFS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, const MBG_REF_OFFS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, MBG_DEBUG_STATUS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl, MBG_OPT_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, const MBG_OPT_SETTINGS *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl, STR_TYPE_INFO_IDX *p, uint16_t idx ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl, PORT_INFO_IDX *p, uint16_t idx ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl, const PORT_SETTINGS *p, uint16_t idx ) ;
_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl, POUT_INFO_IDX *p, uint16_t idx ) ;
_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl, const POUT_SETTINGS *p, uint16_t idx ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl, MBG_TIME_SCALE_INFO *p ) ;
+ _MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmctl, const MBG_TIME_SCALE_SETTINGS *p ) ;
/* ----- function prototypes end ----- */
@@ -95,6 +159,8 @@ extern "C" {
}
#endif
+#define _mbgextio_xmt_msg( _pmctl, _cmd, _s ) \
+ mbgextio_xmt_msg( _pmctl, _cmd, _s, sizeof( *(_s) ) )
/* End of header body */
diff --git a/mbglib/common/mbggeo.h b/mbglib/common/mbggeo.h
index 27bc698..c375570 100644
--- a/mbglib/common/mbggeo.h
+++ b/mbglib/common/mbggeo.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbggeo.h 1.8 2004/11/09 14:16:00 martin REL_M $
+ * $Id: mbggeo.h 1.10 2008/09/03 14:54:28 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -22,7 +22,12 @@
*
* -----------------------------------------------------------------------
* $Log: mbggeo.h $
- * Revision 1.8 2004/11/09 14:16:00 martin
+ * Revision 1.10 2008/09/03 14:54:28 martin
+ * Added macros to swap endianess of structures.
+ * Revision 1.9 2008/01/17 09:31:33 daniel
+ * Made comments compatible for doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.8 2004/11/09 14:16:00Z martin
* Redefined interface data types using C99 fixed-size definitions.
* Revision 1.7 2003/02/14 13:23:04Z martin
* Omit inclusion of mystd.h.
@@ -62,28 +67,47 @@
#endif
-/* geographic longitude or latitude in [degrees, minutes, seconds] */
-/* longitude East latitude North and positve, South or West angles negative */
-
+/**
+ Geographic longitude or latitude in [degrees, minutes, seconds]
+ longitude East latitude North and positve, South or West angles negative
+ */
typedef struct
{
- uint16_t prefix; /* 'N', 'E', 'S' or 'W' */
- uint16_t deg; /* [0...90 (lat) or 0...180 (lon)] */
- uint16_t min; /* [0...59] */
- double sec; /* [0...59.999] */
+ uint16_t prefix; /**< 'N', 'E', 'S' or 'W' */
+ uint16_t deg; /**< [0...90 (lat) or 0...180 (lon)] */
+ uint16_t min; /**< [0...59] */
+ double sec; /**< [0...59.999] */
} DMS;
+// The corresponding macro _mbg_swab_dms() is defined in gpsdefs.h.
+#define _mbg_swab_dms( _p ) \
+{ \
+ _mbg_swab16( &(_p)->prefix ); \
+ _mbg_swab16( &(_p)->deg ); \
+ _mbg_swab16( &(_p)->min ); \
+ _mbg_swab_double( &(_p)->sec ); \
+}
+
typedef struct
{
- XYZ xyz; /* always WGS84 ECEF coordinates */
- LLA lla; /* depending on the ellipsoid used for reference */
- DMS longitude; /* longitude in degrees, minutes, seconds */
- DMS latitude; /* latitude in degrees, minutes, seconds */
- int16_t ellipsoid; /* ellipsoid used for reference */
+ XYZ xyz; /**< always WGS84 ECEF coordinates */
+ LLA lla; /**< depending on the ellipsoid used for reference */
+ DMS longitude; /**< longitude in degrees, minutes, seconds */
+ DMS latitude; /**< latitude in degrees, minutes, seconds */
+ int16_t ellipsoid; /**< ellipsoid used for reference */
} POS;
+#define _mbg_swab_pos( _p ) \
+{ \
+ _mbg_swab_xyz( (_p)->xyz ); \
+ _mbg_swab_lla( (_p)->lla ); \
+ _mbg_swab_dms( &(_p)->longitude ); \
+ _mbg_swab_dms( &(_p)->latitude ); \
+ _mbg_swab16( &(_p)->ellipsoid ); \
+}
+
typedef struct
diff --git a/mbglib/common/mbgserio.c b/mbglib/common/mbgserio.c
new file mode 100644
index 0000000..23005b7
--- /dev/null
+++ b/mbglib/common/mbgserio.c
@@ -0,0 +1,960 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgserio.c 1.3 2009/09/01 10:49:30 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:30 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..2367e14
--- /dev/null
+++ b/mbglib/common/mbgserio.h
@@ -0,0 +1,213 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgserio.h 1.4 2009/09/01 10:54:29 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:29 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..dde928b
--- /dev/null
+++ b/mbglib/common/pcpsdefs.h
@@ -0,0 +1,1222 @@
+
+/**************************************************************************
+ *
+ * $Id: pcpsdefs.h 1.41 2009/06/19 12:16:42 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * General definitions for Meinberg plug-in radio clocks
+ *
+ * -----------------------------------------------------------------------
+ * $Log: pcpsdefs.h $
+ * Revision 1.41 2009/06/19 12:16:42 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) */
+ 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_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 \
+}
+
+
+#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 } \
+}
+
+
+
+/**
+ 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_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_PTP270PEX ( ( PCPS_REF_PTP << 8 ) | 0x01 )
+
+#define PCI_DEV_FRC511PEX ( ( PCPS_REF_FRC << 8 ) | 0x01 )
+
+/** @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 )
+
+// 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 )
+
+
+#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 */
+ uint8_t status; /**< status codes, see below */
+ char corr_dir; /**< space, '<', or '>' */
+ uint8_t flags; /**< reserved, currently always 0 */
+} CORR_INFO;
+
+/** Codes used with CORR_INFO::status: */
+enum
+{
+ PZF_CORR_RAW,
+ PZF_CORR_CHECK,
+ PZF_CORR_FINE,
+ N_PZF_CORR_STATE
+};
+
+
+/**
+ * The enumeration below defines the various types of data that can be
+ * read from or written to a Meinberg GPS plug-in clock. Access should be
+ * done using the functions pcps_read_gps_data() and pcps_write_gps_data()
+ * in file pcpsio.c because the size of some of the structures exceeds
+ * the size of the clock's on-board FIFO 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/words.h b/mbglib/common/words.h
index 94cfbea..9f6f1a9 100644
--- a/mbglib/common/words.h
+++ b/mbglib/common/words.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: words.h 1.11 2004/11/10 10:45:34 martin REL_M $
+ * $Id: words.h 1.21 2009/10/01 14:00:17 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,31 @@
*
* -----------------------------------------------------------------------
* $Log: words.h $
+ * 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().
+ * Revision 1.19 2009/04/14 14:45:45Z martin
+ * Added BYTE_OF_P() and WORD_OF_P() macros.
+ * Revision 1.18 2009/03/27 14:05:18 martin
+ * Cleanup for CVI.
+ * Revision 1.17 2009/03/13 09:06:03Z martin
+ * Declared bit type for non-firmware environments.
+ * Revision 1.16 2008/12/05 12:05:41Z martin
+ * Define dummy int64_t/uint64_t types for targets
+ * which don't support 64 bit data types.
+ * Revision 1.15 2008/07/14 14:44:00Z martin
+ * Use fixed size C99 types which come with GCC and newer Borland compilers.
+ * Revision 1.14 2008/01/30 10:27:50Z martin
+ * Moved some macro definitions here.
+ * Revision 1.13 2007/03/08 15:00:30Z martin
+ * Fixed incompatibility of macro _IS_MBG_FIRMWARE.
+ * Added a workaround for _IS_MBG_FIRMWARE under CVI.
+ * Support for BSD.
+ * Revision 1.12 2006/12/15 10:45:46 martin
+ * Added macro _IS_MBG_FIRMWARE.
+ * Cleanup for Linux, QNX, and Watcom C.
+ * Include mbg_tgt.h for non-firmware targets.
* Revision 1.11 2004/11/10 10:45:34 martin
* Added C99 fixed-type handling for QNX.
* Revision 1.10 2004/11/09 13:12:56 martin
@@ -41,6 +66,27 @@
/* Other headers to be included */
+
+#if !defined( _IS_MBG_FIRMWARE )
+
+#if defined( _C166 ) || \
+ defined( _CC51 ) || \
+ defined( __ARM )
+ #define _IS_MBG_FIRMWARE 1
+#else
+ #define _IS_MBG_FIRMWARE 0
+#endif
+
+
+#endif
+
+#if !_IS_MBG_FIRMWARE
+ #include <mbg_tgt.h>
+
+ typedef unsigned char bit;
+#endif
+
+
#ifdef _WORDS
#define _ext
#else
@@ -50,37 +96,127 @@
/* Start of header body */
-// Depending on the target environment, configure whether
-// C99 fixed-size types are supported, or not.
-// If they are not defined, they have to be defined using
-// standard data types of appropriate size.
-#if defined( __linux ) // any Linux target
+// Check whether the target system supports C99 fixed-size types.
+
+#if defined( MBG_TGT_LINUX ) // any Linux target
#if defined( __KERNEL__ )
#include <linux/types.h>
- #define _C99_BIT_TYPES_DEFINED 1
#else
+ #include <stdint.h>
#include <sys/types.h>
- #define _C99_PSEUDO_BIT_TYPES_DEFINED 1
#endif
-
-#elif defined( __QNX__ ) // target QNX 4 or QNX 6
- #if defined( __QNXNTO__ ) // target QNX 6 (Neutrino)
+ #define _C99_BIT_TYPES_DEFINED 1
+
+#elif defined( MBG_TGT_BSD )
+
+ #include <sys/types.h>
+
+ #define _C99_BIT_TYPES_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
#include <stdint.h>
- #else // QNX 4.25
- #include <inttypes.h>
+ #else // QNX 4.x with Watcom C 10.6
+ #include <sys/types.h> // 64 bit types not supported
#endif
-
- #define _C99_BIT_TYPES_DEFINED 1
-
+
+ #define _C99_BIT_TYPES_DEFINED 1
+
#endif
+// If it's not yet clear whether fixed-size types are supported,
+// check the build environment which may be multi-platform.
+
+#if !defined( _C99_BIT_TYPES_DEFINED )
+
+ #if defined( __WATCOMC__ )
+ #if __WATCOMC__ > 1230 // Open Watcom C 1.3 and above
+ #include <stdint.h>
+ #define _C99_BIT_TYPES_DEFINED 1
+ #elif defined( __WATCOM_INT64__ ) // Watcom C 11, non-QNX
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
+ #define _C99_BIT_TYPES_DEFINED 1
+ #endif
+ #endif
+
+ #if defined( __BORLANDC__ )
+ #if ( __BORLANDC__ >= 0x570 ) // at least Borland Developer Studio 2006
+ #define _C99_BIT_TYPES_DEFINED 1
+ #endif
+ #endif
+
+ #if defined( __GNUC__ )
+ #include <stdint.h>
+ #define _C99_BIT_TYPES_DEFINED 1
+ #endif
+
+#endif
+
+
+// If neither the target system nor the build environment define C99 fixed-size
+// types define those types based on standard types with the proper sizes
+// commonly used in 16/32 bit environments.
+
+#if defined( _C99_BIT_TYPES_DEFINED )
+
+ #define MBG_TGT_HAS_64BIT_TYPES 1
+
+#else
+
+ typedef char int8_t;
+ typedef unsigned char uint8_t;
+
+ typedef short int16_t;
+ typedef unsigned short uint16_t;
+
+ typedef long int32_t;
+ typedef unsigned long uint32_t;
+
+
+ #if defined( MBG_TGT_WIN32 )
+
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
+ #define MBG_TGT_HAS_64BIT_TYPES 1
+
+ #else
+ // The types below are required to avoid build errors
+ // if these types are formally used in function prototypes.
+ // We explicitely use abnormal data types to hopefully
+ // cause compiler errors in case these types are
+ // unexpectedly used to generate real code for a target
+ // platform which does not support 64 bit types.
+ typedef void *int64_t;
+ typedef void *uint64_t;
+ #endif
+
+#endif
+
+
+
+#if !defined( MBG_TGT_HAS_64BIT_TYPES )
+
+ #define MBG_TGT_HAS_64BIT_TYPES 0
+
+#endif
+
+
+
+// Some commonly used types
+
typedef unsigned char uchar;
-#if !defined( __linux )
+#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.
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
@@ -94,57 +230,43 @@ typedef unsigned long longword;
typedef unsigned long dword;
+#define HI_BYTE( _x ) ( (_x) >> 8 )
+#define LO_BYTE( _x ) ( (_x) & 0xFF )
-#if !defined( _C99_BIT_TYPES_DEFINED )
- #if defined( _C99_PSEUDO_BIT_TYPES_DEFINED )
- // While the C99 standard requires names like uint8_t for unsigned integer
- // types with a fixed number of bits, some implementations define types
- // like u_int8_t instead, but not the required names. This is fixed here.
- // Normally, the signed types have been properly defined in this case.
- typedef u_int8_t uint8_t;
- typedef u_int16_t uint16_t;
- typedef u_int32_t uint32_t;
- typedef u_int64_t uint64_t;
- #else
- // The lines below define some C99 types based on standard types with
- // the proper sizes commonly used in 16/32 bit environments.
- // The 64 bit types have not yet been used.
- typedef char int8_t;
- typedef unsigned char uint8_t;
-
- typedef short int16_t;
- typedef unsigned short uint16_t;
-
- typedef long int32_t;
- typedef unsigned long uint32_t;
-
- #if defined( _WIN32 ) || defined( __WIN32__ )
- typedef __int64 int64_t;
- #endif
-
- #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
- typedef __int64 int64_t;
- #endif
+#define HI_WORD( _x ) ( (_x) >> 16 )
+#define LO_WORD( _x ) ( (_x) & 0xFFFF )
- #endif
-#endif
+// the macros below assume little endianess
+// these macros expect the name of a variable
+#define BYTE_OF( _v, _n ) *( ( (uint8_t *) &(_v) ) + (_n) )
+#define WORD_OF( _v, _n ) *( ( (uint16_t *) &(_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) )
// a macro to swap the byte order of a 16 bit value
-#define _bswap16( _x ) \
-( \
- ( ( ( (ushort) (_x) ) & 0x00FF ) << 8 ) | \
- ( ( ( (ushort) (_x) ) & 0xFF00 ) >> 8 ) \
+#define _bswap16( _x ) \
+( \
+ ( ( ( (uint16_t) (_x) ) & 0x00FF ) << 8 ) | \
+ ( ( ( (uint16_t) (_x) ) & 0xFF00 ) >> 8 ) \
)
// a macro to swap the byte order of a 32 bit value
-#define _bswap32( _x ) \
-( \
- ( ( ( (ulong) (_x) ) & 0x000000FFUL ) << 24 ) | \
- ( ( ( (ulong) (_x) ) & 0x0000FF00UL ) << 8 ) | \
- ( ( ( (ulong) (_x) ) & 0x00FF0000UL ) >> 8 ) | \
- ( ( ( (ulong) (_x) ) & 0xFF000000UL ) >> 24 ) \
+#define _bswap32( _x ) \
+( \
+ ( ( ( (uint32_t) (_x) ) & 0x000000FFUL ) << 24 ) | \
+ ( ( ( (uint32_t) (_x) ) & 0x0000FF00UL ) << 8 ) | \
+ ( ( ( (uint32_t) (_x) ) & 0x00FF0000UL ) >> 8 ) | \
+ ( ( ( (uint32_t) (_x) ) & 0xFF000000UL ) >> 24 ) \
+)
+
+// a macro to swap the word order of a 32 bit value
+#define _wswap32( _x ) \
+( \
+ ( ( ( (uint32_t) (_x) ) & 0x0000FFFFUL ) << 16 ) | \
+ ( ( ( (uint32_t) (_x) ) >> 16 ) & 0x0000FFFFUL ) \
)
#define _var_bswap16( _v ) (_v) = _bswap16( _v )
@@ -157,7 +279,7 @@ typedef unsigned long dword;
// little-endian, so we must use macros to adjust the
// byte order if the C51 is used.
-#if defined _CC51
+#if defined( _CC51 )
#define _hilo_16( _x ) _bswap16( _x )
#define _hilo_32( _x ) _bswap32( _x )
#else
diff --git a/unix/Makefile b/unix/Makefile
index e271567..9ceee12 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -1,7 +1,7 @@
#########################################################################
#
-# $Id: Makefile 1.2 2006/08/22 15:49:27 martin REL_M $
+# $Id: Makefile 1.3 2009/10/01 14:09:19 martin REL_M $
#
# Description:
# Makefile for gpsxmple for Unix-like systems.
@@ -9,6 +9,8 @@
#
# -----------------------------------------------------------------------
# $Log: Makefile $
+# Revision 1.3 2009/10/01 14:09:19 martin
+# Added mbgserio.c source module.
# Revision 1.2 2006/08/22 15:49:27 martin
# Moved this makefile for Unix-like systems to folder unix.
# This build environment now supports Linux and QNX 6.x.
@@ -57,23 +59,26 @@ else
endif
-
SRCS=../$(TARGET).c \
$(MBGLIB_COMMON)/mbgextio.c \
+ $(MBGLIB_COMMON)/mbgserio.c \
$(MBGLIB_COMMON)/gpsserio.c \
$(MBGLIB_COMMON)/gpsutils.c \
$(MBGLIB_COMMON)/aes128.c
-all: $(TARGET)
+.PHONY: all
+all: $(TARGET)
$(TARGET): $(SRCS) $(MAKEFILE_LIST)
$(CC) $(CFLAGS) $(SRCS) -o $@
+.PHONY: clean
clean:
rm -f *.o *~ core
rm -f $(TARGET)
+.PHONY: distclean
distclean: clean