summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2015-07-25 12:01:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2015-07-25 12:01:00 +0200
commit5b8da0b6113840a19166272b2046f1e920e91f51 (patch)
treeea35d7f7403bd867b7033adb7d3d2afce123a78b
parent5dc324e85bcb7c1615e4eec8ae4b66792368cef7 (diff)
downloadgpsxmple-5b8da0b6113840a19166272b2046f1e920e91f51.tar.gz
gpsxmple-5b8da0b6113840a19166272b2046f1e920e91f51.zip
Severe API changes.gpsxmple-2.5-dos-win
All device 'open' functions and the device close function now expect the address of an (MBG_MSG_CTL *). the 'open' functions allocate a structure and set it up, and the close function frees the allocated memory and sets the (MBG_MSG_CTL *) to NULL. The MBG_MSG_CTL structure should be considered opaque, just like a (FILE *). API functions now return common, portable MBG_ERR_... codes instead of TR_COMPLETE and friends to allow for common error handling. Support new XBP addressing for potential sub-devices. mbgextio_setup_receiver_info() sets up a RECEIVER_INFO structure for legacy devices, so it is used in favour of mbgextio_get_receiver_info() Preliminary function gpsxmple::set_date_time(). Source code in gpsxmple.c still needs cleanup.
-rwxr-xr-xdos/gpsxmple.exebin68752 -> 176680 bytes
-rw-r--r--dos/gpsxmple.prjbin8433 -> 8870 bytes
-rw-r--r--gpsxmple.c815
-rw-r--r--mbglib/common/cfg_hlp.h431
-rw-r--r--mbglib/common/extiohlp.c275
-rw-r--r--mbglib/common/extiohlp.h158
-rw-r--r--mbglib/common/gpsdefs.h11061
-rw-r--r--mbglib/common/gpsserio.c615
-rw-r--r--mbglib/common/gpsserio.h1227
-rw-r--r--mbglib/common/gpsutils.c143
-rw-r--r--mbglib/common/gpsutils.h23
-rw-r--r--mbglib/common/mbg_arch.h181
-rw-r--r--mbglib/common/mbg_tgt.h362
-rw-r--r--mbglib/common/mbg_tmo.h78
-rw-r--r--mbglib/common/mbgerror.c413
-rw-r--r--mbglib/common/mbgerror.h326
-rw-r--r--mbglib/common/mbgextio.c5221
-rw-r--r--mbglib/common/mbgextio.h2107
-rw-r--r--mbglib/common/mbggeo.h16
-rw-r--r--mbglib/common/mbgmutex.h69
-rw-r--r--mbglib/common/mbgserio.c931
-rw-r--r--mbglib/common/mbgserio.h116
-rw-r--r--mbglib/common/mbgtime.h372
-rw-r--r--mbglib/common/myutil.c68
-rw-r--r--mbglib/common/myutil.h238
-rw-r--r--mbglib/common/pcpsdefs.h1934
-rw-r--r--mbglib/common/use_pack.h8
-rw-r--r--mbglib/common/words.h314
28 files changed, 23310 insertions, 4192 deletions
diff --git a/dos/gpsxmple.exe b/dos/gpsxmple.exe
index ac3dcc9..4603e2c 100755
--- a/dos/gpsxmple.exe
+++ b/dos/gpsxmple.exe
Binary files differ
diff --git a/dos/gpsxmple.prj b/dos/gpsxmple.prj
index f349f0a..fd543dc 100644
--- a/dos/gpsxmple.prj
+++ b/dos/gpsxmple.prj
Binary files differ
diff --git a/gpsxmple.c b/gpsxmple.c
index f5ab204..4120194 100644
--- a/gpsxmple.c
+++ b/gpsxmple.c
@@ -1,14 +1,14 @@
/**************************************************************************
*
- * $Id: gpsxmple.c 1.8 2011/04/15 13:04:14Z martin REL_M $
- * $Name: GPSXMPLE_2_3 $
+ * $Id: gpsxmple.c 1.10.1.8 2015/07/25 15:28:12Z martin TEST $
+ * $Name: GPSXMPLE_2_5 $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* Sample program demonstrating how to access Meinberg devices
- * using the binary data protocol.
+ * using the serial binary data protocol.
*
* Depending on the target operating system this program works
* either via serial port (the default) or via a network socket
@@ -32,7 +32,27 @@
*
* -----------------------------------------------------------------------
* $Log: gpsxmple.c $
- * Revision 1.8 2011/04/15 13:04:14Z martin
+ * Revision 1.10.1.8 2015/07/25 15:28:12Z martin
+ * Revision 1.10.1.7 2015/07/24 13:47:32Z martin
+ * Revision 1.10.1.6 2015/07/14 13:01:02 martin
+ * Revision 1.10.1.5 2014/11/04 11:32:25 martin
+ * Started to support XBP addressing.
+ * Revision 1.10.1.4 2014/10/30 13:49:38 martin
+ * Revision 1.10.1.3 2013/02/01 16:11:59 martin
+ * Revision 1.10.1.2 2012/03/13 16:27:44 martin
+ * Revision 1.10.1.1 2012/03/13 11:48:35Z martin
+ * Revision 1.10 2012/01/12 09:57:04 martin
+ * Support selection of SCU port.
+ * Preliminary code to send PCPS_TIME via binary protocol.
+ * Debug code to test TX flushing problems under Windows.
+ * GPSXMPLE code disabled by default to build mbgevlog.
+ * Revision 1.9 2011/12/15 14:35:49Z martin
+ * Started to migrate to opaque stuctures.
+ * Made more functions static.
+ * Added code to show / clear GPS event log.
+ * Used this module for the mbgevlog program and disabled
+ * some GPSXMPLE code using preprocessor symbol.
+ * Revision 1.8 2011/04/15 13:04:14 martin
* Optionally poll for user capture events.
* Under Unix catch signals to terminate properly.
* Revision 1.7 2009/10/02 14:18:08Z martin
@@ -45,7 +65,7 @@
* 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
+ * Check return codes of API functions and print associated
* messages in case of error.
* Revision 1.5 2006/08/24 13:36:38Z martin
* Conditional support for network socket I/O.
@@ -62,7 +82,9 @@
**************************************************************************/
#include <mbgextio.h>
+#include <extiohlp.h>
#include <gpsutils.h>
+#include <pcpsdefs.h>
#include <stdio.h>
#include <stdlib.h>
@@ -82,16 +104,13 @@
#endif
+const char pname[] = "gpsxmple";
+const char pversion[] = "2.5";
+const char pdescr[] = "Example Program Accessing a Meinberg Device via Binary Protocol";
-// the variables below are required for communication
-MBG_MSG_BUFF rbuff;
-MBG_MSG_BUFF tbuff;
-MBG_MSG_CTL mctl =
-{
- { &rbuff, sizeof( rbuff ) },
- { &tbuff, sizeof( tbuff ) }
-};
+// the variables below are required for communication
+MBG_MSG_CTL *pmctlx;
// Define the minimum number of some resource types
@@ -101,9 +120,11 @@ MBG_MSG_CTL mctl =
// 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_STR_TYPE_MAX 20 // max. number of string types
#define N_POUT_MAX 3 // max. number of programmable outputs
+#define N_SCU_PORT 2
+
#define IDLE_SLEEP_MS 200
@@ -124,8 +145,14 @@ MBG_MSG_CTL mctl =
static const char *target;
static int is_socket;
static int must_force_connection;
+
+static const char *str_new_date;
+static const char *str_new_time;
+
static int must_send_auto;
static int must_poll_ucap;
+
+static int must_clear_event_log;
static RECEIVER_INFO receiver_info;
static const char *feature_names[] = DEFAULT_GPS_FEATURE_NAMES;
@@ -144,6 +171,8 @@ static const char *default_target = DEFAULT_DEV_NAME;
#if _USE_SOCKET_IO
static const char *password;
+ static int scu_port;
+ static int must_set_scu_port;
#endif
@@ -155,6 +184,84 @@ static const char *dow_str[] =
+#if defined( DEBUG )
+
+static /*HDR*/
+void print_original_serial_settings( FILE *fp, SERIAL_IO_STATUS *p )
+{
+ #if defined( MBG_TGT_WIN32 )
+ DCB *dcb = &p->old_dcb;
+ COMMTIMEOUTS *tmo = &p->old_commtimeouts;
+ COMMPROP *prop = &p->comm_prop;
+
+ fprintf( fp, "Comm Properties:\n" );
+ fprintf( fp, " wPacketLength: %u\n", prop->wPacketLength );
+ fprintf( fp, " wPacketVersion: %u\n", prop->wPacketVersion );
+ fprintf( fp, " dwServiceMask: %u (%u)\n", prop->dwServiceMask, SP_SERIALCOMM );
+ fprintf( fp, " dwReserved1: %u\n", prop->dwReserved1 );
+ fprintf( fp, " dwMaxTxQueue: %u\n", prop->dwMaxTxQueue );
+ fprintf( fp, " dwMaxRxQueue: %u\n", prop->dwMaxRxQueue );
+ fprintf( fp, " dwMaxBaud: %u\n", prop->dwMaxBaud );
+ fprintf( fp, " dwProvSubType: %u\n", prop->dwProvSubType );
+ fprintf( fp, " dwProvCapabilities: %u\n", prop->dwProvCapabilities );
+ fprintf( fp, " dwSettableParams: 0x%2X\n", prop->dwSettableParams );
+ fprintf( fp, " dwSettableBaud: 0x%2X\n", prop->dwSettableBaud );
+ fprintf( fp, " wSettableData: 0x%2X\n", prop->wSettableData );
+ fprintf( fp, " wSettableStopParity: 0x%2X\n", prop->wSettableStopParity );
+ fprintf( fp, " dwCurrentTxQueue: %u\n", prop->dwCurrentTxQueue );
+ fprintf( fp, " dwCurrentRxQueue: %u\n", prop->dwCurrentRxQueue );
+ fprintf( fp, " dwProvSpec1: %u\n", prop->dwProvSpec1 );
+ fprintf( fp, " dwProvSpec2: %u\n", prop->dwProvSpec2 );
+ // fprintf( fp, " wcProvChar: %c\n", prop->wcProvChar[0] ); // wchar!!
+ fprintf( fp, "\n" );
+
+ fprintf( fp, "Original serial DCB settings:\n" );
+ fprintf( fp, " DCBlength: %u\n", dcb->DCBlength );
+ fprintf( fp, " BaudRate: %u\n", dcb->BaudRate );
+ fprintf( fp, " fBinary: %u\n", dcb->fBinary );
+ fprintf( fp, " fParity: %u\n", dcb->fParity );
+ fprintf( fp, " fOutxCtsFlow: %u\n", dcb->fOutxCtsFlow );
+ fprintf( fp, " fOutxDsrFlow: %u\n", dcb->fOutxDsrFlow );
+ fprintf( fp, " fDtrControl: %u\n", dcb->fDtrControl );
+ fprintf( fp, " fDsrSensitivity: %u\n", dcb->fDsrSensitivity );
+ fprintf( fp, " fTXContinueOnXoff: %u\n", dcb->fTXContinueOnXoff );
+ fprintf( fp, " fOutX: %u\n", dcb->fOutX );
+ fprintf( fp, " fInX: %u\n", dcb->fInX );
+ fprintf( fp, " fErrorChar: %u\n", dcb->fErrorChar );
+ fprintf( fp, " fNull: %u\n", dcb->fNull );
+ fprintf( fp, " fRtsControl: %u\n", dcb->fRtsControl );
+ fprintf( fp, " fAbortOnError: %u\n", dcb->fAbortOnError );
+ fprintf( fp, " fDummy2: %u\n", dcb->fDummy2 );
+ fprintf( fp, " wReserved: %u\n", dcb->wReserved );
+ fprintf( fp, " XonLim: %u\n", dcb->XonLim );
+ fprintf( fp, " XoffLim: %u\n", dcb->XoffLim );
+ fprintf( fp, " ByteSize: %u\n", dcb->ByteSize );
+ fprintf( fp, " Parity: %u\n", dcb->Parity );
+ fprintf( fp, " StopBits: %u\n", dcb->StopBits );
+ fprintf( fp, " XonChar: %u\n", dcb->XonChar );
+ fprintf( fp, " XoffChar: %u\n", dcb->XoffChar );
+ fprintf( fp, " ErrorChar: %u\n", dcb->ErrorChar );
+ fprintf( fp, " EofChar: %u\n", dcb->EofChar );
+ fprintf( fp, " EvtChar: %u\n", dcb->EvtChar );
+ fprintf( fp, " wReserved1: %u\n", dcb->wReserved1 );
+ fprintf( fp, "\n" );
+
+ fprintf( fp, "Original serial comm timeout settings:\n" );
+ fprintf( fp, " ReadIntervalTimeout: %u\n", tmo->ReadIntervalTimeout );
+ fprintf( fp, " ReadTotalTimeoutMultiplier: %u\n", tmo->ReadTotalTimeoutMultiplier );
+ fprintf( fp, " ReadTotalTimeoutConstant: %u\n", tmo->ReadTotalTimeoutConstant );
+ fprintf( fp, " WriteTotalTimeoutMultiplier: %u\n", tmo->WriteTotalTimeoutMultiplier );
+ fprintf( fp, " WriteTotalTimeoutConstant: %u\n", tmo->WriteTotalTimeoutConstant );
+ fprintf( fp, "\n" );
+
+ #endif
+
+} // print_original_serial_settings
+
+#endif // defined( DEBUG )
+
+
+
static /*HDR*/
void mbg_sleep_msec( long msec )
{
@@ -163,7 +270,7 @@ void mbg_sleep_msec( long msec )
#elif defined( MBG_TGT_WIN32 )
Sleep( msec );
#elif defined( MBG_TGT_DOS )
- delay( msec );
+ delay( (unsigned int) msec );
#endif
} // mbg_sleep_msec
@@ -171,6 +278,28 @@ void mbg_sleep_msec( long msec )
static /*HDR*/
+int set_scu_port( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, int port )
+{
+ // Yet this is preliminary/untested.
+ SCU_STAT_SETTINGS scu_stat_settings = { 0 };
+ int rc;
+
+ scu_stat_settings.epld_control_mask = MSK_EPLD_CNTL_ENA_SNMP | MSK_EPLD_CNTL_SEL_SNMP;
+
+ scu_stat_settings.epld_control_value = MSK_EPLD_CNTL_ENA_SNMP;
+
+ if ( port ) // else leave 0
+ scu_stat_settings.epld_control_value |= MSK_EPLD_CNTL_SEL_SNMP;
+
+ rc = mbgextio_xmt_msg( pmctl, p_addr, GPS_SCU_STAT, &scu_stat_settings, sizeof( scu_stat_settings ) );
+
+ return rc;
+
+} // set_scu_port
+
+
+
+static /*HDR*/
int check_rc( int rc )
{
const char *cp = NULL;
@@ -180,43 +309,31 @@ int check_rc( int rc )
switch ( rc )
{
- case TR_COMPLETE:
+ case MBG_SUCCESS:
cp = "Data received completely.";
break;
- case TR_RECEIVING:
- cp = "Received data not complete.";
- break;
-
- case TR_WAITING:
- cp = "Waiting for data.";
- break;
-
- case TR_TIMEOUT:
+ case MBG_ERR_TIMEOUT:
cp = "Timeout receiving data";
break;
- case TR_CSUM_HDR:
+ case MBG_ERR_HDR_CSUM:
cp = "Header checksum error in received data.";
break;
- case TR_CSUM_DATA:
+ case MBG_ERR_DATA_CSUM:
cp = "Data checksum error in received data.";
break;
- case TR_DECRYPTION:
+ case MBG_ERR_DECRYPT:
cp = "Failed to decrypt received data.";
break;
- case TR_OPEN_ERR:
- cp = "Failed to establish connection.";
- break;
-
- case TR_IO_ERR:
+ case MBG_ERR_IO:
cp = "I/O error receiving data";
break;
- case TR_AUTH_ERR:
+ case MBG_ERR_AUTH:
cp = "Authentication error";
break;
@@ -233,7 +350,7 @@ int check_rc( int rc )
-/*HDR*/
+static /*HDR*/
void sprint_tm( char *s, TM_GPS *tm, int print_frac )
{
int n = 0;
@@ -258,7 +375,7 @@ void sprint_tm( char *s, TM_GPS *tm, int print_frac )
-/*HDR*/
+static /*HDR*/
void sprint_lla( char *s, LLA lla )
{
static const double r2d = 180 / PI;
@@ -273,7 +390,7 @@ void sprint_lla( char *s, LLA lla )
-/*HDR*/
+static /*HDR*/
void print_stat_info( STAT_INFO *p )
{
const char *cp;
@@ -304,7 +421,7 @@ void print_stat_info( STAT_INFO *p )
-/*HDR*/
+static /*HDR*/
void print_time( TTM *p )
{
static const char *s[] =
@@ -333,7 +450,7 @@ 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
+ // 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 ) \
@@ -373,15 +490,15 @@ void check_receiver_info( RECEIVER_INFO *p, int log )
_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_str_type, MAX_PARM_PORT, "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 )
+static /*HDR*/
+int get_receiver_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_INFO *p )
{
int rc;
int i;
@@ -389,13 +506,13 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
printf( fmt, "Receiver info:" );
- rc = mbgextio_get_receiver_info( &mctl, p );
+ rc = mbgextio_setup_receiver_info( pmctl, p_addr, p );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
- if ( rc == TR_TIMEOUT )
+ if ( rc == MBG_ERR_TIMEOUT )
{
printf( "If you are using a very old GPS model then reading the\n"
"receiver info structure may not be supported.\n" );
@@ -457,17 +574,17 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
-/*HDR*/
-void show_sw_rev( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_sw_rev( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SW_REV sw_rev;
int rc;
printf( fmt, "Software Revision:" );
- rc = mbgextio_get_sw_rev( pmctl, &sw_rev );
+ rc = mbgextio_get_sw_rev( pmctl, p_addr, &sw_rev );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -483,17 +600,17 @@ void show_sw_rev( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_bvar_stat( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_bvar_stat( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
BVAR_STAT bvar_stat;
int rc;
printf( fmt, "BVAR status:" );
- rc = mbgextio_get_bvar_stat( pmctl, &bvar_stat );
+ rc = mbgextio_get_bvar_stat( pmctl, p_addr, &bvar_stat );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -505,17 +622,17 @@ void show_bvar_stat( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_stat_info( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_stat_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
STAT_INFO stat_info;
int rc;
printf( fmt, "Receiver status:" );
- rc = mbgextio_get_stat_info( pmctl, &stat_info );
+ rc = mbgextio_get_stat_info( pmctl, p_addr, &stat_info );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -527,17 +644,17 @@ void show_stat_info( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_pos( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_pos( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
LLA lla; // Position as logitude, latitude, altitude
int rc;
printf( fmt, "Receiver Position:" );
- rc = mbgextio_get_pos_lla( pmctl, lla );
+ rc = mbgextio_get_pos_lla( pmctl, p_addr, lla );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -550,17 +667,17 @@ void show_pos( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_tzdl( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
TZDL tzdl;
int rc;
printf( fmt, "Time Zone:" );
- rc = mbgextio_get_tzdl( pmctl, &tzdl );
+ rc = mbgextio_get_tzdl( pmctl, p_addr, &tzdl );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -603,8 +720,8 @@ void show_tzdl( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_synth( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SYNTH synth;
double f;
@@ -612,9 +729,9 @@ void show_synth( MBG_MSG_CTL *pmctl )
printf( fmt, "Synthesizer:" );
- rc = mbgextio_get_synth( pmctl, &synth );
+ rc = mbgextio_get_synth( pmctl, p_addr, &synth );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -629,7 +746,7 @@ void show_synth( MBG_MSG_CTL *pmctl )
if ( synth.range == 0 )
{
- // freq field is in 0.1 Hz units, so if
+ // freq field is in 0.1 Hz units, so if
// the range is 0 we must divide by 10
// to yield the correct result
f = (double) synth.freq / 10.0;
@@ -656,8 +773,8 @@ void show_synth( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void set_synth( void )
+static /*HDR*/
+void set_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SYNTH synth = { 0 };
int rc;
@@ -673,10 +790,10 @@ void set_synth( void )
// 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.range = 1; // multiplier 10^^range
synth.phase = 1800; // phase in 1/10 degrees
- rc = mbgextio_set_synth( &mctl, &synth );
+ rc = mbgextio_set_synth( pmctl, p_addr, &synth );
if ( rc < 0 )
printf( "Failed to set synthesizer output, code: %i\n", rc );
@@ -689,8 +806,8 @@ void set_synth( void )
// set programmable output mode
-/*HDR*/
-void set_pout_mode( void )
+static /*HDR*/
+void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
POUT_INFO_IDX pout_info_idx;
POUT_SETTINGS pout_settings = { 0 }; // new settings, init'd to 0
@@ -712,12 +829,12 @@ void set_pout_mode( void )
return;
}
- // OK, now get the current settings, and see which modes are
+ // OK, now get the current settings, and see which modes are
// supported by the selected programmable pulse output.
- rc = mbgextio_get_pout_info_idx( &mctl, &pout_info_idx, pout_idx );
+ rc = mbgextio_get_pout_info_idx( pmctl, p_addr, &pout_info_idx, pout_idx );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -740,9 +857,9 @@ void set_pout_mode( void )
pout_settings.tm[0].on.t.hour = 0;
pout_settings.tm[0].on.t.min = 20;
pout_settings.tm[0].on.t.sec = 0;
- pout_settings.pulse_len = 30; // 10 millisecond units
+// pout_settings.pulse_len = 30; // 10 millisecond units
- rc = mbgextio_set_pout_settings_idx( &mctl, &pout_settings, pout_idx );
+ rc = mbgextio_set_pout_settings_idx( pmctl, p_addr, &pout_settings, pout_idx );
if ( rc < 0 )
printf( "Failed to set programmable pulse output mode, code: %i\n", rc );
@@ -753,7 +870,9 @@ void set_pout_mode( void )
-/*HDR*/
+#if 0 //##++++++++++++++++
+
+static /*HDR*/
void show_port_parm( MBG_MSG_CTL *pmctl )
{
PORT_PARM port_parm;
@@ -763,7 +882,7 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
rc = mbgextio_get_port_parm( pmctl, &port_parm );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -795,75 +914,45 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
} /* show_port_parm */
+#endif
+
-/*HDR*/
-void show_port_settings( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_port_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
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;
+ RECEIVER_PORT_CFG rpcfg;
int rc;
int i;
printf( fmt, "Serial ports:" );
- if ( receiver_info.model_code == GPS_MODEL_UNKNOWN )
+ rc = mbgextio_get_serial_settings( pmctl, p_addr, &rpcfg, &receiver_info );
+
+ if ( rc != MBG_SUCCESS )
{
- // This may be an old GPS model which does not provide
- // a receiver info structure.
- show_port_parm( pmctl );
+ check_rc( rc );
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
+#if 0 //##++ TODO: possibly print supported string types
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;
}
+#endif
-
- // Read and print port settings
+ // 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;
+ PORT_SETTINGS *p = &rpcfg.pii[i].port_info.port_settings;
printf( "COM%i: %5lu Baud, %s",
i,
@@ -874,13 +963,13 @@ void show_port_settings( MBG_MSG_CTL *pmctl )
// Make sure indices received from the device do not exceed
// maximum numbers supported by this program.
- if ( p->str_type >= N_STR_TYPE_MAX )
+ if ( p->str_type >= MAX_PARM_STR_TYPE )
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( ", \"%s\" string %s", rpcfg.stii[p->str_type].str_type_info.long_name, mode_names[p->mode] );
printf( "\n" );
@@ -894,8 +983,68 @@ void show_port_settings( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_event_log( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
+{
+ static const char *evt_id_names[N_MBG_EVT_ID] = MBG_EVT_ID_NAMES_ENG;
+
+ MBG_NUM_EVT_LOG_ENTRIES log_entries;
+ MBG_EVT_LOG_ENTRY evt_log_entry;
+ time_t t;
+ struct tm *mytime;
+ int n_evt = 0;
+ int event_id = -1;
+
+ if ( mbgextio_get_num_evt_log_entries( pmctl, p_addr, &log_entries ) )
+ printf( "\nEvent Log (%i/%i entries used):\n", log_entries.used, log_entries.max );
+ else
+ {
+ printf( "Failed to read event log entries\n" );
+ return;
+ }
+
+ if ( mbgextio_get_first_evt_log_entry( pmctl, p_addr, &evt_log_entry ) )
+ {
+ unsigned int i;
+
+ for ( i = 0; i < log_entries.max; i++ )
+ {
+ event_id = _mbg_get_evt_id( evt_log_entry.code );
+
+ if ( event_id == 0 )
+ break;
+
+ n_evt++;
+
+ t = evt_log_entry.time;
+ mytime = gmtime( &t );
+
+ printf( "%04i-%02i-%02i %02i:%02i:%02i ",
+ mytime->tm_year + 1900, mytime->tm_mon + 1, mytime->tm_mday,
+ mytime->tm_hour, mytime->tm_min, mytime->tm_sec );
+
+ if ( event_id < N_MBG_EVT_ID )
+ printf( "%s\n", evt_id_names[event_id] );
+ else
+ printf( "Unknown event ID %u", event_id );
+
+ mbgextio_get_next_evt_log_entry( pmctl, p_addr, &evt_log_entry );
+ }
+ }
+ else
+ fprintf( stderr, "** ERROR: failed to read event log\n" );
+
+ if ( n_evt == 0 )
+ fprintf( stderr, "event log is empty\n" );
+
+ printf( "\n" );
+
+} // show_event_log
+
+
+
/*HDR*/ static
-int check_ucap_poll( void )
+int check_ucap_poll( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
int rc;
@@ -906,9 +1055,9 @@ int check_ucap_poll( void )
{
TTM ttm;
memset( &ttm, 0, sizeof( ttm ) );
- rc = mbgextio_get_ucap( &mctl, &ttm );
+ rc = mbgextio_get_ucap( pmctl, p_addr, &ttm );
- if ( _ttm_time_is_avail( &ttm ) )
+ if ( ( rc == MBG_SUCCESS ) && _ttm_time_is_avail( &ttm ) )
{
printf( "CAP%i: %04u-%02u-%02u %02u:%02u:%02u.%07u",
ttm.channel, ttm.tm.year, ttm.tm.month, ttm.tm.mday,
@@ -931,10 +1080,219 @@ int check_ucap_poll( void )
+static /*HDR*/
+int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ const char *str_new_date, const char *str_new_time )
+{
+ PCPS_TIME_UNION u = { { 0 } };
+ TTM ttm = { 0 };
+ unsigned int year = 0;
+ unsigned int month = 0;
+ unsigned int mday = 0;
+ unsigned int hour = 0;
+ unsigned int min = 0;
+ unsigned int sec = 0;
+ unsigned int sec100 = 0;
+ int rc;
+
+ // Either a date string, a time string, or both
+ // may have been passed to this function.
+ // If either of them is NULL read the current date/time
+ // as default values.
+ if ( str_new_date == NULL || str_new_time == NULL )
+ {
+#if 1 //##+++++++++++++
+ return -1;
+#else
+ rc = mbg_get_time( dh, &u.t );
+
+ if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
+ return rc;
+#endif
+ }
+
+
+ if ( str_new_date )
+ {
+ rc = sscanf( str_new_date, "%u-%u-%u", &year, &month, &mday );
+
+ if ( ( rc < 3 )
+ || ( month < 1 ) || ( month > 12 )
+ || ( mday < 1 ) || ( mday > 31 ) )
+ {
+ printf( "** Invalid date: %04u-%02u-%02u\n", year, month, mday );
+ return MBG_ERR_CFG;
+ }
+ }
+
+
+ if ( str_new_time )
+ {
+ rc = sscanf( str_new_time, "%u:%u:%u.%u", &hour, &min, &sec, &sec100 );
+
+ if ( ( rc < 2 ) // at least hours and minutes are required
+ || ( hour > 23 )
+ || ( min > 59 )
+ || ( sec > 60 )
+ || ( sec100 > 99 ) )
+ {
+ printf( "** Invalid time: %02u:%02u:%02u.%02u\n", hour, min, sec, sec100 );
+ return MBG_ERR_CFG;
+ }
+ }
+
+#if 0 //##++++++++++++++++
+ // GPS and non-GPS cards require different API calls which use
+ // different structures to set the on-board date and time,
+ // so we have to distinguish.
+
+ if ( _pcps_is_gps( p_dev ) ) // is a GPS card
+ {
+ ttm.channel = -1;
+
+ if ( str_new_date ) // new date
+ {
+ ttm.tm.year = year;
+ ttm.tm.month = month;
+ ttm.tm.mday = mday;
+ }
+ else // copy current date as default
+ {
+ ttm.tm.year = u.t.year + 2000;
+ ttm.tm.month = u.t.month;
+ ttm.tm.mday = u.t.mday;
+ }
+
+ if ( str_new_time ) // new time
+ {
+ ttm.tm.hour = hour;
+ ttm.tm.min = min;
+ ttm.tm.sec = sec;
+ ttm.tm.frac = sec100;
+ }
+ else // copy current time as default
+ {
+ ttm.tm.hour = u.t.hour;
+ ttm.tm.min = u.t.min;
+ ttm.tm.sec = u.t.sec;
+ ttm.tm.frac = u.t.sec100;
+ }
+
+ ttm.tm.frac *= 100000; // fracs are in 100 ns units
+
+ #if 0
+ // Existing versions of the GPS cards just take
+ // TTM.tm as local time without accounting for
+ // the status flags, or UTC offset.
+ // Instead, the TTM::tm time is converted on-board
+ // to UTC depending on the local TZDL configuration.
+ // This works if the system time and the
+ ttm.tm.offs_from_utc = 7200;
+ ttm.tm.status |= TM_UTC | TM_LOCAL;
+ ttm.tm.status |= TM_DL_ENB;
+ #endif
+
+ rc = mbg_set_gps_time( dh, &ttm );
+
+ if ( mbg_ioctl_err( rc, "mbg_set_gps_time" ) )
+ return rc;
+ }
+ else // is not a GPS card
+ {
+ if ( str_new_date ) // new date
+ {
+ // determine the day-of-week for the given date
+ struct tm tm = { 0 };
+
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = mday;
+ tm.tm_hour = 12;
+ tm.tm_isdst = -1;
+ mktime( &tm );
+
+ u.stime.year = year % 100;
+ u.stime.month = month;
+ u.stime.mday = mday;
+ u.stime.wday = _wday_sun06_to_mon17( tm.tm_wday );
+ }
+
+ if ( str_new_time ) // new time
+ {
+ u.stime.hour = hour;
+ u.stime.min = min;
+ u.stime.sec = sec;
+ u.stime.sec100 = sec100;
+ }
+
+ if ( u.stime.wday == 0 )
+ u.stime.wday = 1; // dummy
+
+ rc = mbg_set_time( dh, &u.stime );
+
+ if ( mbg_ioctl_err( rc, "mbg_set_time" ) )
+ return rc;
+ }
+#else
+ {
+ //
+ PCPS_TIME t = { 0 };
+
+ // determine the day-of-week for the given date
+ struct tm tm = { 0 };
+
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = mday;
+ tm.tm_hour = 12;
+ tm.tm_isdst = -1;
+ mktime( &tm );
+
+ t.year = year % 100;
+ t.month = month;
+ t.mday = mday;
+ t.wday = ( tm.tm_wday == 0 ) ? 7 : tm.tm_wday;
+ t.hour = hour;
+ t.min = min;
+ t.sec = sec;
+ t.sec100 = sec100;
+
+#if 0 //##+++++++++++++++++
+ {
+ MBG_PORT_HANDLE port_handle = pmctl->st.serio.port_handle;
+ const char tmp[] = "\xFF\xFF\xFF\xFF";
+
+ // Note: encrypted msgs over serial are not yet supported.
+
+ // _mbgserio_write( port_handle, &tmp, strlen( tmp ) );
+ // _swab_pcps_time( &t );
+ rc = mbgextio_xmt_msg( pmctl, PZF_PCPS_TIME, &t, sizeof( t ) );
+
+ // _mbgserio_write( port_handle, &tmp, strlen( tmp ) );
+ }
+#else
+ // _swab_pcps_time( &t );
+ rc = mbgextio_xmt_msg( pmctl, p_addr, PZF_PCPS_TIME, &t, sizeof( t ) );
+#endif
+
+ if ( rc < 0 )
+ printf( "Failed to set date/time, rc: %i\n", rc );
+ }
+
+#endif
+ printf( "\n\nDevice date/time have been set to %04u-%02u-%02u %02u:%02u:%02u.%02u\n\n",
+ year, month, mday, hour, min, sec, sec100 );
+
+ return MBG_SUCCESS;
+
+} // set_date_time
+
+
+
/*HDR*/ static
void exit_close_connection( void )
{
- mbgextio_close_connection( &mctl );
+ mbgextio_close_connection( &pmctlx );
printf( "Connection closed.\n" );
printf( "\n" );
@@ -946,7 +1304,7 @@ void exit_close_connection( void )
/*HDR*/ static
void exit_auto_off( void )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_OFF );
+ mbgextio_xmt_cmd( pmctlx, NULL, GPS_AUTO_OFF ); //##++++++ TODO: NULL?
#if defined( DEBUG )
printf( "AUTO mode turned off.\n" );
@@ -957,9 +1315,9 @@ void exit_auto_off( void )
/*HDR*/ static
-void set_auto_mode( void )
+void set_auto_mode( MBG_MSG_CTL *pmctl )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctl, NULL, GPS_AUTO_ON ); //##++++++ TODO: NULL?
#if defined( DEBUG )
printf( "AUTO mode turned on.\n" );
@@ -998,32 +1356,32 @@ int check_command_line( int argc, char *argv[] )
for ( i = 1; i < argc; i++ )
{
- if ( strcmp( argv[i], "-a" ) == 0 )
+ if ( strcmp( argv[i], "-a" ) == 0 )
{
must_send_auto = 1;
continue;
}
- if ( strcmp( argv[i], "-u" ) == 0 )
+ if ( strcmp( argv[i], "-u" ) == 0 )
{
must_poll_ucap = 1;
continue;
}
- if ( strcmp( argv[i], "-?" ) == 0 )
+ if ( strcmp( argv[i], "-?" ) == 0 )
{
must_print_usage = 1;
continue;
}
- if ( strcmp( argv[i], "-h" ) == 0 )
+ if ( strcmp( argv[i], "-h" ) == 0 )
{
must_print_usage = 1;
continue;
}
#if _USE_SOCKET_IO
- if ( strcmp( argv[i], "-n" ) == 0 )
+ if ( strcmp( argv[i], "-n" ) == 0 )
{
is_socket = 1;
continue;
@@ -1032,7 +1390,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SOCKET_IO
if ( strcmp( argv[i], "-p" ) == 0 )
- {
+ {
if ( ++i < argc )
password = argv[i];
else
@@ -1044,7 +1402,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SERIAL_IO
if ( strcmp( argv[i], "-b" ) == 0 )
- {
+ {
if ( ++i < argc )
baudrate = strtoul( argv[i], NULL, 10 );
else
@@ -1056,7 +1414,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SERIAL_IO
if ( strcmp( argv[i], "-f" ) == 0 )
- {
+ {
if ( ++i < argc )
framing = argv[i];
else
@@ -1074,6 +1432,52 @@ int check_command_line( int argc, char *argv[] )
}
#endif
+ if ( strcmp( argv[i], "-c" ) == 0 )
+ {
+ must_clear_event_log = 1;
+ continue;
+ }
+
+
+ #if _USE_SOCKET_IO
+ if ( strcmp( argv[i], "-P" ) == 0 )
+ {
+ if ( ++i < argc )
+ {
+ scu_port = atoi( argv[i] );
+
+ if ( ( scu_port >= 0 ) && ( scu_port < N_SCU_PORT ) )
+ {
+ must_set_scu_port = 1;
+ continue;
+ }
+ }
+
+ fprintf( stderr, "** invalid parameter for \"-P\"\n" );
+ must_print_usage = 1;
+ continue;
+ }
+ #endif
+
+
+ if ( strcmp( argv[i], "-d" ) == 0 )
+ {
+ if ( ++i < argc )
+ str_new_date = argv[i];
+
+ continue;
+ }
+
+
+ if ( strcmp( argv[i], "-t" ) == 0 )
+ {
+ if ( ++i < argc )
+ str_new_time = argv[i];
+
+ continue;
+ }
+
+
if ( argv[i][0] != '-' )
target = argv[i];
else
@@ -1112,6 +1516,10 @@ int check_command_line( int argc, char *argv[] )
" -f xxx Serial port framing, default: %s\n"
" -F Force serial connection to %lu/%s\n"
#endif
+ " -c clear event log (if supported)\n"
+ #if _USE_SOCKET_IO
+ " -P scu_port Select clock at SCU port 0 or 1 (only with SCU over LAN)\n"
+ #endif
"\n"
"Example:\n"
#if _USE_SERIAL_IO
@@ -1148,9 +1556,10 @@ int check_command_line( int argc, char *argv[] )
int main( int argc, char *argv[] )
{
+ XBP_ADDR *p_addr = NULL;
int rc;
- printf( "\n\n\nExample Program Accessing a Meinberg Device via Binary Protocol\n" );
+ fprintf( stderr, "\n\n\n%s v%s %s\n", pname, pversion, pdescr );
baudrate = default_baudrate;
framing = default_framing;
@@ -1166,16 +1575,12 @@ int main( int argc, char *argv[] )
#if _USE_SOCKET_IO
if ( is_socket )
{
- rc = mbgextio_open_socket( &mctl, target, password );
+ rc = mbgextio_open_socket( target, &pmctlx, password );
- if ( rc < 0 )
+ if ( rc != MBG_SUCCESS )
{
- if ( rc == TR_OPEN_ERR )
- perror( "Error connecting" );
- else
- fprintf( stderr, "mbgextio_open_socket returned %i", rc );
-
- exit( 1 );
+ printf( "Failed to connect to %s, rc: %i\n", target, rc );
+ return 1; // Error ...
}
goto doit;
@@ -1186,21 +1591,25 @@ int main( int argc, char *argv[] )
if ( must_force_connection )
{
printf( "Trying to force connection to 19200/8N1 ..." );
- mbgextio_force_connection( target );
+ mbgextio_force_conn_serial( target );
printf( "\n" );
baudrate = default_baudrate;
framing = default_framing;
}
- rc = mbgextio_open_serial( &mctl, target, baudrate, framing );
+ rc = mbgextio_open_serial( target, &pmctlx, baudrate, framing );
- if ( rc < 0 )
+ if ( rc != MBG_SUCCESS )
{
printf( "Error using port %s.\n", target );
- return -1; // Error ...
+ return 1; // Error ...
}
+ #if defined( DEBUG )
+ print_original_serial_settings( stdout, &pmctlx->st.serio );
+ #endif
+
printf( " (Using %s with %li baud, %s)\n\n",
target, (long) baudrate, framing );
@@ -1218,23 +1627,77 @@ doit:
// now start communication with whichever device has been opened above:
- get_receiver_info( &mctl, &receiver_info );
+ // TODO: make sure xbp is supported.
+ mbgextio_setup_xbp_node_list( pmctlx, p_addr );
+
+ #if _USE_SOCKET_IO
+ if ( must_set_scu_port )
+ {
+ int rc = set_scu_port( pmctlx, p_addr, scu_port );
+
+ if ( rc == MBG_SUCCESS )
+ printf( "\nSCU switched to port %i (clock #%i)\n\n",
+ scu_port, scu_port + 1 );
+ else
+ printf( "\nFailed to switch SCU to port %i (clock #%i)\n\n",
+ scu_port, scu_port + 1 );
+ }
+ #endif
+
+ if ( must_send_auto )
+ set_auto_mode( pmctlx );
+
+
+#if 1 //##+++++++++++++
+ get_receiver_info( pmctlx, p_addr, &receiver_info );
+#else
+ printf( "\n(Skipped getting receiver info)\n\n" );
+#endif
+
+ if ( str_new_date && str_new_time )
+ {
+ set_date_time( pmctlx, p_addr, str_new_date, str_new_time );
+ return 0;
+ }
+
check_receiver_info( &receiver_info, 1 );
/* display system specific values */
- show_sw_rev( &mctl );
- show_bvar_stat( &mctl );
- show_stat_info( &mctl );
- show_pos( &mctl );
- show_tzdl( &mctl );
- show_port_settings( &mctl );
- show_synth( &mctl );
+ show_sw_rev( pmctlx, p_addr );
+ show_bvar_stat( pmctlx, p_addr );
+ show_stat_info( pmctlx, p_addr );
+ show_pos( pmctlx, p_addr );
+ show_tzdl( pmctlx, p_addr );
+ show_port_settings( pmctlx, p_addr );
+ show_synth( pmctlx, p_addr );
+
+ if ( must_clear_event_log )
+ {
+ if ( receiver_info.features & GPS_HAS_EVT_LOG )
+ {
+ int ret = mbgextio_clr_evt_log( pmctlx, p_addr );
+
+ if ( ret != 0 )
+ fprintf( stderr, "Failed to clear event log, rc: %i\n", ret );
+ else
+ fprintf( stderr, "event log has been cleared\n" );
+ }
+ else
+ fprintf( stderr, "This device does not support an event log\n" );
+ }
+
+ if ( receiver_info.features & GPS_HAS_EVT_LOG )
+ show_event_log( pmctlx, p_addr );
+ else
+ if ( !must_clear_event_log )
+ printf( "** Warning: this device does not support an event log!\n" );
+
// set_synth();
// set_pout_mode();
if ( must_poll_ucap )
- return check_ucap_poll();
+ return check_ucap_poll( pmctlx, p_addr );
if ( !must_send_auto )
return 0;
@@ -1245,10 +1708,10 @@ doit:
// 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_set_char_rcv_timeout( pmctlx, 2000 ); // [msec]
+ mbgextio_set_msg_rcv_timeout( pmctlx, 2000 ); // [msec]
- set_auto_mode();
+ set_auto_mode( pmctlx );
do
{
@@ -1256,17 +1719,17 @@ doit:
MSG_DATA *p;
- rc = mbgextio_rcv_msg( &mctl, -1 );
+ rc = mbgextio_rcv_msg( pmctlx, p_addr, -1 );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
break;
}
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_AUTO_ON );
- pmb = mctl.rcv.pmb;
+ pmb = pmctlx->rcv.pmb;
p = &pmb->u.msg_data;
switch ( pmb->hdr.cmd )
@@ -1276,9 +1739,9 @@ doit:
if ( p->ttm.channel == -1 )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
- mbgextio_xmt_cmd( &mctl, GPS_STAT_INFO );
- mbgextio_xmt_cmd( &mctl, GPS_UCAP );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_STAT_INFO );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_UCAP );
}
break;
diff --git a/mbglib/common/cfg_hlp.h b/mbglib/common/cfg_hlp.h
new file mode 100644
index 0000000..46609c1
--- /dev/null
+++ b/mbglib/common/cfg_hlp.h
@@ -0,0 +1,431 @@
+
+/**************************************************************************
+ *
+ * $Id: cfg_hlp.h 1.3.1.19 2014/10/29 16:25:31Z martin TEST martin $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for configuration programs.
+ *
+ * WARNING: Changing the constants defined here affects the size of
+ * the related structures and arrays, and thus would break compatibility
+ * if used in DLLs / shared object libraries.
+ *
+ * Care must be taken that the number of objects supported by
+ * any particular device (which can be only determined at runtime)
+ * does not exceed the max. number of objects specified here
+ * for the configuration programs.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: cfg_hlp.h $
+ * Revision 1.3.1.19 2014/10/29 16:25:31Z martin
+ * Moved some functions and structures to more convenient files.
+ * Revision 1.3.1.18 2014/10/29 16:00:37 martin
+ * Revision 1.3.1.17 2014/10/29 14:21:55 martin
+ * Revision 1.3.1.16 2014/09/26 11:43:24 martin
+ * Revision 1.3.1.15 2014/07/22 13:05:35 martin
+ * Revision 1.3.1.14 2014/07/14 15:42:45Z martin
+ * Revision 1.3.1.13 2014/06/25 15:15:20 martin
+ * Revision 1.3.1.12 2014/06/25 08:51:36Z martin
+ * Support GPIO status.
+ * Revision 1.3.1.11 2014/05/22 16:15:16Z martin
+ * Revision 1.3.1.10 2014/05/14 12:43:53 martin
+ * Revision 1.3.1.9 2014/05/13 08:23:24 martin
+ * Revision 1.3.1.8 2014/05/13 08:19:34Z martin
+ * Revision 1.3.1.7 2014/04/28 12:33:09 martin
+ * Revision 1.3.1.6 2014/04/28 12:04:32 martin
+ * Revision 1.3.1.5 2014/04/25 09:16:38 martin
+ * Updated function prototypes.
+ * Revision 1.3.1.4 2013/12/18 14:51:37 martin
+ * Moved inline function num_bits_set() here.
+ * Revision 1.3.1.3 2013/11/13 10:00:09 martin
+ * Revision 1.3.1.2 2013/11/12 12:12:40 marvin
+ * Changed calls for NTP info and settings.
+ * Revision 1.3.1.1 2013/09/25 10:14:38Z martin
+ * Started to support NTP configuration.
+ * Revision 1.3 2013/09/25 10:02:15 martin
+ * Added ALL_PTP_CFG_INFO, ALL_GNSS_SAT_INFO_IDX and
+ * related definitions.
+ * Added doxygen comments.
+ * Revision 1.2 2012/10/02 18:16:26 martin
+ * Modified some typedefs to be more compliant with the underlying types.
+ * Revision 1.1 2011/09/21 15:59:59 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _CFG_HLP_H
+#define _CFG_HLP_H
+
+
+/* Other headers to be included */
+
+#include <gpsdefs.h>
+
+
+#ifdef _CFG_HLP
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// @brief The max number of serial ports supported by configuration programs
+#define MAX_PARM_PORT 4
+
+/// @brief An array of configuration settings for all serial ports
+typedef PORT_INFO_IDX ALL_PORT_INFO_IDX[MAX_PARM_PORT];
+
+
+/// @brief The max number of serial string types supported by configuration programs
+#define MAX_PARM_STR_TYPE 20
+
+/// @brief An array of configuration settings for all serial string types
+typedef STR_TYPE_INFO_IDX ALL_STR_TYPE_INFO_IDX[MAX_PARM_STR_TYPE];
+
+/**
+ * @brief All configuration parameters for all serial ports
+ *
+ * Used to collect all configuration parameters of a clock's serial ports
+ * that can be handled by a configuration program.
+ *
+ * @see ::RECEIVER_INFO::n_com_ports
+ * @see ::RECEIVER_INFO::n_str_type
+ */
+typedef struct
+{
+ ALL_PORT_INFO_IDX pii; ///< all serial port configuration settings
+ ALL_STR_TYPE_INFO_IDX stii; ///< all supported serial string types
+ PORT_PARM tmp_pp; ///< used internally only, for compatibility
+
+} RECEIVER_PORT_CFG;
+
+
+
+/// @brief The max number of programmable pulse outputs supported by configuration programs
+#define MAX_PARM_POUT 4
+
+/**
+ * @brief An array of configuration settings for all programmable pulse outputs
+ *
+ * Used to collect all configuration parameters of a clock's programmable pulse outputs
+ * that can be handled by a configuration program.
+ *
+ * @see ::RECEIVER_INFO::n_prg_out
+ */
+typedef POUT_INFO_IDX ALL_POUT_INFO_IDX[MAX_PARM_POUT];
+
+
+
+/// @brief The max number of PTP unicast masters supported by configuration programs
+#define MAX_PARM_PTP_UC_MASTER 3
+
+/// @brief Configuration settings for all unicast master specifications
+typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO_IDX[MAX_PARM_PTP_UC_MASTER];
+
+/**
+ * @brief All PTP configuration parameters
+ *
+ * Used to collect all configuration parameters for a PTP daemon
+ * that can be handled by a configuration program.
+ *
+ * @see ::GPS_HAS_PTP
+ * @see ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master
+ */
+typedef struct
+{
+ PTP_CFG_INFO ptp_cfg_info;
+ PTP_UC_MASTER_CFG_LIMITS ptp_uc_master_cfg_limits;
+ ALL_PTP_UC_MASTER_INFO_IDX all_ptp_uc_master_info_idx;
+
+} ALL_PTP_CFG_INFO;
+
+
+
+/// @brief The max number of GNSS settings supported by configuration programs
+#define MAX_PARM_GNSS_SAT N_GNSS_TYPES
+
+/**
+ * @brief An array of configuration settings for all programmable pulse outputs
+ *
+ * Used to collect all configuration parameters of a clock's programmable pulse outputs
+ * that can be handled by a configuration program.
+ */
+typedef GNSS_SAT_INFO_IDX ALL_GNSS_SAT_INFO_IDX[MAX_PARM_GNSS_SAT];
+
+
+
+/// @brief The max number of NTP server associations to be handled by configuration programs
+#define MAX_EXTERNAL_SERVER 20
+
+/// @brief Configuration settings for all NTP server associatioions
+typedef NTP_PEER_SETTINGS ALL_NTP_PEER_SETTINGS[MAX_EXTERNAL_SERVER];
+
+/**
+ * @brief All NTP configuration parameters
+ *
+ * Used to collect all configuration parameters for an NTP daemon
+ * that can be handled by a configuration program.
+ *
+ * @see ::GPS_HAS_NTP
+ */
+typedef struct
+{
+ ALL_NTP_PEER_SETTINGS all_ntp_peer_settings;
+
+} NTP_CLIENT_CFG_PEER_SETTINGS;
+
+
+
+
+/// @brief The max number of GPIO ports supported by configuration programs
+#define MAX_PARM_GPIO 10
+
+/// @brief Configuration settings for all GPIO ports
+typedef MBG_GPIO_INFO_IDX ALL_GPIO_INFO_IDX[MAX_PARM_GPIO];
+
+/// @brief Status information on all GPIO ports
+typedef MBG_GPIO_STATUS_IDX ALL_GPIO_STATUS_IDX[MAX_PARM_GPIO];
+
+
+
+
+/// @brief The max number of XMR sources supported by configuration programs
+#define MAX_PARM_XMR 10
+
+/// @brief Status of all XMR inputs
+typedef XMULTI_REF_STATUS_IDX ALL_XMULTI_REF_STATUS_IDX[MAX_PARM_XMR];
+
+/// @brief Configuration settings for all XMR inputs
+typedef XMULTI_REF_INFO_IDX ALL_XMULTI_REF_INFO_IDX[MAX_PARM_XMR];
+
+
+
+
+/**
+ * @brief A mode specifying how to interpret a ::PCPS_SIG_VAL
+ *
+ * Used with ::PCPS_TIME_EXT::comp_sig_mode. Depending on this mode
+ * a signal value can be interpreted e.g. as signal strength (with
+ * long wave or IRIG time code receivers), or as indicator whether an
+ * antenna is connected (satellite receivers), or a network link is
+ * available (PTP slaves) or not, and an appropriate status message
+ * can be displayed.
+ *
+ * @see @ref PCPS_SIG_VAL_DEFS
+ */
+enum COMP_SIG_MODES
+{
+ COMP_SIG_MODE_NONE, ///< signal value not used
+ COMP_SIG_MODE_SIGNAL, ///< input signal strength
+ COMP_SIG_MODE_ANT_CONN, ///< antenna connection state
+ COMP_SIG_MODE_PORT_LINK, ///< port link state
+ N_CONN_SIG_MODES
+};
+
+
+/**
+ * @brief Flag bits indicating if some extended status is available
+ *
+ * @see ::PCPS_TIME_EXT_FLAGS
+ */
+enum PCPS_TIME_EXT_FLAG_BITS
+{
+ PCPS_TIME_EXT_FLAG_BIT_UTC_VALID, ///< ::PCPS_TIME_EXT::utc_offs field is valid
+ N_PCPS_TIME_EXT_FLAG_BITS
+};
+
+
+/**
+ * @brief Flag masks used with ::PCPS_TIME_EXT::flags
+ *
+ * @see ::PCPS_TIME_EXT_FLAG_BITS
+ */
+enum PCPS_TIME_EXT_FLAGS
+{
+ PCPS_TIME_EXT_FLAG_UTC_VALID = ( 1UL << PCPS_TIME_EXT_FLAG_BIT_UTC_VALID ) ///< see ::PCPS_TIME_EXT_FLAG_BIT_UTC_VALID
+};
+
+
+
+_ext const char *str_unknown
+#ifdef _DO_INIT
+ = "unknown"
+#endif
+;
+
+
+_ext const char *str_undefined
+#ifdef _DO_INIT
+ = "(undefined)"
+#endif
+;
+
+
+_ext const char *str_not_spc
+#ifdef _DO_INIT
+ = "not "
+#endif
+;
+
+
+
+_ext const char *mbg_gpio_type_names[N_MBG_GPIO_TYPES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_TYPES_SHORT_STRS
+#endif
+;
+
+#define _get_gpio_type_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_TYPES ) ? mbg_gpio_type_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_port_state_names[N_MBG_GPIO_PORT_STATES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_PORT_STATE_NAMES
+#endif
+;
+
+#define _get_gpio_port_state_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_PORT_STATES ) ? mbg_gpio_port_state_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_signal_shape_names[N_MBG_GPIO_SIGNAL_SHAPES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_SIGNAL_SHAPE_NAMES
+#endif
+;
+
+#define _get_gpio_signal_shape_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_SIGNAL_SHAPES ) ? mbg_gpio_signal_shape_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_fixed_freq_strs[N_MBG_GPIO_FIXED_FREQ]
+#ifdef _DO_INIT
+ = MBG_GPIO_FIXED_FREQ_STRS
+#endif
+;
+
+#define _get_gpio_fixed_freq_str( _i ) \
+ ( ( (_i) < N_MBG_GPIO_FIXED_FREQ ) ? mbg_gpio_fixed_freq_strs[_i] : str_unknown )
+
+
+
+_ext const char *xmr_holdover_status_mode_names[N_XMR_HOLDOVER_STATUS_MODES]
+#ifdef _DO_INIT
+ = XMR_HOLDOVER_STATUS_MODE_NAMES
+#endif
+;
+
+#define _get_xmr_holdover_status_mode_name( _i ) \
+ ( ( (_i) < N_XMR_HOLDOVER_STATUS_MODES ) ? xmr_holdover_status_mode_names[_i] : str_unknown )
+
+
+
+/**
+ * @brief Count the number of bits which are not 0
+ *
+ * @param[in] val Value to be tested
+ *
+ * @return The number of non-zero bits in val
+ */
+static __mbg_inline
+int num_bits_set( long val )
+{
+ int bits_set = 0;
+ int i;
+
+ for ( i = 0; i < ( 8 * sizeof( val ) ); i++ )
+ {
+ if ( val & 1 )
+ bits_set++;
+
+ val >>= 1;
+ }
+
+ return bits_set;
+
+} // num_bits_set
+
+
+
+/* function prototypes: */
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Trim whitespace at the end of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_trailing_whitespace( char *s ) ;
+
+ /**
+ * @brief Trim whitespace at the beginning of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_leading_whitespace( char *s ) ;
+
+ /**
+ * @brief Trim both leading and trailing whitespace from a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_whitespace( char *s ) ;
+
+ /**
+ * @brief Print nano time into string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] len Size of the string buffer, i.e. max length
+ * @param[in] nt The ::NANO_TIME to be printed
+ */
+ int snprint_nano_time( char *s, int len, const NANO_TIME *nt ) ;
+
+ /**
+ * @brief Check if a software revision name should be displayed
+ *
+ * The software revision name is usually empty, except if the
+ * firmware is a customized version, in which case the field
+ * contains an identifier string.
+ *
+ * There are some standard firmware versions where this string
+ * is not empty but padded with spaces, etc., so we try to
+ * clean this up and display the string properly, if appropriate.
+ *
+ * @param[in,out] p The ::SW_REV name to check
+ * @param[in] verbose The app's verbosity level
+ *
+ * @return != 0 if SW name should be displayed
+ */
+ int chk_sw_rev_name( SW_REV *p, int verbose ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _CFG_HLP_H */
diff --git a/mbglib/common/extiohlp.c b/mbglib/common/extiohlp.c
new file mode 100644
index 0000000..064f2ec
--- /dev/null
+++ b/mbglib/common/extiohlp.c
@@ -0,0 +1,275 @@
+
+/**************************************************************************
+ *
+ * $Id: extiohlp.c 1.3.1.4.1.2 2015/01/21 13:24:44Z marvin TEST martin $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Device configuration helper functions. This is an extension to
+ * mbgextio.c providing useful functions to simplify reading/writing
+ * complex device configuration structure sets.
+ *
+ * Warning:
+ * These functions should not be implemented in a DLL / shared library
+ * since the parameter sizes might vary with different versions
+ * of the API calls, which which would make different versions of
+ * precompiled libraries incompatible to each other.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: extiohlp.c $
+ * Revision 1.3.1.4.1.2 2015/01/21 13:24:44Z marvin
+ * Added XBP Adress specifier to mbgextio functions.
+ * Revision 1.3.1.4.1.1 2014/10/31 12:04:45Z martin
+ * Started to support XBP addressing.
+ * Revision 1.3.1.4 2014/10/30 14:50:00 martin
+ * Generally return Meinberg error codes only.
+ * Updated doxygen stuff.
+ * Updated function prototypes.
+ * Revision 1.3.1.3 2013/12/19 09:20:12 martin
+ * Revision 1.3.1.2 2013/12/17 14:57:48Z martin
+ * Revision 1.3.1.1 2013/09/25 11:10:49Z marvin
+ * Added function for all_ptp_cfg_info.
+ * Revision 1.3 2013/02/01 15:49:59Z martin
+ * Updated doxygen comments.
+ * Cleanup.
+ * Revision 1.2 2012/03/09 08:32:58Z martin
+ * Cleanup.
+ * Revision 1.1 2011/09/21 15:59:59 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _EXTIOHLP
+ #include <extiohlp.h>
+#undef _EXTIOHLP
+
+#include <mbggeo.h>
+
+
+
+/*HDR*/
+/**
+ * @brief Read all serial port settings and supported configuration parameters
+ *
+ * @note The function mbgextio_setup_receiver_info() must have been called before,
+ * and the returned ::RECEIVER_INFO has to be passed to this function.
+ *
+ * The complementary function mbgextio_save_serial_settings() should
+ * be used to write a modified port configuration back to the device.
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param p_cfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up
+ * @param p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_get_receiver_info
+ */
+int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr,
+ RECEIVER_PORT_CFG *p_cfg, const RECEIVER_INFO *p_ri )
+{
+ int rc = 0;
+
+ memset( p_cfg, 0, sizeof( *p_cfg ) );
+
+ if ( p_ri->model_code != GPS_MODEL_UNKNOWN )
+ {
+ rc = mbgextio_get_all_port_info( pmctl, p_addr, p_cfg->pii, p_ri );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+ rc = mbgextio_get_all_str_type_info( pmctl, p_addr, p_cfg->stii, p_ri );
+ }
+ else
+ {
+ #if 0 // TODO ##+++++++ provide some symbols
+ uint16_t i;
+
+ rc = mbgextio_get_port_parm( pmctl, p_addr, &p_cfg->tmp_pp );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+ for ( i = 0; i < p_ri->n_com_ports; i++ )
+ {
+ PORT_INFO_IDX *p_pii = &p_cfg->pii[i];
+ PORT_INFO *p_pi = &p_pii->port_info;
+
+ p_pii->idx = i;
+ port_settings_from_port_parm( &p_pi->port_settings,
+ i, &p_cfg->tmp_pp, 1 );
+
+ p_pi->supp_baud_rates = DEFAULT_GPS_BAUD_RATES_C166;
+ p_pi->supp_framings = DEFAULT_GPS_FRAMINGS_C166;
+ p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_GPS;
+ }
+
+ for ( i = 0; i < p_ri->n_str_type; i++ )
+ {
+ STR_TYPE_INFO_IDX *stip = &p_cfg->stii[i];
+ stip->idx = i;
+ stip->str_type_info = default_str_type_info[i];
+ }
+
+ rc = MBG_SUCCESS;
+ #endif
+ }
+
+out:
+ return rc;
+
+} // mbgextio_get_serial_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Send the configuration settings for a single serial port to a device
+ *
+ * @note The function mbgextio_setup_receiver_info() must have been called before,
+ * and the returned ::RECEIVER_INFO has to be passed to this function as well as
+ * to mbgextio_get_serial_settings() which should have been called before to read
+ * the current settings and supported features for each port.
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param pcfg Pointer to a ::RECEIVER_PORT_CFG structure
+ * @param port_idx Index of the serial port to be saved
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_get_receiver_info
+ */
+int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr,
+ const RECEIVER_PORT_CFG *pcfg, uint16_t port_idx )
+{
+ int rc;
+
+ rc = mbgextio_set_port_settings_idx( pmctl, p_addr,
+ &pcfg->pii[port_idx].port_info.port_settings, port_idx );
+
+ return rc; //##++ MBG_SUCCESS or < 0 on error
+
+} // mbgextio_save_serial_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read all PTP configuration in ::ALL_PTP_CFG_INFO format
+ *
+ * @note Only supported if ::GPS_HAS_PTP
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##++++++++++++++++++++++++++++++
+ * @see ::mbgextio_get_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl,
+ XBP_ADDR *p_addr,
+ ALL_PTP_CFG_INFO *p )
+{
+ int rc = mbgextio_get_ptp_cfg_info( pmctl, p_addr, &p->ptp_cfg_info );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+ if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST )
+ {
+ rc = mbgextio_get_ptp_uc_master_cfg_limits( pmctl, p_addr,
+ &p->ptp_uc_master_cfg_limits );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+ if ( p->ptp_uc_master_cfg_limits.n_supp_master > MAX_PARM_PTP_UC_MASTER )
+ {
+ // The number of PTP unicast masters supported by this device
+ // exceeds the number of unicast masters supporterd by this driver.
+ rc = MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP;
+ goto out;
+ }
+
+ rc = mbgextio_get_all_ptp_uc_master_info( pmctl, p_addr,
+ p->all_ptp_uc_master_info_idx, &p->ptp_uc_master_cfg_limits );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+ }
+
+out:
+ return rc;
+
+} // mbgextio_get_all_ptp_cfg_info
+
+
+//#warning mbgextio_save_all_ptp_cfg_settings missing
+
+
+/*HDR*/
+/**
+ * @brief Convert a mathematical angle [rad] to a geographic angle [degree, minute, second]
+ *
+ * @note This has been copied from mbggeo.c, so mbggeo.h should
+ * provide the same prototype.
+ */
+void rad_to_dms( const double *rad, DMS *dms, const char prefix )
+{
+ static const double r2d = 180.0 / PI;
+
+ double r;
+
+ if ( prefix == 'E' )
+ dms->prefix = ( *rad < 0.0 ) ? 'W' : 'E';
+ else
+ dms->prefix = ( *rad < 0.0 ) ? 'S' : 'N';
+
+ r = *rad * r2d;
+
+ if ( r < 0 )
+ r = -r;
+
+ dms->deg = (int) r;
+
+ r -= dms->deg;
+ r *= 60;
+
+ dms->min = (int) r;
+
+ r -= dms->min;
+ r *= 60;
+
+ dms->sec = r;
+
+} /* rad_to_dms */
+
+
+
+/*HDR*/
+/**
+ * @brief Convert mathematic coords to to geographic coords
+ *
+ * Mathematic coords are (longitude, latitude in [rad]), geographic coords
+ * are (longitude, latitude in [degree, minute, second])
+ *
+ * @note This has been copied from mbggeo.c, so mbggeo.h should
+ * provide the same prototype.
+ */
+void lla_to_dms( POS *pos )
+{
+ rad_to_dms( &pos->lla[LON], &pos->longitude, 'E' );
+ rad_to_dms( &pos->lla[LAT], &pos->latitude, 'N' );
+
+} /* lla_to_dms */
+
+
+
diff --git a/mbglib/common/extiohlp.h b/mbglib/common/extiohlp.h
new file mode 100644
index 0000000..27ccd7b
--- /dev/null
+++ b/mbglib/common/extiohlp.h
@@ -0,0 +1,158 @@
+
+/**************************************************************************
+ *
+ * $Id: extiohlp.h 1.3.1.5.1.2 2015/01/21 13:24:47Z marvin TEST martin $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for extiohlp.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: extiohlp.h $
+ * Revision 1.3.1.5.1.2 2015/01/21 13:24:47Z marvin
+ * Added XBP Adress specifier to mbgextio functions.
+ * Revision 1.3.1.5.1.1 2014/10/31 12:03:34Z martin
+ * Started to support XBP addressing.
+ * Revision 1.3.1.5 2014/03/18 11:17:00 gregoire
+ * Revision 1.3.1.4 2014/03/17 14:51:50Z martin
+ * Revision 1.3.1.3 2013/12/19 09:20:12Z martin
+ * Revision 1.3.1.2 2013/12/17 14:57:49Z martin
+ * Revision 1.3.1.1 2013/09/25 11:10:56Z marvin
+ * Added function for all_ptp_cfg_info.
+ * Revision 1.3 2013/02/01 15:52:16Z martin
+ * Updated function prototypes.
+ * Revision 1.2 2012/03/09 08:35:51Z martin
+ * Updated function prototypes.
+ * Revision 1.1 2011/09/21 15:59:59 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _EXTIOHLP_H
+#define _EXTIOHLP_H
+
+
+/* Other headers to be included */
+
+#include <mbgextio.h>
+
+#include <cfg_hlp.h>
+#include <mbgerror.h>
+
+
+#ifdef _EXTIOHLP
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+
+/* function prototypes: */
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Read all serial port settings and supported configuration parameters
+ *
+ * @note The function mbgextio_setup_receiver_info() must have been called before,
+ * and the returned ::RECEIVER_INFO has to be passed to this function.
+ *
+ * The complementary function mbgextio_save_serial_settings() should
+ * be used to write a modified port configuration back to the device.
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param p_cfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up
+ * @param p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_get_receiver_info
+ */
+ int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_PORT_CFG *p_cfg, const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Send the configuration settings for a single serial port to a device
+ *
+ * @note The function mbgextio_setup_receiver_info() must have been called before,
+ * and the returned ::RECEIVER_INFO has to be passed to this function as well as
+ * to mbgextio_get_serial_settings() which should have been called before to read
+ * the current settings and supported features for each port.
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param pcfg Pointer to a ::RECEIVER_PORT_CFG structure
+ * @param port_idx Index of the serial port to be saved
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_get_receiver_info
+ */
+ int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const RECEIVER_PORT_CFG *pcfg, uint16_t port_idx ) ;
+
+ /**
+ * @brief Read all PTP configuration in ::ALL_PTP_CFG_INFO format
+ *
+ * @note Only supported if ::GPS_HAS_PTP
+ *
+ * @param pmctl Pointer to a valid message control structure
+ * @param p_addr Pointer to XBP address specifier
+ * @param p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##++++++++++++++++++++++++++++++
+ * @see ::mbgextio_get_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, ALL_PTP_CFG_INFO *p ) ;
+
+ /**
+ * @brief Convert a mathematical angle [rad] to a geographic angle [degree, minute, second]
+ *
+ * @note This has been copied from mbggeo.c, so mbggeo.h should
+ * provide the same prototype.
+ */
+ void rad_to_dms( const double *rad, DMS *dms, const char prefix ) ;
+
+ /**
+ * @brief Convert mathematic coords to to geographic coords
+ *
+ * Mathematic coords are (longitude, latitude in [rad]), geographic coords
+ * are (longitude, latitude in [degree, minute, second])
+ *
+ * @note This has been copied from mbggeo.c, so mbggeo.h should
+ * provide the same prototype.
+ */
+ void lla_to_dms( POS *pos ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _EXTIOHLP_H */
diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h
index 03d867c..2cbe939 100644
--- a/mbglib/common/gpsdefs.h
+++ b/mbglib/common/gpsdefs.h
@@ -1,18 +1,198 @@
/**************************************************************************
*
- * $Id: gpsdefs.h 1.91 2011/01/31 11:23:56Z martin REL_M $
+ * $Id: gpsdefs.h 1.124 2015/07/14 14:22:46Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* 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
+ * However, more and more Meinberg non-GPS devices also use some of
* these definitions.
*
* -----------------------------------------------------------------------
* $Log: gpsdefs.h $
+ * Revision 1.124 2015/07/14 14:22:46Z martin
+ * Doxygen fix.
+ * Revision 1.123 2015/07/06 13:00:10 martin
+ * Added definitions for VSG180, MSF180, WWVB180, and CPC180.
+ * Added definitions for PZF180.
+ * Definitions for SDI and MDU300 added by stephan.
+ * Definitions for HPS100 added by daniel.
+ * FDM180 and associated definitions added by paul.
+ * Started to support eXtended Binary Protocol (XBP).
+ * Merged daniel and gregoire's changes from the 1.120.2.x branch.
+ * Defines for IPv6 multicast scopes added by gregoire.
+ * XMR_EXT_SRC_INFO and associated XMR_SETTINGS_FLAG_MSKS flags
+ * defined by andre.
+ * Support XMULTI_REF_INFO::n_prio field again.
+ * Fixed _mbg_swab_gpio_cfg_limits() macro.
+ * Added MBG_NET_LINK_OPT_MASK_CAN_SYNCE to MBG_NET_LINK_OPT_MASKS.
+ * New PTP_ROLE_MASKS PTP_ROLE_NTP_SERVER and PTP_ROLE_NTP_CLIENT.
+ * Some PTP profile extensions added by daniel.
+ * Added missing defines for SPT.
+ * Added definitions for REL1000.
+ * Moved structure NANO_TIME_64 here.
+ * Revision 1.122 2014/07/29 08:57:44Z martin
+ * Updated doxygen comments.
+ * Revision 1.121 2014/07/17 09:41:50 martin
+ * Introduced XMR_HOLDOVER_STATUS, MBG_GPIO_STATUS,
+ * and associated definitions.
+ * Huge update and cleanup on doxygen comments.
+ * Revision 1.120 2014/05/27 08:34:40 martin
+ * Fixed braces in some _mbg_rcvr_is_..() macros.
+ * Definitions used with extended network cfg, VST, and SHS.
+ * Introduced XMR_HOLDOVER_STATUS.
+ * Introduced programmable output mode POUT_GPIO.
+ * Introduced oscillator type OCXO_SQ.
+ * Defined some new baud rates.
+ * Defines for IEEE C37.118.1-2011 CTQ.
+ * Support for new model SCG by paul.
+ * Support new model PPG180.
+ * New SCU control masks.
+ * New GNSS flag MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER.
+ * DEFAULT_MULTI_REF_NAMES_SHORT added by udo.
+ * Definitions used for NTP configuration by thomas-b and marvin.
+ * MBG_NET_ADDR structures changed to MBG_IP_ADDR, and
+ * associated symbols defined by marvin.
+ * Huge rework of comments in doxygen format.
+ * Revision 1.119 2013/12/05 10:13:13 daniel
+ * Support new PTP_CFG_FLAGS for 1-step-L2 and 1-step-P2P support
+ * Revision 1.118 2013/11/19 13:38:35 martin
+ * Added LAN_IF_TYPE_RSC.
+ * Revision 1.117 2013/11/18 14:13:39 martin
+ * Support model LNE_GB.
+ * Revision 1.116 2013/11/11 09:46:11 martin
+ * New PTP configuration flags PTP_CFG_SUPP_MCAST_SLAVE_FLAG and
+ * PTP_CFG_CAN_BE_MULTICAST_SLAVE, plus associated bit masks.
+ * New XMR_INST_FLAGS and XMR_INST_FLAG_MASKS defined by andre.
+ * Fixes for big-endian targets.
+ * Updated doxygen comments.
+ * Revision 1.115 2013/10/02 15:19:28 martin
+ * Changed PTP_CFG_SETTINGS::vlan_cfg back to a reserved field,
+ * and removed associated flag and flag mask.
+ * Revision 1.114 2013/09/25 11:02:10 martin
+ * Support models MRI, BPE, GLN180PEX, N2X, RSC180.
+ * Added feature bit GPS_FEAT_NTP.
+ * Enhanced VLAN configuration structures.
+ * Started to support IPv6.
+ * Renamed PTP_CFG_SETTINGS field "profile" to "selected_presets".
+ * Renamed PTP_CFG_INFO field "supp_profiles" to "supp_opt_ext".
+ * New PTP role PTP_ROLE_BOTH_MASTER.
+ * New PTP flag PTP_FLAG_ONE_STEP.
+ * Added some new PTP_CFG_FLAGS flags.
+ * Added PTP_OPT_EXTS and associated definitions.
+ * Added PTP_PRESETS and associated definitions.
+ * Added "tzdl" field to PTP_POWER_PROFILE_CFG.
+ * Made reserved PTP_CFG_SETTINGS field to "opt_ext" field.
+ * Made reserved PTP_CFG_SETTINGS field to "vlan_cfg" field.
+ * Made reserved PTP_STATE field to "parent_clock_class" and "parent_clock_accuracy".
+ * Definitions for MULTI_REF_EXT_OSC added by Andre.
+ * String initializers for supported HaveQuick formats added by Gregoire.
+ * Lots of doxygen changes.
+ * Revision 1.113 2013/04/04 09:02:01Z martin
+ * Added definitions to support HaveQuick.
+ * Fixed a typo.
+ * Revision 1.112 2013/02/19 15:39:13 martin
+ * New PTP settings field ann_rcpt_timeout and associated
+ * values PTP_ANN_RCPT_TIMEOUT_LIMITS.
+ * Changed many defines to named enums to simplify references
+ * with doxygen.
+ * Updated doxygen comments.
+ * Revision 1.111 2013/02/01 15:37:36 martin
+ * Added and modified a huge number of doxygen comments.
+ * Revision 1.110 2013/01/16 15:23:25 martin
+ * Fixed 2 comments which were interchanged.
+ * Revision 1.109 2013/01/11 10:39:34 martin
+ * Added definitions for IMS.
+ * Support XMR_HOLDOVER_INTV.
+ * New XMRS status bit XMRS_BIT_LOW_JITTER / XMRS_MSK_LOW_JITTER.
+ * Added framing type 8E2, though most UARTs don't support this.
+ * Added enum names and updated comments for doxygen.
+ * Revision 1.108 2012/10/30 11:31:16 martin
+ * Defined PTP_UC_MSG_DURATION_MIN and PTP_UC_MSG_DURATION_MAX.
+ * Fixed some doxygen comments.
+ * Changes by andre: changed reserved field to ssm and boc in BITS_OUT settings.
+ * Revision 1.107 2012/10/12 07:40:12 martin
+ * New PTP state flags PTP_FLAG_MSK_UTC_VALID and
+ * PTP_CFG_MSK_SUPP_UTC_VALID.
+ * Revision 1.106 2012/10/02 18:22:10 martin
+ * Added default baud rate and framing for binary protocol.
+ * Added definitions for IRIG codes E002/E112 and NASA36.
+ * Reworked GPIO structures.
+ * Added definitions for GRC, LIU, DCF600RS, and DCF600HS.
+ * New flag POUT_FIXED_PULSE_LEN.
+ * New flag POUT_NOT_INVERTIBLE.
+ * Unified capitalization in MBG_XMRS_STATUS_STRS.
+ * Revision 1.105 2012/06/01 16:31:16 martin
+ * Some TIME_SLOT definitions added by marvin.
+ * Moved some PTP configuration defaults and limits to ptpdflts.h.
+ * Revision 1.104 2012/04/11 16:02:55Z martin
+ * Fixed some doxygen comments.
+ * Revision 1.103 2012/04/02 11:08:57Z martin
+ * Extended description of GPS UTC/leap second data.
+ * Revision 1.102 2012/03/16 11:43:31 martin
+ * Fixed a potential compiler warning.
+ * Revision 1.101 2012/03/06 16:56:01Z martin
+ * Added support for PTP multicast auto role.
+ * Merged Daniel's definitions for PTP profile support.
+ * Support time slot mode for programmable pulse outputs.
+ * Support LNO180.
+ * Moved definition of MBG_MAC_ADDR here.
+ * Use MBG_MAC_ADDR in definition of LAN_IF_INFO.
+ * Revision 1.100 2012/01/17 13:33:55 martin
+ * Added new IRIG RX delay compensation code groups for G0xx and G1xx codes.
+ * As a consequence the value of N_IRIG_RX_COMP has changed.
+ * Added definition of IRIG_RX_COMP_MAX.
+ * Updated IRIG code classification macros.
+ * Removed obsolete/unused definition of CAL_REC_INFO.
+ * Added some comments.
+ * Revision 1.99 2011/12/09 09:22:03 martin
+ * Fixed a typo.
+ * Revision 1.98 2011/11/25 14:58:34 martin
+ * Renamed some evt_log definitions.
+ * Revision 1.97 2011/11/25 10:11:17 martin
+ * Initializers for XMRS status bit strings added by gregoire.
+ * New feature GPS_FEAT_EVT_LOG.
+ * Added definitions used with event logs.
+ * Moved cal_reg and gen_io stuff here.
+ * Added macro _mbg_swab_debug_status().
+ * Updated some comments.
+ * Revision 1.96 2011/10/11 13:40:46Z andre
+ * changed reserved field into slot_id in XMULTI_REF_INSTANCES
+ * Revision 1.95.1.1 2011/10/07 09:31:58Z andre
+ * Revision 1.95 2011/10/04 09:35:41Z martin
+ * Added support for ESI180.
+ * Changed RECEIVER_INFO::flags bit GPS_10MHZ_DISBD to a RECEIVER_INFO::features bit.
+ * Support MULTI_REF_INTERNAL, MULTI_REF_LWR and MULTI_REF_PZF.
+ * Added MBG_GPIO_BITS structure and associated definitions.
+ * Revision 1.94 2011/08/25 07:42:43Z martin
+ * Fixed a bug in macro _mbg_swab_pout_settings() where the 16 bit timeout
+ * field was swapped using a macro for 32 bit types.
+ * Use shorter names for some PTP unicast master default values.
+ * Revision 1.93 2011/08/10 08:19:38Z martin
+ * New PORT_INFO and PORT_SETTINGS flag PORT_FLAG_PORT_INVISIBLE.
+ * Revision 1.92 2011/07/29 09:49:35 martin
+ * Support PZF180PEX, MGR180, MSF600, WWVB600, JJY600,
+ * GPS180HS, and GPS180AMC.
+ * Added receiver info features GPS_FEAT_PTP_UNICAST
+ * and GPS_FEAT_XMRS_MULT_INSTC.
+ * Added receiver info flag bit GPS_10MHZ_DISBD.
+ * Added initializers for PTP timescale names.
+ * New PTP_STATE flags bit PTP_FLAG_MSK_IS_UNICAST.
+ * Made unused PTP_STATE fields num_clients and num_masters reserved.
+ * Account for different PTP roles.
+ * Added / renamed some definitions for PTP.
+ * Modified default string for PTP layer 2 protocol.
+ * Support PTP unicast configuration.
+ * Support GPIO configuration.
+ * Introduced XMULTI_REF_INSTANCES.
+ * Moved flags XMRS_..._IS_EXTERNAL and XMRS_..._INSTC_EXCEEDED
+ * to definitions for XMULTI_REF_STATUS::status.
+ * Some comments added, updated, and converted to doxygen style.
+ * Cleaned up handling of pragma pack().
+ * Removed trailing whitespace and hard tabs.
* Revision 1.91 2011/01/31 11:23:56Z martin
* Added model type name definitions for GPS180PEX and TCR180PEX.
* Introduced synthesizer mode for programmable outputs.
@@ -38,7 +218,7 @@
* Added support for new model GLN170.
* Revision 1.87 2010/03/10 11:29:37Z martin
* Added definitions for GPS180.
- * Added multiref source 1 PPS plus associated string.
+ * Added multi ref source 1 PPS plus associated string.
* Revision 1.86 2010/02/17 14:16:42 martin
* Added definitions for PZF600 and TCR600.
* Revision 1.85 2010/02/15 11:34:36 martin
@@ -53,10 +233,10 @@
* Revision 1.81 2009/11/09 09:08:24 martin
* New TM_GPS status bit TM_INVT.
* Added definitions to support VLAN.
- * Changed DEFAULT_PTP_DELAY_MECH_MASK to include also
+ * Changed DEFAULT_PTP_DELAY_MECH_MASK to include also
* PTP_DELAY_MECH_MSK_P2P.
* There is now only one type of TCXO supported which matches the former
- * TCXO HQ, so the default name for TCXO HQ has been changed to TCXO.
+ * TCXO HQ, so the default name for TCXO HQ has been changed to TCXO.
* TCXO LQ and MQ names are still supported for backward compatibility.
* Revision 1.80 2009/09/28 14:55:53 martin
* Support IRIG formats G002/G142 and G006/G146.
@@ -73,7 +253,7 @@
* 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
+ * Added preliminary structures and definitions for PTP
* configuration and state.
* Added IP4_ADDR type.
* Added Bitmask IP4_MSK_DHCP.
@@ -86,7 +266,7 @@
* 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
+ * 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
@@ -108,7 +288,7 @@
* 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.
+ * Added multi ref 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
@@ -130,7 +310,7 @@
* 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 multi ref 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.
@@ -162,7 +342,7 @@
* 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
+ * 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.
@@ -183,7 +363,7 @@
* Added ROM_CSUM, RCV_TIMEOUT, and IGNORE_LOCK types.
* Revision 1.44 2006/05/18 09:34:41Z martin
* Added definitions for POUT max. pulse_len and max timeout.
- * Changed comment for POUT_SETTINGS::timeout:
+ * Changed comment for POUT_SETTINGS::timeout.
* Units are minutes, not seconds.
* Added definition for MAX_POUT_TIME_STR_PORTS.
* Added definitions for POUT mode 10MHz.
@@ -234,7 +414,7 @@
* Added definitions OSC_DAC_RANGE, OSC_DAC_BIAS.
* Revision 1.27 2004/03/08 14:06:45Z martin
* New model code and name for GPS169PCI.
- * Existing feature GPS_FEAT_IRIG has been
+ * Existing feature GPS_FEAT_IRIG has been
* renamed to GPS_FEAT_IRIG_TX.
* Added feature GPS_FEAT_IRIG_RX.
* Added IPv4 LAN interface feature flags.
@@ -256,7 +436,7 @@
* Revision 1.20 2003/04/03 11:03:44Z martin
* Extended definitions for IRIG support.
* Revision 1.19 2003/01/31 13:38:20 MARTIN
- * Modified type of RECEIVER_INFO.fixed_freq field.
+ * Modified type of RECEIVER_INFO::fixed_freq field.
* Revision 1.18 2002/10/28 09:24:07 MARTIN
* Added/renamed some POUT related symbols.
* Revision 1.17 2002/09/05 10:58:39 MARTIN
@@ -319,7 +499,7 @@
#include <config.h>
#endif
-// CLOCK_MEINBERG is defined in NTP's config.h if configured
+// 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
@@ -328,19 +508,44 @@
#endif
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
+/* Start of header body */
+
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
#endif
-/* Start of header body */
/* "magic" number */
#define MEINBERG_MAGIC 0x6AAC
-#define MIN_SVNO 1 /* min. SV number */
-#define MAX_SVNO 32 /* max. SV number */
-#define N_SVNO ( MAX_SVNO - MIN_SVNO + 1) /* number of possibly active SVs */
+/**
+ * @brief GNSS satellite numbers
+ *
+ * @todo: Check if MAX_SVNO_GLN is 94 instead of 95, and thus
+ * N_SVNO_GLN is 30 instead of 31, as reported by Wikipedia.
+ */
+enum GNSS_SVNOS
+{
+ MIN_SVNO_GPS = 1, ///< min. GPS satellite PRN number
+ MAX_SVNO_GPS = 32, ///< max. GPS satellite PRN number
+ N_SVNO_GPS = 32, ///< max. number of active GPS satellites
+
+ MIN_SVNO_WAAS = 33, ///< min. WAAS satellite number
+ MAX_SVNO_WAAS = 64, ///< max. WAAS satellite number
+ N_SVNO_WAAS = 32, ///< max. number of active WAAS satellites
+
+ MIN_SVNO_GLONASS = 65, ///< min. Glonass satellite number (64 + sat slot ID)
+ MAX_SVNO_GLONASS = 95, ///< max. Glonass satellite number (64 + sat slot ID)
+ N_SVNO_GLONASS = 31 ///< max. number of active Glonass satellites
+};
+
+// for compatibility with GPS-only software:
+#define MIN_SVNO MIN_SVNO_GPS ///< min. SV number
+#define MAX_SVNO MAX_SVNO_GPS ///< max. SV number
+#define N_SVNO N_SVNO_GPS ///< number of possibly active SVs
+
#define GPS_ID_STR_LEN 16
@@ -350,29 +555,30 @@
#define GPS_EPLD_STR_SIZE ( GPS_EPLD_STR_LEN + 1 )
-#define DEFAULT_GPS_TICKS_PER_SEC 10000000L /* system time base */
+#define DEFAULT_GPS_TICKS_PER_SEC 10000000L ///< system time base, see ::GPS_TICKS_PER_SEC
#if !defined( GPS_TICKS_PER_SEC )
/*
* The actual ticks per seconds may vary for different
* GPS receiver models. If this is the case, the receiver
- * model support the RECEIVER_INFO structure which contains
+ * model support the ::RECEIVER_INFO structure which contains
* the actual value.
*/
- #define GPS_TICKS_PER_SEC DEFAULT_GPS_TICKS_PER_SEC
+ #define GPS_TICKS_PER_SEC DEFAULT_GPS_TICKS_PER_SEC ///< see ::DEFAULT_GPS_TICKS_PER_SEC
+
#endif
-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 */
+typedef uint16_t SVNO; ///< the number of an SV (Space Vehicle, i.e. satellite)
+typedef uint16_t HEALTH; ///< an SV's 6 bit health code
+typedef uint16_t CFG; ///< an SV's 4 bit configuration code
+typedef uint16_t IOD; ///< Issue-Of-Data code
/* the type of various checksums */
#ifndef _CSUM_DEFINED
- typedef uint16_t CSUM;
+ typedef uint16_t CSUM; ///< checksum used by some structures stored in non-volatile memory
#define _CSUM_DEFINED
#define _mbg_swab_csum( _p ) _mbg_swab16( _p )
@@ -382,9 +588,8 @@ typedef uint16_t IOD; /* Issue-Of-Data code */
/**
* @brief The type of a GPS command code
*
- * These command codes can be passed via
- * @ref gps_cmds_serial "serial port" (see @file gpsserio.h), or
- * @ref gps_cmds_bus "system bus" (see @file pcpsdefs.h).
+ * @see ::GPS_CMD_CODES
+ * @see ::PC_GPS_CMD_CODES
*/
typedef uint16_t GPS_CMD;
@@ -399,9 +604,10 @@ typedef uint16_t GPS_CMD;
*/
typedef struct
{
- uint16_t code; /**< Version number, e.g. 0x0120 means v1.20 */
- char name[GPS_ID_STR_SIZE]; /**< Optional string identifying a customized version */
- uint8_t reserved; /**< Reserved field to yield even structure size */
+ uint16_t code; ///< Version number, e.g. 0x0120 means v1.20
+ char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized version
+ uint8_t reserved; ///< Reserved field to yield even structure size
+
} SW_REV;
#define _mbg_swab_sw_rev( _p ) \
@@ -412,7 +618,7 @@ typedef struct
/**
- * @defgroup bvar_stat BVAR_STAT status of buffered GPS data
+ * @defgroup group_bvar_stat Status of buffered (non-volatile) data
*
* Status word, associated bit numbers and bit masks indicating
* whether certain data from the GPS satellites are
@@ -424,49 +630,96 @@ typedef struct
* @{ */
/**
- * @brief Status flags of battery buffered data received
- * from GPS satellites.
+ * @brief Status flags of battery buffered data
+ *
+ * Related to data received from the satellites, or data derived thereof.
*
* All '0' means OK, single bits set to '1' indicate
* the associated type of GPS data is not available.
+ *
+ * @see ::BVAR_FLAGS
*/
typedef uint16_t BVAR_STAT;
#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) )
-/** @brief Enumeration of bits used with BVAR_STAT */
-enum
+/**
+ * @brief Enumeration of flag bits used to define ::BVAR_FLAGS
+ *
+ * For each bit which is set this means the associated data set in
+ * non-volatile memory is not available, or incomplete.
+ * Most data sets will just be re-collected from the data streams sent
+ * by the satellites. However, the receiver position has usually been
+ * computed earlier during normal operation, and will be re-computed
+ * when a sufficient number of satellites can be received.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAGS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAG_BITS
{
- BVAR_BIT_CFGH_INVALID,
- BVAR_BIT_ALM_NOT_COMPLETE,
- BVAR_BIT_UTC_INVALID,
- BVAR_BIT_IONO_INVALID,
- BVAR_BIT_RCVR_POS_INVALID,
- N_BVAR_BIT /**< @brief number of defined ::BVAR_STAT bits */
+ BVAR_BIT_CFGH_INVALID, ///< Satellite configuration and health parameters incomplete
+ BVAR_BIT_ALM_NOT_COMPLETE, ///< Almanac parameters incomplete
+ BVAR_BIT_UTC_INVALID, ///< %UTC offset parameters incomplete
+ BVAR_BIT_IONO_INVALID, ///< Ionospheric correction parameters incomplete
+ BVAR_BIT_RCVR_POS_INVALID, ///< No valid receiver position available
+ N_BVAR_BIT ///< number of defined ::BVAR_STAT bits
};
-#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID ) /**< @brief ::CFGH not valid*/
-#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ) /**< @brief ::ALM not complete */
-#define BVAR_UTC_INVALID ( 1UL << BVAR_BIT_UTC_INVALID ) /**< @brief UTC data not valid */
-#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID ) /**< @brief IONO data not valid */
-#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID ) /**< @brief ::POS not valid */
-
-#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) /**< @brief Bit mask for all defined bits */
-/** @} */
+/**
+ * @brief Bit masks associated with ::BVAR_FLAG_BITS
+ *
+ * Used with ::BVAR_STAT.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAG_BITS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAGS
+{
+ BVAR_CFGH_INVALID = ( 1UL << BVAR_BIT_CFGH_INVALID ), ///< see ::BVAR_BIT_CFGH_INVALID
+ BVAR_ALM_NOT_COMPLETE = ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ), ///< see ::BVAR_BIT_ALM_NOT_COMPLETE
+ BVAR_UTC_INVALID = ( 1UL << BVAR_BIT_UTC_INVALID ), ///< see ::BVAR_BIT_UTC_INVALID
+ BVAR_IONO_INVALID = ( 1UL << BVAR_BIT_IONO_INVALID ), ///< see ::BVAR_BIT_IONO_INVALID
+ BVAR_RCVR_POS_INVALID = ( 1UL << BVAR_BIT_RCVR_POS_INVALID ), ///< see ::BVAR_BIT_RCVR_POS_INVALID
+};
+#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) ///< Bit mask for all defined bits
/**
- A structure used to hold a fixed frequency value.
- frequ[kHz] = khz_val * 10^range
-*/
+ * @brief String initializer for ::BVAR_STAT flag names
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAG_BITS
+ * @see ::BVAR_FLAGS
+ */
+#define BVAR_FLAG_NAMES \
+{ \
+ "Sat. config and health", \
+ "Almanac", \
+ "UTC offset", \
+ "Ionospheric correction", \
+ "Receiver position" \
+}
+
+/** @} defgroup group_bvar_stat */
+
+
+/**
+ * @brief A structure used to hold a fixed frequency value
+ *
+ * @note frequ[kHz] = khz_val * 10^range
+ */
typedef struct
{
- uint16_t khz_val; /* the base frequency in [kHz] */
- int16_t range; /* an optional base 10 exponent */
+ uint16_t khz_val; ///< the base frequency in [kHz]
+ int16_t range; ///< an optional base 10 exponent
+
} FIXED_FREQ_INFO;
#define _mbg_swab_fixed_freq_info( _p ) \
@@ -476,38 +729,37 @@ typedef struct
}
-typedef uint32_t RI_FEATURES; // type of RECEIVER_INFO::features field
+/**
+ * @brief A data type to specify feature flags within ::RECEIVER_INFO
+ */
+typedef uint32_t RI_FEATURES; ///< see @ref GPS_FEATURE_MASKS
-/*
- * The following code defines features and properties
- * of the various GPS receivers. Older GPS receivers
- * may require a recent firmvare version to support
- * 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 */
- RI_FEATURES features; /**< optional features, see below */
- FIXED_FREQ_INFO fixed_freq; /**< optional non-standard fixed frequency */
- uint8_t osc_type; /**< type of installed oscillator, see below */
- uint8_t osc_flags; /**< oscillator flags, see below */
- 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 */
+
+/**
+ * @brief A structure used to identify a device type and supported features
+ *
+ * @note This may not be supported by some very old devices.
+ */
+typedef struct
+{
+ uint16_t model_code; ///< identifier for receiver model, see ::GPS_MODEL_CODES
+ 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 (optional)
+ uint8_t n_channels; ///< number of satellites which can be tracked simultaneously
+ uint32_t ticks_per_sec; ///< resolution of fractions of seconds, see ::GPS_TICKS_PER_SEC
+ RI_FEATURES features; ///< optional features, see @ref GPS_FEATURE_MASKS
+ FIXED_FREQ_INFO fixed_freq; ///< optional non-standard fixed frequency, may be 0 if not supported
+ uint8_t osc_type; ///< type of installed oscillator, see ::GPS_OSC_TYPES
+ uint8_t osc_flags; ///< oscillator flags, actually not used and always 0
+ 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 ::RECEIVER_INFO_FLAG_BITS
+
} RECEIVER_INFO;
#define _mbg_swab_receiver_info( _p ) \
@@ -522,9 +774,12 @@ typedef struct
/**
- * Valid codes for RECEIVER_INFO.model_code:
+ * @brief Known device ID codes for ::RECEIVER_INFO::model_code
+ *
+ * @see @ref GPS_MODEL_NAMES
+ * @see ::DEFAULT_GPS_MODEL_NAMES
*/
-enum
+enum GPS_MODEL_CODES
{
GPS_MODEL_UNKNOWN,
GPS_MODEL_GPS166,
@@ -560,20 +815,60 @@ enum
GPS_MODEL_GLN170,
GPS_MODEL_GPS180PEX,
GPS_MODEL_TCR180PEX,
+ GPS_MODEL_PZF180PEX,
+ GPS_MODEL_MGR180,
+ GPS_MODEL_MSF600,
+ GPS_MODEL_WWVB600,
+ GPS_MODEL_JJY600,
+ GPS_MODEL_GPS180HS,
+ GPS_MODEL_GPS180AMC,
+ GPS_MODEL_ESI180,
+ GPS_MODEL_CPE180,
+ GPS_MODEL_LNO180,
+ GPS_MODEL_GRC180,
+ GPS_MODEL_LIU,
+ GPS_MODEL_DCF600HS,
+ GPS_MODEL_DCF600RS,
+ GPS_MODEL_MRI,
+ GPS_MODEL_BPE,
+ GPS_MODEL_GLN180PEX,
+ GPS_MODEL_N2X,
+ GPS_MODEL_RSC180,
+ GPS_MODEL_LNE_GB,
+ GPS_MODEL_PPG180,
+ GPS_MODEL_SCG,
+ GPS_MODEL_MDU300,
+ GPS_MODEL_SDI,
+ GPS_MODEL_FDM180,
+ GPS_MODEL_SPT,
+ GPS_MODEL_PZF180,
+ GPS_MODEL_REL1000,
+ GPS_MODEL_HPS100,
+ GPS_MODEL_VSG180,
+ GPS_MODEL_MSF180,
+ GPS_MODEL_WWVB180,
+ GPS_MODEL_CPC180,
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. */
+ /* If new model codes are added then care must be taken
+ * to update the associated string initializers GPS_MODEL_NAMES
+ * and GPS_MODEL_NAME_TABLE accordingly, and to check whether
+ * the classification macros also cover the new model names.
+ */
};
+/**
+ * @brief Model name strings used with Meinberg devices
+ *
+ * String initializers for each of the device models
+ * enumerated in ::GPS_MODEL_CODES.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::DEFAULT_GPS_MODEL_NAMES
+ *
+ * @anchor GPS_MODEL_NAMES @{ */
-/*
- * String initializers for each of the GPS
- * receiver models enum'ed above:
- */
#define GPS_MODEL_NAME_UNKNOWN "(unknown)"
#define GPS_MODEL_NAME_GPS166 "GPS166"
#define GPS_MODEL_NAME_GPS167 "GPS167"
@@ -608,13 +903,55 @@ enum
#define GPS_MODEL_NAME_GLN170 "GLN170"
#define GPS_MODEL_NAME_GPS180PEX "GPS180PEX"
#define GPS_MODEL_NAME_TCR180PEX "TCR180PEX"
+#define GPS_MODEL_NAME_PZF180PEX "PZF180PEX"
+#define GPS_MODEL_NAME_MGR180 "MGR180"
+#define GPS_MODEL_NAME_MSF600 "MSF600"
+#define GPS_MODEL_NAME_WWVB600 "WWVB600"
+#define GPS_MODEL_NAME_JJY600 "JJY600"
+#define GPS_MODEL_NAME_GPS180HS "GPS180HS"
+#define GPS_MODEL_NAME_GPS180AMC "GPS180AMC"
+#define GPS_MODEL_NAME_ESI180 "ESI180"
+#define GPS_MODEL_NAME_CPE180 "CPE180"
+#define GPS_MODEL_NAME_LNO180 "LNO180"
+#define GPS_MODEL_NAME_GRC180 "GRC180"
+#define GPS_MODEL_NAME_LIU "LIU"
+#define GPS_MODEL_NAME_DCF600HS "DCF600HS"
+#define GPS_MODEL_NAME_DCF600RS "DCF600RS"
+#define GPS_MODEL_NAME_MRI "MRI"
+#define GPS_MODEL_NAME_BPE "BPE"
+#define GPS_MODEL_NAME_GLN180PEX "GLN180PEX"
+#define GPS_MODEL_NAME_N2X "N2X"
+#define GPS_MODEL_NAME_RSC180 "RSC180"
+#define GPS_MODEL_NAME_LNE_GB "LNE_GB"
+#define GPS_MODEL_NAME_PPG180 "PPG180"
+#define GPS_MODEL_NAME_SCG "SCG"
+#define GPS_MODEL_NAME_MDU300 "MDU300"
+#define GPS_MODEL_NAME_SDI "SDI"
+#define GPS_MODEL_NAME_FDM180 "FDM180"
+#define GPS_MODEL_NAME_SPT "SPT"
+#define GPS_MODEL_NAME_PZF180 "PZF180"
+#define GPS_MODEL_NAME_REL1000 "REL1000"
+#define GPS_MODEL_NAME_HPS100 "HPS100"
+#define GPS_MODEL_NAME_VSG180 "VSG180"
+#define GPS_MODEL_NAME_MSF180 "MSF180"
+#define GPS_MODEL_NAME_WWVB180 "WWVB180"
+#define GPS_MODEL_NAME_CPC180 "CPC180"
+
+/** @} anchor GPS_MODEL_NAMES */
-/*
- * The definition below can be used to initialize
- * an array of N_GPS_MODEL type name strings.
- * Including the trailing 0, each name must not
- * exceed GPS_ID_STR_SIZE chars.
+
+/**
+ * @brief An initializer for a table of device names
+ *
+ * Can be used to initialize an array of ::N_GPS_MODEL
+ * type name strings.
+ *
+ * @note Including the trailing 0, each name must not
+ * exceed ::GPS_ID_STR_SIZE chars.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_NAMES
*/
#define DEFAULT_GPS_MODEL_NAMES \
{ \
@@ -651,23 +988,455 @@ enum
GPS_MODEL_NAME_GPS180, \
GPS_MODEL_NAME_GLN170, \
GPS_MODEL_NAME_GPS180PEX, \
- GPS_MODEL_NAME_TCR180PEX \
+ GPS_MODEL_NAME_TCR180PEX, \
+ GPS_MODEL_NAME_PZF180PEX, \
+ GPS_MODEL_NAME_MGR180, \
+ GPS_MODEL_NAME_MSF600, \
+ GPS_MODEL_NAME_WWVB600, \
+ GPS_MODEL_NAME_JJY600, \
+ GPS_MODEL_NAME_GPS180HS, \
+ GPS_MODEL_NAME_GPS180AMC, \
+ GPS_MODEL_NAME_ESI180, \
+ GPS_MODEL_NAME_CPE180, \
+ GPS_MODEL_NAME_LNO180, \
+ GPS_MODEL_NAME_GRC180, \
+ GPS_MODEL_NAME_LIU, \
+ GPS_MODEL_NAME_DCF600HS, \
+ GPS_MODEL_NAME_DCF600RS, \
+ GPS_MODEL_NAME_MRI, \
+ GPS_MODEL_NAME_BPE, \
+ GPS_MODEL_NAME_GLN180PEX, \
+ GPS_MODEL_NAME_N2X, \
+ GPS_MODEL_NAME_RSC180, \
+ GPS_MODEL_NAME_LNE_GB, \
+ GPS_MODEL_NAME_PPG180, \
+ GPS_MODEL_NAME_SCG, \
+ GPS_MODEL_NAME_MDU300, \
+ GPS_MODEL_NAME_SDI, \
+ GPS_MODEL_NAME_FDM180, \
+ GPS_MODEL_NAME_SPT, \
+ GPS_MODEL_NAME_PZF180, \
+ GPS_MODEL_NAME_REL1000, \
+ GPS_MODEL_NAME_HPS100, \
+ GPS_MODEL_NAME_VSG180, \
+ GPS_MODEL_NAME_MSF180, \
+ GPS_MODEL_NAME_WWVB180, \
+ GPS_MODEL_NAME_CPC180 \
+}
+
+
+
+/**
+ * @brief Definitions used to classify devices and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::GPS_BUILTIN_FEATURE_BITS
+ * @see @ref GPS_BUILTIN_FEATURE_MASKS
+ *
+ * @anchor GPS_BUILTIN_FEATURE_DEFS @{ */
+
+
+/**
+ * @brief Enumeration of classifiers and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_BUILTIN_FEATURE_MASKS
+ */
+enum GPS_BUILTIN_FEATURE_BITS
+{
+ GPS_BIT_MODEL_IS_GPS,
+ GPS_BIT_MODEL_IS_GNSS,
+ GPS_BIT_MODEL_IS_TCR,
+ GPS_BIT_MODEL_IS_DCF_AM,
+ GPS_BIT_MODEL_IS_DCF_PZF,
+ GPS_BIT_MODEL_IS_MSF,
+ GPS_BIT_MODEL_IS_JJY,
+ GPS_BIT_MODEL_IS_WWV,
+
+ GPS_BIT_MODEL_IS_LNO,
+ GPS_BIT_MODEL_IS_SCU,
+
+ GPS_BIT_MODEL_HAS_BVAR_STAT,
+ GPS_BIT_MODEL_HAS_POS_XYZ,
+ GPS_BIT_MODEL_HAS_POS_LLA,
+ GPS_BIT_MODEL_HAS_TZDL,
+ GPS_BIT_MODEL_HAS_ANT_INFO,
+ GPS_BIT_MODEL_HAS_ENABLE_FLAGS,
+ GPS_BIT_MODEL_HAS_STAT_INFO,
+ GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH,
+ GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK,
+ GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV,
+ GPS_BIT_MODEL_HAS_GNSS_MODE,
+
+ N_GPS_BIT_MODEL
+};
+
+
+
+/**
+ * @brief Bit masks associated with classifiers and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::GPS_BUILTIN_FEATURE_BITS
+ *
+ * @anchor GPS_BUILTIN_FEATURE_MASKS @{ */
+
+#define GPS_MODEL_IS_GPS ( 1UL << GPS_BIT_MODEL_IS_GPS ) ///< see ::GPS_BIT_MODEL_IS_GPS
+#define GPS_MODEL_IS_GNSS ( 1UL << GPS_BIT_MODEL_IS_GNSS ) ///< see ::GPS_BIT_MODEL_IS_GNSS
+#define GPS_MODEL_IS_TCR ( 1UL << GPS_BIT_MODEL_IS_TCR ) ///< see ::GPS_BIT_MODEL_IS_TCR
+#define GPS_MODEL_IS_DCF_AM ( 1UL << GPS_BIT_MODEL_IS_DCF_AM ) ///< see ::GPS_BIT_MODEL_IS_DCF_AM
+#define GPS_MODEL_IS_DCF_PZF ( 1UL << GPS_BIT_MODEL_IS_DCF_PZF ) ///< see ::GPS_BIT_MODEL_IS_DCF_PZF
+#define GPS_MODEL_IS_MSF ( 1UL << GPS_BIT_MODEL_IS_MSF ) ///< see ::GPS_BIT_MODEL_IS_MSF
+#define GPS_MODEL_IS_JJY ( 1UL << GPS_BIT_MODEL_IS_JJY ) ///< see ::GPS_BIT_MODEL_IS_JJY
+#define GPS_MODEL_IS_WWV ( 1UL << GPS_BIT_MODEL_IS_WWV ) ///< see ::GPS_BIT_MODEL_IS_WWV
+
+#define GPS_MODEL_IS_LNO ( 1UL << GPS_BIT_MODEL_IS_LNO ) ///< see ::GPS_BIT_MODEL_IS_LNO
+#define GPS_MODEL_IS_SCU ( 1UL << GPS_BIT_MODEL_IS_SCU ) ///< see ::GPS_BIT_MODEL_IS_SCU
+
+#define GPS_MODEL_HAS_BVAR_STAT ( 1UL << GPS_BIT_MODEL_HAS_BVAR_STAT ) ///< see ::GPS_BIT_MODEL_HAS_BVAR_STAT
+#define GPS_MODEL_HAS_POS_XYZ ( 1UL << GPS_BIT_MODEL_HAS_POS_XYZ ) ///< see ::GPS_BIT_MODEL_HAS_POS_XYZ
+#define GPS_MODEL_HAS_POS_LLA ( 1UL << GPS_BIT_MODEL_HAS_POS_LLA ) ///< see ::GPS_BIT_MODEL_HAS_POS_LLA
+#define GPS_MODEL_HAS_TZDL ( 1UL << GPS_BIT_MODEL_HAS_TZDL ) ///< see ::GPS_BIT_MODEL_HAS_TZDL
+#define GPS_MODEL_HAS_ANT_INFO ( 1UL << GPS_BIT_MODEL_HAS_ANT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_ANT_INFO
+#define GPS_MODEL_HAS_ENABLE_FLAGS ( 1UL << GPS_BIT_MODEL_HAS_ENABLE_FLAGS ) ///< see ::GPS_BIT_MODEL_HAS_ENABLE_FLAGS
+#define GPS_MODEL_HAS_STAT_INFO ( 1UL << GPS_BIT_MODEL_HAS_STAT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_STAT_INFO
+#define GPS_MODEL_HAS_ANT_CABLE_LENGTH ( 1UL << GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH ) ///< see ::GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH
+#define GPS_MODEL_HAS_GPS_IGNORE_LOCK ( 1UL << GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK ) ///< see ::GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK
+#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV ( 1UL << GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV ) ///< see ::GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV
+
+#define GPS_MODEL_HAS_GNSS_MODE ( 1UL << GPS_BIT_MODEL_HAS_GNSS_MODE ) ///< see ::GPS_BIT_MODEL_HAS_GNSS_MODE
+
+//##+++++ TODO: should we use an extra flag?
+#define GPS_MODEL_HAS_POS ( GPS_MODEL_HAS_POS_XYZ | GPS_MODEL_HAS_POS_LLA )
+
+/** @} anchor GPS_BUILTIN_FEATURE_MASKS */
+
+
+#if 0 //##++ more potential builtin features and classifiers
+
+ GPS_MODEL_HAS_CFGH | \
+ GPS_MODEL_HAS_ALM | \
+ GPS_MODEL_HAS_EPH | \
+ GPS_MODEL_HAS_UTC | \
+ GPS_MODEL_HAS_IONO \
+
+#define GPS_MODEL_HAS_AUTO_ON // --
+#define GPS_MODEL_HAS_AUTO_OFF // --
+#define GPS_MODEL_HAS_SW_REV // deprecated, use only if ri not supported
+#define GPS_MODEL_HAS_BVAR_STAT // req
+#define GPS_MODEL_HAS_TIME // ?
+#define GPS_MODEL_HAS_POS_XYZ // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_XYZ ?
+#define GPS_MODEL_HAS_POS_LLA // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_LLA ?
+#define GPS_MODEL_HAS_TZDL // req
+#define GPS_MODEL_HAS_PORT_PARM // deprecated, use only if ri not supported
+#define GPS_MODEL_HAS_SYNTH // ri GPS_HAS_SYNTH
+#define GPS_MODEL_HAS_ANT_INFO // GPS_MODEL_IS_GPS, also GNSS, or req?
+#define GPS_MODEL_HAS_UCAP // ri n_ucap
+#define GPS_MODEL_HAS_ENABLE_FLAGS // req
+#define GPS_MODEL_HAS_STAT_INFO // req
+#define GPS_MODEL_HAS_SWITCH_PARMS // deprecated, use ...
+#define GPS_MODEL_HAS_STRING_PARMS // deprecated, use ...
+#define GPS_MODEL_HAS_ANT_CABLE_LENGTH // GPS_MODEL_IS_GPS, also GNSS, or req?
+#define GPS_MODEL_HAS_SYNC_OUTAGE_DELAY // custom
+#define GPS_MODEL_HAS_PULSE_INFO // custom
+#define GPS_MODEL_HAS_OPT_FEATURES // deprecated, use ri
+#define GPS_MODEL_HAS_IRIG_TX_SETTINGS // ri GPS_HAS_IRIG_TX
+#define GPS_MODEL_HAS_RECEIVER_INFO // --
+#define GPS_MODEL_HAS_STR_TYPE_INFO_IDX // ri n_str_type
+#define GPS_MODEL_HAS_PORT_INFO_IDX // ri n_com
+#define GPS_MODEL_HAS_PORT_SETTINGS_IDX // ri n_com
+#define GPS_MODEL_HAS_POUT_INFO_IDX // ri n_pout
+#define GPS_MODEL_HAS_POUT_SETTINGS_IDX // ri n_pout
+#define GPS_MODEL_HAS_IRIG_TX_INFO // ri GPS_HAS_IRIG_TX
+#define GPS_MODEL_HAS_MULTI_REF_SETTINGS // ri GPS_HAS_MULTI_REF
+#define GPS_MODEL_HAS_MULTI_REF_INFO // ri GPS_HAS_MULTI_REF
+#define GPS_MODEL_HAS_ROM_CSUM // ?
+#define GPS_MODEL_HAS_MULTI_REF_STATUS // ri ...
+#define GPS_MODEL_HAS_RCV_TIMEOUT // ri ...
+#define GPS_MODEL_HAS_IGNORE_LOCK // ?
+#define GPS_MODEL_HAS_IRIG_RX_SETTINGS // ri ...
+#define GPS_MODEL_HAS_IRIG_RX_INFO // ri ...
+#define GPS_MODEL_HAS_REF_OFFS // ri ...
+#define GPS_MODEL_HAS_DEBUG_STATUS //
+#define GPS_MODEL_HAS_XMR_SETTINGS_IDX //
+#define GPS_MODEL_HAS_XMR_INFO_IDX //
+#define GPS_MODEL_HAS_XMR_STATUS_IDX //
+#define GPS_MODEL_HAS_OPT_SETTINGS //
+#define GPS_MODEL_HAS_OPT_INFO //
+#define GPS_MODEL_HAS_CLR_UCAP_BUFF //
+#define GPS_MODEL_HAS_TIME_SCALE //
+#define GPS_MODEL_HAS_NAV_ENG_SETTINGS //
+#define GPS_MODEL_HAS_RAW_IRIG_DATA //
+#define GPS_MODEL_HAS_GPIO_CFG_LIMITS //
+#define GPS_MODEL_HAS_GPIO_INFO_IDX //
+#define GPS_MODEL_HAS_GPIO_SETTINGS_IDX //
+#define GPS_MODEL_HAS_XMR_INSTANCES //
+#define GPS_MODEL_HAS_CLR_EVT_LOG //
+#define GPS_MODEL_HAS_NUM_EVT_LOG_ENTRIES //
+#define GPS_MODEL_HAS_FIRST_EVT_LOG_ENTRY //
+#define GPS_MODEL_HAS_NEXT_EVT_LOG_ENTRY //
+#define GPS_MODEL_HAS_LNO_STATUS //
+#define GPS_MODEL_HAS_IMS_STATE //
+#define GPS_MODEL_HAS_IMS_SENSOR_STATE_IDX //
+#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV //
+#define GPS_MODEL_HAS_HAVEQUICK_RX_SETTINGS //
+#define GPS_MODEL_HAS_HAVEQUICK_RX_INFO //
+#define GPS_MODEL_HAS_HAVEQUICK_TX_SETTINGS //
+#define GPS_MODEL_HAS_HAVEQUICK_TX_INFO //
+#define GPS_MODEL_HAS_PTP_CFG //
+#define GPS_MODEL_HAS_PTP_STATE //
+#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG_LIMITS //
+#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG //
+#define GPS_MODEL_HAS_NTP_GLB_CFG //
+#define GPS_MODEL_HAS_NTP_CLNT_MODE_CFG //
+#define GPS_MODEL_HAS_NTP_SRV_MODE_CFG //
+#define GPS_MODEL_HAS_NTP_PEER_SETTINGS_IDX //
+#define GPS_MODEL_HAS_NTP_SYS_STATE //
+#define GPS_MODEL_HAS_NTP_PEER_STATE_IDX //
+#define GPS_MODEL_HAS_SHS //
+#define GPS_MODEL_HAS_SHS_STATUS //
+#define GPS_MODEL_HAS_NET_GLB_CFG //
+#define GPS_MODEL_HAS_NET_DNS_SRVR //
+#define GPS_MODEL_HAS_NET_DNS_SRCH_DOM //
+#define GPS_MODEL_HAS_NET_STAT_DNS_SRVR //
+#define GPS_MODEL_HAS_NET_STAT_DNS_SRCH_DOM //
+#define GPS_MODEL_HAS_GNSS_SAT_INFO_IDX //
+
+#define GPS_MODEL_HAS_CFGH //
+#define GPS_MODEL_HAS_ALM //
+#define GPS_MODEL_HAS_EPH //
+#define GPS_MODEL_HAS_UTC //
+#define GPS_MODEL_HAS_IONO //
+#define GPS_MODEL_HAS_ASCII_MSG //
+
+#define GPS_MODEL_HAS_GLNS_ALM //
+#define GPS_MODEL_HAS_GNSS_SAT_INFO //
+#define GPS_MODEL_HAS_GNSS_MODE //
+
+#define GPS_MODEL_HAS_IP4_SETTINGS //
+#define GPS_MODEL_HAS_LAN_IF_INFO //
+#define GPS_MODEL_HAS_IP4_STATE //
+
+#define GPS_MODEL_HAS_SCU_STAT //
+
+#define GPS_MODEL_HAS_CRYPTED_PACKET //
+#define GPS_MODEL_HAS_CRYPTED_RAW_PACKET //
+
+#define GPS_MODEL_HAS_SECU_INFO //
+#define GPS_MODEL_HAS_SECU_SETTINGS //
+#define GPS_MODEL_HAS_SECU_PUBLIC_KEY //
+
+#endif //##++ more potential builtin features and classifiers
+
+
+
+/**
+ * @brief Common builtin features of all GPS receivers
+ */
+#define BUILTIN_FEAT_GPS \
+( \
+ GPS_MODEL_IS_GPS | \
+ GPS_MODEL_HAS_BVAR_STAT | \
+ GPS_MODEL_HAS_POS_XYZ | \
+ GPS_MODEL_HAS_POS_LLA | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS | \
+ GPS_MODEL_HAS_STAT_INFO | \
+ GPS_MODEL_HAS_ANT_CABLE_LENGTH \
+)
+
+
+/**
+ * @brief Common builtin features of all GNSS receivers
+ *
+ * GNSS includes GPS but optionally other satellite systems,
+ * and the associated API.
+ */
+#define BUILTIN_FEAT_GNSS \
+( \
+ BUILTIN_FEAT_GPS | \
+ GPS_MODEL_IS_GNSS | \
+ GPS_MODEL_HAS_GNSS_MODE \
+)
+
+
+
+/**
+ * @brief Definitions of builtin features per device type
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_BUILTIN_FEATURES
+ *
+ * @anchor GPS_MODEL_BUILTIN_FEATURE_MASKS @{ */
+
+#define BUILTIN_FEAT_GPS166 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167SV ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167PC ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167PCI ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS163 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS168PCI ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS161 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS169PCI ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_TCR167PCI ( 0 )
+#define BUILTIN_FEAT_GPS164 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS170PCI ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_PZF511 ( 0 )
+#define BUILTIN_FEAT_GPS170 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_TCR511 ( 0 )
+#define BUILTIN_FEAT_AM511 ( 0 )
+#define BUILTIN_FEAT_MSF511 ( 0 )
+#define BUILTIN_FEAT_GRC170 ( 0 )
+#define BUILTIN_FEAT_GPS170PEX ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS162 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_PTP270PEX ( 0 )
+#define BUILTIN_FEAT_FRC511PEX ( 0 )
+#define BUILTIN_FEAT_GEN170 ( 0 )
+#define BUILTIN_FEAT_TCR170PEX ( 0 )
+#define BUILTIN_FEAT_WWVB511 ( 0 )
+#define BUILTIN_FEAT_MGR170 ( 0 )
+#define BUILTIN_FEAT_JJY511 ( 0 )
+#define BUILTIN_FEAT_PZF600 ( 0 )
+#define BUILTIN_FEAT_TCR600 ( 0 )
+#define BUILTIN_FEAT_GPS180 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GLN170 ( 0 )
+#define BUILTIN_FEAT_GPS180PEX ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_TCR180PEX ( 0 )
+#define BUILTIN_FEAT_PZF180PEX ( 0 )
+#define BUILTIN_FEAT_MGR180 ( 0 )
+#define BUILTIN_FEAT_MSF600 ( 0 )
+#define BUILTIN_FEAT_WWVB600 ( 0 )
+#define BUILTIN_FEAT_JJY600 ( 0 )
+#define BUILTIN_FEAT_GPS180HS ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS180AMC ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_ESI180 ( 0 )
+#define BUILTIN_FEAT_CPE180 ( 0 )
+#define BUILTIN_FEAT_LNO180 ( 0 )
+#define BUILTIN_FEAT_GRC180 ( 0 )
+#define BUILTIN_FEAT_LIU ( 0 )
+#define BUILTIN_FEAT_DCF600HS ( 0 )
+#define BUILTIN_FEAT_DCF600RS ( 0 )
+#define BUILTIN_FEAT_MRI ( 0 )
+#define BUILTIN_FEAT_BPE ( 0 )
+#define BUILTIN_FEAT_GLN180PEX ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_N2X ( 0 )
+#define BUILTIN_FEAT_RSC180 ( 0 )
+#define BUILTIN_FEAT_LNE_GB ( 0 )
+#define BUILTIN_FEAT_PPG180 ( 0 )
+#define BUILTIN_FEAT_SCG ( 0 )
+#define BUILTIN_FEAT_MDU300 ( 0 )
+#define BUILTIN_FEAT_SDI ( 0 )
+#define BUILTIN_FEAT_FDM180 ( 0 )
+#define BUILTIN_FEAT_SPT ( 0 )
+#define BUILTIN_FEAT_PZF180 ( 0 )
+#define BUILTIN_FEAT_REL1000 ( 0 )
+#define BUILTIN_FEAT_HPS100 ( 0 )
+#define BUILTIN_FEAT_VSG180 ( 0 )
+#define BUILTIN_FEAT_MSF180 ( 0 )
+#define BUILTIN_FEAT_WWVB180 ( 0 )
+#define BUILTIN_FEAT_CPC180 ( 0 )
+
+/** @} anchor GPS_MODEL_BUILTIN_FEATURE_MASKS */
+
+
+
+/**
+ * @brief Initializer for a table of built-in features per device
+ *
+ * Last entry is all zero to indicated end of table.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_BUILTIN_FEATURE_MASKS
+ */
+#define GPS_MODEL_BUILTIN_FEATURES \
+{ \
+ { GPS_MODEL_GPS166, BUILTIN_FEAT_GPS166 }, \
+ { GPS_MODEL_GPS167, BUILTIN_FEAT_GPS167 }, \
+ { GPS_MODEL_GPS167SV, BUILTIN_FEAT_GPS167SV }, \
+ { GPS_MODEL_GPS167PC, BUILTIN_FEAT_GPS167PC }, \
+ { GPS_MODEL_GPS167PCI, BUILTIN_FEAT_GPS167PCI }, \
+ { GPS_MODEL_GPS163, BUILTIN_FEAT_GPS163 }, \
+ { GPS_MODEL_GPS168PCI, BUILTIN_FEAT_GPS168PCI }, \
+ { GPS_MODEL_GPS161, BUILTIN_FEAT_GPS161 }, \
+ { GPS_MODEL_GPS169PCI, BUILTIN_FEAT_GPS169PCI }, \
+ { GPS_MODEL_TCR167PCI, BUILTIN_FEAT_TCR167PCI }, \
+ { GPS_MODEL_GPS164, BUILTIN_FEAT_GPS164 }, \
+ { GPS_MODEL_GPS170PCI, BUILTIN_FEAT_GPS170PCI }, \
+ { GPS_MODEL_PZF511, BUILTIN_FEAT_PZF511 }, \
+ { GPS_MODEL_GPS170, BUILTIN_FEAT_GPS170 }, \
+ { GPS_MODEL_TCR511, BUILTIN_FEAT_TCR511 }, \
+ { GPS_MODEL_AM511, BUILTIN_FEAT_AM511 }, \
+ { GPS_MODEL_MSF511, BUILTIN_FEAT_MSF511 }, \
+ { GPS_MODEL_GRC170, BUILTIN_FEAT_GRC170 }, \
+ { GPS_MODEL_GPS170PEX, BUILTIN_FEAT_GPS170PEX }, \
+ { GPS_MODEL_GPS162, BUILTIN_FEAT_GPS162 }, \
+ { GPS_MODEL_PTP270PEX, BUILTIN_FEAT_PTP270PEX }, \
+ { GPS_MODEL_FRC511PEX, BUILTIN_FEAT_FRC511PEX }, \
+ { GPS_MODEL_GEN170, BUILTIN_FEAT_GEN170 }, \
+ { GPS_MODEL_TCR170PEX, BUILTIN_FEAT_TCR170PEX }, \
+ { GPS_MODEL_WWVB511, BUILTIN_FEAT_WWVB511 }, \
+ { GPS_MODEL_MGR170, BUILTIN_FEAT_MGR170 }, \
+ { GPS_MODEL_JJY511, BUILTIN_FEAT_JJY511 }, \
+ { GPS_MODEL_PZF600, BUILTIN_FEAT_PZF600 }, \
+ { GPS_MODEL_TCR600, BUILTIN_FEAT_TCR600 }, \
+ { GPS_MODEL_GPS180, BUILTIN_FEAT_GPS180 }, \
+ { GPS_MODEL_GLN170, BUILTIN_FEAT_GLN170 }, \
+ { GPS_MODEL_GPS180PEX, BUILTIN_FEAT_GPS180PEX }, \
+ { GPS_MODEL_TCR180PEX, BUILTIN_FEAT_TCR180PEX }, \
+ { GPS_MODEL_PZF180PEX, BUILTIN_FEAT_PZF180PEX }, \
+ { GPS_MODEL_MGR180, BUILTIN_FEAT_MGR180 }, \
+ { GPS_MODEL_MSF600, BUILTIN_FEAT_MSF600 }, \
+ { GPS_MODEL_WWVB600, BUILTIN_FEAT_WWVB600 }, \
+ { GPS_MODEL_JJY600, BUILTIN_FEAT_JJY600 }, \
+ { GPS_MODEL_GPS180HS, BUILTIN_FEAT_GPS180HS }, \
+ { GPS_MODEL_GPS180AMC, BUILTIN_FEAT_GPS180AMC }, \
+ { GPS_MODEL_ESI180, BUILTIN_FEAT_ESI180 }, \
+ { GPS_MODEL_CPE180, BUILTIN_FEAT_CPE180 }, \
+ { GPS_MODEL_LNO180, BUILTIN_FEAT_LNO180 }, \
+ { GPS_MODEL_GRC180, BUILTIN_FEAT_GRC180 }, \
+ { GPS_MODEL_LIU, BUILTIN_FEAT_LIU }, \
+ { GPS_MODEL_DCF600HS, BUILTIN_FEAT_DCF600HS }, \
+ { GPS_MODEL_DCF600RS, BUILTIN_FEAT_DCF600RS }, \
+ { GPS_MODEL_MRI, BUILTIN_FEAT_MRI }, \
+ { GPS_MODEL_BPE, BUILTIN_FEAT_BPE }, \
+ { GPS_MODEL_GLN180PEX, BUILTIN_FEAT_GLN180PEX }, \
+ { GPS_MODEL_N2X, BUILTIN_FEAT_N2X }, \
+ { GPS_MODEL_RSC180, BUILTIN_FEAT_RSC180 }, \
+ { GPS_MODEL_LNE_GB, BUILTIN_FEAT_LNE_GB }, \
+ { GPS_MODEL_PPG180, BUILTIN_FEAT_PPG180 }, \
+ { GPS_MODEL_SCG, BUILTIN_FEAT_SCG }, \
+ { GPS_MODEL_MDU300, BUILTIN_FEAT_MDU300 }, \
+ { GPS_MODEL_SDI, BUILTIN_FEAT_SDI }, \
+ { GPS_MODEL_FDM180, BUILTIN_FEAT_FDM180 }, \
+ { GPS_MODEL_SPT, BUILTIN_FEAT_SPT }, \
+ { GPS_MODEL_PZF180, BUILTIN_FEAT_PZF180 }, \
+ { GPS_MODEL_REL1000, BUILTIN_FEAT_REL1000 }, \
+ { GPS_MODEL_HPS100, BUILTIN_FEAT_HPS100 }, \
+ { GPS_MODEL_VSG180, BUILTIN_FEAT_VSG180 }, \
+ { GPS_MODEL_MSF180, BUILTIN_FEAT_MSF180 }, \
+ { GPS_MODEL_WWVB180, BUILTIN_FEAT_WWVB180 }, \
+ { GPS_MODEL_CPC180, BUILTIN_FEAT_CPC180 }, \
+ { 0, 0 } \
}
+/** @} anchor GPS_BUILTIN_FEATURE_DEFS */
+
+
/*
* The macros below can be used to classify a receiver,
- * e.g. depending on the time source and/or depending on
+ * 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" ) )
+ 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" ) )
+ strstr( (_p_ri)->model_name, "MGR" ) )
#define _mbg_rcvr_is_mobile_gps( _p_ri ) \
( strstr( (_p_ri)->model_name, "MGR" ) )
@@ -717,7 +1486,7 @@ enum
#define _mbg_rcvr_is_glonass( _p_ri ) \
( strstr( (_p_ri)->model_name, "GRC" ) || \
- ( strstr( (_p_ri)->model_name, "GLN" ) )
+ strstr( (_p_ri)->model_name, "GLN" ) )
#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \
( _mbg_rcvr_is_glonass( _p_ri ) && \
@@ -731,13 +1500,17 @@ enum
_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
- * of codes does NOT reflect the order of quality:
+ * @brief Known oscillator types used with ::RECEIVER_INFO::osc_type
+ *
+ * The sequence of codes does NOT reflect the order of quality.
+ * New oscillator type codes will just be appended to the enumeration.
+ *
+ * @see ::DEFAULT_GPS_OSC_NAMES
+ * @see ::DEFAULT_GPS_OSC_QUALITY_IDX
*/
-enum
+enum GPS_OSC_TYPES
{
GPS_OSC_UNKNOWN,
GPS_OSC_TCXO_LQ,
@@ -749,14 +1522,19 @@ enum
GPS_OSC_RUBIDIUM,
GPS_OSC_TCXO_MQ,
GPS_OSC_OCXO_DHQ,
+ GPS_OSC_OCXO_SQ,
N_GPS_OSC
};
-/*
- * The sequence and number of oscillator names
- * listed below must correspond to the enumeration
- * above:
+/**
+ * @brief Oscillator type name string initializer
+ *
+ * The sequence and number of oscillator names has to
+ * correspond to the enumeration in ::GPS_OSC_TYPES
+ *
+ * @see ::GPS_OSC_TYPES
+ * @see ::DEFAULT_GPS_OSC_QUALITY_IDX
*/
#define DEFAULT_GPS_OSC_NAMES \
{ \
@@ -769,15 +1547,21 @@ enum
"OCXO XHQ", \
"RUBIDIUM", \
"TCXO MQ", \
- "OCXO DHQ" \
+ "OCXO DHQ", \
+ "OCXO SQ" \
}
-/*
- * The initializer below can be used to initialize
- * an array (e.g. "int osc_quality_idx[N_GPS_OSC]")
- * which allows to display the oscillator types
- * ordered by quality:
+/**
+ * @brief Oscillator quality index
+ *
+ * Can be used to initialize a index array
+ * (e.g. "int osc_quality_idx[N_GPS_OSC];")
+ * allowing to display the oscillator types
+ * ordered by quality
+ *
+ * @see ::GPS_OSC_TYPES
+ * @see ::DEFAULT_GPS_OSC_NAMES
*/
#define DEFAULT_GPS_OSC_QUALITY_IDX \
{ \
@@ -786,6 +1570,7 @@ enum
GPS_OSC_TCXO_MQ, \
GPS_OSC_TCXO_HQ, \
GPS_OSC_OCXO_LQ, \
+ GPS_OSC_OCXO_SQ, \
GPS_OSC_OCXO_MQ, \
GPS_OSC_OCXO_HQ, \
GPS_OSC_OCXO_DHQ, \
@@ -795,43 +1580,62 @@ enum
-/*
- * Codes to be used with RECEIVER_INFO.osc_flags
- * are not yet used/required, so they are reserved
- * for future use.
- */
-
-
/**
- * The codes below enumerate some features which may be
- * supported by a given clock, or not.
+ * @brief Enumeration of device features flags reported in ::RECEIVER_INFO::features
+ *
+ * Each flags indicates if a device supports the associated feature.
*/
-enum
+enum GPS_FEATURE_BITS
{
- 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 */
- GPS_FEAT_RAW_IRIG_DATA, /**< supports reading raw IRIG input data */
- GPS_FEAT_RAW_IRIG_TIME, /**< supports reading decoded IRIG time */
- N_GPS_FEATURE /**< the number of valid features */
+ 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 simple LAN IPv4 interface, superseded by ::GPS_FEAT_NET_CFG
+ GPS_FEAT_MULTI_REF, ///< has multiple input sources with priorities, superseded by ::GPS_FEAT_XMULTI_REF
+
+ GPS_FEAT_RCV_TIMEOUT, ///< timeout after GPS reception has stopped
+ GPS_FEAT_IGNORE_LOCK, ///< supports "ignore lock", ::MBG_OPT_BIT_EMU_SYNC can be set alternatively
+ GPS_FEAT_5_MHZ, ///< output 5 MHz rather than 100 kHz
+ GPS_FEAT_XMULTI_REF, ///< has extended multiple input source configuration, supersedes ::GPS_FEAT_MULTI_REF
+ 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 (::MBG_IRIG_CTRL_BITS)
+ GPS_FEAT_PTP, ///< has PTP support
+
+ GPS_FEAT_NAV_ENGINE_SETTINGS, ///< supports navigation engine configuration
+ GPS_FEAT_RAW_IRIG_DATA, ///< supports reading raw IRIG input data (::MBG_RAW_IRIG_DATA)
+ GPS_FEAT_RAW_IRIG_TIME, ///< supports reading decoded IRIG time (::PCPS_IRIG_TIME)
+ GPS_FEAT_PTP_UNICAST, ///< has PTP Unicast support
+ GPS_FEAT_GPIO, ///< has general purpose inputs/outputs
+ GPS_FEAT_XMRS_MULT_INSTC, ///< multiple XMRS instances of the same ref type supported (::XMULTI_REF_INSTANCES)
+ GPS_FEAT_10MHZ_DISBD, ///< 10 MHz output is always disabled
+ GPS_FEAT_EVT_LOG, ///< Event logging supported
+
+ GPS_FEAT_IMS, ///< supports IMS data structures
+ GPS_FEAT_HAVEQUICK, ///< supports HaveQuick structures
+ GPS_FEAT_NTP, ///< supports NTP structures
+ GPS_FEAT_NET_CFG, ///< supports extended network interface configuration, supersedes ::GPS_FEAT_LAN_IP4
+ GPS_FEAT_VST, ///< supports VST (Versatile Storage) API and structures
+ GPS_FEAT_SHS, ///< supports SHS (Secure Hybrid System) API and structures
+ GPS_FEAT_XBP, ///< supports XBP (eXtended Binary Protocol) API and structures, see @ref group_xbp
+ // WARNING: There are no more unassigned feature bits available here.
+ // The MSB has to be reserved to indicate that a new, extended feature
+ // reporting scheme is supported, which still has to be defined.
+
+ N_GPS_FEATURE ///< the number of known features
+ // If new features are added then care must be taken to update the associated
+ // definitions below accordingly, e.g. string initializers and bit masks.
};
+/**
+ * @brief Names of device features
+ *
+ * @see ::GPS_FEATURE_BITS
+ */
#define DEFAULT_GPS_FEATURE_NAMES \
{ \
"Pulse Per Second", \
@@ -852,35 +1656,69 @@ enum
"PTP/IEEE1588", \
"Nav. Engine Settings", \
"Raw IRIG Data", \
- "Raw IRIG Time" \
+ "Raw IRIG Time", \
+ "PTP/IEEE1588 Unicast", \
+ "General Purpose I/O", \
+ "Multiple XMRS Instances", \
+ "10 MHz Output Disabled", \
+ "Event Logging", \
+ "IMS data", \
+ "HaveQuick", \
+ "NTP", \
+ "Ext. Network Config", \
+ "Versatile Storage", \
+ "SHS", \
+ "Extended Binary Protocol" \
}
-/*
- * Bit masks used with RECEIVER_INFO.features
- * (others are reserved):
- */
-#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS )
-#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM )
-#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH )
-#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS )
-#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX )
-#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX )
-#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 )
-#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF )
-#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT )
-#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK )
-#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ )
-#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF )
-#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS )
-#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE )
-#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS )
-#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP )
-#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS )
-#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA )
-#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME )
-
-#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX
+/**
+ * @brief Bit masks used with ::RECEIVER_INFO::features
+ *
+ * @see ::GPS_FEATURE_BITS
+ *
+ * @anchor GPS_FEATURE_MASKS @{ */
+
+#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS ) ///< see ::GPS_FEAT_PPS
+#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM ) ///< see ::GPS_FEAT_PPM
+#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH ) ///< see ::GPS_FEAT_SYNTH
+#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS ) ///< see ::GPS_FEAT_DCFMARKS
+#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX ) ///< see ::GPS_FEAT_IRIG_TX
+#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX ) ///< see ::GPS_FEAT_IRIG_RX
+#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 ) ///< see ::GPS_FEAT_LAN_IP4
+#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF ) ///< see ::GPS_FEAT_MULTI_REF
+
+#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT ) ///< see ::GPS_FEAT_RCV_TIMEOUT
+#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK ) ///< see ::GPS_FEAT_IGNORE_LOCK
+#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ ) ///< see ::GPS_FEAT_5_MHZ
+#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF ) ///< see ::GPS_FEAT_XMULTI_REF
+#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS ) ///< see ::GPS_FEAT_OPT_SETTINGS
+#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE ) ///< see ::GPS_FEAT_TIME_SCALE
+#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS ) ///< see ::GPS_FEAT_IRIG_CTRL_BITS
+#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP ) ///< see ::GPS_FEAT_PTP
+
+#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS ) ///< see ::GPS_FEAT_NAV_ENGINE_SETTINGS
+#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA ) ///< see ::GPS_FEAT_RAW_IRIG_DATA
+#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME ) ///< see ::GPS_FEAT_RAW_IRIG_TIME
+#define GPS_HAS_PTP_UNICAST ( 1UL << GPS_FEAT_PTP_UNICAST ) ///< see ::GPS_FEAT_PTP_UNICAST
+#define GPS_HAS_GPIO ( 1UL << GPS_FEAT_GPIO ) ///< see ::GPS_FEAT_GPIO
+#define GPS_HAS_XMRS_MULT_INSTC ( 1UL << GPS_FEAT_XMRS_MULT_INSTC ) ///< see ::GPS_FEAT_XMRS_MULT_INSTC
+#define GPS_HAS_10MHZ_DISBD ( 1UL << GPS_FEAT_10MHZ_DISBD ) ///< see ::GPS_FEAT_10MHZ_DISBD
+#define GPS_HAS_EVT_LOG ( 1UL << GPS_FEAT_EVT_LOG ) ///< see ::GPS_FEAT_EVT_LOG
+
+#define GPS_HAS_IMS ( 1UL << GPS_FEAT_IMS ) ///< see ::GPS_FEAT_IMS
+#define GPS_HAS_HAVEQUICK ( 1UL << GPS_FEAT_HAVEQUICK ) ///< see ::GPS_FEAT_HAVEQUICK
+#define GPS_HAS_NTP ( 1UL << GPS_FEAT_NTP ) ///< see ::GPS_FEAT_NTP
+#define GPS_HAS_NET_CFG ( 1UL << GPS_FEAT_NET_CFG ) ///< see ::GPS_FEAT_NET_CFG
+#define GPS_HAS_VST ( 1UL << GPS_FEAT_VST ) ///< see ::GPS_FEAT_VST
+#define GPS_HAS_SHS ( 1UL << GPS_FEAT_SHS ) ///< see ::GPS_FEAT_SHS
+#define GPS_HAS_XBP ( 1UL << GPS_FEAT_XBP ) ///< see ::GPS_FEAT_XBP
+
+// the next ones are special since they just shadow another flag:
+#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX
+#define GPS_HAS_DEBUG_STATUS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX
+
+/** @} anchor GPS_FEATURE_MASKS */
/*
@@ -896,16 +1734,32 @@ enum
}
-/*
- * Codes to be used with RECEIVER_INFO::flags:
+/**
+ * @brief Bits used to define ::RECEIVER_INFO_FLAG_MASKS
*/
-#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
+enum RECEIVER_INFO_FLAG_BITS
+{
+ GPS_BIT_OSC_CFG_SUPP, ///< oscillator cfg is supported, see ::RECEIVER_INFO::osc_type
+ GPS_BIT_IRIG_FO_IN, ///< IRIG input via fiber optics
+ GPS_BIT_HAS_FPGA, ///< device provides on-board FPGA
+ N_RECEIVER_INFO_FLAG_BITS ///< number of known bits
+};
+
+
+/**
+ * @brief Bit masks to be used with ::RECEIVER_INFO::flags
+ */
+enum RECEIVER_INFO_FLAG_MASKS
+{
+ GPS_OSC_CFG_SUPP = ( 1UL << GPS_BIT_OSC_CFG_SUPP ), ///< see ::GPS_BIT_OSC_CFG_SUPP
+ GPS_IRIG_FO_IN = ( 1UL << GPS_BIT_IRIG_FO_IN ), ///< see ::GPS_BIT_IRIG_FO_IN
+ GPS_HAS_FPGA = ( 1UL << GPS_BIT_HAS_FPGA ) ///< see ::GPS_BIT_HAS_FPGA
+};
+
/*
- * If the GPS_HAS_FPGA flag is set in RECEIVER_INFO::flags then the card
+ * 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
@@ -941,6 +1795,7 @@ typedef struct
{
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
@@ -953,19 +1808,29 @@ typedef struct
-/**
- 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.
-*/
+/**
+ * @brief A structure used to hold time in GPS format
+ *
+ * Date and time refer to the linear time scale defined by GPS, with
+ * the epoch starting at %UTC midnight at the beginning of January 6, 1980.
+ *
+ * GPS time is counted by the week numbers since the epoch, plus second
+ * of the week, plus fraction of the second. The week number transmitted
+ * by the satellites rolls over from 1023 to 0, but Meinberg devices
+ * just continue to count the weeks beyond the 1024 week limit to keep
+ * the receiver's internal time.
+ *
+ * %UTC time differs from GPS time since a number of leap seconds have
+ * been inserted in the %UTC time scale after the GPS epoche. The number
+ * of leap seconds is disseminated by the satellites using the ::UTC
+ * parameter set, which also provides info on pending leap seconds.
+ */
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 */
+ 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, 1/::RECEIVER_INFO::ticks_per_sec units
+
} T_GPS;
#define _mbg_swab_t_gps( _p ) \
@@ -977,26 +1842,32 @@ typedef struct
/**
- Local date and time computed from GPS time. The current number
- of leap seconds have to be added to get UTC from GPS time.
- Additional corrections could have been made according to the
- time zone/daylight saving parameters (TZDL, see below) defined
- by the user. The status field can be checked to see which corrections
- have been applied.
-*/
+ * @brief Local date and time computed from GPS time
+ *
+ * The current number of leap seconds have to be added to get %UTC
+ * from GPS time. Additional corrections could have been made according
+ * to the time zone/daylight saving parameters ::TZDL defined by the user.
+ * The status field can be checked to see which corrections
+ * have actually been applied.
+ *
+ * @note Conversion from GPS time to %UTC and/or local time can only be
+ * done if some valid ::UTC correction parameters are available in the
+ * receiver's non-volatile memory.
+ */
typedef struct
{
- int16_t year; /**< year number, 0..9999 */
- int8_t month; /**< month, 1..12 */
- int8_t mday; /**< day of month, 1..31 */
- int16_t yday; /**< day of year, 1..366 */
- int8_t wday; /**< day of week, 0..6 == Sun..Sat */
- int8_t hour; /**< hours, 0..23 */
- int8_t min; /**< minutes, 0..59 */
- int8_t sec; /**< seconds, 0..59 */
- int32_t frac; /**< fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
- int32_t offs_from_utc; /**< local time's offset from UTC */
- uint16_t status; /**< status flags */
+ int16_t year; ///< year number, 0..9999
+ int8_t month; ///< month, 1..12
+ int8_t mday; ///< day of month, 1..31
+ int16_t yday; ///< day of year, 1..365, or 366 in case of leap year
+ int8_t wday; ///< day of week, 0..6 == Sun..Sat
+ int8_t hour; ///< hours, 0..23
+ int8_t min; ///< minutes, 0..59
+ int8_t sec; ///< seconds, 0..59, or 60 in case of inserted leap second
+ int32_t frac; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
+ int32_t offs_from_utc; ///< local time offset from %UTC [sec]
+ uint16_t status; ///< status flags, see ::TM_GPS_STATUS_BIT_MASKS
+
} TM_GPS;
#define _mbg_swab_tm_gps( _p ) \
@@ -1009,76 +1880,105 @@ typedef struct
}
-/* status flag bits used with conversion from GPS time to local time */
-
-enum
+/**
+ * @brief Status flag bits used to define ::TM_GPS_STATUS_BIT_MASKS
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BIT_MASKS
+ */
+enum TM_GPS_STATUS_BITS
{
- TM_BIT_UTC, /* UTC correction has been made */
- TM_BIT_LOCAL, /* UTC has been converted to local time */
- TM_BIT_DL_ANN, /* state of daylight saving is going to change */
- TM_BIT_DL_ENB, /* daylight saving is enabled */
- TM_BIT_LS_ANN, /* leap second will be inserted */
- TM_BIT_LS_ENB, /* current second is leap second */
- TM_BIT_LS_ANN_NEG, /* set in addition to TM_LS_ANN if leap sec negative */
- TM_BIT_INVT, /* invalid time, e.g. if RTC battery empty */
-
- TM_BIT_EXT_SYNC, /* sync'd externally */
- TM_BIT_HOLDOVER, /* holdover mode after previous sync. */
- TM_BIT_ANT_SHORT, /* antenna cable short circuited */
- TM_BIT_NO_WARM, /* OCXO has not warmed up */
- TM_BIT_ANT_DISCONN, /* antenna currently disconnected */
- TM_BIT_SYN_FLAG, /* TIME_SYN output is low */
- TM_BIT_NO_SYNC, /* time sync actually not verified */
- 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_UTC, ///< %UTC correction has been made
+ TM_BIT_LOCAL, ///< %UTC has been converted to local time according to ::TZDL settings
+ TM_BIT_DL_ANN, ///< state of daylight saving is going to change
+ TM_BIT_DL_ENB, ///< daylight saving is in effect
+ TM_BIT_LS_ANN, ///< leap second pending
+ TM_BIT_LS_ENB, ///< current second is leap second
+ TM_BIT_LS_ANN_NEG, ///< set in addition to ::TM_BIT_LS_ANN if leap sec is negative
+ TM_BIT_INVT, ///< invalid time, e.g. if RTC battery bas been empty
+
+ TM_BIT_EXT_SYNC, ///< synchronized externally
+ TM_BIT_HOLDOVER, ///< in holdover mode after previous synchronization
+ TM_BIT_ANT_SHORT, ///< antenna cable short circuited
+ TM_BIT_NO_WARM, ///< OCXO has not warmed up
+ TM_BIT_ANT_DISCONN, ///< antenna currently disconnected
+ TM_BIT_SYN_FLAG, ///< TIME_SYN output is low
+ TM_BIT_NO_SYNC, ///< time sync actually not verified
+ TM_BIT_NO_POS ///< position actually not verified, LOCK LED off
+};
+
+
+/**
+ * @brief Status flag masks used with ::TM_GPS::status
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BITS
+ */
+enum TM_GPS_STATUS_BIT_MASKS
{
- TM_BIT_SCALE_GPS = 16,
- TM_BIT_SCALE_TAI
- // the remaining bits are reserved
+ TM_UTC = ( 1UL << TM_BIT_UTC ), ///< see ::TM_BIT_UTC
+ TM_LOCAL = ( 1UL << TM_BIT_LOCAL ), ///< see ::TM_BIT_LOCAL
+ TM_DL_ANN = ( 1UL << TM_BIT_DL_ANN ), ///< see ::TM_BIT_DL_ANN
+ TM_DL_ENB = ( 1UL << TM_BIT_DL_ENB ), ///< see ::TM_BIT_DL_ENB
+ TM_LS_ANN = ( 1UL << TM_BIT_LS_ANN ), ///< see ::TM_BIT_LS_ANN
+ TM_LS_ENB = ( 1UL << TM_BIT_LS_ENB ), ///< see ::TM_BIT_LS_ENB
+ TM_LS_ANN_NEG = ( 1UL << TM_BIT_LS_ANN_NEG ), ///< see ::TM_BIT_LS_ANN_NEG
+ TM_INVT = ( 1UL << TM_BIT_INVT ), ///< see ::TM_BIT_INVT
+
+ TM_EXT_SYNC = ( 1UL << TM_BIT_EXT_SYNC ), ///< see ::TM_BIT_EXT_SYNC
+ TM_HOLDOVER = ( 1UL << TM_BIT_HOLDOVER ), ///< see ::TM_BIT_HOLDOVER
+ TM_ANT_SHORT = ( 1UL << TM_BIT_ANT_SHORT ), ///< see ::TM_BIT_ANT_SHORT
+ TM_NO_WARM = ( 1UL << TM_BIT_NO_WARM ), ///< see ::TM_BIT_NO_WARM
+ TM_ANT_DISCONN = ( 1UL << TM_BIT_ANT_DISCONN ), ///< see ::TM_BIT_ANT_DISCONN
+ TM_SYN_FLAG = ( 1UL << TM_BIT_SYN_FLAG ), ///< see ::TM_BIT_SYN_FLAG
+ TM_NO_SYNC = ( 1UL << TM_BIT_NO_SYNC ), ///< see ::TM_BIT_NO_SYNC
+ TM_NO_POS = ( 1UL << TM_BIT_NO_POS ) ///< see ::TM_BIT_NO_POS
};
-/* bit masks corresponding to the flag bits above */
-#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_INVT ( 1UL << TM_BIT_INVT )
+/**
+ * @brief Type of an extended TM status which is mainly used inside the firmware
+ */
+typedef uint32_t TM_STATUS_EXT;
-#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 )
+/**
+ * @brief Enumeration of extended status bits used with ::TM_STATUS_EXT
+ *
+ * @note The lower 16 bits correspond to ::TM_GPS_STATUS_BITS
+ */
+enum TM_GPS_STATUS_BITS_EX
+{
+ TM_BIT_SCALE_GPS = 16, ///< time scale configured to return GPS time
+ TM_BIT_SCALE_TAI ///< time scale configured to return TAI
+ // the remaining bits are reserved
+};
-// The following bits are only used with the TM_STATUS_X type:
+// 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 )
#define TM_MSK_TIME_VALID ( TM_UTC | TM_SCALE_GPS | TM_SCALE_TAI )
+
/**
- This structure is used to transmit information on date and time
+ * @brief A structure used to transmit information on date and time
+ *
+ * This structure can be used to transfer the current time, in which
+ * case the channel field has to be set to -1, or an event capture time
+ * retrieved from the on-board FIFO, in which case the channel field
+ * contains the index of the time capture input, e.g. 0 or 1.
*/
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 on-board time; >= 0 the capture channel number
+ T_GPS t; ///< time in GPS scale and format
+ TM_GPS tm; ///< time converted to %UTC and/or local time according to ::TZDL settings
+
} TTM;
#define _mbg_swab_ttm( _p ) \
@@ -1090,10 +1990,24 @@ typedef struct
+/**
+ * @brief A timestamp with nanosecond resolution
+ *
+ * @note The secs field will roll over on 2038-01-19 03:14:07
+ * if used for the number of seconds since 1970-01-01, just like
+ * 32 bit POSIX time_t.
+ *
+ * @see ::NANO_TIME_64
+ */
typedef struct
{
- int32_t nano_secs; // [nanoseconds]
- int32_t secs; // [seconds]
+ // ATTENTION:
+ // This structure is and has has been used in public API calls for a long time,
+ // so even though the order of member fields is different than in NANO_TIME_64
+ // this must *NOT* be changed, or API compatibility will get lost!
+ int32_t nano_secs; ///< [nanoseconds]
+ int32_t secs; ///< [seconds]
+
} NANO_TIME;
#define _mbg_swab_nano_time( _p ) \
@@ -1102,24 +2016,48 @@ typedef struct
_mbg_swab32( &(_p)->secs ); \
}
-// The macro below checks if a NANO_TIME value is negative.
+// 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 */
-/* used with a position in earth centered, earth fixed (ECEF) */
-/* coordinates whereas type LLA holds such a position converted */
-/* to geographic coordinates as defined by WGS84 (World Geodetic */
-/* System from 1984). */
+/**
+ * @brief A timestamp with nanosecond resolution, but 64 bit size
+ *
+ * @see ::NANO_TIME
+ */
+typedef struct
+{
+ // ATTENTION:
+ // This structure is and has been used in public API calls for a long time,
+ // so even though the order of member fields is different than in NANO_TIME
+ // this must *NOT* be changed, or API compatibility will get lost!
+ uint64_t secs; ///< [seconds]
+ uint64_t nano_secs; ///< [nanoseconds]
+
+} NANO_TIME_64;
+
+#define _mbg_swab_nano_time_64( _p ) \
+{ \
+ _mbg_swab64( &(_p)->secs ); \
+ _mbg_swab64( &(_p)->nano_secs ); \
+}
+
+
#ifndef _XYZ_DEFINED
- /* sequence and number of components of a cartesian position */
- enum { XP, YP, ZP, N_XYZ };
+ /**
+ * @brief Sequence and number of components of a cartesian position
+ */
+ enum XYZ_FIELDS { XP, YP, ZP, N_XYZ }; // x, y, z
- /** a type of array holding a cartesian position */
- typedef double XYZ[N_XYZ]; /**< values are in [m] */
+ /**
+ * @brief A position in cartesian coordinates
+ *
+ * Usually earth centered, earth fixed (ECEF) coordinates.
+ */
+ typedef double XYZ[N_XYZ]; ///< values are in [m], see ::XYZ_FIELDS
#define _XYZ_DEFINED
#endif
@@ -1128,11 +2066,20 @@ typedef struct
#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] */
+ /**
+ * @brief Sequence and number of components of a geographic position
+ */
+ enum LLA_FIELDS { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
+
+ /**
+ * @brief A geographic position based on latitude, longitude, and altitude
+ *
+ * The geographic position associated to specific cartesian coordinates
+ * depends on the characteristics of the ellipsoid used for the computation,
+ * the so-called geographic datum. GPS uses the WGS84 (World Geodetic System
+ * from 1984) ellipsoid by default.
+ */
+ typedef double LLA[N_LLA]; ///< lon, lat in [rad], alt in [m], see ::LLA_FIELDS
#define _LLA_DEFINED
#endif
@@ -1141,67 +2088,74 @@ typedef struct
/**
- @defgroup group_synth 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.
-
- 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.
-
- 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)
-
- If range == MAX_RANGE the value of freq must not exceed 1000, so the
- output frequency is limited to 10 MHz.
- @{
-*/
+ * @defgroup group_synth 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.
+ *
+ * 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.
+ *
+ * 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)
+ *
+ * If range == ::MAX_SYNTH_RANGE the value of freq must not exceed 1000, so
+ * the output frequency is limited to 10 MHz (see ::MAX_SYNTH_FREQ_VAL).
+ *
+ * @{ */
-#define N_SYNTH_FREQ_DIGIT 4 /**< number of digits to edit */
-#define MAX_SYNTH_FREQ 1000 /**< if range == MAX_SYNTH_RANGE */
+#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
#define N_SYNTH_RANGE ( MAX_SYNTH_RANGE - MIN_SYNTH_RANGE + 1 )
-#define N_SYNTH_PHASE_DIGIT 4
-#define MAX_SYNTH_PHASE 3600
+#define N_SYNTH_PHASE_DIGIT 4
+#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 */
+/**
+ * @brief 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 */
+/**
+ * @brief The synthesizer's phase is 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 */
+/**
+ * A Macro used to determine the position of the decimal point
+ * when printing the synthesizer frequency 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) */
+/**
+ * @brief Synthesizer frequency units
+ *
+ * An initializer for commonly displayed synthesizer frequency units
+ * (::N_SYNTH_RANGE strings)
+ */
#define DEFAULT_FREQ_RANGES \
{ \
"Hz", \
@@ -1214,11 +2168,15 @@ typedef struct
+/**
+ * @brief Synthesizer configuration parameters
+ */
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 Hz; 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 ) \
@@ -1229,57 +2187,81 @@ typedef struct
}
-/**
- The definitions below can be used to query the
- current synthesizer state.
+/**
+ * @brief Enumeration of synthesizer states
*/
-enum
+enum SYNTH_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 */
+ 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
};
+
+/**
+ * @brief A structure used to report the synthesizer state
+ */
typedef struct
{
- uint8_t state; /**< state code as enumerated above */
- uint8_t flags; /**< reserved, currently always 0 */
+ uint8_t state; ///< state code as enumerated in ::SYNTH_STATES
+ 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
+/** @} defgroup group_synth */
-/**
- @defgroup group_tzdl Time zone/daylight saving parameters
- 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 */
+/**
+ * @defgroup group_tzdl Time zone / daylight saving parameters
+ *
+ * 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
+ *
+ * @{ */
+
+/**
+ * @brief The name of a time zone
+ *
+ * @note Up to 5 printable characters, plus trailing zero
+ */
typedef char TZ_NAME[6];
+/**
+ * @brief Time zone / daylight saving parameters
+ *
+ * This structure is used to specify how a device converts on-board %UTC
+ * to local time, including computation of beginning and end of daylight
+ * saving time (DST), if required.
+ *
+ * @note The ::TZDL structure contains members of type ::TM_GPS to specify
+ * the times for beginning and end of DST. However, the ::TM_GPS::frac,
+ * ::TM_GPS::offs_from_utc, and ::TM_GPS::status fields of these ::TZDL::tm_on
+ * and ::TZDL::tm_off members are ignored for the conversion to local time,
+ * and thus should be 0.
+ */
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; ///< standard 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;
#define _mbg_swab_tzdl( _p ) \
@@ -1292,8 +2274,10 @@ typedef struct
/**
- 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.
+ * @brief A flag indicating automatic computation of DST
+ *
+ * If this flag is or'ed to the year numbers in ::TZDL::tm_on and ::TZDL::tm_off
+ * then daylight saving is computed automatically year by year.
*/
#define DL_AUTO_FLAG 0x8000
@@ -1303,18 +2287,18 @@ typedef struct
#define DEFAULT_TZDL_AUTO_YEAR ( 2007 | DL_AUTO_FLAG )
-#define DEFAULt_TZDL_OFFS_DL 3600L /**< usually DST is +1 hour */
+#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:
+/**
+ * An initializer for ::TZDL::tm_on and ::TZDL::tm_off for time zones
+ * which do not observe 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:
+// Settings used with %UTC:
#define TZ_INFO_UTC "UTC (Universal Time, Coordinated)"
@@ -1322,22 +2306,23 @@ typedef struct
#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[] */ \
+ 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 */ \
}
-/**
- The symbols below specify beginning and end of DST for
- Central Europe, as constituted by the European Parliament:
- */
-
+/**
+ * @brief An initializer for ::TZDL::tm_on according to the rules for Central Europe
+ */
#define DEFAULT_TZDL_TM_ON_CET_CEST \
{ DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 }
+/**
+ * @brief An initializer for ::TZDL::tm_off according to the rules for Central Europe
+ */
#define DEFAULT_TZDL_TM_OFF_CET_CEST \
{ DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
@@ -1347,27 +2332,27 @@ typedef struct
#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_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[] */ \
+ 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[] */ \
+ 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 */ \
}
@@ -1386,8 +2371,8 @@ typedef struct
#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 DEFAULT_TZDL_NAMES_EET_EEST_EN { "EET ", "EEST " }
+#define DEFAULT_TZDL_NAMES_EET_EEST_DE { "OEZ ", "OESZ " }
#define DEFAULT_TZDL_OFFS_EET 7200L
@@ -1397,7 +2382,7 @@ typedef struct
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[] */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_EN /* name */ \
}
#define DEFAULT_TZDL_EET_EEST_DE \
@@ -1406,22 +2391,35 @@ typedef struct
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[] */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_DE /* name */ \
}
-/** @} */ // endgroup
+/** @} defgroup group_tzdl */
+
+
/**
- * The structure below reflects the status of the antenna,
+ * @brief Antenna status and error at reconnect information
+ *
+ * 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.
+ * clock offset when it has synchronized again after the
+ * disconnection interval.
+ *
+ * @note ::ANT_INFO::status changes back to ::ANT_RECONN only
+ * after the antenna has been reconnected <b>and</b> the
+ * receiver has re-synchronized to the satellite signal.
+ * In this case ::ANT_INFO::delta_t reports the time offset
+ * before resynchronization, i.e. how much the internal
+ * time has drifted while the antenna was disconnected.
*/
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, see ::ANT_STATUS_CODES
+ 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 1/::RECEIVER_INFO::ticks_per_sec units
+
} ANT_INFO;
#define _mbg_swab_ant_info( _p ) \
@@ -1433,39 +2431,36 @@ typedef struct
}
-/**
- The status field may be set to one of the values below:
-*/
-enum
+/**
+ * @brief Status code used with ::ANT_INFO::status
+ */
+enum ANT_STATUS_CODES
{
- 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, ///< No other fields valid since antenna has not yet been disconnected
+ ANT_DISCONN, ///< Antenna is disconnected, tm_reconn and delta_t not yet set
+ ANT_RECONN, ///< Antenna has been disconnect, and receiver sync. after reconnect, so all fields valid
+ N_ANT_STATUS_CODES ///< the number of known status codes
};
-/* 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 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.
-*/
+/**
+ * @brief A structure controlling when output signals are enabled
+ *
+ * The structure holds some flags which let the corresponding outputs
+ * be disabled after power-up until the receiver has synchronized
+ * (flags == ::EF_OFF, 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 ::ENABLE_FLAGS::freq must
+ * always be set to ::EF_FREQ_ALL.
+ */
typedef struct
{
- 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 */
+ 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 ) \
@@ -1477,25 +2472,53 @@ typedef struct
}
-/* A struct used to hold the settings of a serial port: */
+/**
+ * @brief Codes used with ::ENABLE_FLAGS
+ **/
+enum ENABLE_FLAGS_CODES
+{
+ EF_OFF = 0x00, ///< associated outputs off until synchronized
+
+ EF_SERIAL_BOTH = 0x03, ///< both serial ports on, use with ::ENABLE_FLAGS::serial
+ EF_PULSES_BOTH = 0x03, ///< both pulses P_SEC and P_MIN on, use with ::ENABLE_FLAGS::pulses
+ EF_FREQ_ALL = 0x07, ///< all fixed freq. outputs on, use with ::ENABLE_FLAGS::freq
+ EF_SYNTH = 0x01 ///< synthesizer on, use with ::ENABLE_FLAGS::synth
+};
+
+
#ifndef _COM_HS_DEFINED
- /* types of handshake */
- enum { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
+ /**
+ * @brief Enumeration of handshake modes
+ */
+ enum COM_HANSHAKE_MODES { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
#define _COM_HS_DEFINED
#endif
#ifndef _COM_PARM_DEFINED
+ /**
+ * @brief A data type to configure a serial port's baud rate
+ *
+ * @see ::MBG_BAUD_RATES
+ */
typedef int32_t BAUD_RATE;
- /* indices used to identify a parameter in the framing string */
- enum { F_DBITS, F_PRTY, F_STBITS };
+ /**
+ * @brief Indices used to identify a parameter in the framing string
+ *
+ * @see ::MBG_FRAMING_STRS
+ */
+ enum MBG_FRAMING_STR_IDXS { F_DBITS, F_PRTY, F_STBITS };
+ /**
+ * @brief A structure to store the configuration of a serial port
+ */
typedef struct
{
- BAUD_RATE baud_rate; /* e.g. 19200L */
- char framing[4]; /* e.g. "8N1" */
- int16_t handshake; /* a numeric value, only HS_NONE supported yet */
+ BAUD_RATE baud_rate; ///< transmission speed, e.g. 19200L, see ::MBG_BAUD_RATES
+ char framing[4]; ///< ASCIIZ framing string, e.g. "8N1" or "7E2", see ::MBG_FRAMING_STRS
+ int16_t handshake; ///< handshake mode, yet only ::HS_NONE supported
+
} COM_PARM;
#define _COM_PARM_DEFINED
@@ -1510,12 +2533,15 @@ typedef struct
}
-/*
- * Indices of any supported baud rates.
- * Note that not each baud rate must be supported by
- * any clock model and/or port:
+/**
+ * @brief Enumeration of serial port baud rates
+ *
+ * @note Most clock models and/or serial ports don't support all defined baud rates.
+ *
+ * @see ::MBG_BAUD_RATES
+ * @see ::MBG_BAUD_RATE_MASKS
*/
-enum
+enum MBG_BAUD_RATE_CODES
{
MBG_BAUD_RATE_300,
MBG_BAUD_RATE_600,
@@ -1525,12 +2551,23 @@ enum
MBG_BAUD_RATE_9600,
MBG_BAUD_RATE_19200,
MBG_BAUD_RATE_38400,
- N_MBG_BAUD_RATES /* the number of supported baud rates */
+ MBG_BAUD_RATE_57600,
+ MBG_BAUD_RATE_115200,
+ MBG_BAUD_RATE_230400,
+ MBG_BAUD_RATE_460800,
+ MBG_BAUD_RATE_921600,
+ N_MBG_BAUD_RATES ///< the number of known baud rates
};
-/*
- * An initializer for a table of baud rate values.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of baud rate values
+ *
+ * These values can be used with ::COM_PARM::baud_rate, if the device
+ * supports the particular baud rate.
+ *
+ * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES
+ *
+ * @see ::MBG_BAUD_RATE_CODES
*/
#define MBG_BAUD_RATES \
{ \
@@ -1541,12 +2578,20 @@ enum
4800L, \
9600L, \
19200L, \
- 38400L \
+ 38400L, \
+ 57600L, \
+ 115200L, \
+ 230400L, \
+ 460800L, \
+ 921600L \
}
-/*
- * An initializer for a table of baud rate strings.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of baud rate strings
+ *
+ * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES
+ *
+ * @see ::MBG_BAUD_RATE_CODES
*/
#define MBG_BAUD_STRS \
{ \
@@ -1557,32 +2602,49 @@ enum
"4800", \
"9600", \
"19200", \
- "38400" \
+ "38400", \
+ "57600", \
+ "115200", \
+ "230400", \
+ "460800", \
+ "921600" \
}
-/*
- * The bit masks below can be used to determine which baud rates
- * are supported by a serial port. This may vary between
- * different ports of the same radio clock since different
- * types of UART are used which must not necessarily support
- * each baud rate:
- */
-#define MBG_PORT_HAS_300 ( 1UL << MBG_BAUD_RATE_300 )
-#define MBG_PORT_HAS_600 ( 1UL << MBG_BAUD_RATE_600 )
-#define MBG_PORT_HAS_1200 ( 1UL << MBG_BAUD_RATE_1200 )
-#define MBG_PORT_HAS_2400 ( 1UL << MBG_BAUD_RATE_2400 )
-#define MBG_PORT_HAS_4800 ( 1UL << MBG_BAUD_RATE_4800 )
-#define MBG_PORT_HAS_9600 ( 1UL << MBG_BAUD_RATE_9600 )
-#define MBG_PORT_HAS_19200 ( 1UL << MBG_BAUD_RATE_19200 )
-#define MBG_PORT_HAS_38400 ( 1UL << MBG_BAUD_RATE_38400 )
+/**
+ * @brief Bit masks associated with baud rates enumerated in ::MBG_BAUD_RATE_CODES
+ *
+ * These bit masks are used e.g. with ::PORT_INFO::supp_baud_rates to
+ * determine which baud rates are supported by a particular serial port.
+ *
+ * @see ::MBG_BAUD_RATE_CODES
+ * @see ::MBG_FRAMING_MASKS
+ */
+enum MBG_BAUD_RATE_MASKS
+{
+ MBG_PORT_HAS_300 = ( 1UL << MBG_BAUD_RATE_300 ), ///< see ::MBG_BAUD_RATE_300
+ MBG_PORT_HAS_600 = ( 1UL << MBG_BAUD_RATE_600 ), ///< see ::MBG_BAUD_RATE_600
+ MBG_PORT_HAS_1200 = ( 1UL << MBG_BAUD_RATE_1200 ), ///< see ::MBG_BAUD_RATE_1200
+ MBG_PORT_HAS_2400 = ( 1UL << MBG_BAUD_RATE_2400 ), ///< see ::MBG_BAUD_RATE_2400
+ MBG_PORT_HAS_4800 = ( 1UL << MBG_BAUD_RATE_4800 ), ///< see ::MBG_BAUD_RATE_4800
+ MBG_PORT_HAS_9600 = ( 1UL << MBG_BAUD_RATE_9600 ), ///< see ::MBG_BAUD_RATE_9600
+ MBG_PORT_HAS_19200 = ( 1UL << MBG_BAUD_RATE_19200 ), ///< see ::MBG_BAUD_RATE_19200
+ MBG_PORT_HAS_38400 = ( 1UL << MBG_BAUD_RATE_38400 ), ///< see ::MBG_BAUD_RATE_38400
+ MBG_PORT_HAS_57600 = ( 1UL << MBG_BAUD_RATE_57600 ), ///< see ::MBG_BAUD_RATE_57600
+ MBG_PORT_HAS_115200 = ( 1UL << MBG_BAUD_RATE_115200 ), ///< see ::MBG_BAUD_RATE_115200
+ MBG_PORT_HAS_230400 = ( 1UL << MBG_BAUD_RATE_230400 ), ///< see ::MBG_BAUD_RATE_230400
+ MBG_PORT_HAS_460800 = ( 1UL << MBG_BAUD_RATE_460800 ), ///< see ::MBG_BAUD_RATE_460800
+ MBG_PORT_HAS_921600 = ( 1UL << MBG_BAUD_RATE_921600 ) ///< see ::MBG_BAUD_RATE_921600
+};
-/*
- * Indices of any supported framings.
- * Note that not each framing must be supported by
- * any clock model and/or port:
+/**
+ * @brief Enumeration of all known serial port framings
+ *
+ * @note Most clock models and/or serial ports don't support all defined framing types.
+ *
+ * @see ::MBG_FRAMING_STRS
*/
-enum
+enum MBG_FRAMING_CODES
{
MBG_FRAMING_7N2,
MBG_FRAMING_7E1,
@@ -1593,12 +2655,21 @@ enum
MBG_FRAMING_7O1,
MBG_FRAMING_7O2,
MBG_FRAMING_8O1,
- N_MBG_FRAMINGS /* the number of supported framings */
+ MBG_FRAMING_8E2, ///< Note: most serial ports don't support this!
+ N_MBG_FRAMINGS ///< the number of known framings
};
-/*
- * An initializer for a table of framing strings.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of known framing strings
+ *
+ * These values can be used with ::COM_PARM::framing, if the device
+ * supports the particular framing.
+ *
+ * The values must correspond to the enumeration ::MBG_FRAMING_CODES
+ *
+ * @see ::MBG_FRAMING_CODES
+ * @see ::MBG_FRAMING_MASKS
+ * @see ::MBG_FRAMING_STR_IDXS
*/
#define MBG_FRAMING_STRS \
{ \
@@ -1610,25 +2681,80 @@ enum
"8E1", \
"7O1", \
"7O2", \
- "8O1" \
+ "8O1", \
+ "8E2" \
}
-/*
- * The bit masks below can be used to determine which framings
- * are supported by a serial port. This may vary between
- * different ports of the same radio clock since different
- * types of UART are used which must not necessarily support
- * each framing type:
+/**
+ * @brief Bit masks associated with framings enumerated in ::MBG_FRAMING_CODES
+ *
+ * These bit masks are used e.g. with ::PORT_INFO::supp_framings to
+ * determine which framings are supported by a particular serial port.
+ *
+ * @see ::MBG_FRAMING_CODES
+ * @see ::MBG_FRAMING_STRS
*/
-#define MBG_PORT_HAS_7N2 ( 1UL << MBG_FRAMING_7N2 )
-#define MBG_PORT_HAS_7E1 ( 1UL << MBG_FRAMING_7E1 )
-#define MBG_PORT_HAS_7E2 ( 1UL << MBG_FRAMING_7E2 )
-#define MBG_PORT_HAS_8N1 ( 1UL << MBG_FRAMING_8N1 )
-#define MBG_PORT_HAS_8N2 ( 1UL << MBG_FRAMING_8N2 )
-#define MBG_PORT_HAS_8E1 ( 1UL << MBG_FRAMING_8E1 )
-#define MBG_PORT_HAS_7O1 ( 1UL << MBG_FRAMING_7O1 )
-#define MBG_PORT_HAS_7O2 ( 1UL << MBG_FRAMING_7O2 )
-#define MBG_PORT_HAS_8O1 ( 1UL << MBG_FRAMING_8O1 )
+enum MBG_FRAMING_MASKS
+{
+ MBG_PORT_HAS_7N2 = ( 1UL << MBG_FRAMING_7N2 ), ///< see ::MBG_FRAMING_7N2
+ MBG_PORT_HAS_7E1 = ( 1UL << MBG_FRAMING_7E1 ), ///< see ::MBG_FRAMING_7E1
+ MBG_PORT_HAS_7E2 = ( 1UL << MBG_FRAMING_7E2 ), ///< see ::MBG_FRAMING_7E2
+ MBG_PORT_HAS_8N1 = ( 1UL << MBG_FRAMING_8N1 ), ///< see ::MBG_FRAMING_8N1
+ MBG_PORT_HAS_8N2 = ( 1UL << MBG_FRAMING_8N2 ), ///< see ::MBG_FRAMING_8N2
+ MBG_PORT_HAS_8E1 = ( 1UL << MBG_FRAMING_8E1 ), ///< see ::MBG_FRAMING_8E1
+ MBG_PORT_HAS_7O1 = ( 1UL << MBG_FRAMING_7O1 ), ///< see ::MBG_FRAMING_7O1
+ MBG_PORT_HAS_7O2 = ( 1UL << MBG_FRAMING_7O2 ), ///< see ::MBG_FRAMING_7O2
+ MBG_PORT_HAS_8O1 = ( 1UL << MBG_FRAMING_8O1 ), ///< see ::MBG_FRAMING_8O1
+ MBG_PORT_HAS_8E2 = ( 1UL << MBG_FRAMING_8E2 ) ///< see ::MBG_FRAMING_8E2
+};
+
+
+
+/**
+ * @brief Definitions used with the Meinberg binary protocol
+ *
+ * @anchor GPS_BIN_PROT_DEFS @{ */
+
+/**
+ * @brief Framing used with the binary protocol
+ *
+ * Different data length, or parity settings would corrupt
+ * the binary data.
+ */
+#define MBG_DEFAULT_FRAMING "8N1"
+
+/**
+ * @brief The standard baud rate used for the binary protocol
+ *
+ * This is supported by most devices. Some new devices may also
+ * support ::MBG_DEFAULT_BAUDRATE_HS
+ */
+#define MBG_DEFAULT_BAUDRATE 19200L
+
+/**
+ * @brief The high speed baud rate used for the binary protocol
+ *
+ * This is not supported by older devices which work
+ * with ::MBG_DEFAULT_BAUDRATE only.
+ */
+#define MBG_DEFAULT_BAUDRATE_HS 115200L
+
+
+/**
+ * @brief Strings used to force connection settings for the binary protocol
+ *
+ * If a device supports this and receives one of these ASCII strings
+ * then it temporarily switches the serial port to some well-known
+ * baud rate and framing appropriate for the binary protocol.
+ *
+ * @anchor GPS_BIN_PROT_CMD_STRS @{ */
+
+#define MBG_FORCE_CONN_CMD_STR "\nDFC\n" ///< switch to ::MBG_DEFAULT_BAUDRATE
+#define MBG_FORCE_CONN_HS_CMD_STR "\nDFCHS\n" ///< switch to ::MBG_DEFAULT_BAUDRATE_HS
+
+/** @} anchor GPS_BIN_PROT_CMD_STRS */
+
+/** @} anchor GPS_BIN_PROT_DEFS */
@@ -1685,17 +2811,19 @@ enum
)
-/*
- * The structure below is more flexible if different receiver
- * models have different numbers of serial ports, so the old
- * structure PORT_PARM will become obsolete.
+/**
+ * @brief Configuration settings of a serial port
+ *
+ * @note This should be used preferably instead of
+ * ::PORT_PARM, which is deprecated.
*/
typedef struct
{
- COM_PARM parm; /* speed, framing, etc. */
- uint8_t mode; /* per second, per minute, etc. */
- uint8_t str_type; /* type of the output string */
- uint32_t flags; /* reserved for future use, currently 0 */
+ COM_PARM parm; ///< transmission speed, framing, etc.
+ uint8_t mode; ///< string mode, see ::STR_MODES
+ uint8_t str_type; ///< index of the supported time string formats, see ::STR_TYPE_INFO_IDX
+ uint32_t flags; ///< reserved, don't use, currently 0
+
} PORT_SETTINGS;
#define _mbg_swab_port_settings( _p ) \
@@ -1705,59 +2833,81 @@ typedef struct
}
-/*
- * 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.
+/**
+ * @brief Flag bits used to mark individual ::PORT_SETTINGS fields
+ *
+ * These definitions can be used to mark specific fields of a
+ * ::PORT_SETTINGS structure, e.g. which fields have changed when
+ * editing, or which fields have settings which are not valid.
*/
-enum
+enum MBG_COM_CFG_STATUS_BITS
{
- 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 */
+ 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 )
+/**
+ * @brief Flag bit masks associated with ::MBG_COM_CFG_STATUS_BITS
+ *
+ * These definitions can be used to mark specific fields of a
+ * ::PORT_SETTINGS structure, e.g. which fields have changed when
+ * editing, or which fields have settings which are not valid.
+ *
+ * @anchor MBG_COM_CFG_STATUS_MASKS @{ */
+
+#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW ) ///< see ::MBG_PS_BIT_BAUD_RATE_OVR_SW
+#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV ) ///< see ::MBG_PS_BIT_BAUD_RATE_OVR_DEV
+#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE ) ///< see ::MBG_PS_BIT_BAUD_RATE
+#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW ) ///< see ::MBG_PS_BIT_FRAMING_OVR_SW
+#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV ) ///< see ::MBG_PS_BIT_FRAMING_OVR_DEV
+#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING ) ///< see ::MBG_PS_BIT_FRAMING
+#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW ) ///< see ::MBG_PS_BIT_HS_OVR_SW
+#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS ) ///< see ::MBG_PS_BIT_HS
+#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW ) ///< see ::MBG_PS_BIT_STR_TYPE_OVR_SW
+#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV ) ///< see ::MBG_PS_BIT_STR_TYPE_OVR_DEV
+#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE ) ///< see ::MBG_PS_BIT_STR_TYPE
+#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW ) ///< see ::MBG_PS_BIT_STR_MODE_OVR_SW
+#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV ) ///< see ::MBG_PS_BIT_STR_MODE_OVR_DEV
+#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE ) ///< see ::MBG_PS_BIT_STR_MODE
+#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW ) ///< see ::MBG_PS_BIT_FLAGS_OVR_SW
+#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS ) ///< see ::MBG_PS_BIT_FLAGS
+/** @} anchor MBG_COM_CFG_STATUS_MASKS */
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+
+/**
+ * @brief Configuration settings of a specific serial port
+ *
+ * This structure should be sent to a device to configure
+ * a specific serial port. The number of supported ports
+ * is ::RECEIVER_INFO::n_com_ports.
+ *
+ * @note The ::PORT_INFO_IDX structure should be read from
+ * a device to retrieve the current settings and capabilities.
+ *
+ * @see ::STR_TYPE_INFO
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ uint16_t idx; ///< port index, 0..::RECEIVER_INFO::n_com_ports-1
PORT_SETTINGS port_settings;
+
} PORT_SETTINGS_IDX;
#define _mbg_swab_port_settings_idx( _p ) \
@@ -1767,21 +2917,24 @@ typedef struct
}
-/*
- * The structure below holds the current settings
- * for a port, plus additional informaton on the
- * port's capabilities. This can be read by setup
- * programs to allow setup of supported features
- * only.
+/**
+ * @brief Current settings and general capabilities of a serial port
+ *
+ * @note This structure should be read from a device to retrieve
+ * the current settings of a serial port plus its capabilities,
+ * e.g. supported baud rates, supported string formats, etc.
+ *
+ * @see ::STR_TYPE_INFO
*/
typedef struct
{
- PORT_SETTINGS port_settings; /* COM port settings as defined above */
- uint32_t supp_baud_rates; /* bit mask of baud rates supp. by this port */
- uint32_t supp_framings; /* bit mask of framings supp. by this port */
- uint32_t supp_str_types; /* bit mask, bit 0 set if str_type[0] supp. */
- uint32_t reserved; /* reserved for future use, currently 0 */
- uint32_t flags; /* reserved for future use, currently 0 */
+ PORT_SETTINGS port_settings; ///< current configuration of the port
+ uint32_t supp_baud_rates; ///< bit mask of baud rates supp. by this port, see ::MBG_BAUD_RATE_MASKS
+ uint32_t supp_framings; ///< bit mask of framings supp. by this port, see ::MBG_FRAMING_MASKS
+ uint32_t supp_str_types; ///< bit mask of string types supp. by this port, i.e. bit 0 set if str_type[0] is supp.
+ uint32_t reserved; ///< reserved for future use, currently always 0
+ uint32_t flags; ///< see ::PORT_INFO_FLAGS
+
} PORT_INFO;
#define _mbg_swab_port_info( _p ) \
@@ -1795,14 +2948,47 @@ typedef struct
}
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+/**
+ * @brief Flags bits used to define ::PORT_INFO_FLAGS
+ *
+ * @see ::PORT_INFO_FLAGS
+ */
+enum PORT_INFO_FLAG_BITS
+{
+ PORT_INFO_FLAG_BIT_PORT_INVISIBLE, ///< port is used internally and should not be displayed by config apps
+ PORT_INFO_FLAG_BIT_BIN_PROT_HS, ///< port supports binary protocol at high speed, see ::MBG_DEFAULT_BAUDRATE_HS
+ N_PORT_INFO_FLAG_BITS ///< the number of defined bits
+};
+
+
+/**
+ * @brief Bit masks used with ::PORT_INFO::flags
+ *
+ * @see ::PORT_INFO_FLAG_BITS
+ */
+enum PORT_INFO_FLAGS
+{
+ PORT_INFO_FLAG_PORT_INVISIBLE = ( 1UL << PORT_INFO_FLAG_BIT_PORT_INVISIBLE ), ///< see ::PORT_INFO_FLAG_BIT_PORT_INVISIBLE
+ PORT_INFO_FLAG_BIN_PROT_HS = ( 1UL << PORT_INFO_FLAG_BIT_BIN_PROT_HS ) ///< see ::PORT_INFO_FLAG_BIT_BIN_PROT_HS
+};
+
+
+/**
+ * @brief Current settings and general capabilities of a specific serial port
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a specific serial port plus its capabilities,
+ * e.g. supported baud rates, supported string formats, etc.
+ * The number of supported ports is ::RECEIVER_INFO::n_com_ports.
+ *
+ * @note The ::PORT_SETTINGS_IDX structure should be send back to
+ * the device to configure the specified serial port.
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ uint16_t idx; ///< port index, 0..::RECEIVER_INFO::n_com_ports-1
PORT_INFO port_info;
+
} PORT_INFO_IDX;
#define _mbg_swab_port_info_idx( _p ) \
@@ -1812,17 +2998,25 @@ typedef struct
}
-/*
- * The structure below keeps information for a given
- * string type, e.g. which modes can be used with that
- * string type:
+/**
+ * @brief Information on a supported string format
+ *
+ * Information includes the name of the string format, which
+ * transmission modes are supported, etc.
+ *
+ * The number of string types, and which string types are supported
+ * depends on the device type and firmware version.
+ *
+ * @note Multiple structures ::STR_TYPE_INFO_IDX should be read
+ * to retrieve all supported string types.
*/
typedef struct
{
- uint32_t supp_modes; /* bit mask of modes supp. with this string type */
- char long_name[23]; /* long name of the string format */
- char short_name[11]; /* short name of the string format */
- uint16_t flags; /* reserved, currently always 0 */
+ uint32_t supp_modes; ///< bit mask of modes supp. for this string type, see ::STR_MODE_MASKS
+ char long_name[23]; ///< long name of the string format
+ char short_name[11]; ///< short name of the string format
+ uint16_t flags; ///< reserved, currently always 0
+
} STR_TYPE_INFO;
#define _mbg_swab_str_type_info( _p ) \
@@ -1833,14 +3027,22 @@ typedef struct
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+/**
+ * @brief Information on a specific supported string format
+ *
+ * This structure should be read from a device to retrieve information
+ * on a specific supported time string type from an array of supported
+ * string types. The number of supported string types is returned
+ * in ::RECEIVER_INFO::n_str_type.
+ *
+ * A selected index number can be saved in ::PORT_SETTINGS::str_type to
+ * configure the selected string type for the specific serial port.
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_str_type-1 */
+ uint16_t idx; ///< string type index, 0..::RECEIVER_INFO::n_str_type-1
STR_TYPE_INFO str_type_info;
+
} STR_TYPE_INFO_IDX;
#define _mbg_swab_str_type_info_idx( _p ) \
@@ -1850,22 +3052,49 @@ typedef struct
}
-/*
- * The codes below define valid modes for time strings,
- * i.e. the condition when a string is being sent
- * via the serial port:
+/**
+ * @brief Enumeration of modes supported for time string transmission
+ *
+ * This determines e.g. at which point in time a string starts
+ * to be transmitted via the serial port.
+ * Used with ::PORT_SETTINGS::mode.
+ *
+ * @see ::STR_MODE_MASKS
*/
-enum
+enum STR_MODES
+{
+ STR_ON_REQ, ///< transmission on request by received '?' character only
+ STR_PER_SEC, ///< transmission automatically if second changes
+ STR_PER_MIN, ///< transmission automatically if minute changes
+ STR_AUTO, ///< transmission automatically if required, e.g. on capture event
+ STR_ON_REQ_SEC, ///< transmission if second changes and a request has been received before
+ N_STR_MODE ///< the number of known modes
+};
+
+
+/**
+ * @brief Bit masks associated with ::STR_MODES
+ *
+ * Used with ::STR_TYPE_INFO::supp_modes to indicate which
+ * transmission modes are supported by the particular string type.
+ *
+ * @see ::STR_MODES
+ */
+enum STR_MODE_MASKS
{
- STR_ON_REQ, /* on request only */
- STR_PER_SEC, /* automatically if second changes */
- STR_PER_MIN, /* automatically if minute changes */
- STR_AUTO, /* automatically if required, e.g. on capture event */
- STR_ON_REQ_SEC, /* if second changes and a request has been received */
- N_STR_MODE /* the number of valid modes */
+ MSK_STR_ON_REQ = ( 1UL << STR_ON_REQ ), ///< see ::STR_ON_REQ
+ MSK_STR_PER_SEC = ( 1UL << STR_PER_SEC ), ///< see ::STR_PER_SEC
+ MSK_STR_PER_MIN = ( 1UL << STR_PER_MIN ), ///< see ::STR_PER_MIN
+ MSK_STR_AUTO = ( 1UL << STR_AUTO ), ///< see ::STR_AUTO
+ MSK_STR_ON_REQ_SEC = ( 1UL << STR_ON_REQ_SEC ) ///< see ::STR_ON_REQ_SEC
};
+/**
+ * @brief Initializer for short name strings associated with ::STR_MODES
+ *
+ * @see ::STR_MODES
+ */
#define DEFAULT_SHORT_MODE_NAMES \
{ \
"'?'", \
@@ -1876,9 +3105,12 @@ enum
}
-/*
- * Default initializers for English mode string names. Initializers
- * for multi-language strings can be found in pcpslstr.h.
+/**
+ * @brief Default initializers for English mode name strings
+ *
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::STR_MODES
*/
#define ENG_MODE_NAME_STR_ON_REQ "on request '?' only"
#define ENG_MODE_NAME_STR_PER_SEC "per second"
@@ -1886,6 +3118,14 @@ enum
#define ENG_MODE_NAME_STR_AUTO "automatically"
#define ENG_MODE_NAME_STR_ON_REQ_SEC "sec after request"
+
+/**
+ * @brief Initializer for an English mode name string table
+ *
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::STR_MODES
+ */
#define DEFAULT_ENG_MODE_NAMES \
{ \
ENG_MODE_NAME_STR_ON_REQ, \
@@ -1895,17 +3135,6 @@ enum
ENG_MODE_NAME_STR_ON_REQ_SEC \
}
-/*
- * The definitions below are used to set up bit masks
- * which restrict the modes which can be used with
- * a given string type:
- */
-#define MSK_STR_ON_REQ ( 1UL << STR_ON_REQ )
-#define MSK_STR_PER_SEC ( 1UL << STR_PER_SEC )
-#define MSK_STR_PER_MIN ( 1UL << STR_PER_MIN )
-#define MSK_STR_AUTO ( 1UL << STR_AUTO )
-#define MSK_STR_ON_REQ_SEC ( 1UL << STR_ON_REQ_SEC )
-
/*
* The modes below are supported by most string types:
@@ -1929,9 +3158,11 @@ enum
-/**
- * The number of serial ports which were available
- * with all GPS receiver models:
+/*
+ * The number of serial ports which are at least available
+ * even with very old GPS receiver models. For devices providing
+ * a ::RECEIVER_INFO structure the number of provided COM ports
+ * is available in ::RECEIVER_INFO::n_com_ports.
*/
#define DEFAULT_N_COM 2
@@ -1944,13 +3175,16 @@ enum
#endif
/**
- * The structure used to store the modes of both serial ports:<br>
- * <b>(now obsolete)</b>
+ * @brief A The structure used to store the configuration of two serial ports
+ *
+ * @deprecated This structure is deprecated, ::PORT_SETTINGS and related structures
+ * should be used instead, if supported by the device.
*/
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 ) \
@@ -1964,10 +3198,14 @@ typedef struct
}
-/*
- * The codes below were used with the obsolete
- * PORT_PARM.mode above. They are defined for
- * compatibility with older devices only:
+/**
+ * @brief Deprecated codes for mode of operation
+ *
+ * @deprecated These codes have been used with the
+ * deprecated ::PORT_PARM::mode. They are only still
+ * defined for compatibility with older devices.
+ *
+ * @see ::STR_MODES
*/
enum
{
@@ -1983,75 +3221,91 @@ enum
/**
- @defgroup group_icode IRIG Codes
-
- The following definitions are used to configure an optional
- on-board IRIG input or output. Which frame types are supported
- by a device depends on the device type, and may eventually
- depend on the device's firmware version.
-
- All IRIG frames transport the day-of-year number plus the time-of-day,
- and include a control field segment which can transport user defined
- information.
-
- Some newer IRIG frames are compatible with older frame types but support
- well defined extensions like the year number, local time offset, DST status,
- etc., in the control fields:
-
- - Supported IRIG signal code types:
- - \b A002: 1000 bps, DCLS, time-of-year
- - \b A003: 1000 bps, DCLS, time-of-year, SBS
- - \b A132: 1000 bps, 10 kHz carrier, time-of-year
- - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
- - \b B002: 100 bps, DCLS, time-of-year
- - \b B003: 100 bps, DCLS, time-of-year, SBS
- - \b B122: 100 bps, 1 kHz carrier, time-of-year
- - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
- - \b B006: 100 bps, DCLS, complete date
- - \b B007: 100 bps, DCLS, complete date, SBS
- - \b B126: 100 bps, 1 kHz carrier, complete date
- - \b B127: 100 bps, 1 kHz carrier, complete date, SBS
- - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions
- - \b B222: 100 bps, DCLS, manchester encoded, time-of-year
- - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS
- - \b G002: 10 kbps, DCLS, time-of-year
- - \b G142: 10 kbps, 100 kHz carrier, time-of-year
- - \b G006: 10 kbps, DCLS, complete date
- - \b G146: 10 kbps, 100 kHz carrier, complete date
- - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
- - <b> AFNOR DC:</b> 100 bps, DCLS, SBS, complete date
- - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE1344 extensions (B120)
- - <b> IEEE1344 DC:</b> 100 bps, DCLS, time-of-year, SBS, IEEE1344 extensions (B000)
- - \b C37.118: like IEEE1344, but UTC offset with reversed sign
- - \b C37.118 DC: like IEEE1344 DC, but UTC offset with reversed sign
-
- - time-of-year: day-of-year, hours, minutes, seconds
- - complete date: time-of-year plus year number
- - SBS: straight binary seconds, second-of-day
-
- AFNOR codes are based on the french standard AFNOR NF S87-500
-
- IEEE1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible
- with B002/B122 but provides some welldefined extensions in the control field which
- include a quality indicator (time figure of merit, TFOM), year number, DST and leap
- second status, and local time offset from UTC.
-
- C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version
- of the IEEE1344 standard from 1995. These codes provide the same extensions as IEEE1344
- but unfortunately define the UTC offset with reversed sign.
-
- <b>ATTENTION:</b> There are 3rd party IRIG devices out there which apply the UTC offset
- as specified in C37.118, but claim to be compatible with IEEE1344. So if local time is
- transmitted in the IRIG signal then care must be taken that the UTC offset is evaluated
- by the IRIG receiver in the same way as output by the IRIG generator. Otherwise the UTC
- time computed by the receiver may be wrong.
- @{
- */
-
-/**
- * Definitions used with IRIG transmitters which usually output both
- * the unmodulated and the modulated IRIG signals at the same time: */
-enum
+ * @defgroup group_icode IRIG time codes
+ *
+ * The following definitions are used to configure an optional
+ * on-board IRIG input or output. Which frame types are supported
+ * by a device depends on the device type, and may eventually
+ * depend on the device's firmware version.
+ *
+ * All IRIG frames transport the day-of-year number plus the time-of-day,
+ * and include a control field segment which can transport user defined
+ * information.
+ *
+ * Some newer IRIG frames are compatible with older frame types but support
+ * well defined extensions like the year number, local time offset, DST status,
+ * etc., in the control fields:
+ *
+ * - Known IRIG signal code types:
+ * - \b A002: 1000 bps, DCLS, time-of-year
+ * - \b A003: 1000 bps, DCLS, time-of-year, SBS
+ * - \b A132: 1000 bps, 10 kHz carrier, time-of-year
+ * - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
+ * - \b B002: 100 bps, DCLS, time-of-year
+ * - \b B003: 100 bps, DCLS, time-of-year, SBS
+ * - \b B122: 100 bps, 1 kHz carrier, time-of-year
+ * - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
+ * - \b B006: 100 bps, DCLS, complete date
+ * - \b B007: 100 bps, DCLS, complete date, SBS
+ * - \b B126: 100 bps, 1 kHz carrier, complete date
+ * - \b B127: 100 bps, 1 kHz carrier, complete date, SBS
+ * - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions
+ * - \b B222: 100 bps, DCLS, manchester encoded, time-of-year
+ * - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS
+ * - \b G002: 10 kbps, DCLS, time-of-year
+ * - \b G142: 10 kbps, 100 kHz carrier, time-of-year
+ * - \b G006: 10 kbps, DCLS, complete date
+ * - \b G146: 10 kbps, 100 kHz carrier, complete date
+ * - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
+ * - \b AFNOR DC: 100 bps, DCLS, SBS, complete date
+ * - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE 1344 extensions (B120)
+ * - \b IEEE1344 DC: 100 bps, DCLS, time-of-year, SBS, IEEE 1344 extensions (B000)
+ * - \b C37.118: like IEEE 1344, but %UTC offset applied with reversed sign
+ * - \b C37.118 DC: like IEEE 1344 DC, but %UTC offset applied with reversed sign
+ *
+ * - time-of-year: day-of-year, hours, minutes, seconds
+ * - complete date: time-of-year plus year number
+ * - SBS: straight binary seconds, second-of-day
+ *
+ * AFNOR codes are based on the french standard AFNOR NF S87-500
+ *
+ * IEEE 1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible
+ * with B002/B122 but provides some well defined extensions in the control field which
+ * include a quality indicator (time figure of merit, TFOM), year number, DST and leap
+ * second status, and local time offset from %UTC.
+ *
+ * IEEE C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version
+ * of the IEEE 1344 standard from 1995. These codes provide the same extensions as IEEE 1344
+ * but unfortunately determine that the %UTC offset has to be applied with reversed sign.
+ *
+ * For example, if a -6 hours UTC offset is transmitted in the time code:<br>
+ * IEEE 1344: (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)<br>
+ * IEEE C37.118: (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)<br>
+ *
+ * @see @ref MSK_ICODE_RX_UTC_OFFS_ADD and @ref MSK_ICODE_RX_UTC_OFFS_SUB
+ *
+ * @note There are 3rd party IRIG devices out there which apply the %UTC offset as specified
+ * in IEEE C37.118-2005, but claim to be compatible with IEEE 1344. So if local time is transmitted
+ * by the timecode then care must be taken that the %UTC offset is evaluated by the timecode
+ * receiver in the same way as computed by the timecode generator. Otherwise the %UTC
+ * time computed by the receiver may be <b>wrong</b>.
+ *
+ * @{ */
+
+/**
+ * @brief Known IRIG TX code formats
+ *
+ * Used with ::IRIG_SETTINGS::icode for IRIG transmitters.
+ * For IRIG receivers see ::ICODE_RX_CODES.
+ *
+ * Meinberg timecode transmitters always generate the unmodulated (DCLS)
+ * and usually the modulated timecode signals internally at the same time,
+ * so the code definitions always refer to both.
+ *
+ * @note Not all device may provide both the modulated and unmodulated
+ * signal externally.
+ */
+enum ICODE_TX_CODES
{
ICODE_TX_B002_B122,
ICODE_TX_B003_B123,
@@ -2059,20 +3313,25 @@ enum
ICODE_TX_A003_A133,
ICODE_TX_AFNOR,
ICODE_TX_IEEE1344,
- ICODE_TX_B2201344, // DCLS only
- ICODE_TX_B222, // DCLS only
- ICODE_TX_B223, // DCLS only
+ ICODE_TX_B2201344, ///< DCLS only
+ ICODE_TX_B222, ///< DCLS only
+ ICODE_TX_B223, ///< DCLS only
ICODE_TX_B006_B126,
ICODE_TX_B007_B127,
ICODE_TX_G002_G142,
ICODE_TX_G006_G146,
ICODE_TX_C37118,
- N_ICODE_TX /**< number of code types */
+ ICODE_TX_TXC101,
+ ICODE_TX_E002_E112,
+ ICODE_TX_NASA36,
+ N_ICODE_TX ///< number of known codes
};
/**
- * Initializers for format name strings.
+ * @brief Initializers for timecode format name strings
+ *
+ * @see ::ICODE_TX_CODES
*/
#define DEFAULT_ICODE_TX_NAMES \
{ \
@@ -2089,12 +3348,18 @@ enum
"B007+B127", \
"G002+G142", \
"G006+G146", \
- "C37.118" \
+ "C37.118", \
+ "TXC-101 DTR-6", \
+ "E002+E112", \
+ "NASA 36" \
}
/**
- * Initializers for short name strings which must not
- * be longer than 10 printable characters.
+ * @brief Initializers for short timecode format name strings
+ *
+ * @note Must not be longer than 10 printable characters
+ *
+ * @see ::ICODE_TX_CODES
*/
#define DEFAULT_ICODE_TX_NAMES_SHORT \
{ \
@@ -2102,7 +3367,7 @@ enum
"B003+B123", \
"A002+A132", \
"A003+A133", \
- "AFNOR NF-S", \
+ "AFNOR NF S", \
"IEEE1344", \
"B220/1344", \
"B222 DC", \
@@ -2111,12 +3376,17 @@ enum
"B007+B127", \
"G002+G142", \
"G006+G146", \
- "C37.118" \
+ "C37.118", \
+ "TXC-101", \
+ "E002+E112", \
+ "NASA 36" \
}
/**
- * Initializers for English format description strings.
+ * @brief Initializers for English format description strings
+ *
+ * @see ::ICODE_TX_CODES
*/
#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \
{ \
@@ -2133,14 +3403,24 @@ enum
"100 bps, DCLS or 1 kHz carrier, complete date, SBS", \
"10 kbps, DCLS or 100 kHz carrier", \
"10 kbps, DCLS or 100 kHz carrier, complete date", \
- "like IEEE1344, but UTC offset with reversed sign" \
+ "like IEEE1344, but UTC offset with reversed sign", \
+ "code from TV time sync device TXC-101 DTR-6", \
+ "10 bps, DCLS or 100 Hz carrier", \
+ "100 bps, DCLS or 1 kHz carrier" \
}
-/*
- * The definitions below are used to set up bit masks
- * which restrict the IRIG formats which are supported
- * by a given IRIG transmitter device:
- */
+
+/**
+ * @brief Bit masks used with ::IRIG_INFO::supp_codes
+ *
+ * These bit masks are used with timecode receivers only
+ *
+ * @see @ref ICODE_TX_CODES
+ * @see @ref ICODE_RX_CODES
+ * @see @ref ICODE_RX_MASKS
+ *
+ * @anchor ICODE_TX_MASKS @{ */
+
#define MSK_ICODE_TX_B002_B122 ( 1UL << ICODE_TX_B002_B122 )
#define MSK_ICODE_TX_B003_B123 ( 1UL << ICODE_TX_B003_B123 )
#define MSK_ICODE_TX_A002_A132 ( 1UL << ICODE_TX_A002_A132 )
@@ -2155,19 +3435,33 @@ enum
#define MSK_ICODE_TX_G002_G142 ( 1UL << ICODE_TX_G002_G142 )
#define MSK_ICODE_TX_G006_G146 ( 1UL << ICODE_TX_G006_G146 )
#define MSK_ICODE_TX_C37118 ( 1UL << ICODE_TX_C37118 )
+#define MSK_ICODE_TX_TXC101 ( 1UL << ICODE_TX_TXC101 )
+#define MSK_ICODE_TX_E002_E112 ( 1UL << ICODE_TX_E002_E112 )
+#define MSK_ICODE_TX_NASA36 ( 1UL << ICODE_TX_NASA36 )
+
+/** @} anchor ICODE_TX_MASKS */
+
/**
- * A mask of IRIG formats with manchester encoded DC output:
+ * @brief A mask of IRIG formats with manchester encoded DC output
*/
#define MSK_ICODE_TX_DC_MANCH \
( \
- MSK_ICODE_TX_B2201344 | \
- MSK_ICODE_TX_B222 | \
+ MSK_ICODE_TX_B2201344 | \
+ MSK_ICODE_TX_B222 | \
MSK_ICODE_TX_B223 \
)
/**
- * A mask of IRIG formats with 1 kHz carrier:
+ * @brief A mask of IRIG formats with 100 Hz carrier
+ */
+#define MSK_ICODE_TX_100HZ \
+( \
+ MSK_ICODE_TX_E002_E112 \
+)
+
+/**
+ * @brief A mask of IRIG formats with 1 kHz carrier
*/
#define MSK_ICODE_TX_1KHZ \
( \
@@ -2180,11 +3474,12 @@ enum
MSK_ICODE_TX_B223 | \
MSK_ICODE_TX_B006_B126 | \
MSK_ICODE_TX_B007_B127 | \
- MSK_ICODE_TX_C37118 \
+ MSK_ICODE_TX_C37118 | \
+ MSK_ICODE_TX_NASA36 \
)
/**
- * A mask of IRIG formats with 10 kHz carrier:
+ * @brief A mask of IRIG formats with 10 kHz carrier
*/
#define MSK_ICODE_TX_10KHZ \
( \
@@ -2193,67 +3488,163 @@ enum
)
/**
- * A mask of IRIG formats with 100 kHz carrier:
+ * @brief A mask of IRIG formats with 100 kHz carrier
*/
#define MSK_ICODE_TX_100KHZ \
( \
- MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G002_G142 | \
MSK_ICODE_TX_G006_G146 \
)
/**
- * A mask of IRIG formats with 100 bps data rate:
+ * @brief A mask of IRIG formats with 10 bps data rate
+ */
+#define MSK_ICODE_TX_10BPS \
+( \
+ MSK_ICODE_TX_E002_E112 \
+)
+
+/**
+ * @brief A mask of IRIG formats with 100 bps data rate
*/
#define MSK_ICODE_TX_100BPS \
( \
- MSK_ICODE_TX_B002_B122 | \
- MSK_ICODE_TX_B003_B123 | \
- MSK_ICODE_TX_AFNOR | \
- MSK_ICODE_TX_IEEE1344 | \
- MSK_ICODE_TX_B006_B126 | \
- MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_B002_B122 | \
+ MSK_ICODE_TX_B003_B123 | \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_B006_B126 | \
+ MSK_ICODE_TX_B007_B127 | \
MSK_ICODE_TX_C37118 \
)
/**
- * A mask of IRIG formats with 1000 bps data rate:
+ * @brief A mask of IRIG formats with 1000 bps data rate
*/
#define MSK_ICODE_TX_1000BPS \
( \
- MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A002_A132 | \
MSK_ICODE_TX_A003_A133 \
)
/**
- * A mask of IRIG formats with 10 kbps data rate:
+ * @brief A mask of IRIG formats with 10 kbps data rate
*/
#define MSK_ICODE_TX_10000BPS \
( \
- MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G002_G142 | \
MSK_ICODE_TX_G006_G146 \
)
/**
- * A mask of IRIG formats which support TFOM:
+ * @brief A mask of IRIG formats supporting 10ths of seconds
+ */
+#define MSK_ICODE_TX_HAS_SEC10THS \
+( \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 | \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting 100ths of seconds
+ */
+#define MSK_ICODE_TX_HAS_SEC100THS \
+( \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a 2 digit year number
+ */
+#define MSK_ICODE_TX_HAS_SHORT_YEAR \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_B006_B126 | \
+ MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_C37118 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting TFOM
*/
#define MSK_ICODE_TX_HAS_TFOM \
( \
- MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_C37118 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting CTQ continuous time quality
+ *
+ * This has been introduced in IEEE C37.118.1-2011
+ */
+#define MSK_ICODE_TX_HAS_CTQ \
+( \
+ MSK_ICODE_TX_IEEE1344 | \
MSK_ICODE_TX_C37118 \
)
/**
- * A mask of IRIG formats which support time zone information:
+ * @brief A mask of IRIG formats supporting time zone information
*/
#define MSK_ICODE_TX_HAS_TZI \
( \
- MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_IEEE1344 | \
MSK_ICODE_TX_C37118 \
)
/**
- * The default mask of IRIG formats supported by
- * IRIG transmitters:
+ * @brief IRIG formats where UTC offset must be subtracted to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)
+ */
+#define MSK_ICODE_TX_UTC_OFFS_SUB \
+( \
+ MSK_ICODE_TX_IEEE1344 \
+)
+
+/**
+ * @brief IRIG formats where UTC offset must be added to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)
+ */
+#define MSK_ICODE_TX_UTC_OFFS_ADD \
+( \
+ MSK_ICODE_TX_C37118 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a day of week number
+ */
+#define MSK_ICODE_TX_HAS_AFNOR_WDAY \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_AFNOR_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a date (day-of-month, month)
+ */
+#define MSK_ICODE_TX_HAS_AFNOR_DATE \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_AFNOR_DC \
+)
+
+
+/**
+ * @brief The default mask of IRIG formats supported by IRIG transmitters
+ *
+ * @note The formats which are actually supported should be retrieved
+ * from the device
*/
#if !defined( SUPP_MSK_ICODE_TX )
#define SUPP_MSK_ICODE_TX \
@@ -2269,33 +3660,46 @@ enum
/**
- * Definitions used with IRIG receivers which decode
- * two similar IRIG codes (with or without SBS)
- * at the same time.
+ * @brief Known IRIG RX code formats
+ *
+ * Used with ::IRIG_SETTINGS::icode for IRIG receivers.
+ * For IRIG transmitters see ::ICODE_TX_CODES.
+ *
+ * The SBS value is redundant and can easily by computed
+ * from the time-of-day, so Meinberg time code receivers
+ * usually don't evaluate the SBS field anyway, and thus
+ * it makes no difference if a code with or withour SBS
+ * is supplied.
*/
-enum
+enum ICODE_RX_CODES
{
- ICODE_RX_B122_B123, // modulated
- ICODE_RX_A132_A133, // modulated
- ICODE_RX_B002_B003, // DCLS
- ICODE_RX_A002_A003, // DCLS
- ICODE_RX_AFNOR, // modulated
- ICODE_RX_AFNOR_DC, // DCLS
- ICODE_RX_IEEE1344, // modulated
- ICODE_RX_IEEE1344_DC, // DCLS
- ICODE_RX_B126_B127, // modulated
- ICODE_RX_B006_B007, // DCLS
- ICODE_RX_G142_G146, // modulated
- ICODE_RX_G002_G006, // DCLS
- ICODE_RX_C37118, // modulated
- ICODE_RX_C37118_DC, // DCLS
- ICODE_RX_TXC_101, // modulated
- ICODE_RX_TXC_101_DC, // DCLS
- N_ICODE_RX /* the number of valid signal code types */
+ ICODE_RX_B122_B123, ///< modulated
+ ICODE_RX_A132_A133, ///< modulated
+ ICODE_RX_B002_B003, ///< DCLS
+ ICODE_RX_A002_A003, ///< DCLS
+ ICODE_RX_AFNOR, ///< modulated
+ ICODE_RX_AFNOR_DC, ///< DCLS
+ ICODE_RX_IEEE1344, ///< modulated
+ ICODE_RX_IEEE1344_DC, ///< DCLS
+ ICODE_RX_B126_B127, ///< modulated
+ ICODE_RX_B006_B007, ///< DCLS
+ ICODE_RX_G142_G146, ///< modulated
+ ICODE_RX_G002_G006, ///< DCLS
+ ICODE_RX_C37118, ///< modulated
+ ICODE_RX_C37118_DC, ///< DCLS
+ ICODE_RX_TXC101, ///< modulated
+ ICODE_RX_TXC101_DC, ///< DCLS
+ ICODE_RX_E112, ///< modulated
+ ICODE_RX_E002, ///< DCLS
+ ICODE_RX_NASA36, ///< modulated
+ ICODE_RX_NASA36_DC, ///< DCLS
+ N_ICODE_RX ///< the number of known codes
};
/**
- * Initializers for format name strings.
+ * @brief Initializers for timecode format name strings
+ *
+ * @see ::ICODE_RX_CODES
*/
#define DEFAULT_ICODE_RX_NAMES \
{ \
@@ -2314,12 +3718,19 @@ enum
"C37.118", \
"C37.118 (DCLS)", \
"TXC-101 DTR-6", \
- "TXC-101 DTR-6 (DCLS)" \
+ "TXC-101 DTR-6 (DCLS)", \
+ "E112", \
+ "E002 (DCLS)", \
+ "NASA-36", \
+ "NASA-36 (DCLS)" \
}
/**
- * Initializers for short name strings which must not
- * be longer than 11 printable characters.
+ * @brief Initializers for short timecode format name strings
+ *
+ * @note Must not be longer than 11 printable characters
+ *
+ * @see ::ICODE_RX_CODES
*/
#define DEFAULT_ICODE_RX_NAMES_SHORT \
{ \
@@ -2327,7 +3738,7 @@ enum
"A132/A133", \
"B002/B003", \
"A002/A003", \
- "AFNOR NF-S", \
+ "AFNOR NF S", \
"AFNOR DC", \
"IEEE1344", \
"IEEE1344 DC", \
@@ -2338,12 +3749,18 @@ enum
"C37.118", \
"C37.118 DC", \
"TXC-101", \
- "TXC-101 DC" \
+ "TXC-101 DC", \
+ "E112", \
+ "E002 DC", \
+ "NASA-36", \
+ "NASA-36 DC" \
}
/**
- * Initializers for English format description strings.
+ * @brief Initializers for English format description strings
+ *
+ * @see ::ICODE_RX_CODES
*/
#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
{ \
@@ -2362,12 +3779,24 @@ enum
"like IEEE1344, but UTC offset with reversed sign", \
"like IEEE1344 DC, but UTC offset with reversed sign", \
"code from TV time sync device TXC-101 DTR-6", \
- "DC code from TV time sync device TXC-101 DTR-6" \
+ "DC code from TV time sync device TXC-101 DTR-6", \
+ "10 bps, 100 Hz carrier", \
+ "10 bps, DCLS", \
+ "100 bps, 1 kHz carrier", \
+ "100 bps, DCLS" \
}
-/*
- * Bit masks corresponding to the enumeration above:
- */
+/**
+ * @brief Bit masks used with ::IRIG_INFO::supp_codes
+ *
+ * These bit masks are used with timecode receivers only
+ *
+ * @see @ref ICODE_RX_CODES
+ * @see @ref ICODE_TX_CODES
+ * @see @ref ICODE_TX_MASKS
+ *
+ * @anchor ICODE_RX_MASKS @{ */
+
#define MSK_ICODE_RX_B122_B123 ( 1UL << ICODE_RX_B122_B123 )
#define MSK_ICODE_RX_A132_A133 ( 1UL << ICODE_RX_A132_A133 )
#define MSK_ICODE_RX_B002_B003 ( 1UL << ICODE_RX_B002_B003 )
@@ -2382,11 +3811,18 @@ enum
#define MSK_ICODE_RX_G002_G006 ( 1UL << ICODE_RX_G002_G006 )
#define MSK_ICODE_RX_C37118 ( 1UL << ICODE_RX_C37118 )
#define MSK_ICODE_RX_C37118_DC ( 1UL << ICODE_RX_C37118_DC )
-#define MSK_ICODE_RX_TXC_101 ( 1UL << ICODE_RX_TXC_101 )
-#define MSK_ICODE_RX_TXC_101_DC ( 1UL << ICODE_RX_TXC_101_DC )
+#define MSK_ICODE_RX_TXC101 ( 1UL << ICODE_RX_TXC101 )
+#define MSK_ICODE_RX_TXC101_DC ( 1UL << ICODE_RX_TXC101_DC )
+#define MSK_ICODE_RX_E112 ( 1UL << ICODE_RX_E112 )
+#define MSK_ICODE_RX_E002 ( 1UL << ICODE_RX_E002 )
+#define MSK_ICODE_RX_NASA36 ( 1UL << ICODE_RX_NASA36 )
+#define MSK_ICODE_RX_NASA36_DC ( 1UL << ICODE_RX_NASA36_DC )
+
+/** @} anchor ICODE_RX_MASKS */
+
/**
- * A mask of IRIG DCLS formats:
+ * @brief A mask of IRIG DCLS formats
*/
#define MSK_ICODE_RX_DC \
( \
@@ -2396,11 +3832,23 @@ enum
MSK_ICODE_RX_IEEE1344_DC | \
MSK_ICODE_RX_B006_B007 | \
MSK_ICODE_RX_G002_G006 | \
- MSK_ICODE_RX_C37118_DC \
+ MSK_ICODE_RX_C37118_DC | \
+ MSK_ICODE_RX_TXC101_DC | \
+ MSK_ICODE_RX_E002 | \
+ MSK_ICODE_RX_NASA36_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats with 100 Hz carrier
+ */
+#define MSK_ICODE_RX_100HZ \
+( \
+ MSK_ICODE_RX_E112 | \
+ MSK_ICODE_RX_E002 \
)
/**
- * A mask of IRIG formats with 1 kHz carrier:
+ * @brief A mask of IRIG formats with 1 kHz carrier
*/
#define MSK_ICODE_RX_1KHZ \
( \
@@ -2408,11 +3856,13 @@ enum
MSK_ICODE_RX_AFNOR | \
MSK_ICODE_RX_IEEE1344 | \
MSK_ICODE_RX_B126_B127 | \
- MSK_ICODE_RX_C37118 \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_TXC101 | \
+ MSK_ICODE_RX_NASA36 \
)
/**
- * A mask of IRIG formats with 10 kHz carrier:
+ * @brief A mask of IRIG formats with 10 kHz carrier
*/
#define MSK_ICODE_RX_10KHZ \
( \
@@ -2420,7 +3870,7 @@ enum
)
/**
- * A mask of IRIG formats with 100 kHz carrier:
+ * @brief A mask of IRIG formats with 100 kHz carrier
*/
#define MSK_ICODE_RX_100KHZ \
( \
@@ -2428,7 +3878,16 @@ enum
)
/**
- * A mask of IRIG formats with 100 bps data rate:
+ * @brief A mask of IRIG formats with 10 bps data rate
+ */
+#define MSK_ICODE_RX_10BPS \
+( \
+ MSK_ICODE_RX_E002_E112 | \
+ MSK_ICODE_RX_E002_E002 \
+)
+
+/**
+ * @brief A mask of IRIG formats with 100 bps data rate
*/
#define MSK_ICODE_RX_100BPS \
( \
@@ -2441,28 +3900,68 @@ enum
MSK_ICODE_RX_B126_B127 | \
MSK_ICODE_RX_B006_B007 | \
MSK_ICODE_RX_C37118 | \
- MSK_ICODE_RX_C37118_DC \
+ MSK_ICODE_RX_C37118_DC | \
+ MSK_ICODE_RX_TXC101 | \
+ MSK_ICODE_RX_TXC101_DC | \
+ MSK_ICODE_RX_NASA36 | \
+ MSK_ICODE_RX_NASA36_DC \
)
/**
- * A mask of IRIG formats with 1000 bps data rate:
+ * @brief A mask of IRIG formats with 1000 bps data rate
*/
#define MSK_ICODE_RX_1000BPS \
( \
- MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A132_A133 | \
MSK_ICODE_RX_A002_A003 \
)
/**
- * A mask of IRIG formats with 10 kbps data rate:
+ * @brief A mask of IRIG formats with 10 kbps data rate
*/
#define MSK_ICODE_RX_10000BPS \
( \
- MSK_ICODE_RX_G142_G146 \
+ MSK_ICODE_RX_G142_G146 | \
+ MSK_ICODE_RX_G002_G006 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting 10ths of seconds
+ */
+#define MSK_ICODE_RX_HAS_SEC10THS \
+( \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_G142_G146 | \
+ MSK_ICODE_RX_G002_G006 \
)
/**
- * A mask of IRIG formats which support TFOM:
+ * @brief A mask of IRIG formats which support 100ths of seconds
+ */
+#define MSK_ICODE_RX_HAS_SEC100THS \
+( \
+ MSK_ICODE_RX_G142_G146 | \
+ MSK_ICODE_RX_G002_G006 \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a 2 digit year number
+ */
+#define MSK_ICODE_RX_HAS_SHORT_YEAR \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B126_B127 | \
+ MSK_ICODE_RX_B006_B007 | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting TFOM time quality indicator
*/
#define MSK_ICODE_RX_HAS_TFOM \
( \
@@ -2473,7 +3972,20 @@ enum
)
/**
- * A mask of IRIG formats which support time zone information:
+ * @brief A mask of IRIG formats supporting CTQ continuous time quality
+ *
+ * This has been introduced in IEEE C37.118.1-2011
+ */
+#define MSK_ICODE_RX_HAS_CTQ \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting time zone information
*/
#define MSK_ICODE_RX_HAS_TZI \
( \
@@ -2484,8 +3996,55 @@ enum
)
/**
- * The default mask of IRIG formats supported by
- * IRIG receivers:
+ * @brief IRIG formats where UTC offset must be subtracted to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)
+ */
+#define MSK_ICODE_RX_UTC_OFFS_SUB \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC \
+)
+
+/**
+ * @brief IRIG formats where UTC offset must be added to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)
+ */
+#define MSK_ICODE_RX_UTC_OFFS_ADD \
+( \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a day of week number
+ */
+#define MSK_ICODE_RX_HAS_AFNOR_WDAY \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC \
+)
+
+/**
+ * @brief A mask of IRIG formats supporting a date (day-of-month, month)
+ */
+#define MSK_ICODE_RX_HAS_AFNOR_DATE \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC \
+)
+
+
+/**
+ * @brief The default mask of IRIG formats supported by IRIG receivers
+ *
+ * @note The formats which are actually supported should be retrieved
+ * from the device
*/
#if !defined( SUPP_MSK_ICODE_RX )
#define SUPP_MSK_ICODE_RX \
@@ -2498,18 +4057,21 @@ enum
MSK_ICODE_RX_AFNOR_DC \
)
#endif
-/** @} */
+
+/** @} defgroup group_icode */
/**
- * The structure below is used to configure an optional
- * on-board IRIG output:
+ * @brief Configuration settings of an IRIG input or output
+ *
+ * @see @ref group_icode
*/
typedef struct
{
- uint16_t icode; /**< IRIG signal code, see \ref group_icode */
- uint16_t flags; /**< see \ref group_irig_flags */
+ uint16_t icode; ///< IRIG signal code, see ::ICODE_RX_CODES and ::ICODE_TX_CODES
+ uint16_t flags; ///< see ::IFLAGS_BIT_MASKS
+
} IRIG_SETTINGS;
#define _mbg_swab_irig_settings( _p ) \
@@ -2519,35 +4081,51 @@ typedef struct
}
-/**
- @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS::flags
- (others are reserved)
-* @{
+/**
+ * @brief Flag bits used to define ::IFLAGS_BIT_MASKS
+ *
+ * @see ::IFLAGS_BIT_MASKS
*/
-#define IFLAGS_DISABLE_TFOM 0x0001 /**< RX ignore/TX don't gen TFOM */
-#define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /**< gen local time, not UTC */
+enum IFLAGS_BITS
+{
+ IFLAGS_BIT_DISABLE_TFOM, ///< for RX ignore, for TX don't generate TFOM flag
+ IFLAGS_BIT_TX_GEN_LOCAL_TIME, ///< TX output local time instead of %UTC
+ N_IFLAGS_BITS ///< number of known bits
+};
-#define IFLAGS_MASK 0x0003 /**< flags above or'ed */
-// Note: the presence or absence of the IFLAGS_DISABLE_TFOM flag for the IRIG RX
-// settings of some PCI cards may not be evaluated correctly by some firmware
-// versions for those cards, even if an IRIG code has been configured which supports
-// this flag. See the comments near the declaration of the _pcps_incoming_tfom_ignored()
-// macro in pcpsdev.h for details.
+/**
+ * @brief Bit masks used with ::IRIG_SETTINGS::flags
+ *
+ * @note The presence or absence of the ::IFLAGS_DISABLE_TFOM flag for the IRIG RX
+ * settings of some PCI cards may not be evaluated correctly by some firmware
+ * versions for those cards, even if an IRIG code has been configured which supports
+ * this flag. See the comments near the declaration of the ::_pcps_incoming_tfom_ignored
+ * macro in pcpsdev.h for details.
+ *
+ * @see ::IFLAGS_BITS
+ */
+enum IFLAGS_BIT_MASKS
+{
+ IFLAGS_DISABLE_TFOM = ( 1UL << IFLAGS_BIT_DISABLE_TFOM ), ///< see ::IFLAGS_BIT_DISABLE_TFOM
+ IFLAGS_TX_GEN_LOCAL_TIME = ( 1UL << IFLAGS_BIT_TX_GEN_LOCAL_TIME ), ///< see ::IFLAGS_BIT_TX_GEN_LOCAL_TIME
+
+ IFLAGS_MASK = ( ( 1UL << N_IFLAGS_BITS ) - 1 ) ///< mask of all known flags
+};
-/** @} */
/**
* @brief Current IRIG settings and supported codes
*
- * Used to query the IRIG current IRIG settings
+ * Used to query the current IRIG settings
* plus a mask of supported codes.
*/
typedef struct
{
- IRIG_SETTINGS settings;
- uint32_t supp_codes; /**< bit mask of supported codes */
+ IRIG_SETTINGS settings; ///< current settings
+ uint32_t supp_codes; ///< see @ref ICODE_TX_MASKS and @ref ICODE_RX_MASKS
+
} IRIG_INFO;
#define _mbg_swab_irig_info( _p ) \
@@ -2557,32 +4135,173 @@ typedef struct
}
-// The type below is used to read the board's debug status
-// which also include IRIG decoder status:
-typedef uint32_t MBG_DEBUG_STATUS;
+/**
+ * @defgroup group_irig_comp IRIG input delay compensation
+ *
+ * These definitions are used with IRIG RX delay compensation
+ * which is supported by some IRIG receivers. Delay compensation
+ * depends on the basic frame type, so there are different records
+ * required for the different frame type groups.
+ *
+ * @{ */
-// The debug status is bit coded as defined below:
-enum
+/**
+ * The number of coefficients of a compensation record
+ * for a single frame type group, and the structure
+ * which contains those coefficients.
+ */
+#define N_IRIG_RX_COMP_VAL 4
+
+/**
+ * @brief A structure used to store compensation values
+ */
+typedef struct
+{
+ /**
+ * @brief Delay compensation values [100 ns units]
+ *
+ * @note Only the first value is actually used to compensate
+ * a delay, so the remaining values should be 0.
+ */
+ int16_t c[N_IRIG_RX_COMP_VAL];
+
+} IRIG_RX_COMP;
+
+#define _mbg_swab_irig_rx_comp( _p ) \
+{ \
+ int i; \
+ for ( i = 0; i < N_IRIG_RX_COMP_VAL; i++ ) \
+ _mbg_swab16( &(_p)->c[i] ); \
+}
+
+
+/** The absolute value of the maximum compensation value accepted by a device */
+#define IRIG_RX_COMP_MAX 999 // [100 ns units], i.e. valid range is +/-99.9 us
+
+
+
+/**
+ * @brief Structure used to retrieve the number of records for a given type
+ */
+typedef struct
+{
+ uint16_t type; ///< record type, see ::CAL_REC_TYPES
+ uint16_t idx; ///< index if several records of same type are supported, see ::IRIG_RX_COMP_GROUPS
+
+} CAL_REC_HDR;
+
+#define _mbg_swab_cal_rec_hdr( _p ) \
+{ \
+ _mbg_swab16( &(_p)->type ); \
+ _mbg_swab16( &(_p)->idx ); \
+}
+
+
+/**
+ * @brief Types to be used with ::CAL_REC_HDR::type
+ */
+enum CAL_REC_TYPES
{
- 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 */
+ CAL_REC_TYPE_UNDEF, ///< undefined type
+ CAL_REC_TYPE_IRIG_RX_COMP, ///< IRIG receiver delay compensation
+ N_CAL_REC_TYPE ///< number of known types
+};
- 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
+/**
+ * @brief Types to be used with ::CAL_REC_HDR::idx
+ *
+ * IRIG frame type groups to be distinguished for delay compensation.
+ */
+enum IRIG_RX_COMP_GROUPS
+{
+ IRIG_RX_COMP_B1, ///< codes B1xx, AFNOR, IEEE1344
+ IRIG_RX_COMP_A1, ///< code A1xx
+ IRIG_RX_COMP_B0, ///< codes B0xx, AFNOR DC, IEEE1344 DC
+ IRIG_RX_COMP_A0, ///< code A0xx
+ IRIG_RX_COMP_G1, ///< code G14x
+ IRIG_RX_COMP_G0, ///< code G00x
+ N_IRIG_RX_COMP ///< number of compensation values
};
-/*
- * Initializers for IRIG status bit strings.
+
+/**
+ * @brief Initializers for format name strings
+ */
+#define DEFAULT_IRIG_RX_COMP_NAMES \
+{ \
+ "B1xx/AFNOR/IEEE1344", \
+ "A1xx", \
+ "B0xx/AFNOR DC/IEEE1344 DC", \
+ "A0xx", \
+ "G14X", \
+ "G00X", \
+}
+
+
+
+/**
+ * @brief Structure used to transfer calibration records
+ */
+typedef struct
+{
+ CAL_REC_HDR hdr; ///< data header
+ IRIG_RX_COMP comp_data; ///< IRIG receiver delay compensation
+
+} CAL_REC_IRIG_RX_COMP;
+
+#define _mbg_swab_cal_rec_irig_rx_comp( _p ) \
+{ \
+ _mbg_swab_cal_rec_hdr( &(_p)->hdr ); \
+ _mbg_swab_irig_rx_comp( &(_p)->comp_data ); \
+}
+
+/** @} defgroup group_irig_comp */
+
+
+
+/**
+ * @brief A data type used to read the board's debug status
+ *
+ * @note This also includes IRIG decoder status.
+ *
+ * @see @ref MBG_DEBUG_STATUS_BIT_MASKS
+ */
+typedef uint32_t MBG_DEBUG_STATUS;
+
+#define _mbg_swab_debug_status( _p ) \
+ _mbg_swab32( _p )
+
+
+
+/**
+ * @brief Enumeration of flag bits used for debug status
+ *
+ * @see @ref MBG_DEBUG_STATUS_BIT_MASKS
+ */
+enum MBG_DEBUG_STATUS_BITS
+{
+ 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 ///< The number of known bits
+};
+
+/**
+ * @brief Initializers for debug status bit strings
+ *
+ * @see ::MBG_DEBUG_STATUS_BITS
*/
#define MBG_DEBUG_STATUS_STRS \
{ \
@@ -2602,6 +4321,12 @@ enum
}
+/**
+ * @brief Bit masks used with ::MBG_DEBUG_STATUS
+ *
+ * @see ::MBG_DEBUG_STATUS_BITS
+ *
+ * @anchor MBG_DEBUG_STATUS_BIT_MASKS @{ */
#define MBG_IRIG_MSK_WARMED_UP ( 1UL << MBG_IRIG_BIT_WARMED_UP )
#define MBG_IRIG_MSK_PPS_ACTIVE ( 1UL << MBG_IRIG_BIT_PPS_ACTIVE )
@@ -2617,26 +4342,54 @@ enum
#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 )
+/** @} anchor MBG_DEBUG_STATUS_BIT_MASKS */
-typedef int16_t MBG_REF_OFFS; /**< -MBG_REF_OFFS_MAX..MBG_REF_OFFS_MAX */
+/**
+ * @brief A data type used to configure the ref offset
+ *
+ * The ref offset if the offset of the incoming reference time from %UTC.
+ * For some types of signal (e.g. most IRIG frame formats) this can't be
+ * determined automatically.
+ *
+ * Valid range: -::MBG_REF_OFFS_MAX..::MBG_REF_OFFS_MAX, or ::MBG_REF_OFFS_NOT_CFGD
+ *
+ * @note There's a special flag ::MBG_REF_OFFS_NOT_CFGD indicating that
+ * this parameter is unconfigured, in which case a Meinberg time code
+ * receiver refuses to synchronize to the time code signal unless a time
+ * code frame has been configured which provides the UTC offset (namely
+ * IEEE 1344 or IEEE C37.118).
+ */
+typedef int16_t MBG_REF_OFFS;
#define _mbg_swab_mbg_ref_offs( _p ) _mbg_swab16( (_p) )
-/** the maximum allowed positive / negative offset */
+/**
+ * @brief The maximum allowed positive / negative ref 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
+ * @brief A flag indicating that the ref offset has not yet been configured
+ *
+ * If this flag is set in ::MBG_REF_OFFS this means the ref offset
+ * (time offset from %UTC) has not yet been configured. This is usually
+ * the case for IRIG receiver devices right after they have been shipped.
*/
#define MBG_REF_OFFS_NOT_CFGD 0x8000
+
+/**
+ * @brief A structure used to configure optional settings
+ *
+ * Optional settings are a generic way to configure some extended settings.
+ */
typedef struct
{
- uint32_t flags;
+ uint32_t flags; ///< @see ::MBG_OPT_FLAGS
+
} MBG_OPT_SETTINGS;
#define _mbg_swab_mbg_opt_settings( _p ) \
@@ -2645,10 +4398,17 @@ typedef struct
}
+/**
+ * @brief A structure used to configure optional settings
+ *
+ * This structure includes the current settings, and a bit mask
+ * indicating which flags are supported.
+ */
typedef struct
{
- MBG_OPT_SETTINGS settings;
- uint32_t supp_flags;
+ MBG_OPT_SETTINGS settings; ///< current settings
+ uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_OPT_FLAGS
+
} MBG_OPT_INFO;
#define _mbg_swab_mbg_opt_info( _p ) \
@@ -2658,32 +4418,55 @@ typedef struct
}
-enum
+/**
+ * @brief Enumeration of flag bits used to define ::MBG_OPT_FLAGS
+ */
+enum MBG_OPT_BITS
{
- 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 */
+ MBG_OPT_BIT_STR_UTC, ///< serial time string contains %UTC time
+ MBG_OPT_BIT_EMU_SYNC, ///< always pretend to be synchronized, alternatively ::GPS_FEAT_IGNORE_LOCK may be supported
N_MBG_OPT_BIT
};
-/*
- * Bit masks corresponding to the enumeration above:
+
+/**
+ * @brief Bit masks according to ::MBG_OPT_BITS
+ *
+ * Used with ::MBG_OPT_SETTINGS::flags and ::MBG_OPT_INFO::supp_flags.
*/
-#define MBG_OPT_FLAG_STR_UTC ( 1UL << MBG_OPT_BIT_STR_UTC )
-#define MBG_OPT_FLAG_EMU_SYNC ( 1UL << MBG_OPT_BIT_EMU_SYNC )
+enum MBG_OPT_FLAGS
+{
+ MBG_OPT_FLAG_STR_UTC = ( 1UL << MBG_OPT_BIT_STR_UTC ), ///< see ::MBG_OPT_BIT_STR_UTC
+ MBG_OPT_FLAG_EMU_SYNC = ( 1UL << MBG_OPT_BIT_EMU_SYNC ) ///< see ::MBG_OPT_BIT_EMU_SYNC
+};
-// bit coded return type for PCPS_GET_IRIG_CTRL_BITS
-typedef uint32_t MBG_IRIG_CTRL_BITS;
+/**
+ * @brief Bit coded return type for ::PCPS_GET_IRIG_CTRL_BITS
+ *
+ * The control bits a time code receiver has decoded from
+ * the incoming time code signal.
+ *
+ * @note ::MBG_RAW_IRIG_DATA is more versatile and should
+ * be used preferably, if supported.
+ *
+ * @see ::MBG_RAW_IRIG_DATA
+ */
+typedef uint32_t MBG_IRIG_CTRL_BITS;
#define _mbg_swab_irig_ctrl_bits( _p ) _mbg_swab32( _p )
-// The following macro extracts the 4 bit TFOM code from the
-// IRIG control bits read from a card. This only works if the received
-// IRIG code is a code which supports TFOM, this is currently
-// only IEEE1344.
+/**
+ * @brief Extract the TFOM code from ::MBG_IRIG_CTRL_BITS
+ *
+ * The resulting code is only valid if the configured IRIG code frame format
+ * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM
+ *
+ * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is
+ * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable).
+ */
#define _pcps_tfom_from_irig_ctrl_bits( _p ) \
( ( ( *(_p) ) >> 24 ) & 0x0F )
@@ -2692,24 +4475,33 @@ typedef uint32_t MBG_IRIG_CTRL_BITS;
#define RAW_IRIG_SIZE 16
/**
- The buffer below can be used to get the raw data bits
- from the IRIG decoder. A maximum number of RAW_IRIG_SIZE
- bytes can be filled. If less bytes are used then the rest
- of the bytes are filled with zeros.
-
- The first IRIG bit received from the transmitter is saved
- in the MSB (bit 7) of data_bytes[0], etc.
-*/
-typedef struct
+ * @brief A buffer used to read raw IRIG data bits from an IRIG receiver
+ *
+ * Used to get the raw data bits from the IRIG decoder. A maximum number
+ * of ::RAW_IRIG_SIZE bytes can be filled up, depending on the IRIG code.
+ * If less bytes are used then the rest of the bytes are filled with zeros.
+ *
+ * @note The first IRIG bit received from the transmitter is saved
+ * in the MSB (bit 7) of data_bytes[0], etc.
+ */
+typedef struct
{
uint8_t data_bytes[RAW_IRIG_SIZE];
+
} MBG_RAW_IRIG_DATA;
-// The following macro extracts the 4 bit TFOM code from the raw
-// data bits read from a card. This only works if the received
-// IRIG code is a code which supports TFOM, this is currently
-// only IEEE1344.
-#define _pcps_tfom_from_raw_irig_data( _p ) \
+#define _mbg_swab_mbg_raw_irig_data( _p ) _nop_macro_fnc()
+
+/**
+ * @brief Extract the TFOM code from ::MBG_RAW_IRIG_DATA
+ *
+ * The resulting code is only valid if the configured IRIG code frame format
+ * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM
+ *
+ * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is
+ * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable).
+ */
+#define _pcps_tfom_from_raw_irig_data( _p ) \
( ( ( (_p)->data_bytes[9] >> 2 ) & 0x08 ) \
| ( ( (_p)->data_bytes[9] >> 4 ) & 0x04 ) \
| ( ( (_p)->data_bytes[9] >> 6 ) & 0x02 ) \
@@ -2717,33 +4509,44 @@ typedef struct
-/**
- @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.
- @{
-*/
+/**
+ * @defgroup group_time_scale Time Scale Configuration
+ *
+ * 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
+/**
+ * @brief Known time scales
+ *
+ * @see ::MBG_TIME_SCALE_MASKS
+ * @see ::TM_SCALE_GPS
+ * @see ::TM_SCALE_TAI
+ */
+enum MBG_TIME_SCALES
{
- 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 */
+ MBG_TIME_SCALE_DEFAULT, ///< %UTC or local time according to ::UTC parameters and ::TZDL configuration
+ MBG_TIME_SCALE_GPS, ///< GPS time as sent by the satellites, monotonical
+ MBG_TIME_SCALE_TAI, ///< TAI, i.e. GPS time plus constant offset (see ::GPS_TAI_OFFSET)
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.
-
+/**
+ * @brief Bit masks for known time scales
+ *
+ * @see ::MBG_TIME_SCALES
+ */
+enum MBG_TIME_SCALE_MASKS
+{
+ MBG_TIME_SCALE_MSK_DEFAULT = ( 1UL << MBG_TIME_SCALE_DEFAULT ), ///< see ::MBG_TIME_SCALE_DEFAULT
+ MBG_TIME_SCALE_MSK_GPS = ( 1UL << MBG_TIME_SCALE_GPS ), ///< see ::MBG_TIME_SCALE_GPS
+ MBG_TIME_SCALE_MSK_TAI = ( 1UL << MBG_TIME_SCALE_TAI ) ///< see ::MBG_TIME_SCALE_TAI
+};
#define MBG_TIME_SCALE_STRS \
{ \
@@ -2754,27 +4557,35 @@ enum
-/**
- The fixed time offset between the GPS and TAI time scales, in seconds
-*/
-#define GPS_TAI_OFFSET 19 /**< [s], TAI = GPS + GPS_TAI_OFFSET */
+/**
+ * @brief The constant time offset between the GPS and TAI time scales, in seconds
+ */
+#define GPS_TAI_OFFSET 19 ///< [s], TAI = GPS + GPS_TAI_OFFSET
+/**
+ * @brief Time scale configuration settings
+ */
typedef struct
{
- uint8_t scale; /**< current time scale code from the enum above */
- uint8_t flags; /**< reserved, currently always 0 */
+ uint8_t scale; ///< current time scale code, see ::MBG_TIME_SCALES
+ uint8_t flags; ///< reserved, don't use, currently always 0
+
} MBG_TIME_SCALE_SETTINGS;
#define _mbg_swab_mbg_time_scale_settings( _p ) \
_nop_macro_fnc()
+/**
+ * @brief Time scale configuration settings plus capabilities
+ */
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_SETTINGS settings; ///< current settings
+ MBG_TIME_SCALE_SETTINGS max_settings; ///< number of scales, all supported flags
+ uint32_t supp_scales; ///< bit masks of supported scales, see ::MBG_TIME_SCALE_MASKS
+
} MBG_TIME_SCALE_INFO;
#define _mbg_swab_mbg_time_scale_info( _p ) \
@@ -2784,24 +4595,25 @@ typedef struct
_mbg_swab32( &(_p)->supp_scales ); \
}
-/** @} */ // endgroup
+/** @} defgroup group_time_scale */
/*
* The structures below are required to setup the programmable
* pulse outputs which are provided by some GPS receivers.
* The number of programmable pulse outputs supported by a GPS
- * receiver is reported in the RECEIVER_INFO.n_str_type field.
+ * receiver is reported in the RECEIVER_INFO::n_str_type field.
*/
/**
- * The structure is used to define a date of year:
+ * @brief A calendar date including full year number
*/
typedef struct
{
- uint8_t mday; /* 1..28,29,30,31 */
- uint8_t month; /* 1..12 */
- uint16_t year; /* including century */
+ uint8_t mday; ///< 1..28,29,30,31
+ uint8_t month; ///< 1..12
+ uint16_t year; ///< including century
+
} MBG_DATE;
#define _mbg_swab_mbg_date( _p ) \
@@ -2811,14 +4623,15 @@ typedef struct
/**
- * The structure is used to define a time of day:
+ * @brief The time of day including hundredths of seconds
*/
typedef struct
{
- uint8_t hour; /* 0..23 */
- uint8_t min; /* 0..59 */
- uint8_t sec; /* 0..59,60 */
- uint8_t sec100; /* reserved, currently always 0 */
+ uint8_t hour; ///< 0..23
+ uint8_t min; ///< 0..59
+ uint8_t sec; ///< 0..59,60
+ uint8_t sec100; ///< reserved, currently always 0
+
} MBG_TIME;
#define _mbg_swab_mbg_time( _p ) \
@@ -2826,15 +4639,15 @@ typedef struct
/**
- * The structure defines a single date and time
- * for switching operations:
+ * @brief Date and time specification for switching operations
*/
typedef struct
{
- MBG_DATE d; /* date to switch */
- MBG_TIME t; /* time to switch */
- uint8_t wday; /* reserved, currently always 0 */
- uint8_t flags; /* reserved, currently 0 */
+ MBG_DATE d; ///< date to switch
+ MBG_TIME t; ///< time to switch
+ uint8_t wday; ///< reserved, currently always 0
+ uint8_t flags; ///< reserved, currently 0
+
} MBG_DATE_TIME;
#define _mbg_swab_mbg_date_time( _p ) \
@@ -2845,13 +4658,13 @@ typedef struct
/**
- * The structure defines times and dates
- * for an on/off cycle:
+ * @brief A structure to define on/off cycle times
*/
typedef struct
{
- MBG_DATE_TIME on; /* time and date to switch on */
- MBG_DATE_TIME off; /* time and date to switch off */
+ MBG_DATE_TIME on; ///< date and time to switch on
+ MBG_DATE_TIME off; ///< date and time to switch off
+
} POUT_TIME;
#define _mbg_swab_pout_time( _p ) \
@@ -2862,67 +4675,197 @@ typedef struct
/**
- * The number of POUT_TIMEs for each programmable pulse output
+ * @brief The number of ::POUT_TIME settings for each programmable pulse output
+ *
+ * @note This can't be changed without breaking compatibility of the API
*/
-#define N_POUT_TIMES 3
+#define N_POUT_TIMES 3
/**
- * The structure is used to configure a single programmable
- * pulse output.
+ * @brief Configuration settings for 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, see ::POUT_MODES
+ uint16_t mode_param; ///< depending on the mode, e.g. pulse length, or index of a signal source
+ uint16_t timeout; ///< timeout after which output signal is disabled [min], used with ::POUT_DCF77 and ::POUT_DCF77_M59 only, see ::MAX_POUT_DCF_TIMOUT
+ uint16_t flags; ///< @see ::POUT_SETTINGS_FLAGS
+ POUT_TIME tm[N_POUT_TIMES]; ///< switching times, or other data, see ::POUT_DATA
+
} POUT_SETTINGS;
-#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] ); \
+/**
+ * @brief A Generic data field for programmable output settings
+ *
+ * If the mode is set to ::POUT_TIME_SLOTS then ::POUT_SETTINGS::tm must be
+ * interpreted as ::POUT_DATA, i.e. just an array of bytes. We can not change
+ * the type of the tm field to a union for compatibility reasons ... :(
+ */
+typedef union
+{
+ uint8_t b[N_POUT_TIMES * sizeof( POUT_TIME )];
+
+} POUT_DATA;
+
+
+/**
+ * @brief Convert ::POUT_SETTINGS endianess after reading from a device
+ *
+ * When reading data from a device we first need to correct the endianess
+ * of the mode first, and correct the endianess of the tm field only
+ * if the tm field is not interpreted as ::POUT_DATA.
+ */
+#define _mbg_swab_pout_settings_on_get( _p ) \
+{ \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->mode_param ); \
+ _mbg_swab16( &(_p)->timeout ); \
+ _mbg_swab16( &(_p)->flags ); \
+ \
+ if ( (_p)->mode != POUT_TIME_SLOTS ) \
+ { \
+ int i; \
+ \
+ for ( i = 0; i < N_POUT_TIMES; i++ ) \
+ _mbg_swab_pout_time( &(_p)->tm[i] ); \
+ } \
}
+/**
+ * @brief Convert ::POUT_SETTINGS endianess before writing to a device
+ *
+ * When writing data to a device we first need to check the mode,
+ * and correct the endianess of the tm field only if the tm field
+ * is not interpreted as ::POUT_DATA. Finally we can also correct
+ * the endianess of the mode field.
+ */
+#define _mbg_swab_pout_settings_on_set( _p ) \
+{ \
+ if ( (_p)->mode != POUT_TIME_SLOTS ) \
+ { \
+ int i; \
+ \
+ for ( i = 0; i < N_POUT_TIMES; i++ ) \
+ _mbg_swab_pout_time( &(_p)->tm[i] ); \
+ } \
+ \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->mode_param ); \
+ _mbg_swab16( &(_p)->timeout ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
-#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:
+ * @brief Definitions used with ::POUT_TIME_SLOTS mode
+ *
+ * If ::POUT_SETTINGS::mode is set to ::POUT_TIME_SLOTS then the number
+ * of time slots per minute is stored in ::POUT_SETTINGS::mode_param.
+ * Valid numbers are all numbers n in the range ::MIN_TIME_SLOTS_PER_MINUTE
+ * to ::MAX_TIME_SLOTS_PER_MINUTE for which the remainder of 60 / n is 0.
+ *
+ * @anchor POUT_TIME_SLOTS_MODE_DEFS @{ */
+
+#define MIN_TIME_SLOTS_PER_MINUTE 1
+#define MAX_TIME_SLOTS_PER_MINUTE 60
+#define TIME_SLOT_REGISTER_IN_SEC 60
+
+#define TIMEOUT_DIVIDED_BY 10
+#define TIME_SLOT_SWITCH_OFF_BUFFER_MIN 50 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_MAX 500 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_STD 500 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_STEP_SIZE 50 / TIMEOUT_DIVIDED_BY
+
+#define _valid_time_slots_per_minute( _n ) \
+ ( ( (_n) >= MIN_TIME_SLOTS_PER_MINUTE ) && \
+ ( (_n) <= MAX_TIME_SLOTS_PER_MINUTE ) && \
+ ( ( 60 % (_n) ) == 0 ) \
+ )
+
+/** @} anchor POUT_TIME_SLOTS_MODE_DEFS */
+
+
+
+#define MAX_POUT_PULSE_LEN 1000 ///< 10 secs, in 10 msec units
+#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) ///< 48 hours, in minutes
+
+
+
+/**
+ * @brief Enumeration of known operation modes for programmable pulse outputs
+ *
+ * These codes are used with ::POUT_SETTINGS::mode. One or more of
+ * the remaining fields in ::POUT_SETTINGS are evaluated depending
+ * on the selected mode.
+ *
+ * Unless ::POUT_NOT_INVERTIBLE is set in ::POUT_INFO::flags
+ * the output signal level can be inverted if ::POUT_INVERTED
+ * is set in ::POUT_SETTINGS::flags.
+ *
+ * @note Not every programmable pulse output supports all modes.
+ *
+ * @see @ref POUT_MODE_MASKS
*/
-enum
+enum POUT_MODES
{
- 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_DCF77_M59, /**< DCF77-like signal with 500 ms pulse in 59th second */
- POUT_SYNTH, /**< programmable synthesizer frequency */
- N_POUT_MODES
+ POUT_IDLE, ///< always off, or on if ::POUT_INVERTED flag is set
+ POUT_TIMER, ///< switch on/off at times specified in ::POUT_SETTINGS::tm
+ POUT_SINGLE_SHOT, ///< pulse at time POUT_SETTINGS::tm[0].on, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN
+ POUT_CYCLIC_PULSE, ///< pulse every POUT_SETTINGS::tm[0].on.t interval, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN
+ POUT_PER_SEC, ///< pulse if second changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN
+ POUT_PER_MIN, ///< pulse if minute changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN
+ POUT_PER_HOUR, ///< pulse if hour changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN
+ POUT_DCF77, ///< emulate DCF77 signal, uses ::POUT_SETTINGS::timeout, see ::MAX_POUT_DCF_TIMOUT
+ POUT_POS_OK, ///< on if receiver position verified (nav_solved)
+ POUT_TIME_SYNC, ///< on if time synchronized (time_syn)
+ POUT_ALL_SYNC, ///< on if position verified and time synchronized
+ POUT_TIMECODE, ///< IRIG/AFNOR DCLS signal output
+ POUT_TIMESTR, ///< serial time string, ::POUT_SETTINGS::mode_param contains the number of the COM port, see ::MAX_POUT_TIMESTR_PORTS
+ POUT_10MHZ, ///< 10 MHz fixed frequency
+ POUT_DCF77_M59, ///< DCF77-like signal with 500 ms pulse in 59th second, uses ::POUT_SETTINGS::timeout, see ::MAX_POUT_DCF_TIMOUT
+ POUT_SYNTH, ///< programmable frequency synthesizer output signal
+ POUT_TIME_SLOTS, ///< programmable time slots during each minute, uses ::POUT_DATA, ::POUT_SETTINGS::mode_param contains time slots per minute
+ POUT_GPIO, ///< GPIO input or output signal, ::POUT_SETTINGS::mode_param specifies the GPIO number, see ::MBG_GPIO_CFG_LIMITS::num_io
+ // New modes have to be added here at the end of the enumeration, and
+ // the POUT_MODE_MASKS and string initializers (also in pcpslstr.h)
+ // have to be updated accordingly.
+ N_POUT_MODES ///< the number of known modes
};
+/**
+ * @brief Bit masks associated with ::POUT_MODES
+ *
+ * Used with ::POUT_INFO::supp_modes to specify which ::POUT_MODES
+ * are supported for a particular programmable output.
+ *
+ * @see ::POUT_MODES
+ *
+ * @anchor POUT_MODE_MASKS @{ */
+
+#define MSK_POUT_IDLE ( 1UL << POUT_IDLE ) ///< see ::POUT_IDLE
+#define MSK_POUT_TIMER ( 1UL << POUT_TIMER ) ///< see ::POUT_TIMER
+#define MSK_POUT_SINGLE_SHOT ( 1UL << POUT_SINGLE_SHOT ) ///< see ::POUT_SINGLE_SHOT
+#define MSK_POUT_CYCLIC_PULSE ( 1UL << POUT_CYCLIC_PULSE ) ///< see ::POUT_CYCLIC_PULSE
+#define MSK_POUT_PER_SEC ( 1UL << POUT_PER_SEC ) ///< see ::POUT_PER_SEC
+#define MSK_POUT_PER_MIN ( 1UL << POUT_PER_MIN ) ///< see ::POUT_PER_MIN
+#define MSK_POUT_PER_HOUR ( 1UL << POUT_PER_HOUR ) ///< see ::POUT_PER_HOUR
+#define MSK_POUT_DCF77 ( 1UL << POUT_DCF77 ) ///< see ::POUT_DCF77
+#define MSK_POUT_POS_OK ( 1UL << POUT_POS_OK ) ///< see ::POUT_POS_OK
+#define MSK_POUT_TIME_SYNC ( 1UL << POUT_TIME_SYNC ) ///< see ::POUT_TIME_SYNC
+#define MSK_POUT_ALL_SYNC ( 1UL << POUT_ALL_SYNC ) ///< see ::POUT_ALL_SYNC
+#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE ) ///< see ::POUT_TIMECODE
+#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR ) ///< see ::POUT_TIMESTR
+#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ ) ///< see ::POUT_10MHZ
+#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 ) ///< see ::POUT_DCF77_M59
+#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH ) ///< see ::POUT_SYNTH
+#define MSK_POUT_TIME_SLOTS ( 1UL << POUT_TIME_SLOTS ) ///< see ::POUT_TIME_SLOTS
+#define MSK_POUT_GPIO ( 1UL << POUT_GPIO ) ///< see ::POUT_GPIO
+
+/** @} anchor POUT_MODE_MASKS */
+
+
/*
* Default initializers for English pulse mode names. Initializers
* for multi-language strings can be found in pcpslstr.h.
@@ -2939,10 +4882,12 @@ enum
#define ENG_POUT_NAME_TIME_SYNC "Time Sync"
#define ENG_POUT_NAME_ALL_SYNC "All Sync"
#define ENG_POUT_NAME_TIMECODE "DCLS Time Code"
-#define ENG_POUT_NAME_TIMESTR "COM Time String"
+#define ENG_POUT_NAME_TIMESTR "Serial Time String"
#define ENG_POUT_NAME_10MHZ "10 MHz Frequency"
#define ENG_POUT_NAME_DCF77_M59 "DCF77-like M59"
#define ENG_POUT_NAME_SYNTH "Synthesizer Frequency"
+#define ENG_POUT_NAME_TIME_SLOTS "Time Slots per Minute"
+#define ENG_POUT_NAME_GPIO "GPIO Signal"
#define DEFAULT_ENG_POUT_NAMES \
{ \
@@ -2961,7 +4906,9 @@ enum
ENG_POUT_NAME_TIMESTR, \
ENG_POUT_NAME_10MHZ, \
ENG_POUT_NAME_DCF77_M59, \
- ENG_POUT_NAME_SYNTH \
+ ENG_POUT_NAME_SYNTH, \
+ ENG_POUT_NAME_TIME_SLOTS, \
+ ENG_POUT_NAME_GPIO \
}
@@ -2981,6 +4928,8 @@ enum
#define ENG_POUT_HINT_10MHZ "10 MHz fixed output frequency"
#define ENG_POUT_HINT_DCF77_M59 "DCF77 time marks with 500 ms pulse in 59th second"
#define ENG_POUT_HINT_SYNTH "Frequency generated by programmable synthesizer"
+#define ENG_POUT_HINT_TIME_SLOTS "Output enabled during specified time slots per minute"
+#define ENG_POUT_HINT_GPIO "Duplicated signal of the specified GPIO input or output"
#define DEFAULT_ENG_POUT_HINTS \
{ \
@@ -2999,144 +4948,247 @@ enum
ENG_POUT_HINT_TIMESTR, \
ENG_POUT_HINT_10MHZ, \
ENG_POUT_HINT_DCF77_M59, \
- ENG_POUT_HINT_SYNTH \
+ ENG_POUT_HINT_SYNTH, \
+ ENG_POUT_HINT_TIME_SLOTS, \
+ ENG_POUT_HINT_GPIO \
}
-/*
- * The definitions below are used to set up bit masks
- * which restrict the modes which can be used with
- * a given programmable output:
- */
-#define MSK_POUT_IDLE ( 1UL << POUT_IDLE )
-#define MSK_POUT_TIMER ( 1UL << POUT_TIMER )
-#define MSK_POUT_SINGLE_SHOT ( 1UL << POUT_SINGLE_SHOT )
-#define MSK_POUT_CYCLIC_PULSE ( 1UL << POUT_CYCLIC_PULSE )
-#define MSK_POUT_PER_SEC ( 1UL << POUT_PER_SEC )
-#define MSK_POUT_PER_MIN ( 1UL << POUT_PER_MIN )
-#define MSK_POUT_PER_HOUR ( 1UL << POUT_PER_HOUR )
-#define MSK_POUT_DCF77 ( 1UL << POUT_DCF77 )
-#define MSK_POUT_POS_OK ( 1UL << POUT_POS_OK )
-#define MSK_POUT_TIME_SYNC ( 1UL << POUT_TIME_SYNC )
-#define MSK_POUT_ALL_SYNC ( 1UL << POUT_ALL_SYNC )
-#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE )
-#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR )
-#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ )
-#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 )
-#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH )
+
+/**
+ * @brief Flag bits used to define ::POUT_SETTINGS_FLAGS
+ *
+ * @see ::POUT_SETTINGS_FLAGS
+ */
+enum POUT_SETTINGS_FLAG_BITS
+{
+ POUT_BIT_INVERTED, ///< output level is inverted, use only if ::POUT_NOT_INVERTIBLE not set
+ POUT_BIT_IF_SYNC_ONLY, ///< disable output in holdover mode, use only if ::POUT_SUPP_IF_SYNC_ONLY is set
+ POUT_BIT_TIMEBASE_UTC, ///< output %UTC if mode is ::POUT_DCF77 or ::POUT_DCF77_M59, use only if ::POUT_SUPP_DCF77_UTC is set
+ N_POUT_SETTINGS_FLAG_BITS ///< Number of known flag bits
+};
-/*
- * The codes below are used with POUT_SETTINGS::flags:
+/**
+ * @brief Flag bit masks used with ::POUT_SETTINGS::flags
+ *
+ * @see ::POUT_SETTINGS_FLAG_BITS
*/
-#define POUT_INVERTED 0x0001 // invert output level
-#define POUT_IF_SYNC_ONLY 0x0002 // disable in holdover mode
-#define POUT_TIMEBASE_UTC 0x0004 // use UTC, only applicable for DCF77 output
+enum POUT_SETTINGS_FLAGS
+{
+ POUT_INVERTED = ( 1UL << POUT_BIT_INVERTED ), ///< see ::POUT_BIT_INVERTED, ::POUT_NOT_INVERTIBLE
+ POUT_IF_SYNC_ONLY = ( 1UL << POUT_BIT_IF_SYNC_ONLY ), ///< see ::POUT_BIT_IF_SYNC_ONLY, ::POUT_SUPP_IF_SYNC_ONLY
+ POUT_TIMEBASE_UTC = ( 1UL << POUT_BIT_TIMEBASE_UTC ) ///< see ::POUT_BIT_TIMEBASE_UTC, ::POUT_SUPP_DCF77_UTC
+};
+
/**
- 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.
+ * @brief Configuration settings for a specific programmable pulse output
+ *
+ * This structure can be used to send configuration settings for a specific
+ * programmable output to a device.
+ * The number of supported outputs is RECEIVER_INFO::n_prg_out.
+ *
+ * @note The ::POUT_INFO_IDX structure should be read from
+ * a device to retrieve the current settings and capabilities.
*/
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 ); \
+#define _mbg_swab_pout_settings_idx_on_set( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \
+}
+
+#define _mbg_swab_pout_settings_idx_on_get( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings_on_get( &(_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.
+ * @brief Current settings and general capabilities of a programmable pulse output
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a programmable pulse output plus its capabilities,
+ * e.g. the supported output modes, etc.
+ *
+ * @note The ::POUT_INFO_IDX structure should be used to read
+ * current settings and capabilities of a specific output.
*/
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; /**< see below */
+ uint32_t supp_modes; ///< bit mask of modes supp. by this output, see @ref POUT_MODE_MASKS
+ uint8_t timestr_ports; ///< bit mask of COM ports supported for mode ::POUT_TIMESTR, see ::MAX_POUT_TIMESTR_PORTS
+ uint8_t reserved_0; ///< reserved for future use, currently unused and always 0
+ uint16_t reserved_1; ///< reserved for future use, currently unused and always 0
+ uint32_t flags; ///< @see ::POUT_INFO_FLAG_MASKS
+
} POUT_INFO;
-#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 ); \
+#define _mbg_swab_pout_info_on_get( _p ) \
+{ \
+ _mbg_swab_pout_settings_on_get( &(_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
+#define MAX_POUT_TIMESTR_PORTS 8 ///< The max number of COM ports that can be handled by ::POUT_INFO::timestr_ports
-/*
- * The codes below are used with POUT_INFO::flags:
+
+/**
+ * @brief Flag bits used to define ::POUT_INFO_FLAG_MASKS
+ *
+ * @see ::POUT_INFO_FLAG_MASKS
*/
-#define POUT_SUPP_IF_SYNC_ONLY 0x0001 // supports disabling outputs in holdover mode
-#define POUT_SUPP_DCF77_UTC 0x0002 // supports UTC output in DCF77 mode
+enum POUT_INFO_FLAG_BITS
+{
+ POUT_BIT_SUPP_IF_SYNC_ONLY, ///< ::POUT_IF_SYNC_ONLY is supported for this output
+ POUT_BIT_SUPP_DCF77_UTC, ///< ::POUT_SUPP_DCF77_UTC is supported for this output
+ POUT_BIT_FIXED_PULSE_LEN, ///< pulse length is limited to the value ::POUT_SETTINGS::mode_param
+ POUT_BIT_NOT_INVERTIBLE, ///< output level can't be inverted, thus ::POUT_INVERTED is not supported for this output
+ N_POUT_INFO_FLAG_BITS ///< number of known flag bits
+};
/**
- The structure below adds an index number to the structure
- above to allow addressing of several instances:
+ * @brief Flag bit masks used with ::POUT_INFO::flags
+ *
+ * @see ::POUT_INFO_FLAG_BITS
+ */
+enum POUT_INFO_FLAG_MASKS
+{
+ POUT_SUPP_IF_SYNC_ONLY = ( 1UL << POUT_BIT_SUPP_IF_SYNC_ONLY ), ///< see ::POUT_BIT_SUPP_IF_SYNC_ONLY, ::POUT_IF_SYNC_ONLY
+ POUT_SUPP_DCF77_UTC = ( 1UL << POUT_BIT_SUPP_DCF77_UTC ), ///< see ::POUT_BIT_SUPP_DCF77_UTC, ::POUT_SUPP_DCF77_UTC
+ POUT_FIXED_PULSE_LEN = ( 1UL << POUT_BIT_FIXED_PULSE_LEN ), ///< see ::POUT_BIT_FIXED_PULSE_LEN
+ POUT_NOT_INVERTIBLE = ( 1UL << POUT_BIT_NOT_INVERTIBLE ) ///< see ::POUT_BIT_NOT_INVERTIBLE, ::POUT_INVERTED
+};
+
+
+
+/**
+ * @brief Current settings and general capabilities of a specific programmable pulse output
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a specific programmable output plus its capabilities,
+ * e.g. supported modes of operation, etc.
+ * The number of supported ports is RECEIVER_INFO::n_prg_out.
+ *
+ * @note The ::POUT_SETTINGS_IDX structure should be send back to
+ * the device to configure the specified programmable pulse output.
*/
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 ); \
+#define _mbg_swab_pout_info_idx_on_get( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \
}
-/*
- * The codes below are used with devices which support multiple
- * ref time sources at the same time. The priorities of the
- * supported ref time sources is configurable.
- */
+/**
+ * @defgroup group_multi_ref_all Support for multiple reference time sources
+ *
+ * Some devices can evaluate and synchronize to several different types
+ * of input signal, and eventually even several signals of the same type,
+ * e.g. several 1 PPS input signals.
+ *
+ * There are two different ways to configure multi ref devices.
+ *
+ * Newer devices which have the ::GPS_HAS_XMULTI_REF flag set in
+ * ::RECEIVER_INFO::features support the newer XMULTI_REF_... structures
+ * which provide a more flexible API, see @ref group_multi_ref_ext
+ *
+ * Older devices may have the ::GPS_FEAT_MULTI_REF flag set in which
+ * case an older API is supported, see @ref group_multi_ref_old
+ *
+ * Symbols defined in @ref group_multi_ref_common can be used
+ * with both APIs.
+ *
+ * @see @ref group_multi_ref_common
+ * @see @ref group_multi_ref_old
+ * @see @ref group_multi_ref_ext
+ * @{ */
-/*
- * All possibly supported ref time sources
+/**
+ * @defgroup group_multi_ref_common Common multi ref definitions
+ *
+ * Common definitions used with both the old and the extended
+ * multi ref API.
+ *
+ * @{ */
+
+/**
+ * @brief Enumeration of all known types of reference time source
+ *
+ * All known types of input signal which may possibly be supported
+ * by devices which support several different input signals, i.e.
+ * have the ::GPS_HAS_MULTI_REF or ::GPS_HAS_XMULTI_REF bit set
+ * in ::RECEIVER_INFO::features. Not all devices support each known
+ * type of input signal.
+ *
+ * @see @ref group_multi_ref_all
+ * @see ::DEFAULT_MULTI_REF_NAMES
+ * @see ::DEFAULT_MULTI_REF_NAMES_SHORT
+ * @see @ref MULTI_REF_TYPE_MASKS
*/
-enum
+enum MULTI_REF_TYPES
{
- 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
- MULTI_REF_PPS_STRING, // 1 PPS in addition to string
- N_MULTI_REF // the number of defined sources
+ /// This ref type must not be used as index, but marks particular
+ /// ::XMULTI_REF_SETTINGS structures as "unused". It is only
+ /// supported if bit ::XMRIF_BIT_MRF_NONE_SUPP is set.
+ MULTI_REF_NONE = -1,
+
+ 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
+ MULTI_REF_PPS_STRING, ///< 1 PPS in addition to time string
+ MULTI_REF_GPIO, ///< variable input signal via GPIO
+ MULTI_REF_INTERNAL, ///< reserved, used internally by firmware only
+ MULTI_REF_PZF, ///< DCF77 PZF providing much more accuracy than a standard LWR
+ MULTI_REF_LWR, ///< long wave receiver. e.g. DCF77 AM, WWVB, MSF, JJY
+ MULTI_REF_GRC, ///< Glonass / GPS receiver
+ MULTI_REF_HAVEQUICK, ///< HaveQuick input
+ MULTI_REF_EXT_OSC, ///< external oscillator disciplined and looped back via 1 PPS I/O
+ N_MULTI_REF ///< the number of defined sources, must not exceed ::MAX_N_MULTI_REF_TYPES
};
+/**
+ * @brief Theoretical maximum number of multi ref input signal types
+ *
+ * Actually only ::N_MULTI_REF types have been defined, but ::N_MULTI_REF
+ * must not exceed the number of bits which can be hold by a uint32_t type.
+ */
+#define MAX_N_MULTI_REF_TYPES 32
-/*
- * Names of supported ref time sources
+
+/**
+ * @brief Names of known ref time sources
+ *
+ * @see ::MULTI_REF_TYPES
*/
#define DEFAULT_MULTI_REF_NAMES \
{ \
@@ -3149,240 +5201,437 @@ enum
"PTP (IEEE1588)", \
"PTP over E1", \
"Fixed Freq. in", \
- "PPS plus string" \
+ "PPS plus string", \
+ "Var. freq. via GPIO", \
+ "(reserved)", \
+ "DCF77 PZF Receiver", \
+ "Long Wave Receiver", \
+ "GLONASS/GPS Receiver", \
+ "HaveQuick Input", \
+ "ext. Osc." \
}
-
-/*
- * Bit masks used to indicate supported reference sources
+/**
+ * @brief Short names of supported ref time sources
+ *
+ * Used e.g. to configure a particular input signal type
+ *
+ * @see ::MULTI_REF_TYPES
*/
-#define HAS_MULTI_REF_GPS ( 1UL << MULTI_REF_GPS )
-#define HAS_MULTI_REF_10MHZ ( 1UL << MULTI_REF_10MHZ )
-#define HAS_MULTI_REF_PPS ( 1UL << MULTI_REF_PPS )
-#define HAS_MULTI_REF_10MHZ_PPS ( 1UL << MULTI_REF_10MHZ_PPS )
-#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 )
-#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING )
+#define DEFAULT_MULTI_REF_NAMES_SHORT \
+{ \
+ "GPS", \
+ "FRQ", \
+ "PPS", \
+ "10MHZ+PPS", \
+ "TCR", \
+ "NTP", \
+ "PTP hq", \
+ "PTP E1", \
+ "Fixed in", \
+ "STR in", \
+ "GPIO in", \
+ "(reserved)", \
+ "PZF", \
+ "LWR", \
+ "GGR", \
+ "HQI", \
+ "EXT" \
+}
-/*
- * There are 2 different ways to configure multi ref support
- * provided by some devices.
+/**
+ * @brief Bit masks associated with multi ref types
*
- * 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.
+ * Used to indicate which multi ref types are supported, e.g.
+ * in ::XMULTI_REF_INFO::supp_ref or ::MULTI_REF_INFO::supp_ref.
*
- * 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.
- */
+ * @see ::MULTI_REF_TYPES
+ *
+ * @anchor MULTI_REF_TYPE_MASKS @{ */
+
+#define HAS_MULTI_REF_GPS ( 1UL << MULTI_REF_GPS ) ///< see ::MULTI_REF_GPS
+#define HAS_MULTI_REF_10MHZ ( 1UL << MULTI_REF_10MHZ ) ///< see ::MULTI_REF_10MHZ
+#define HAS_MULTI_REF_PPS ( 1UL << MULTI_REF_PPS ) ///< see ::MULTI_REF_PPS
+#define HAS_MULTI_REF_10MHZ_PPS ( 1UL << MULTI_REF_10MHZ_PPS ) ///< see ::MULTI_REF_10MHZ_PPS
+#define HAS_MULTI_REF_IRIG ( 1UL << MULTI_REF_IRIG ) ///< see ::MULTI_REF_IRIG
+#define HAS_MULTI_REF_NTP ( 1UL << MULTI_REF_NTP ) ///< see ::MULTI_REF_NTP
+#define HAS_MULTI_REF_PTP ( 1UL << MULTI_REF_PTP ) ///< see ::MULTI_REF_PTP
+#define HAS_MULTI_REF_PTP_E1 ( 1UL << MULTI_REF_PTP_E1 ) ///< see ::MULTI_REF_PTP_E1
+
+#define HAS_MULTI_REF_FREQ ( 1UL << MULTI_REF_FREQ ) ///< see ::MULTI_REF_FREQ
+#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING ) ///< see ::MULTI_REF_PPS_STRING
+#define HAS_MULTI_REF_GPIO ( 1UL << MULTI_REF_GPIO ) ///< see ::MULTI_REF_GPIO
+#define HAS_MULTI_REF_INTERNAL ( 1UL << MULTI_REF_INTERNAL ) ///< see ::MULTI_REF_INTERNAL
+#define HAS_MULTI_REF_PZF ( 1UL << MULTI_REF_PZF ) ///< see ::MULTI_REF_PZF
+#define HAS_MULTI_REF_LWR ( 1UL << MULTI_REF_LWR ) ///< see ::MULTI_REF_LWR
+#define HAS_MULTI_REF_GRC ( 1UL << MULTI_REF_GRC ) ///< see ::MULTI_REF_GRC
+#define HAS_MULTI_REF_HAVEQUICK ( 1UL << MULTI_REF_HAVEQUICK ) ///< see ::MULTI_REF_HAVEQUICK
+
+#define HAS_MULTI_REF_EXT_OSC ( 1UL << MULTI_REF_EXT_OSC ) ///< see ::MULTI_REF_EXT_OSC
+
+/** @} anchor MULTI_REF_TYPE_MASKS */
+
+/** @} defgroup group_multi_ref_common */
-#define N_MULTI_REF_PRIO 4
/**
- The structure below is used to configure the priority of
- the supported ref sources.
+ * @defgroup group_multi_ref_old Definitions used with the old multi ref API
+ *
+ * This API has been deprecated by a newer one which should be used preferably.
+ *
+ * @see @ref group_multi_ref_ext
+ *
+ * @{ */
- 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.
+/**
+ * @brief Maximum number of input sources
+ *
+ * The number of supported input sources and priorities is
+ * limited to this value if the old API is used, i.e. if only
+ * the ::GPS_FEAT_MULTI_REF flag is set.
+ */
+#define N_MULTI_REF_PRIO 4
+
+
+/**
+ * @brief A structure 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 has to be set to one of the values 0..::N_MULTI_REF-1,
+ * or to ::MULTI_REF_NONE if no time source is specified.
*/
typedef struct
{
uint8_t prio[N_MULTI_REF_PRIO];
+
} MULTI_REF_SETTINGS;
/**
- The structure below is used to query the MULTI_REF configuration,
- plus the supported ref sources.
+ * @brief A structure used to query MULTI_REF configuration parameters
+ *
+ * This also includes a bit mask of supported ref sources.
*/
typedef struct
{
- MULTI_REF_SETTINGS settings; /* current settings */
- uint32_t supp_ref; /* supp. HAS_MULTI_REF_... codes or'ed */
- uint16_t n_levels; /* supp. levels, 0..N_MULTI_REF_PRIO */
- uint16_t flags; /* reserved, currently 0 */
+ MULTI_REF_SETTINGS settings; ///< current settings
+ uint32_t supp_ref; ///< bit mask of supported sources, see @ref MULTI_REF_TYPE_MASKS
+ uint16_t n_levels; ///< supported priority levels, 0..::N_MULTI_REF_PRIO-1
+ uint16_t flags; ///< reserved, currently always 0
+
} MULTI_REF_INFO;
-/*
- * The type below is used to query the MULTI_REF status information,
+/**
+ * @brief A data type used to query MULTI_REF status information
+ *
+ * @see ::MULTI_REF_STATUS_BIT_MASKS
*/
-typedef uint16_t MULTI_REF_STATUS; /* flag bits as defined below */
+typedef uint16_t MULTI_REF_STATUS;
-/*
- * 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:
+/**
+ * @brief Enumeration of multi ref status bits
+ *
+ * @see ::MULTI_REF_STATUS_BIT_MASKS
+ */
+enum MULTI_REF_STATUS_BITS
+{
+ WRN_MODULE_MODE, ///< selected input mode was invalid, set to default
+ WRN_COLD_BOOT, ///< GPS is in cold boot mode
+ WRN_WARM_BOOT, ///< GPS is in warm boot mode
+ WRN_ANT_DISCONN, ///< antenna is disconnected
+ WRN_10MHZ_UNLOCK, ///< impossible to lock to external 10 MHz reference
+ WRN_1PPS_UNLOCK, ///< impossible to lock to external 1 PPS reference
+ WRN_GPS_UNLOCK, ///< impossible to lock to GPS
+ WRN_10MHZ_MISSING, ///< external 10 MHz signal not available
+ WRN_1PPS_MISSING, ///< external 1 PPS signal not available
+ N_MULTI_REF_STATUS_BITS ///< the number of known bits
+};
+
+
+/**
+ * @brief Bit masks associated with ::MULTI_REF_STATUS_BITS
+ *
+ * Used with ::MULTI_REF_STATUS.
+ *
+ * @see ::MULTI_REF_STATUS_BITS
*/
-enum
+enum MULTI_REF_STATUS_BIT_MASKS
{
- WRN_MODULE_MODE, /* selected input mode was invalid, set to default */
- WRN_COLD_BOOT, /* GPS is in cold boot mode */
- WRN_WARM_BOOT, /* GPS is in warm boot mode */
- WRN_ANT_DISCONN, /* antenna is disconnected */
- WRN_10MHZ_UNLOCK, /* impossible to lock to external 10MHz reference */
- WRN_1PPS_UNLOCK, /* impossible to lock to external 1PPS reference */
- WRN_GPS_UNLOCK, /* impossible to lock to GPS */
- WRN_10MHZ_MISSING, /* external 10MHz signal not available */
- WRN_1PPS_MISSING, /* external 1PPS signal not available */
- N_MULTI_REF_STATUS_BITS
+ MSK_WRN_COLD_BOOT = ( 1UL << WRN_COLD_BOOT ), ///< see ::WRN_COLD_BOOT
+ MSK_WRN_WARM_BOOT = ( 1UL << WRN_WARM_BOOT ), ///< see ::WRN_WARM_BOOT
+ MSK_WRN_ANT_DISCONN = ( 1UL << WRN_ANT_DISCONN ), ///< see ::WRN_ANT_DISCONN
+ MSK_WRN_10MHZ_UNLOCK = ( 1UL << WRN_10MHZ_UNLOCK ), ///< see ::WRN_10MHZ_UNLOCK
+ MSK_WRN_1PPS_UNLOCK = ( 1UL << WRN_1PPS_UNLOCK ), ///< see ::WRN_1PPS_UNLOCK
+ MSK_WRN_GPS_UNLOCK = ( 1UL << WRN_GPS_UNLOCK ), ///< see ::WRN_GPS_UNLOCK
+ MSK_WRN_10MHZ_MISSING = ( 1UL << WRN_10MHZ_MISSING ), ///< see ::WRN_10MHZ_MISSING
+ MSK_WRN_1PPS_MISSING = ( 1UL << WRN_1PPS_MISSING ), ///< see ::WRN_1PPS_MISSING
+ MSK_WRN_MODULE_MODE = ( 1UL << WRN_MODULE_MODE ) ///< see ::WRN_MODULE_MODE
};
-#define MSK_WRN_COLD_BOOT ( 1UL << WRN_COLD_BOOT )
-#define MSK_WRN_WARM_BOOT ( 1UL << WRN_WARM_BOOT )
-#define MSK_WRN_ANT_DISCONN ( 1UL << WRN_ANT_DISCONN )
-#define MSK_WRN_10MHZ_UNLOCK ( 1UL << WRN_10MHZ_UNLOCK )
-#define MSK_WRN_1PPS_UNLOCK ( 1UL << WRN_1PPS_UNLOCK )
-#define MSK_WRN_GPS_UNLOCK ( 1UL << WRN_GPS_UNLOCK )
-#define MSK_WRN_10MHZ_MISSING ( 1UL << WRN_10MHZ_MISSING )
-#define MSK_WRN_1PPS_MISSING ( 1UL << WRN_1PPS_MISSING )
-#define MSK_WRN_MODULE_MODE ( 1UL << WRN_MODULE_MODE )
+/** @} defgroup group_multi_ref_old */
-/*
- * 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.
+/**
+ * @defgroup group_multi_ref_ext Extended multi ref definitions
*
- * 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.
- */
+ * If the ::GPS_HAS_XMULTI_REF feature is set in ::RECEIVER_INFO::features then
+ * the XMULTI_REF (extended multi ref, XMR) feature and API are supported and
+ * have to be used in favor of the older multi ref API (see @ref group_multi_ref_old).
+ *
+ * Devices supporting the XMULTI_REF feature provide 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.
+ *
+ * These structures are used to configure the individual time source for each
+ * priority level, and retrieve the status of the time source at each priority level.
+ *
+ * If ::GPS_HAS_XMRS_MULT_INSTC is also set in ::RECEIVER_INFO::features then
+ * ::XMULTI_REF_INSTANCES can be used to find out which types of input source
+ * are supported (::XMULTI_REF_INSTANCES::n_inst array entries != 0), and
+ * how many priority levels are supported to which an input source can be
+ * assigned (::XMULTI_REF_INSTANCES::n_xmr_settings).
+ *
+ * If ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags
+ * then ::XMR_HOLDOVER_STATUS can be used to monitor the switching between
+ * different time sources when they become available or unavailable.
+ *
+ * If an XMR time source at a high priority level becomes unavailable the
+ * XMR control function tries to find and switch to a different time source
+ * at a lower level of the priority list, which is still available.
+ *
+ * On the other hand, if a time source at a higher priority level becomes
+ * available again, the XMR control function switches over to the time source
+ * at the higher priority even if the current time source is still available.
+ *
+ * If the accuracy of the time source at the next priority level is better than
+ * the accuracy of the time source at the current priority level then switching
+ * can be done immediately. However, if the next time source is worse than
+ * the current one it makes more sense to switch only after a certain holdover
+ * interval.
+ *
+ * The holdover interval is computed so that the time error due to the expected
+ * drift of the previously disciplined time base grows until it reaches the
+ * accuracy level of the next available reference time source.
+ *
+ * Only if the time source at the current priority level is still unavailable
+ * when the holdover interval expires the reference time source is switched
+ * to the time source at the next available priority level.
+ *
+ * @{ */
+
+/**
+ * @brief Identifier for a reference source
+ */
typedef struct
{
- uint8_t type; /* 0..N_MULTI_REF-1 from the enum above */
- uint8_t instance; /* reserved, currently always 0 */
+ uint8_t type; ///< see ::MULTI_REF_TYPES, and note for ::XMRIF_BIT_MRF_NONE_SUPP
+ uint8_t instance; ///< instance number, if multiple instances are supported, else 0
+
} XMULTI_REF_ID;
+
+
+/**
+ * @brief Reference source configuration settings
+ */
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_ID id; ///< reference time source identifier
+ uint16_t flags; ///< see ::XMR_SETTINGS_FLAG_MSKS and ::XMR_EXT_SRC_INFO::supp_flags
+ NANO_TIME bias; ///< time bias, e.g. path delay @todo specify sign vs. earlier/later
+ NANO_TIME precision; ///< precision of the time source
+ uint32_t reserved; ///< reserved, currently always 0
+
} 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.
+
+/**
+ * @brief Reference source configuration for a specific priority level
+ *
+ * @note After all other ::XMULTI_REF_SETTINGS_IDX configuration structures
+ * have been sent to a device, an additional structure with idx == -1 (0xFFFF)
+ * has to be sent to let the new settings come into effect.
*/
typedef struct
{
- uint16_t idx; /* the priority level index, highest == 0 */
- XMULTI_REF_SETTINGS settings; /* the settings configured for this level */
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ 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.
+
+/**
+ * @brief Bit masks used to define ::XMR_SETTINGS_FLAG_MSKS
+ */
+enum XMR_SETTINGS_FLAG_BITS
+{
+ XMRSF_BIT_AUTO_BIAS_MASTER, ///< src is allowed to operate as zero asymmetry master
+ XMRSF_BIT_AUTO_BIAS_SLAVE, ///< accept static bias correction from zero asymmetry master
+ XMRSF_BIT_ASYMMETRY_STEP_DETECTION, ///< static bias auto correction in case of step
+ N_XMRSF_BITS ///< number of know status bits
+};
+
+
+/**
+ * @brief Bit masks used with ::XMULTI_REF_SETTINGS::flags and ::XMR_EXT_SRC_INFO::supp_flags
+ */
+enum XMR_SETTINGS_FLAG_MSKS
+{
+ XMRSF_MSK_AUTO_BIAS_MASTER = ( 1UL << XMRSF_BIT_AUTO_BIAS_MASTER ), ///< see ::XMRSF_BIT_AUTO_BIAS_MASTER
+ XMRSF_MSK_AUTO_BIAS_SLAVE = ( 1UL << XMRSF_BIT_AUTO_BIAS_SLAVE ), ///< see ::XMRSF_BIT_AUTO_BIAS_SLAVE
+ XMRSF_MSK_ASYMMETRY_STEP_DETECTION = ( 1UL << XMRSF_BIT_ASYMMETRY_STEP_DETECTION ) ///< see ::XMRSF_BIT_ASYMMETRY_STEP_DETECTION
+};
+
+
+
+/**
+ * @brief Reference source capabilities and current configuration
*/
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_SETTINGS settings; ///< current settings
+
+ /**
+ * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_inst.
+ * If ::GPS_HAS_XMRS_MULT_INSTC is *not* set then this field provides
+ * a bit mask of supported sources (see @ref MULTI_REF_TYPE_MASKS),
+ * and only a single instance of each source signal type is supported.
+ */
+ uint32_t supp_ref;
+
+ /**
+ * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_xmr_settings.
+ * If ::GPS_HAS_XMRS_MULT_INSTC is *not* set then this field
+ * reports the number of priority levels supported by the device.
+ */
+ uint8_t n_supp_ref;
+
+ uint8_t n_prio; ///< reserved, don't use, currently always 0 //##++++ TODO: check which devices support/use this field
+ uint16_t flags; ///< reserved, don't use, currently always 0
} XMULTI_REF_INFO;
-/*
- * The structure below is used to retrieve the XMULTI_REF configuration
- * information for a specific priority level.
+
+/**
+ * @brief Reference source capabilities and current configuration for a specific priority level
*/
typedef struct
{
- uint16_t idx; /* the priority level index, highest == 0 */
- XMULTI_REF_INFO info;
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMULTI_REF_INFO info; ///< ref source configuration and capabilities
} XMULTI_REF_INFO_IDX;
-/*
- * The structure below contains status information on a single
- * ref time source.
+
+/**
+ * @brief 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_ID id; ///< time source identifier
+ uint16_t status; ///< status bits, see @ref XMR_REF_STATUS_BIT_MASKS
+ NANO_TIME offset; ///< time offset from main time base @todo specify sign vs. earlier/later
+ uint16_t flags; ///< flags, currently unused
+ uint8_t ssm; ///< synchronization status message, if supported by signal source
+ uint8_t soc; ///< signal outage counter, incremented on loss of signal
} XMULTI_REF_STATUS;
-/*
- * The structure below is used to retrieve the the status information
- * of the time source at a specific priority level.
+
+/**
+ * @brief Status information on a ref time source at a specific priority level
*/
typedef struct
{
- uint16_t idx; /* the priority level index, highest == 0 */
- XMULTI_REF_STATUS status;
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMULTI_REF_STATUS status; ///< status information
} XMULTI_REF_STATUS_IDX;
-/*
- * Bits used with XMULTI_REF_STATUS.
+
+/**
+ * @brief XMULTI_REF status bits
*/
-enum
+enum XMR_REF_STATUS_BITS
{
- XMRS_BIT_NOT_SUPP, /* ref type cfg'd for this level is not supported */
- XMRS_BIT_NO_CONN, /* input signal is disconnected */
- XMRS_BIT_NO_SIGNAL, /* no input signal */
- XMRS_BIT_IS_MASTER, /* reference is master source */
- XMRS_BIT_IS_LOCKED, /* locked to input signal */
- XMRS_BIT_IS_ACCURATE, /* oscillator control has reached full accuracy */
- XMRS_BIT_NOT_SETTLED, /* reference time signal not settled */
- XMRS_BIT_NOT_PHASE_LOCKED, /* oscillator not phase locked to PPS */
- N_XMRS_BITS
+ XMRS_BIT_NOT_SUPP, ///< ref type cfg'd for this level is not supported
+ XMRS_BIT_NO_CONN, ///< input signal is disconnected
+ XMRS_BIT_NO_SIGNAL, ///< no input signal
+ XMRS_BIT_IS_MASTER, ///< reference is master source
+ XMRS_BIT_IS_LOCKED, ///< locked to input signal
+ XMRS_BIT_IS_ACCURATE, ///< oscillator control has reached full accuracy
+ XMRS_BIT_NOT_SETTLED, ///< reference time signal not settled
+ XMRS_BIT_NOT_PHASE_LOCKED, ///< oscillator not phase locked to PPS
+ XMRS_BIT_NUM_SRC_EXC, ///< number of available sources exceeds what can be handled
+ XMRS_BIT_IS_EXTERNAL, ///< this ref source is on extension card
+ XMRS_BIT_LOW_JITTER, ///< this ref source has low jitter
+ N_XMRS_BITS ///< number of know status bits
};
-/* bit masks corresponding to the flag bits above */
+/**
+ * @brief Bit masks associated with ::XMR_REF_STATUS_BITS
+ *
+ * Used with ::XMULTI_REF_STATUS::status.
+ *
+ * @see ::XMR_REF_STATUS_BITS
+ *
+ * @anchor XMR_REF_STATUS_BIT_MASKS @{ */
+
+#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) ///< see ::XMRS_BIT_NOT_SUPP
+#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) ///< see ::XMRS_BIT_NO_CONN
+#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) ///< see ::XMRS_BIT_NO_SIGNAL
+#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER ) ///< see ::XMRS_BIT_IS_MASTER
+#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED ) ///< see ::XMRS_BIT_IS_LOCKED
+#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE ) ///< see ::XMRS_BIT_IS_ACCURATE
+#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED ) ///< see ::XMRS_BIT_NOT_SETTLED
+#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED ) ///< see ::XMRS_BIT_NOT_PHASE_LOCKED
+#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC ) ///< see ::XMRS_BIT_NUM_SRC_EXC
+#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL ) ///< see ::XMRS_BIT_IS_EXTERNAL
+#define XMRS_MSK_LOW_JITTER ( 1UL << XMRS_BIT_LOW_JITTER ) ///< see ::XMRS_BIT_LOW_JITTER
-#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP )
-#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN )
-#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL )
-#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER )
-#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED )
-#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE )
-#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED )
-#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED )
+/** @} anchor XMR_REF_STATUS_BIT_MASKS */
+/**
+ * @brief XMRS status bit name strings
+ *
+ * @see ::XMR_REF_STATUS_BITS
+ */
+#define MBG_XMRS_STATUS_STRS \
+{ \
+ "Ref type not supported", \
+ "No connection", \
+ "No signal", \
+ "Is master", \
+ "Is locked", \
+ "Is accurate", \
+ "Not settled", \
+ "Phase not locked", \
+ "Number sources exceeds limit", \
+ "Is external", \
+ "Low jitter" \
+}
+
/*
- * An initializer for a XMULTI_REF_STATUS variable
- * with status invalid / not used
+ * An initializer for a ::XMULTI_REF_STATUS variable
+ * with status invalid / not used
*/
#define XMULTI_REF_STATUS_INVALID \
{ \
@@ -3393,30 +5642,1840 @@ enum
}
+/**
+ * @brief General info on supported XMR sources and instances
+ *
+ * @note This structure is only supported if ::GPS_HAS_XMRS_MULT_INSTC
+ * is set in ::RECEIVER_INFO::features.
+ *
+ * The field ::XMULTI_REF_INSTANCES::n_xmr_settings reports the maximum number
+ * of entries that can be held by the input source table provided by this device.
+ * The input source table entry with the lowest index has the highest priority,
+ * and values 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 can be used as index
+ * when reading ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX from the device,
+ * or when writing ::XMULTI_REF_SETTINGS_IDX to the device to configure
+ * the priority/order of input sources.
+ *
+ * An input source table entry is empty if ::XMULTI_REF_ID::type is set to
+ * ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id, and accordingly
+ * in ::XMULTI_REF_STATUS::id.
+ *
+ * The array ::XMULTI_REF_INSTANCES::n_inst reports how many instances are supported
+ * for every known reference type. For example, if 2 PPS input signals were supported
+ * then ::XMULTI_REF_INSTANCES::n_inst[::MULTI_REF_PPS] was set to 2. Even though
+ * this array can hold up to ::MAX_N_MULTI_REF_TYPES entries, the number entries
+ * which are actually used is ::N_MULTI_REF, according to the number of known
+ * reference signal types, which is less or equal than ::MAX_N_MULTI_REF_TYPES.
+ */
+typedef struct
+{
+ uint32_t flags; ///< see ::XMR_INST_FLAG_BIT_MASKS
+ uint16_t n_xmr_settings; ///< number of ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX which can be retrieved
+ uint8_t slot_id; ///< ID of the slot in which this device is installed, 0 or up to 15, if multiple slots not supported
+ uint8_t reserved; ///< reserved, don't use, currently always 0
+ uint8_t n_inst[MAX_N_MULTI_REF_TYPES]; ///< the number of supported instances of each input signal type
+
+} XMULTI_REF_INSTANCES;
+
-/*------------------------------------------------------------------------*/
+
+/**
+ * @brief Enumeration of flag bits used with XMULTI_REF instances
+ *
+ * @see ::XMR_INST_FLAG_BIT_MASKS
+ */
+enum XMR_INST_FLAGS
+{
+ /// This flag indicates that configuration programs may set
+ /// ::XMULTI_REF_ID::type to ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id
+ /// for unused priority levels, and that this will be reflected in
+ /// ::XMULTI_REF_STATUS::id accordingly. With some older firmware versions
+ /// this was not supported.
+ XMRIF_BIT_MRF_NONE_SUPP,
+
+ XMRIF_BIT_HOLDOVER_STATUS_SUPP, ///< ::XMR_HOLDOVER_STATUS and associated types supported
+
+ XMRIF_BIT_EXT_SRC_INFO_SUPP, ///< ::XMR_EXT_SRC_INFO structure supported
+
+ N_XMRIF_BITS ///< number of known flag bits
+};
+
+
+/**
+ * @brief Bit masks associated with ::XMR_INST_FLAGS
+ *
+ * Used with ::XMULTI_REF_INSTANCES::flags.
+ *
+ * @see ::XMR_INST_FLAGS
+ */
+enum XMR_INST_FLAG_BIT_MASKS
+{
+ XMRIF_MSK_MRF_NONE_SUPP = ( 1UL << XMRIF_BIT_MRF_NONE_SUPP ), ///< see ::XMRIF_BIT_MRF_NONE_SUPP
+ XMRIF_MSK_HOLDOVER_STATUS_SUPP = ( 1UL << XMRIF_BIT_HOLDOVER_STATUS_SUPP ), ///< see ::XMRIF_BIT_HOLDOVER_STATUS_SUPP
+ XMRIF_MSK_EXT_SRC_INFO_SUPP = ( 1UL << XMRIF_BIT_EXT_SRC_INFO_SUPP ) ///< see ::XMRIF_BIT_EXT_SRC_INFO_SUPP
+};
+
+
+/**
+ * @brief XMR holdover interval, or elapsed holdover time, in [s]
+ */
+typedef uint32_t XMR_HOLDOVER_INTV;
+
+#define _mbg_swab_xmr_holdover_intv( _p ) \
+ _mbg_swab32( _p );
+
+
+
+/**
+ * @brief A code used to indicate that a input source table index is unspecified
+ */
+#define XMR_PRIO_LVL_UNSPEC -1
+
+
+/**
+ * @brief XMR holdover status
+ *
+ * Only supported if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags
+ *
+ * Reports the current holdover status including the elapsed holdover time
+ * and the currently active holdover interval, as well as the indices of the
+ * current and next XMR time source.
+ *
+ * The flag ::XMR_HLDOVR_MSK_IN_HOLDOVER is set if holdover mode is currently active.
+ *
+ * The fields ::XMR_HOLDOVER_STATUS::curr_prio and ::XMR_HOLDOVER_STATUS::nxt_prio
+ * specify the current or next priority level which can be in the range
+ * 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, or ::XMR_PRIO_LVL_UNSPEC if the
+ * index is undefined, e.g. because no input source is available to which can
+ * be switched after the holdover interval.
+ *
+ * The ::XMR_HOLDOVER_STATUS::mode field indicates the current XMR/holdover mode
+ * which is usually ::XMR_HLDOVR_AUTONOMOUS. However, in certain applications
+ * XMR switching is controlled remotely, in which case ::XMR_HOLDOVER_STATUS::mode
+ * is set to ::XMR_HLDOVR_REMOTE.
+ *
+ * If the device is in remote mode and needs to switch XMR sources then mode changes
+ * to ::XMR_HLDOVR_PRE_AUTONOMOUS, and the ::XMR_HOLDOVER_STATUS::remote_watchdog
+ * starts to count down. If the watchdog expires before a remote switch command
+ * has been received the device switches to ::XMR_HLDOVR_AUTONOMOUS.
+ */
+typedef struct
+{
+ uint8_t mode; ///< XMR/holdover mode, see ::XMR_HOLDOVER_STATUS_MODES
+ int8_t curr_prio; ///< current priority level, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ int8_t nxt_prio; ///< next priority level after holdover, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ uint8_t remote_watchdog; ///< counts down in ::XMR_HLDOVR_PRE_AUTONOMOUS mode
+ uint32_t reserved; ///< reserved, don't use, currently 0
+ XMR_HOLDOVER_INTV elapsed; ///< elapsed time in holdover mode, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ XMR_HOLDOVER_INTV interval; ///< current holdover interval, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ uint32_t flags; ///< holdover status flags, see ::XMR_HOLDOVER_STATUS_FLAG_MASKS
+
+} XMR_HOLDOVER_STATUS;
+
+
+/**
+ * @brief XMR holdover status modes
+ *
+ * Used with ::XMR_HOLDOVER_STATUS::mode.
+ *
+ * @see ::XMR_HOLDOVER_STATUS_MODE_NAMES
+ */
+enum XMR_HOLDOVER_STATUS_MODES
+{
+ XMR_HLDOVR_AUTONOMOUS, ///< autonomous mode, XMR sources are selected automatically by the device
+ XMR_HLDOVR_PRE_AUTONOMOUS, ///< going to switch to autonomous mode when ::XMR_HOLDOVER_STATUS::remote_watchdog reaches 0
+ XMR_HLDOVR_REMOTE, ///< remote mode, XMR switching done by external command/control
+ N_XMR_HOLDOVER_STATUS_MODES ///< the number of known modes
+};
+
+
+/**
+ * @brief String initializers for XMR holdover status mode
+ *
+ * @see ::XMR_HOLDOVER_STATUS_MODES
+ */
+#define XMR_HOLDOVER_STATUS_MODE_NAMES \
+{ \
+ "autonomous", \
+ "pre-autonomous", \
+ "remote" \
+}
+
+
+
+/**
+ * @brief XMR holdover status flag bits
+ *
+ * Used to define ::XMR_HOLDOVER_STATUS_FLAG_MASKS.
+ */
+enum XMR_HOLDOVER_STATUS_FLAG_BITS
+{
+ XMR_HLDOVR_BIT_IN_HOLDOVER, ///< the device is currently in holdover mode
+ XMR_HLDOVR_BIT_TRANSITION_ENBD, ///< timebase is in transition (being slewed) after sources have been switched
+ XMR_HLDOVR_BIT_IN_TRANSITION, ///< transition is currently active, slewing in progress
+ N_XMR_HOLDOVER_STATUS_FLAG_BITS ///< the number of known status flags
+};
+
+
+/**
+ * @brief XMR holdover status flag masks
+ *
+ * Used with ::XMR_HOLDOVER_STATUS::flags.
+ */
+enum XMR_HOLDOVER_STATUS_FLAG_MASKS
+{
+ XMR_HLDOVR_MSK_IN_HOLDOVER = ( 1UL << XMR_HLDOVR_BIT_IN_HOLDOVER ), ///< see ::XMR_HLDOVR_BIT_IN_HOLDOVER
+ XMR_HLDOVR_MSK_TRANSITION_ENBD = ( 1UL << XMR_HLDOVR_BIT_TRANSITION_ENBD ), ///< see ::XMR_HLDOVR_BIT_TRANSITION_ENBD
+ XMR_HLDOVR_MSK_IN_TRANSITION = ( 1UL << XMR_HLDOVR_BIT_IN_TRANSITION ) ///< see ::XMR_HLDOVR_BIT_IN_TRANSITION
+};
+
+
+typedef struct
+{
+ uint16_t supp_flags; ///< indicates which flags are supported by ::XMULTI_REF_SETTINGS::flags, see ::XMR_SETTINGS_FLAG_MSKS
+ uint16_t reserved_0;
+ uint32_t reserved_1;
+
+} XMR_EXT_SRC_INFO;
+
+
+typedef struct
+{
+ uint16_t idx; //
+ XMR_EXT_SRC_INFO info; //
+
+} XMR_EXT_SRC_INFO_IDX; //
+
+
+/** @} defgroup group_multi_ref_ext */
+
+/** @} defgroup group_multi_ref_all */
+
+
+
+/**
+ * @defgroup group_gpio GPIO port configuration stuff
+ *
+ * @note This is only supported if ::GPS_HAS_GPIO is set
+ * in the ::RECEIVER_INFO::features mask.
+ *
+ * @{ */
+
+
+/**
+ * @brief General GPIO config info to be read from a device
+ *
+ * Used to query from a device how many GPIO ports are supported
+ * by the device, then index 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ * configuration or status records can be read from or written to
+ * the device.
+ */
+typedef struct
+{
+ uint32_t num_io; ///< number of supported GPIO ports
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+
+} MBG_GPIO_CFG_LIMITS;
+
+#define _mbg_swab_mbg_gpio_cfg_limits( _p ) \
+{ \
+ _mbg_swab32( &(_p)->num_io ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief GPIO limits flag bits used to define ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+ *
+ * @see ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+ */
+enum MBG_GPIO_CFG_LIMIT_FLAG_BITS
+{
+ MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP, ///< indicates that ::MBG_GPIO_STATUS is supported
+ N_MBG_GPIO_CFG_LIMIT_FLAG_BITS
+};
+
+
+
+/**
+ * @brief GPIO limits flag masks associated with ::MBG_GPIO_CFG_LIMIT_FLAG_BITS
+ *
+ * Used with ::MBG_GPIO_CFG_LIMITS::flags
+ *
+ * @see ::MBG_GPIO_CFG_LIMIT_FLAG_BITS
+ */
+enum MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+{
+ MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP = ( 1UL << MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP ), ///< see ::MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP
+};
+
+
+
+/**
+ * @brief Enumeration of GPIO types
+ *
+ * Usually a specific GPIO port can only be either an input
+ * or an output, and supports only a single signal type.
+ * This is due to hardware limitations, i.e. input or output
+ * circuitry required for the given signal.
+ *
+ * @see ::DEFAULT_GPIO_TYPES_SHORT_STRS
+ */
+enum MBG_GPIO_TYPES
+{
+ MBG_GPIO_TYPE_FREQ_IN, ///< variable frequency input, freq == 0 if input not used
+ MBG_GPIO_TYPE_FREQ_OUT, ///< variable frequency output
+ MBG_GPIO_TYPE_FIXED_FREQ_OUT, ///< fixed frequency output
+ MBG_GPIO_TYPE_BITS_IN, ///< framed data stream input
+ MBG_GPIO_TYPE_BITS_OUT, ///< framed data stream output
+ N_MBG_GPIO_TYPES ///< number of known types
+};
+
+
+#define DEFAULT_GPIO_TYPES_SHORT_STRS \
+{ \
+ "Freq. In", \
+ "Freq. Out", \
+ "Fixed Freq Out", \
+ "BITS In", \
+ "BITS Out" \
+}
+
+
+
+/**
+ * @brief Enumeration of known signal shapes
+ *
+ * Used to specify the signal shape of an input or output
+ * frequency signal.
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ * @see ::DEFAULT_GPIO_SIGNAL_SHAPE_NAMES
+ */
+enum MBG_GPIO_SIGNAL_SHAPES
+{
+ MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED, ///< unknown or unspecified signal shape
+ MBG_GPIO_SIGNAL_SHAPE_SINE, ///< sine wave
+ MBG_GPIO_SIGNAL_SHAPE_SQUARE, ///< square wave
+ N_MBG_GPIO_SIGNAL_SHAPES ///< number of known signal shapes
+};
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_SIGNAL_SHAPES
+ *
+ * Used e.g. with ::MBG_GPIO_FREQ_IN_SUPP::supp_shapes,
+ * ::MBG_GPIO_FREQ_OUT_SUPP::supp_shapes,
+ * and ::MBG_GPIO_FIXED_FREQ_OUT_SUPP::supp_shapes.
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPES
+ */
+enum MBG_GPIO_SIGNAL_SHAPE_MASKS
+{
+ MBG_GPIO_SIGNAL_SHAPE_MSK_UNSPECIFIED = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED ), ///< see ::MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED
+ MBG_GPIO_SIGNAL_SHAPE_MSK_SINE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SINE ), ///< see ::MBG_GPIO_SIGNAL_SHAPE_SINE
+ MBG_GPIO_SIGNAL_SHAPE_MSK_SQUARE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SQUARE ) ///< see ::MBG_GPIO_SIGNAL_SHAPE_SQUARE
+};
+
+
+
+/**
+ * @brief String initializers for GPIO signal shapes
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPES
+ */
+#define DEFAULT_GPIO_SIGNAL_SHAPE_NAMES \
+{ \
+ "(unspec. shape)", \
+ "Sine wave", \
+ "Rectangle Pulse" \
+}
+
+
+
+/**
+ * @brief A structure used to specify a variable frequency
+ *
+ * Used to specify a variable frequency for GPIO input or output
+ */
+typedef struct
+{
+ uint32_t hz; ///< integral number [Hz]
+ uint32_t frac; ///< fractional part, binary (0x80000000 --> 0.5, 0xFFFFFFFF --> 0.9999999...)
+
+} MBG_GPIO_FREQ;
+
+#define _mbg_swab_mbg_gpio_freq( _p ) \
+{ \
+ _mbg_swab32( &(_p)->hz ); \
+ _mbg_swab32( &(_p)->frac); \
+}
+
+
+
+/**
+ * @brief Configuration of a GPIO variable frequency input
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_IN
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ MBG_GPIO_FREQ freq; ///< frequency in range ::MBG_GPIO_FREQ_IN_SUPP::freq_min..::MBG_GPIO_FREQ_IN_SUPP::freq_max, or 0 if input is not used
+ uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units], see ::MBG_GPIO_FREQ_IN_SUPP::csc_limit_max
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_IN_SETTINGS;
+
+
+/**
+ * @brief Supported options for a variable frequency GPIO input
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_IN
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t freq_min; ///< minimum output frequency [Hz]
+ uint32_t freq_max; ///< maximum output frequency [Hz]
+ uint32_t csc_limit_max; ///< 1/1000 units of the signal period, limited due to 10 ns sampling interval, see ::MBG_GPIO_FREQ_IN_SETTINGS::csc_limit //##++++++++++++++++
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_IN_SUPP;
+
+
+
+/**
+ * @brief Configuration of a GPIO variable frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ MBG_GPIO_FREQ freq; ///< frequency, see ::MBG_GPIO_FREQ_OUT_SUPP::freq_min and ::MBG_GPIO_FREQ_OUT_SUPP::freq_max
+ int32_t milli_phase; ///< phase [1/1000 degree units], see ::MBG_GPIO_FREQ_OUT_SUPP::milli_phase_max
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_OUT_SETTINGS;
+
+
+
+/**
+ * @brief Supported options for a variable frequency GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t freq_min; ///< minimum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq
+ uint32_t freq_max; ///< maximum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq
+ uint32_t freq_resolution; ///< frequency resolution [Hz], unspecified if 0
+ uint32_t milli_phase_max; ///< max. abs. milli_phase, see ::MBG_GPIO_FREQ_OUT_SETTINGS::milli_phase
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_OUT_SUPP;
+
+
+
+/**
+ * @brief Enumeration of predefined fixed frequencies
+ *
+ * @see ::MBG_GPIO_FIXED_FREQ_MASKS
+ * @see ::MBG_GPIO_FIXED_FREQ_STRS
+ */
+enum MBG_GPIO_FIXED_FREQS
+{
+ MBG_GPIO_FIXED_FREQ_8kHz, ///< 8 kHz
+ MBG_GPIO_FIXED_FREQ_48kHz, ///< 48 kHz
+ MBG_GPIO_FIXED_FREQ_1MHz, ///< 1 MHz
+ MBG_GPIO_FIXED_FREQ_1544kHz, ///< 1.544 MHz
+ MBG_GPIO_FIXED_FREQ_2048kHz, ///< 2.048 MHz
+ MBG_GPIO_FIXED_FREQ_5MHz, ///< 5 MHz
+ MBG_GPIO_FIXED_FREQ_10MHz, ///< 10 MHz
+ MBG_GPIO_FIXED_FREQ_19440kHz, ///< 19.44 MHz
+ N_MBG_GPIO_FIXED_FREQ ///< number of predefined fixed frequencies
+};
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_FIXED_FREQS
+ *
+ * @see ::MBG_GPIO_FIXED_FREQS
+ * @see ::MBG_GPIO_FIXED_FREQ_STRS
+ */
+enum MBG_GPIO_FIXED_FREQ_MASKS
+{
+ MSK_MBG_GPIO_FIXED_FREQ_8kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_8kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_8kHz
+ MSK_MBG_GPIO_FIXED_FREQ_48kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_48kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_48kHz
+ MSK_MBG_GPIO_FIXED_FREQ_1MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_1MHz
+ MSK_MBG_GPIO_FIXED_FREQ_1544kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1544kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_1544kHz
+ MSK_MBG_GPIO_FIXED_FREQ_2048kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_2048kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_2048kHz
+ MSK_MBG_GPIO_FIXED_FREQ_5MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_5MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_5MHz
+ MSK_MBG_GPIO_FIXED_FREQ_10MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_10MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_10MHz
+ MSK_MBG_GPIO_FIXED_FREQ_19440kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_19440kHz ) ///< see ::MBG_GPIO_FIXED_FREQ_19440kHz
+};
+
+
+/**
+ * @brief Initializers for an array of GPIO fixed frequency name strings
+ *
+ * @see ::MBG_GPIO_FIXED_FREQS
+ * @see ::MBG_GPIO_FIXED_FREQ_MASKS
+ */
+#define MBG_GPIO_FIXED_FREQ_STRS \
+{ \
+ "8 kHz", \
+ "48 kHz", \
+ "1 MHz", \
+ "1544 kHz", \
+ "2048 kHz", \
+ "5 MHz", \
+ "10 MHz", \
+ "19440 kHz" \
+}
+
+
+/**
+ * @brief Configuration of a GPIO fixed frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t freq_idx; ///< fixed frequency index, see ::MBG_GPIO_FIXED_FREQS
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FIXED_FREQ_OUT_SETTINGS;
+
+
+/**
+ * @brief Supported options for a fixed frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_freq; ///< bit mask of supported fixed frequencies, see ::MBG_GPIO_FIXED_FREQ_MASKS
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FIXED_FREQ_OUT_SUPP;
+
+
+
+/**
+ * @brief Enumeration of BITS signal formats
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::format and ::MBG_GPIO_BITS_OUT_SETTINGS::format
+ *
+ * @see ::MBG_GPIO_BITS_FORMAT_MASKS
+ */
+enum MBG_GPIO_BITS_FORMATS
+{
+ MBG_GPIO_BITS_E1_FRAMED, ///< 2.048 MBit
+ MBG_GPIO_BITS_T1_FRAMED, ///< 1.544 MBit
+ MBG_GPIO_BITS_E1_TIMING, ///< 2.048 MHz
+ MBG_GPIO_BITS_T1_TIMING, ///< 2.048 MHz
+ N_MBG_GPIO_BITS_FORMATS ///< number of defined formats
+};
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_BITS_FORMATS
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SUPP::supp_fmts and ::MBG_GPIO_BITS_OUT_SUPP::supp_fmts.
+ *
+ * @see ::MBG_GPIO_BITS_FORMATS
+ */
+enum MBG_GPIO_BITS_FORMAT_MASKS
+{
+ MSK_MBG_GPIO_BITS_E1_FRAMED = ( 1UL << MBG_GPIO_BITS_E1_FRAMED ), ///< see ::MBG_GPIO_BITS_E1_FRAMED
+ MSK_MBG_GPIO_BITS_T1_FRAMED = ( 1UL << MBG_GPIO_BITS_T1_FRAMED ), ///< see ::MBG_GPIO_BITS_T1_FRAMED
+ MSK_MBG_GPIO_BITS_E1_TIMING = ( 1UL << MBG_GPIO_BITS_E1_TIMING ), ///< see ::MBG_GPIO_BITS_E1_TIMING
+ MSK_MBG_GPIO_BITS_T1_TIMING = ( 1UL << MBG_GPIO_BITS_T1_TIMING ) ///< see ::MBG_GPIO_BITS_T1_TIMING
+};
+
+
+
+/**
+ * @brief Minimum and maximum known SSM values
+ *
+ * Values according to ITU G.704-1998
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1.ssm
+ * and ::MBG_GPIO_BITS_OUT_SETTINGS::ssm.
+ */
+enum GPIO_SSM_VALS
+{
+ GPIO_SSM_UNKNOWN, ///< Quality unknown, existing synchronization network
+ GPIO_SSM_RSVD_1, ///< (reserved)
+ GPIO_SSM_G_811, ///< Rec. G.811
+ GPIO_SSM_RSVD_3, ///< (reserved)
+ GPIO_SSM_SSU_A, ///< SSU-A
+ GPIO_SSM_RSVD_5, ///< (reserved)
+ GPIO_SSM_RSVD_6, ///< (reserved)
+ GPIO_SSM_RSVD_7, ///< (reserved)
+ GPIO_SSM_SSU_B, ///< SSU-B
+ GPIO_SSM_RSVD_9, ///< (reserved)
+ GPIO_SSM_RSVD_10, ///< (reserved)
+ GPIO_SSM_RSVD_SETS, ///< Synchronous Equipment Timing Source (SETS)
+ GPIO_SSM_RSVD_12, ///< (reserved)
+ GPIO_SSM_RSVD_13, ///< (reserved)
+ GPIO_SSM_RSVD_14, ///< (reserved)
+ GPIO_SSM_DONT_USE, ///< don't use
+ N_GPIO_SSM_VALS
+};
+
+
+
+/**
+ * @brief Minimum and maximum SA BITS groups
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1::sa_bits
+ * and ::MBG_GPIO_BITS_OUT_SETTINGS::sa_bits.
+ */
+enum GPIO_SA_BITS_GROUPS
+{
+ MIN_SA_BITS_GROUP = 4,
+ MAX_SA_BITS_GROUP = 8
+};
+
+
+/**
+ * @brief Configuration of a GPIO as BITS input module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_IN
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units]
+
+ union quality
+ {
+ struct e1
+ {
+ uint8_t ssm; ///< minimum E1 SSM for acceptance, 0..::N_GPIO_SSM_VALS-1
+ uint8_t sa_bits; ///< sa bits group carrying SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP
+ uint16_t reserved; ///< reserved, currently always 0
+ } e1; ///< used with E1 formats
+
+ struct t1
+ {
+ uint8_t min_boc;
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint16_t reserved_1; ///< reserved, currently always 0
+ } t1; ///< used with T1 formats
+
+ uint32_t u32; ///< dummy to force at least 32 bit alignment
+
+ } quality;
+
+ uint32_t err_msk; ///< controls which types of error can be ignored, see ::MBG_GPIO_BITS_ERR_MASKS
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_IN_SETTINGS;
+
+
+
+/**
+ * @brief Enumeration of BITS input error conditions
+ */
+enum MBG_GPIO_BITS_ERRS
+{
+ MBG_GPIO_BITS_ERR_LOS, ///< loss of signal
+ MBG_GPIO_BITS_ERR_LOF, ///< loss of frame
+ N_MBG_GPIO_BITS_ERRS ///< number of known errors
+};
+
+/**
+ * @brief Bit masks associated with BITS input error conditions
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::err_msk
+ *
+ * @see ::MBG_GPIO_BITS_ERRS
+ */
+enum MBG_GPIO_BITS_ERR_MASKS
+{
+ MSK_MBG_GPIO_BITS_ERR_LOS = ( 1UL << MBG_GPIO_BITS_ERR_LOS ), ///< see ::MBG_GPIO_BITS_ERR_LOS
+ MSK_MBG_GPIO_BITS_ERR_LOF = ( 1UL << MBG_GPIO_BITS_ERR_LOF ) ///< see ::MBG_GPIO_BITS_ERR_LOF
+};
+
+
+/**
+ * @brief Supported options of a BITS GPIO input
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_IN
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_IN_SUPP;
+
+
+
+/**
+ * @brief Configuration of a GPIO as BITS output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS
+ uint32_t flags; ///< flags for encoder control etc., see ::MBG_GPIO_BITS_OUT_FLAG_MASKS
+ uint8_t sa_bits; ///< number of SA bit group for E1 SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP
+ uint8_t ssm; ///< ssm for E1 mode, 0..::N_GPIO_SSM_VALS-1
+ uint8_t boc; ///< boc for T1 mode, 0..0x1F //##++++++++++++++
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+ uint32_t reserved_2; ///< reserved, currently always 0
+ uint32_t reserved_3; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_OUT_SETTINGS;
+
+
+/**
+ * @brief Enumeration of flags used with BITS type GPIO outputs
+ */
+enum MBG_GPIO_BITS_OUT_FLAGS
+{
+ MBG_GPIO_BITS_OUT_FLAG_HDB3, ///< enable HDB3 encoding (E1 mode only)
+ MBG_GPIO_BITS_OUT_FLAG_B8ZS, ///< enable B8ZS encoding (T1 mode only)
+ N_MBG_GPIO_BITS_OUT_FLAGS ///< number of known flags
+};
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_BITS_OUT_FLAGS
+ *
+ * Used with ::MBG_GPIO_BITS_OUT_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_BITS_OUT_FLAGS
+ */
+enum MBG_GPIO_BITS_OUT_FLAG_MASKS
+{
+ MSK_MBG_GPIO_BITS_OUT_FLAG_HDB3 = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_HDB3 ), ///< see ::MBG_GPIO_BITS_OUT_FLAG_HDB3
+ MSK_MBG_GPIO_BITS_OUT_FLAG_B8ZS = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_B8ZS ) ///< see ::MBG_GPIO_BITS_OUT_FLAG_B8ZS
+};
+
+
+/**
+ * @brief Supported options of a BITS type GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_OUT_SUPP;
+
+
+
+/**
+ * @brief A generic structure used to hold a GPIO port's settings
+ */
+typedef struct
+{
+ uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+ /// settings depending on the GPIO type, see ::MBG_GPIO_TYPES
+ union
+ {
+ MBG_GPIO_FREQ_IN_SETTINGS freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN
+ MBG_GPIO_FREQ_OUT_SETTINGS freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT
+ MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ MBG_GPIO_BITS_IN_SETTINGS bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN
+ MBG_GPIO_BITS_OUT_SETTINGS bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT
+ } u;
+
+} MBG_GPIO_SETTINGS;
+
+
+
+/**
+ * @brief A GPIO port's current settings, plus port index
+ */
+typedef struct
+{
+ uint32_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_SETTINGS settings; ///< current settings
+
+} MBG_GPIO_SETTINGS_IDX;
+
+
+
+/**
+ * @brief A generic structure used to specify a GPIO port's limits
+ */
+typedef struct
+{
+ uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< supported flags //##++++++++++++ which?
+
+ /// limits depending on the GPIO type, see ::MBG_GPIO_TYPES
+ union
+ {
+ MBG_GPIO_FREQ_IN_SUPP freq_in; ///< if type is ::MBG_GPIO_TYPE_FREQ_IN
+ MBG_GPIO_FREQ_OUT_SUPP freq_out; ///< if type is ::MBG_GPIO_TYPE_FREQ_OUT
+ MBG_GPIO_FIXED_FREQ_OUT_SUPP ff_out; ///< if type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ MBG_GPIO_BITS_IN_SUPP bits_in; ///< if type is ::MBG_GPIO_TYPE_BITS_IN
+ MBG_GPIO_BITS_OUT_SUPP bits_out; ///< if type is ::MBG_GPIO_TYPE_BITS_OUT
+ } u;
+
+} MBG_GPIO_LIMITS;
+
+
+
+/**
+ * @brief A GPIO port's current settings and limits
+ */
+typedef struct
+{
+ MBG_GPIO_SETTINGS settings; ///< current settings
+ MBG_GPIO_LIMITS limits; ///< limits of this GPIO port
+
+} MBG_GPIO_INFO;
+
+
+
+/**
+ * @brief A GPIO port's current settings and limits, plus port index
+ */
+typedef struct
+{
+ uint32_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_INFO info; ///< limits and current settings of this GPIO port
+
+} MBG_GPIO_INFO_IDX;
+
+
+
+/**
+ * @brief Status information on a single GPIO port
+ */
+typedef struct
+{
+ uint8_t port_state; ///< see ::MBG_GPIO_PORT_STATES
+ uint8_t reserved_0; ///< reserved, currently unused and always 0
+ uint16_t reserved_1; ///< reserved, currently unused and always 0
+ uint32_t reserved_2; ///< reserved, currently unused and always 0
+ uint32_t reserved_3; ///< reserved, currently unused and always 0
+
+} MBG_GPIO_STATUS;
+
+
+
+/**
+ * @brief Status information on a specific GPIO port
+ */
+typedef struct
+{
+ uint16_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_STATUS status; ///< status information
+
+} MBG_GPIO_STATUS_IDX;
+
+
+
+/**
+ * @brief GPIO port states
+ *
+ * Used with ::MBG_GPIO_STATUS::port_state
+ *
+ * @see ::DEFAULT_GPIO_PORT_STATE_NAMES
+ */
+enum MBG_GPIO_PORT_STATES
+{
+ MBG_GPIO_PORT_UNUSED, ///< configured as unused input
+ MBG_GPIO_PORT_OUTPUT_ENBD, ///< configured output signal enabled
+ MBG_GPIO_INPUT_SIG_AVAIL, ///< input signal is available
+ N_MBG_GPIO_PORT_STATES ///< number of known port states
+};
+
+
+
+/**
+ * @brief String initializers for GPIO port state names
+ *
+ * @see ::MBG_GPIO_PORT_STATES
+ */
+#define DEFAULT_GPIO_PORT_STATE_NAMES \
+{ \
+ "unused", \
+ "output enabled", \
+ "input signal available" \
+}
+
+
+/** @} defgroup group_gpio */
+
+
+
+/**
+ * @defgroup group_havequick HaveQuick definitions
+ *
+ * @note This is only supported if the ::GPS_HAS_HAVEQUICK bit is set
+ * in the ::RECEIVER_INFO::features mask.
+ *
+ * @{ */
+
+
+/**
+ * @brief Enumeration of HaveQuick formats
+ *
+ * @see ::HAVEQUICK_SETTINGS::format
+ * @see ::HAVEQUICK_FORMAT_MASKS
+ */
+enum HAVEQUICK_FORMATS
+{
+ HQ_FMT_STANAG4246_1,
+ HQ_FMT_STANAG4246_2,
+ HQ_FMT_STANAG4246_PTTI,
+ HQ_FMT_STANAG4372_SATURN_1,
+ HQ_FMT_STANAG4372_SATURN_2,
+ HQ_FMT_STANAG4430_EXTD,
+ N_HQ_FMT ///< number of known formats
+};
+
+
+/**
+ * @brief Bit masks associated with the enumerated HaveQuick formats
+ *
+ * @see ::HAVEQUICK_INFO::supp_formats
+ * @see ::HAVEQUICK_FORMATS
+ */
+enum HAVEQUICK_FORMAT_MASKS
+{
+ HQ_MSK_STANAG4246_1 = ( 1UL << HQ_FMT_STANAG4246_1 ), ///< see ::HQ_FMT_STANAG4246_1
+ HQ_MSK_STANAG4246_2 = ( 1UL << HQ_FMT_STANAG4246_2 ), ///< see ::HQ_FMT_STANAG4246_2
+ HQ_MSK_STANAG4246_PTTI = ( 1UL << HQ_FMT_STANAG4246_PTTI ), ///< see ::HQ_FMT_STANAG4246_PTTI
+ HQ_MSK_STANAG4372_SATURN_1 = ( 1UL << HQ_FMT_STANAG4372_SATURN_1 ), ///< see ::HQ_FMT_STANAG4372_SATURN_1
+ HQ_MSK_STANAG4372_SATURN_2 = ( 1UL << HQ_FMT_STANAG4372_SATURN_2 ), ///< see ::HQ_FMT_STANAG4372_SATURN_2
+ HQ_MSK_STANAG4430_EXTD = ( 1UL << HQ_FMT_STANAG4430_EXTD ) ///< see ::HQ_FMT_STANAG4430_EXTD
+};
+
+/*
+ * String initializers for each Havequick format
+ */
+#define HQ_FMT_NAME_STANAG4246_1 "STANAG4246 1"
+#define HQ_FMT_NAME_STANAG4246_2 "STANAG4246 2"
+#define HQ_FMT_NAME_STANAG4246_PTTI "STANAG4246 PTTI"
+#define HQ_FMT_NAME_STANAG4372_SATURN_1 "STANAG4372 SATURN 1"
+#define HQ_FMT_NAME_STANAG4372_SATURN_2 "STANAG4372 SATURN 2"
+#define HQ_FMT_NAME_STANAG4430_EXTD "STANAG4430 EXTD"
+
+#define HQ_FMT_SHRT_NAME_STANAG4246_1 "STG4246 1"
+#define HQ_FMT_SHRT_NAME_STANAG4246_2 "STG4246 2"
+#define HQ_FMT_SHRT_NAME_STANAG4246_PTTI "STG4246 PTTI"
+#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1 "STG4372 SATURN1"
+#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2 "STG4372 SATURN2"
+#define HQ_FMT_SHRT_NAME_STANAG4430_EXTD "STG4430 EXTD"
/*
- * The types below are not used with all devices:
+ * The definition below can be used to initialize
+ * an array of ::N_HQ_FMT name strings.
+ */
+#define DEFAULT_HQ_FMT_NAMES \
+{ \
+ HQ_FMT_NAME_STANAG4246_1, \
+ HQ_FMT_NAME_STANAG4246_2, \
+ HQ_FMT_NAME_STANAG4246_PTTI, \
+ HQ_FMT_NAME_STANAG4372_SATURN_1, \
+ HQ_FMT_NAME_STANAG4372_SATURN_2, \
+ HQ_FMT_NAME_STANAG4430_EXTD \
+}
+
+#define DEFAULT_HQ_SHRT_FMT_NAMES \
+{ \
+ HQ_FMT_SHRT_NAME_STANAG4246_1, \
+ HQ_FMT_SHRT_NAME_STANAG4246_2, \
+ HQ_FMT_SHRT_NAME_STANAG4246_PTTI, \
+ HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1, \
+ HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2, \
+ HQ_FMT_SHRT_NAME_STANAG4430_EXTD \
+}
+
+
+
+/**
+ * @brief Configuration settings for a HaveQuick input or output
+ */
+typedef struct
+{
+ uint16_t format; ///< see ::HAVEQUICK_FORMATS
+ uint16_t flags; ///< see ::HAVEQUICK_FLAG_MASKS
+ int32_t offset; ///< Tx: unused, Rx: offset of incoming time in [s]
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} HAVEQUICK_SETTINGS;
+
+#define _mbg_swab_havequick_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->format ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->offset ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+}
+
+/**
+ * @brief Current settings and capabilities of a HaveQuick input or output
+ */
+typedef struct
+{
+ HAVEQUICK_SETTINGS settings; ///< current settings
+ uint32_t supp_formats; ///< see ::HAVEQUICK_FORMAT_MASKS
+ uint16_t supp_flags; ///< mask of flags supported in settings, see ::HAVEQUICK_FLAG_MASKS
+ uint16_t reserved; ///< reserved, currently always 0
+
+} HAVEQUICK_INFO;
+
+#define _mbg_swab_havequick_info( _p ) \
+{ \
+ _mbg_swab_havequick_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_formats ); \
+ _mbg_swab16( &(_p)->supp_flags ); \
+ _mbg_swab16( &(_p)->reserved ); \
+}
+
+
+/**
+ * @brief Known HaveQuick control flags
+ *
+ * @see ::HAVEQUICK_FLAG_MASKS
+ */
+enum HAVEQUICK_FLAG_BITS
+{
+ HQ_FLAG_TX_GEN_LOCAL_TIME,
+ HQ_FLAG_SIGNAL_INVERTED,
+ HQ_FLAG_USE_EXT_PPS,
+ N_HQ_FLAG_BITS
+};
+
+
+/**
+ * @brief Bit masks associated with HaveQuick control flags
+ *
+ * @see ::HAVEQUICK_SETTINGS::flags
+ * @see ::HAVEQUICK_INFO::supp_flags
+ * @see ::HAVEQUICK_FLAG_BITS
+ */
+enum HAVEQUICK_FLAG_MASKS
+{
+ HQ_MSK_TX_GEN_LOCAL_TIME = ( 1UL << HQ_FLAG_TX_GEN_LOCAL_TIME ), ///< see ::HQ_FLAG_TX_GEN_LOCAL_TIME
+ HQ_MSK_SIGNAL_INVERTED = ( 1UL << HQ_FLAG_SIGNAL_INVERTED ), ///< see ::HQ_FLAG_SIGNAL_INVERTED
+ HQ_MSK_USE_EXT_PPS = ( 1UL << HQ_FLAG_USE_EXT_PPS ) ///< see ::HQ_FLAG_USE_EXT_PPS
+};
+
+/** @} defgroup group_havequick */
+
+
+
+/**
+ * @defgroup group_evt_log Event logging support
+ *
+ * @note This is only available if ::GPS_HAS_EVT_LOG is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Number of event log entries that can be stored and yet have been saved
+ */
+typedef struct
+{
+ uint32_t used; ///< current number of saved log entries
+ uint32_t max; ///< max number of log entries which can be saved
+
+} MBG_NUM_EVT_LOG_ENTRIES;
+
+#define _mbg_swab_mbg_num_evt_log_entries( _p ) \
+{ \
+ _mbg_swab32( &(_p)->used ); \
+ _mbg_swab32( &(_p)->max ); \
+}
+
+
+typedef uint16_t MBG_EVT_CODE;
+#define _mbg_swab_evt_code( _p ) _mbg_swab16( _p );
+
+typedef uint16_t MBG_EVT_INFO;
+#define _mbg_swab_evt_info( _p ) _mbg_swab16( _p );
+
+/**
+ * @brief An event log entry
+ */
+typedef struct
+{
+ uint32_t time; ///< like time_t, seconds since 1970
+ MBG_EVT_CODE code; ///< event ID or'ed with severity level, see @ref MBG_EVENT_CODES
+ MBG_EVT_INFO info; ///< optional event info, depending on event ID
+
+} MBG_EVT_LOG_ENTRY;
+
+#define _mbg_swab_mbg_evt_log_entry( _p ) \
+{ \
+ _mbg_swab32( &(_p)->time ); \
+ _mbg_swab_evt_code( &(_p)->code ); \
+ _mbg_swab_evt_info( &(_p)->info ); \
+}
+
+
+// ::MBG_EVT_LOG_ENTRY::code is a combination of some bits used for the ID,
+// plus some bits used for the severity/level. The sum of bits must not
+// exceed (8 * sizeof ::MBG_EVT_LOG_ENTRY::code):
+
+#define MBG_EVT_ID_BITS 13
+#define MBG_EVT_LVL_BITS 3
+
+#define MBG_EVT_ID_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_ID_BITS ) - 1 )
+#define MBG_EVT_LVL_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_LVL_BITS ) - 1 )
+
+
+// Combine an ID and Level to a code which can be stored
+// in the code field:
+#define _mbg_mk_evt_code( _id, _lvl ) \
+ ( (MBG_EVT_CODE) ( (MBG_EVT_CODE)(_id) | ( (MBG_EVT_CODE)(_lvl) << MBG_EVT_ID_BITS ) ) )
+
+// Extract the event ID from the code field:
+#define _mbg_get_evt_id( _code ) \
+ ( (_code) & MBG_EVT_ID_MASK )
+
+// Extract the severity level from the code field:
+#define _mbg_get_evt_lvl( _code ) \
+ ( ( (_code) >> MBG_EVT_ID_BITS ) & MBG_EVT_LVL_MASK )
+
+
+/**
+ * @brief Enumeration of event IDs
+ *
+ * @see @ref MBG_EVENT_CODES
+ * @see @ref MBG_EVT_ID_BITS
+ * @see @ref MBG_EVT_LVL_BITS
+ */
+enum MBG_EVT_IDS
+{
+ MBG_EVT_ID_NONE, ///< no event (empty entry)
+ MBG_EVT_ID_POW_UP_RES, ///< power up reset
+ MBG_EVT_ID_WDOG_RES, ///< watchdog reset
+ MBG_EVT_ID_COLD_BOOT, ///< entering cold boot mode
+ MBG_EVT_ID_WARM_BOOT, ///< entering warm boot mode
+ MBG_EVT_ID_NORMAL_OP, ///< entering normal operation
+ MBG_EVT_ID_ANT_DISCONN, ///< antenna disconnect detected
+ MBG_EVT_ID_ANT_SHORT, ///< antenna short circuit detected
+ MBG_EVT_ID_ANT_OK, ///< antenna OK after failure
+ MBG_EVT_ID_LOW_SATS, ///< no satellites can be received though antenna not failing
+ N_MBG_EVT_ID
+};
+
+
+#define ENG_EVT_ID_NAME_NONE "No event"
+#define ENG_EVT_ID_NAME_POW_UP_RES "Power Up Reset"
+#define ENG_EVT_ID_NAME_WDOG_RES "Watchdog Reset"
+#define ENG_EVT_ID_NAME_COLD_BOOT "Cold Boot"
+#define ENG_EVT_ID_NAME_WARM_BOOT "Warm Boot"
+#define ENG_EVT_ID_NAME_NORMAL_OP "Normal Operation"
+#define ENG_EVT_ID_NAME_ANT_DISCONN "Antenna Disconn."
+#define ENG_EVT_ID_NAME_ANT_SHORT "Ant. Short-Circ."
+#define ENG_EVT_ID_NAME_ANT_OK "Antenna OK"
+#define ENG_EVT_ID_NAME_LOW_SATS "Few Sats Only"
+
+
+#define MBG_EVT_ID_NAMES_ENG \
+{ \
+ ENG_EVT_ID_NAME_NONE, \
+ ENG_EVT_ID_NAME_POW_UP_RES, \
+ ENG_EVT_ID_NAME_WDOG_RES, \
+ ENG_EVT_ID_NAME_COLD_BOOT, \
+ ENG_EVT_ID_NAME_WARM_BOOT, \
+ ENG_EVT_ID_NAME_NORMAL_OP, \
+ ENG_EVT_ID_NAME_ANT_DISCONN, \
+ ENG_EVT_ID_NAME_ANT_SHORT, \
+ ENG_EVT_ID_NAME_ANT_OK, \
+ ENG_EVT_ID_NAME_LOW_SATS \
+}
+
+
+
+/**
+ * @brief Enumeration of event severity levels
+ *
+ * @see @ref MBG_EVENT_CODES
+ * @see @ref MBG_EVT_ID_BITS
+ * @see @ref MBG_EVT_LVL_BITS
+ */
+enum MBG_EVT_LVLS
+{
+ MBG_EVT_LVL_NONE,
+ MBG_EVT_LVL_DEBUG,
+ MBG_EVT_LVL_INFO,
+ MBG_EVT_LVL_WARN,
+ MBG_EVT_LVL_ERR,
+ MBG_EVT_LVL_CRIT,
+ N_MBG_EVT_LVL
+};
+
+
+#define ENG_EVT_LVL_NAME_NONE "None"
+#define ENG_EVT_LVL_NAME_DEBUG "Debug"
+#define ENG_EVT_LVL_NAME_INFO "Info"
+#define ENG_EVT_LVL_NAME_WARN "Warn"
+#define ENG_EVT_LVL_NAME_ERR "Err"
+#define ENG_EVT_LVL_NAME_CRIT "Crit."
+
+
+#define MBG_EVT_LVL_NAMES_ENG \
+{ \
+ ENG_EVT_LVL_NAME_NONE, \
+ ENG_EVT_LVL_NAME_DEBUG, \
+ ENG_EVT_LVL_NAME_INFO, \
+ ENG_EVT_LVL_NAME_WARN, \
+ ENG_EVT_LVL_NAME_ERR, \
+ ENG_EVT_LVL_NAME_CRIT \
+}
+
+
+/**
+ * @brief Predefined event codes with associated severity levels
+ *
+ * @see ::MBG_EVT_IDS
+ * @see ::MBG_EVT_LVLS
+ *
+ * @anchor MBG_EVENT_CODES @{ */
+
+#define MBG_EVT_NONE _mbg_mk_evt_code( MBG_EVT_ID_NONE, MBG_EVT_LVL_NONE )
+#define MBG_EVT_POW_UP_RES _mbg_mk_evt_code( MBG_EVT_ID_POW_UP_RES, MBG_EVT_LVL_WARN )
+#define MBG_EVT_WDOG_RES _mbg_mk_evt_code( MBG_EVT_ID_WDOG_RES, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_COLD_BOOT _mbg_mk_evt_code( MBG_EVT_ID_COLD_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_WARM_BOOT _mbg_mk_evt_code( MBG_EVT_ID_WARM_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_NORMAL_OP _mbg_mk_evt_code( MBG_EVT_ID_NORMAL_OP, MBG_EVT_LVL_INFO )
+#define MBG_EVT_ANT_DISCONN _mbg_mk_evt_code( MBG_EVT_ID_ANT_DISCONN, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_SHORT _mbg_mk_evt_code( MBG_EVT_ID_ANT_SHORT, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_OK _mbg_mk_evt_code( MBG_EVT_ID_ANT_OK, MBG_EVT_LVL_INFO )
+#define MBG_EVT_LOW_SATS _mbg_mk_evt_code( MBG_EVT_ID_LOW_SATS, MBG_EVT_LVL_WARN )
+
+/** @} anchor MBG_EVENT_CODES */
+
+/** @} defgroup group_evt_log */
+
+
+
+/**
+ * @defgroup group_ims IMS support
+ *
+ * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Generic state of an IMS device
+ */
+typedef struct
+{
+ uint8_t chassis_id; ///< chassis ID, 0 if installed on the backplane
+ uint8_t slot_id; ///< slot number on the chassis
+ uint16_t num_sensors; ///< number of sensors provided by the device
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::MBG_IMS_STATE_FLAG_MASKS
+
+} MBG_IMS_STATE;
+
+#define _mbg_swab_mbg_ims_state( _p ) \
+{ \
+ _mbg_swab16( &(_p)->num_sensors ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief Enumeration of bits used to define ::MBG_IMS_STATE_FLAG_MASKS
+ *
+ * @see ::MBG_IMS_STATE_FLAG_MASKS
+ */
+enum MBG_IMS_STATE_FLAG_BITS
+{
+ MBG_IMS_STATE_FLAG_BIT_HAS_FDM, ///< device supports FDM API
+ N_MBG_IMS_STATE_FLAG_BITS
+};
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_STATE::flags
+ *
+ * @see ::MBG_IMS_STATE_FLAG_BITS
+ */
+enum MBG_IMS_STATE_FLAG_MASKS
+{
+ MBG_IMS_STATE_FLAG_MSK_HAS_FDM = ( 1UL << MBG_IMS_STATE_FLAG_BIT_HAS_FDM ) ///< see ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM
+};
+
+
+
+/**
+ * @brief Generic state of an IMS sensor
+ */
+typedef struct
+{
+ uint16_t type; ///< sensor type, see ::MBG_IMS_SENSORS
+ uint16_t idx; ///< index of the sensor of this type
+ int32_t val; ///< sensor value, in units according to the type
+ int16_t exp; ///< 10s exponent of the sensor value
+ uint16_t reserved; ///< currently unused, always 0
+ uint32_t flags; ///< currently unused, always 0
+
+} MBG_IMS_SENSOR_STATE;
+
+#define _mbg_swab_mbg_ims_sensor_state( _p ) \
+{ \
+ _mbg_swab16( &(_p)->type ); \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab32( &(_p)->val ); \
+ _mbg_swab16( &(_p)->exp ); \
+ _mbg_swab16( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Generic state of an IMS sensor, with sensor index
+ */
+typedef struct
+{
+ uint32_t idx; ///< sensor index, 0..::MBG_IMS_STATE::num_sensors-1
+ MBG_IMS_SENSOR_STATE state; ///< sensor state
+
+} MBG_IMS_SENSOR_STATE_IDX;
+
+#define _mbg_swab_mbg_ims_sensor_state_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_sensor_state( &(_p)->state ); \
+}
+
+
+
+/**
+ * @brief IMS sensor types
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::type
+ */
+enum MBG_IMS_SENSORS
+{
+ MBG_IMS_SENSOR_TEMP_C, ///< temperature in degrees Celsius
+ MBG_IMS_SENSOR_VOLTAGE, ///< voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_PLL, ///< control voltage in val/exp, lock state in flags
+ N_MBG_IMS_SENSORS ///< number of supported sensor types
+};
+
+
+
+/**
+ * @brief IMS sensor state flags for voltage
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type
+ * is ::MBG_IMS_SENSOR_VOLTAGE.
+ */
+enum MBG_IMS_SENSOR_STATE_FLAG_MASK_VOLTAGE
+{
+ MBG_IMS_SENSOR_VOLTAGE_OUT_ENB = 0x01, ///< output is enabled
+ MBG_IMS_SENSOR_VOLTAGE_OUT_OVR = 0x02 ///< output overload
+};
+
+
+/**
+ * @brief IMS sensor state flags for PLL
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type
+ * is ::MBG_IMS_SENSOR_PLL.
+ */
+enum MBG_IMS_SENSOR_STATE_FLAG_MASK_PLL
+{
+ MBG_IMS_SENSOR_PLL_LOCKED = 0x01 ///< PLL is locked
+};
+
+
+
+/**
+ * @brief DAC limit specs
+ */
+typedef struct
+{
+ int32_t dac_val_min; ///< min. possible DAC Value, positive or negative
+ int32_t dac_val_max; ///< max. possible DAC Value, positive or negative
+
+ int32_t u_min; ///< min. possible real voltage range, positive or negative, depending on ::MBG_DAC_SPECS::dac_val_min
+ int32_t u_max; ///< max. possible real voltage range, positive or negative, depending on ::MBG_DAC_SPECS::dac_val_max
+
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} MBG_DAC_SPECS;
+
+#define _mbg_swab_mbg_dac_specs( _p ) \
+{ \
+ _mbg_swab32( &(_p)->dac_val_min ); \
+ _mbg_swab32( &(-p)->dac_val_max ); \
+ _mbg_swab32( &(_P)->u_min ); \
+ _mbg_swab32( &(_p)->u_max ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+}
+
+
+
+/**
+ * @brief Output state of FDM device.
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ */
+typedef struct
+{
+ int32_t dac_val; ///< current DAC value, positive or negative
+ uint32_t mode; ///< current output mode, see ::MBG_IMS_FDM_OUTPUT_MODES
+
+ MBG_DAC_SPECS dac_specs; ///< DAC specific limits
+
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_OUTPUT_STATE;
+
+#define _mbg_swab_mbg_ims_fdm_output_state( _p ) \
+{ \
+ _mbg_swab32( &(_p)->dac_val ); \
+ _mbg_swab32( &(_p)->mode ); \
+ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+}
+
+
+/**
+ * @brief Output state of FDM device plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_STATE state;
+
+} MBG_IMS_FDM_OUTPUT_STATE_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_state_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_state( &(_p)->state ); \
+}
+
+
+
+/**
+ * @brief Output settings of FDM device
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ */
+typedef struct
+{
+ uint32_t mode; ///< mode, see ::MBG_IMS_FDM_OUTPUT_MODES
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_OUTPUT_SETTINGS;
+
+#define _mbg_swab_mbg_ims_fdm_output_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->mode ); \
+ _mbg_swab32( &(_p)->reserved ); \
+}
+
+
+/**
+ * @brief Output settings for FDM devices plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_SETTINGS settings;
+
+} MBG_IMS_FDM_OUTPUT_SETTINGS_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_settings_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \
+}
+
+
+
+/**
+ * @brief Specific output settings and limits.
+ */
+typedef struct
+{
+ MBG_IMS_FDM_OUTPUT_SETTINGS settings; ///< current settings
+ uint32_t supp_modes; ///< supported modes, see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS
+ MBG_DAC_SPECS dac_specs; ///< DAC specific limits
+
+} MBG_IMS_FDM_OUTPUT_INFO;
+
+#define _mbg_swab_mbg_ims_fdm_output_info( _p ) \
+{ \
+ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \
+}
+
+
+/**
+ * @brief Specific output settings and limits, plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_INFO info;
+
+} MBG_IMS_FDM_OUTPUT_INFO_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_info_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_info( &(_p)->info ); \
+}
+
+
+
+/**
+ * @brief Enumeration of known output modes
+ *
+ * Used with ::MBG_IMS_FDM_OUTPUT_STATE::mode
+ *
+ * @see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS
+ */
+enum MBG_IMS_FDM_OUTPUT_MODES
+{
+ MBG_IMS_FDM_OUTPUT_MODE_FD, ///< Analog output reflects frequency deviation
+ MBG_IMS_FDM_OUTPUT_MODE_TD, ///< Analog output reflects time deviation
+ N_MBG_IMS_FDM_OUTPUT_MODES ///< Number of known output modes
+};
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_FDM_OUTPUT_STATE::mode
+ *
+ * @see ::MBG_IMS_FDM_OUTPUT_MODES
+ */
+enum MBG_IMS_FDM_OUTPUT_MODE_MASKS
+{
+ MBG_IMS_FDM_OUTPUT_MODE_MSK_FD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_FD ), ///< see ::MBG_IMS_FDM_OUTPUT_MODE_FD
+ MBG_IMS_FDM_OUTPUT_MODE_MSK_TD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_TD ) ///< see ::MBG_IMS_FDM_OUTPUT_MODE_TD
+};
+
+
+
+/**
+ * @brief A generic structure used to specify FDM limits
+ */
+typedef struct
+{
+ uint8_t n_outputs; ///< number of outputs per module
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint16_t reserved_1; ///< reserved, currently always 0
+
+ uint32_t fd_min; ///< min. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units
+ uint32_t fd_max; ///< max. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units
+ uint32_t fd_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::fd_min and ::MBG_IMS_FDM_LIMITS::fd_max
+
+ uint32_t td_min; ///< min. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units
+ uint32_t td_max; ///< max. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units
+ uint32_t td_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::td_min and ::MBG_IMS_FDM_LIMITS::td_max
+
+ uint32_t reserved_2; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_LIMITS;
+
+#define _mbg_swab_mbg_ims_fdm_limits( _p ) \
+{ \
+ _mbg_swab8( &(_p)->n_outputs ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->fd_min ); \
+ _mbg_swab32( &(_p)->fd_max ); \
+ _mbg_swab32( &(_p)->td_min ); \
+ _mbg_swab32( &(_p)->td_max ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+}
+
+
+
+/**
+ * @brief State of FDM device
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags.
+ *
+ */
+typedef struct
+{
+ MBG_GPIO_FREQ freq; ///< Current frequency
+
+ NANO_TIME_64 t_ref; ///< Current reference time
+ NANO_TIME_64 t_plt; ///< Current power line time
+ NANO_TIME_64 t_sync; ///< Last sync Time (reference time)
+
+ uint32_t line_freq; ///< Nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS
+ uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_STATE_FLAG_MASKS
+ uint32_t reserved; ///< Reserved, currently always 0
+
+} MBG_IMS_FDM_STATE;
+
+#define _mbg_swab_mbg_ims_fdm_state( _p ) \
+{ \
+ _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \
+ _mbg_swab_nano_time_64( &(_p)->t_ref ); \
+ _mbg_swab_nano_time_64( &(_p)->t_plt ); \
+ _mbg_swab_nano_time_64( &(_p)->t_sync ); \
+ _mbg_swab32( &(_p)->line_freq ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved ); \
+}
+
+
+
+/**
+ * @brief Enumeration known line frequencies
+ *
+ * Used with ::MBG_IMS_FDM_STATE::line_freq
+ *
+ * @see ::MBG_IMS_FDM_LINE_FREQ_MASKS
+ */
+enum MBG_IMS_FDM_LINE_FREQS
+{
+ MBG_IMS_FDM_LINE_FREQ_AUTO, ///< Auto detect line frequency
+ MBG_IMS_FDM_LINE_FREQ_50HZ, ///< 50Hz line frequency
+ MBG_IMS_FDM_LINE_FREQ_60HZ, ///< 60Hz line frequency
+ N_MBG_IMS_FDM_LINE_FREQS ///< number of known line frequencies
+};
+
+
+/**
+ * @brief Bit masks corresponding to defined line frequencies
+ *
+ * @see ::MBG_IMS_FDM_LINE_FREQS
+ */
+enum MBG_IMS_FDM_LINE_FREQ_MASKS
+{
+ MBG_IMS_FDM_LINE_FREQ_MSK_AUTO = ( 1UL << MBG_IMS_FDM_LINE_FREQ_AUTO ), ///< see ::MBG_IMS_FDM_LINE_FREQ_AUTO
+ MBG_IMS_FDM_LINE_FREQ_MSK_50HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_50HZ ), ///< see ::MBG_IMS_FDM_LINE_FREQ_50HZ
+ MBG_IMS_FDM_LINE_FREQ_MSK_60HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_60HZ ) ///< see ::MBG_IMS_FDM_LINE_FREQ_60HZ
+};
+
+
+
+/**
+ * @brief Enumeration of flag bits used to define ::MBG_IMS_FDM_STATE_FLAG_MASKS
+ */
+enum MBG_IMS_FDM_STATE_FLAG_BITS
+{
+ MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET, ///< if sync'ed after reset
+ MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED, ///< Power Line Time is locked
+ MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW, ///< Frequency deviation overflow occurred
+ MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW, ///< Time deviation overflow occurred
+ N_MBG_IMS_FDM_STATE_FLAG_BITS ///< number of known state flag bits
+};
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_FDM_STATE::flags
+ *
+ * @see ::MBG_IMS_FDM_STATE_FLAG_BITS
+ */
+enum MBG_IMS_FDM_STATE_FLAG_MASKS
+{
+ MBG_IMS_FDM_STATE_FLAG_MSK_SYNC_AFTER_RESET = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET
+ MBG_IMS_FDM_STATE_FLAG_MSK_PLT_IS_LOCKED = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED
+ MBG_IMS_FDM_STATE_FLAG_MSK_FD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW
+ MBG_IMS_FDM_STATE_FLAG_MSK_TD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW ) ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW
+};
+
+
+
+/**
+ * @brief FDM device settings
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags.
+ *
+ */
+typedef struct
+{
+ uint32_t fd_min; ///< min. frequency deviation limit in 100 uHz steps
+ uint32_t fd_max; ///< max. frequency deviation limit in 100 uHz steps
+
+ uint32_t td_min; ///< min. time deviation limit in 100 us steps
+ uint32_t td_max; ///< max. time deviation limit in 100 us steps
+
+ uint32_t line_freq; ///< nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_SETTINGS;
+
+#define _mbg_swab_mbg_ims_fdm_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->fd_min ); \
+ _mbg_swab32( &(_p)->fd_max ); \
+ _mbg_swab32( &(_p)->td_min ); \
+ _mbg_swab32( &(_p)->td_max ); \
+ _mbg_swab32( &(_p)->mode ); \
+ _mbg_swab32( &(_p)->reserved ); \
+}
+
+
+/**
+* @brief Specific FDM settings and limits.
+*/
+typedef struct
+{
+ MBG_IMS_FDM_SETTINGS settings;
+ uint32_t supp_line_freqs; ///< Bit mask of supported line frequencies, see ::MBG_IMS_FDM_LINE_FREQ_MASKS
+ uint32_t reserved; ///< Reserved, currently always 0
+ uint32_t flags; ///< Flags, currently always 0
+
+} MBG_IMS_FDM_INFO;
+
+#define _mbg_swab_mbg_ims_fdm_info( _p ) \
+{ \
+ _mbg_swab_mbg_ims_fdm_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_line_freqs ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+/** @} defgroup group_ims */
+
+
+
+/**
+ * @defgroup group_generic_io Generic I/O support.
+ *
+ * The definitions below are used with the GENERIC_IO API.
+ *
+ * This API is <b>NOT</b> supported by all devices, it depends on
+ * the type of the device, and the firmware version. The macro
+ * _pcps_has_generic_io() or the corresponding function
+ * mbg_dev_has_generic_io() should be used by applications to
+ * check whether a particular bus-level device supports this.
+ *
+ * @{ */
+
+typedef uint16_t GEN_IO_INFO_TYPE;
+
+#define _mbg_swab_gen_io_info_type( _p ) \
+ _mbg_swab16( _p )
+
+
+
+/**
+ * @brief The data structure used with the ::PCPS_GEN_IO_GET_INFO command
+ *
+ * Used to determine how many data sets of a specific type are supported
+ * by the device.
+ */
+typedef struct
+{
+ GEN_IO_INFO_TYPE type; // see ::PCPS_GEN_IO_TYPES
+ uint16_t num; // supported number of data sets of the specified type
+
+} GEN_IO_INFO;
+
+#define _mbg_swab_gen_io_info( _p ) \
+{ \
+ _mbg_swab_gen_io_info_type( &(_p)->type ); \
+ _mbg_swab16( &(_p)->num ); \
+}
+
+
+
+/**
+ * @brief Data types used with ::GEN_IO_INFO::type
+ *
+ * The first type specifier, ::PCPS_GEN_IO_GET_INFO, can
+ * be used to find out which of the other data types are
+ * supported, and how many data sets of the specified type
+ * are supported by a device.
*/
+enum PCPS_GEN_IO_TYPES
+{
+ PCPS_GEN_IO_GET_INFO, ///< ::GEN_IO_INFO (read only)
+ PCPS_GEN_IO_CAL_REC_IRIG_RX_COMP, ///< ::CAL_REC_IRIG_RX_COMP (read/write)
+ N_PCPS_GEN_IO_TYPE ///< number of known types
+};
+
+/** @} defgroup group_generic_io */
+
+
typedef uint16_t ROM_CSUM; /* The ROM checksum */
-typedef uint16_t RCV_TIMEOUT; /* [min] (only if HAS_RCV_TIMEOUT) */
-typedef uint16_t IGNORE_LOCK; /* (only if GPS_HAS_IGNORE_LOCK) */
+typedef uint16_t RCV_TIMEOUT; /* [min] (only if ::HAS_RCV_TIMEOUT) */
+typedef uint16_t IGNORE_LOCK; /* (only if ::GPS_HAS_IGNORE_LOCK) */
/*
- * Originally IGNORE_LOG above has been a boolean value (equal or
+ * 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
+ * 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
+ * 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:
+ * The macros below can be used to simplify the code:
*/
/* return a bit mask depending on the port number */
@@ -3434,84 +7493,124 @@ typedef uint16_t IGNORE_LOCK; /* (only if GPS_HAS_IGNORE_LOCK) */
( (_il) & ( _ignore_lock_for_port(_n) | IGNORE_LOCK_FOR_ALL_PORTS ) )
-/*------------------------------------------------------------------------*/
-/*
- * The structures below are used with the SCU multiplexer board
- * in a redundant system:
- */
+/**
+ * @defgroup group_scu Definitions used with SCU devices
+ *
+ * The structures below are used with the SCU multiplexer board
+ * in a redundant system.
+ *
+ * @see ::GPS_MODEL_IS_SCU
+ *
+ * @{ */
typedef struct
{
- uint32_t hw_id; // hardware identification
- uint32_t fw_id; // firmware identification
- uint16_t flags; // reserved currently 0
- uint8_t clk0_info; // reference clock 0 type
- uint8_t clk1_info; // reference clock 1 type
- uint16_t epld_status; // epld status word, see defintions below
- uint16_t epld_control; // epld control word, see defintions below
+ uint32_t hw_id; ///< hardware identification
+ uint32_t fw_id; ///< firmware identification
+ uint16_t flags; ///< reserved currently 0
+ uint8_t clk0_info; ///< reference clock 0 type
+ uint8_t clk1_info; ///< reference clock 1 type
+ uint16_t epld_status; ///< EPLD status word, see ::SCU_STAT_MASKS
+ uint16_t epld_control; ///< EPLD control word, see ::SCU_CTRL_MASKS
+
} SCU_STAT_INFO;
-typedef struct
+
+typedef struct
{
- uint16_t epld_control_mask; // control mask, determines which bit is to be changed
- uint16_t epld_control_value; // control value, determines value of bits to be changed
- uint32_t flags; // reserved, currently 0
+ uint16_t epld_control_mask; ///< control mask, determines which bit is to be changed, see ::SCU_CTRL_MASKS
+ uint16_t epld_control_value; ///< control value, determines value of bits to be changed, see ::SCU_CTRL_MASKS
+ uint32_t flags; ///< reserved, currently 0
+
} SCU_STAT_SETTINGS;
-// definitions for status word bit masks
-#define MSK_EPLD_STAT_TS1 0x0001 // state of time sync signal clk_1
-#define MSK_EPLD_STAT_TS2 0x0002 // state of time sync signal clk_2
-#define MSK_EPLD_STAT_TL_ERROR 0x0004 // state of time limit error input
-#define MSK_EPLD_STAT_PSU1_OK 0x0008 // state of power supply 1 monitoring input
-#define MSK_EPLD_STAT_PSU2_OK 0x0010 // state of power supply 2 monitoring input
-#define MSK_EPLD_STAT_AUTO 0x0020 // AUTOMATIC/REMOTE or MANUAL Mode
-#define MSK_EPLD_STAT_SEL 0x0040 // select bit for output MUX, ( clk_1 = 0 )
-#define MSK_EPLD_STAT_ENA 0x0080 // enable Bit for output MUX, set if enabled
-#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
+/**
+ * @brief Bit masks used to check the SCU EPLD status
+ *
+ * Used with ::SCU_STAT_INFO::epld_status
+ */
+enum SCU_STAT_MASKS
+{
+ MSK_EPLD_STAT_TS1 = 0x0001, ///< state of time sync signal clk_1
+ MSK_EPLD_STAT_TS2 = 0x0002, ///< state of time sync signal clk_2
+ MSK_EPLD_STAT_TL_ERROR = 0x0004, ///< state of time limit error input
+ MSK_EPLD_STAT_PSU1_OK = 0x0008, ///< state of power supply 1 monitoring input
+ MSK_EPLD_STAT_PSU2_OK = 0x0010, ///< state of power supply 2 monitoring input
+ MSK_EPLD_STAT_AUTO = 0x0020, ///< AUTOMATIC/REMOTE or MANUAL Mode
+ MSK_EPLD_STAT_SEL = 0x0040, ///< select bit for output MUX, ( clk_1 = 0 )
+ MSK_EPLD_STAT_ENA = 0x0080, ///< enable Bit for output MUX, set if enabled
+
+ MSK_EPLD_STAT_ACO = 0x4000, ///< Access control override bit
+ 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
-#define MSK_EPLD_CNTL_SEL_SNMP 0x4000 // connect COM0 channels to XPORT
-#define MSK_EPLD_CNTL_ENA_SNMP 0x8000 // select clk for comm. ( clk1 = 0 )
-/*
- * Definitions for clk0_info and clk1_info, can be used to determine
- * the reference clock type connected to SCU input channel 0 and 1:
+/**
+ * @brief Bit masks used to control the SCU EPLD
+ *
+ * Used with ::SCU_STAT_INFO::epld_control, ::SCU_STAT_SETTINGS::epld_control_mask,
+ * and ::SCU_STAT_SETTINGS::epld_control_value.
*/
-enum
+enum SCU_CTRL_MASKS
{
- SCU_CLK_INFO_GPS, // ref. clock is GPS receiver
- SCU_CLK_INFO_DCF_PZF, // ref. clock is DCF77 PZF receiver
- SCU_CLK_INFO_DCF_AM, // ref. clock is DCF77 AM receiver
- SCU_CLK_INFO_TCR // ref. clock is IRIG time code receiver
+ MSK_EPLD_CTL_DISB_SERIAL = 0x0001, ///< disable serial output on error
+ MSK_EPLD_CTL_DISB_PPS = 0x0002, ///< disable PPS output on error
+ MSK_EPLD_CTL_DISB_10MHZ = 0x0004, ///< disable 10 MHz output on error
+
+ MSK_EPLD_CNTL_SEL_REM = 0x0800, ///< remote select for output MUX (clk_1 = 0)
+ MSK_EPLD_CNTL_DIS_REM = 0x1000, ///< remote disable for output MUX
+ MSK_EPLD_CNTL_REMOTE = 0x2000, ///< must be set to enable remote operation
+ MSK_EPLD_CNTL_SEL_SNMP = 0x4000, ///< select clk for comm. (clk1 = 0)
+ MSK_EPLD_CNTL_ENA_SNMP = 0x8000, ///< connect COM0 channels to XPORT
};
+/**
+ * @brief Definitions for ::SCU_STAT_INFO::clk0_info and ::SCU_STAT_INFO::clk1_info
+ *
+ * Can be used to determine the reference clock type connected to the SCU input channels.
+ */
+enum SCU_CLK_INFO_TYPES
+{
+ SCU_CLK_INFO_GPS, ///< ref. clock is GPS receiver
+ SCU_CLK_INFO_DCF_PZF, ///< ref. clock is DCF77 PZF receiver
+ SCU_CLK_INFO_DCF_AM, ///< ref. clock is DCF77 AM receiver
+ SCU_CLK_INFO_TCR, ///< ref. clock is IRIG time code receiver
+ N_SCU_CLK_INFO ///< number of known types
+};
+
+/** @} defgroup group_scu */
+
+
+
/*------------------------------------------------------------------------*/
-/*
- * GPS receiver modes of operation. Some of the codes combinations
- * are obsolete with recent GPS receivers. However, that doesn't
- * matter since the mode is just read from the receiver:
- */
#define REMOTE 0x10
#define BOOT 0x20
-#define TRACK ( 0x01 )
-#define AUTO_166 ( 0x02 )
-#define WARM_166 ( 0x03 | BOOT )
-#define COLD_166 ( 0x04 | BOOT )
-#define AUTO_BC ( 0x05 | REMOTE )
-#define WARM_BC ( 0x06 | REMOTE | BOOT )
-#define COLD_BC ( 0x07 | REMOTE | BOOT )
-#define UPDA_166 ( 0x08 | BOOT )
-#define UPDA_BC ( 0x09 | REMOTE | BOOT )
+/**
+ * @brief Satellite receiver modes of operation.
+ *
+ * @note Some of the code combinations are deprecated with recent
+ * satellite receivers. However, this doesn't matter since the mode
+ * is just read from the receiver.
+ */
+enum RECEIVER_MODES
+{
+ TRACK = ( 0x01 ),
+ AUTO_166 = ( 0x02 ),
+ WARM_166 = ( 0x03 | BOOT ),
+ COLD_166 = ( 0x04 | BOOT ),
+ AUTO_BC = ( 0x05 | REMOTE ),
+ WARM_BC = ( 0x06 | REMOTE | BOOT ),
+ COLD_BC = ( 0x07 | REMOTE | BOOT ),
+ UPDA_166 = ( 0x08 | BOOT ),
+ UPDA_BC = ( 0x09 | REMOTE | BOOT )
+};
@@ -3522,13 +7621,17 @@ typedef int16_t DAC_VAL;
+/**
+ * @brief Satellite receiver status information
+ */
typedef struct
{
- 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 ) */
+ uint16_t mode; ///< Mode of operation, see ::RECEIVER_MODES
+ 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 visible above the horizon
+ 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 ) \
@@ -3546,105 +7649,168 @@ typedef struct
-/*
- The enumeration below lists all
- known satellite navigation systems
-*/
-enum
+/**
+ * @brief An enumeration of known satellite navigation systems
+ *
+ * @see ::MBG_GNSS_TYPE_MASKS
+ * @see ::GNSS_TYPE_STRS
+ */
+enum MBG_GNSS_TYPES
{
- GNSS_TYPE_GPS,
- GNSS_TYPE_GLONASS,
- GNSS_TYPE_BEIDOU,
- GNSS_TYPE_GALILEO,
- N_GNSS_TYPES
+ GNSS_TYPE_GPS, ///< GPS, United States
+ GNSS_TYPE_GLONASS, ///< GLONASS, Russia
+ GNSS_TYPE_BEIDOU, ///< BEIDOU, China
+ GNSS_TYPE_GALILEO, ///< GALILEO, Europe
+ GNSS_TYPE_WAAS, ///< WAAS, Wide Area Augmentation System
+ GNSS_TYPE_EGNOS, ///< EGNOS, European Geostationary Navigation Overlay Service
+ N_GNSS_TYPES ///< Number of defined codes
};
-
-#define GNSS_TYPE_STRS \
-{ \
- "GPS", \
- "GLONASS", \
- "BEIDOU" , \
- "GALILEO" \
-}
-
+/**
+ * @brief Bit masks associated with ::MBG_GNSS_TYPES
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
+enum MBG_GNSS_TYPE_MASKS
+{
+ MBG_GNSS_TYPE_MSK_GPS = ( 1UL << GNSS_TYPE_GPS ), ///< see ::GNSS_TYPE_GPS
+ MBG_GNSS_TYPE_MSK_GLONASS = ( 1UL << GNSS_TYPE_GLONASS ), ///< see ::GNSS_TYPE_GLONASS
+ MBG_GNSS_TYPE_MSK_BEIDOU = ( 1UL << GNSS_TYPE_BEIDOU ), ///< see ::GNSS_TYPE_BEIDOU
+ MBG_GNSS_TYPE_MSK_GALILEO = ( 1UL << GNSS_TYPE_GALILEO ), ///< see ::GNSS_TYPE_GALILEO
+ MBG_GNSS_TYPE_MSK_WAAS = ( 1UL << GNSS_TYPE_WAAS ), ///< see ::GNSS_TYPE_WAAS
+ MBG_GNSS_TYPE_MSK_EGNOS = ( 1UL << GNSS_TYPE_EGNOS ) ///< see ::GNSS_TYPE_EGNOS
+};
-#define MBG_GNSS_TYPE_MSK_GPS ( 1UL << GNSS_TYPE_GPS )
-#define MBG_GNSS_TYPE_MSK_GLONASS ( 1UL << GNSS_TYPE_GLONASS )
-#define MBG_GNSS_TYPE_MSK_BEIDOU ( 1UL << GNSS_TYPE_BEIDOU )
-#define MBG_GNSS_TYPE_MSK_GALILEO ( 1UL << GNSS_TYPE_GALILEO )
+/**
+ * @brief Name strings for the the known satellite navigation systems
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
+#define GNSS_TYPE_STRS \
+{ \
+ "GPS", \
+ "GLONASS", \
+ "BEIDOU", \
+ "GALILEO", \
+ "WAAS", \
+ "EGNOS" \
+}
#define N_GNSS_MODE_PRIO 8
+/**
+ * @brief GNSS mode settings
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
typedef struct
{
- uint32_t gnss_set; /**< current set of GNSS types */
- uint8_t prio[N_GNSS_MODE_PRIO]; /**< index 0 for highest priority, use GNSS enumeration above, init with 0xFF if not supported */
- uint32_t flags; /**< see below */
+ uint32_t gnss_set; ///< bit mask of currently used GNSS systems, see ::MBG_GNSS_TYPE_MASKS
+ uint8_t prio[N_GNSS_MODE_PRIO]; ///< see ::MBG_GNSS_TYPES, unused fields set to 0xFF, idx 0 is highest prio
+ uint32_t flags; ///< see ::MBG_GNSS_MODE_FLAG_MASKS
+
} MBG_GNSS_MODE_SETTINGS;
-#define _mbg_swab_mbg_gnss_mode_settings( _p ) \
-{ \
- _mbg_swab32( &(_p)->gnss_set ); \
- _mbg_swab32( &(_p)->flags ); \
+#define _mbg_swab_mbg_gnss_mode_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->gnss_set ); \
+ _mbg_swab32( &(_p)->flags ); \
}
typedef struct
{
- MBG_GNSS_MODE_SETTINGS settings; /**< current GNSS mode settings */
- uint32_t supp_gnss_types; /**< bit masks of supported GNSS types */
- uint32_t flags; /**< indicates which of the defined flags are supported by the device */
+ MBG_GNSS_MODE_SETTINGS settings; ///< current GNSS mode settings
+ uint32_t supp_gnss_types; ///< bit masks of supported GNSS types, see ::MBG_GNSS_TYPE_MASKS
+ uint32_t flags; ///< indicates which flags are supported for settings::flags, see ::MBG_GNSS_MODE_FLAG_MASKS
+
} MBG_GNSS_MODE_INFO;
-#define _mbg_swab_mbg_gnss_mode_info( _p ) \
-{ \
- _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \
- _mbg_swab32( &(_p)->supp_gnss_types ); \
- _mbg_swab32( &(_p)->flags ); \
+#define _mbg_swab_mbg_gnss_mode_info( _p ) \
+{ \
+ _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_gnss_types ); \
+ _mbg_swab32( &(_p)->flags ); \
}
-/* Flags used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags: */
-
-enum
+/**
+ * @brief Flag bits used with ::MBG_GNSS_MODE_SETTINGS and ::MBG_GNSS_MODE_INFO
+ *
+ * @see ::MBG_GNSS_MODE_FLAG_MASKS
+ */
+enum MBG_GNSS_MODE_FLAG_BITS
{
- MBG_GNSS_FLAG_EXCLUSIVE, /**< (read only) only one of the supported GNSS systems can be used at the same time */
- MBG_GNSS_FLAG_HAS_PRIORITY, /**< (read only) priority can be configured using the MBG_GNSS_MODE_SETTINGS::prio field */
+ MBG_GNSS_FLAG_EXCLUSIVE, ///< (read only) only one of the supported GNSS systems can be used at the same time
+ MBG_GNSS_FLAG_HAS_PRIORITY, ///< (read only) priority can be configured using the MBG_GNSS_MODE_SETTINGS::prio field
+ MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, ///< (read only)
N_MBG_GNSS_FLAGS
};
-#define MBG_GNSS_FLAG_MSK_EXCLUSIVE ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE )
-#define MBG_GNSS_FLAG_MSK_HAS_PRIORITY ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY )
+/**
+ * @brief Flag masks used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags
+ *
+ * @see ::MBG_GNSS_MODE_FLAG_BITS
+ */
+enum MBG_GNSS_MODE_FLAG_MASKS
+{
+ MBG_GNSS_FLAG_MSK_EXCLUSIVE = ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE ), ///< see ::MBG_GNSS_FLAG_EXCLUSIVE
+ MBG_GNSS_FLAG_MSK_HAS_PRIORITY = ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY ), ///< see ::MBG_GNSS_FLAG_HAS_PRIORITY
+ MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER = ( 1UL << MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER ) ///< see ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER
+};
-#define MAX_USED_SATS 32
-/*
- The structure below allos to transfer
- SV information from a certain GNSS type.
-*/
+
+#define MAX_USED_SATS 32
+
+/**
+ * @brief Satellite information for a particular GNSS type.
+ */
typedef struct
{
- uint8_t gnss_type; /**< GNSS type from the enumeration above */
- uint8_t reserved;
- uint16_t good_svs;
- uint16_t svs_in_view;
- uint8_t svs[MAX_USED_SATS];
+ uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES
+ uint8_t reserved; ///< Reserved, currently always 0
+ uint16_t good_svs; ///< Num. of satellites that can currently be received and used
+ uint16_t svs_in_view; ///< Num. of satellites that should be visible above the horizon
+ uint8_t svs[MAX_USED_SATS]; ///< IDs of the satellites actually used for navigation, 0 == not used
+
} GNSS_SAT_INFO;
-#define _mbg_swab_gnss_sat_info( _p ) \
+#define _mbg_swab_gnss_sat_info( _p ) \
{ \
_mbg_swab16( &(_p)->good_svs ); \
_mbg_swab16( &(_p)->svs_in_view ); \
}
+
+/**
+ * @brief One of several sets of satellite information for a particular GNSS type.
+ *
+ *
+ */
+typedef struct
+{
+ uint16_t idx; ///< GNSS system type index
+ GNSS_SAT_INFO gnss_sat_info; ///< see ::GNSS_SAT_INFO
+
+} GNSS_SAT_INFO_IDX;
+
+#define _mbg_swab_gnss_sat_info_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_gnss_sat_info( &(_p)->gnss_sat_info ); \
+}
+
+
+
+
#ifndef _IDENT_DEFINED
typedef union
@@ -3665,8 +7831,7 @@ typedef struct
}
/**
- * The type below is used to configure the length of the
- * antenna cable in [m]:
+ * @brief A data type used to configure the length of an antenna cable [m]
*/
typedef uint16_t ANT_CABLE_LEN;
@@ -3674,112 +7839,236 @@ typedef uint16_t ANT_CABLE_LEN;
-/* Configuration data for an optional LAN interface.
+/**
+ * @defgroup group_net_cfg Network configuration stuff
+ *
+ * @{ */
+
+/**
+ * @defgroup group_net_basic_types Basic network parameter types
*
- * This is only supported if the flag GPS_HAS_LAN_IP4
- * is set in RECEIVER_INFO::features.
+ * @{ */
+
+/**
+ * @brief The MAC address of a network interface
*/
+typedef struct
+{
+ uint8_t b[6];
+} MBG_MAC_ADDR;
-/* Basic network settings */
+
+/**
+ * @brief An IPv4 address
+ */
typedef uint32_t IP4_ADDR;
#define _mbg_swab_ip4_addr( _p ) \
_mbg_swab32( _p );
+
+/** @brief The number of bits used for an IPv6 address */
+#define IP6_ADDR_BITS 128
+
+/** @brief The number of bytes used for an IPv6 address */
+#define IP6_ADDR_BYTES ( IP6_ADDR_BITS / 8 ) // == 16
+
+/**
+ * @brief An IPv6 address
+ */
typedef struct
{
- IP4_ADDR ip_addr;
- IP4_ADDR netmask;
- IP4_ADDR broad_addr;
- IP4_ADDR gateway;
- uint16_t flags; /* see below */
- uint16_t vlan_cfg; /* see below */
+ uint8_t b[IP6_ADDR_BYTES]; ///< bytes holding the address bits (not the string notation), b[0] == LSBs
-} IP4_SETTINGS;
+} IP6_ADDR;
-#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_swab16( &(_p)->flags ); \
- _mbg_swab16( &(_p)->vlan_cfg ); \
+
+
+/**
+ * @brief An IPv6 address plus number of netmask bits
+ */
+typedef struct
+{
+ IP6_ADDR addr; ///< bit mask of the bytes holding the address bits, b[0] == LSBs
+ uint8_t prefix; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24
+ uint8_t reserved[3]; ///< Reserved, alignment, currently 0
+
+} IP6_ADDR_CIDR;
+
+
+
+/** @brief The max number of chars required for an IPv6 address string */
+#define MAX_IP6_ADDR_STR_LEN 43 ///< e.g. 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/128
+
+/** @brief Buffer size required to store an IPv6 address string */
+#define IP6_ADDR_STR_SIZE ( MAX_IP6_ADDR_STR_LEN + 1 ) ///< ::MAX_IP6_ADDR_STR_LEN + terminating 0
+
+/** @brief A buffer for an IPv6 address string */
+typedef char IP6_ADDR_STR[IP6_ADDR_STR_SIZE];
+
+
+
+/**
+ * @brief Possible IPv6 Multicast Scopes
+ *
+ * If the first (most significant) byte of an IPv6 address is 0xFF this
+ * indicates that the address is a multicast address, and in this case
+ * the second byte determines the scope for which the specified address
+ * is valid. These scope ID numbers are assigned in RFC 7346 which
+ * supersedes RFC 4291.
+ *
+ * @see ::IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES
+ */
+enum IPV6_MULTICAST_SCOPES
+{
+ IPV6_MULTICAST_SCOPE_INTF_LOCAL = 0x01, ///< Interface-Local scope
+ IPV6_MULTICAST_SCOPE_LINK_LOCAL, ///< Link-Local scope
+ IPV6_MULTICAST_SCOPE_REALM_LOCAL, ///< Realm-Local scope
+ IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, ///< Admin-Local scope
+ IPV6_MULTICAST_SCOPE_SITE_LOCAL, ///< Site-Local scope
+ IPV6_MULTICAST_SCOPE_ORGA_LOCAL = 0x08, ///< Organization-Local scope
+ IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE = 0x0E ///< Global scope
+};
+
+
+/**
+ * @brief Name strings for IPv6 multicast scopes
+ *
+ * This can e.g. be used to initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements.
+ *
+ * @see ::IPV6_MULTICAST_SCOPES
+ */
+#define IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES \
+{ \
+ { IPV6_MULTICAST_SCOPE_INTF_LOCAL, "FF01 - Interface-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_LINK_LOCAL, "FF02 - Link-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_REALM_LOCAL, "FF03 - Realm-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, "FF04 - Admin-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_SITE_LOCAL, "FF05 - Site-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_ORGA_LOCAL, "FF08 - Organization-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE, "FF0E - Global Scope" }, \
+ { 0, NULL } \
}
-// IP4_SETTINGS::vlan_cfg contains a combination of
-// a VLAN ID number plus a VLAN priiority code.
-// Definitions used with IP4_SETTINGS::vlan_cfg:
-#define VLAN_ID_BITS 12 // number of bits to hold the ID
-#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) // number of ID values
-#define MIN_VLAN_ID 0 // minimum ID value
-#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) // maximum ID value
+/**
+ * @brief A host's fully qualified domain name (FQDN), or a numeric IP address string
+ *
+ * In theory each single component (host name, domain name, top level domain name)
+ * of a FQDN can have up to 63 characters, but the overall length is limited to
+ * 255 characters. We specify one more character for the trailing 0.
+ */
+typedef char MBG_HOSTNAME[256]; ///< ASCIIZ format
+
+/** @} defgroup group_net_basic_types */
+
+
+
+/**
+ * @defgroup group_vlan_cfg Definitions used with VLAN configuration
+ *
+ * @{ */
+
+/**
+ * @brief VLAN configuration
+ *
+ * @note This is a combination of a VLAN ID number plus a VLAN priority code.
+ */
+typedef uint16_t MBG_VLAN_CFG;
+
+#define _mbg_swab_mbg_vlan_cfg( _p ) _mbg_swab16( _p );
+
+#define VLAN_ID_BITS 12 ///< number of bits to hold the ID
+#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) ///< number of ID values
+#define MIN_VLAN_ID 0 ///< minimum ID value
+#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) ///< maximum ID value
// vlan_id = ( vlan_cfg >> VLAN_ID_SHIFT ) & VLAN_ID_MSK
#define VLAN_ID_SHIFT 0
#define VLAN_ID_MSK ( ( 1 << VLAN_ID_BITS ) - 1 )
-#define VLAN_PRIORITY_BITS 3 // number of bits to hold priority
-#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) // number of priority values
-#define MIN_VLAN_PRIORITY 0 // minimum priority
-#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) // maximum priority
+#define VLAN_PRIORITY_BITS 3 ///< number of bits to hold priority
+#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) ///< number of priority values
+#define MIN_VLAN_PRIORITY 0 ///< minimum priority
+#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) ///< maximum priority
// vlan_priority = ( vlan_cfg >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK
-#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( uint16_t ) ) - VLAN_PRIORITY_BITS )
+#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( MBG_VLAN_CFG ) ) - VLAN_PRIORITY_BITS )
#define VLAN_PRIORITY_MSK ( ( 1 << VLAN_PRIORITY_BITS ) - 1 )
-// The macros below can be used to encode/decode packed vlan_cfg variables:
+/**
+ * @brief Macros used to encode/decode packed vlan_cfg variables
+ */
#define _decode_vlan_id( _cfg ) ( ( (_cfg) >> VLAN_ID_SHIFT ) & VLAN_ID_MSK )
#define _decode_vlan_priority( _cfg ) ( ( (_cfg) >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK )
#define _encode_vlan_cfg( _id, _prty ) ( ( (_id) << VLAN_ID_SHIFT ) | ( (_prty) << VLAN_PRIORITY_SHIFT ) )
+/** @} defgroup group_vlan_cfg */
-#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;
+/**
+ * @defgroup group_ip4_cfg Simple IPv4-only configuration or status
+ *
+ * This is only supported if the flag ::GPS_HAS_LAN_IP4 is set
+ * in ::RECEIVER_INFO::features.
+ * @see @ref group_ext_net_cfg Extended network configuration and status
+ *
+ * @{ */
-/* Description of a service running on a device */
-
+/**
+ * @brief Settings of an IPv4-only network interface
+ */
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 */
+ IP4_ADDR ip_addr; ///< the IP address
+ IP4_ADDR netmask; ///< the network mask
+ IP4_ADDR broad_addr; ///< the broadcast address
+ IP4_ADDR gateway; ///< the default gateway
+ uint16_t flags; ///< see ::MBG_IP4_FLAG_MASKS
+ MBG_VLAN_CFG vlan_cfg; ///< VLAN configuration
-} IP_SERVICE;
-
-#endif // 0
+} 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_swab16( &(_p)->flags ); \
+ _mbg_swab_mbg_vlan_cfg( &(_p)->vlan_cfg ); \
+}
-/* LAN interface information */
+/**
+ * @brief Simple LAN interface information
+ *
+ * This structure can be retrieved from a device
+ * to check the device's capabilities.
+ *
+ * It is only supported if the flag ::GPS_HAS_LAN_IP4 is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @see @ref group_ext_net_cfg Extended network configuration and status
+ */
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_0; /* reserved, currently always 0 */
- uint16_t flags; /* see below */
- uint16_t rsvd_1; /* reserved, currently always 0 */
+ uint16_t type; ///< type of LAN interface, see ::LAN_IF_TYPES
+ MBG_MAC_ADDR mac_addr; ///< MAC address
+ uint16_t ver_code; ///< version number (hex)
+ char ver_str[GPS_ID_STR_SIZE]; ///< version string
+ char sernum[GPS_ID_STR_SIZE]; ///< serial number
+ uint32_t rsvd_0; ///< reserved, currently always 0
+ uint16_t flags; ///< see ::MBG_IP4_FLAG_MASKS
+ uint16_t rsvd_1; ///< reserved, currently always 0
+
} LAN_IF_INFO;
#define _mbg_swab_lan_if_info( _p ) \
@@ -3792,84 +8081,782 @@ typedef struct
}
+/**
+ * @brief Codes used with ::LAN_IF_INFO::type
+ */
+enum LAN_IF_TYPES
+{
+ LAN_IF_TYPE_XPORT, ///< LAN interface on an XPORT, superseded by RSC devices
+ LAN_IF_TYPE_PTP, ///< LAN interface is a special PTP interface
+ LAN_IF_TYPE_RSC, ///< RSC device, supersedes XPORT
+ N_LAN_IF_TYPE ///< number of defined LAN interface types
+};
-/* codes used with LAN_IF_INFO::type: */
-enum
+/**
+ * @brief Enumeration of flag bits used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags
+ *
+ * @see ::MBG_IP4_FLAG_MASKS
+ */
+enum MBG_IP4_FLAG_BITS
{
- LAN_IF_TYPE_XPORT,
- LAN_IF_TYPE_PTP,
- N_LAN_IF_TYPE
+ /// In ::LAN_IF_INFO::flags this reports if DHCP is supported by the device.
+ /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable
+ /// or disable DHCP for the network interface.
+ IP4_BIT_DHCP,
+
+ /// Only used with ::IP4_SETTINGS::flags. Set if port link has been established.
+ IP4_BIT_LINK,
+
+ /// In ::LAN_IF_INFO::flags this reports if VLAN is supported by the device.
+ /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable
+ /// or disable VLAN for the network interface.
+ IP4_BIT_VLAN,
+
+ N_IP4_BIT ///< number of defined flag bits
};
-/* Flags used with IP4_SETTINGS::flags and LAN_IF_INFO::flags: */
+/**
+ * @brief Bit masks used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags
+ *
+ * @see ::MBG_IP4_FLAG_BITS
+ */
+enum MBG_IP4_FLAG_MASKS
+{
+ IP4_MSK_DHCP = ( 1UL << IP4_BIT_DHCP ), ///< see ::IP4_BIT_DHCP
+ IP4_MSK_LINK = ( 1UL << IP4_BIT_LINK ), ///< see ::IP4_BIT_LINK
+ IP4_MSK_VLAN = ( 1UL << IP4_BIT_VLAN ), ///< see ::IP4_BIT_VLAN
+};
-enum
+/** @} defgroup group_ip4_cfg */
+
+
+
+/**
+ * @defgroup group_ext_net_cfg_types Types used for extended network configuration and status
+ *
+ * @{ */
+
+/**
+ * @brief Enumeration of types used with ::MBG_IP_ADDR::type
+ */
+enum MBG_IP_ADDR_TYPES
{
- IP4_BIT_DHCP, // DHCP supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
- IP4_BIT_LINK, // used only in IP4_SETTINGS to report link state
- IP4_BIT_VLAN, // VLAN supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
- N_IP4_BIT
+ MBG_IP_ADDR_TYPE_UNKNOWN,
+ MBG_IP_ADDR_TYPE_IP4,
+ MBG_IP_ADDR_TYPE_IP6
};
-#define IP4_MSK_DHCP ( 1UL << IP4_BIT_DHCP )
-#define IP4_MSK_LINK ( 1UL << IP4_BIT_LINK )
-#define IP4_MSK_VLAN ( 1UL << IP4_BIT_VLAN )
+/*
+ * Default initializers for English mode string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN "unknown"
+#define MBG_IP_ADDR_TYPE_STR_ENG_IP4 "IPv4"
+#define MBG_IP_ADDR_TYPE_STR_ENG_IP6 "IPv6"
+#define MBG_IP_ADDR_TYPE_NAMES_ENG \
+{ \
+ MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN, \
+ MBG_IP_ADDR_TYPE_STR_ENG_IP4, \
+ MBG_IP_ADDR_TYPE_STR_ENG_IP6 \
+}
-enum
+
+/**
+ * @brief Network link speed modes
+ *
+ * @see ::MBG_NET_LINK_MODE_MASKS
+ *
+ * Note: Half duplex is not supported for 10GBit
+ */
+enum MBG_NET_LINK_MODES
+{
+ MBG_NET_LINK_MODE_AUTONEG, ///< auto negotiation
+ MBG_NET_LINK_MODE_10_BT_H, ///< 10 MBit half duplex
+ MBG_NET_LINK_MODE_10_BT_F, ///< 10 MBit full duplex
+ MBG_NET_LINK_MODE_100_BT_H, ///< 100 MBit half duplex
+ MBG_NET_LINK_MODE_100_BT_F, ///< 100 MBit full duplex
+ MBG_NET_LINK_MODE_1000_BT_H, ///< 1 GBit half duplex
+ MBG_NET_LINK_MODE_1000_BT_F, ///< 1 GBit full duplex
+ MBG_NET_LINK_MODE_10000_BT_F, ///< 10 GBit Full Duplex
+ N_MBG_NET_LINK_MODES
+};
+
+
+/**
+ * @brief Network link speed mode masks
+ *
+ * @see ::MBG_NET_LINK_MODES
+ */
+enum MBG_NET_LINK_MODE_MASKS
+{
+ MBG_NET_LINK_MODE_MASK_AUTONEG = ( 1UL << MBG_NET_LINK_MODE_AUTONEG ), ///< see ::MBG_NET_LINK_MODE_AUTONEG
+ MBG_NET_LINK_MODE_MASK_10_BT_H = ( 1UL << MBG_NET_LINK_MODE_10_BT_H ), ///< see ::MBG_NET_LINK_MODE_10_BT_H
+ MBG_NET_LINK_MODE_MASK_10_BT_F = ( 1UL << MBG_NET_LINK_MODE_10_BT_F ), ///< see ::MBG_NET_LINK_MODE_10_BT_F
+ MBG_NET_LINK_MODE_MASK_100_BT_H = ( 1UL << MBG_NET_LINK_MODE_100_BT_H ), ///< see ::MBG_NET_LINK_MODE_100_BT_H
+ MBG_NET_LINK_MODE_MASK_100_BT_F = ( 1UL << MBG_NET_LINK_MODE_100_BT_F ), ///< see ::MBG_NET_LINK_MODE_100_BT_F
+ MBG_NET_LINK_MODE_MASK_1000_BT_H = ( 1UL << MBG_NET_LINK_MODE_1000_BT_H ), ///< see ::MBG_NET_LINK_MODE_1000_BT_H
+ MBG_NET_LINK_MODE_MASK_1000_BT_F = ( 1UL << MBG_NET_LINK_MODE_1000_BT_F ), ///< see ::MBG_NET_LINK_MODE_1000_BT_F
+ MBG_NET_LINK_MODE_MASK_10000_BT_F = ( 1UL << MBG_NET_LINK_MODE_10000_BT_F ) ///< see ::MBG_NET_LINK_MODE_10000_BT_F
+};
+
+
+
+/**
+ * @brief Network link port types
+ *
+ * @see ::MBG_NET_LINK_PORT_MASKS
+ */
+enum MBG_NET_LINK_PORTS
+{
+ MBG_NET_LINK_PORT_AUTO, ///< auto detection
+ MBG_NET_LINK_PORT_TP, ///< Twisted Pair (TP)
+ MBG_NET_LINK_PORT_AUI, ///< Attachment Unit Interface (AUI), externel transceiver
+ MBG_NET_LINK_PORT_MII, ///< Media Independent Interface (MII), external receiver
+ MBG_NET_LINK_PORT_FIBRE, ///< fibre optic
+ MBG_NET_LINK_PORT_BNC, ///< coaxial cable
+ N_MBG_NET_LINK_PORTS
+};
+
+
+/**
+ * @brief Network link port type masks
+ *
+ * @see ::MBG_NET_LINK_PORTS
+ */
+enum MBG_NET_LINK_PORT_MASKS
{
- 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 )
+ MBG_NET_LINK_PORT_MASK_AUTO = ( 1UL << MBG_NET_LINK_PORT_AUTO ), ///< see ::MBG_NET_LINK_PORT_AUTO
+ MBG_NET_LINK_PORT_MASK_TP = ( 1UL << MBG_NET_LINK_PORT_TP ), ///< see ::MBG_NET_LINK_PORT_TP
+ MBG_NET_LINK_PORT_MASK_AUI = ( 1UL << MBG_NET_LINK_PORT_AUI ), ///< see ::MBG_NET_LINK_PORT_AUI
+ MBG_NET_LINK_PORT_MASK_MII = ( 1UL << MBG_NET_LINK_PORT_MII ), ///< see ::MBG_NET_LINK_PORT_MII
+ MBG_NET_LINK_PORT_MASK_FIBRE = ( 1UL << MBG_NET_LINK_PORT_FIBRE ), ///< see ::MBG_NET_LINK_PORT_FIBRE
+ MBG_NET_LINK_PORT_MASK_BNC = ( 1UL << MBG_NET_LINK_PORT_BNC ) ///< see ::MBG_NET_LINK_PORT_BNC
+};
+
+
+
+/**
+ * @brief Network link state bits
+ *
+ * @see ::MBG_NET_LINK_STATE_MASKS
+ *
+ * @note See official Linux kernel documentation
+ * https://www.kernel.org/doc/Documentation/networking/operstates.txt
+ * for states below and explanations. Windows supports this in nearly the same way
+ * using similar names struct IP_ADAPTER_ADDRESSES which is explained at
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx
+ */
+enum MBG_NET_LINK_STATE_BITS
+{
+ MBG_NET_LINK_STATE_BIT_UP,
+ MBG_NET_LINK_STATE_BIT_BROADCAST,
+ MBG_NET_LINK_STATE_BIT_LOOPBACK,
+ MBG_NET_LINK_STATE_BIT_P2P,
+ MBG_NET_LINK_STATE_BIT_RUNNING,
+ MBG_NET_LINK_STATE_BIT_NO_ARP,
+ MBG_NET_LINK_STATE_BIT_PROMISC,
+ MBG_NET_LINK_STATE_BIT_MASTER,
+ MBG_NET_LINK_STATE_BIT_SLAVE,
+ MBG_NET_LINK_STATE_BIT_MULTICAST,
+ MBG_NET_LINK_STATE_BIT_LOWER_UP,
+ MBG_NET_LINK_STATE_BIT_DORMANT,
+ MBG_NET_LINK_STATE_BIT_ECHO,
+ N_MBG_NET_LINK_STATE_BITS
+};
+
+
+/**
+ * @brief Network link state masks
+ *
+ * @see ::MBG_NET_LINK_STATE_BITS (reclined to Linux' if.h, Windows is similiar)
+ */
+enum MBG_NET_LINK_STATE_MASKS
+{
+ MBG_NET_LINK_STATE_MASK_UP = ( 1UL << MBG_NET_LINK_STATE_BIT_UP ), ///< see ::MBG_NET_LINK_STATE_BIT_UP
+ MBG_NET_LINK_STATE_MASK_BROADCAST = ( 1UL << MBG_NET_LINK_STATE_BIT_BROADCAST ), ///< see ::MBG_NET_LINK_STATE_BIT_BROADCAST
+ MBG_NET_LINK_STATE_MASK_LOOPBACK = ( 1UL << MBG_NET_LINK_STATE_BIT_LOOPBACK ), ///< see ::MBG_NET_LINK_STATE_BIT_LOOPBACK
+ MBG_NET_LINK_STATE_MASK_P2P = ( 1UL << MBG_NET_LINK_STATE_BIT_P2P ), ///< see ::MBG_NET_LINK_STATE_BIT_P2P
+ MBG_NET_LINK_STATE_MASK_RUNNING = ( 1UL << MBG_NET_LINK_STATE_BIT_RUNNING ), ///< see ::MBG_NET_LINK_STATE_BIT_RUNNING
+ MBG_NET_LINK_STATE_MASK_NO_ARP = ( 1UL << MBG_NET_LINK_STATE_BIT_NO_ARP ), ///< see ::MBG_NET_LINK_STATE_BIT_NO_ARP
+ MBG_NET_LINK_STATE_MASK_PROMISC = ( 1UL << MBG_NET_LINK_STATE_BIT_PROMISC ), ///< see ::MBG_NET_LINK_STATE_BIT_PROMISC
+ MBG_NET_LINK_STATE_MASK_MASTER = ( 1UL << MBG_NET_LINK_STATE_BIT_MASTER ), ///< see ::MBG_NET_LINK_STATE_BIT_MASTER
+ MBG_NET_LINK_STATE_MASK_SLAVE = ( 1UL << MBG_NET_LINK_STATE_BIT_SLAVE ), ///< see ::MBG_NET_LINK_STATE_BIT_SLAVE
+ MBG_NET_LINK_STATE_MASK_MULTICAST = ( 1UL << MBG_NET_LINK_STATE_BIT_MULTICAST ), ///< see ::MBG_NET_LINK_STATE_BIT_MULTICAST
+ MBG_NET_LINK_STATE_MASK_LOWER_UP = ( 1UL << MBG_NET_LINK_STATE_BIT_LOWER_UP ), ///< see ::MBG_NET_LINK_STATE_BIT_LOWER_UP
+ MBG_NET_LINK_STATE_MASK_DORMANT = ( 1UL << MBG_NET_LINK_STATE_BIT_DORMANT ), ///< see ::MBG_NET_LINK_STATE_BIT_DORMANT
+ MBG_NET_LINK_STATE_MASK_ECHO = ( 1UL << MBG_NET_LINK_STATE_BIT_ECHO ) ///< see ::MBG_NET_LINK_STATE_BIT_ECHO
+};
+
+
+
+/**
+ * @brief Network link option bits
+ *
+ * @see ::MBG_NET_LINK_OPT_MASKS
+ */
+enum MBG_NET_LINK_OPTS
+{
+ MBG_NET_LINK_OPT_CAN_SET_MAC,
+ MBG_NET_LINK_OPT_CAN_BOND,
+ MBG_NET_LINK_OPT_CAN_SYNCE,
+ N_MBG_NET_LINK_OPTS
+};
+
+
+/**
+ * @brief Network link option masks
+ *
+ * @see ::MBG_NET_LINK_OPTS
+ */
+enum MBG_NET_LINK_OPT_MASKS
+{
+ MBG_NET_LINK_OPT_MASK_CAN_SET_MAC = ( 1UL << MBG_NET_LINK_OPT_CAN_SET_MAC ), ///< see ::MBG_NET_LINK_OPT_CAN_SET_MAC
+ MBG_NET_LINK_OPT_MASK_CAN_BOND = ( 1UL << MBG_NET_LINK_OPT_CAN_BOND ), ///< see ::MBG_NET_LINK_OPT_CAN_BOND
+ MBG_NET_LINK_OPT_MASK_CAN_SYNCE = ( 1UL << MBG_NET_LINK_OPT_CAN_SYNCE ) ///< see ::MBG_NET_LINK_OPT_CAN_SYNCE
+};
+
+
+
+/**
+ * @brief Network link roles
+ *
+ * Used with ::MBG_NET_LINK_SETTINGS::role to determine
+ * if a network link operates in normal mode, or in
+ * a special mode, e.g. as part of a higher level pseudo
+ * interface (bonding, etc.)
+ */
+enum MBG_NET_LINK_ROLES
+{
+ MBG_NET_LINK_ROLE_UNKNOWN, ///< role can't be determined
+ MBG_NET_LINK_ROLE_NORMAL, ///< link is normal physical interface
+ MBG_NET_LINK_ROLE_MASTER, ///< link is master (e.g. bonding)
+ MBG_NET_LINK_ROLE_SLAVE, ///< link is slave (e.g. bonding)
+ N_MBG_NET_LINK_ROLES
+};
+//##++++++++++++++++ TODO define masks?
+
+
+
+/**
+ * @brief Network link bonding bits
+ *
+ * @see SIOCGIFPFLAGS under Linux, found no hint under Windows
+ */
+enum MBG_NET_LINK_ROLE_BITS
+{
+ MBG_NET_LINK_ROLE_BIT_BONDING, ///< Bonding master
+ MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE, ///< Bonding slave is not active
+ MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD, ///< 802.3ad bonding master
+ MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB, ///< Balanced-alb bonding master
+ N_MBG_NET_LINK_ROLE_BITS
+};
+
+
+/**
+ * @brief Network link role masks
+ *
+ * @see ::MBG_NET_LINK_ROLE_BITS
+ */
+enum MBG_NET_LINK_ROLE_MASKS
+{
+ MBG_NET_LINK_ROLE_MASK_BONDING = ( 1UL << MBG_NET_LINK_ROLE_BIT_BONDING ), ///< see ::MBG_NET_LINK_ROLE_BIT_BONDING
+ MBG_NET_LINK_ROLE_MASK_BOND_SLAVE_INACTIVE = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE
+ MBG_NET_LINK_ROLE_MASK_BOND_MASTER_8023AD = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD
+ MBG_NET_LINK_ROLE_MASK_BOND_MASTER_ALB = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB
+ N_MBG_NET_LINK_ROLE_MASKS
+};
+
+
+
+/**
+ * @brief Network link bonding mode
+ *
+ * Used with ::MBG_NET_LINK_SETTINGS::role_value
+ *
+ * @note if_bonding.h contains bonding modes under Linux, found no hint under Windows.
+ * BUT: Something similiar (concerning naming) can be configured under Windows
+ * via GUI in device manager, if supported.
+ */
+enum MBG_NET_LINK_BOND_MODES
+{
+ MBG_NET_LINK_BOND_MODE_UNKNOWN,
+ MBG_NET_LINK_BOND_MODE_ROUNDROBIN,
+ MBG_NET_LINK_BOND_MODE_ACTIVEBACKUP,
+ MBG_NET_LINK_BOND_MODE_XOR,
+ MBG_NET_LINK_BOND_MODE_BROADCAST,
+ MBG_NET_LINK_BOND_MODE_8023AD,
+ MBG_NET_LINK_BOND_MODE_TLB,
+ MBG_NET_LINK_BOND_MODE_ALB,
+ N_MBG_NET_LINK_BOND_MODES
+};
+
+
+/**
+ * @brief Network logical interface commands
+ *
+ * Used with ::MBG_NET_INTF_SETTINGS::cmd
+ */
+enum MBG_NET_LOG_INTF_CMDS
+{
+ MBG_NET_LOG_CMD_NONE,
+ MBG_NET_LOG_CMD_ADD_UPDATE,
+ MBG_NET_LOG_CMD_REMOVE,
+ N_MBG_NET_LOG_CMDS
+};
+
+
+/**
+ * @brief Network logical interface roles
+ *
+ * Used with ::MBG_NET_INTF_SETTINGS::role
+ */
+enum MBG_NET_LOG_INTF_ROLES
+{
+ MBG_NET_LOG_ROLE_STANDARD,
+ MBG_NET_LOG_ROLE_BOND,
+ MBG_NET_LOG_ROLE_VLAN,
+ N_MBG_NET_INTF_ROLE
+};
+
+
+/**
+ * @brief Network interface bits
+ *
+ * @see ::MBG_NET_INTF_MASKS
+ *
+ * Used with ::MBG_NET_INTF_INFO::supp_flags
+ */
+enum MBG_NET_INTF_BITS
+{
+ MBG_NET_INTF_BIT_EXT_ROUTING,
+ N_MBG_NET_INTF_BITS
+};
+
+
+/**
+ * @brief Network interface masks
+ *
+ * @see ::MBG_NET_INTF_BITS
+ */
+enum MBG_NET_INTF_MASKS
+{
+ MBG_NET_INTF_MASK_EXT_ROUTING = ( 1UL << MBG_NET_INTF_BIT_EXT_ROUTING ) ///< see ::MBG_NET_INTF_BIT_EXT_ROUTING
+};
+
+/** @} defgroup group_ext_net_cfg_types */
+
+
+
+/**
+ * @defgroup group_ext_net_cfg Extended network configuration and status
+ *
+ * This is only supported if the flag ::GPS_HAS_NET_CFG is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Global network configuration settings
+ */
+typedef struct
+{
+ MBG_HOSTNAME hostname; ///< hostname, eventually FQDN including domain name
+ uint32_t reserved; ///< currently reserved, always 0
+ uint32_t flags; ///< currently reserved, always 0
+ //##++++ TODO: flags could control IPv6, enable forwarding, etc.
+
+} MBG_NET_GLB_CFG_SETTINGS;
+
+#define _mbg_swab_net_glb_cfg_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Global current network settings and supported features
+ */
+typedef struct
+{
+ MBG_NET_GLB_CFG_SETTINGS glb_settings;
+ uint16_t num_link; ///< max. supported links (physical interfaces), see ::MBG_NET_LINK_SETTINGS_IDX, ::MBG_NET_LINK_INFO_IDX
+ uint16_t num_intf; ///< max. logical (including virtual) interfaces, see ::MBG_NET_INTF_SETTINGS_IDX, ::MBG_NET_INTF_INFO_IDX
+ uint16_t num_dns_srvr; ///< max. configurable DNS server addresses, using ::MBG_IP_ADDR_IDX records
+ uint16_t num_dns_srch_dom; ///< max. configurable DNS search domain records, using ::MBG_NET_NAME_IDX records
+ uint16_t num_static_routes; ///< max. configurable static routes
+ uint16_t max_hostname_len; ///< max. length of hostname including trailing 0; if set to 0, max. length is 256 (see rfc1123)
+ uint32_t reserved_1; ///< currently reserved, always 0
+ uint32_t reserved_2; ///< currently reserved, always 0
+ uint32_t flags_1; ///< currently reserved, always 0
+ uint32_t flags_2; ///< currently reserved, always 0
+
+} MBG_NET_GLB_CFG_INFO;
+
+#define _mbg_swab_net_glb_cfg_info( _p ) \
+{ \
+ _mbg_swab_net_glb_cfg_settings( &(_p)->glb_settings ); \
+ _mbg_swab16( &(_p)->num_link ); \
+ _mbg_swab16( &(_p)->num_intf ); \
+ _mbg_swab16( &(_p)->num_dns_srvr ); \
+ _mbg_swab16( &(_p)->num_dns_srch_dom ); \
+ _mbg_swab16( &(_p)->num_static_routes ); \
+ _mbg_swab16( &(_p)->max_hostname_len ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags_1 ); \
+ _mbg_swab32( &(_p)->flags_2 ); \
+}
+
+
+/**
+ * @brief An IPv4 or IPv6 network address
+ */
+typedef struct
+{
+ uint8_t type; ///< see ::MBG_IP_ADDR_TYPES
+ uint8_t reserved_1; ///< reserved, currently always 0 @todo Do we need this as scope indicator?
+ uint16_t reserved_2; ///< reserved, currently always 0
+
+ union
+ {
+ IP4_ADDR ip4_addr; ///< IPv4 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP4
+ IP6_ADDR ip6_addr; ///< IPv6 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP6
+ } u_addr;
+
+} MBG_IP_ADDR;
+
+
+/**
+ * @brief An IPv4 or IPv6 network address, plus index
+ */
+typedef struct
+{
+ uint16_t idx;
+ MBG_IP_ADDR addr; ///< network address
+
+} MBG_IP_ADDR_IDX;
+
+
+/**
+ * @brief Network host or domain name
+ */
+typedef struct
+{
+ MBG_HOSTNAME name;
+
+} MBG_NET_NAME;
+
+
+/**
+ * @brief Network host or domain name, plus index
+ */
+typedef struct
+{
+ uint16_t idx;
+ MBG_NET_NAME net_name;
+
+} MBG_NET_NAME_IDX;
+
+
+
+/**
+ * @brief Link (physical interface) specific settings
+ */
+typedef struct
+{
+ MBG_MAC_ADDR mac_addr; ///< Physical hardware address
+ MBG_MAC_ADDR broadcast; ///< Physical broadcast address
+ uint32_t mtu; ///< Max. packet size in bytes
+ uint32_t states; ///< see ::MBG_NET_LINK_STATE_BITS
+ uint32_t flags; ///< Reserved, currently 0
+ uint32_t reserved_1; ///< Reserved, currently 0
+ uint32_t reserved_2; ///< Reserved, currently 0
+ uint16_t bond_idx; ///< Current primary slave link index in ::MBG_NET_LINK_ROLE_MASTER role,
+ ///< current bonding master link index in ::MBG_NET_LINK_ROLE_SLAVE role,
+ ///< otherwise reserved and usually 0.
+ uint8_t speed_mode; ///< see ::MBG_NET_LINK_MODES
+ uint8_t port; ///< see ::MBG_NET_LINK_PORTS
+ uint8_t role; ///< see ::MBG_NET_LINK_ROLES
+ uint8_t reserved[3]; ///< Alignment. Can be used in future for usefull stuff.
+//##+++++ TODO check reserved above
+ uint32_t role_flags; ///< see ::MBG_NET_LINK_ROLE_BITS
+ uint32_t role_value; ///< Additional role parameters depending on role and role_flags,
+ ///< e.g. if role is master and flags contain bonding.
+ ///< See ::MBG_NET_LINK_BOND_MODES.
+} MBG_NET_LINK_SETTINGS;
+
+#define _mbg_swab_net_link_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->mtu ); \
+ _mbg_swab32( &(_p)->states ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab16( &(_p)->bond_idx ); \
+ _mbg_swab32( &(_p)->role_flags ); \
+ _mbg_swab32( &(_p)->role_value ); \
+}
+
+/**
+ * @brief Link (physical interface) specific settings, plus index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_link-1
+ MBG_NET_LINK_SETTINGS settings;
+
+} MBG_NET_LINK_SETTINGS_IDX;
+
+
+/**
+ * @brief Link (physical interface) specific settings, flags and supported features
+ */
+typedef struct
+{
+ MBG_NET_LINK_SETTINGS link_settings; ///< see ::MBG_NET_LINK_SETTINGS
+ uint32_t supp_opts; ///< see ::MBG_NET_LINK_OPT_MASKS
+ uint32_t supp_speed_modes; ///< see ::MBG_NET_LINK_MODE_MASKS
+ uint32_t supp_link_ports; ///< see ::MBG_NET_LINK_PORT_MASKS
+ uint32_t supp_states; ///< see ::MBG_NET_LINK_STATE_MASKS
+ uint32_t reserved_2;
+ uint32_t reserved_3;
+
+} MBG_NET_LINK_INFO;
+
+#define _mbg_swab_net_link_info( _p ) \
+{ \
+ _mbg_swab_net_link_settings( &(_p)->link_settings ); \
+ _mbg_swab32( &(_p)->supp_opts ); \
+ _mbg_swab32( &(_p)->supp_speed_modes ); \
+ _mbg_swab32( &(_p)->supp_link_ports ); \
+ _mbg_swab32( &(_p)->supp_states ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+}
+
+
+/**
+ * @brief Query MBG_NET_LINK_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_link-1
+ MBG_NET_LINK_INFO info;
+
+} MBG_NET_LINK_INFO_IDX;
+
+
+/**
+ * @brief Interface specific settings, flags and supported features
+ *
+ * @note Use link_mac and role to identify uniquely its associated network link.
+ */
+typedef struct
+{
+ uint8_t cmd; ///< see ::MBG_NET_LOG_INTF_CMDS
+ uint8_t role; ///< see ::MBG_NET_LOG_INTF_ROLES
+ uint16_t reserved_1; ///< Reserved, currently 0
+ uint32_t role_value; ///< Role specific value. E.g. VLAN ID
+ uint32_t flags; ///< Reserved, currently 0
+ uint32_t reserved_2; ///< Reserved, currently 0
+ MBG_IP_ADDR ip; ///< IP address associated with this interface
+ MBG_IP_ADDR gateway; ///< Interface specific. Reserved for future use. see ::MBG_IP_ADDR and ::MBG_NET_INTF_BIT_EXT_ROUTING
+ MBG_MAC_ADDR link_mac; ///< Unique identifier for related link (physical) interface
+ uint8_t prefix; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24
+ uint8_t reserved_3; ///< Reserved, currently 0
+
+} MBG_NET_INTF_SETTINGS;
+
+
+/**
+ * @brief Query MBG_NET_INTF_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_intf-1
+ MBG_NET_INTF_SETTINGS settings;
+
+} MBG_NET_INTF_SETTINGS_IDX;
+
+
+/**
+ * @brief Interface specific settings, flags and supported features
+ */
+typedef struct
+{
+ MBG_NET_INTF_SETTINGS intf_settings;
+ uint32_t supp_flags; ///< see ::MBG_NET_INTF_MASKS
+ uint32_t reserved_1; ///< Reserved, currently 0
+ uint32_t reserved_2; ///< Reserved, currently 0
+
+} MBG_NET_INTF_INFO;
+
+
+/**
+ * @brief Query MBG_NET_INTF_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_intf-1
+ MBG_NET_INTF_INFO info;
+
+} MBG_NET_INTF_INFO_IDX;
+
+
+/**
+ * @brief An IPv4 or IPv6 network address plus UDP or TCP port number
+ */
+typedef struct
+{
+ MBG_IP_ADDR addr; ///< see ::MBG_IP_ADDR
+
+ uint16_t port; ///< UDP or TCP port
+ uint16_t flags; ///< currently always 0
+ //##+++++ TODO should the flags field indicate if the port is UDP and/or TCP?
+
+} MBG_IP_ADDR_PORT;
+
+
+
+#if 0 //##++++++++++++++++++++++
+
+/**
+ * @brief Network service configuration
+ *
+ * Used to configure known services, e.g SSH, FTP, etc.
+ */
+typedef struct
+{
+ uint16_t svc_type; ///< see ::MBG_NET_SVC_TYPES
+ uint16_t reserved; ///< reserved, currently always 0
+ MBG_IP_ADDR_PORT settings; ///< The network address and port a service listens on
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_NET_INTF_CFG;
+
+
+
+/**
+ * @brief
+ */
+typedef struct
+{
+ uint8_t b[IP6_ADDR_BYTES]; ///< bytes holding the address bits, b[0] == LSBs
+//##+++ uint8_t cidr_net_mask; ///< number of CIDR net mask bits, 0..::IP6_ADDR_BITS
+// uint8_t reserved; ///< not yet used, always 0
+// uint16_t flags; ///< not yet used, always 0
+
+} MBG_NET_INTF_CFG;
+
#endif
+/** @} defgroup group_ext_net_cfg */
+
+/** @} defgroup group_net_cfg */
+
+
+
+/**
+ * @defgroup group_ptp Definitions used with PTP/IEEE1588
+ *
+ * @{ */
+
+/**
+ * @brief Enumeration of protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROT_MASKS
+ */
+enum PTP_NW_PROTS
+{
+ PTP_NW_PROT_RESERVED, ///< reserved
+ PTP_NW_PROT_UDP_IPV4, ///< IPv4
+ PTP_NW_PROT_UDP_IPV6, ///< IPv6
+ PTP_NW_PROT_IEEE_802_3, ///< Ethernet (raw layer 2)
+ PTP_NW_PROT_DEVICE_NET, ///< DeviceNet
+ PTP_NW_PROT_CONTROL_NET, ///< ControlNet
+ PTP_NW_PROT_PROFINET, ///< ProfiNet
+ N_PTP_NW_PROT ///< number of defined protocols
+};
+
+
+/**
+ * @brief Bit masks for enumerated protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
+ */
+enum PTP_NW_PROT_MASKS
+{
+ PTP_NW_PROT_MSK_RESERVED = ( 1UL << PTP_NW_PROT_RESERVED ), ///< see ::PTP_NW_PROT_RESERVED
+ PTP_NW_PROT_MSK_UDP_IPV4 = ( 1UL << PTP_NW_PROT_UDP_IPV4 ), ///< see ::PTP_NW_PROT_UDP_IPV4
+ PTP_NW_PROT_MSK_UDP_IPV6 = ( 1UL << PTP_NW_PROT_UDP_IPV6 ), ///< see ::PTP_NW_PROT_UDP_IPV6
+ PTP_NW_PROT_MSK_IEEE_802_3 = ( 1UL << PTP_NW_PROT_IEEE_802_3 ), ///< see ::PTP_NW_PROT_IEEE_802_3
+ PTP_NW_PROT_MSK_DEVICE_NET = ( 1UL << PTP_NW_PROT_DEVICE_NET ), ///< see ::PTP_NW_PROT_DEVICE_NET
+ PTP_NW_PROT_MSK_CONTROL_NET = ( 1UL << PTP_NW_PROT_CONTROL_NET ), ///< see ::PTP_NW_PROT_CONTROL_NET
+ PTP_NW_PROT_MSK_PROFINET = ( 1UL << PTP_NW_PROT_PROFINET ) ///< see ::PTP_NW_PROT_PROFINET
+};
+
+
+
+/**
+ * @brief Name strings for the protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
+ */
#define PTP_NW_PROT_STRS \
{ \
"Reserved", \
- "UDP/IPv4", \
- "UDP/IPv6", \
- "IEEE 802.3", \
+ "UDP/IPv4 (L3)", \
+ "UDP/IPv6 (L3)", \
+ "IEEE 802.3 (L2)", \
"DeviceNet", \
"ControlNet", \
"PROFINET" \
}
+/**
+ * @brief Short name strings for the protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
+ */
+#define PTP_NW_PROT_STRS_SHORT \
+{ \
+ "RSV", \
+ "IP4", \
+ "IP6", \
+ "ETH", \
+ "DN", \
+ "CN", \
+ "PN" \
+}
-enum
+
+/**
+ * @brief Possible states of a PTP port
+ */
+enum PTP_PORT_STATES
{
- 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
+ PTP_PORT_STATE_UNINITIALIZED, ///< uninitialized
+ PTP_PORT_STATE_INITIALIZING, ///< currently initializing
+ PTP_PORT_STATE_FAULTY, ///< faulty
+ PTP_PORT_STATE_DISABLED, ///< disabled
+ PTP_PORT_STATE_LISTENING, ///< listening for PTP packets
+ PTP_PORT_STATE_PRE_MASTER, ///< going to become master
+ PTP_PORT_STATE_MASTER, ///< master
+ PTP_PORT_STATE_PASSIVE, ///< passive
+ PTP_PORT_STATE_UNCALIBRATED, ///< uncalibrated
+ PTP_PORT_STATE_SLAVE, ///< slave
+ N_PTP_PORT_STATE ///< number of defined port states
};
+
+/**
+ * @brief Name strings for the PTP port states
+ */
#define PTP_PORT_STATE_STRS \
{ \
"UNINITIALIZED", \
@@ -3885,40 +8872,76 @@ enum
}
+/**
+ * @brief An entry for a table of parameters which can not be accessed by an enumerated index
+ */
typedef struct
{
- uint8_t value;
- const char *name;
+ uint8_t value; ///< the parameter value
+ const char *name; ///< the parameter name
+
} PTP_TABLE;
-enum
+
+/**
+ * @brief An enumeration of PTP delay mechanisms
+ *
+ * @note This is different than the numeric values specified
+ * in the published specs for IEEE1588. In addition, the specs
+ * define code 0x14 for "disabled".
+ *
+ * @see ::PTP_DELAY_MECH_MASKS
+ * @see ::PTP_DELAY_MECH_NAMES
+ */
+enum PTP_DELAY_MECHS
{
- 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
+ PTP_DELAY_MECH_E2E, ///< End-to-End (in PTP2 specs: 0x01)
+ PTP_DELAY_MECH_P2P, ///< Peer-to-Peer (in PTP2 specs: 0x02)
+ N_PTP_DELAY_MECH ///< number of defined delay mechanisms
};
-#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 | PTP_DELAY_MECH_MSK_P2P )
-#endif
+/**
+ * @brief Bit masks associated with enumerated PTP delay mechanisms
+ *
+ * @see ::PTP_DELAY_MECH_MASKS
+ */
+enum PTP_DELAY_MECH_MASKS
+{
+ PTP_DELAY_MECH_MSK_E2E = ( 1UL << PTP_DELAY_MECH_E2E ), ///< see ::PTP_DELAY_MECH_E2E
+ PTP_DELAY_MECH_MSK_P2P = ( 1UL << PTP_DELAY_MECH_P2P ) ///< see ::PTP_DELAY_MECH_P2P
+};
+
+#define PTP_DELAY_MECH_NAME_E2E "E2E"
+#define PTP_DELAY_MECH_NAME_P2P "P2P"
+
+/**
+ * @brief Name strings for the PTP delay mechanisms
+ *
+ * @see ::PTP_DELAY_MECHS
+ */
#define PTP_DELAY_MECH_NAMES \
{ \
- "E2E", \
- "P2P" \
+ PTP_DELAY_MECH_NAME_E2E, \
+ PTP_DELAY_MECH_NAME_P2P \
}
-#define PTP_CLOCK_ACCURACY_RESERVED_OFFSET 0x20
-
-enum
+/**
+ * @brief An enumeration of accuracy classes used with PTP
+ *
+ * @note This enumeration does not start at 0 but with a bias
+ * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS.
+ *
+ * @see ::PTP_CLOCK_ACCURACY_STRS
+ */
+enum PTP_CLOCK_ACCURACIES
{
- PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_RESERVED_OFFSET,
+ PTP_CLOCK_ACCURACY_NUM_BIAS = 0x20,
+ PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_NUM_BIAS,
PTP_CLOCK_ACCURACY_100ns,
PTP_CLOCK_ACCURACY_250ns,
PTP_CLOCK_ACCURACY_1us,
@@ -3941,11 +8964,20 @@ enum
PTP_CLOCK_ACCURACY_RESERVED_3,
PTP_CLOCK_ACCURACY_RESERVED_4,
N_PTP_CLOCK_ACCURACY
+ //##++++ TODO: Add a code for 0xFE (unknown), or eventually
+ // redesign the lookup of associated strings completely.
};
-// Attention: Substract offset of PTP_CLOCK_ACCURACY_RESERVED_OFFSET when
-// using the enum above as index for the initializer below!
+/**
+ * @brief Name strings for PTP accuracy classes
+ *
+ * @note The enumeration does not start at 0 but with a bias
+ * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS, so this bias needs
+ * to be accounted for when accessing a string table.
+ *
+ * @see ::PTP_CLOCK_ACCURACIES
+ */
#define PTP_CLOCK_ACCURACY_STRS \
{ \
"< 25 ns", \
@@ -3974,17 +9006,30 @@ enum
-#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
+/**
+ * @brief Codes to specify the type of a time source used with PTP
+ *
+ * @see ::PTP_TIME_SOURCE_TABLE
+ */
+enum PTP_TIME_SOURCES
+{
+ PTP_TIME_SOURCE_ATOMIC_CLOCK = 0x10,
+ PTP_TIME_SOURCE_GPS = 0x20,
+ PTP_TIME_SOURCE_TERRESTRIAL_RADIO = 0x30,
+ PTP_TIME_SOURCE_PTP = 0x40,
+ PTP_TIME_SOURCE_NTP = 0x50,
+ PTP_TIME_SOURCE_HAND_SET = 0x60,
+ PTP_TIME_SOURCE_OTHER = 0x90,
+ PTP_TIME_SOURCE_INTERNAL_OSCILLATOR = 0xA0
+};
+/**
+ * @brief A table of PTP time source codes plus associated name strings
+ *
+ * @see ::PTP_TIME_SOURCES
+ */
#define PTP_TIME_SOURCE_TABLE \
{ \
{ PTP_TIME_SOURCE_ATOMIC_CLOCK, "Atomic Clock" }, \
@@ -3999,292 +9044,3006 @@ enum
}
+/**
+ * @brief An enumeration of roles which can be taken by a PTP node
+ *
+ * A role in this context specifies a certain mode of operation.
+ * Depending on its specification a devices may not be able to take
+ * each of the specified roles.
+ *
+ * @note: A device in MULTICAST_AUTO role can be either master or slave,
+ * so the port state needs to be checked to determine the current
+ * mode of operation.
+ *
+ * @see ::PTP_ROLE_MASKS
+ * @see ::PTP_ROLE_STRS
+ * @see ::PTP_ROLE_STRS_SHORT
+ */
+enum PTP_ROLES
+{
+ PTP_ROLE_MULTICAST_SLAVE, ///< slave in multicast mode
+ PTP_ROLE_UNICAST_SLAVE, ///< slave in unicast mode
+ PTP_ROLE_MULTICAST_MASTER, ///< multicast master
+ PTP_ROLE_UNICAST_MASTER, ///< unicast master
+ PTP_ROLE_MULTICAST_AUTO, ///< multicast master or slave (auto selection)
+ PTP_ROLE_BOTH_MASTER, ///< simultanous multicast and unicast master
+ PTP_ROLE_NTP_SERVER, ///< NTP Unicast Server
+ PTP_ROLE_NTP_CLIENT, ///< NTP Unicast Client
+ N_PTP_ROLES ///< number of defined roles
+};
+
+
+/**
+ * @brief Bit mask associated with ::PTP_ROLES
+ *
+ * A role in this context specifies a certain mode of operation.
+ * Depending on its specification a devices may not be able to take
+ * each of the specified roles.
+ *
+ * @note: A device in MULTICAST_AUTO role can be either master or slave,
+ * so the port state needs to be checked to determine the current
+ * mode of operation.
+ *
+ * @see ::PTP_ROLES
+ * @see ::get_supp_ptp_role_mask
+ */
+enum PTP_ROLE_MASKS
+{
+ PTP_ROLE_MSK_MULTICAST_SLAVE = ( 1UL << PTP_ROLE_MULTICAST_SLAVE ), ///< see ::PTP_ROLE_MULTICAST_SLAVE
+ PTP_ROLE_MSK_UNICAST_SLAVE = ( 1UL << PTP_ROLE_UNICAST_SLAVE ), ///< see ::PTP_ROLE_UNICAST_SLAVE
+ PTP_ROLE_MSK_MULTICAST_MASTER = ( 1UL << PTP_ROLE_MULTICAST_MASTER ), ///< see ::PTP_ROLE_MULTICAST_MASTER
+ PTP_ROLE_MSK_UNICAST_MASTER = ( 1UL << PTP_ROLE_UNICAST_MASTER ), ///< see ::PTP_ROLE_UNICAST_MASTER
+ PTP_ROLE_MSK_MULTICAST_AUTO = ( 1UL << PTP_ROLE_MULTICAST_AUTO ), ///< see ::PTP_ROLE_MULTICAST_AUTO
+ PTP_ROLE_MSK_BOTH_MASTER = ( 1UL << PTP_ROLE_BOTH_MASTER ), ///< see ::PTP_ROLE_BOTH_MASTER
+ PTP_ROLE_MSK_NTP_SERVER = ( 1UL << PTP_ROLE_NTP_SERVER ), ///< see ::PTP_ROLE_NTP_SERVER
+ PTP_ROLE_MSK_NTP_CLIENT = ( 1UL << PTP_ROLE_NTP_CLIENT ) ///< see ::PTP_ROLE_NTP_CLIENT
+};
+
+#define PTP_ROLE_MSK_SLAVES ( PTP_ROLE_MSK_MULTICAST_SLAVE \
+ | PTP_ROLE_MSK_UNICAST_SLAVE \
+ | PTP_ROLE_MSK_MULTICAST_AUTO )
-/* PTP configuration stuff */
+#define PTP_ROLE_MSK_MASTERS ( PTP_ROLE_MSK_MULTICAST_MASTER \
+ | PTP_ROLE_MSK_UNICAST_MASTER \
+ | PTP_ROLE_MSK_MULTICAST_AUTO \
+ | PTP_ROLE_BOTH_MASTER )
+
+/**
+ * @brief Name strings for defined PTP roles
+ *
+ * @see ::PTP_ROLES
+ * @see ::PTP_ROLE_STRS_SHORT
+ */
+#define PTP_ROLE_STRS \
+{ \
+ "Multicast Slave", \
+ "Unicast Slave", \
+ "Multicast Master", \
+ "Unicast Master", \
+ "Multicast (Auto)", \
+ "UC+MC Master", \
+ "NTP Server", \
+ "NTP Client" \
+}
+
+
+/**
+ * @brief Short name strings for defined PTP roles
+ *
+ * @see ::PTP_ROLES
+ * @see ::PTP_ROLE_STRS
+ */
+#define PTP_ROLE_STRS_SHORT \
+{ \
+ "MCS", \
+ "UCS", \
+ "MCM", \
+ "UCM", \
+ "MCA", \
+ "UMM", \
+ "NSV", \
+ "NCL" \
+}
+
+
+/**
+ * @brief A PTP clock identity
+ *
+ * @note This usually consists of a 6 byte MAC address with
+ * 2 fixed bytes inserted, or all ones as wildcard.
+ */
typedef struct
{
uint8_t b[8];
-} PTP_CLOCK_IDENTITY;
+
+} PTP_CLOCK_ID;
+
+#define _mbg_swab_ptp_clock_id( _p ) _nop_macro_fnc() // nothing to swap
+
+#define PTP_CLOCK_ID_WILDCARD { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
+
+
+/**
+ * @brief A PTP port ID
+ */
+typedef uint16_t PTP_PORT_ID;
+
+#define _mbg_swab_ptp_port_id( _p ) _mbg_swab16( _p )
+
+#define PTP_PORT_ID_WILDCARD 0xFFFF
+
+
+/**
+ * @brief An enumeration of time scales used with PTP
+ *
+ * @note The standard time scale used by PTP is TAI, which is a linear time scale.
+ * The protocol provides a %UTC offset to be able to convert TAI to compute %UTC, which
+ * can observe leap seconds. For the arbitrary time scale the %UTC offset is unspecified,
+ * so arbitrary time can be %UTC, or something else.
+ *
+ * @see ::PTP_TIMESCALE_NAMES
+ * @see ::PTP_TIMESCALE_NAMES_SHORT
+ */
+enum PTP_TIME_SCALES
+{
+ PTP_TIMESCALE_PTP, ///< PTP default, TAI
+ PTP_TIMESCALE_ARB, ///< arbitrary time scale, maybe %UTC
+ N_PTP_TIMESCALE
+};
+
+
+/**
+ * @brief Name strings for the PTP time scales
+ */
+#define PTP_TIMESCALE_NAME_PTP "PTP Standard (TAI)"
+#define PTP_TIMESCALE_NAME_ARB "Arbitrary"
+
+/**
+ * @brief Short name strings for the PTP time scales
+ */
+#define PTP_TIMESCALE_NAME_PTP_SHORT "PTP"
+#define PTP_TIMESCALE_NAME_ARB_SHORT "Arb"
+
+
+/**
+ * @brief A table of name strings for the PTP time scales
+ *
+ * @see ::PTP_TIME_SCALES
+ * @see ::PTP_TIMESCALE_NAMES_SHORT
+ */
+#define PTP_TIMESCALE_NAMES \
+{ \
+ PTP_TIMESCALE_NAME_PTP, \
+ PTP_TIMESCALE_NAME_ARB \
+}
+
+/**
+ * @brief A table of short name strings for the PTP time scales
+ *
+ * @see ::PTP_TIME_SCALES
+ * @see ::PTP_TIMESCALE_NAMES
+ */
+#define PTP_TIMESCALE_NAMES_SHORT \
+{ \
+ PTP_TIMESCALE_NAME_PTP_SHORT, \
+ PTP_TIMESCALE_NAME_ARB_SHORT \
+}
+/**
+ * @brief A structure to used to read the status of the PTP protocol stack
+ */
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;
+ uint16_t nw_prot; ///< one of the enumerated protocols, see ::PTP_NW_PROTS
+ uint8_t ptp_prot_version; ///< PTP protocol version, 1, or 2, usually 2 for v2
+ uint8_t port_state; ///< one of the enumerated port states, see ::PTP_PORT_STATES
+ uint32_t flags; ///< see ::PTP_STATE_FLAGS
+ NANO_TIME offset; ///< estimated time offset from the upstream time source
NANO_TIME path_delay;
NANO_TIME mean_path_delay;
NANO_TIME delay_asymmetry;
- PTP_CLOCK_IDENTITY gm_identity;
+ PTP_CLOCK_ID gm_id; ///< identifier ot the upstream time source
uint16_t clock_offset_scaled_log_variance;
uint8_t clock_class;
- uint8_t clock_accuracy; // enum
+ uint8_t clock_accuracy; ///< see ::PTP_CLOCK_ACCURACIES
+
+ uint32_t reserved_1; ///< reserved, currently always 0
+ uint32_t reserved_2; ///< reserved, currently always 0
+
+ uint8_t domain_number; ///< the PTP clock domain number, 0:3
+ uint8_t time_source; ///< see ::PTP_TIME_SOURCES
+ uint8_t delay_mech; ///< see ::PTP_DELAY_MECHS
+ int8_t log_delay_req_intv;
- uint32_t num_clients;
- uint32_t num_masters;
+ int16_t utc_offset; ///< %UTC offset observed against TAI
+ DAC_VAL osc_dac_cal; ///< disciplination value of the oscillator
- uint8_t domain_number;
- uint8_t time_source; // enum
- uint8_t delay_mech;
- int8_t log_delay_req_intv;
+ uint8_t parent_clock_class; ///< clock class of the parent node
+ uint8_t parent_clock_accuracy; ///< clock accuracy of the parent node, see ::PTP_CLOCK_ACCURACIES
- int16_t utc_offset;
- DAC_VAL osc_dac_cal;
+ uint16_t reserved_3; ///< reserved, currently always 0
- uint32_t reserved;
} PTP_STATE;
#define _mbg_swab_ptp_state( _p ) \
{ \
- _mbg_swab16( &(_p)->network_protocol ); \
+ _mbg_swab16( &(_p)->nw_prot ); \
_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_swab_ptp_clock_id( &(_p)->gm_id ); \
_mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \
- _mbg_swab32( &(_p)->num_clients ); \
- _mbg_swab32( &(_p)->num_masters ); \
- _mbg_swab32( &(_p)->utc_offset ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab16( &(_p)->utc_offset ); \
_mbg_swab_dac_val( &(_p)->osc_dac_cal ); \
+ _mbg_swab16( &(_p)->reserved_3 ); \
}
-enum
+/**
+ * @brief Flags bits used with PTP_STATE::flags
+ *
+ * @see ::PTP_STATE_FLAG_MASKS
+ */
+enum PTP_STATE_FLAGS
{
- 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
+ PTP_FLAG_SLAVE_ONLY, ///< the port can only be slave
+ PTP_FLAG_IS_SLAVE, ///< the port is currently slave
+ PTP_FLAG_TIMESCALE_IS_PTP, ///< the timescale is PTP standard, not arbitrary
+ PTP_FLAG_LS_ANN, ///< a leap second is being announced
+ PTP_FLAG_LS_ANN_NEG, ///< the announced leap second is negative
+ PTP_FLAG_IS_UNICAST, ///< the port currently operates in unicast mode
+ PTP_FLAG_UTC_VALID, ///< %UTC parameters are valid
+ PTP_FLAG_ONE_STEP, ///< One-Step Clock active
+ N_PTP_STATE_FLAGS ///< the number of defined flag bits
};
-#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
+/**
+ * @brief Flags masks used with PTP_STATE::flags
+ *
+ * @see ::PTP_STATE_FLAGS
+ */
+enum PTP_STATE_FLAG_MASKS
+{
+ PTP_FLAG_MSK_SLAVE_ONLY = ( 1UL << PTP_FLAG_SLAVE_ONLY ), ///< see ::PTP_FLAG_SLAVE_ONLY
+ PTP_FLAG_MSK_IS_SLAVE = ( 1UL << PTP_FLAG_IS_SLAVE ), ///< see ::PTP_FLAG_IS_SLAVE
+ PTP_FLAG_MSK_TIMESCALE_IS_PTP = ( 1UL << PTP_FLAG_TIMESCALE_IS_PTP ), ///< see ::PTP_FLAG_TIMESCALE_IS_PTP
+ PTP_FLAG_MSK_LS_ANN = ( 1UL << PTP_FLAG_LS_ANN ), ///< see ::PTP_FLAG_LS_ANN
+ PTP_FLAG_MSK_LS_ANN_NEG = ( 1UL << PTP_FLAG_LS_ANN_NEG ), ///< see ::PTP_FLAG_LS_ANN_NEG
+ PTP_FLAG_MSK_IS_UNICAST = ( 1UL << PTP_FLAG_IS_UNICAST ), ///< see ::PTP_FLAG_IS_UNICAST
+ PTP_FLAG_MSK_UTC_VALID = ( 1UL << PTP_FLAG_UTC_VALID ), ///< see ::PTP_FLAG_UTC_VALID
+ PTP_FLAG_MSK_ONE_STEP = ( 1UL << PTP_FLAG_ONE_STEP ) ///< see ::PTP_FLAG_ONE_STEP
+};
-#define PTP_DELAY_REQ_INTERVAL_MIN -6
-#define PTP_DELAY_REQ_INTERVAL_MAX 6
+/**
+ * @brief A structure used to configure a PTP port
+ */
typedef struct
{
- uint16_t network_protocol; // enum, only 1 or 3
- uint8_t profile; // currently only 0 = default
- uint8_t domain_number; // 0:3
+ uint16_t nw_prot; ///< see ::PTP_NW_PROTS
+ uint8_t selected_presets; ///< selected PTP presets, see ::PTP_PRESETS
+ uint8_t domain_number; ///< the PTP clock 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 delay_mech; ///< see ::PTP_DELAY_MECHS
+ uint8_t ptp_role; ///< one of the supported PTP roles, see ::PTP_ROLES
+ uint8_t priority_1; ///< priority 1
+ uint8_t priority_2; ///< 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
+ uint8_t ann_rcpt_timeout; ///< announce msg. receipt timeout, see ::PTP_ANN_RCPT_TIMEOUT_LIMITS
+ uint8_t opt_ext; ///< optional configuration extension, see ::PTP_OPT_EXTS
+ int16_t sync_intv; ///< log2 of the sync interval [s]
- int16_t announce_interval; // log 2
- int16_t delay_request_interval; // log 2
+ int16_t ann_intv; ///< log2 of the announce interval [s]
+ int16_t delay_req_intv; ///< log2 of the delay request interval [s]
- 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 upper_bound; ///< sync state set to false if above this limit [ns]
+ uint32_t lower_bound; ///< sync state set to true if below this limit [ns]
- uint32_t reserved_3; // currently always 0
- uint32_t flags; // (see below)
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see @ref PTP_CFG_FLAG_MASKS
} 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 ); \
+#define _mbg_swab_ptp_cfg_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->nw_prot ); \
+ _mbg_swab16( &(_p)->sync_intv ); \
+ _mbg_swab16( &(_p)->ann_intv ); \
+ _mbg_swab16( &(_p)->delay_req_intv ); \
+ _mbg_swab32( &(_p)->upper_bound ); \
+ _mbg_swab32( &(_p)->lower_bound ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
}
+/**
+ * @brief Possible values for PTP_CFG_SETTINGS::ann_rcpt_timeout
+ */
+enum PTP_ANN_RCPT_TIMEOUT_LIMITS
+{
+ PTP_ANN_RCPT_TIMEOUT_MIN = 2,
+ PTP_ANN_RCPT_TIMEOUT_MAX = 255,
+ DEFAULT_PTP_ANN_RCPT_TIMEOUT = 3
+};
+
+
+
+/**
+ * @brief A structure to used to query the current configuration and capabilities of a PTP port
+ */
typedef struct
{
- PTP_CFG_SETTINGS settings;
+ PTP_CFG_SETTINGS settings; ///< the current configuration
- uint8_t ptp_proto_version; // PTP v1 or v2
- uint8_t reserved_1; // currently always 0
- uint16_t reserved_2; // currently always 0
+ uint8_t ptp_proto_version; ///< PTP protocol version, 1, or 2, usually 2 for v2
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t reserved_2; ///< reserved, 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
+ int16_t sync_intv_min; ///< log2 of minimum sync interval [s]
+ int16_t sync_intv_max; ///< log2 of maximum sync interval [s]
+ int16_t ann_intv_min; ///< log2 of minimum announce interval [s]
+ int16_t ann_intv_max; ///< log2 of maximum announce interval [s]
+ int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s]
+ int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s]
- uint32_t supported_flags; // (see below)
- uint32_t supported_network_protocols;
- uint32_t supported_profiles;
- uint32_t supported_delay_mechanisms;
+ uint32_t supp_flags; ///< a bit mask of supported features, see @ref PTP_CFG_FLAG_MASKS
+ uint32_t supp_nw_prot; ///< a bit mask of supported network protocols, see ::PTP_NW_PROT_MASKS
+ uint32_t supp_opt_ext; ///< a bit mask of supported optional extensions, see ::PTP_OPT_EXT_MASKS
+ uint32_t supp_delay_mech; ///< a bit mask of supported delay mechanisms, see ::PTP_DELAY_MECH_MASKS
} 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 ); \
+#define _mbg_swab_ptp_cfg_info( _p ) \
+{ \
+ _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab16( &(_p)->sync_intv_min ); \
+ _mbg_swab16( &(_p)->sync_intv_max ); \
+ _mbg_swab16( &(_p)->ann_intv_min ); \
+ _mbg_swab16( &(_p)->ann_intv_max ); \
+ _mbg_swab16( &(_p)->delay_req_intv_min ); \
+ _mbg_swab16( &(_p)->delay_req_intv_max ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_nw_prot ); \
+ _mbg_swab32( &(_p)->supp_opt_ext ); \
+ _mbg_swab32( &(_p)->supp_delay_mech ); \
}
-// 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
+/**
+ * @brief Flags bits used with PTP configuration
+ *
+ * Flags labeled [R/-] can only be used with ::PTP_CFG_INFO::supp_flags
+ * to indicate that the associated feature is supported in general.
+ *
+ * If a flag labeled [R/W] is set in ::PTP_CFG_INFO::supp_flags then
+ * this flag can also be used with ::PTP_CFG_SETTINGS::flags to control
+ * the associated feature.
+ *
+ * @note Originally, all devices supported the multicast slave role, so
+ * there was no extra flag to indicate this. However, some newer devices
+ * may not support the multicast slave role, so two new flags have been
+ * introduced to cope with this:
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is set then a different flag
+ * ::PTP_CFG_CAN_BE_MULTICAST_SLAVE needs to be checked to tell if
+ * the multicast slave role is supported, or not.
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is not set then the device
+ * definitely supports the multicast slave role.
+ *
+ * @see @ref PTP_CFG_FLAG_MASKS
+ */
+enum PTP_CFG_FLAGS
{
- PTP_CFG_BIT_TIME_SCALE_IS_PTP, // time scale is PTP/TAI, else arbitrary
- PTP_CFG_BIT_V1_HW_COMPAT,
- N_PTP_CFG_BIT
+ PTP_CFG_TIME_SCALE_IS_PTP, ///< [R/W] time scale is PTP/TAI, else arbitrary
+ PTP_CFG_V1_HW_COMPAT, ///< [R/W] maybe required for certain NIC chips, not used by Meinberg
+ PTP_CFG_CAN_BE_UNICAST_SLAVE, ///< [R/-] supports unicast slave role, see ::PTP_ROLE_UNICAST_SLAVE
+ PTP_CFG_CAN_BE_MULTICAST_MASTER, ///< [R/-] supports multicast master role, see ::PTP_ROLE_MULTICAST_MASTER
+ PTP_CFG_CAN_BE_UNICAST_MASTER, ///< [R/-] supports unicast master, see ::PTP_ROLE_UNICAST_MASTER
+ PTP_CFG_CAN_BE_MULTICAST_AUTO, ///< [R/-] can automatically become multicast master or slave, see ::PTP_CFG_CAN_BE_MULTICAST_AUTO
+ PTP_CFG_SUPP_UTC_VALID, ///< [R/-] ::PTP_FLAG_UTC_VALID bit in ::PTP_STATE::flags is supported
+ PTP_CFG_CAN_BE_BOTH_MASTER, ///< [R/-] supports unicast and multicast master role at the same time, see ::PTP_CFG_CAN_BE_BOTH_MASTER
+
+ PTP_CFG_HYBRID_MASTER, ///< [R/W] supports hybrid mode in master roles
+ PTP_CFG_HYBRID_SLAVE, ///< [R/W] supports hybrid mode in slave roles
+ PTP_CFG_ONE_STEP_MASTER, ///< [R/W] supports one-step mode in master roles
+ PTP_CFG_MNGMNT_MSGS_DISB, ///< [R/W] supports disabling of PTP management messages
+ PTP_CFG_SUPP_MCAST_SLAVE_FLAG, ///< [R/-] indicates that ::PTP_CFG_CAN_BE_MULTICAST_SLAVE flag is supported and can be checked
+ PTP_CFG_CAN_BE_MULTICAST_SLAVE, ///< [R/-] if ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG bit set, indicates if multicast slave role is supported
+ PTP_CFG_ONE_STEP_L2, ///< [R/-] supports the combination of One-Step and Layer2 mode
+ PTP_CFG_ONE_STEP_P2P, ///< [R/-] supports the combination of One-Step and P2P Delay Mechanism
+
+ PTP_CFG_TSU_RESET, ///< [R/-] supports TSU reset via register cmd
+ PTP_CFG_NTP_HW_TS_MASTER, ///< [R/-] supports the NTP HW time stamping in Master mode
+ PTP_CFG_NTP_HW_TS_SLAVE, ///< [R/-] supports the NTP HW time stamping in Slave mode
+ PTP_CFG_SYNCE_MASTER, ///< [R/-] Hardware supports Synchronous Ethernet Out
+ PTP_CFG_SYNCE_SLAVE, ///< [R/-] Hardware supports Synchronous Ethernet In
+ PTP_CFG_HAS_MUX, ///< [R/-] Hardware supports multiplexed signal outputs
+
+ N_PTP_CFG_FLAGS ///< the number of defined flags
};
-#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 )
+
+/**
+ * @defgroup group_PTP_CFG_FLAG_MASKS Bit masks used with ::PTP_CFG_INFO::supp_flags and ::PTP_CFG_SETTINGS::flags
+ *
+ * @see ::PTP_CFG_FLAGS
+ *
+ * @anchor PTP_CFG_FLAG_MASKS
+ *
+ * @{ */
+
+#define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_TIME_SCALE_IS_PTP ) ///< see ::PTP_CFG_TIME_SCALE_IS_PTP
+#define PTP_CFG_MSK_V1_HW_COMPAT ( 1UL << PTP_CFG_V1_HW_COMPAT ) ///< see ::PTP_CFG_V1_HW_COMPAT
+#define PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_UNICAST_SLAVE ) ///< see ::PTP_CFG_CAN_BE_UNICAST_SLAVE
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_MULTICAST_MASTER ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_MASTER
+#define PTP_CFG_MSK_CAN_BE_UNICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_UNICAST_MASTER ) ///< see ::PTP_CFG_CAN_BE_UNICAST_MASTER
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_AUTO ( 1UL << PTP_CFG_CAN_BE_MULTICAST_AUTO ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_AUTO
+#define PTP_CFG_MSK_SUPP_UTC_VALID ( 1UL << PTP_CFG_SUPP_UTC_VALID ) ///< see ::PTP_CFG_SUPP_UTC_VALID
+#define PTP_CFG_MSK_CAN_BE_BOTH_MASTER ( 1UL << PTP_CFG_CAN_BE_BOTH_MASTER ) ///< see ::PTP_CFG_CAN_BE_BOTH_MASTER
+
+#define PTP_CFG_MSK_HYBRID_MASTER ( 1UL << PTP_CFG_HYBRID_MASTER ) ///< see ::PTP_CFG_HYBRID_MASTER
+#define PTP_CFG_MSK_HYBRID_SLAVE ( 1UL << PTP_CFG_HYBRID_SLAVE ) ///< see ::PTP_CFG_HYBRID_SLAVE
+#define PTP_CFG_MSK_ONE_STEP_MASTER ( 1UL << PTP_CFG_ONE_STEP_MASTER ) ///< see ::PTP_CFG_ONE_STEP_MASTER
+#define PTP_CFG_MSK_MNGMNT_MSGS_DISB ( 1UL << PTP_CFG_MNGMNT_MSGS_DISB ) ///< see ::PTP_CFG_MNGMNT_MSGS_DISB
+#define PTP_CFG_MSK_SUPP_MCAST_SLAVE_FLAG ( 1UL << PTP_CFG_SUPP_MCAST_SLAVE_FLAG ) ///< see ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_MULTICAST_SLAVE ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_SLAVE
+#define PTP_CFG_MSK_ONE_STEP_L2 ( 1UL << PTP_CFG_ONE_STEP_L2 ) ///< see ::PTP_CFG_ONE_STEP_L2
+#define PTP_CFG_MSK_ONE_STEP_P2P ( 1UL << PTP_CFG_ONE_STEP_P2P ) ///< see ::PTP_CFG_ONE_STEP_P2P
+
+#define PTP_CFG_MSK_TSU_RESET ( 1UL << PTP_CFG_TSU_RESET ) ///< see ::PTP_CFG_TSU_RESET
+#define PTP_CFG_MSK_NTP_HW_TS_MASTER ( 1UL << PTP_CFG_NTP_HW_TS_MASTER ) ///< see ::PTP_CFG_NTP_HW_TS_MASTER
+#define PTP_CFG_MSK_NTP_HW_TS_SLAVE ( 1UL << PTP_CFG_NTP_HW_TS_SLAVE) ///< see ::PTP_CFG_NTP_HW_TS_SLAVE
+#define PTP_CFG_MSK_SYNCE_MASTER ( 1UL << PTP_CFG_SYNCE_MASTER ) ///< see ::PTP_CFG_SYNCE_MASTER
+#define PTP_CFG_MSK_SYNCE_SLAVE ( 1UL << PTP_CFG_SYNCE_SLAVE ) ///< see ::PTP_CFG_SYNCE_SLAVE
+#define PTP_CFG_MSK_HAS_MUX ( 1UL << PTP_CFG_HAS_MUX ) ///< see ::PTP_CFG_HAS_MUX
+
+/** @} defgroup group_PTP_CFG_FLAG_MASKS */
+
+
+
+/** @brief A bit mask of the unicast role bits within the flag bits */
+#define PTP_CFG_MSK_SUPPORT_PTP_UNICAST ( PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE | \
+ PTP_CFG_MSK_CAN_BE_UNICAST_MASTER )
+
+
+
+/**
+ * @brief Register in TSU-GbE FPGA to determine board features of the current TSU board revision
+ */
+typedef uint16_t PTP_HW_FEATURES;
+
+
+
+/**
+ * @brief Bits used to define ::PTP_HW_FEAT_MASKS
+ */
+enum PTP_HW_FEAT_BITS
+{
+ PTP_FEAT_SYNCE_EXT_MUX, ///< [R] supports SyncE and external signal multiplexer
+ N_PTP_HW_FEAT ///< the number of defined features
+};
+
+
+// TODO fix comment linkage
+/**
+ * @brief Bit masks used with ::PTP_HW_FEATURES
+ *
+ * @see ::PTP_HW_FEAT_BITS
+ */
+enum PTP_HW_FEAT_MASKS
+{
+ PTP_HW_FEAT_MSK_SYNCE_EXT_MUX = ( 1UL << PTP_FEAT_SYNCE_EXT_MUX ) ///< see ::PTP_FEAT_SYNCE_EXT_MUX
+};
+
+
+
+/**
+ * @brief Known optional PTP protocol extensions, see ::PTP_CFG_SETTINGS::opt_ext
+ *
+ * @see ::PTP_OPT_EXT_MASKS
+ */
+enum PTP_OPT_EXTS
+{
+ PTP_OPT_EXT_NONE, ///< no extension used
+ PTP_OPT_EXT_POWER, ///< IEEE C37.238 profile extension
+ PTP_OPT_EXT_TELECOM, ///< ITU-T G.8265.1 profile extension
+ PTP_OPT_EXT_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension
+ PTP_OPT_EXT_SMPTE, ///< SMPTE ST 2059-2 profile extension
+ N_PTP_OPT_EXT ///< number of known optional extensions
+};
+
+
+/**
+ * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext
+ *
+ * @see ::PTP_OPT_EXTS
+ */
+enum PTP_OPT_EXT_MASKS
+{
+ PTP_MSK_OPT_EXT_NONE = ( 1UL << PTP_OPT_EXT_NONE ), ///< this is actually not used, see ::PTP_OPT_EXT_NONE
+ PTP_MSK_OPT_EXT_POWER = ( 1UL << PTP_OPT_EXT_POWER ), ///< see ::PTP_OPT_EXT_POWER
+ PTP_MSK_OPT_EXT_TELECOM = ( 1UL << PTP_OPT_EXT_TELECOM ), ///< see ::PTP_OPT_EXT_TELECOM
+ PTP_MSK_OPT_EXT_TELECOM_PHASE = ( 1UL << PTP_OPT_EXT_TELECOM_PHASE ), ///< see ::PTP_OPT_EXT_TELECOM_PHASE
+ PTP_MSK_OPT_EXT_SMPTE = ( 1UL << PTP_OPT_EXT_SMPTE ) ///< see ::PTP_OPT_EXT_SMPTE
+};
+
+
+
+/**
+ * @brief Enumeration of PTP cfg presets used with ::PTP_CFG_SETTINGS::selected_presets
+ *
+ * This can be used by configuration programs to determine
+ * the last recently selected presets.
+ *
+ * @see ::PTP_PRESETS_STRS
+ * @see ::PTP_PRESETS_MASKS
+ */
+enum PTP_PRESETS
+{
+ PTP_PRESETS_CUSTOM, ///< customizable, always supported
+ PTP_PRESETS_DFLT_E2E, ///< pure IEEE1588-2008 (PTPv2) with E2E
+ PTP_PRESETS_DFLT_P2P, ///< pure IEEE1588-2008 (PTPv2) with P2P
+ PTP_PRESETS_POWER, ///< IEEE C37.238 profile extension, only if ::PTP_MSK_OPT_EXT_POWER is set
+ PTP_PRESETS_TELECOM, ///< ITU-T G.8265.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM is set
+ PTP_PRESETS_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set
+ PTP_PRESETS_SMPTE, ///< SMPTE ST 2059-2 profile extension, only if ::PTP_MSK_OPT_EXT_SMPTE is set
+ N_PTP_PRESETS ///< number of supported presets
+};
+
+
+/**
+ * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext
+ *
+ * @see ::PTP_PRESETS
+ */
+enum PTP_PRESETS_MASKS
+{
+ PTP_MSK_PRESETS_CUSTOM = ( 1UL << PTP_PRESETS_CUSTOM ), ///< see ::PTP_PRESETS_CUSTOM
+ PTP_MSK_PRESETS_DFLT_E2E = ( 1UL << PTP_PRESETS_DFLT_E2E ), ///< see ::PTP_PRESETS_DFLT_E2E
+ PTP_MSK_PRESETS_DFLT_P2P = ( 1UL << PTP_PRESETS_DFLT_P2P ), ///< see ::PTP_PRESETS_DFLT_P2P
+ PTP_MSK_PRESETS_POWER = ( 1UL << PTP_PRESETS_POWER ), ///< see ::PTP_PRESETS_POWER
+ PTP_MSK_PRESETS_TELECOM = ( 1UL << PTP_PRESETS_TELECOM ), ///< see ::PTP_PRESETS_TELECOM
+ PTP_MSK_PRESETS_TELECOM_PHASE = ( 1UL << PTP_PRESETS_TELECOM_PHASE ), ///< see ::PTP_PRESETS_TELECOM_PHASE
+ PTP_MSK_PRESETS_SMPTE = ( 1UL << PTP_PRESETS_SMPTE ) ///< see ::PTP_PRESETS_SMPTE
+};
+
+
+/**
+ * @brief Name strings for defined PTP presets
+ *
+ * @see ::PTP_PRESETS
+ */
+#define PTP_PRESETS_STRS \
+{ \
+ "Custom", \
+ "Default E2E IEEE1588-2008", \
+ "Default P2P IEEE1588-2008", \
+ "Power IEEE C37.238", \
+ "Telecom ITU-T G.8265.1", \
+ "Telecom ITU-T G.8275.1", \
+ "SMPTE ST 2059-2" \
+}
+
+
+
+/**
+ * @brief Additional parameters for Power Profile
+ */
+#define PTP_POWER_PROFILE_GM_ID_MIN 3
+#define PTP_POWER_PROFILE_GM_ID_MAX 255
+
+typedef struct
+{
+ uint32_t network_incaccuracy; ///< Pre-defined network inaccuracy from master in [ns]
+ uint8_t grandmaster_id; ///< [::PTP_POWER_PROFILE_GM_ID_MIN..::PTP_POWER_PROFILE_GM_ID_MAX]
+ uint8_t reserved_1;
+ uint16_t reserved_2;
+ TZDL tzdl;
+
+} PTP_POWER_PROFILE_CFG;
+
+#define _mbg_swab_ptp_power_profile_cfg( _p ) \
+{ \
+ _mbg_swab32( &(_p)->network_incaccuracy ); \
+ _mbg_swab8( &(_p)->grandmaster_id ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab_tzdl( &(_p)->tzdl ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+
+#if 1 // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+// TODO: These definitions are preliminary and maybe subject to changes.
+
+
+/**
+ * @brief SMPTE System Frame Rates according to SMPTE ST 2059-2
+ *
+ * @see ::XXX
+ */
+enum SMPTE_SYSTEM_FRAME_RATES
+{
+ SMPTE_23_98HZ,
+ SMPTE_24HZ,
+ SMPTE_25HZ,
+ SMPTE_29_97HZ,
+ SMPTE_50HZ,
+ SMPTE_59_94HZ,
+ N_SMPTE_SYSTEM_FRAME_RATES
+};
+
+
+#define SMPTE_SYSTEM_FRAME_RATE_STR \
+{ \
+ "24Hz (23.98)", \
+ "24Hz", \
+ "25Hz", \
+ "30Hz (29.97)", \
+ "50Hz", \
+ "60Hz (59.94)" \
+}
+
+
+#define SMPTE_FRAME_RATE_NUM \
+{ \
+ 24000, \
+ 24000, \
+ 25000, \
+ 30000, \
+ 50000, \
+ 60000, \
+}
+
+#define SMPTE_FRAME_RATE_DENUM \
+{ \
+ 1001, \
+ 1000, \
+ 1000, \
+ 1001, \
+ 1000, \
+ 1001, \
+}
+
+
+/**
+ * @brief Additional parameters for SMPTE ST 2059-2 profile
+ *
+ * This stucture holds the synchronization metadata required for the SMPTE profile.
+ * This structure is only used for internal storage of the data. The data is
+ * distributed through a network by using management messages and the dedicated
+ * organization extension TLV defined in the SMPTE profile.
+ */
+typedef struct
+{
+ /// Default system frame rate
+ /// Default video frame rate of the slave system as a lowest term rational.
+ /// The data type shall be composed of a pair of unsigned Int32 values coded
+ /// in big-endian form where the first shall be the numerator and the second
+ /// shall be the denominator. The denominator shall be the smallest value
+ /// that represents the frame rate denominator.
+ /// For example, 29.97 Hz: (30000/1001) or 25 Hz: (25/1).
+ uint32_t defaultSystemFrameRateNum;
+ uint32_t defaultSystemFrameRateDenum;
+
+ /// Master locking status
+ /// Complementary information to clockClass (0: Not in use, 1: Free Run,
+ /// 2: Cold Locking, 3: Warm Locking, 4: Locked)
+ uint8_t masterLockingStatus;
+
+ /// Time Address Flags
+ /// Indicates the intended ST 12-1 flags.
+ /// Bit 0: Drop frame (0: Non-drop-frame, 1: Drop-frame)
+ /// Bit 1: Color Frame Identification (0: Not in use, 1: In use)
+ /// Bits 2-7: Reserved
+ uint8_t timeAddressFlags;
+
+ /// Current local offset
+ /// Offset in seconds of Local Time from PTP time. For example, if Local
+ /// Time is Eastern Standard Time (North America) UTC-5 and the number of
+ /// leap seconds is 35, the value will be -18035 (decimal).
+ int32_t currentLocalOffset;
+
+ /// Jump seconds
+ /// The size of the next discontinuity, in seconds, of Local Time. A value
+ /// of zero indicates that no discontinuity is expected. A positive value
+ /// indicates that the discontinuity will cause the currentLocalOffset to increase.
+ int32_t jumpSeconds;
+
+ /// Time of next jump
+ /// The value of the seconds portion of the master PTP time at the time
+ /// that the next discontinuity of the currentLocalOffset will occur. The
+ /// discontinuity occurs at the start of the second indicated
+ uint8_t timeOfNextJump[6];
+
+ /// Daily jam
+ /// Daily point in Local Time (in ten-minute intervals since midnight) for
+ /// jamming ST 12-1 time address to Local Time. 255: Daily jam not in use
+ /// 1-143: Daily Jam Time offset since midnight in number of ten-minute
+ /// intervals since midnight. A value 0 indicated midnight; 143 indicates
+ /// ten minutes to next midnight. 144 and 254: Reserved
+ uint8_t dailyJamTime;
+
+ /// Previous daily jam
+ /// Point in Local Time (in ten-minute intervals since midnight) of previous
+ /// jam of ST 12-1 time address to Local Time. This item shall be updated in
+ /// the message immediately following a jam event. Value definition as daily
+ /// Jam Time
+ uint8_t previousDailyJamTime;
+
+ /// Previous jam local offset
+ /// The value of currentLocalOffset at the previous daily jam time.
+ /// If a discontinuity of Local Time occurs at the jam time, this parameter
+ /// reflects the offset after the discontinuity
+ int32_t previousJamLocalOffset;
+
+ /// Daylight saving
+ /// Bit 0: Current Daylight Saving (0: Not in effect, 1: In effect)
+ /// Bit 1: Daylight Saving at next discontinuity (0: Not in effect, 1: In effect)
+ /// Bit 2: Daylight Saving at previous daily jam time (0: Not in effect, 1: In effect)
+ /// Bits 3-7: Reserved
+ uint8_t daylightSaving;
+
+} PTP_SMPTE_PROFILE_CFG;
+
+
+
+/**
+ * @brief Additional parameters for Telecom8275.1 profile
+ */
+typedef struct
+{
+ uint8_t use_alternate_multicast_address;
+
+} PTP_TELECOMG8275_PROFILE_CFG;
+
+#define _mbg_swab_ptp_telecom8275_profile_cfg( _p ) \
+{ \
+ _mbg_swab8( &(_p)->use_alternate_multicast_mac_address ); \
+}
+
+
+
+/**
+ * @brief A type which holds one of the ITU-T SSM codes
+ *
+ * @see ::ITU_SSM_CODES
+ */
+typedef uint16_t ITU_SSM_CODE;
+
+
+
+/**
+ * @brief ITU-T SSM codes acc. to Recommendation G.781
+ *
+ * @see ::ITU_SSM_CODE
+ */
+enum ITU_SSM_CODES
+{
+ ITU_SSM_CODE_STU_UKN,
+ ITU_SSM_CODE_PRS,
+ ITU_SSM_CODE_PRC,
+ ITU_SSM_CODE_INV3,
+ ITU_SSM_CODE_SSU_A_TNC,
+ ITU_SSM_CODE_INV5,
+ ITU_SSM_CODE_INV6,
+ ITU_SSM_CODE_ST2,
+ ITU_SSM_CODE_SSU_B,
+ ITU_SSM_CODE_INV9,
+ ITU_SSM_CODE_ST3,
+ ITU_SSM_CODE_SEC,
+ ITU_SSM_CODE_SMC,
+ ITU_SSM_CODE_ST3E,
+ ITU_SSM_CODE_PROV,
+ ITU_SSM_CODE_DNU_DUS,
+ N_ITU_SSM_CODES
+};
+
+
+#define N_SSM_CODES_OPTION_1 5
+#define N_SSM_CODES_OPTION_2 9
+
+
+/**
+ * @brief Name strings for SSM codes, network option I
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_OPT_1_STRS \
+{ \
+ "", \
+ "", \
+ "QL-PRC", \
+ "", \
+ "QL-SSU-A", \
+ "", \
+ "", \
+ "", \
+ "QL-SSU-B", \
+ "", \
+ "", \
+ "QL-SEC", \
+ "", \
+ "", \
+ "", \
+ "QL-DNU" \
+}
+
+
+
+/**
+ * @brief Name strings for SSM codes, network option II
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_OPT_2_STRS \
+{ \
+ "QL-STU", \
+ "QL-PRS", \
+ "", \
+ "", \
+ "QL-TNC", \
+ "", \
+ "", \
+ "QL-ST2", \
+ "", \
+ "", \
+ "QL-ST3", \
+ "", \
+ "QL-SMC", \
+ "QL-ST3E", \
+ "QL-PROV", \
+ "QL-DUS" \
+}
+
+
+
+/**
+ * @brief Name strings for SSM codes, option I and II combined
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_STRS_COMBINED \
+{ \
+ "QL-STU/UKN", \
+ "QL-PRS", \
+ "QL-PRC", \
+ "QL-INV3", \
+ "QL-SSU-A/TNC", \
+ "QL-INV5", \
+ "QL-INV6", \
+ "QL-ST2", \
+ "QL-SSU-B", \
+ "QL-INV9", \
+ "QL-EEC2/ST3", \
+ "QL-EEC1/SEC", \
+ "QL-SMC", \
+ "QL-ST3E", \
+ "QL-PROV", \
+ "QL-DNU/DUS", \
+}
+
+
+/**
+ * @brief SDH network options
+ *
+ * @see ::SDH_NETWORK_OPTION_MASKS
+ */
+enum SDH_NETWORK_OPTION
+{
+ SDH_NETWORK_OPTION_1,
+ SDH_NETWORK_OPTION_2,
+ N_SDH_NETWORK_OPTIONS
+
+};
+
+
+
+/**
+ * @brief Flag masks used with ::MBG_SYNC_E_INFO::supp_sdh_network_opts
+ *
+ * @see ::SDH_NETWORK_OPTION
+ */
+enum SDH_NETWORK_OPTION_MASKS
+{
+ SDH_NETWORK_OPTION_1_MSK = ( 1UL << SDH_NETWORK_OPTION_1 ), ///< see ::SDH_NETWORK_OPTION_1_MSK
+ SDH_NETWORK_OPTION_2_MSK = ( 1UL << SDH_NETWORK_OPTION_2 ), ///< see ::SDH_NETWORK_OPTION_2_MSK
+};
+
+
+
+/**
+ * @brief Name strings for SDH network options
+ *
+ * @see ::SDH_NETWORK_OPTION
+ */
+#define SDH_NETWORK_OPTION_STRS \
+{ \
+ "SDH Network Opt. 1", \
+ "SDH Network Opt. 2", \
+}
+
+
+
+//##++++ TODO: shouldn't this be merged with / replaced by MBG_NET_LINK_MODES?
+/**
+ * @brief Link modes for SyncE on a 1000BASE-T interface
+ *
+ * @see ::GBIT_LINK_COPPER_MODE_MASKS
+ */
+enum GBIT_LINK_COPPER_MODE
+{
+ GBIT_LINK_COPPER_AUTO, // valid if synce is disabled
+ GBIT_LINK_COPPER_FORCE_SYNCE_AUTO,
+ GBIT_LINK_COPPER_FORCE_OR_IS_MASTER, // Used in both structures, settings and status
+ GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE, // Used in both structures, settings and status
+ GBIT_LINK_COPPER_PREFER_MASTER,
+ GBIT_LINK_COPPER_PREFER_SLAVE,
+ N_GBIT_LINK_COPPER_MODES
+};
+
+
+
+/**
+ * @brief Flag masks used with ::MBG_SYNC_E_INFO::supp_gbit_link_copper_modes
+ *
+ * @see ::GBIT_LINK_COPPER_MODE
+ */
+enum GBIT_LINK_COPPER_MODE_MASKS
+{
+ GBIT_LINK_COPPER_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_AUTO ), ///< see ::GBIT_LINK_COPPER_AUTO_MSK
+ GBIT_LINK_COPPER_FORCE_SYNCE_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_SYNCE_AUTO ), ///< see ::GBIT_LINK_COPPER_FORCE_SYNCE_AUTO
+ GBIT_LINK_COPPER_FORCE_OR_IS_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_MASTER ), ///< see ::GBIT_LINK_COPPER_FORCE_OR_IS_MASTER
+ GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE ), ///< see ::GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE
+ GBIT_LINK_COPPER_PREFER_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_MASTER ), ///< see ::GBIT_LINK_COPPER_PREFER_MASTER
+ GBIT_LINK_COPPER_PREFER_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_SLAVE ) ///< see ::GBIT_LINK_COPPER_PREFER_SLAVE
+};
+
+
+
+//##++++ TODO: shouldn't this be merged with MBG_NET_LINK_ROLE_BITS / MBG_NET_LINK_ROLE_MASKS?
+/**
+ * @brief Link status for SyncE on a 1000BASE-T interface
+ *
+ * @see ::XXX
+ */
+enum GBIT_LINK_STATUS
+{
+ GBIT_LINK_COPPER_IS_MASTER, ///< GBIT Link is currently clock master
+ GBIT_LINK_COPPER_IS_SLAVE, ///< GBIT Link is currently clock slave
+ GBIT_LINK_COPPER_CFG_FAULT, ///< GBIT Link has a configruation fault (conflict with link partner
+ GBIT_LINK_COPPER_IS_FE, ///< Link is running on Fast Ethernet (no MASTER/SLAVE decision)
+ GBIT_LINK_DOWN, ///< Currently no link
+ GBIT_LINK_FIBER, ///< GBIT Linkup on SFP interface
+ N_GBIT_LINK_STATUS
+};
+
+
+#define GBIT_LINK_STATUS_STRS \
+{ \
+ "MASTER (1000BASE-T)", \
+ "SLAVE (1000BASE-T)", \
+ "CFG FAULT", \
+ "AUTO (100BASE-TX)", \
+ "LINK DOWN", \
+ "AUTO (SFP LINK UP)", \
+}
+
+
+/**
+ * @brief Bits used to define ::MBG_SYNCE_FLAG_MASKS
+ */
+enum MBG_SYNCE_FLAGS
+{
+ SYNCE_FLAG_ACTIVE_SYNC_MASTER,
+ N_SYNCE_FLAGS // number of defined bits
+};
+
+
+
+/**
+ * @brief Flag masks used with ::MBG_SYNC_E_SETTINGS::flags
+ *
+ * @see ::MBG_SYNCE_FLAGS
+ */
+enum MBG_SYNCE_FLAG_MASKS
+{
+ SYNCE_FLAG_ACTIVE_SYNC_MASTER_MSK = ( 1UL << SYNCE_FLAG_ACTIVE_SYNC_MASTER ) ///< see ::SYNCE_FLAG_ACTIVE_SYNC_MASTER
+};
+
+
+
+/**
+ * @brief Settings for a Synchronous Ethernet interface
+ *
+ * @see ::XXX
+ */
+typedef struct
+{
+ uint8_t synce_enabled; ///< SyncE is activated for the specific interface
+ uint8_t ql_selection_enabled; ///< Quality Level is determined automatically
+ uint8_t sdh_network_option; ///< see ::SDH_NETWORK_OPTION
+ uint8_t local_priority; ///< user defined priority value for selected port
+ uint8_t local_network_sync_level_ssm; ///< automatically assigend quality level for SyncE output
+ uint8_t fixed_output_ssm; ///< Fixed SSM output override
+ uint8_t fixed_input_ssm; ///< Assumed SSM value for SyncE Input (0xFF if taken from network)
+ uint8_t gbit_link_copper_mode; ///< see ::GBIT_LINK_COPPER_MODE
+ uint8_t reserved_1;
+ uint8_t reserved_2;
+ uint32_t reserved_3;
+ uint32_t flags; ///< see ::MBG_SYNCE_FLAG_MASKS
+
+} MBG_SYNC_E_SETTINGS;
+
+
+
+typedef struct
+{
+ MBG_SYNC_E_SETTINGS settings;
+ uint32_t supp_sdh_network_opts;
+ uint32_t supp_gbit_link_copper_modes;
+ uint32_t supp_flags;
+ uint32_t reserved;
+
+} MBG_SYNC_E_INFO;
+
+
+
+typedef struct
+{
+ uint8_t synce_enabled;
+ uint8_t output_ssm;
+ uint8_t input_ssm;
+ uint8_t gbit_link_status; ///< see ::GBIT_LINK_STATUS
+ uint8_t reserved_1;
+ uint8_t reserved_2;
+ uint32_t reserved_3;
+ uint32_t flags; ///< MBG_SYNCE_FLAG_MASKS
+
+} MBG_SYNC_E_STATUS;
+
+#endif // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+
+/**
+ * @brief Limits to be considered when specifying PTP unicast masters
+ */
+typedef struct
+{
+ uint16_t n_supp_master; ///< number of unicast masters which can be specified
+ int16_t sync_intv_min; ///< log2 of minimum sync interval [s]
+ int16_t sync_intv_max; ///< log2 of maximum sync interval [s]
+ int16_t ann_intv_min; ///< log2 of minimum announce interval [s]
+ int16_t ann_intv_max; ///< log2 of maximum announce interval [s]
+ int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s]
+ int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s]
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< a bit mask indicating which flags are supported
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} PTP_UC_MASTER_CFG_LIMITS;
+
+#define _mbg_swab_ptp_uc_master_cfg_limits( _p ) \
+{ \
+ _mbg_swab16( &(_p)->n_supp_master ); \
+ _mbg_swab16( &(_p)->sync_intv_min ); \
+ _mbg_swab16( &(_p)->sync_intv_max ); \
+ _mbg_swab16( &(_p)->ann_intv_min ); \
+ _mbg_swab16( &(_p)->ann_intv_max ); \
+ _mbg_swab16( &(_p)->delay_req_intv_min ); \
+ _mbg_swab16( &(_p)->delay_req_intv_max ); \
+ _mbg_swab16( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+}
+
+
+/**
+ * @brief Configuration settings specifiying how to query a PTP unicast master
+ *
+ * This structure is used on a unicast slave to specify the settings of
+ * a unicast master polled by the slave. The number of unicast masters
+ * which can be specified depends on the capabilities of the slave device
+ * and is returned in ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master.
+ *
+ * The structure ::PTP_UC_MASTER_SETTINGS_IDX should be sent to the device
+ * to save the configuration.
+ */
+typedef struct
+{
+ MBG_HOSTNAME gm_host; ///< grandmaster's hostname or IP address
+ PTP_CLOCK_ID gm_clock_id; ///< use clock ID of master port, or ::PTP_CLOCK_ID_WILDCARD
+ PTP_PORT_ID gm_port_id; ///< use target port ID of master port (e.g. 135) or ::PTP_PORT_ID_WILDCARD
+ int16_t sync_intv; ///< sync interval [log2 s]
+ int16_t ann_intv; ///< announce interval [log2 s]
+ int16_t delay_req_intv; ///< delay request interval [log2 s]
+ int32_t fix_offset; ///< constant time offset to be compensated [ns]
+ uint16_t message_duration; ///< time period until master stops sending messages [s]
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} PTP_UC_MASTER_SETTINGS;
+
+#define _mbg_swab_ptp_uc_master_settings( _p ) \
+{ \
+ _mbg_swab_ptp_clock_id( &(_p)->gm_clock_id ); \
+ _mbg_swab_ptp_port_id( &(_p)->gm_port_id ); \
+ _mbg_swab16( &(_p)->sync_intv ); \
+ _mbg_swab16( &(_p)->ann_intv ); \
+ _mbg_swab16( &(_p)->delay_req_intv ); \
+ _mbg_swab32( &(_p)->fix_offset ); \
+ _mbg_swab16( &(_p)->message_duration ); \
+ _mbg_swab16( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Unicast PTP master message duration limits
+ *
+ * Each unicast PTP master sends messages to a unicast slave only
+ * for a given interval as requested by the particular slave, which
+ * is called message duration.
+ * These symbols define the minimum and maximum message duration
+ * configured on a slave for a specific unicast master, i.e. for
+ * PTP_UC_MASTER_SETTINGS::message_duration. The values are defined
+ * in the PTP v2 standard.
+ */
+enum PTP_UC_MSG_DURATION_LIMITS
+{
+ PTP_UC_MSG_DURATION_MIN = 10, ///< minimum message duration [s]
+ PTP_UC_MSG_DURATION_MAX = 1000 ///< maximum message duration [s]
+};
+
+
+
+/**
+ * @brief Configuration settings for a specific PTP unicast master
+ */
+typedef struct
+{
+ uint32_t idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1
+ PTP_UC_MASTER_SETTINGS settings; ///< specification for the unicast master with that index
+
+} PTP_UC_MASTER_SETTINGS_IDX;
+
+#define _mbg_swab_ptp_uc_master_settings_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \
+}
+
+
+/**
+ * @brief Current settings and general capabilities of a unicast master
+ *
+ * This structure is used with a PTP unicast slave device to specify
+ * a PTP unicast master which can be queried by the slave device.
+ */
+typedef struct
+{
+ PTP_UC_MASTER_SETTINGS settings; ///< current settings
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} PTP_UC_MASTER_INFO;
+
+#define _mbg_swab_ptp_uc_master_info( _p ) \
+{ \
+ _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Current settings and general capabilities of a specific unicast master
+ *
+ * This structure is used with a PTP unicast slave device to specify
+ * a PTP unicast master which can be queried by the slave device.
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings and capabilities. The number of supported
+ * configuration records is PTP_UC_MASTER_CFG_LIMITS::n_supp_master.
+ *
+ * @note The ::PTP_UC_MASTER_SETTINGS_IDX structure should be send back
+ * to the device to save the configuration.
+ */
+typedef struct
+{
+ uint32_t idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1
+ PTP_UC_MASTER_INFO info; ///< capabilities and current settings
+
+} PTP_UC_MASTER_INFO_IDX;
+
+#define _mbg_swab_ptp_uc_master_info_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ptp_uc_master_info( &(_p)->info ); \
+}
+
+/** @} defgroup group_ptp */
+
+
+
+/**
+ * @defgroup group_ntp Definitions used with NTP
+ *
+ * @{ */
+
+
+/**
+ * @brief Enumeration of known NTP roles
+ *
+ * @see ::NTP_GLB_SETTINGS::ntp_role
+ */
+enum NTP_ROLES
+{
+ NTP_ROLE_NONE = 0, ///< NTP services disabled
+ NTP_ROLE_CLIENT, ///< NTP client
+ NTP_ROLE_SERVER, ///< NTP server
+ NTP_ROLE_CLIENT_SERVER, ///< both NTP client and server
+ N_NTP_ROLES ///< number of supported roles
+};
+
+
+/**
+ * @brief Flag masks associated with NTP roles
+ *
+ * @see ::NTP_GLB_INFO::supp_ntp_roles
+ */
+enum NTP_ROLE_MASKS
+{
+ NTP_MSK_ROLE_NONE = ( 1UL << NTP_ROLE_NONE ), ///< see ::NTP_ROLE_NONE
+ NTP_MSK_ROLE_CLIENT = ( 1UL << NTP_ROLE_CLIENT ), ///< see ::NTP_ROLE_CLIENT
+ NTP_MSK_ROLE_SERVER = ( 1UL << NTP_ROLE_SERVER ), ///< see ::NTP_ROLE_SERVER
+ NTP_MSK_ROLE_CLIENT_SERVER = ( 1UL << NTP_ROLE_CLIENT_SERVER ), ///< see ::NTP_ROLE_CLIENT_SERVER
+};
+
+
+/**
+ * @brief Enumeration of global NTP flags
+ *
+ * @see ::NTP_FLAG_MASKS
+ */
+enum NTP_FLAGS
+{
+ NTP_IPV4, ///< NTP via IPv4/UDP
+ NTP_IPV6, ///< NTP via IPv6/UDP
+ NTP_SYMM_KEYS, ///< support symmetric key authentication (MD5)
+ NTP_AUTOKEY, ///< include authentication fields encrypted using the autokey scheme
+ NTP_BURST, ///< send a burst of eight packets at each polling cycle
+ NTP_IBURST, ///< send a burst of eight packets at the first polling cycle
+ NTP_NO_SELECT, ///< marks a server as not to be selected for time synchronization
+ NTP_PREEMPT, ///< specifies the association as preemptable rather than the default persistent
+ NTP_PREFER, ///< marks a server as preferred peer for time synchronization
+ NTP_TRUE, ///< force the association to assume truechimer status; always survive the selection and clustering algorithms
+ NTP_BROADCAST, ///< transmission via broadcast, point to multipoint
+ NTP_MULTICAST, ///< transmission via multicast, point to multipoint
+ NTP_MANYCAST, ///< transmission via manycast, point to multipoint
+ NTP_POOL, ///< peer shall be treated as a pool server
+ N_NTP_FLAGS
+};
+
+
+/**
+ * @brief Flag masks associated with ::NTP_FLAGS
+ *
+ * Used with ::NTP_GLB_INFO::supp_flags, ::NTP_GLB_SETTINGS::flags, NTP_CLNT_MODE_INFO::supp_flags,
+ * ::NTP_CLNT_MODE_INFO::supp_peer_flags, ::NTP_CLNT_MODE_SETTINGS::flags, ::NTP_PEER_SETTINGS::flags,
+ * ::NTP_SRV_MODE_SETTINGS::flags, and ::NTP_SRV_MODE_INFO::supp_flags.
+ *
+ * @todo We may need structures to configure symmetric keys, and autokey certificates.
+ *
+ * @see ::NTP_FLAGS
+ */
+enum NTP_FLAG_MASKS
+{
+ NTP_MSK_IPV4 = ( 1UL << NTP_IPV4 ), ///< see ::NTP_IPV4
+ NTP_MSK_IPV6 = ( 1UL << NTP_IPV6 ), ///< see ::NTP_IPV6
+ NTP_MSK_SYMM_KEYS = ( 1UL << NTP_SYMM_KEYS ), ///< see ::NTP_SYMM_KEYS
+ NTP_MSK_AUTOKEY = ( 1UL << NTP_AUTOKEY ), ///< see ::NTP_AUTOKEY
+ NTP_MSK_BURST = ( 1UL << NTP_BURST ), ///< see ::NTP_BURST
+ NTP_MSK_IBURST = ( 1UL << NTP_IBURST ), ///< see ::NTP_IBURST
+ NTP_MSK_NO_SELECT = ( 1UL << NTP_NO_SELECT ), ///< see ::NTP_NO_SELECT
+ NTP_MSK_PREEMPT = ( 1UL << NTP_PREEMPT ), ///< see ::NTP_PREEMPT
+ NTP_MSK_PREFER = ( 1UL << NTP_PREFER ), ///< see ::NTP_PREFER
+ NTP_MSK_TRUE = ( 1UL << NTP_TRUE ), ///< see ::NTP_TRUE
+ NTP_MSK_BROADCAST = ( 1UL << NTP_BROADCAST ), ///< see ::NTP_BROADCAST
+ NTP_MSK_MULTICAST = ( 1UL << NTP_MULTICAST ), ///< see ::NTP_MULTICAST
+ NTP_MSK_MANYCAST = ( 1UL << NTP_MANYCAST ), ///< see ::NTP_MANYCAST
+ NTP_MSK_POOL = ( 1UL << NTP_POOL ) ///< see ::NTP_POOL
+};
+
+
+/**
+ * @brief Global configuration settings of an NTP device (client/server)
+ *
+ * This structure should be sent to an NTP device to configure global settings
+ */
+typedef struct
+{
+ uint8_t ntp_role; ///< one of the supported NTP roles, see ::NTP_ROLES
+ uint8_t reserved_1; ///< reserved, currently 0
+ uint16_t reserved_2; ///< reserved, currently 0
+
+ uint32_t reserved_3; ///< reserved, currently 0
+ uint32_t reserved_4; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS
+
+} NTP_GLB_SETTINGS;
+
+#define _mbg_swab_ntp_glb_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief Global configuration info of an NTP device (client/server)
+ *
+ * This structure can be used to determine possible configurations of an NTP device
+ */
+typedef struct
+{
+ NTP_GLB_SETTINGS settings; ///< current configuration settings
+
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t supp_ntp_roles; ///< supported NTP roles, see ::NTP_ROLE_MASKS
+ uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS
+
+} NTP_GLB_INFO;
+
+#define _mbg_swab_ntp_glb_info( _p ) \
+{ \
+ _mbg_swab_ntp_glb_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->supp_ntp_roles ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+}
+
+
+/**
+ * @brief Client settings of an NTP device
+ *
+ * This structure should be sent to an NTP client to configure client parameters
+ */
+typedef struct
+{
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS
+
+} NTP_CLNT_MODE_SETTINGS;
+
+#define _mbg_swab_ntp_clnt_mode_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Client settings info of an NTP device
+ *
+ * This structure can be used to determine possible NTP client settings and the current configuration
+ */
+typedef struct
+{
+ NTP_CLNT_MODE_SETTINGS settings;
+
+ uint8_t n_supp_peers; ///< maximal number of configurable peers
+ uint8_t n_supp_pref_peers; ///< maximal number of configurable preferred ref sources
+ uint8_t poll_intv_min; ///< minimal supported NTP polling interval
+ uint8_t poll_intv_max; ///< maximal supported NTP polling interval
+
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS
+ uint32_t supp_peer_flags; ///< supported NTP flags for peers, see ::NTP_FLAG_MASKS
+
+} NTP_CLNT_MODE_INFO;
+
+#define _mbg_swab_ntp_clnt_mode_info( _p ) \
+{ \
+ _mbg_swab_ntp_clnt_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_peer_flags ); \
+}
+
+
+/**
+ * @brief Peer settings for NTP devices to configure an upload NTP server
+ *
+ * This structure should be read from the NTP client device to retrieve the
+ * current settings and capabilities. The number of supported peers is
+ * ::NTP_CLNT_MODE_INFO::n_supp_peers.
+ *
+ * @note The ::NTP_PEER_SETTINGS_IDX structure should be send back
+ * to the device to save the configuration.
+ */
+typedef struct
+{
+ MBG_HOSTNAME hostname; ///< hostname or IP address of the peer
+
+ uint8_t min_poll; ///< minimal configurable NTP polling interval
+ uint8_t max_poll; ///< maximal configurable NTP polling interval
+ uint8_t ttl; ///< time-to-live to use with broadcast/multicast/manycast
+ uint8_t reserved_1; ///< reserved, currently 0
+
+ uint32_t reserved_2; ///< reserved, currently 0
+ uint32_t reserved_3; ///< reserved, currently 0
+ uint32_t reserved_4; ///< reserved, currently 0
+
+ uint32_t flags; ///< additional options configured, see ::NTP_FLAG_MASKS
+
+} NTP_PEER_SETTINGS;
+
+#define _mbg_swab_ntp_peer_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+/**
+ * @brief Peer settings for NTP devices
+ *
+ * @see ::NTP_PEER_SETTINGS
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_PEER_SETTINGS peer_settings;
+
+} NTP_PEER_SETTINGS_IDX;
+
+#define _mbg_swab_ntp_peer_settings_idx( _p ) \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_peer_settings( &(_p)->peer_settings ); \
+}
+
+#ifdef DEBUG
+/**
+ * @brief Dummy structure for later NTP server implementations, not used, yet
+ */
+typedef struct
+{
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS
+
+} NTP_SRV_MODE_SETTINGS;
+
+#define _mbg_swab_ntp_srv_mode_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Dummy structure for later NTP server implementations
+ */
+typedef struct
+{
+ NTP_SRV_MODE_SETTINGS settings;
+
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS
+
+} NTP_SRV_MODE_INFO;
+
+#define _mbg_swab_ntp_srv_mode_info( _p ) \
+{ \
+ _mbg_swab_ntp_srv_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+}
+#endif // DEBUG
+
+
+/**
+ * @brief Structure that represents a timestamp in NTP Short Format
+ *
+ * Maximal value for seconds is 65535.
+ * Resolution of fractions is 15 microseconds.
+ */
+typedef struct
+{
+ uint16_t seconds;
+ uint16_t fractions;
+
+} NTP_SHORT_TSTAMP;
+
+#define _mbg_swab_ntp_short_tstamp( _p ) \
+{ \
+ _mbg_swab16( &(_p)->seconds ); \
+ _mbg_swab16( &(_p)->fractions ); \
+}
+
+
+/**
+ * @brief Structure that represents a timestamp in NTP Timestamp Format
+ */
+typedef struct
+{
+ uint32_t seconds; ///< seconds since NTP epoch, see ::NTP_SEC_BIAS
+ uint32_t fractions; ///< binary fractional part of a second, 0xFFFFFFFF -> 0.9999999... s (resolution 2^-32s =~ 233 ps)
+
+} NTP_TSTAMP;
+
+#define _mbg_swab_ntp_tstamp( _p ) \
+{ \
+ _mbg_swab32( &(_p)->seconds ); \
+ _mbg_swab32( &(_p)->fractions ); \
+}
+
+
+/**
+ * @brief Enumeration of known NTP implementations
+ *
+ * Used with ::NTP_SYS_STATE::impl_type
+ */
+enum NTP_IMPL
+{
+ NTP_IMPL_UNKNOWN = 0, ///< Unknown NTP implementation
+ NTP_IMPL_NTPD, ///< Network Time Protocol daemon (ntpd)
+ NTP_IMPL_NTPDATE, ///< NTP client only (ntpdate)
+ NTP_IMPL_SNTP, ///< Simple Network Time Protocol (sntp)
+ NTP_IMPL_W32TIME, ///< Windows time service (w32time)
+ NTP_IMPL_MBGNTP, ///< Meinberg NTP implementation (mbgntp)
+ N_NTP_IMPLS
+};
+
+/*
+ * Default initializers for English leapsecond string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_IMPL_STR_ENG "Implemetation Type:"
+#define MBG_NTP_IMPL_STR_ENG_UNKNOWN "Unknown NTP implementation"
+#define MBG_NTP_IMPL_STR_ENG_NTPD "Network Time Protocol daemon (ntpd)"
+#define MBG_NTP_IMPL_STR_ENG_NTPDATE "NTP client only (ntpdate)"
+#define MBG_NTP_IMPL_STR_ENG_SNTP "Simple Network Time Protocol (sntp)"
+#define MBG_NTP_IMPL_STR_ENG_W32TIME "Windows time service (w32time)"
+#define MBG_NTP_IMPL_STR_ENG_MBGNTP "Meinberg NTP implementation (mbgntp)"
+
+
+#define MBG_NTP_IMPL_NAMES_ENG \
+{ \
+ MBG_NTP_IMPL_STR_ENG_UNKNOWN, \
+ MBG_NTP_IMPL_STR_ENG_NTPD, \
+ MBG_NTP_IMPL_STR_ENG_NTPDATE, \
+ MBG_NTP_IMPL_STR_ENG_SNTP, \
+ MBG_NTP_IMPL_STR_ENG_W32TIME, \
+ MBG_NTP_IMPL_STR_ENG_MBGNTP \
+}
+
+
+/**
+ * @brief Enumeration of CPU types using NTP
+ *
+ * Used with ::NTP_SYS_STATE::cpu_type
+ */
+enum NTP_CPU_TYPES
+{
+ NTP_CPU_TYPE_UNKNOWN = 0,
+ NTP_CPU_TYPE_X86,
+ NTP_CPU_TYPE_I386,
+ NTP_CPU_TYPE_I486,
+ NTP_CPU_TYPE_I586,
+ NTP_CPU_TYPE_I686,
+ NTP_CPU_TYPE_X64,
+ NTP_CPU_TYPE_X86_64,
+ NTP_CPU_TYPE_AMD64,
+ NTP_CPU_TYPE_SUN4U,
+ NTP_CPU_TYPE_ARM,
+ N_NTP_CPU_TYPES
+};
+
+
+/**
+ * @brief Name strings for known CPU types using NTP
+ *
+ * @see ::NTP_CPU_TYPES
+ */
+#define NTP_CPU_TYPES_STRS \
+{ \
+ "Unknown", \
+ "x86", \
+ "i386", \
+ "i486", \
+ "i586", \
+ "i686", \
+ "x64", \
+ "x86_64", \
+ "amd64", \
+ "sun4u", \
+ "arm" \
+}
+
+
+/**
+ * @brief Enumeration of operating systems using NTP
+ *
+ * Used with ::NTP_SYS_STATE::system
+*/
+enum NTP_SYSTEMS
+{
+ NTP_SYSTEM_UNKNOWN = 0,
+ NTP_SYSTEM_NONE,
+ NTP_SYSTEM_WINDOWS,
+ NTP_SYSTEM_LINUX,
+ NTP_SYSTEM_BSD,
+ NTP_SYSTEM_SOLARIS,
+ N_NTP_SYSTEMS
+};
+
+
+/**
+ * @brief Name strings for operating systens using NTP
+ *
+ * @see ::NTP_SYSTEMS
+ */
+#define NTP_SYSTEMS_STRS \
+{ \
+ "Unknown", \
+ "No OS", \
+ "Windows", \
+ "Linux", \
+ "BSD", \
+ "Solaris" \
+}
+
+
+/**
+ * @brief Enumeration of NTP leap indication bits
+ *
+ * Used with ::NTP_SYS_STATE::leap_ind
+ *
+ */
+enum NTP_LI_BITS
+{
+ NTP_LEAP_NONE = 0, ///< normal synchronized state
+ NTP_LEAP_ADD_SEC, ///< insert second after 23:59:59 of the current day
+ NTP_LEAP_DEL_SEC, ///< delete second 23:59:59 of the current day
+ NTP_LEAP_ALARM, ///< never synchronized
+ N_NTP_LI_BITS
+};
+
+/*
+ * Default initializers for English leapsecond string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_LEAP_STR_ENG "Leapsecond indication:"
+#define MBG_NTP_LEAP_STR_ENG_NONE "None"
+#define MBG_NTP_LEAP_STR_ENG_ADD_SEC "Insert second"
+#define MBG_NTP_LEAP_STR_ENG_DEL_SEC "Delete second"
+#define MBG_NTP_LEAP_STR_ENG_ALARM "Alarm"
+
+#define MBG_NTP_LEAP_NAMES_ENG \
+{ \
+ MBG_NTP_LEAP_STR_ENG_NONE, \
+ MBG_NTP_LEAP_STR_ENG_ADD_SEC, \
+ MBG_NTP_LEAP_STR_ENG_DEL_SEC, \
+ MBG_NTP_LEAP_STR_ENG_ALARM \
+}
+
+
+/**
+ * @brief Enumeration of NTP synchronization source bits
+ *
+ * Used with ::NTP_SYS_STATE::sys_sync_src
+ *
+ */
+enum NTP_SYNC_SRC_BITS
+{
+ NTP_SYNC_SRC_UNSPEC = 0, ///< not yet synchronized
+ NTP_SYNC_SRC_PPS, ///< pulse-per-second signal (Cs, Ru, GPS, etc.)
+ NTP_SYNC_SRC_LF_RADIO, ///< VLF/LF radio (WWVB, DCF77, etc.)
+ NTP_SYNC_SRC_HF_RADIO, ///< MF/HF radio (WWV, etc.)
+ NTP_SYNC_SRC_UHF_RADIO, ///< VHF/UHF radio/satellite (GPS, Galileo, etc.)
+ NTP_SYNC_SRC_LOCAL, ///< local timecode (IRIG, LOCAL driver, etc.)
+ NTP_SYNC_SRC_NTP, ///< NTP
+ NTP_SYNC_SRC_OTHER, ///< other (IEEE 1588, openntp, crony, etc.)
+ NTP_SYNC_SRC_WRISTWATCH, ///< eyeball and wristwatch
+ NTP_SYNC_SRC_TELEPHONE, ///< telephone modem (ACTS, PTB, etc.)
+ N_NTP_SYNC_SRC_BITS
+};
+
+/*
+ * Default initializers for English sync source string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_SYNC_SRC_STR_ENG_LABEL "Sync Source:"
+#define MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC "Not yet synchronized"
+#define MBG_NTP_SYNC_SRC_STR_ENG_PPS "Pulse per second signal"
+#define MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO "VLF/LF radio"
+#define MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO "MF/HF radio"
+#define MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO "VHF/UHF radio/satellite"
+#define MBG_NTP_SYNC_SRC_STR_ENG_LOCAL "local timecode"
+#define MBG_NTP_SYNC_SRC_STR_ENG_NTP "NTP"
+#define MBG_NTP_SYNC_SRC_STR_ENG_OTHER "other"
+#define MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH "eyeball and wristwatch"
+#define MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE "telephone modem"
+
+#define MBG_NTP_SYNC_SRC_NAMES_ENG \
+{ \
+ MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC, \
+ MBG_NTP_SYNC_SRC_STR_ENG_PPS, \
+ MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_LOCAL, \
+ MBG_NTP_SYNC_SRC_STR_ENG_NTP, \
+ MBG_NTP_SYNC_SRC_STR_ENG_OTHER, \
+ MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH, \
+ MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE \
+}
+
+
+/**
+ * @brief Enumeration of NTP system event message bits
+ *
+ * Used with ::NTP_SYS_STATE::sys_rec_evt
+ *
+ */
+enum NTP_SYS_EVT_BITS
+{
+ NTP_SYS_EVT_UNSPEC = 0, ///< unspecified NTP event
+ NTP_SYS_EVT_FREQ_NOT_SET, ///< frequency file not available
+ NTP_SYS_EVT_FREQ_SET, ///< frequency set from frequency file
+ NTP_SYS_EVT_SPIKE_DETECT, ///< spike detected
+ NTP_SYS_EVT_FREQ_MODE, ///< initial frequency training mode
+ NTP_SYS_EVT_CLOCK_SYNC, ///< clock synchronized
+ NTP_SYS_EVT_RESTART, ///< program restart
+ NTP_SYS_EVT_PANIC_STOP, ///< clock error more than 600 s
+ NTP_SYS_EVT_NO_SYSTEM_PEER, ///< no system peer
+ NTP_SYS_EVT_LEAP_ARMED, ///< leap second armed from file or autokey
+ NTP_SYS_EVT_LEAP_DISARMED, ///< leap second disarmed
+ NTP_SYS_EVT_LEAP_EVENT, ///< leap event
+ NTP_SYS_EVT_CLOCK_STEP, ///< clock stepped
+ NTP_SYS_EVT_KERNEL, ///< kernel information message
+ NTP_SYS_EVT_TAI, ///< leapsecond values update from file
+ NTP_SYS_EVT_STALE_LS_VALUES, ///< new NIST leapseconds file needed
+ N_NTP_SYS_EVT_BITS
+};
+
+/*
+ * Default initializers for English sync source string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_SYS_EVT_STR_ENG_CNT_LABEL "System Event Counter:"
+#define MBG_NTP_SYS_EVT_STR_ENG_MSG_LABEL "System Event Message:"
+#define MBG_NTP_SYS_EVT_STR_ENG_UNSPEC "Unspecified NTP event"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET "Frequency file not available"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET "Frequency set from frequency file"
+#define MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT "Spike detected"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE "Initial frequency training mode"
+#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC "Clock synchronized"
+#define MBG_NTP_SYS_EVT_STR_ENG_RESTART "Program restart"
+#define MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP "Clock error more than 600 s"
+#define MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER "No system peer"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED "Leap second armed from file or autokey"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED "Leap second disarmed"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT "Leap event"
+#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP "Clock stepped"
+#define MBG_NTP_SYS_EVT_STR_ENG_KERNEL "Kernel information message"
+#define MBG_NTP_SYS_EVT_STR_ENG_TAI "Leap second values update from file"
+#define MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES "New NIST leapseconds file needed"
+
+
+#define MBG_NTP_SYS_EVT_NAMES_ENG \
+{ \
+ MBG_NTP_SYS_EVT_STR_ENG_UNSPEC, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET, \
+ MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE, \
+ MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC, \
+ MBG_NTP_SYS_EVT_STR_ENG_RESTART, \
+ MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP, \
+ MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT, \
+ MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP, \
+ MBG_NTP_SYS_EVT_STR_ENG_KERNEL, \
+ MBG_NTP_SYS_EVT_STR_ENG_TAI, \
+ MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES \
+}
+
+/**
+ * @brief Enumeration of supported NTP system state values
+ *
+ * @see ::NTP_SYS_STATE_SUPP_FLAG_MASKS
+ */
+enum NTP_SYS_STATE_SUPP_FLAGS
+{
+ NTP_SYS_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_SYS_STATE, all fields except below and reserved
+ NTP_SYS_STATE_SUPP_EVENTS, ///< supports sys state events (::NTP_SYS_STATE::sys_evt_cnt, ::NTP_SYS_STATE::sys_rec_evt)
+ NTP_SYS_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_SYS_STATE::precision
+ NTP_SYS_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_SYS_STATE::root_delay
+ NTP_SYS_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_SYS_STATE::root_disp
+ NTP_SYS_STATE_SUPP_FREQ, ///< supports frequency offset, see ::NTP_SYS_STATE::freq
+ NTP_SYS_STATE_SUPP_SYS_JITTER, ///< supports combined jitter, see ::NTP_SYS_STATE::sys_jitter
+ NTP_SYS_STATE_SUPP_CLK_JITTER, ///< supports clock jitter, see ::NTP_SYS_STATE::clk_jitter
+ NTP_SYS_STATE_SUPP_CLK_WANDER, ///< supports clock wander, see ::NTP_SYS_STATE::clk_wander
+ N_NTP_SYS_STATE_SUPP_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for NTP_SYS_STATE_SUPP_FLAGS
+ *
+ * Used with ::NTP_SYS_STATE::supp_flags
+ *
+ * @see ::NTP_SYS_STATE_SUPP_FLAGS
+ */
+enum NTP_SYS_STATE_SUPP_FLAG_MASKS
+{
+ NTP_SYS_STATE_SUPP_STD_MSK = ( 1UL << NTP_SYS_STATE_SUPP_STD ), ///< see ::NTP_SYS_STATE_SUPP_STD
+ NTP_SYS_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_SYS_STATE_SUPP_EVENTS ), ///< see ::NTP_SYS_STATE_SUPP_EVENTS
+ NTP_SYS_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_SYS_STATE_SUPP_PRECISION ), ///< see ::NTP_SYS_STATE_SUPP_PRECISION
+ NTP_SYS_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DELAY
+ NTP_SYS_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DISP
+ NTP_SYS_STATE_SUPP_FREQ_MSK = ( 1UL << NTP_SYS_STATE_SUPP_FREQ ), ///< see ::NTP_SYS_STATE_SUPP_FREQ
+ NTP_SYS_STATE_SUPP_SYS_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_SYS_JITTER
+ NTP_SYS_STATE_SUPP_CLK_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_JITTER
+ NTP_SYS_STATE_SUPP_CLK_WANDER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_WANDER ) ///< see ::NTP_SYS_STATE_SUPP_CLK_WANDER
+};
+
+
+/**
+ * @brief Structure that represents the current system status of an NTP device
+ *
+ * This structure can be requested from a monitoring program to determine the device system status
+ */
+typedef struct
+{
+ uint32_t supp_flags; ///< Supported NTP system state values, see ::NTP_SYS_STATE_SUPP_FLAG_MASKS
+
+ uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS
+ uint8_t sys_sync_src; ///< Current synchronization source, see ::NTP_SYNC_SRC_BITS
+ uint8_t sys_evt_cnt; ///< Number of events, since the last time the event code changed
+ uint8_t sys_rec_evt; ///< Most recent event message, see ::NTP_SYS_EVT_BITS
+
+ uint8_t impl_type; ///< NTP implementation type, see ::NTP_IMPL
+ uint8_t major_version; ///< Major version number
+ uint8_t minor_version; ///< Minor version number
+ uint8_t micro_version; ///< Micro version number
+
+ uint16_t patch_lvl; ///< Patch level number
+ uint8_t cpu_type; ///< Processor type, see ::NTP_CPU_TYPES
+ uint8_t system; ///< Operating system, see ::NTP_SYSTEMS
+
+ uint8_t stratum; ///< Current stratum level of the system
+ int8_t precision; ///< Precision of the system clock (2^precision)
+ uint16_t reserved_1; ///< Reserved, currently always 0
+
+ int32_t root_delay; ///< [us] Total roundtrip delay to the system peer
+ int32_t root_disp; ///< [us] Total dispersion to the system peer
+
+ MBG_IP_ADDR ref_id; ///< Reference ID of the current system peer, see ::MBG_IP_ADDR
+
+ NTP_TSTAMP ref_time; ///< Last time the system time has been adjusted, see ::NTP_TSTAMP
+ NTP_TSTAMP sys_time; ///< Current system time, see ::NTP_TSTAMP
+
+ uint16_t sys_peer; ///< Assocation ID of the current system peer
+ uint8_t poll; ///< Current polling interval for the system peer (tc)
+ uint8_t minpoll; ///< Minimal polling interval for the system peer (mintc)
+
+ int64_t offset; ///< [ns] Combined offset to the system peer
+
+ int32_t freq; ///< [ppb] Frequency offset relative to hardware clock
+ int32_t sys_jitter; ///< [us] Combined jitter of the system
+ int32_t clk_jitter; ///< [us] Jitter of the clock
+ int32_t clk_wander; ///< [ppb] Frequency wander of the clock
+
+ uint32_t reserved_2; ///< Reserved, currently always 0
+ uint32_t reserved_3; ///< Reserved, currently always 0
+
+} NTP_SYS_STATE;
+
+
+/**
+ * @brief Enumeration of NTP mode bits
+ *
+ * Used with ::NTP_PEER_STATE::host_mode and ::NTP_PEER_STATE::peer_mode
+ *
+ */
+enum NTP_MODE_BITS
+{
+ NTP_MODE_RESERVED = 0,
+ NTP_MODE_SYMM_ACT,
+ NTP_MODE_SYMM_PASS,
+ NTP_MODE_CLIENT,
+ NTP_MODE_SERVER,
+ NTP_MODE_BROADCAST,
+ NTP_MODE_CONTROL,
+ NTP_MODE_PRIVATE,
+ N_NTP_MODE_BITS
+};
+
+/*
+ * Default initializers for English NTP peer mode string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_MODE_STR_ENG_HOST_LABEL "Host Mode:"
+#define MBG_NTP_MODE_STR_ENG_PEER_LABEL "Peer Mode:"
+
+#define MBG_NTP_PEER_MODE_STR_ENG_RESERVED "Reserved"
+#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT "Symm Act"
+#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS "Symm Pass"
+#define MBG_NTP_PEER_MODE_STR_ENG_CLIENT "Client"
+#define MBG_NTP_PEER_MODE_STR_ENG_SERVER "Server"
+#define MBG_NTP_PEER_MODE_STR_ENG_BROADCAST "Broadcast"
+#define MBG_NTP_PEER_MODE_STR_ENG_CONTROL "Control"
+#define MBG_NTP_PEER_MODE_STR_ENG_PRIVATE "Private"
+
+#define MBG_NTP_MODE_STAT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_MODE_STR_ENG_RESERVED, \
+ MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT, \
+ MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS, \
+ MBG_NTP_PEER_MODE_STR_ENG_CLIENT, \
+ MBG_NTP_PEER_MODE_STR_ENG_SERVER, \
+ MBG_NTP_PEER_MODE_STR_ENG_BROADCAST, \
+ MBG_NTP_PEER_MODE_STR_ENG_CONTROL, \
+ MBG_NTP_PEER_MODE_STR_ENG_PRIVATE \
+}
+
+
+/**
+ * @brief Enumeration of NTP peer reach status
+ *
+ * Used with ::NTP_PEER_STATE::peer_reach_stat
+ */
+enum NTP_REACH_STAT_BITS
+{
+ NTP_REACH_STAT_UNKNOWN = 0, ///< unknown reach status
+ NTP_REACH_STAT_NO_LINK, ///< no network connection
+ NTP_REACH_STAT_DNS_UNREACH, ///< DNS server could not be reached
+ NTP_REACH_STAT_DNS_UNRESOLVED, ///< DNS name could not be resolved
+ NTP_REACH_STAT_PEER_UNREACH, ///< peer could not be reached
+ NTP_REACH_STAT_PEER_NOT_SYNC, ///< peer is not sync (leap alarm, stratum 16)
+ NTP_REACH_STAT_PEER_BAD_QUALITY, ///< peer has bad quality (dispersion, ...)
+ NTP_REACH_STAT_OK, ///< reach status is fine
+ N_NTP_REACH_STAT_BITS
+};
+
+/*
+ * Default initializers for English reach status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_LABEL "Reach State:"
+
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN "Unknown"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK "No link"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH "DNS Server unreached"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED "DNS name not resolved"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH "Peer not reached"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC "Peer not sync"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY "Peer has bad quality"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_OK "Good"
+
+#define MBG_NTP_PEER_REACH_STAT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_OK \
+}
+
+
+/**
+ * @brief Enumeration of NTP peer selection status
+ *
+ * Used with ::NTP_PEER_STATE::peer_sel_stat
+ *
+ */
+enum NTP_PEER_SEL_STATUS_BITS
+{
+ NTP_PEER_SEL_REJECT = 0, ///< discarded as not valid (TEST10-TEST13)
+ NTP_PEER_SEL_FALSETICK, ///< discarded by intersection algorithm
+ NTP_PEER_SEL_EXCESS, ///< discarded by table overflow (not used)
+ NTP_PEER_SEL_OUTLYER, ///< discarded by the cluster algorithm
+ NTP_PEER_SEL_CANDIDATE, ///< included by the combine algorithm
+ NTP_PEER_SEL_BACKUP, ///< backup (more than tos maxclock sources)
+ NTP_PEER_SEL_SYS_PEER, ///< system peer
+ NTP_PEER_SEL_PPS_PEER, ///< PPS peer (when the prefer peer is valid)
+ N_NTP_PEER_SEL_STATUS_BITS
+};
+
+/*
+ * Default initializers for English peer select status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_LABEL "Selected Status:"
+
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT "Not valid"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK "Falsetick"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS "Excess"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER "Outlyer"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE "Candidate"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP "Backup"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER "System Peer"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER "PPS Peer"
+
+#define MBG_NTP_PEER_SEL_STATUS_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER \
+}
+
+
+/**
+ * @brief Enumeration of NTP peer status codes
+ *
+ * @see ::NTP_PEER_STATUS_FLAG_MASKS
+ *
+ */
+enum NTP_PEER_STATUS_FLAGS
+{
+ NTP_PEER_STATUS_BCST = 0, ///< broadcast association
+ NTP_PEER_STATUS_REACH, ///< host reachable
+ NTP_PEER_STATUS_AUTHENB, ///< authentication enabled
+ NTP_PEER_STATUS_AUTH, ///< authentication ok
+ NTP_PEER_STATUS_CONFIG, ///< persistent association
+ N_NTP_PEER_STATUS_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for NTP_PEER_STATUS_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::peer_status_flags
+ *
+ * @see ::NTP_PEER_STATUS_FLAGS
+ */
+enum NTP_PEER_STATUS_FLAG_MASKS
+{
+ NTP_PEER_STATUS_BCST_MSK = ( 1UL << NTP_PEER_STATUS_BCST ), ///< see ::NTP_PEER_STATUS_BCST
+ NTP_PEER_STATUS_REACH_MSK = ( 1UL << NTP_PEER_STATUS_REACH ), ///< see ::NTP_PEER_STATUS_REACH
+ NTP_PEER_STATUS_AUTHENB_MSK = ( 1UL << NTP_PEER_STATUS_AUTHENB ), ///< see ::NTP_PEER_STATUS_AUTHENB
+ NTP_PEER_STATUS_AUTH_MSK = ( 1UL << NTP_PEER_STATUS_AUTH ), ///< see ::NTP_PEER_STATUS_AUTH
+ NTP_PEER_STATUS_CONFIG_MSK = ( 1UL << NTP_PEER_STATUS_CONFIG ), ///< see ::NTP_PEER_STATUS_CONFIG
+};
+
+
+/*
+ * Default initializers for English peer status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_STATUS_STR_ENG_LABEL "Peer Status:"
+#define MBG_NTP_PEER_STATUS_STR_ENG_BCST "Broadcast association"
+#define MBG_NTP_PEER_STATUS_STR_ENG_REACH "Host reachable"
+#define MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB "Authentication enabled"
+#define MBG_NTP_PEER_STATUS_STR_ENG_CONFIG "Persistant assosiation"
+
+#define MBG_NTP_PEER_STATUS_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_STATUS_STR_ENG_BCST, \
+ MBG_NTP_PEER_STATUS_STR_ENG_REACH, \
+ MBG_NTP_PEER_STATUS_STR_ENG_REACH, \
+ MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB, \
+ MBG_NTP_PEER_STATUS_STR_ENG_CONFIG \
+}
+
+
+/**
+ * @brief Enumeration of NTP peer event message codes
+ *
+ * Used with ::NTP_PEER_STATE::peer_rec_evt
+ *
+ */
+enum NTP_PEER_EVT_BITS
+{
+ NTP_PEER_EVT_UNSPEC = 0, ///< unspecified NTP event
+ NTP_PEER_EVT_MOBILIZE, ///< association mobilized
+ NTP_PEER_EVT_DEMOBILIZE, ///< association demobilized
+ NTP_PEER_EVT_UNREACHABLE, ///< server unreachable
+ NTP_PEER_EVT_REACHABLE, ///< server reachable
+ NTP_PEER_EVT_RESTART, ///< association restart
+ NTP_PEER_EVT_NO_REPLY, ///< no server found (ntpdate mode)
+ NTP_PEER_EVT_RATE_EXCEEDED, ///< rate exceeded (kiss code RATE)
+ NTP_PEER_EVT_ACCESS_DENIED, ///< access denied (kiss code DENY)
+ NTP_PEER_EVT_LEAP_ARMED, ///< leap armed from server LI code
+ NTP_PEER_EVT_SYS_PEER, ///< become system peer
+ NTP_PEER_EVT_CLOCK_EVENT, ///< see clock status word
+ NTP_PEER_EVT_BAD_AUTH, ///< authentication failure
+ NTP_PEER_EVT_POPCORN, ///< popcorn spike suppressor
+ NTP_PEER_EVT_INTERLEAVE_MODE, ///< entering interleave mode
+ NTP_PEER_EVT_INTERLEAVE_ERROR, ///< interleave error (recovered)
+ N_NTP_PEER_EVT_BITS
+};
+
+/*
+ * Default initializers for English event message codes. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_EVT_STR_ENG_CNT_LABEL "Peer Event Counter:"
+#define MBG_NTP_PEER_EVT_STR_ENG_MSG_LABEL "Peer Event Message:"
+#define MBG_NTP_PEER_EVT_STR_ENG_UNSPEC "Unspecified NTP event"
+#define MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE "Association mobilized"
+#define MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE "Association demobilized"
+#define MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE "Server unreachable"
+#define MBG_NTP_PEER_EVT_STR_ENG_REACHABLE "Server reachable"
+#define MBG_NTP_PEER_EVT_STR_ENG_RESTART "Association restart"
+#define MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY "No server found"
+#define MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED "Rate exceeded"
+#define MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED "Access denied"
+#define MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED "Leap second armed from LI code"
+#define MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER "Become system Peer"
+#define MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT "Clock event"
+#define MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH "Authentication failure"
+#define MBG_NTP_PEER_EVT_STR_ENG_POPCORN "Popcorn Spike suspressor"
+#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE "Entering Interleave mode"
+#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR "Interleave error"
+
+
+#define MBG_NTP_PEER_EVT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_EVT_STR_ENG_UNSPEC, \
+ MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE, \
+ MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE, \
+ MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE, \
+ MBG_NTP_PEER_EVT_STR_ENG_REACHABLE, \
+ MBG_NTP_PEER_EVT_STR_ENG_RESTART, \
+ MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY, \
+ MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED, \
+ MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED, \
+ MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED, \
+ MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER, \
+ MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT, \
+ MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH, \
+ MBG_NTP_PEER_EVT_STR_ENG_POPCORN, \
+ MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE, \
+ MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR \
+}
+
+
+/**
+ * @brief Enumeration of NTP flash status bit codes
+ *
+ * @see ::NTP_FLASH_STAT_FLAG_MASKS
+ *
+ */
+enum NTP_FLASH_STAT_FLAGS
+{
+ NTP_FLASH_STAT_PKT_DUP = 0, ///< duplicate packet
+ NTP_FLASH_STAT_PKT_BOGUS, ///< bogus packet
+ NTP_FLASH_STAT_PKT_UNSYNC, ///< server not synchronized
+ NTP_FLASH_STAT_PKT_DENIED, ///< access denied
+ NTP_FLASH_STAT_PKT_AUTH, ///< authentication failure
+ NTP_FLASH_STAT_PKT_STRATUM, ///< invalid leap or stratum
+ NTP_FLASH_STAT_PKT_HEADER, ///< header distance exceeded
+ NTP_FLASH_STAT_PKT_AUTOKEY, ///< Autokey sequence error
+ NTP_FLASH_STAT_PKT_CRYPTO, ///< Autokey protocol error
+ NTP_FLASH_STAT_PEER_STRATUM, ///< invalid header or stratum
+ NTP_FLASH_STAT_PEER_DIST, ///< distance threshold exceeded
+ NTP_FLASH_STAT_PEER_LOOP, ///< synchronization loop
+ NTP_FLASH_STAT_PEER_UNREACH, ///< unreachable or nonselect
+ N_NTP_FLASH_STAT_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for ::NTP_FLASH_STAT_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::flash_stat_flags
+ *
+ * @see ::NTP_FLASH_STAT_FLAGS
+ */
+enum NTP_FLASH_STAT_FLAG_MASKS
+{
+ NTP_FLASH_STAT_PKT_DUP_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DUP ), ///< see ::NTP_FLASH_STAT_PKT_DUP
+ NTP_FLASH_STAT_PKT_BOGUS_MSK = ( 1UL << NTP_FLASH_STAT_PKT_BOGUS ), ///< see ::NTP_FLASH_STAT_PKT_BOGUS
+ NTP_FLASH_STAT_PKT_UNSYNC_MSK = ( 1UL << NTP_FLASH_STAT_PKT_UNSYNC ), ///< see ::NTP_FLASH_STAT_PKT_UNSYNC
+ NTP_FLASH_STAT_PKT_DENIED_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DENIED ), ///< see ::NTP_FLASH_STAT_PKT_DENIED
+ NTP_FLASH_STAT_PKT_AUTH_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTH ), ///< see ::NTP_FLASH_STAT_PKT_AUTH
+ NTP_FLASH_STAT_PKT_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PKT_STRATUM ), ///< see ::NTP_FLASH_STAT_PKT_STRATUM
+ NTP_FLASH_STAT_PKT_HEADER_MSK = ( 1UL << NTP_FLASH_STAT_PKT_HEADER ), ///< see ::NTP_FLASH_STAT_PKT_HEADER
+ NTP_FLASH_STAT_PKT_AUTOKEY_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTOKEY ), ///< see ::NTP_FLASH_STAT_PKT_AUTOKEY
+ NTP_FLASH_STAT_PKT_CRYPTO_MSK = ( 1UL << NTP_FLASH_STAT_PKT_CRYPTO ), ///< see ::NTP_FLASH_STAT_PKT_CRYPTO
+ NTP_FLASH_STAT_PEER_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PEER_STRATUM ), ///< see ::NTP_FLASH_STAT_PEER_STRATUM
+ NTP_FLASH_STAT_PEER_DIST_MSK = ( 1UL << NTP_FLASH_STAT_PEER_DIST ), ///< see ::NTP_FLASH_STAT_PEER_DIST
+ NTP_FLASH_STAT_PEER_LOOP_MSK = ( 1UL << NTP_FLASH_STAT_PEER_LOOP ), ///< see ::NTP_FLASH_STAT_PEER_LOOP
+ NTP_FLASH_STAT_PEER_UNREACH_MSK = ( 1UL << NTP_FLASH_STAT_PEER_UNREACH ), ///< see ::NTP_FLASH_STAT_PEER_UNREACH
+};
+
+/*
+ * Default initializers for English ntp flash state mask. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+
+#define MBG_NTP_FLASH_STR_ENG_LABEL "Flash Status:"
+#define MBG_NTP_FLASH_STR_ENG_PKT_DUP "Duplicate packet"
+#define MBG_NTP_FLASH_STR_ENG_PKT_BOGUS "Bogus packet"
+#define MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC "Server not synchronized"
+#define MBG_NTP_FLASH_STR_ENG_PKT_DENIED "Access denied"
+#define MBG_NTP_FLASH_STR_ENG_PKT_AUTH "Authentication failure"
+#define MBG_NTP_FLASH_STR_ENG_PKT_STRATUM "Invalid leap or stratum"
+#define MBG_NTP_FLASH_STR_ENG_PKT_HEADER "Header distance exceeded"
+#define MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY "Autokey sequence error"
+#define MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO "Autokey protocol error"
+#define MBG_NTP_FLASH_STR_ENG_PEER_STRATUM "Invalid header or stratum"
+#define MBG_NTP_FLASH_STR_ENG_PEER_DIST "Distance threshold exceeded"
+#define MBG_NTP_FLASH_STR_ENG_PEER_LOOP "Synchronization loop"
+#define MBG_NTP_FLASH_STR_ENG_PEER_UNREACH "Unreachable or nonselect"
+
+
+#define MBG_NTP_FLASH_NAMES_ENG \
+{ \
+ MBG_NTP_FLASH_STR_ENG_PKT_DUP, \
+ MBG_NTP_FLASH_STR_ENG_PKT_BOGUS, \
+ MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC, \
+ MBG_NTP_FLASH_STR_ENG_PKT_DENIED, \
+ MBG_NTP_FLASH_STR_ENG_PKT_AUTH, \
+ MBG_NTP_FLASH_STR_ENG_PKT_STRATUM, \
+ MBG_NTP_FLASH_STR_ENG_PKT_HEADER, \
+ MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY, \
+ MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO, \
+ MBG_NTP_FLASH_STR_ENG_PEER_STRATUM, \
+ MBG_NTP_FLASH_STR_ENG_PEER_DIST, \
+ MBG_NTP_FLASH_STR_ENG_PEER_LOOP, \
+ MBG_NTP_FLASH_STR_ENG_PEER_UNREACH \
+}
+
+
+/**
+ * @brief Enumeration of supported NTP peer state values
+ *
+ * @see ::NTP_PEER_STATE_SUPP_FLAG_MASKS
+ */
+enum NTP_PEER_STATE_SUPP_FLAGS
+{
+ NTP_PEER_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_PEER_STATE, all fields except below and reserved
+ NTP_PEER_STATE_SUPP_ASS_ID, ///< supports association ID, see ::NTP_PEER_STATE::ass_id
+ NTP_PEER_STATE_SUPP_EVENTS, ///< supports peer state events (NTP_PEER_STATE::peer_evt_cnt, NTP_PEER_STATE::peer_rec_evt)
+ NTP_PEER_STATE_SUPP_REACH_STAT, ///< supports peer reach status, see ::NTP_PEER_STATE::peer_reach_stat
+ NTP_PEER_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_PEER_STATE::precision
+ NTP_PEER_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_PEER_STATE::root_delay
+ NTP_PEER_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_PEER_STATE::root_disp
+ NTP_PEER_STATE_SUPP_HEADWAY, ///< supports headway, see ::NTP_PEER_STATE::headway
+ NTP_PEER_STATE_SUPP_FLASH_STAT, ///< supports flash status word, see ::NTP_PEER_STATE::flash_stat_flags
+ NTP_PEER_STATE_SUPP_KEY_ID, ///< supports symmetric key id, see ::NTP_PEER_STATE::key_id
+ NTP_PEER_STATE_SUPP_DISP, ///< supports filter dispersion, see ::NTP_PEER_STATE::disp
+ NTP_PEER_STATE_SUPP_JITTER, ///< supports filter jitter, see ::NTP_PEER_STATE::jitter
+ NTP_PEER_STATE_SUPP_XLEAVE, ///< supports interleave delay, see ::NTP_PEER_STATE::xleave
+ N_NTP_PEER_STATE_SUPP_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for NTP_PEER_STATE_SUPP_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::supp_flags
+ *
+ * @see ::NTP_PEER_STATE_SUPP_FLAGS
+ */
+enum NTP_PEER_STATE_SUPP_FLAG_MASKS
+{
+ NTP_PEER_STATE_SUPP_STD_MSK = ( 1UL << NTP_PEER_STATE_SUPP_STD ), ///< see ::NTP_PEER_STATE_SUPP_STD
+ NTP_PEER_STATE_SUPP_ASS_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ASS_ID ), ///< see ::NTP_PEER_STATE_SUPP_ASS_ID
+ NTP_PEER_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_PEER_STATE_SUPP_EVENTS ), ///< see ::NTP_PEER_STATE_SUPP_EVENTS
+ NTP_PEER_STATE_SUPP_REACH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_REACH_STAT ), ///< see ::NTP_PEER_STATE_SUPP_REACH_STAT
+ NTP_PEER_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_PEER_STATE_SUPP_PRECISION ), ///< see ::NTP_PEER_STATE_SUPP_PRECISION
+ NTP_PEER_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_PEER_STATE_SUPP_ROOT_DELAY
+ NTP_PEER_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_PEER_STATE_SUPP_ROOT_DISP
+ NTP_PEER_STATE_SUPP_HEADWAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_HEADWAY ), ///< see ::NTP_PEER_STATE_SUPP_HEADWAY
+ NTP_PEER_STATE_SUPP_FLASH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_FLASH_STAT ), ///< see ::NTP_PEER_STATE_SUPP_FLASH_STAT
+ NTP_PEER_STATE_SUPP_KEY_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_KEY_ID ), ///< see ::NTP_PEER_STATE_SUPP_KEY_ID
+ NTP_PEER_STATE_SUPP_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_DISP ), ///< see ::NTP_PEER_STATE_SUPP_DISP
+ NTP_PEER_STATE_SUPP_JITTER_MSK = ( 1UL << NTP_PEER_STATE_SUPP_JITTER ), ///< see ::NTP_PEER_STATE_SUPP_JITTER
+ NTP_PEER_STATE_SUPP_XLEAVE_MSK = ( 1UL << NTP_PEER_STATE_SUPP_XLEAVE ), ///< see ::NTP_PEER_STATE_SUPP_XLEAVE
+};
+
+
+/**
+ * @brief Structure that represents the status of an NTP peer
+ *
+ * This structure should be requested via ::NTP_PEER_STATE_IDX
+ *
+ * @see ::NTP_PEER_STATE_IDX
+ */
+typedef struct
+{
+ uint32_t supp_flags; ///< Supported NTP peer state values, see ::NTP_PEER_STATE_SUPP_FLAG_MASKS
+
+ uint16_t ass_id; ///< Association ID of the peer
+ uint16_t peer_status_flags; ///< Peer status flags, see ::NTP_PEER_STATUS_FLAG_MASKS
+
+ uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS
+ uint8_t peer_sel_stat; ///< Current selection status of the peer, see ::NTP_PEER_SEL_STATUS_BITS
+ uint8_t peer_evt_cnt; ///< Number of events, since the last time the event code changed
+ uint8_t peer_rec_evt; ///< Most recent event message, see ::NTP_PEER_EVT_BITS
+
+ uint8_t peer_reach_stat; ///< Current reach status of the peer, see ::NTP_REACH_STAT_BITS
+ uint8_t reserved_1; ///< Reserved, currently always 0
+ uint16_t reserved_2; ///< Reserved, currently always 0
+
+ MBG_IP_ADDR_PORT src_addr; ///< Source address of the NTP peer, see ::MBG_IP_ADDR_PORT
+ MBG_IP_ADDR_PORT dst_addr; ///< Destination address of the NTP peer, see ::MBG_IP_ADDR_PORT
+
+ uint8_t stratum; ///< Current stratum level of the NTP peer
+ int8_t precision; ///< Precision of the peer clock (2^precision)
+ uint16_t reserved_3; ///< Reserved, currently always 0
+
+ int32_t root_delay; ///< [us] Total roundtrip delay to the system peer of the NTP peer
+ int32_t root_disp; ///< [us] Total dispersion to the system peer of the NTP peer
+
+ MBG_IP_ADDR ref_id; ///< Reference ID of the NTP peer, see ::MBG_IP_ADDR
+
+ NTP_TSTAMP ref_time; ///< Last time the NTP peers time has been adjusted, see ::NTP_TSTAMP
+ NTP_TSTAMP rec_time; ///< Current system time of the NTP peer, see ::NTP_TSTAMP
+
+ uint8_t reach; ///< Shift register for the last 8 polling intervals
+ uint8_t reserved_4; ///< Reserved, currently always 0
+ uint16_t unreach; ///< Counter for the number of unsuccessful polling intervals
+
+ uint8_t host_mode; ///< NTP mode of the requesting host, see ::NTP_MODE_BITS
+ uint8_t peer_mode; ///< NTP mode of the peer, see ::NTP_MODE_BITS
+ uint8_t host_poll; ///< Host NTP polling interval
+ uint8_t peer_poll; ///< Peer NTP polling interval
+
+ uint8_t headway; ///< Indicator for the KoD packet, TODO: further investigation
+ uint8_t reserved_5; ///< Reserved, currently always 0
+ uint16_t flash_stat_flags; ///< Flash status flags, see ::NTP_FLASH_STAT_FLAG_MASKS
+
+ uint16_t key_id; ///< ID of symmetric authentication key
+ uint16_t reserved_6; ///< Reserved, currently always 0
+
+ int64_t offset; ///< [ns] filter offset to this NTP peer
+ int64_t delay; ///< [ns] filter delay to this NTP peer
+
+ int32_t disp; ///< [us] filter dispersion of the NTP peer
+ int32_t jitter; ///< [us] filter jitter of the NTP peer
+
+ uint32_t xleave; ///< [ns] interleave delay of the NTP peer
+
+ uint8_t n_filter_values; ///< Number of filter values available, currently always 0
+ uint8_t reserved_7; ///< Reserved, currently always 0
+ uint16_t reserved_8; ///< Reserved, currently always 0
+
+ uint32_t reserved_9; ///< Reserved, currently always 0
+
+} NTP_PEER_STATE;
+
+
+/**
+ * @brief Structure that contains an index value and the NTP peer state
+ *
+ * This structure can be requested by a monitoring program to observe the status of configured NTP peers
+ *
+ * @see ::NTP_PEER_STATE
+ */
+typedef struct
+{
+ uint32_t idx; ///< The index of the observed NTP peer
+ NTP_PEER_STATE peer_state; ///< Peer state, see ::NTP_PEER_STATE
+
+} NTP_PEER_STATE_IDX;
+
+/** @} defgroup group_ntp */
+
+
+
+/**
+ * @defgroup group_lno Definitions used with LNO devices
+ *
+ * @{ */
+
+#define MAX_LNO_OUTPUT 4
+
+/**
+ * @brief LNO status
+ */
+typedef struct
+{
+ uint16_t sine_lvl[MAX_LNO_OUTPUT]; ///< signal levels at the outputs
+
+ uint16_t max_sine_lvl; ///< max level of an output, e.g. 1024
+ uint8_t n_outputs; ///< actual number of outputs [0..::MAX_LNO_OUTPUT-1]
+ uint8_t out_enb_state; ///< e.g. bit 0 is set if corresponding output 0 is enabled, etc.
+
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint16_t flags; ///< status flags, see ::LNO_STATE_FLAG_BITS
+
+} LNO_STATE;
+
+#define _mbg_swab_lno_state( _p ) \
+{ \
+ int i; \
+ \
+ for ( i = 0; i < MAX_LNO_OUTPUT; i++ ) \
+ _mbg_swab16( &(_p)->sine_lvl[i] ); \
+ \
+ _mbg_swab_16( &(_p)->max_sine_lvl ); \
+ _mbg_swab_16( &(_p)->reserved_0 ); \
+ _mbg_swab_16( &(_p)->flags ); \
+}
+
+
+/**
+ * @brief Flags used with LNO_STATE::flags
+ */
+enum LNO_STATE_FLAG_BITS
+{
+ LNO_FLAG_BIT_PLL_LOCKED, ///< PLL is locked
+ N_LNO_FLAG_BIT ///< number of known bits
+};
+
+#define LNO_FLAG_PLL_LOCKED ( 1UL << LNO_FLAG_BIT_PLL_LOCKED )
+
+/** @} defgroup group_lno */
+
+
+
+/**
+ * @defgroup group_vst Definitions used with Versatile Storage
+ *
+ * Versatile storage is used to store binary data on a device where the storage
+ * device must not necessarily know about the data structure. It just stores
+ * a piece of data, and retrieves it on demand.
+ *
+ * The structures and associated API calls are only supported if the
+ * ::GPS_HAS_VST bit is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Known common VST data types
+ */
+enum VST_DATA_TYPES
+{
+ VST_DATA_TYPE_MAC_ADDR, //##++++++++++++ This is just an example. More to be added.
+ N_VST_DATA_TYPES
+};
+
+
+/**
+ * @brief
+ */
+typedef struct
+{
+ uint16_t data_type; ///< data type identifier, see ::VST_DATA_TYPES for common types
+ uint16_t idx; ///< Index for several sets of the same type
+ uint16_t data_len; ///< length of the data set appended to the header
+ uint16_t reserved; ///< reserved, currently always 0
+
+} VST_HEADER;
+
+#define _mbg_swab_vst_header( _p ) \
+{ \
+ _mbg_swab16( &(_p)->data_type ); \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab16( &(_p)->data_len ); \
+ _mbg_swab16( &(_p)->reserved ); \
+}
+
+/** @} defgroup group_vst */
+
+
+
+/**
+ * @defgroup group_shs Definitions used with SHS devices
+ *
+ * An SHS (Secure Hybrid System) device compares the times from 2 sources
+ * and eventually sets an alarm (warning and/or error) flag if the difference
+ * between the 2 time sources exceeds a configurable limit.
+ *
+ * These structures and associated definitions are used to query the SHS
+ * capabilities, configure the SHS device according to its capabilities,
+ * and query the SHS status.
+ *
+ * The structures and associated API calls are only supported if the
+ * ::GPS_HAS_SHS bit is set in ::RECEIVER_INFO::features.
+ *
+ * The ::SHS_INFO structure can be read to retrieve the capabilities and
+ * current settings of the device. The ::SHS_SETTINGS structure can then
+ * be set up according to the capabilities, and be written back to configure
+ * the device.
+ *
+ * If ::SHS_SETTINGS::err_limit and/or ::SHS_SETTINGS::warn_limit are
+ * not 0 then the SHS device checks if the time difference between the
+ * 2 clocks exceeds these limits and sets ::SHS_STATUS::shs_state
+ * as appropriate.
+ *
+ * If indicated by ::SHS_INFO::supp_flags the SHS device can also take
+ * certain actions if the time difference exceeds the error limit.
+ * If this happens then the same flags are set in ::SHS_STATUS::flags
+ * to indicate the action has been taken.
+ *
+ * @{ */
+
+/**
+ * @brief Current configuration of an SHS controller
+ *
+ * @see ::SHS_INFO
+ * @see ::SHS_STATUS
+ */
+typedef struct
+{
+ NANO_TIME err_limit; ///< time difference limit above which an error is indicated
+ NANO_TIME warn_limit; ///< time difference limit above which a warning is indicated
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::SHS_FLAG_MASKS
+
+} SHS_SETTINGS;
+
+#define _mbg_swab_shs_settings( _p ) \
+{ \
+ _mbg_swab_nano_time( &(_p)->err_limit ); \
+ _mbg_swab_nano_time( &(_p)->warn_limit ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief Current SHS settings and general SHS capabilities
+ *
+ * @see ::SHS_SETTINGS
+ * @see ::SHS_STATUS
+ */
+typedef struct
+{
+ SHS_SETTINGS settings; ///< current configuration settings
+ NANO_TIME max_limit; ///< if not 0, the max. allowed value for ::SHS_SETTINGS::err_limit and ::SHS_SETTINGS::warn_limit
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< indicates which flags are supported for ::SHS_SETTINGS::flags, see ::SHS_FLAG_MASKS
+
+} SHS_INFO;
+
+#define _mbg_swab_shs_info( _p ) \
+{ \
+ _mbg_swab_shs_settings( &(_p)->settings ); \
+ _mbg_swab_nano_time( &(_p)->max_limit ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief Current SHS status
+ */
+typedef struct
+{
+ NANO_TIME time_diff; ///< current time difference between the 2 clocks
+ TM_STATUS_EXT clk_status_1; ///< status of first clock
+ TM_STATUS_EXT clk_status_2; ///< status of second clock
+ uint8_t shs_state; ///< see ::SHS_STATES
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t reserved_2; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::SHS_FLAG_MASKS
+
+} SHS_STATUS;
+
+#define _mbg_swab_shs_status( _p ) \
+{ \
+ _mbg_swab_nano_time( &(_p)->time_diff ); \
+ _mbg_swab32( &(_p)->clk_status_1 ); \
+ _mbg_swab32( &(_p)->clk_status_2 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+
+/**
+ * @brief SHS configuration flag bits
+ *
+ * Codes used with ::SHS_STATUS::shs_state
+ */
+enum SHS_STATES
+{
+ SHS_STATE_DISABLED, ///< time difference not checked, eventually no limits configured
+ SHS_STATE_OK, ///< time difference OK, below warning limit
+ SHS_STATE_WARNING, ///< time difference exceeds warning limit
+ SHS_STATE_ERROR, ///< time difference exceeds error limit
+ SHS_STATE_FATAL, ///< one or both time sources disconnected
+ N_SHS_STATES
+};
+
+
+
+/**
+ * @brief SHS flag bits
+ *
+ * @see ::SHS_FLAG_MASKS
+ */
+enum SHS_FLAG_BITS
+{
+ SHS_FLAG_BIT_DISB_SERIAL, ///< disable serial output in state ::SHS_STATE_ERROR
+ SHS_FLAG_BIT_DISB_PPS, ///< disable PPS output in state ::SHS_STATE_ERROR
+ SHS_FLAG_BIT_DISB_10MHZ, ///< disable 10 MHz output in state ::SHS_STATE_ERROR
+ N_SHS_FLAG_BITS
+};
+
+
+/**
+ * @brief SHS flag masks
+ *
+ * With ::SHS_INFO::supp_flags these flags indicate what is supported
+ * by the SHS controller, e.g. what action can be taken automatically.
+ * Each bit set in ::SHS_INFO::supp_flags can be set by a configuration
+ * tool in ::SHS_SETTINGS::flags to enable the associated feature.
+ * If a corresponding bit is set in ::SHS_STATUS::flags this means the
+ * associated feature has been enabled, e.g. an action has been taken.
+ *
+ * @see ::SHS_FLAG_BITS
+ */
+enum SHS_FLAG_MASKS
+{
+ SHS_FLAG_DISB_SERIAL = ( 1UL << SHS_FLAG_BIT_DISB_SERIAL ), ///< see ::SHS_FLAG_BIT_DISB_SERIAL
+ SHS_FLAG_DISB_PPS = ( 1UL << SHS_FLAG_BIT_DISB_PPS ), ///< see ::SHS_FLAG_BIT_DISB_PPS
+ SHS_FLAG_DISB_10MHZ = ( 1UL << SHS_FLAG_BIT_DISB_10MHZ ) ///< see ::SHS_FLAG_BIT_DISB_10MHZ
+};
+
+/** @} defgroup group_shs */
+
+
+
+/**
+ * @defgroup group_xbp eXtended Binary Protocol definitions
+ *
+ * @note These structures are only supported if ::GPS_HAS_XBP is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief An identifier used to mark an XBP port unused
+ */
+#define XBP_PORT_RESERVED ( (uint8_t) 255 )
+
+/**
+ * @brief An XBP port specifier
+ *
+ * Each controller can provide up to 255 ports with numbers 0..254.
+ * XBP port number ::XBP_PORT_RESERVED is reserved to mark unused ports.
+ */
+typedef uint8_t XBP_PORT;
+
+
+/**
+ * @brief Maximum XBP bus/controller cascading level
+ *
+ * Should be 7 so the total size of ::XBP_ADDR is 8 bytes.
+ */
+#define MAX_XBP_CASC_LVL 7
+
+
+/**
+ * @brief An XBP address specifier
+ *
+ * A generic scheme to address devices connected to cascaded controllers.
+ */
+typedef struct
+{
+ uint8_t hop_count; ///< Used as index to the addr array
+ XBP_PORT addr[MAX_XBP_CASC_LVL]; ///< An array of port numbers on cascaded controllers
+
+} XBP_ADDR;
+
+
+
+/**
+ * @brief A structure used to report XBP features and limits
+ */
+typedef struct
+{
+ uint32_t features; ///< Mask of XBP features, see ::XBP_FEAT_MASKS
+ uint32_t flags; ///< XBP flags, currently not used
+ uint32_t reserved[4]; ///< reserved, currently not used
+
+} XBP_LIMITS;
+
+
+
+/**
+ * @brief Enumeration of bits used to define ::XBP_FEAT_MASKS
+ */
+enum XBP_FEAT_BITS
+{
+ XBP_FEAT_BIT_NODES, ///< Supports ::XBP_NODE_LIMITS and associated structures
+ N_XBP_FEAT_BITS
+};
+
+
+/**
+ * @brief XBP feature masks used with ::XBP_LIMITS::features
+ *
+ * @see ::XBP_FEAT_BITS
+ */
+enum XBP_FEAT_MASKS
+{
+ XBP_FEAT_MASK_NODES = ( 1UL << XBP_FEAT_BIT_NODES ) ///< See ::XBP_FEAT_BIT_NODES
+};
+
+
+
+/**
+ * @brief Information on available XBP nodes
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ */
+typedef struct
+{
+ uint32_t node_count; ///< Number of XBP nodes available in the system
+ uint32_t reserved_0; ///< Currently reserved, always 0
+ uint32_t reserved_1; ///< Currently reserved, always 0
+ // TODO: do we need additional fields here?
+
+} XBP_NODE_LIMITS;
+
+
+
+/**
+ * @brief Possible states of an XBP device
+ *
+ * Used with ::XBP_NODE_INFO::state.
+ */
+enum XBP_DEVICE_STATES
+{
+ XBP_DEVICE_STATE_UNKNOWN,
+ XBP_DEVICE_STATE_NOT_AVAILABLE,
+ XBP_DEVICE_STATE_INITIALIZING,
+ XBP_DEVICE_STATE_AVAILABLE,
+ XBP_DEVICE_STATE_DISCONNECTED,
+ N_XBP_DEVICE_STATES
+};
+
+
+
+/**
+ * @brief Information on a specific XBP node
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ * The number of instances supported by a device is specified
+ * in ::XBP_NODE_LIMITS::node_count.
+ */
+typedef struct
+{
+ XBP_ADDR addr; ///< The address of the specific node
+
+ /// ::RECEIVER_INFO of the device connected to this node.
+ /// If no device is available then ::RECEIVER_INFO::model_code
+ /// is set to ::GPS_MODEL_UNKNOWN (== 0).
+ RECEIVER_INFO ri;
+
+ uint8_t state; ///< The device state, see ::XBP_DEVICE_STATES
+ uint8_t reserved; ///< Currently reserved, always 0
+ uint32_t flags; ///< Currently reserved, always 0
+
+} XBP_NODE_INFO;
+
+
+/**
+ * @brief Information on an XBP node with specific index
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ */
+typedef struct
+{
+ uint32_t idx; ///< node index, 0..::XBP_NODE_LIMITS::node_count-1
+ XBP_NODE_INFO node_info; ///< ::RECEIVER_INFO of the device behind this node
+
+} XBP_NODE_INFO_IDX;
+
+/** @} defgroup group_xbp */
/*------------------------------------------------------------------------*/
-/* Ephemeris parameters of one specific SV. Needed to compute the position */
-/* of a satellite at a given time with high precision. Valid for an */
-/* interval of 4 to 6 hours from start of transmission. */
-
-typedef struct
-{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
-
- HEALTH health; /* health indication of transmitting SV [---] */
- IOD IODC; /* Issue Of Data, Clock */
- IOD IODE2; /* Issue of Data, Ephemeris (Subframe 2) */
- IOD IODE3; /* Issue of Data, Ephemeris (Subframe 3) */
- T_GPS tt; /* time of transmission */
- T_GPS t0c; /* Reference Time Clock [---] */
- T_GPS t0e; /* Reference Time Ephemeris [---] */
-
- double sqrt_A; /* Square Root of semi-major Axis [sqrt(m)] */
- double e; /* Eccentricity [---] */
- double M0; /* +- Mean Anomaly at Ref. Time [rad] */
- double omega; /* +- Argument of Perigee [rad] */
- double OMEGA0; /* +- Longit. of Asc. Node of orbit plane [rad] */
- double OMEGADOT; /* +- Rate of Right Ascension [rad/sec] */
- double deltan; /* +- Mean Motion Diff. from computed value [rad/sec] */
- double i0; /* +- Inclination Angle [rad] */
- double idot; /* +- Rate of Inclination Angle [rad/sec] */
- double crc; /* +- Cosine Corr. Term to Orbit Radius [m] */
- double crs; /* +- Sine Corr. Term to Orbit Radius [m] */
- double cuc; /* +- Cosine Corr. Term to Arg. of Latitude [rad] */
- double cus; /* +- Sine Corr. Term to Arg. of Latitude [rad] */
- double cic; /* +- Cosine Corr. Term to Inclination Angle [rad] */
- double cis; /* +- Sine Corr. Term to Inclination Angle [rad] */
-
- double af0; /* +- Clock Correction Coefficient 0 [sec] */
- double af1; /* +- Clock Correction Coefficient 1 [sec/sec] */
- double af2; /* +- Clock Correction Coefficient 2 [sec/sec^2] */
- double tgd; /* +- estimated group delay differential [sec] */
-
- uint16_t URA; /* predicted User Range Accuracy */
-
- uint8_t L2code; /* code on L2 channel [---] */
- uint8_t L2flag; /* L2 P data flag [---] */
-} EPH;
+/**
+ * @brief Ephemeris parameters of one specific satellite
+ *
+ * Needed to compute the position of a satellite at a given time with
+ * high precision. Valid for an interval of 4 to 6 hours from start
+ * of transmission.
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ HEALTH health; ///< health indication of transmitting SV [---]
+ IOD IODC; ///< Issue Of Data, Clock
+ IOD IODE2; ///< Issue of Data, Ephemeris (Subframe 2)
+ IOD IODE3; ///< Issue of Data, Ephemeris (Subframe 3)
+ T_GPS tt; ///< time of transmission
+ T_GPS t0c; ///< Reference Time Clock [---]
+ T_GPS t0e; ///< Reference Time Ephemeris [---]
+
+ double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ double e; ///< Eccentricity [---]
+ double M0; ///< +- Mean Anomaly at Ref. Time [rad]
+ double omega; ///< +- Argument of Perigee [rad]
+ double OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad]
+ double OMEGADOT; ///< +- Rate of Right Ascension [rad/sec]
+ double deltan; ///< +- Mean Motion Diff. from computed value [rad/sec]
+ double i0; ///< +- Inclination Angle [rad]
+ double idot; ///< +- Rate of Inclination Angle [rad/sec]
+ double crc; ///< +- Cosine Corr. Term to Orbit Radius [m]
+ double crs; ///< +- Sine Corr. Term to Orbit Radius [m]
+ double cuc; ///< +- Cosine Corr. Term to Arg. of Latitude [rad]
+ double cus; ///< +- Sine Corr. Term to Arg. of Latitude [rad]
+ double cic; ///< +- Cosine Corr. Term to Inclination Angle [rad]
+ double cis; ///< +- Sine Corr. Term to Inclination Angle [rad]
+
+ double af0; ///< +- Clock Correction Coefficient 0 [sec]
+ double af1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+ double af2; ///< +- Clock Correction Coefficient 2 [sec/sec^2]
+ double tgd; ///< +- estimated group delay differential [sec]
+
+ uint16_t URA; ///< predicted User Range Accuracy
+
+ uint8_t L2code; ///< code on L2 channel [---]
+ uint8_t L2flag; ///< L2 P data flag [---]
+} EPH;
-/* Almanac parameters of one specific SV. A reduced precision set of */
-/* parameters used to check if a satellite is in view at a given time. */
-/* Valid for an interval of more than 7 days from start of transmission. */
+/**
+ * @brief Almanac parameters of one specific satellite
+ *
+ * A reduced precision set of parameters used to check if a satellite
+ * is in view at a given time. Valid for an interval of more than 7 days
+ * from start of transmission.
+ */
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 data are valid
- HEALTH health; /* [---] */
- T_GPS t0a; /* Reference Time Almanac [sec] */
+ HEALTH health; ///< [---]
+ T_GPS t0a; ///< Reference Time Almanac [sec]
- double sqrt_A; /* Square Root of semi-major Axis [sqrt(m)] */
- double e; /* Eccentricity [---] */
+ double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ double e; ///< Eccentricity [---]
- double M0; /* +- Mean Anomaly at Ref. Time [rad] */
- double omega; /* +- Argument of Perigee [rad] */
- double OMEGA0; /* +- Longit. of Asc. Node of orbit plane [rad] */
- double OMEGADOT; /* +- Rate of Right Ascension [rad/sec] */
- double deltai; /* +- [rad] */
- double af0; /* +- Clock Correction Coefficient 0 [sec] */
- double af1; /* +- Clock Correction Coefficient 1 [sec/sec] */
-} ALM;
+ double M0; ///< +- Mean Anomaly at Ref. Time [rad]
+ double omega; ///< +- Argument of Perigee [rad]
+ double OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad]
+ double OMEGADOT; ///< +- Rate of Right Ascension [rad/sec]
+ double deltai; ///< +- [rad]
+ double af0; ///< +- Clock Correction Coefficient 0 [sec]
+ double af1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+} ALM;
-/* Summary of configuration and health data of all SVs. */
+/**
+ * @brief Summary of configuration and health data of all satellites
+ */
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 data are valid
+
+ T_GPS tot_51; ///< time of transmission, page 51
+ T_GPS tot_63; ///< time of transmission, page 63
+ T_GPS t0a; ///< complete reference time almanac
- T_GPS tot_51; /* time of transmission, page 51 */
- T_GPS tot_63; /* time of transmission, page 63 */
- T_GPS t0a; /* complete reference time almanac */
+ CFG cfg[N_SVNO_GPS]; ///< 4 bit SV configuration code from page 63
+ HEALTH health[N_SVNO_GPS]; ///< 6 bit SV health codes from pages 51, 63
- CFG cfg[N_SVNO]; /* SV configuration from page 63 */
- HEALTH health[N_SVNO]; /* SV health from pages 51, 63 */
} CFGH;
/**
- @brief GPS UTC correction parameters
-*/
+ * @brief GPS %UTC correction parameters
+ *
+ * %UTC correction parameters basically as sent by the GPS satellites.
+ *
+ * The csum field is only used by the card's firmware to check the
+ * consistency of the structure in non-volatile memory.
+ *
+ * The field labeled valid indicates if the parameter set is valid, i.e.
+ * if it contains data received from the satellites.
+ *
+ * t0t, A0 and A1 contain fractional correction parameters for the current
+ * GPS-%UTC time offset in addition to the whole seconds. This is evaluated
+ * by the receivers' firmware to convert GPS time to %UTC time.
+ *
+ * The delta_tls field contains the current full seconds offset between
+ * GPS time and %UTC, which corresponds to the number of leap seconds inserted
+ * into the %UTC time scale since GPS was put into operation in January 1980.
+ *
+ * delta_tlfs holds the number of "future" leap seconds, i.e. the %UTC offset
+ * after the next leap second event defined by WNlsf and DNt.
+ *
+ * The fields WNlsf and DNt specify the GPS week number and the day number
+ * in that week for the end of which a leap second has been scheduled.
+ *
+ * @note: The satellites transmit WNlsf only as a signed 8 bit value, so it
+ * can only define a point in time which is +/- 127 weeks off the current time.
+ * The firmware tries to expand this based on the current week number, but
+ * the result is ambiguous if the leap second occurs or occurred more
+ * than 127 weeks in the future or past.
+ *
+ * So the leap second date should <b>only</b> be evaluated and displayed
+ * in a user interface if the fields delta_tls and delta_tlsf have
+ * different values, in which case there is indeed a leap second announcement
+ * inside the +/- 127 week range.
+ */
typedef struct
{
- CSUM csum; /**< Checksum of the remaining bytes */
- int16_t valid; /**< Flag indicating UTC parameters are valid */
+ CSUM csum; ///< Checksum of the remaining bytes
+ int16_t valid; ///< Flag indicating %UTC parameters are valid
- T_GPS t0t; /**< Reference Time UTC Parameters [wn|sec] */
- double A0; /**< +- Clock Correction Coefficient 0 [sec] */
- double A1; /**< +- Clock Correction Coefficient 1 [sec/sec] */
+ T_GPS t0t; ///< Reference Time %UTC Parameters [wn|sec]
+ double A0; ///< +- Clock Correction Coefficient 0 [sec]
+ double A1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+
+ uint16_t WNlsf; ///< Week number of nearest leap second
+ int16_t DNt; ///< The day number at the end of which a leap second occurs
+ int8_t delta_tls; ///< Current %UTC offset to GPS system time [sec]
+ int8_t delta_tlsf; ///< Future %UTC offset to GPS system time after next leap second transition [sec]
- uint16_t WNlsf; /**< Week number of nearest leap second */
- int16_t DNt; /**< The day number at the end of which a leap second occurs */
- int8_t delta_tls; /**< Current UTC offset to GPS system time [sec] */
- int8_t delta_tlsf; /**< Future UTC offset to GPS system time after next leap second transition [sec] */
} UTC;
#define _mbg_swab_utc_parm( _p ) \
@@ -4300,38 +12059,42 @@ typedef struct
-/* Ionospheric correction parameters */
-
+/**
+ * @brief Ionospheric 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 data are valid
- double alpha_0; /* Ionosph. Corr. Coeff. Alpha 0 [sec] */
- double alpha_1; /* Ionosph. Corr. Coeff. Alpha 1 [sec/deg] */
- double alpha_2; /* Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2] */
- double alpha_3; /* Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3] */
+ double alpha_0; ///< Ionosph. Corr. Coeff. Alpha 0 [sec]
+ double alpha_1; ///< Ionosph. Corr. Coeff. Alpha 1 [sec/deg]
+ double alpha_2; ///< Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2]
+ double alpha_3; ///< Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3]
- double beta_0; /* Ionosph. Corr. Coeff. Beta 0 [sec] */
- double beta_1; /* Ionosph. Corr. Coeff. Beta 1 [sec/deg] */
- double beta_2; /* Ionosph. Corr. Coeff. Beta 2 [sec/deg^2] */
- double beta_3; /* Ionosph. Corr. Coeff. Beta 3 [sec/deg^3] */
-} IONO;
+ double beta_0; ///< Ionosph. Corr. Coeff. Beta 0 [sec]
+ double beta_1; ///< Ionosph. Corr. Coeff. Beta 1 [sec/deg]
+ double beta_2; ///< Ionosph. Corr. Coeff. Beta 2 [sec/deg^2]
+ double beta_3; ///< Ionosph. Corr. Coeff. Beta 3 [sec/deg^3]
+} IONO;
-/* GPS ASCII message */
+/**
+ * @brief GPS ASCII message
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
- char s[23]; /* 22 chars GPS ASCII message plus trailing zero */
+ CSUM csum; ///< checksum of the remaining bytes */
+ int16_t valid; ///< flag data are valid
+ char s[23]; ///< 22 chars GPS ASCII message plus trailing zero
+
} ASCII_MSG;
-enum
+enum GPS_PLATFORMS
{
GPS_PLATFORM_PORTABLE,
GPS_PLATFORM_FIXED,
@@ -4344,7 +12107,7 @@ enum
GPS_PLATFORM_AIRBORNE_4G,
N_GPS_PLATFORMS
};
-
+
#define GPS_PLATFORM_STRS \
{ \
@@ -4361,15 +12124,16 @@ enum
-enum
+enum TIME_MODES
{
TIME_MODE_DISABLED,
TIME_MODE_SURVEY_IN,
- TIME_MODE_FIXED
+ TIME_MODE_FIXED,
+ N_TIME_MODES
};
-
+
typedef struct
{
uint32_t time_mode;
@@ -4379,17 +12143,18 @@ typedef struct
int32_t fixedPosY; // cm
int32_t fixedPosZ; // cm
uint32_t fixedPosVar; // cm
- uint32_t flags; // currently 0
- uint32_t reserved; // currently 0
+ 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.
-*/
+/**
+ * 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;
@@ -4399,15 +12164,15 @@ typedef struct
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 */
+} NAV_ENGINE_SETTINGS;
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
#endif
+/* End of header body */
#endif /* _GPSDEFS_H */
diff --git a/mbglib/common/gpsserio.c b/mbglib/common/gpsserio.c
index 7ad0374..d0381aa 100644
--- a/mbglib/common/gpsserio.c
+++ b/mbglib/common/gpsserio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsserio.c 1.9 2009/09/01 09:51:56Z martin REL_M $
+ * $Id: gpsserio.c 1.13.1.3 2015/07/24 11:07:17Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,24 @@
*
* -----------------------------------------------------------------------
* $Log: gpsserio.c $
- * Revision 1.9 2009/09/01 09:51:56Z martin
+ * Revision 1.13.1.3 2015/07/24 11:07:17Z martin
+ * Revision 1.13.1.2 2015/05/20 12:21:23 martin
+ * Revision 1.13.1.1 2015/05/19 13:20:21 daniel
+ * Preliminary support for USB_DIRECT_IO
+ * Revision 1.13 2015/05/13 13:47:52 martin
+ * Support new libusb v1.0 and newer which is not compatible with v0.1x.
+ * Use preprocessor symbol MBG_TGT_POSIX.
+ * Use Meinberg error codes from mbgerror.h.
+ * Support XBP addressing.
+ * Updated doxygen-style comments.
+ * Revision 1.12 2012/03/08 12:09:38 martin
+ * Removed an obsolete printf().
+ * Revision 1.11 2012/03/06 15:41:24Z martin
+ * Use mbgserio_read/write functions rather than macros.
+ * Save system timestamp on start of incoming binary packet.
+ * Revision 1.10 2011/07/29 09:53:43Z daniel
+ * Account for communication via USB if _USE_USB_IO is defined
+ * 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.
@@ -47,13 +64,14 @@
#include <gpsserio.h>
#undef _GPSSERIO
+#include <mbgerror.h>
+
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
-#if defined( MBG_TGT_UNIX )
+#if defined( MBG_TGT_POSIX )
#include <unistd.h>
-//##++++ #include <sys/time.h>
#endif
#if _USE_ENCRYPTION
@@ -62,23 +80,65 @@
-/*--------------------------------------------------------------
- * Name: msg_csum_update()
- *
- * Purpose: Compute a checksum about a number of bytes
- * starting with a given initial value.
- *
- * Input: CSUM csum the initial value
- * uint8_t *p address of the first byte
- * int n the number of bytes
+#if _USE_SERIAL_IO_FTDI
+
+/*HDR*/
+/**
+ * @brief Translate a FTDI API status code to one of the @ref MBG_ERROR_CODES
*
- * Output: --
+ * @param[in] status A status code defined by the FTDI API interface
*
- * Ret val: the checksum
- *+------------------------------------------------------------*/
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int mbg_ftdi_ft_status_to_mbg( FT_STATUS status )
+{
+ switch ( status )
+ {
+ case FT_OK: return MBG_SUCCESS;
+ case FT_INVALID_HANDLE: return MBG_ERR_INV_HANDLE;
+ case FT_DEVICE_NOT_FOUND: return MBG_ERR_NO_DEV;
+ case FT_DEVICE_NOT_OPENED: return MBG_ERR_INV_HANDLE;
+ case FT_IO_ERROR: return MBG_ERR_IO;
+ // case FT_INSUFFICIENT_RESOURCES: return ;
+ case FT_INVALID_PARAMETER: return MBG_ERR_INV_PARM;
+ case FT_INVALID_BAUD_RATE: return MBG_ERR_INV_PARM;
+
+ // case FT_DEVICE_NOT_OPENED_FOR_ERASE: return ;
+ // case FT_DEVICE_NOT_OPENED_FOR_WRITE: return ;
+ // case FT_FAILED_TO_WRITE_DEVICE: return ;
+ case FT_EEPROM_READ_FAILED: return MBG_ERR_IO;
+ case FT_EEPROM_WRITE_FAILED: return MBG_ERR_IO;
+ // case FT_EEPROM_ERASE_FAILED: return ;
+ // case FT_EEPROM_NOT_PRESENT: return ;
+ // case FT_EEPROM_NOT_PROGRAMMED: return ;
+ case FT_INVALID_ARGS: return MBG_ERR_INV_PARM;
+ case FT_NOT_SUPPORTED: return MBG_ERR_NOT_SUPP_BY_DEV;
+ case FT_OTHER_ERROR: return MBG_ERR_UNSPEC;
+ case FT_DEVICE_LIST_NOT_READY: return MBG_ERR_NO_DEV;
+ }
+
+ return MBG_ERR_UNSPEC;
+
+} // mbg_ftdi_ft_status_to_mbg
+
+#endif // _USE_SERIAL_IO_FTDI
+
+
/*HDR*/
-CSUM msg_csum_update( CSUM csum, uint8_t *p, int n )
+/**
+ * @brief Compute a simple binary checksum
+ *
+ * Compute a checksum about a number of bytes starting
+ * with a given initial value.
+ *
+ * @param[in] csum the initial value
+ * @param[in] p pointer to a buffer of data bytes
+ * @param[in] n the number of bytes in the buffer
+ *
+ * @return the computed checksum
+ */
+CSUM msg_csum_update( CSUM csum, const uint8_t *p, int n )
{
int i;
@@ -91,26 +151,19 @@ CSUM msg_csum_update( CSUM csum, uint8_t *p, int n )
-/*--------------------------------------------------------------
- * Name: msg_csum()
- *
- * Purpose: Compute a message checksum over a number
- * of bytes.
- *
- * ATTENTION: This function differs from the
- * checksum() function which is used to compute
- * the checksum of battery-buffered variables!
+/*HDR*/
+/**
+ * @brief Compute a checksum for a binary message
*
- * Input: uint8_t *p address of the first byte
- * int n the number of bytes
+ * @note This function differs from the checksum() function
+ * used to compute the checksum of battery-buffered variables.
*
- * Output: --
+ * @param[in] p pointer to a buffer of data bytes
+ * @param[in] n the number of bytes in the buffer
*
- * Ret val: the checksum
- *+------------------------------------------------------------*/
-
-/*HDR*/
-CSUM msg_csum( uint8_t *p, int n )
+ * @return the computed checksum
+ */
+CSUM msg_csum( const uint8_t *p, int n )
{
return msg_csum_update( 0, p, n );
@@ -118,22 +171,17 @@ CSUM msg_csum( uint8_t *p, int n )
-/*--------------------------------------------------------------
- * Name: msg_hdr_csum()
- *
- * Purpose: Compute the checksum of a message header.
- *
- * Input: MSG_HDR *pmh pointer to a message header
+/*HDR*/
+/**
+ * @brief Compute the checksum of a binary message header
*
- * Output: --
+ * @param[in] pmh pointer to a binary message header
*
- * Ret val: the checksum
- *+------------------------------------------------------------*/
-
-/*HDR*/
-CSUM msg_hdr_csum( MSG_HDR *pmh )
+ * @return the computed checksum
+ */
+CSUM msg_hdr_csum( const MSG_HDR *pmh )
{
- return msg_csum( (uint8_t *) pmh,
+ return msg_csum( (uint8_t *) pmh,
sizeof( *pmh ) - sizeof( pmh->hdr_csum ) );
} /* msg_hdr_csum */
@@ -141,28 +189,42 @@ CSUM msg_hdr_csum( MSG_HDR *pmh )
/*HDR*/
-int chk_hdr_csum( MSG_HDR *pmh )
+/**
+ * @brief Check if the header checksum of a binary message is valid
+ *
+ * @param[in] pmh pointer to a binary message header
+ *
+ * @return ::MBG_SUCCESS or ::MBG_ERR_HDR_CSUM
+ */
+int chk_hdr_csum( const MSG_HDR *pmh )
{
CSUM calc_csum = msg_hdr_csum( pmh );
if ( calc_csum != pmh->hdr_csum )
- return -1; /* error */
+ return MBG_ERR_HDR_CSUM; /* error */
- return 0;
+ return MBG_SUCCESS;
} /* chk_hdr_csum */
/*HDR*/
-int chk_data_csum( MBG_MSG_BUFF *pmb )
+/**
+ * @brief Check if the data checksum of a binary message is valid
+ *
+ * @param[in] pmb pointer to a binary message buffer
+ *
+ * @return ::MBG_SUCCESS or ::MBG_ERR_DATA_CSUM
+ */
+int chk_data_csum( const MBG_MSG_BUFF *pmb )
{
CSUM calc_csum = msg_csum( pmb->u.bytes, pmb->hdr.len );
if ( calc_csum != pmb->hdr.data_csum )
- return -1; /* error */
+ return MBG_ERR_DATA_CSUM; /* error */
- return 0;
+ return MBG_SUCCESS;
} /* chk_data_csum */
@@ -198,51 +260,46 @@ int chk_data_csum( MBG_MSG_BUFF *pmb )
#endif
-//----------------------------------------------------------------------
-// in encrypted mode data packets are packed into a new encrypted packet
-// where InitVect, XMSG_BUFF and Fill bytes form the new data section
-//
-// Format : [MSG_HDR][InitVect][XMSG_BUFF][FillBytes]
-// |<-HDR->|<----------- DATA ------------>|
-// |<-- plaintext -->|<---- encrypted ---->|
-//
-// - MSG_HDR : Standard Binary Message Handler with
-// cmd = GPS_CRYPTED_PACKET, len is size of complete
-// block, data_csum calculated over complete block
-// ( InitVect, XMSG_BUFF and FILL_BYTES )
-// - InitVect : random number for AES128 CFM initialization
-// - XMSG_BUFF : Message buffer as prepared for unencrypted transfer
-// consists of MSG_HEADER and DATA, will be completely
-// encrypted before transmission
-// - FillBytes : Bytes to fill up for the next 128Bit/16Byte boundary
-//----------------------------------------------------------------------
/*HDR*/
+/**
+ * @brief Encrypt a binary message
+ *
+ * In encryption mode the original packet is encrypted and put
+ * as data portion into an envelope package.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in,out] pcmp Pointer to encryption settings
+ * @param[in,out] pmb Pointer to a binary message buffer
+ *
+ * @return the number of bytes of the encrypted message, or one of the @ref MBG_ERROR_CODES
+ */
int encrypt_message( MBG_MSG_CTL *pmctl, CRYPT_MSG_PREFIX *pcmp, MBG_MSG_BUFF *pmb )
{
- int n_bytes = pmb->hdr.len + sizeof( pmb->hdr ); /* size of unencrypted msg */
+ int n_bytes = pmb->hdr.len + sizeof( pmb->hdr ); // size of unencrypted msg
int rc;
- /* correct original msg size for 16 byte boundary */
+ // align original msg size with 16 byte boundary
n_bytes += AES_BLOCK_SIZE - ( n_bytes % AES_BLOCK_SIZE );
- /* encrypt original message */
+ // encrypt original message
rc = aes_encrypt_buff( (uint8_t *) pmb, pmctl->aes_keyvect, pmctl->aes_initvect, n_bytes );
- if ( rc < 0 )
- return rc; // encryption failed
+ if ( rc < 0 ) // -1 on error
+ return MBG_ERR_ENCRYPT; // encryption failed
- /* copy AES init vector into encrypted message */
+ // copy AES init vector into encrypted message
+ //##++ check types of aes_initvect fields
memcpy( pcmp->aes_initvect, pmctl->aes_initvect, sizeof( pcmp->aes_initvect ) );
pcmp->hdr.cmd = GPS_CRYPTED_PACKET;
- pcmp->hdr.len = n_bytes + sizeof( pcmp->aes_initvect );
+ pcmp->hdr.len = (uint16_t) ( n_bytes + sizeof( pcmp->aes_initvect ) );
pcmp->hdr.data_csum = msg_csum( pcmp->aes_initvect, sizeof( pcmp->aes_initvect ) );
- pcmp->hdr.data_csum = msg_csum_update( pcmp->hdr.data_csum,
- (uint8_t *) pmb, n_bytes );
+ pcmp->hdr.data_csum = msg_csum_update( pcmp->hdr.data_csum,
+ (uint8_t *) pmb, n_bytes );
pcmp->hdr.hdr_csum = msg_hdr_csum( &pcmp->hdr );
@@ -253,56 +310,84 @@ int encrypt_message( MBG_MSG_CTL *pmctl, CRYPT_MSG_PREFIX *pcmp, MBG_MSG_BUFF *p
/*HDR*/
+/**
+ * @brief Decrypt an encrypted binary message
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
int decrypt_message( MBG_MSG_CTL *pmctl )
{
MBG_MSG_RCV_CTL *prctl = &pmctl->rcv;
MBG_MSG_BUFF *pmb = prctl->pmb;
CRYPT_MSG_DATA *pcmd = &pmb->u.crypt_msg_data;
int rc;
+ int len;
if ( pmb->hdr.len < AES_BLOCK_SIZE )
return 0;
- rc = aes_decrypt_buff( (unsigned char *) &pcmd->enc_msg,
- pmctl->aes_keyvect,
+ rc = aes_decrypt_buff( (uint8_t *) &pcmd->std_msg,
+ pmctl->aes_keyvect,
pcmd->aes_initvect,
pmb->hdr.len - sizeof( pcmd->aes_initvect )
- );
+ );
- if ( rc < 0 ) /* decryption error */
+ if ( rc < 0 ) // decryption error
{
prctl->flags |= MBG_MSG_RCV_CTL_DECRYPT_ERR;
- return TR_DECRYPTION;
+ return MBG_ERR_DECRYPT;
}
- /* packet decrypted successfully. */
+ // 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,
+ // 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
+ //##+++++++++ TODO
+ // A potential problem arises if the garbage data len exceeds
+ // the buffer size and the data csum is computed using
+ // that length, which goes beyond the buffer limit.
+ // also, me must not copy more than the sizeof MBG_STD_MSG
+ // bytes to avoid a buffer overflow.
+ // We should really check the decrypted header here.
- /* 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 ) );
+ len = pcmd->std_msg.hdr.len + sizeof( pcmd->std_msg.hdr );
- /* now check the csums of the decrypted packet */
+ if ( len > sizeof( MBG_STD_MSG ) )
+ len = sizeof( MBG_STD_MSG );
- if ( chk_hdr_csum( &pmb->hdr ) < 0 ) /* error */
- return TR_CSUM_DATA; /* invalid header checksum received */
+ // copy the decrypted message to the head of the buffer
+ memcpy( pmb, &pcmd->std_msg, len );
- if ( chk_data_csum( pmb ) < 0 ) /* error */
- return TR_CSUM_DATA; /* invalid header checksum received */
- return 0;
+ // now check the CSUMs of the decrypted packet
+ //##++++ TODO: which error code to return? This was actually the data portion of the encrypted msg
+
+ if ( chk_hdr_csum( &pmb->hdr ) != MBG_SUCCESS )
+ return MBG_ERR_DECRYPT; // invalid header checksum due to faulty decryption
+
+ if ( chk_data_csum( pmb ) != MBG_SUCCESS )
+ return MBG_ERR_DECRYPT; // invalid data checksum due to faulty decryption
+
+ return MBG_SUCCESS;
} /* decrypt_message */
/*HDR*/
+/**
+ * @brief Set communication channel to specified encryption mode
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] mode Encryption mode, usually ::MBG_XFER_MODE_ENCRYPTED
+ * @param[in] key The crypto key (password) to be used
+ */
void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, const char *key )
{
int i;
@@ -323,59 +408,104 @@ void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, const char *key )
-/*--------------------------------------------------------------
- * Name: xmt_tbuff()
+static /*HDR*/
+/**
+ * @brief Copy array of bytes in reverse order
*
- * Purpose: Compute checksums and complete the message
- * header, then transmit both header and data.
- * The caller must have copied the data to be
- * sent to the data field of the transmit buffer
- * and have set up the cmd field and the
- * len field of pm->hdr.
+ * Can be used if the destination address is in the same buffer
+ * behind the source address, so the source address would be
+ * overwritten by a normal memcpy().
*
- * Input: MBG_MSG_BUFF *pm pointer to the message buffer
- *
- * Output: --
- *
- * Ret val: --
- *+------------------------------------------------------------*/
+ * @param[out] dst Destination address behind the source address
+ * @param[in] src Source address
+ * @param[in] n_bytes Number of bytes to copy
+ */
+void memcpy_reverse( void *dst, const void *src, int n_bytes )
+{
+ if ( n_bytes ) // just to be sure it isn't 0
+ {
+ uint8_t *dstp = ( (uint8_t *) dst ) + n_bytes;
+ uint8_t *srcp = ( (uint8_t *) src ) + n_bytes;
+
+ while ( --n_bytes )
+ *(--dstp) = *(--srcp);
+ }
+
+} // memcpy_reverse
+
+
/*HDR*/
-int xmt_tbuff( MBG_MSG_CTL *pmctl )
+/**
+ * @brief Complete message header and transmit message
+ *
+ * Compute checksums and complete the message header,
+ * then transmit both header and data. The caller must
+ * have copied the data to be sent to the data field
+ * of the transmit buffer and have set up the cmd and
+ * len fields of the message header.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ *
+ * @return one of the @ref MBG_RETURN_CODES
+ */
+int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr )
{
static const char soh = START_OF_HEADER;
MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
- int n_bytes = pmb->hdr.len + sizeof( pmb->hdr );
- #if _USE_ENCRYPTION || _USE_SOCKET_IO
- int rc;
- #endif
+ int msg_len = sizeof( pmb->hdr ) + pmb->hdr.len;
+ int rc = MBG_ERR_UNSPEC;
#if _USE_ENCRYPTION
- CRYPT_MSG_PREFIX cm_pfx = { { 0 } };
+ CRYPT_MSG_PREFIX cm_pfx;
#endif
// Set up the checksums of the unencrypted packet.
pmb->hdr.data_csum = msg_csum( pmb->u.bytes, pmb->hdr.len );
pmb->hdr.hdr_csum = msg_hdr_csum( &pmb->hdr );
+ // If an XBP address has been specified we convert
+ // the original msg into an XBP msg.
+ if ( p_addr )
+ {
+ // Move the original msg to the data part of an XBP msg
+ // don't just use memcpy here since the destination memory area
+ // overlaps the source memory area.
+ memcpy_reverse( &pmb->u.xbp_msg_data.std_msg.hdr, &pmb->hdr, msg_len );
+
+ // Fill in the specified XBP address.
+ pmb->u.xbp_msg_data.xbp_addr = *p_addr;
+
+ // Set up the new msg header as XPB msg.
+ pmb->hdr.cmd = GPS_XBP_PACKET;
+ msg_len += sizeof( pmb->u.xbp_msg_data.xbp_addr );
+ pmb->hdr.len = msg_len;
+ pmb->hdr.data_csum = msg_csum( pmb->u.bytes, pmb->hdr.len );
+ pmb->hdr.hdr_csum = msg_hdr_csum( &pmb->hdr );
+ msg_len += sizeof( pmb->hdr );
+ }
+
#if _USE_ENCRYPTION
- if ( pmctl->xmt.xfer_mode == MBG_XFER_MODE_ENCRYTED )
+ if ( pmctl->xmt.xfer_mode == MBG_XFER_MODE_ENCRYPTED )
{
+ memset( &cm_pfx, 0, sizeof( cm_pfx ) );
+
rc = encrypt_message( pmctl, &cm_pfx, pmb );
+ // on error, one of the MBG_ERROR_CODES, else number of bytes encrypted
- if ( rc < 0 )
- return rc; // an error occurred
+ if ( rc < 0 ) // error
+ goto out;
- n_bytes = rc;
+ msg_len = rc;
}
#endif
- // n_bytes now contains the original msg data len which may
- // possibly have been rounded up by the encryption routine.
+ // msg_len now contains the original msg data len which may
+ // possibly have been rounded up by the encryption routine.
//
- // The full msg consists of the CRYPT_MSG_PREFIX (if the msg
- // has been encrypted), the msg header, and n_bytes of data.
-
+ // The full msg consists of the CRYPT_MSG_PREFIX (if the msg
+ // has been encrypted), the msg header, and msg_len of data.
switch ( pmctl->conn_type )
{
#if _USE_SERIAL_IO
@@ -385,103 +515,218 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl )
// Note: encrypted msgs over serial are not yet supported.
- _mbgserio_write( port_handle, &soh, sizeof( soh ) );
- _mbgserio_write( port_handle, pmb, n_bytes );
+ rc = mbgserio_write( port_handle, &soh, sizeof( soh ) );
+
+ if ( rc < 0 ) // error
+ goto out;
+
+ if ( rc != sizeof( soh ) )
+ goto out_write_failed;
+
+ rc = mbgserio_write( port_handle, pmb, msg_len );
+
+ if ( rc < 0 ) // error
+ goto out;
+
+ if ( rc != msg_len ) // error
+ goto out_write_failed;
+
} break;
#endif // _USE_SERIAL_IO
+ #if _USE_SERIAL_IO_FTDI
+ case MBG_CONN_TYPE_SERIAL_FTDI:
+ {
+ // Yet this is anyway supported under Windows only, so we can
+ // safely use Windows-specific types as expected by the FTDI API.
+ DWORD bytes_written;
+ FT_HANDLE port_handle = pmctl->st.ftdiio.port_handle;
+ FT_STATUS status;
+
+ // Note: encrypted msgs over serial are not yet supported.
+ status = FT_Write( port_handle, (LPVOID) &soh, sizeof( soh ), &bytes_written );
+
+ if ( status != FT_OK )
+ {
+ rc = mbg_ftdi_ft_status_to_mbg( status );
+ goto out;
+ }
+
+ if ( bytes_written != sizeof( soh ) )
+ goto out_write_failed;
+
+ status = FT_Write( port_handle, pmb, msg_len, &bytes_written );
+
+ if ( status != FT_OK )
+ {
+ rc = mbg_ftdi_ft_status_to_mbg( status );
+ goto out;
+ }
+
+ if ( bytes_written != (DWORD) msg_len )
+ goto out_write_failed;
+
+ } break;
+ #endif // _USE_SERIAL_IO_FTDI
+
#if _USE_SOCKET_IO
case MBG_CONN_TYPE_SOCKET:
{
- uint8_t net_xmt_buffer[sizeof( MBG_MSG_BUFF ) + 1] = { 0 };
- uint8_t *p = net_xmt_buffer;
+ uint8_t sock_xmt_buffer[sizeof( MBG_MSG_BUFF ) + 1];
+ uint8_t *p = sock_xmt_buffer;
+
+ #if defined( DEBUG )
+ memset( sock_xmt_buffer, 0, sizeof( sock_xmt_buffer ) ); // only to simplify debugging
+ #endif
*p++ = soh;
- rc = n_bytes; // save the value of n_bytes
+ rc = msg_len; // save the value of msg_len
#if _USE_ENCRYPTION
- if ( pmctl->xmt.xfer_mode == MBG_XFER_MODE_ENCRYTED )
+ if ( pmctl->xmt.xfer_mode == MBG_XFER_MODE_ENCRYPTED )
{
memcpy( p, &cm_pfx, sizeof( cm_pfx ) );
p += sizeof( cm_pfx );
- n_bytes += sizeof( cm_pfx );
+ msg_len += sizeof( cm_pfx );
}
#endif
memcpy( p, pmb, rc );
p += rc;
- n_bytes++; // also account for SOH
+ msg_len += sizeof( soh ); // also account for SOH
- rc = sendto( pmctl->st.sockio.sockfd, net_xmt_buffer, n_bytes, 0,
- (const struct sockaddr *) &pmctl->st.sockio.addr,
+ rc = sendto( pmctl->st.sockio.sockfd, sock_xmt_buffer, msg_len, 0,
+ (const struct sockaddr *) &pmctl->st.sockio.addr,
sizeof( pmctl->st.sockio.addr ) );
- if ( rc < 0 )
- goto fail;
+ if ( rc < 0 ) // on error: -1 on Linux, SOCKET_ERROR == -1 on Windows
+ {
+ rc = mbg_get_last_socket_error( "sendto failed in xmt_tbuff" );
+ goto out;
+ }
+
+ if ( rc != msg_len )
+ goto out_write_failed;
} break;
#endif // _USE_SOCKET_IO
+ #if _USE_USB_IO
+ case MBG_CONN_TYPE_USB:
+ {
+ uint8_t usb_xmt_buffer[sizeof( MBG_MSG_BUFF ) + 1];
+ uint8_t *p = usb_xmt_buffer;
+
+ #if defined( DEBUG )
+ memset( usb_xmt_buffer, 0, sizeof( usb_xmt_buffer ) ); // only to simplify debugging
+ #endif
+
+ *p = soh;
+ memcpy( p + 1, pmb, msg_len );
+ msg_len++; // also account for SOH
+
+ // Note: encrypted msgs over USB are not yet supported.
+ rc = mbgusbio_write( &pmctl->st.usbio, p, msg_len, 1000 );
+
+ if ( rc < 0 ) // error
+ goto out;
+
+ if ( rc != msg_len )
+ goto out_write_failed;
+
+ } break;
+ #endif // _USE_USB_IO
+
+ #if _USE_USB_DIRECT_IO
+ case MBG_CONN_TYPE_USB_DIRECT_IO:
+ {
+ ssize_t bytes;
+ uint8_t usb_xmt_buffer[sizeof( MBG_MSG_BUFF ) + 1];
+ uint8_t *p = usb_xmt_buffer;
+
+ #if defined( DEBUG )
+ memset( usb_xmt_buffer, 0, sizeof( usb_xmt_buffer ) ); // only to simplify debugging
+ #endif
+
+ *p = soh;
+ memcpy( p + 1, pmb, msg_len );
+ msg_len++; // also account for SOH
+
+ // Note: encrypted msgs over direct USB I/O are not yet supported.
+ bytes = write( pmctl->st.usbdio.usbdiofd, p, msg_len );
+
+ if ( bytes < 0 ) // error
+ {
+ rc = mbg_get_last_error( "write failed for USB direct I/O" );
+ goto out;
+ }
+
+ if ( bytes != msg_len )
+ goto out_write_failed;
+
+ } break;
+ #endif
+
default:
- goto fail;
+ rc = MBG_ERR_NOT_SUPP_ON_OS;
+ goto out;
+
+ } // switch
- } /* switch */
+ rc = MBG_SUCCESS;
+ goto out;
- return 0;
+out_write_failed:
+ rc = MBG_ERR_BYTES_WRITTEN;
-fail:
- return -1; //##++
+out:
+ return rc;
} /* xmt_tbuff */
-/*--------------------------------------------------------------
- * Name: xmt_cmd()
- *
- * Purpose: Send a command without parameters
+/*HDR*/
+/**
+ * @brief Send a binary command message without parameters
*
- * Input: MBG_MSG_BUFF *pm pointer to the message buffer
- * ushort cmd the command code
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
*
- * Output: --
+ * @return One of the @ref MBG_RETURN_CODES
*
- * Ret val: --
- *+------------------------------------------------------------*/
-
-/*HDR*/
-int xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
+ * @see ::xmt_cmd_us
+ */
+int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd )
{
MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
pmb->hdr.len = 0;
pmb->hdr.cmd = cmd;
- return xmt_tbuff( pmctl );
+ return xmt_tbuff( pmctl, p_addr );
} /* xmt_cmd */
-/*--------------------------------------------------------------
- * Name: xmt_cmd_us()
- *
- * Purpose: Send a command that needs one parameter with
- * type ushort.
+/*HDR*/
+/**
+ * @brief Send a binary command message with ushort (16 bit) parameter
*
- * Input: MBG_MSG_BUFF *pm pointer to the message buffer
- * ushort cmd the command code
- * ushort us the parameter
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] us The 16 bit message parameter (data)
*
- * Output: --
+ * @return One of the @ref MBG_RETURN_CODES
*
- * Ret val: --
- *+------------------------------------------------------------*/
-
-/*HDR*/
-int xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us )
+ * @see ::xmt_cmd
+ */
+int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us )
{
MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
@@ -489,30 +734,26 @@ int xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us )
pmb->hdr.len = sizeof( pmb->u.msg_data.us );
pmb->hdr.cmd = cmd;
- return xmt_tbuff( pmctl );
+ return xmt_tbuff( pmctl, p_addr );
} /* xmt_cmd_us */
-/*--------------------------------------------------------------
- * Name: check_transfer()
- *
- * Purpose: Check the sequence of incoming characters for
- * blocks of binary data. Blocks of data are
- * saved in a MBG_MSG_BUFF variable and the
- * caller checks the return value to get the
- * receive status.
+/*HDR*/
+/**
+ * @brief Check an incoming data stream for a binary message
*
- * Input: MSG_RCV_CTL *pctl pointer to rcv ctrl structure
- * uint8_t c the latest char that came in
+ * Check the sequence of incoming characters for blocks of
+ * binary message data. Binary messages are saved in a buffer
+ * which is part of the ::MBG_MSG_RCV_CTL structure and the
+ * caller checks the return value to get the receive status.
*
- * Output: --
+ * @param[in,out] prctl Pointer to a valid receive control structure
+ * @param[in] c A byte from the incoming data stream
*
- * Ret val: see header file for valid codes
- *+------------------------------------------------------------*/
-
-/*HDR*/
+ * @return One of the ::TR_STATUS_CODES
+ */
int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
{
MBG_MSG_BUFF *pmb = prctl->pmb;
@@ -524,6 +765,7 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c )
return TR_WAITING; /* ignore this character */
/* initialize receiving */
+ mbg_tmo_get_time( &prctl->tstamp );
prctl->cur = (uint8_t *) pmb; /* first byte of buffer */
prctl->cnt = sizeof( *pmh ); /* prepare to rcv msg header */
prctl->flags = 0;
@@ -593,4 +835,3 @@ msg_complete:
-
diff --git a/mbglib/common/gpsserio.h b/mbglib/common/gpsserio.h
index de5fa04..d1d4d26 100644
--- a/mbglib/common/gpsserio.h
+++ b/mbglib/common/gpsserio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsserio.h 1.34 2011/04/15 13:12:02Z martin REL_M $
+ * $Id: gpsserio.h 1.48.1.1 2015/07/24 11:07:39Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -31,7 +31,63 @@
*
* -----------------------------------------------------------------------
* $Log: gpsserio.h $
- * Revision 1.34 2011/04/15 13:12:02Z martin
+ * Revision 1.48.1.1 2015/07/24 11:07:39Z martin
+ * Revision 1.48 2015/07/06 15:23:51 martin
+ * Updated function prototypes.
+ * Revision 1.47 2015/05/13 13:52:57 martin
+ * Support XBP addressing.
+ * Fixed misspelled MBG_XFER_MODE_ENCRYPTED.
+ * Renamed some GPS cmd codes to more intuitive names.
+ * Added GPS cmd CMD codes for FDM.
+ * New cmd code GPS_XMR_EXT_SRC_INFO_IDX.
+ * Removed trailing whitespace.
+ * Updated doxygen-style comments.
+ * Updated function prototypes.
+ * Revision 1.46 2014/07/17 09:47:21 martin
+ * New command codes GPS_GPIO_STATUS_IDX
+ * and GPS_XMR_HOLDOVER_STATUS.
+ * Updated doxygen comments.
+ * Revision 1.45 2014/05/27 08:58:47 martin
+ * Defined a some new command codes and added
+ * associated fields to MSG_DATA union.
+ * Introduced MBG_SOCK_FD type.
+ * Use new preprocessor symbol MBG_TGT_POSIX.
+ * Support new libusb.
+ * Conditional FTDI serial interface support.
+ * Account for definitions renamed elsewhere.
+ * Simplified declaration of code/name tables.
+ * Conditionally use new CHK_TSTR_FNC type.
+ * Huge rework of comments in doxygen format.
+ * Revision 1.44 2013/04/04 09:03:29Z martin
+ * Support HaveQuick configuration.
+ * Revision 1.43 2013/01/30 16:07:49 martin
+ * Changed definition of transfer status codes to an enum
+ * with appropriate comments.
+ * Added union TZCODE_UNION.
+ * Fixed some doxygen comments.
+ * Revision 1.42 2013/01/16 11:48:36Z martin
+ * Support IMS and XMR_HOLDOVER_INTV.
+ * Revision 1.41 2012/10/30 16:25:15 martin
+ * Added GPS_WILDCARD cmd code.
+ * Account for changed chk_tstr_func return code.
+ * Added completion codes TR_COMPLETE_TSTR and TR_RCVD_NACK.
+ * Revision 1.40 2012/04/11 16:03:29 martin
+ * Fixed some doxygen stuff.
+ * Revision 1.39 2012/03/08 15:34:18Z martin
+ * Added default setting for _USE_USB_IO.
+ * Revision 1.38 2012/03/06 15:33:43 martin
+ * Added support for SCU and LNO.
+ * Account for modified chk_tstr() parameters.
+ * Revision 1.37 2011/11/25 14:59:17Z martin
+ * Account for some renamed evt_log library symbols.
+ * Revision 1.36 2011/11/25 10:37:10 martin
+ * Added commands and data structures to support log events.
+ * Revision 1.35 2011/07/29 09:46:54 daniel
+ * Use native alignment only.
+ * Added command code GPS_XMR_INSTANCES.
+ * Support GPIO configuration.
+ * Support for USB.
+ * Revision 1.34 2011/04/15 13:12:02 martin
* Added initializer for command name table.
* Unified mutex stuff using macros from mbgmutex.h.
* Revision 1.33 2010/09/07 07:18:08 daniel
@@ -61,7 +117,7 @@
* 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
+ * Modified comment for PZF_PCPS_TIME which can now also
* be sent to a device.
* Added mutex support.
* Added SVNO to the buffer union.
@@ -91,7 +147,7 @@
* Revision 1.19 2006/06/15 10:39:49Z martin
* Added some special types to the MSG_DATA union which have
* previously been defined as generic uint16_t types.
- * Removed MBG_OPT_SETTINGS and MBG_OPT_INFO from
+ * Removed MBG_OPT_SETTINGS and MBG_OPT_INFO from
* the MSG_DATA union since those types are not used with
* the binary protocol.
* Revision 1.18 2006/05/18 09:43:35Z martin
@@ -100,7 +156,7 @@
* Renamed IRIG_... symbols to IRIG_TX_... in order to distinguish
* from IRIG input configuration which might be available in the future.
* Added some fields to the MSG_DATA union.
- * Renamed MSG_BUFF field "data" to "msg_data" in order to avoid
+ * Renamed MSG_BUFF field "data" to "msg_data" in order to avoid
* conflict with reserved word in some environments.
* Rewrote inclusion control macros.
* Replace control of inclusion of function prototypes by new symbol
@@ -124,7 +180,7 @@
* Don't include function prototypes by default if compiling firmware.
* Conditionally support private data structures, automatically include
* those definitions if compiling firmware.
- * The data portion of MSG_BUFF is now a union whose maximum size
+ * The data portion of MSG_BUFF is now a union whose maximum size
* can be overridden by a preprocessor value.
* Added MBG_OPT_SETTINGS and MBG_OPT_INFO to the buffer union.
* Updated function prototypes.
@@ -186,7 +242,7 @@
#ifndef _USE_MUTEX
#if defined( MBG_TGT_WIN32 )
#define _USE_MUTEX 1
- #elif defined( MBG_TGT_UNIX )
+ #elif defined( MBG_TGT_POSIX )
#define _USE_MUTEX 1
#endif
#endif
@@ -204,24 +260,52 @@
/* Control whether serial port communication shall be supported */
#ifndef _USE_SERIAL_IO
#if _IS_MBG_FIRMWARE
- #define _USE_SERIAL_IO 0 // Firmware provides its own serial I/O functions
+ #define _USE_SERIAL_IO 0 // firmware provides its own serial I/O functions
#else
- #define _USE_SERIAL_IO 1 // supported by default
+ #define _USE_SERIAL_IO 1 // supported by default
+ #endif
+#endif
+
+#ifndef _USE_SERIAL_IO_FTDI
+ // FTDI D2xx USB-To-Serial converters accessed via a proprietary DLL
+ #define _USE_SERIAL_IO_FTDI 0 // not supported by default
+#endif
+
+/* Control whether USB communication shall be supported */
+#if defined( MBG_TGT_LINUX )
+ #ifndef _USE_USB_IO // may be overridden by project settings
+ #define _USE_USB_IO 0 // not supported by default
#endif
+#else
+ // USB I/O requires libusb and is currently only supported under Linux.
+ // So for non-Linux targets force _USE_USB_IO to 0.
+ #define _USE_USB_IO 0 // not supported by default
+#endif
+
+/*
+ * Control whether direct USB I/O communication is supported
+ * for example via "/dev/mbgims" in case there is an appropriate
+ * channel to do so.
+ */
+#if defined( MBG_TGT_LINUX )
+ #ifndef _USE_USB_DIRECT_IO
+ #define _USE_USB_DIRECT_IO 0 // Not supported by default
+ #endif
+#else
+ // Not supported by other platforms
+ #define _USE_USB_DIRECT_IO 0 // Not supported by default
#endif
/* Control inclusion of secudefs.h */
#if _USE_SOCKET_IO
// Network socket I/O always requires secudefs, so make sure
// this is defined correctly.
- #ifdef _USE_ENCRYPTION
- #undef _USE_ENCRYPTION
- #endif
- #define _USE_ENCRYPTION 1
+ #undef _USE_ENCRYPTION
+ #define _USE_ENCRYPTION 1
#else
// If no socket I/O is used then secudefs aren't required, either.
#ifndef _USE_ENCRYPTION
- #define _USE_ENCRYPTION 0
+ #define _USE_ENCRYPTION 0
#endif
#endif
@@ -265,8 +349,19 @@
#include <mbgserio.h>
#endif
+#if _USE_SERIAL_IO_FTDI
+ #include <ftd2xx.h> // interface for ftd2xx.dll
+#else
+ // just to avoid build errors if FTDI API is not supported
+ #define FT_STATUS int
+#endif
+
+#if _USE_USB_IO
+ #include <mbgusbio.h>
+#endif
+
#if _USE_SOCKET_IO
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
#include <netdb.h>
#endif
#endif
@@ -289,246 +384,387 @@
#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifdef _GPSSERIO
#define _ext
#else
#define _ext extern
#endif
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
-#endif
+/* Start of header body */
+// We don't use pragma pack() here but native alignment.
-/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
-/* Status codes of check_transfer() function. */
+/**
+ * @brief Status codes returned by the check_transfer() function.
+ */
+enum TR_STATUS_CODES
+{
+ TR_COMPLETE_TSTR = 3, ///< The optional time string check has detected a valid time string
+ TR_COMPLETE = 2, ///< A binary message has been received successfully
+ TR_RECEIVING = 1, ///< Binary reception in progress, i.e. after START_OF_HEADER received
+ TR_WAITING = 0, ///< Waiting for a binary message, i.e. no START_OF_HEADER received, yet
+ TR_TIMEOUT = -1, ///< No data received during the timeout interval
+ TR_CSUM_HDR = -2, ///< The header checksum of a received message is invalid
+ TR_CSUM_DATA = -3, ///< The data checksum of a received message is invalid
+ TR_DECRYPTION = -4, ///< A binary message received over LAN could not be decrypted.
+ TR_OPEN_ERR = -5, ///< Failed to open connection.
+ TR_IO_ERR = -6, ///< I/O error for the specified connection
+ TR_AUTH_ERR = -7, ///< Authentication error for the specified LAN connection
+ TR_RCVD_NACK = -8 ///< Received Negative Acknowledge from a device (prev. msg not accepted or not supported)
+};
-#define TR_COMPLETE 2
-#define TR_RECEIVING 1
-#define TR_WAITING 0
-#define TR_TIMEOUT -1
-#define TR_CSUM_HDR -2
-#define TR_CSUM_DATA -3
-#define TR_DECRYPTION -4
-#define TR_OPEN_ERR -5
-#define TR_IO_ERR -6
-#define TR_AUTH_ERR -7
-/* The code below is sent before a message header. */
+/**
+ * @brief The start of header code sent before a binary message header
+ */
+#define START_OF_HEADER 0x01 ///< ASCII SOH
-#define START_OF_HEADER 0x01 /* ASCII SOH */
+/**
+ * @brief Control codes to be or'ed with a particular command/type code
+ */
+enum GPS_CMD_CTRL_CODES
+{
+ GPS_REQACK = 0x8000, ///< to device: request acknowledge
+ GPS_ACK = 0x4000, ///< from device: acknowledge a command
+ GPS_NACK = 0x2000, ///< from device: error evaluating a command
+};
-/* The control codes defined below are to be or'ed with a command/type code. */
+#define GPS_CTRL_MSK 0xF000 ///< bit mask of all ::GPS_CMD_CTRL_CODES
-#define GPS_REQACK 0x8000 /* to GPS rcvr: request acknowledge */
-#define GPS_ACK 0x4000 /* from GPS rcvr: acknowledge a command */
-#define GPS_NACK 0x2000 /* from GPS rcvr: error receiving command */
-#define GPS_CTRL_MSK 0xF000 /* masks control code from command */
+/**
+ * @brief A wildcard command code
+ *
+ * This code can be passed to a receive routine to wait for any type
+ * of binary packet rather than for a specific packet.
+ */
+#define GPS_WILDCARD ( (GPS_CMD) -1 )
-/**< @defgroup gps_cmds_serial GPS commands passed via serial port
+/**
+ * @brief Command codes for the binary protocol
+ *
+ * These codes specify commands and associated data types used by Meinberg's
+ * binary protocol to exchange data with a device via serial port, direct USB,
+ * or socket I/O.
+ *
+ * Some commands and associated data structures can be read (r) from a device, others
+ * can be written (w) to the device, and some can also be sent automatically (a) by
+ * a device after a ::GPS_AUTO_ON command has been sent to the device.
+ * The individual command codes are marked with (rwa) accordingly, where '-' is used
+ * to indicate that a particular mode is not supported.
*
- * These codes specify commands/types of data to be supplied to
- * the GPS receiver:
+ * @note Not all command code are supported by all devices.
+ * See the hints for a particular command.
+ *
+ * @note 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_GPS to ::MAX_SVNO_GPS. If the number is 0 then all ::N_SVNO_GPS
+ * almanacs or ephemeris data structures are returned.
+ *
+ * @see ::GPS_CMD_CODES_TABLE
*/
-/* clock auto-message to host */
-/* | host request, clock response */
-/* | | host download to clock */
-/* | | | */
-enum /* | | | */
+enum GPS_CMD_CODES
{ /* system data */
- GPS_AUTO_ON = 0x000, /* | | | X | no param, enable auto-msgs from GPS rcvr */
- GPS_AUTO_OFF, /* | | | X | no param, disable auto-msgs from GPS rcvr */
- GPS_SW_REV, /* | | X | | SW_REV, software revision */
- GPS_BVAR_STAT, /* | | X | | BVAR_STAT, status of buffered variables */
- GPS_TIME, /* | X | | X | TTM, current time or capture, or init board time */
- GPS_POS_XYZ, /* | | X | X | XYZ, current position in ECEF coords */
- GPS_POS_LLA, /* | | X | X | LLA, current position in geographic coords */
- GPS_TZDL, /* | | X | X | TZDL, time zone / daylight saving */
- GPS_PORT_PARM, /* | | X | X | PORT_PARM, (obsolete, use PORT_SETTINGS etc. ) */
- GPS_SYNTH, /* | | X | X | SYNTH synthesizer's frequency and phase */
- GPS_ANT_INFO, /* | X | X | | ANT_INFO, time diff after antenna disconnect */
- GPS_UCAP, /* | X | X | | TTM, user capture events */
- GPS_ENABLE_FLAGS, /* | | X | X | ENABLE_FLAGS, when to enable serial, pulses, and synth */
- GPS_STAT_INFO, /* | | X | | STAT_INFO, request SV, mode and DAC info */
- GPS_SWITCH_PARMS, /* | | X | X | (obsolete, use GPS_POUT_PROG_IDX) */
- GPS_STRING_PARMS, /* | | X | X | (obsolete, use GPS_PORT_INFO/GPS_PORT_SETTINGS */
- GPS_ANT_CABLE_LENGTH, /* | | X | X | ANT_CABLE_LEN, length of antenna cable */
- GPS_SYNC_OUTAGE_DELAY, /* | | X | X | (customized firmware only) */
- GPS_PULSE_INFO, /* | | X | X | (customized firmware only) */
- GPS_OPT_FEATURES, /* | | X | | (obsolete, use GPS_RECEIVER_INFO) */
- GPS_IRIG_TX_SETTINGS, /* | | X | X | IRIG_SETTINGS, (only if GPS_HAS_IRIG_TX) */
- GPS_RECEIVER_INFO, /* | | X | | RECEIVER_INFO, model specific info */
- GPS_STR_TYPE_INFO_IDX, /* | | X | | STR_TYPE_INFO_IDX, names and modes of supp. string types */
- GPS_PORT_INFO_IDX, /* | | X | | PORT_INFO_IDX, port settings + additional info */
- GPS_PORT_SETTINGS_IDX, /* | | X | X | PORT_SETTINGS_IDX, settings for specified port */
- GPS_POUT_INFO_IDX, /* | | X | | POUT_INFO_IDX, pout settings + additional info */
- GPS_POUT_SETTINGS_IDX, /* | | X | X | POUT_SETTINGS_IDX, programmable pulse output cfg */
- GPS_IRIG_TX_INFO, /* | | X | | IRIG_INFO, (only if GPS_HAS_IRIG_TX) */
- GPS_MULTI_REF_SETTINGS,/* | | X | X | MULTI_REF_SETTINGS, (only if HAS_MULTI_REF) */
- GPS_MULTI_REF_INFO, /* | | X | | MULTI_REF_INFO, (only if HAS_MULTI_REF) */
- GPS_ROM_CSUM, /* | | X | | ROM_CSUM, (not supported by all devices) */
- 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_RAW_IRIG_DATA, /* | | X | | MBG_RAW_IRIG_DATA, (only if GPS_HAS_RAW_IRIG_DATA) */
+ GPS_AUTO_ON = 0x000, ///< (-w-) no data, enable auto-msgs from device
+ GPS_AUTO_OFF, ///< (-w-) no data, disable auto-msgs from device
+ GPS_SW_REV, ///< (r--) deprecated, ::SW_REV, software revision, use only if ::GPS_RECEIVER_INFO not supp.
+ GPS_BVAR_STAT, ///< (r--) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT
+ GPS_TIME, ///< (-wa) ::TTM, current time or capture, or init board time
+ GPS_POS_XYZ, ///< (rw-) ::XYZ, current position in ECEF coordinates, only if ::GPS_MODEL_HAS_POS_XYZ
+ GPS_POS_LLA, ///< (rw-) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA
+ GPS_TZDL, ///< (rw-) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL
+ GPS_PORT_PARM, ///< (rw-) deprecated, ::PORT_PARM, use ::PORT_SETTINGS etc. if ::GPS_RECEIVER_INFO supported
+ GPS_SYNTH, ///< (rw-) ::SYNTH, synthesizer settings, only if ::GPS_HAS_SYNTH
+ GPS_ANT_INFO, ///< (r-a) ::ANT_INFO, time diff after antenna disconnect, only if ::GPS_MODEL_HAS_ANT_INFO
+ GPS_UCAP, ///< (r-a) ::TTM, user capture events, only if ::RECEIVER_INFO::n_ucaps > 0
+ GPS_ENABLE_FLAGS, ///< (rw-) ::ENABLE_FLAGS, when to enable serial, pulses, and synth, only if ::GPS_MODEL_HAS_ENABLE_FLAGS
+ GPS_STAT_INFO, ///< (r--) ::STAT_INFO, satellite info, mode of operation, and DAC info, only if ::GPS_MODEL_HAS_STAT_INFO
+ GPS_SWITCH_PARMS, ///< (rw-) deprecated, use ::GPS_POUT_INFO_IDX/::GPS_POUT_SETTINGS_IDX
+ GPS_STRING_PARMS, ///< (rw-) deprecated, use ::GPS_PORT_INFO_IDX/::GPS_PORT_SETTINGS_IDX
+ GPS_ANT_CABLE_LENGTH, ///< (rw-) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+ GPS_SYNC_OUTAGE_DELAY, ///< (rw-) (customized firmware only)
+ GPS_PULSE_INFO, ///< (rw-) (customized firmware only)
+ GPS_OPT_FEATURES, ///< (r--) deprecated, use ::GPS_RECEIVER_INFO
+ GPS_IRIG_TX_SETTINGS, ///< (rw-) ::IRIG_SETTINGS, only if ::GPS_HAS_IRIG_TX
+ GPS_RECEIVER_INFO, ///< (r--) ::RECEIVER_INFO, model specific info, not supported by *very* old devices
+ GPS_STR_TYPE_INFO_IDX, ///< (r--) ::STR_TYPE_INFO_IDX, names and capabilities of supp. string types, only if ::RECEIVER_INFO::n_str_type > 0
+ GPS_PORT_INFO_IDX, ///< (r--) ::PORT_INFO_IDX, serial port settings and capabilities, only if ::RECEIVER_INFO::n_com_ports > 0
+ GPS_PORT_SETTINGS_IDX, ///< (rw-) ::PORT_SETTINGS_IDX, settings for specified serial port, only if ::RECEIVER_INFO::n_com_ports > 0
+ GPS_POUT_INFO_IDX, ///< (r--) ::POUT_INFO_IDX, programmable pulse output settings and capabilities, only if ::RECEIVER_INFO::n_prg_out > 0
+ GPS_POUT_SETTINGS_IDX, ///< (rw-) ::POUT_SETTINGS_IDX, programmable pulse output settings, only if ::RECEIVER_INFO::n_prg_out > 0
+ GPS_IRIG_TX_INFO, ///< (r--) ::IRIG_INFO, only if ::GPS_HAS_IRIG_TX
+ GPS_MULTI_REF_SETTINGS, ///< (rw-) ::MULTI_REF_SETTINGS, only if ::GPS_HAS_MULTI_REF
+ GPS_MULTI_REF_INFO, ///< (r--) ::MULTI_REF_INFO, only if ::GPS_HAS_MULTI_REF
+ GPS_ROM_CSUM, ///< (r--) ::ROM_CSUM, not supported by all devices
+ GPS_MULTI_REF_STATUS, ///< (r--) ::MULTI_REF_STATUS, only if ::GPS_HAS_MULTI_REF
+ GPS_RCV_TIMEOUT, ///< (rw-) ::RCV_TIMEOUT, [min], only if ::GPS_HAS_RCV_TIMEOUT
+ GPS_IGNORE_LOCK, ///< (rw-) ::IGNORE_LOCK, if != 0 always claim to be sync, only if ::GPS_MODEL_HAS_GPS_IGNORE_LOCK
+ GPS_IRIG_RX_SETTINGS, ///< (rw-) ::IRIG_SETTINGS, only if ::GPS_HAS_IRIG_RX
+ GPS_IRIG_RX_INFO, ///< (r--) ::IRIG_INFO, only if ::GPS_HAS_IRIG_RX
+ GPS_REF_OFFS, ///< (rw-) ::MBG_REF_OFFS, only if ::GPS_HAS_REF_OFFS
+ GPS_DEBUG_STATUS, ///< (r--) ::MBG_DEBUG_STATUS, only if ::GPS_HAS_DEBUG_STATUS
+ GPS_XMR_SETTINGS_IDX, ///< (rw-) ::XMULTI_REF_SETTINGS_IDX, idx 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, only if ::GPS_HAS_XMULTI_REF
+ GPS_XMR_INFO_IDX, ///< (r--) ::XMULTI_REF_INFO_IDX, idx 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, only if ::GPS_HAS_XMULTI_REF
+ GPS_XMR_STATUS_IDX, ///< (r--) ::XMULTI_REF_STATUS_IDX, idx 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, only if ::GPS_HAS_XMULTI_REF
+ GPS_OPT_SETTINGS, ///< (rw-) ::MBG_OPT_SETTINGS, only if ::GPS_HAS_OPT_SETTINGS
+ GPS_OPT_INFO, ///< (r--) ::MBG_OPT_INFO, only if ::GPS_HAS_OPT_SETTINGS
+ GPS_CLR_UCAP_BUFF, ///< (-w-) no data, only if ::RECEIVER_INFO::n_ucaps > 0
+ GPS_TIME_SCALE, ///< (rw-) ::MBG_TIME_SCALE_SETTINGS/::MBG_TIME_SCALE_INFO, only if ::GPS_HAS_TIME_SCALE
+ GPS_NAV_ENG_SETTINGS, ///< (rw-) ::NAV_ENGINE_SETTINGS, only if ::GPS_HAS_NAV_ENGINE_SETTINGS
+ GPS_RAW_IRIG_DATA, ///< (r--) ::MBG_RAW_IRIG_DATA, only if ::GPS_HAS_RAW_IRIG_DATA
+ GPS_GPIO_CFG_LIMITS, ///< (r--) ::MBG_GPIO_CFG_LIMITS, only if ::GPS_HAS_GPIO
+ GPS_GPIO_INFO_IDX, ///< (r--) ::MBG_GPIO_INFO_IDX, settings and capabilities, only if ::GPS_HAS_GPIO
+ GPS_GPIO_SETTINGS_IDX, ///< (rw-) ::MBG_GPIO_SETTINGS_IDX, settings of a specific port, only if ::GPS_HAS_GPIO
+ GPS_XMR_INSTANCES, ///< (r--) ::XMULTI_REF_INSTANCES, only if ::GPS_HAS_XMRS_MULT_INSTC
+ GPS_CLR_EVT_LOG, ///< (-w-) no data, clear event log command, only if ::GPS_HAS_EVT_LOG
+ GPS_NUM_EVT_LOG_ENTRIES, ///< (r--) ::MBG_NUM_EVT_LOG_ENTRIES, num. of log entries, only if ::GPS_HAS_EVT_LOG
+ GPS_FIRST_EVT_LOG_ENTRY, ///< (r--) first/oldest ::MBG_EVT_LOG_ENTRY, only if ::GPS_HAS_EVT_LOG
+ GPS_NEXT_EVT_LOG_ENTRY, ///< (r--) next ::MBG_EVT_LOG_ENTRY, only if ::GPS_HAS_EVT_LOG
+ GPS_LNO_STATUS, ///< (r--) ::LNO_STATE, only if ::GPS_MODEL_IS_LNO
+ GPS_IMS_STATE, ///< (r--) ::MBG_IMS_STATE, only if ::GPS_HAS_IMS
+ GPS_IMS_SENSOR_STATE_IDX, ///< (r--) ::MBG_IMS_SENSOR_STATE_IDX, only if ::GPS_HAS_IMS
+ GPS_XMR_HOLDOVER_INTV, ///< (rw-) ::XMR_HOLDOVER_INTV, only if ::GPS_MODEL_HAS_XMR_HOLDOVER_INTV, see also ::GPS_XMR_HOLDOVER_STATUS
+ GPS_HAVEQUICK_RX_SETTINGS, ///< (rw-) ::HAVEQUICK_SETTINGS for input, only if ::GPS_HAS_HAVEQUICK
+ GPS_HAVEQUICK_RX_INFO, ///< (r--) ::HAVEQUICK_INFO for input, only if ::GPS_HAS_HAVEQUICK
+ GPS_HAVEQUICK_TX_SETTINGS, ///< (rw-) ::HAVEQUICK_SETTINGS for output, only if ::GPS_HAS_HAVEQUICK
+ GPS_HAVEQUICK_TX_INFO, ///< (r--) ::HAVEQUICK_INFO for output, only if ::GPS_HAS_HAVEQUICK
+ GPS_PTP_CFG, ///< (rw-) ::PTP_CFG_INFO/::PTP_CFG_SETTINGS, only if ::GPS_HAS_PTP
+ GPS_PTP_STATE, ///< (r--) ::PTP_STATE, current PTP status, only if ::GPS_HAS_PTP
+ GPS_PTP_UC_MASTER_CFG_LIMITS, ///< (r--) ::PTP_UC_MASTER_CFG_LIMITS, only if ::PTP_CFG_CAN_BE_UNICAST_SLAVE
+ GPS_PTP_UC_MASTER_CFG, ///< (rw-) ::PTP_UC_MASTER_INFO_IDX/::PTP_UC_MASTER_SETTINGS_IDX, only if ::PTP_CFG_CAN_BE_UNICAST_SLAVE
+ GPS_NTP_GLB_CFG, ///< (rw-) ::NTP_GLB_INFO/::NTP_GLB_SETTINGS, only if ::GPS_HAS_NTP
+ GPS_NTP_CLNT_MODE_CFG, ///< (rw-) ::NTP_CLNT_MODE_INFO/::NTP_CLNT_MODE_SETTINGS, only if ::NTP_MSK_ROLE_CLIENT
+ GPS_NTP_SRV_MODE_CFG, ///< (rw-) ::NTP_SRV_MODE_INFO/::NTP_SRV_MODE_SETTINGS, only if ::NTP_MSK_ROLE_SERVER
+ GPS_NTP_PEER_SETTINGS_IDX, ///< (rw-) ::NTP_PEER_SETTINGS_IDX, only if ???
+ GPS_NTP_SYS_STATE, ///< (r--) ::NTP_SYS_STATE, only if ???
+ GPS_NTP_PEER_STATE_IDX, ///< (r--) ::NTP_PEER_STATE_IDX, only if ???
+ GPS_SHS, ///< (rw-) ::SHS_INFO/::SHS_SETTINGS, only if ::GPS_HAS_SHS
+ GPS_SHS_STATUS, ///< (r--) ::SHS_STATUS, only if ::GPS_HAS_SHS
+ GPS_NET_GLB_CFG, ///< (rw-) ::MBG_NET_GLB_CFG_INFO/::MBG_NET_GLB_CFG_SETTINGS, only if ::GPS_HAS_NET_CFG
+ GPS_NET_DNS_SRVR, ///< (rw-) ::MBG_IP_ADDR_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::num_dns_srvr > 0
+ GPS_NET_DNS_SRCH_DOM, ///< (rw-) ::MBG_NET_NAME_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom > 0
+ GPS_NET_STAT_DNS_SRVR, ///< (r--) ::MBG_IP_ADDR_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::num_dns_srvr > 0
+ GPS_NET_STAT_DNS_SRCH_DOM, ///< (r--) ::MBG_NET_NAME_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom > 0
+ GPS_GNSS_SAT_INFO_IDX, ///< (r--) ::GNSS_SAT_INFO_IDX, only if ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, deprecates ::GPS_GNSS_SAT_INFO
+ GPS_XMR_HOLDOVER_ELAPSED, ///< (r--) ::XMR_HOLDOVER_INTV, elapsed time in holdover mode, only if ::GPS_MODEL_HAS_XMR_HOLDOVER_INTV, deprecated by ::GPS_XMR_HOLDOVER_STATUS
+ GPS_GPIO_STATUS_IDX, ///< (r--) ::MBG_GPIO_STATUS_IDX, only if ::MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP
+ GPS_XMR_HOLDOVER_STATUS, ///< (r--) ::XMR_HOLDOVER_STATUS, only if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP, deprecates ::GPS_XMR_HOLDOVER_ELAPSED and partially ::GPS_XMR_HOLDOVER_INTV
+ GPS_XBP_LIMITS, ///< (r--) ::XBP_LIMITS, only if ::GPS_HAS_XBP
+ GPS_XBP_NODE_LIMITS, ///< (r--) ::XBP_NODE_LIMITS, only if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features
+ GPS_XBP_NODE_INFO_IDX, ///< (r--) ::XBP_NODE_INFO_IDX, 0..::XBP_NODE_LIMITS::node_count-1 instances can be retrieved
+ GPS_FDM_OUTPUT_STATE_IDX, ///< (r--) ::MBG_IMS_FDM_OUTPUT_STATE_IDX, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_OUTPUT_SETTINGS_IDX, ///< (rw-) ::MBG_IMS_FDM_OUTPUT_SETTINGS_IDX, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_OUTPUT_INFO_IDX, ///< (r--) ::MBG_IMS_FDM_OUTPUT_INFO, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_LIMITS, ///< (r--) ::MBG_IMS_FDM_LIMITS, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_STATE, ///< (r--) ::MBG_IMS_FDM_STATE, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_SETTINGS, ///< (rw-) ::MBG_IMS_FDM_SETTINGS, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_FDM_INFO, ///< (r--) ::MBG_IMS_FDM_INFO, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ GPS_XMR_EXT_SRC_INFO_IDX, ///< (r--) ::XMR_EXT_SRC_INFO_IDX, only if ::XMRIF_MSK_EXT_SRC_INFO_SUPP
/* GPS data */
- GPS_CFGH = 0x100, /* | | X | X | CFGH, SVs' configuration and health codes */
- GPS_ALM, /* | | X | X | req: uint16_t SV num, SV_ALM, one SV's almanac */
- GPS_EPH, /* | | X | X | req: uint16_t SV num, SV_EPH, one SV's ephemeris */
- GPS_UTC, /* | | X | X | UTC, GPS UTC correction parameters */
- GPS_IONO, /* | | X | X | IONO, GPS ionospheric correction parameters */
- GPS_ASCII_MSG, /* | | X | | ASCII_MSG, the GPS ASCII message */
+ GPS_CFGH = 0x100, ///< (rw-) ::CFGH, SVs' configuration and health codes
+ GPS_ALM, ///< (rw-) req: uint16_t SV num, ::SV_ALM, one SV's almanac
+ GPS_EPH, ///< (rw-) req: uint16_t SV num, ::SV_EPH, one SV's ephemeris
+ GPS_UTC, ///< (rw-) ::UTC, GPS %UTC correction parameters
+ GPS_IONO, ///< (rw-) ::IONO, GPS ionospheric correction parameters
+ GPS_ASCII_MSG, ///< (r--) ::ASCII_MSG, the GPS ASCII message
/* Glonass data */
- GPS_GLNS_ALM = 0x200, /* | | X | X | ** preliminary ** */ //##++
- GPS_GNSS_SAT_INFO, /* | | X | | GNSS_SAT_INFO, request SVs */
- GPS_GNSS_MODE, /* | | X | X | MBG_GNSS_MODE_{SETTINGS|INFO}, GNSS operation mode */
+ GPS_GLNS_ALM = 0x200, ///< (rw-) ** preliminary ** //##++
+ GPS_GNSS_SAT_INFO, ///< (r--) ::GNSS_SAT_INFO, Glonass-only sat. info (deprecated by ::GPS_GNSS_SAT_INFO_IDX)
+ GPS_GNSS_MODE, ///< (rw-) ::MBG_GNSS_MODE_SETTINGS/::MBG_GNSS_MODE_INFO}, GNSS operation mode
+ // Warning:
+ // The next numbers in range 0x200 are reserved
/* 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_IP4_SETTINGS = 0x800, ///< (rw-) ::IP4_SETTINGS, only if ::GPS_HAS_LAN_IP4
+ GPS_LAN_IF_INFO, ///< (r--) ::LAN_IF_INFO, only if ::GPS_HAS_LAN_IP4
+ GPS_IP4_STATE, ///< (r--) ::IP4_SETTINGS, only if ::GPS_HAS_LAN_IP4
+
+ /* misc data (SCU) */
+ GPS_SCU_STAT = 0x820, ///< (rwa) ::SCU_STAT_SETTINGS/::SCU_STAT_INFO, SCU board control, only if ::GPS_MODEL_IS_SCU
- GPS_CRYPTED_PACKET = 0x880, /* | X | X | X | encrypted binary packet */
- GPS_CRYPTED_RAW_PACKET, /* | X | X | X | encrypted binary raw packet */
+ GPS_CRYPTED_PACKET = 0x880, ///< (rwa) encrypted binary packet
+ GPS_CRYPTED_RAW_PACKET, ///< (rwa) encrypted binary raw packet
+ GPS_XBP_PACKET, ///< (rwa) eXtended Binary Packet, only if ::GPS_HAS_XBP, see @ref group_xbp
- GPS_SECU_INFO = 0x900, /* | | X | | encryption method for LAN interface */
- GPS_SECU_SETTINGS, /* | | X | X | reserved for public key LAN interface */
- GPS_SECU_PUBLIC_KEY, /* | | | | settings and password for LAN interface */
+ GPS_SECU_INFO = 0x900, ///< (r--) encryption method for LAN interface
+ GPS_SECU_SETTINGS, ///< (rw-) reserved for public key LAN interface
+ GPS_SECU_PUBLIC_KEY, ///< (---) settings and password for LAN interface
/* PZF data */
- 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 */
+ PZF_PCPS_TIME = 0xA00, ///< (rw-) ::PCPS_TIME, date/time/status, only if ::GPS_MODEL_IS_DCF_PZF
+ PZF_TR_DISTANCE, ///< (rw-) ::TR_DISTANCE, dist. from transmitter [km], only if ::GPS_MODEL_IS_DCF_PZF
+ PZF_TZCODE, ///< (rw-) ::TZCODE, time zone code, only if ::GPS_MODEL_IS_DCF_PZF
+ PZF_CORR_INFO ///< (r--) ::CORR_INFO, correlation info, only if ::GPS_MODEL_IS_DCF_PZF
};
-/*
- * 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.
- */
-typedef struct
-{
- GPS_CMD cmd_code;
- const char *cmd_name;
-} GPS_CMD_NAME_TABLE_ENTRY;
-
-#define GPS_CMD_NAME_TABLE_ENTRIES \
-{ \
- { GPS_AUTO_ON, "GPS_AUTO_ON" }, \
- { GPS_AUTO_OFF, "GPS_AUTO_OFF" }, \
- { GPS_SW_REV, "GPS_SW_REV" }, \
- { GPS_BVAR_STAT, "GPS_BVAR_STAT" }, \
- { GPS_TIME, "GPS_TIME" }, \
- { GPS_POS_XYZ, "GPS_POS_XYZ" }, \
- { GPS_POS_LLA, "GPS_POS_LLA" }, \
- { GPS_TZDL, "GPS_TZDL" }, \
- { GPS_PORT_PARM, "GPS_PORT_PARM" }, \
- { GPS_SYNTH, "GPS_SYNTH" }, \
- { GPS_ANT_INFO, "GPS_ANT_INFO" }, \
- { GPS_UCAP, "GPS_UCAP" }, \
- { GPS_ENABLE_FLAGS, "GPS_ENABLE_FLAGS" }, \
- { GPS_STAT_INFO, "GPS_STAT_INFO" }, \
- { GPS_SWITCH_PARMS, "GPS_SWITCH_PARMS" }, \
- { GPS_STRING_PARMS, "GPS_STRING_PARMS" }, \
- { GPS_ANT_CABLE_LENGTH, "GPS_ANT_CABLE_LENGTH" }, \
- { GPS_SYNC_OUTAGE_DELAY, "GPS_SYNC_OUTAGE_DELAY" }, \
- { GPS_PULSE_INFO, "GPS_PULSE_INFO" }, \
- { GPS_OPT_FEATURES, "GPS_OPT_FEATURES" }, \
- { GPS_IRIG_TX_SETTINGS, "GPS_IRIG_TX_SETTINGS" }, \
- { GPS_RECEIVER_INFO, "GPS_RECEIVER_INFO" }, \
- { GPS_STR_TYPE_INFO_IDX, "GPS_STR_TYPE_INFO_IDX" }, \
- { GPS_PORT_INFO_IDX, "GPS_PORT_INFO_IDX" }, \
- { GPS_PORT_SETTINGS_IDX, "GPS_PORT_SETTINGS_IDX" }, \
- { GPS_POUT_INFO_IDX, "GPS_POUT_INFO_IDX" }, \
- { GPS_POUT_SETTINGS_IDX, "GPS_POUT_SETTINGS_IDX" }, \
- { GPS_IRIG_TX_INFO, "GPS_IRIG_TX_INFO" }, \
- { GPS_MULTI_REF_SETTINGS, "GPS_MULTI_REF_SETTINGS" }, \
- { GPS_MULTI_REF_INFO, "GPS_MULTI_REF_INFO" }, \
- { GPS_ROM_CSUM, "GPS_ROM_CSUM" }, \
- { GPS_MULTI_REF_STATUS, "GPS_MULTI_REF_STATUS" }, \
- { GPS_RCV_TIMEOUT, "GPS_RCV_TIMEOUT" }, \
- { GPS_IGNORE_LOCK, "GPS_IGNORE_LOCK" }, \
- { GPS_IRIG_RX_SETTINGS, "GPS_IRIG_RX_SETTINGS" }, \
- { GPS_IRIG_RX_INFO, "GPS_IRIG_RX_INFO" }, \
- { GPS_REF_OFFS, "GPS_REF_OFFS" }, \
- { GPS_DEBUG_STATUS, "GPS_DEBUG_STATUS" }, \
- { GPS_XMR_SETTINGS_IDX, "GPS_XMR_SETTINGS_IDX" }, \
- { GPS_XMR_INFO_IDX, "GPS_XMR_INFO_IDX" }, \
- { GPS_XMR_STATUS_IDX, "GPS_XMR_STATUS_IDX" }, \
- { GPS_OPT_SETTINGS, "GPS_OPT_SETTINGS" }, \
- { GPS_OPT_INFO, "GPS_OPT_INFO" }, \
- { GPS_CLR_UCAP_BUFF, "GPS_CLR_UCAP_BUFF" }, \
- { GPS_TIME_SCALE, "GPS_TIME_SCALE" }, \
- { GPS_NAV_ENG_SETTINGS, "GPS_NAV_ENG_SETTINGS" }, \
- { GPS_RAW_IRIG_DATA, "GPS_RAW_IRIG_DATA" }, \
- \
- /* GPS data */ \
- { GPS_CFGH, "GPS_CFGH" }, \
- { GPS_ALM, "GPS_ALM" }, \
- { GPS_EPH, "GPS_EPH" }, \
- { GPS_UTC, "GPS_UTC" }, \
- { GPS_IONO, "GPS_IONO" }, \
- { GPS_ASCII_MSG, "GPS_ASCII_MSG" }, \
- \
- /* Glonass data */ \
- { GPS_GLNS_ALM, "GPS_GLNS_ALM" }, \
- { GPS_GNSS_SAT_INFO, "GPS_GNSS_SAT_INFO" }, \
- { GPS_GNSS_MODE, "GPS_GNSS_MODE" }, \
- \
- /* Misc data */ \
- { GPS_IP4_SETTINGS, "GPS_IP4_SETTINGS" }, \
- { GPS_LAN_IF_INFO, "GPS_LAN_IF_INFO" }, \
- \
- { GPS_CRYPTED_PACKET, "GPS_CRYPTED_PACKET" }, \
- { GPS_CRYPTED_RAW_PACKET, "GPS_CRYPTED_RAW_PACKET" }, \
- \
- { GPS_SECU_INFO, "GPS_SECU_INFO" }, \
- { GPS_SECU_SETTINGS, "GPS_SECU_SETTINGS" }, \
- { GPS_SECU_PUBLIC_KEY, "GPS_SECU_PUBLIC_KEY" }, \
- \
- /* PZF data */ \
- { PZF_PCPS_TIME, "PZF_PCPS_TIME" }, \
- { PZF_TR_DISTANCE, "PZF_TR_DISTANCE" }, \
- { PZF_TZCODE, "PZF_TZCODE" }, \
- { PZF_CORR_INFO, "PZF_CORR_INFO" }, \
- { 0, NULL } \
+#if !defined( MBG_TGT_DOS )
+
+/**
+ * @brief An initializer for a table of code/name entries of ::GPS_CMD_CODES
+ *
+ * This can e.g. be assigned to an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
+ * and may be helpful when debugging.
+ *
+ * @see ::GPS_CMD_CODES
+ */
+#define GPS_CMD_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( GPS_WILDCARD ), \
+ _mbg_cn_table_entry( GPS_AUTO_ON ), \
+ _mbg_cn_table_entry( GPS_AUTO_OFF ), \
+ _mbg_cn_table_entry( GPS_SW_REV ), \
+ _mbg_cn_table_entry( GPS_BVAR_STAT ), \
+ _mbg_cn_table_entry( GPS_TIME ), \
+ _mbg_cn_table_entry( GPS_POS_XYZ ), \
+ _mbg_cn_table_entry( GPS_POS_LLA ), \
+ _mbg_cn_table_entry( GPS_TZDL ), \
+ _mbg_cn_table_entry( GPS_PORT_PARM ), \
+ _mbg_cn_table_entry( GPS_SYNTH ), \
+ _mbg_cn_table_entry( GPS_ANT_INFO ), \
+ _mbg_cn_table_entry( GPS_UCAP ), \
+ _mbg_cn_table_entry( GPS_ENABLE_FLAGS ), \
+ _mbg_cn_table_entry( GPS_STAT_INFO ), \
+ _mbg_cn_table_entry( GPS_SWITCH_PARMS ), \
+ _mbg_cn_table_entry( GPS_STRING_PARMS ), \
+ _mbg_cn_table_entry( GPS_ANT_CABLE_LENGTH ), \
+ _mbg_cn_table_entry( GPS_SYNC_OUTAGE_DELAY ), \
+ _mbg_cn_table_entry( GPS_PULSE_INFO ), \
+ _mbg_cn_table_entry( GPS_OPT_FEATURES ), \
+ _mbg_cn_table_entry( GPS_IRIG_TX_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_RECEIVER_INFO ), \
+ _mbg_cn_table_entry( GPS_STR_TYPE_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_PORT_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_PORT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_POUT_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_POUT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_IRIG_TX_INFO ), \
+ _mbg_cn_table_entry( GPS_MULTI_REF_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_MULTI_REF_INFO ), \
+ _mbg_cn_table_entry( GPS_ROM_CSUM ), \
+ _mbg_cn_table_entry( GPS_MULTI_REF_STATUS ), \
+ _mbg_cn_table_entry( GPS_RCV_TIMEOUT ), \
+ _mbg_cn_table_entry( GPS_IGNORE_LOCK ), \
+ _mbg_cn_table_entry( GPS_IRIG_RX_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_IRIG_RX_INFO ), \
+ _mbg_cn_table_entry( GPS_REF_OFFS ), \
+ _mbg_cn_table_entry( GPS_DEBUG_STATUS ), \
+ _mbg_cn_table_entry( GPS_XMR_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_STATUS_IDX ), \
+ _mbg_cn_table_entry( GPS_OPT_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_OPT_INFO ), \
+ _mbg_cn_table_entry( GPS_CLR_UCAP_BUFF ), \
+ _mbg_cn_table_entry( GPS_TIME_SCALE ), \
+ _mbg_cn_table_entry( GPS_NAV_ENG_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_RAW_IRIG_DATA ), \
+ _mbg_cn_table_entry( GPS_GPIO_CFG_LIMITS ), \
+ _mbg_cn_table_entry( GPS_GPIO_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_GPIO_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_INSTANCES ), \
+ _mbg_cn_table_entry( GPS_CLR_EVT_LOG ), \
+ _mbg_cn_table_entry( GPS_NUM_EVT_LOG_ENTRIES ), \
+ _mbg_cn_table_entry( GPS_FIRST_EVT_LOG_ENTRY ), \
+ _mbg_cn_table_entry( GPS_NEXT_EVT_LOG_ENTRY ), \
+ _mbg_cn_table_entry( GPS_LNO_STATUS ), \
+ _mbg_cn_table_entry( GPS_IMS_STATE ), \
+ _mbg_cn_table_entry( GPS_IMS_SENSOR_STATE_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_HOLDOVER_INTV ), \
+ _mbg_cn_table_entry( GPS_HAVEQUICK_RX_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_HAVEQUICK_RX_INFO ), \
+ _mbg_cn_table_entry( GPS_HAVEQUICK_TX_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_HAVEQUICK_TX_INFO ), \
+ _mbg_cn_table_entry( GPS_PTP_CFG ), \
+ _mbg_cn_table_entry( GPS_PTP_STATE ), \
+ _mbg_cn_table_entry( GPS_PTP_UC_MASTER_CFG_LIMITS ), \
+ _mbg_cn_table_entry( GPS_PTP_UC_MASTER_CFG ), \
+ _mbg_cn_table_entry( GPS_NTP_GLB_CFG ), \
+ _mbg_cn_table_entry( GPS_NTP_CLNT_MODE_CFG ), \
+ _mbg_cn_table_entry( GPS_NTP_SRV_MODE_CFG ), \
+ _mbg_cn_table_entry( GPS_NTP_PEER_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_NTP_SYS_STATE ), \
+ _mbg_cn_table_entry( GPS_NTP_PEER_STATE_IDX ), \
+ _mbg_cn_table_entry( GPS_SHS ), \
+ _mbg_cn_table_entry( GPS_SHS_STATUS ), \
+ _mbg_cn_table_entry( GPS_NET_GLB_CFG ), \
+ _mbg_cn_table_entry( GPS_NET_DNS_SRVR ), \
+ _mbg_cn_table_entry( GPS_NET_DNS_SRCH_DOM ), \
+ _mbg_cn_table_entry( GPS_NET_STAT_DNS_SRVR ), \
+ _mbg_cn_table_entry( GPS_NET_STAT_DNS_SRCH_DOM ), \
+ _mbg_cn_table_entry( GPS_GNSS_SAT_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_HOLDOVER_ELAPSED ), \
+ _mbg_cn_table_entry( GPS_GPIO_STATUS_IDX ), \
+ _mbg_cn_table_entry( GPS_XMR_HOLDOVER_STATUS ), \
+ _mbg_cn_table_entry( GPS_XBP_LIMITS ), \
+ _mbg_cn_table_entry( GPS_XBP_NODE_LIMITS ), \
+ _mbg_cn_table_entry( GPS_XBP_NODE_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_FDM_OUTPUT_STATE_IDX ), \
+ _mbg_cn_table_entry( GPS_FDM_OUTPUT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( GPS_FDM_OUTPUT_INFO_IDX ), \
+ _mbg_cn_table_entry( GPS_FDM_LIMITS ), \
+ _mbg_cn_table_entry( GPS_FDM_STATE ), \
+ _mbg_cn_table_entry( GPS_FDM_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_FDM_INFO ), \
+ _mbg_cn_table_entry( GPS_XMR_EXT_SRC_INFO_IDX ), \
+ \
+ /* GPS data */ \
+ _mbg_cn_table_entry( GPS_CFGH ), \
+ _mbg_cn_table_entry( GPS_ALM ), \
+ _mbg_cn_table_entry( GPS_EPH ), \
+ _mbg_cn_table_entry( GPS_UTC ), \
+ _mbg_cn_table_entry( GPS_IONO ), \
+ _mbg_cn_table_entry( GPS_ASCII_MSG ), \
+ \
+ /* Glonass data */ \
+ _mbg_cn_table_entry( GPS_GLNS_ALM ), \
+ _mbg_cn_table_entry( GPS_GNSS_SAT_INFO ), \
+ _mbg_cn_table_entry( GPS_GNSS_MODE ), \
+ \
+ /* Misc data */ \
+ _mbg_cn_table_entry( GPS_IP4_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_LAN_IF_INFO ), \
+ _mbg_cn_table_entry( GPS_IP4_STATE ), \
+ \
+ /* misc data (SCU) */ \
+ _mbg_cn_table_entry( GPS_SCU_STAT ), \
+ \
+ _mbg_cn_table_entry( GPS_CRYPTED_PACKET ), \
+ _mbg_cn_table_entry( GPS_CRYPTED_RAW_PACKET ), \
+ _mbg_cn_table_entry( GPS_XBP_PACKET ), \
+ \
+ _mbg_cn_table_entry( GPS_SECU_INFO ), \
+ _mbg_cn_table_entry( GPS_SECU_SETTINGS ), \
+ _mbg_cn_table_entry( GPS_SECU_PUBLIC_KEY ), \
+ \
+ /* PZF data */ \
+ _mbg_cn_table_entry( PZF_PCPS_TIME ), \
+ _mbg_cn_table_entry( PZF_TR_DISTANCE ), \
+ _mbg_cn_table_entry( PZF_TZCODE ), \
+ _mbg_cn_table_entry( PZF_CORR_INFO ), \
+ _mbg_cn_table_end() \
}
+#endif // !defined( MBG_TGT_DOS )
-/* A structure holding the number of a SV and the SV's almanac. */
+/**
+ * @brief An SV number plus the SV's almanac data
+ */
typedef struct
{
SVNO svno;
@@ -536,9 +772,9 @@ typedef struct
} SV_ALM;
-
-/* A structure holding the number of a SV and the SV's ephemeris. */
-
+/**
+ * @brief An SV number plus the SV's ephemeris data
+ */
typedef struct
{
SVNO svno;
@@ -549,37 +785,63 @@ typedef struct
#if _USE_PCPSDEFS
-/* Attention: this differs from PCPS_TZCODE defined in pcpsdefs.h */
+/**
+ * @brief Type of variable to hold a TZ code
+ *
+ * This is used with the binary protocol but differs from ::PCPS_TZCODE
+ * which is used with the PCI interface.
+ *
+ * @see ::PCPS_TZCODE
+ * @see ::TZCODE_UNION
+ */
typedef uint16_t TZCODE;
-#endif
+#define _mbg_swab_tzcode( _p ) \
+ _mbg_swab16( _p );
+
+
+/**
+ * @brief A union holding different types of a TZ code
+ *
+ * This is used with the binary protocol but differs from ::PCPS_TZCODE
+ * which is used with the PCI interface.
+ *
+ * @see ::TZCODE
+ * @see ::PCPS_TZCODE
+ */
+typedef union
+{
+ TZCODE ser; ///< code retrieved via serial binary protocol
+ PCPS_TZCODE pci; ///< code retrieved via PCI bus
+
+} TZCODE_UNION;
+#endif
-/* The message header */
+/**
+ * @brief The header of a binary message.
+ */
typedef struct
{
- GPS_CMD cmd;
- uint16_t len;
- CSUM data_csum;
- CSUM hdr_csum;
-} MSG_HDR;
+ GPS_CMD cmd; ///< see ::GPS_CMD_CODES and ::GPS_CMD_CTRL_CODES
+ uint16_t len; ///< length of the data portion appended after the header
+ CSUM data_csum; ///< checksum of the data portion appended after the header
+ CSUM hdr_csum; ///< checksum of the preceding header bytes
+} MSG_HDR;
-/* A union combining all kinds of parameters to be read from or written */
-/* to the GPS receiver. The size of the union corresponds to the maximum */
-/* size of the data part of a message. */
+/**
+ * @brief A union of all data types used with the binary protocol.
+ */
typedef union
{
- /* common types */
uint16_t us;
double d;
SVNO svno;
-
- /* user data */
SW_REV sw_rev;
BVAR_STAT bvar_stat;
TTM ttm;
@@ -623,8 +885,59 @@ typedef union
GNSS_SAT_INFO gnss_sat_info; //##++++++
MBG_GNSS_MODE_INFO gnss_mode_info; //##++++++
MBG_GNSS_MODE_SETTINGS gnss_mode_settings; //##++++++
+ MBG_GPIO_CFG_LIMITS gpio_cfg_limits;
+ MBG_GPIO_INFO_IDX gpio_info_idx;
+ MBG_GPIO_SETTINGS_IDX gpio_settings_idx;
+ XMULTI_REF_INSTANCES xmulti_ref_instances;
+ MBG_NUM_EVT_LOG_ENTRIES num_evt_log_entries;
+ MBG_EVT_LOG_ENTRY evt_log_entry;
+ LNO_STATE lno_state;
+ MBG_IMS_STATE ims_state;
+ MBG_IMS_SENSOR_STATE_IDX ims_sensor_state_idx;
+ XMR_HOLDOVER_INTV xmr_holdover_intv;
+ HAVEQUICK_SETTINGS havequick_settings;
+ HAVEQUICK_INFO havequick_info;
+ PTP_CFG_INFO ptp_cfg_info;
+ PTP_CFG_SETTINGS ptp_cfg_settings;
+ PTP_STATE ptp_state;
+ PTP_UC_MASTER_CFG_LIMITS ptp_uc_master_cfg_limits;
+ PTP_UC_MASTER_INFO_IDX ptp_uc_master_info_idx;
+ PTP_UC_MASTER_SETTINGS_IDX ptp_uc_master_settings_idx;
+ NTP_GLB_INFO ntp_glb_info;
+ NTP_GLB_SETTINGS ntp_glb_settings;
+ NTP_CLNT_MODE_INFO ntp_clnt_mode_info;
+ NTP_CLNT_MODE_SETTINGS ntp_clnt_mode_settings;
+ #if defined( DEBUG )
+ NTP_SRV_MODE_INFO ntp_srv_mode_info;
+ NTP_SRV_MODE_INFO ntp_srv_mode_settings;
+ #endif
+ NTP_PEER_SETTINGS_IDX ntp_peer_settings_idx;
+ NTP_SYS_STATE ntp_sys_state;
+ NTP_PEER_STATE_IDX ntp_peer_state_idx;
+ SHS_INFO shs_info;
+ SHS_SETTINGS shs_settings;
+ SHS_STATUS shs_status;
+ MBG_NET_GLB_CFG_INFO net_glb_cfg_info;
+ MBG_NET_GLB_CFG_SETTINGS net_glb_cfg_settings;
+ MBG_IP_ADDR_IDX ip_addr_idx;
+ MBG_NET_NAME_IDX net_name_idx;
+ GNSS_SAT_INFO_IDX gnss_sat_info_idx;
+ MBG_GPIO_STATUS_IDX gpio_status_idx;
+ XMR_HOLDOVER_STATUS xmr_holdover_status;
+ XBP_LIMITS xbp_limits;
+ XBP_NODE_LIMITS xbp_node_limits;
+ XBP_NODE_INFO_IDX xbp_node_info_idx;
+ MBG_IMS_FDM_OUTPUT_STATE_IDX fdm_output_state_idx;
+ MBG_IMS_FDM_OUTPUT_SETTINGS_IDX fdm_output_settings_idx;
+ MBG_IMS_FDM_OUTPUT_INFO_IDX fdm_output_info_idx;
+ MBG_IMS_FDM_LIMITS fdm_limits;
+ MBG_IMS_FDM_STATE fdm_state;
+ MBG_IMS_FDM_SETTINGS fdm_settings;
+ MBG_IMS_FDM_INFO fdm_info;
+ XMR_EXT_SRC_INFO_IDX xmr_ext_src_info_idx;
+
+ //##++ PTP_POWER_PROFILE_CFG ptp_power_profile_cfg; // no cmd code, yet.
- /* GPS system data */
CFGH cfgh;
SV_ALM sv_alm;
SV_EPH sv_eph;
@@ -632,10 +945,12 @@ typedef union
IONO iono;
ASCII_MSG ascii_msg;
- /* Misc data */
IP4_SETTINGS ip4_settings;
LAN_IF_INFO lan_if_info;
+ SCU_STAT_INFO scu_stat_info;
+ SCU_STAT_SETTINGS scu_stat_settings;
+
#if _USE_PCPSDEFS
PCPS_TIME pcps_time;
TR_DISTANCE tr_distance;
@@ -654,6 +969,7 @@ typedef union
} MSG_DATA;
+/// The maximum number of bytes required for a ::MSG_DATA buffer
#ifndef MAX_MSG_DATA_SIZE
#ifndef ADD_MSG_DATA_SIZE
#if _USE_ENCRYPTION
@@ -667,10 +983,66 @@ typedef union
#endif
+/**
+ * @brief A union of all data types used with the binary protocol, or array of bytes.
+ *
+ * This union can be used to implement a buffer which can hold either a known data structure
+ * or an array of bytes which can be read from or written to a device.
+ */
+typedef union
+{
+ MSG_DATA msg_data; ///< union of known structures
+ uint8_t bytes[MAX_MSG_DATA_SIZE];
+
+} STD_MSG_DATA_BUFF;
+
-/* The structures below define parts of a binary message packet which */
-/* are used with encrypted messages, */
+/**
+ * @brief The format of a standard binary message.
+ */
+typedef struct
+{
+ MSG_HDR hdr; ///< Message header containing the command code and length of the data portion
+ STD_MSG_DATA_BUFF data_buf; ///< Data portion using the number of bytes specified in the header
+
+} MBG_STD_MSG;
+
+
+
+/**
+ * @brief The data portion of an XBP message.
+ */
+typedef struct
+{
+ XBP_ADDR xbp_addr; ///< XBP address of the transmitter or receiver
+ MBG_STD_MSG std_msg; ///< Encapsulated standard binary message
+
+} XBP_MSG_DATA;
+
+
+
+/**
+ * @brief A message header for the eXtended Binary Protocol (XBP)
+ *
+ * The data portion of such message is a standard binary message.
+ * The ::MSG_HDR::len field in ::XBP_MSG_HDR::xbp_hdr must contain
+ * the number of bytes following the xbp_hdr field, i.e. the length
+ * of the whole encapsulated binary message plus the size of the
+ * xbp_addr field.
+ */
+typedef struct
+{
+ MSG_HDR xbp_hdr;
+ XBP_ADDR xpb_addr;
+
+} XBP_MSG_HDR;
+
+
+
+/**
+ * @brief A message prefix used for encrypted messages
+ */
typedef struct
{
MSG_HDR hdr;
@@ -678,7 +1050,7 @@ typedef struct
#if _USE_ENCRYPTION
uint8_t aes_initvect[AES_BLOCK_SIZE];
#else
- // In this case this structure is just a dummy to avoid
+ // In this case this structure is just a dummy to avoid
// a compiler error with the function prototypes.
#endif
@@ -688,21 +1060,13 @@ typedef struct
#if _USE_ENCRYPTION
+/**
+ * @brief A message data block used for encrypted messages
+ */
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;
+ MBG_STD_MSG std_msg;
} CRYPT_MSG_DATA;
@@ -710,21 +1074,25 @@ typedef struct
-/* A buffer holding a message header plus data part of a message */
-/* For portability reasons the CMSG_BUFF structure defined below */
-/* should be preferred for coding. */
-
+/**
+ * @brief A buffer for a message header plus data part
+ *
+ * The data part has to be interpreted depending on the command code
+ * in the message header field, hdr.
+ */
typedef struct
{
- MSG_HDR hdr;
+ MSG_HDR hdr; ///< The message header
union
{
- uint8_t bytes[MAX_MSG_DATA_SIZE];
- MSG_DATA msg_data;
+ uint8_t bytes[MAX_MSG_DATA_SIZE]; ///< Data part as a number of bytes
+ MSG_DATA msg_data; ///< Standard message data structures
+ MBG_STD_MSG std_msg; ///< Encapsulated standard message
+ XBP_MSG_DATA xbp_msg_data; ///< XBP address field plus encapsulated standard message
#if _USE_ENCRYPTION
- CRYPT_MSG_DATA crypt_msg_data;
+ CRYPT_MSG_DATA crypt_msg_data; ///< Encryption data plus encrypted standard message
#endif
} u;
@@ -733,30 +1101,34 @@ typedef struct
-/* The structure below is used to control the reception of messages */
-
+/**
+ * @brief A structure used to control the reception of binary messages
+ */
typedef struct
{
- MBG_MSG_BUFF *pmb; /* points to unencrypted message buffer */
- int buf_size; /* size of buffer, including header */
- 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 */
+ MBG_MSG_BUFF *pmb; ///< points to unencrypted message buffer
+ int buf_size; ///< size of buffer, including header
+ uint8_t *cur; ///< points to current pos inside receive buffer
+ int cnt; ///< the number of bytes to be received
+ ulong flags; ///< flags if header already completed, etc., see ::MBG_MSG_RCV_CTL_MASKS
#if _USE_RCV_TSTAMP
- MBG_TMO_TIME tstamp;
+ MBG_TMO_TIME tstamp; ///< time when the first byte of the packet was received
#endif
#if _USE_CHK_TSTR
- void (*chk_tstr_fnc)( char c, TIMESTR_CHECK *arg ); /* optional handler for normal, non-protocol data */
- TIMESTR_CHECK *chk_tstr_arg;
+ CHK_TSTR_FNC chk_tstr_fnc; ///< optional handler for normal, non-protocol data
+ CHK_TSTR_ARG *chk_tstr_arg; ///< arguments for the non-protocol data handler
#endif
} MBG_MSG_RCV_CTL;
-/* The flag bits below and the corresponding bit masks are used
- for MBG_MSG_RCV_CTL::flags: */
-enum
+/**
+ * @brief Receive control bits used to define ::MBG_MSG_RCV_CTL_MASKS
+ *
+ * @see ::MBG_MSG_RCV_CTL_MASKS
+ */
+enum MBG_MSG_RCV_CTL_BITS
{
MBG_MSG_RCV_CTL_BIT_RCVD_HDR,
MBG_MSG_RCV_CTL_BIT_MSG_TOO_LONG,
@@ -766,32 +1138,50 @@ enum
N_MBG_MSG_RCV_CTL_BIT
};
-#define MBG_MSG_RCV_CTL_RCVD_HDR ( 1UL << MBG_MSG_RCV_CTL_BIT_RCVD_HDR )
-#define MBG_MSG_RCV_CTL_MSG_TOO_LONG ( 1UL << MBG_MSG_RCV_CTL_BIT_MSG_TOO_LONG )
-#define MBG_MSG_RCV_CTL_OVERFLOW ( 1UL << MBG_MSG_RCV_CTL_BIT_OVERFLOW )
-#define MBG_MSG_RCV_CTL_DECRYPT_ERR ( 1UL << MBG_MSG_RCV_CTL_BIT_DECRYPT_ERR )
-#define MBG_MSG_RCV_CTL_DECRYPTED ( 1UL << MBG_MSG_RCV_CTL_BIT_DECRYPTED )
+/**
+ * @brief Receive control bit masks
+ *
+ * Used with ::MBG_MSG_RCV_CTL::flags
+ *
+ * @see ::MBG_MSG_RCV_CTL_BITS
+ */
+enum MBG_MSG_RCV_CTL_MASKS
+{
+ MBG_MSG_RCV_CTL_RCVD_HDR = ( 1UL << MBG_MSG_RCV_CTL_BIT_RCVD_HDR ), ///< see ::MBG_MSG_RCV_CTL_BIT_RCVD_HDR
+ MBG_MSG_RCV_CTL_MSG_TOO_LONG = ( 1UL << MBG_MSG_RCV_CTL_BIT_MSG_TOO_LONG ), ///< see ::MBG_MSG_RCV_CTL_BIT_MSG_TOO_LONG
+ MBG_MSG_RCV_CTL_OVERFLOW = ( 1UL << MBG_MSG_RCV_CTL_BIT_OVERFLOW ), ///< see ::MBG_MSG_RCV_CTL_BIT_OVERFLOW
+ MBG_MSG_RCV_CTL_DECRYPT_ERR = ( 1UL << MBG_MSG_RCV_CTL_BIT_DECRYPT_ERR ), ///< see ::MBG_MSG_RCV_CTL_BIT_DECRYPT_ERR
+ MBG_MSG_RCV_CTL_DECRYPTED = ( 1UL << MBG_MSG_RCV_CTL_BIT_DECRYPTED ) ///< see ::MBG_MSG_RCV_CTL_BIT_DECRYPTED
+};
+
-typedef struct
+/**
+ * @brief A structure used to control the transmission of binary messages
+ */
+typedef struct
{
- MBG_MSG_BUFF *pmb;
- int buf_size;
- int xfer_mode;
+ MBG_MSG_BUFF *pmb; ///< points to unencrypted message buffer
+ int buf_size; ///< size of buffer, including header
+ int xfer_mode; ///< transfer mode, see ::MBG_XFER_MODES
#if _USE_MUTEX
- MBG_MUTEX xmt_mutex;
+ MBG_MUTEX xmt_mutex; ///< mutex to serialize transmission
#endif
} MBG_MSG_XMT_CTL;
-// codes used with MBG_MSG_CTL::xfer_mode:
-enum
+/**
+ * @brief Binary message transfer modes
+ *
+ * Used with ::MBG_MSG_XMT_CTL::xfer_mode
+ */
+enum MBG_XFER_MODES
{
- MBG_XFER_MODE_NORMAL,
- MBG_XFER_MODE_ENCRYTED,
+ MBG_XFER_MODE_NORMAL, ///< normal, unencrypted transmission
+ MBG_XFER_MODE_ENCRYPTED, ///< encrypted transmission, usually over network
N_MBG_XFER_MODE
};
@@ -805,13 +1195,47 @@ enum
#define LAN_XPT_PORT 10001
-#ifndef INVALID_SOCKET
- #define INVALID_SOCKET -1
+
+/**
+ * @brief A socket file descriptor type
+ */
+#if defined( MBG_TGT_WIN32 )
+ typedef SOCKET MBG_SOCK_FD; // usually evaluates to (unsigned int), or (unsigned __int64)
+#elif defined( MBG_TGT_POSIX )
+ typedef int MBG_SOCK_FD;
#endif
+
+/**
+ * @brief A value to mark an ::MBG_SOCK_FD as invalid
+ */
+#if defined( MBG_TGT_WIN32 )
+ #define MBG_INVALID_SOCK_FD INVALID_SOCKET // usually evaluates to (SOCKET)(~0) since SOCKET is unsigned
+#elif defined( MBG_TGT_POSIX )
+ #define MBG_INVALID_SOCK_FD -1
+#endif
+
+#if defined( MBG_TGT_WIN32 )
+ #define socklen_t int
+#elif defined( MBG_TGT_POSIX )
+ #define socklen_t socklen_t
+#endif
+
+
+/**
+ * @brief The return code of socket functions in case of error
+ */
+#if defined( MBG_TGT_WIN32 )
+ #define MBG_SOCKET_ERR_RETVAL SOCKET_ERROR // usually evaluates to -1
+#elif defined( MBG_TGT_POSIX )
+ #define MBG_SOCKET_ERR_RETVAL -1
+#endif
+
+
+
typedef struct
{
- int sockfd;
+ MBG_SOCK_FD sockfd;
struct sockaddr_in addr;
} SOCKET_IO_STATUS;
@@ -819,27 +1243,50 @@ typedef struct
#endif // _USE_SOCKET_IO
-#if _USE_SERIAL_IO
+#if _USE_SERIAL_IO_FTDI
+
+typedef struct
+{
+ FT_HANDLE port_handle;
+
+} FTDI_IO_STATUS;
-#endif // _USE_SERIAL_IO
+#endif // _USE_SERIAL_IO_FTDI
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+
+#if _USE_USB_DIRECT_IO
+
+typedef int MBG_USB_DIRECT_IO_FD;
+
+#if !defined (MBG_USB_DIRECT_IO_INVALID_FD)
+ #define MBG_USB_DIRECT_IO_INVALID_FD -1
#endif
+#if !defined ( MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO )
+ #define MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO 1000 // [ms]
+#endif
+
+typedef struct
+{
+ MBG_USB_DIRECT_IO_FD usbdiofd;
+}USB_DIRECT_IO_STATUS;
-// For the next structure we can and should use native alignment:
+#endif // _USE_USB_DIRECT_IO
-typedef struct
+
+
+/**
+ * @brief A generic message send and receive control structure
+ */
+typedef struct
{
MBG_MSG_RCV_CTL rcv;
MBG_MSG_XMT_CTL xmt;
int conn_type;
- int io_error;
- ulong msg_rcv_timeout; // binary message receive timeout [ms]
- ulong char_rcv_timeout; // serial character receive timeout [ms]
+ 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];
@@ -850,7 +1297,11 @@ typedef struct
SECU_SETTINGS secu_settings;
#endif
- #if _USE_SERIAL_IO || _USE_SOCKET_IO
+ #if _USE_SERIAL_IO || \
+ _USE_SERIAL_IO_FTDI || \
+ _USE_SOCKET_IO || \
+ _USE_USB_IO || \
+ _USE_USB_DIRECT_IO
union
{
#if _USE_SOCKET_IO
@@ -860,18 +1311,36 @@ typedef struct
#if _USE_SERIAL_IO
SERIAL_IO_STATUS serio;
#endif
+
+ #if _USE_SERIAL_IO_FTDI
+ FTDI_IO_STATUS ftdiio;
+ #endif
+
+ #if _USE_USB_IO
+ USB_IO_STATUS usbio;
+ #endif
+
+ #if _USE_USB_DIRECT_IO
+ USB_DIRECT_IO_STATUS usbdio;
+ #endif
} st;
#endif
} MBG_MSG_CTL;
-// codes used with MBG_MSG_CTL::conn_type:
-
-enum
+/**
+ * @brief Binary message connection types
+ *
+ * Used with ::MBG_MSG_CTL::conn_type
+ */
+enum MBG_CONN_TYPES
{
- MBG_CONN_TYPE_SERIAL,
- MBG_CONN_TYPE_SOCKET,
+ MBG_CONN_TYPE_SERIAL, ///< connection via serial port
+ MBG_CONN_TYPE_SOCKET, ///< connection via network socket
+ MBG_CONN_TYPE_USB, ///< connection via direct USB
+ MBG_CONN_TYPE_SERIAL_FTDI, ///< connection via FTDI D2xx USB-To-Serial converter
+ MBG_CONN_TYPE_USB_DIRECT_IO, ///< connection via direct USB I/O operation
N_MBG_CONN_TYPE
};
@@ -886,19 +1355,160 @@ enum
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
- CSUM msg_csum_update( CSUM csum, uint8_t *p, int n ) ;
- CSUM msg_csum( uint8_t *p, int n ) ;
- CSUM msg_hdr_csum( MSG_HDR *pmh ) ;
- int chk_hdr_csum( MSG_HDR *pmh ) ;
- int chk_data_csum( MBG_MSG_BUFF *pmb ) ;
+ /**
+ * @brief Translate a FTDI API status code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] status A status code defined by the FTDI API interface
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ int mbg_ftdi_ft_status_to_mbg( FT_STATUS status ) ;
+
+ /**
+ * @brief Compute a simple binary checksum
+ *
+ * Compute a checksum about a number of bytes starting
+ * with a given initial value.
+ *
+ * @param[in] csum the initial value
+ * @param[in] p pointer to a buffer of data bytes
+ * @param[in] n the number of bytes in the buffer
+ *
+ * @return the computed checksum
+ */
+ CSUM msg_csum_update( CSUM csum, const uint8_t *p, int n ) ;
+
+ /**
+ * @brief Compute a checksum for a binary message
+ *
+ * @note This function differs from the checksum() function
+ * used to compute the checksum of battery-buffered variables.
+ *
+ * @param[in] p pointer to a buffer of data bytes
+ * @param[in] n the number of bytes in the buffer
+ *
+ * @return the computed checksum
+ */
+ CSUM msg_csum( const uint8_t *p, int n ) ;
+
+ /**
+ * @brief Compute the checksum of a binary message header
+ *
+ * @param[in] pmh pointer to a binary message header
+ *
+ * @return the computed checksum
+ */
+ CSUM msg_hdr_csum( const MSG_HDR *pmh ) ;
+
+ /**
+ * @brief Check if the header checksum of a binary message is valid
+ *
+ * @param[in] pmh pointer to a binary message header
+ *
+ * @return ::MBG_SUCCESS or ::MBG_ERR_HDR_CSUM
+ */
+ int chk_hdr_csum( const MSG_HDR *pmh ) ;
+
+ /**
+ * @brief Check if the data checksum of a binary message is valid
+ *
+ * @param[in] pmb pointer to a binary message buffer
+ *
+ * @return ::MBG_SUCCESS or ::MBG_ERR_DATA_CSUM
+ */
+ int chk_data_csum( const MBG_MSG_BUFF *pmb ) ;
+
+ /**
+ * @brief Encrypt a binary message
+ *
+ * In encryption mode the original packet is encrypted and put
+ * as data portion into an envelope package.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in,out] pcmp Pointer to encryption settings
+ * @param[in,out] pmb Pointer to a binary message buffer
+ *
+ * @return the number of bytes of the encrypted message, or one of the @ref MBG_ERROR_CODES
+ */
int encrypt_message( MBG_MSG_CTL *pmctl, CRYPT_MSG_PREFIX *pcmp, MBG_MSG_BUFF *pmb ) ;
+
+ /**
+ * @brief Decrypt an encrypted binary message
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
int decrypt_message( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Set communication channel to specified encryption mode
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] mode Encryption mode, usually ::MBG_XFER_MODE_ENCRYPTED
+ * @param[in] key The crypto key (password) to be used
+ */
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 ) ;
+
+ /**
+ * @brief Complete message header and transmit message
+ *
+ * Compute checksums and complete the message header,
+ * then transmit both header and data. The caller must
+ * have copied the data to be sent to the data field
+ * of the transmit buffer and have set up the cmd and
+ * len fields of the message header.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ *
+ * @return one of the @ref MBG_RETURN_CODES
+ */
+ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ;
+
+ /**
+ * @brief Send a binary command message without parameters
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::xmt_cmd_us
+ */
+ int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ;
+
+ /**
+ * @brief Send a binary command message with ushort ( 16 bit) parameter
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to XBP address specifier
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] us The 16 bit message parameter (data)
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::xmt_cmd
+ */
+ int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us ) ;
+
+ /**
+ * @brief Check an incoming data stream for a binary message
+ *
+ * Check the sequence of incoming characters for blocks of
+ * binary message data. Binary messages are saved in a buffer
+ * which is part of the ::MBG_MSG_RCV_CTL structure and the
+ * caller checks the return value to get the receive status.
+ *
+ * @param[in,out] prctl Pointer to a valid receive control structure
+ * @param[in] c A byte from the incoming data stream
+ *
+ * @return One of the ::TR_STATUS_CODES
+ */
int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c ) ;
+
/* ----- function prototypes end ----- */
#endif // _USE_GPSSERIO_FNC
@@ -914,3 +1524,4 @@ enum
#endif /* _GPSSERIO_H */
+
diff --git a/mbglib/common/gpsutils.c b/mbglib/common/gpsutils.c
index f0c2987..caa885b 100644
--- a/mbglib/common/gpsutils.c
+++ b/mbglib/common/gpsutils.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsutils.c 1.4.1.2 2004/11/09 14:42:36Z martin REL_M $
+ * $Id: gpsutils.c 1.9 2013/01/30 16:10:08Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,10 +10,18 @@
*
* -----------------------------------------------------------------------
* $Log: gpsutils.c $
- * Revision 1.4.1.2 2004/11/09 14:42:36Z martin
- * Use C99 fixed-size types in swap_double().
- * Revision 1.4.1.1 2003/05/16 08:36:27 MARTIN
- * Fixed sprint_dms() to work correctly under QNX.
+ * Revision 1.9 2013/01/30 16:10:08Z martin
+ * Exclude some code from compiling by default, and
+ * thus don't require pcpslstr.h by default.
+ * Revision 1.8 2012/10/15 14:27:05Z martin
+ * Exclude sprint_fixed_freq() from build except for Borland C / Windows.
+ * Revision 1.7 2010/07/15 09:32:09 martin
+ * Use DEG character definition from pcpslstr.h.
+ * Revision 1.6 2004/12/28 11:21:26Z martin
+ * Omit trap if fixed_freq is 0.
+ * Use C99 fixed-size data types were required.
+ * Revision 1.5 2003/02/04 09:20:04Z MARTIN
+ * New functions sprint_alt(), sprint_fixed_freq().
* Revision 1.4 2003/01/31 13:45:19 MARTIN
* sprint_pos_geo() returns N/A if position not valid.
* Revision 1.3 2002/12/12 16:07:04 martin
@@ -30,9 +38,17 @@
#include <gpsutils.h>
#undef _GPSUTILS
+#if !defined( USE_SPRINTF )
+ #define USE_SPRINTF 0
+#endif
+
+#if USE_SPRINTF
+ #include <pcpslstr.h>
+#endif
+
#include <stdio.h>
#include <string.h>
-
+#include <math.h>
#define _eos( _s ) ( &(_s)[strlen( _s )] )
@@ -155,13 +171,14 @@ void swap_pos_doubles( POS *posp )
+#if USE_SPRINTF
+
/*HDR*/
void sprint_dms( char *s, DMS *pdms, int prec )
{
- sprintf( s, "%c %i%c%02i'%02.*f\"",
+ sprintf( s, "%c %i" DEG "%02i'%02.*f\"",
pdms->prefix,
pdms->deg,
- C_DEGREE,
pdms->min,
prec,
pdms->sec
@@ -172,6 +189,15 @@ void sprint_dms( char *s, DMS *pdms, int prec )
/*HDR*/
+void sprint_alt( char *s, double alt )
+{
+ sprintf( s, "%.0fm", alt );
+
+} /* sprint_dms */
+
+
+
+/*HDR*/
void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec )
{
if ( ppos->lla[LON] && ppos->lla[LAT] && ppos->lla[ALT] )
@@ -180,12 +206,111 @@ void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec )
strcat( s, sep );
sprint_dms( _eos( s ), &ppos->longitude, prec );
strcat( s, sep );
- sprintf( _eos( s ), "%.0fm", ppos->lla[ALT] );
+ sprint_alt( _eos( s ), ppos->lla[ALT] );
}
else
strcpy( s, "N/A" );
} /* sprint_pos_geo */
+#endif
+
+
+
+#if defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ )
+
+/*HDR*/
+void sprint_fixed_freq( char *s, FIXED_FREQ_INFO *p_ff )
+{
+ double freq;
+ int range;
+ ushort unit;
+ ushort format;
+
+ // Before re-calculating frequency, range is the base 10 exponent
+ // to the frequency value which is represented in kHz.
+ // After calculating range from real frequency, range is represented
+ // as follows:
+ // range display format divisor format index calculation
+ // -3 100mHz 1.000 [/1e-3] -3 % 3 = -3 + 3 = 0 % 3 = 0
+ // -2 100mHz 10.00 [/1e-3] -2 % 3 = -2 + 3 = 1 % 3 = 1
+ // -1 100mHz 100.0 [/1e-3] -1 % 3 = -1 + 3 = 2 % 3 = 2
+ // 0 1Hz 1.000 [/1e0] 0 % 3 = 0 + 3 = 3 % 3 = 0
+ // 1 10Hz 10.00 [/1e0] 1 % 3 = 1 + 3 = 1 % 3 = 1
+ // 2 100Hz 100.0 [/1e0] 2 % 3 = 2 + 3 = 2 % 3 = 2
+ // 3 1kHz 1.000 [/1e3] 3 % 3 = 0 + 3 = 3 % 3 = 0
+ // 4 10kHz 10.00 [/1e3] 4 % 3 = 1 + 3 = 4 % 3 = 1
+ // 5 100kHz 100.0 [/1e3] 5 % 3 = 2 + 3 = 5 % 3 = 2
+ // 6 1MHz 1.000 [/1e6] 6 % 3 = 0 + 3 = 3 % 3 = 0
+ // 7 10MHz 10.00 [/1e6] 7 % 3 = 1 + 3 = 4 % 3 = 1
+ // 8 100MHz 100.0 [/1e6] 8 % 3 = 2 + 3 = 5 % 3 = 2
+
+ // format string for fp output
+ static const char *fmt_str[] =
+ {
+ "%4.3lf%s",
+ "%4.2lf%s",
+ "%4.1lf%s",
+ };
+
+ // Unit index and divisor are calculated as follows:
+ // range unit index calculation divisor calculation
+ // -3 mHz ( int )( ( -3 + 3 ) / 3 ) = 0
+ // -2 mHz ( int )( ( -2 + 3 ) / 3 ) = 0
+ // -1 mHz ( int )( ( -1 + 3 ) / 3 ) = 0 / 10e-3 = 10e( 3 * 0 - 3 )
+ // 0 Hz ( int )( ( 0 + 3 ) / 3 ) = 1
+ // 1 Hz ( int )( ( 1 + 3 ) / 3 ) = 1
+ // 2 Hz ( int )( ( 2 + 3 ) / 3 ) = 1 / 1e0 = 10e( 3 * 1 - 3 )
+ // 3 kHz ( int )( ( 3 + 3 ) / 3 ) = 2
+ // 4 kHz ( int )( ( 4 + 3 ) / 3 ) = 2
+ // 5 kHz ( int )( ( 5 + 3 ) / 3 ) = 2 / 10e3 = 10e( 3 * 2 - 3 )
+ // 6 MHz ( int )( ( 6 + 3 ) / 3 ) = 3
+ // 7 MHz ( int )( ( 7 + 3 ) / 3 ) = 3
+ // 8 MHz ( int )( ( 8 + 3 ) / 3 ) = 3 / 10e6 =10e( 3 * 3 - 3 )
+
+ // unit string
+ static const char *unit_str[] =
+ {
+ "mHz",
+ "Hz",
+ "kHz",
+ "MHz"
+ };
+
+
+ if ( p_ff->khz_val )
+ {
+ // calculate frequency in Hz
+ freq = ( double ) p_ff->khz_val * pow( 10, ( p_ff->range + 3 ) );
+
+ // calculate decimal exponent
+ range = ( ( int ) log10( freq ) );
+
+ // check whether range is in the allowed range
+ // if so display frequency in broken format
+ if ( ( range >= -3 ) && ( range <= 8 ) )
+ {
+ // calculate format index ( see above )
+ format = ( ( ( range % 3 ) + 3 ) % 3 );
+
+ // calculate unit index
+ unit = ( ushort )( range + 3 ) / 3;
+
+ // calculate display value
+ freq = freq / pow( 10, ( ( 3 * unit ) - 3 ) );
+ sprintf( s, fmt_str[format], freq, unit_str[unit] );
+ return;
+ }
+ else
+ {
+ // out of range display fequency in Hz
+ sprintf( s, "%lfHz", freq );
+ }
+ }
+ else
+ strcpy( s, "N/A" );
+
+} /* sprint_fixed_freq */
+#endif // defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ )
diff --git a/mbglib/common/gpsutils.h b/mbglib/common/gpsutils.h
index 09627d9..c2143ca 100644
--- a/mbglib/common/gpsutils.h
+++ b/mbglib/common/gpsutils.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsutils.h 1.4.1.1 2003/05/15 09:40:25Z martin REL_M $
+ * $Id: gpsutils.h 1.7 2010/07/15 09:32:09Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,8 +10,12 @@
*
* -----------------------------------------------------------------------
* $Log: gpsutils.h $
- * Revision 1.4.1.1 2003/05/15 09:40:25Z martin
- * Changed degree string/char for QNX.
+ * Revision 1.7 2010/07/15 09:32:09Z martin
+ * Use DEG character definition from pcpslstr.h.
+ * Revision 1.6 2005/02/18 10:32:33Z martin
+ * Check more predefined macros to determine if compiling for Windows.
+ * Revision 1.5 2003/02/04 09:18:48Z MARTIN
+ * Updated function prototypes.
* Revision 1.4 2002/12/12 16:08:11 martin
* Definitions for degree character.
* Requires mbggeo.h.
@@ -41,17 +45,6 @@
/* Start of header body */
-#define ANSI_C_DEGREE '°' // single char
-#define ANSI_S_DEGREE "°" // string
-
-#if defined( _Windows ) || defined( __linux ) || defined( __QNX__ )
- #define C_DEGREE ANSI_C_DEGREE
- #define S_DEGREE ANSI_S_DEGREE
-#else
- #define C_DEGREE 'ø'
- #define S_DEGREE "ø"
-#endif
-
/* function prototypes: */
@@ -71,7 +64,9 @@ extern "C" {
void swap_iono_doubles( IONO *ionop ) ;
void swap_pos_doubles( POS *posp ) ;
void sprint_dms( char *s, DMS *pdms, int prec ) ;
+ void sprint_alt( char *s, double alt ) ;
void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec ) ;
+ void sprint_fixed_freq( char *s, FIXED_FREQ_INFO *p_ff ) ;
/* ----- function prototypes end ----- */
diff --git a/mbglib/common/mbg_arch.h b/mbglib/common/mbg_arch.h
new file mode 100644
index 0000000..37357be
--- /dev/null
+++ b/mbglib/common/mbg_arch.h
@@ -0,0 +1,181 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_arch.h 1.5.1.1 2014/10/29 14:21:17Z martin TEST $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions to support different computer hardware architectures.
+ *
+ * For a good summary of predefined macros which can be used to determine
+ * the build environment, the target environment, and architecture, see:
+ * http://sourceforge.net/p/predef/wiki/Home/
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_arch.h $
+ * Revision 1.5.1.1 2014/10/29 14:21:17Z martin
+ * Revision 1.5 2014/03/11 16:01:55 martin
+ * Added a comment.
+ * Revision 1.4 2012/10/02 18:32:00 martin
+ * Include words.h and, conditionally, stdlib.h.
+ * Use generic preprocessor symbol MBG_TGT_KERNEL.
+ * Revision 1.3 2009/06/12 13:12:37Z martin
+ * Fixed compiler warning.
+ * Revision 1.2 2009/03/19 15:14:15 martin
+ * Fixed byte swapping of doubles for SPARC architecture.
+ * Revision 1.1 2008/12/05 13:47:42 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBG_ARCH_H
+#define _MBG_ARCH_H
+
+#include <mbg_tgt.h>
+#include <words.h>
+
+#if !defined( MBG_TGT_KERNEL )
+ #include <stdlib.h>
+#endif
+
+
+#if defined( MBG_ARCH_SPARC )
+ #define MBG_ARCH_BIG_ENDIAN 1
+#endif
+
+
+#if !defined( MBG_ARCH_BIG_ENDIAN )
+ #define MBG_ARCH_LITTLE_ENDIAN 1
+#endif
+
+
+
+#if defined( MBG_TGT_LINUX )
+
+ #include <asm/byteorder.h>
+
+ #if defined( MBG_TGT_KERNEL )
+ #include <asm/unaligned.h>
+
+ #define _mbg_put_unaligned( _v, _p ) put_unaligned( _v, _p )
+ #define _mbg_get_unaligned( _p ) get_unaligned( _p )
+ #endif
+
+#endif
+
+
+
+// If no macros required to access unaligned data have yet been defined,
+// define some default macros assuming no special handling is required
+// to access unaligned data.
+
+#if !defined( _mbg_put_unaligned )
+ #define _mbg_put_unaligned( _v, _p ) ((void)( *(_p) = (_v) ))
+#endif
+
+#if !defined( _mbg_get_unaligned )
+ #define _mbg_get_unaligned( _p ) (*(_p))
+#endif
+
+
+
+// If no macros to convert endianess have yet been defined, define
+// some default macros assuming endianess conversion is not required.
+
+#if !defined( __le16_to_cpu )
+ #define __le16_to_cpu( _x ) (_x)
+#endif
+
+#if !defined( __le32_to_cpu )
+ #define __le32_to_cpu( _x ) (_x)
+#endif
+
+#if !defined( __le64_to_cpu )
+ #define __le64_to_cpu( _x ) (_x)
+#endif
+
+#if !defined( __cpu_to_le16 )
+ #define __cpu_to_le16( _x ) (_x)
+#endif
+
+#if !defined( __cpu_to_le32 )
+ #define __cpu_to_le32( _x ) (_x)
+#endif
+
+#if !defined( __cpu_to_le64 )
+ #define __cpu_to_le64( _x ) (_x)
+#endif
+
+
+
+// The macros below are used to convert the endianess
+// of the plug-in cards to the endianess of the host CPU
+
+#define _mbg8_to_cpu( _x ) ( _x )
+#define _mbg16_to_cpu( _x ) __le16_to_cpu( _x )
+#define _mbg32_to_cpu( _x ) __le32_to_cpu( _x )
+#define _mbg64_to_cpu( _x ) __le64_to_cpu( _x )
+
+#define _cpu_to_mbg8( _x ) ( _x )
+#define _cpu_to_mbg16( _x ) __cpu_to_le16( _x )
+#define _cpu_to_mbg32( _x ) __cpu_to_le32( _x )
+#define _cpu_to_mbg64( _x ) __cpu_to_le64( _x )
+
+
+
+// swap a double type variable bytewise e.g. to convert the endianess
+
+static __mbg_inline
+void mbg_swab_double( double *p )
+{
+#if 0 // The __swab64() may not work correctly for whatever reason ...
+ __swab64p( p );
+#else // ... so we do the swapping manually
+ double d = 0;
+ size_t i;
+
+ for ( i = 0; i < sizeof( double); i++ )
+ BYTE_OF( d, i ) = BYTE_OF( *p, ( sizeof( double) - 1 - i ) );
+
+ for ( i = 0; i < sizeof( double); i++ )
+ BYTE_OF( *p, i ) = BYTE_OF( d, i );
+#endif
+
+} // mbg_swab_double
+
+
+
+#if defined( MBG_ARCH_BIG_ENDIAN )
+
+ #define _mbg_swab16( _p ) *(_p) = __swab16( *(_p) )
+ #define _mbg_swab32( _p ) *(_p) = __swab32( *(_p) )
+
+ #define _mbg_swab_double( _p ) mbg_swab_double( _p )
+
+ #define _mbg_swab_doubles( _p, _n ) \
+ { \
+ int i; \
+ for ( i = 0; i < (_n); i++ ) \
+ _mbg_swab_double( &_p[i] ); \
+ }
+
+#else
+
+ #define _mbg_swab16( _p ) _nop_macro_fnc()
+ #define _mbg_swab32( _p ) _nop_macro_fnc()
+
+ #define _mbg_swab_double( _p ) _nop_macro_fnc()
+
+ #define _mbg_swab_doubles( _p, _n ) _nop_macro_fnc()
+
+#endif
+
+
+
+//##++++++++++++
+/// @brief A placeholder for yet missing _mbg_swab_..() macros
+#define _mbg_swab_dummy( _x ) _nop_macro_fnc()
+
+
+#endif /* _MBG_ARCH_H */
diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h
index 06e9a86..8cff80e 100644
--- a/mbglib/common/mbg_tgt.h
+++ b/mbglib/common/mbg_tgt.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_tgt.h 1.22 2009/10/01 08:20:50Z martin REL_M $
+ * $Id: mbg_tgt.h 1.34 2015/03/03 13:32:49Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,9 +11,47 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_tgt.h $
- * Revision 1.22 2009/10/01 08:20:50Z martin
+ * Revision 1.34 2015/03/03 13:32:49Z martin
+ * Provide __func__ for MS Visual Studio.
+ * Revision 1.33 2015/03/02 11:27:59Z martin
+ * Windows only:
+ * Define _CRT_SECURE_NO_WARNINGS to quiet compiler warnings.
+ * Define WIN32_LEAN_AND_MEAN only if it hasn't been defined before.
+ * Revision 1.32 2014/06/24 09:21:44 martin
+ * Update for newer C++Builder versions.
+ * Revision 1.31 2014/05/27 10:23:33 martin
+ * Finer control of which types are required for or already
+ * available on particular target systems.
+ * First definitions to support SunOS/Solaris.
+ * Revision 1.30 2014/04/01 12:55:58 martin
+ * Define MBG_TGT_WIN32 also for MS resource compiler.
+ * New target MBG_TGT_POSIX.
+ * Always include winsock2.h and windows.h for MBG_TGT_WIN32.
+ * Always include unistd.h for MBG_TGT_POSIX.
+ * Define empty __attribute__ macro for non-gcc environments.
+ * Revision 1.29 2013/02/01 14:50:46 martin
+ * Fixed a typo which caused an error under Borland CBuilder 5.
+ * Revision 1.28 2012/12/12 10:03:16Z martin
+ * Fix for Borland C 3.1.
+ * Revision 1.27 2012/11/29 12:03:14Z martin
+ * Moved definition of _no_macro_fnc() to words.h.
+ * Revision 1.26 2012/11/02 09:01:47Z martin
+ * Merged some stuff depending on the build environment here
+ * and cleaned up.
+ * Revision 1.25 2012/04/04 07:17:18 martin
+ * Treat QNX Neutrino as Unix target.
+ * Revision 1.24 2011/08/23 10:21:23 martin
+ * New symbol _NO_MBG_API_ATTR which can be used with functions
+ * which are going to be exported by a DLL, but actually aren't, yet.
+ * Revision 1.23 2011/08/19 10:47:00 martin
+ * Don't include stddef.h.
+ * Distinguish between different gcc target platforms.
+ * Initial support for IA64 platform.
+ * Support wchar_t for BSD.
+ * Defined _NO_USE_PACK_INTF for Sparc and IA64.
+ * Fixed typo in comment.
+ * Revision 1.22 2009/10/01 08:20:50 martin
* Fixed inline code support with different BC versions.
- * Revision 1.1 2009/11/20 12:24:05 philipp
* Revision 1.21 2009/09/01 10:34:23Z martin
* Don't define __mbg_inline for CVI and undefined targets.
* Revision 1.20 2009/08/18 15:14:26 martin
@@ -80,8 +118,6 @@
/* Other headers to be included */
-#include <stddef.h>
-
#ifdef _MBG_TGT
#define _ext
#else
@@ -91,11 +127,16 @@
/* Start of header body */
-#if defined( _CVI ) || defined( _CVI_ )
+#if defined( _CVI_ )
- #define MBG_TGT_WIN32
#define MBG_TGT_CVI
+ #if defined( _NI_mswin_ )
+ #define MBG_TGT_WIN32
+ #else
+ #error Unsupported CVI target platform.
+ #endif
+
#elif defined( _WIN32_WINNT )
// MS platform SDK
@@ -131,6 +172,11 @@
// MS Visual C++
#define MBG_TGT_WIN32
+#elif defined( RC_INVOKED )
+
+ //MS resource compiler
+ #define MBG_TGT_WIN32
+
#elif defined( __WINDOWS_386__ )
// Watcom C/C++ for target Win32
@@ -152,6 +198,10 @@
#define MBG_TGT_LINUX
#define _GNU_SOURCE 1
+ #if defined( __KERNEL__ )
+ #define MBG_TGT_KERNEL
+ #endif
+
#elif defined( __FreeBSD__ )
// GCC for target FreeBSD
@@ -164,9 +214,26 @@
#elif defined( __OpenBSD__ )
- // GCC for target FreeBSD
+ // GCC for target OpenBSD
#define MBG_TGT_OPENBSD
+#elif defined( __sun ) // Oracle Solaris or other SunOS derived operating system
+
+ // __SUNPRO_C Oracle Solaris Studio C compiler, __SUNPRO_C value is the version number
+ // __SUNPRO_CC Oracle Solaris Studio C++ compiler, __SUNPRO_CC value is the version number
+ // __sparc generate code for SPARC (R) architecture (32-bit or 64-bit)
+ // __sparcv9 generate code for 64-bit SPARC architecture
+ // __i386 generate code for 32-bit x86 architecture
+ // __amd64 generate code for 64-bit x64 architecture
+
+ #define MBG_TGT_SUNOS
+
+ #define __mbg_inline __inline__
+
+ #include <stdint.h>
+ #include <stdbool.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+
#elif defined( __QNX__ )
// any compiler for target QNX
@@ -190,39 +257,211 @@
#endif
-// Some definitions which depend on the type of compiler ...
+
+
+#if defined( MBG_TGT_FREEBSD ) \
+ || defined( MBG_TGT_NETBSD ) \
+ || defined( MBG_TGT_OPENBSD )
+ #define MBG_TGT_BSD
+
+ #if defined( _KERNEL )
+ #define MBG_TGT_KERNEL
+ #endif
+
+#endif
+
+#if defined( MBG_TGT_LINUX ) \
+ || defined( MBG_TGT_BSD ) \
+ || defined( MBG_TGT_SUNOS )
+ #define MBG_TGT_POSIX
+ #define MBG_TGT_UNIX
+#endif
+
+
+
+// Some definitions depending on the build environment ...
#if defined( __GNUC__ )
- #define __mbg_inline __inline__
+ #if defined( __i386__ )
- #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+ #define MBG_ARCH_I386
+ #define MBG_ARCH_X86
- #if defined( __sparc__ )
+ #elif defined( __x86_64__ )
+
+ #define MBG_ARCH_X86_64
+ #define MBG_ARCH_X86
+
+ #elif defined( __ia64__ )
+
+ #define MBG_ARCH_IA64
+
+ #define _NO_USE_PACK_INTF
+
+ #elif defined( __sparc__ )
#define MBG_ARCH_SPARC
- #define _MBG_ARCH_DEFINED
+ #define MBG_USE_MM_IO_FOR_PCI 1
+
+ #define _NO_USE_PACK_INTF
#elif defined( __arm__ )
#define MBG_ARCH_ARM
- #define _MBG_ARCH_DEFINED
#endif
+ #if defined( MBG_TGT_LINUX )
+
+ #if defined( __KERNEL__ )
+
+ #include <linux/types.h>
+ #include <linux/version.h>
+
+ #if ( LINUX_VERSION_CODE <= KERNEL_VERSION( 2, 6, 4 ) )
+ #define _ULONG_DEFINED 1
+ #define _USHORT_DEFINED 1
+ #define _UINT_DEFINED 1
+ #endif
+
+ #else
+
+ #include <sys/types.h>
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ #if defined( __u_char_defined )
+ #define _ULONG_DEFINED 1
+ #define _USHORT_DEFINED 1
+ #define _UINT_DEFINED 1
+ #endif
+
+ #endif
+
+ #elif defined( MBG_TGT_BSD )
+
+ #include <sys/types.h>
+
+ #elif defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino)
+
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ #else
+
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ #endif
+
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+
+ #define MBG_TGT_HAS_WCHAR_T 1
+
+ #define __mbg_inline __inline__
+
#elif defined( _MSC_VER )
+ // Known predifined MS compiler version codes:
+ // 1700: MSVC++ 11.0 (Visual Studio 2012)
+ // 1600: MSVC++ 10.0 (Visual Studio 2010)
+ // 1500: MSVC++ 9.0 (Visual Studio 2008)
+ // 1400: MSVC++ 8.0 (Visual Studio 2005)
+ // 1310: MSVC++ 7.1 (Visual Studio 2003)
+ // 1300: MSVC++ 7.0
+ // 1200: MSVC++ 6.0
+ // 1100: MSVC++ 5.0
+
+ #if ( _MSC_VER >= 1600 )
+ #include <stdint.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define MBG_TGT_HAS_INT_8_16_32 1
+ #endif
+
+ // no bool support anyway
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+
+ #define MBG_TGT_HAS_WCHAR_T 1
+
#define __mbg_inline __forceinline
- #define MBG_TGT_HAS_WCHAR_T 1
+ // At least up to VS2008 the builtin symbol __func__
+ // is not supported, but __FUNCTION__ returns the name
+ // of the current function instead.
+ #define __func__ __FUNCTION__
-#elif defined( _CVI ) || defined( _CVI_ )
+#elif defined( _CVI_ )
- // Inline code is not supported.
+ // 1000 for CVI v10.0 (CVI 2010)
+ // 911 for CVI v9.1.1 (CVI 2009 SP1)
+ // 910 for CVI v9.1 (CVI 2009)
+ // 310 for CVI v3.1
+ // 301 for CVI v3.0.1
+ // 1 for CVI v3.0
- #define MBG_TGT_HAS_WCHAR_T 0
+ #if ( _CVI_ >= 910 )
+ // LabWindows/CVI 2009 is the first version providing stdint.h.
+ #include <stdint.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define USE_LONG_FOR_INT32 1
+ #endif
-#elif defined( __BORLANDC__ )
+ // As of LabWindows/CVI 2010, stdbool.h is still missing.
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+
+ #define MBG_TGT_HAS_WCHAR_T 0
+
+ // Inline code is not supported, though the inline keyword
+ // is silently accepted since CVI v9.0
+
+#elif defined( __BORLANDC__ ) // or __CODEGEARC__ in newer versions
+
+ // 0x0200 Borland C/C++ 2.0
+ // 0x0400 Borland C/C++ 3.0
+ // 0x0410 Borland C/C++ 3.1
+ // 0x0550 Borland C/C++ 5.5 (C++Builder 5.0)
+
+ // Next codes are in addition defined as __CODEGEARC__
+ // See http://docwiki.embarcadero.com
+
+ // 0x0570 for Borland Developer Studio 2006 (BDS 2006)
+ // 0x0590 for C++Builder 2007
+ // 0x0591 for update 1 to C++Builder 2007
+ // 0x0592 for RAD Studio 2007
+ // 0x0593 for the December update to RAD Studio 2007
+ // 0x0610 for C++Builder 2009 and for C++Builder 2009 Update 1
+ // 0x0620 for C++Builder 2010 and for C++Builder 2010 Update 1
+ // 0x0621 for C++Builder 2010 Update 2
+ // 0x0630 for C++Builder XE
+ // 0x0631 for C++Builder XE Update 1
+ // 0x0640 for C++Builder XE2
+ // 0x0650 for C++Builder XE3
+
+ #if ( __BORLANDC__ >= 0x630 )
+ // C++Builder XE starts to provide stdbool.h
+ #include <stdint.h>
+ #include <stdbool.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #elif ( __BORLANDC__ >= 0x570 )
+ // at least BDS 2006 starts to provide stdint.h
+ #include <stdint.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #elif ( __BORLANDC__ >= 0x0550 )
+ #define MBG_TGT_HAS_INT_8_16_32 1
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #else // e.g. BC 3.1 or earlier
+ #if ( __BORLANDC__ <= 0x410 )
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #define USE_LONG_FOR_INT32 1
+ #endif
+ #endif
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
#if defined( __cplusplus )
#define __mbg_inline inline // standard C++ syntax
@@ -232,42 +471,46 @@
#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
+ // 1050 v10.5
+ // 1100 v11.0
+ // 1200 Open Watcom C++ v1.0
+ // 1230 Open Watcom C++ v1.3
+ // 1270 Open Watcom C++ v1.7
- #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+ #if defined( MBG_TGT_QNX ) // QNX 4.x
-#endif
+ #include <sys/types.h>
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #elif ( __WATCOMC__ > 1230 ) // Open Watcom C 1.3 and above
-// Currently we support only Sparc and i386/x86_64 architectures,
-// so unless we have explicitely found sparc we assume i386.
+ #include <stdint.h>
-#if !defined( _MBG_ARCH_DEFINED )
- #define MBG_ARCH_I386
-#endif
+ #elif !defined( __WATCOM_INT64__ ) // Watcom C 11
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
-#if defined( MBG_TGT_FREEBSD ) \
- || defined( MBG_TGT_NETBSD ) \
- || defined( MBG_TGT_OPENBSD )
- #define MBG_TGT_BSD
-#endif
+ #endif
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+
+ #define __mbg_inline _inline
-#if defined( MBG_TGT_LINUX ) \
- || defined( MBG_TGT_BSD ) \
- || defined( MBG_TGT_QNX_NTO )
- #define MBG_TGT_UNIX
#endif
+#if !defined( __GNUC__ ) && !defined( __attribute__ )
+ #define __attribute__( _x )
+#endif
+
#if defined( MBG_TGT_WIN32 )
+ #define _CRT_SECURE_NO_WARNINGS
+
#if defined( _AMD64_ )
// This is used for AMD64 architecture and for
// Intel XEON CPUs with 64 bit extension.
@@ -279,10 +522,18 @@
#endif
#if defined( _KDD_ )
+ #define MBG_TGT_KERNEL
#include <ntddk.h>
#else
// This must not be used for kernel drivers.
+ #if !defined( WIN32_LEAN_AND_MEAN )
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+
+ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
+ #include <winsock2.h>
#include <windows.h>
+
typedef HANDLE MBG_HANDLE;
#define MBG_INVALID_HANDLE INVALID_HANDLE_VALUE
@@ -313,7 +564,11 @@
#define _MBG_API_ATTR __declspec( dllimport )
#endif
-#elif defined( MBG_TGT_UNIX )
+#elif defined( MBG_TGT_POSIX )
+
+ #if !defined( MBG_TGT_KERNEL )
+ #include <unistd.h>
+ #endif
typedef int MBG_HANDLE;
typedef int MBG_PORT_HANDLE;
@@ -338,28 +593,33 @@
#define _MBG_API_ATTR
#endif
+#if !defined( _NO_MBG_API_ATTR )
+ #define _NO_MBG_API_ATTR
+#endif
+
#if !defined( MBG_INVALID_PORT_HANDLE )
#define MBG_INVALID_PORT_HANDLE MBG_INVALID_HANDLE
#endif
#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
+ #define MBG_USE_MM_IO_FOR_PCI 0
#endif
-#if !defined( _nop_macro_fnc )
- #define _nop_macro_fnc() do {} while (0)
+// The macros below are defined in order to be able to check if
+// certain C language extensions are available on the target system:
+#if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199409L )
+ #define MBG_TGT_C94 1
+#else
+ #define MBG_TGT_C94 0
#endif
-// 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 ) )
+#if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L )
+ #define MBG_TGT_C99 1
+#else
+ #define MBG_TGT_C99 0
+#endif
// Check if wchar_t is supported
#if !defined( MBG_TGT_HAS_WCHAR_T )
@@ -372,7 +632,7 @@
// 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
#define wchar_t char
#endif
#endif
diff --git a/mbglib/common/mbg_tmo.h b/mbglib/common/mbg_tmo.h
index 60399b9..3035d60 100644
--- a/mbglib/common/mbg_tmo.h
+++ b/mbglib/common/mbg_tmo.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_tmo.h 1.4 2011/01/26 16:55:33Z martin REL_M $
+ * $Id: mbg_tmo.h 1.8.1.3 2014/03/06 13:51:39Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,19 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_tmo.h $
+ * Revision 1.8.1.3 2014/03/06 13:51:39Z martin
+ * Renamed mbgserio_msec_to_timeval to mbg_msec_to_timeval.
+ * Revision 1.8.1.2 2014/03/04 12:08:11 martin
+ * Revision 1.8.1.1 2014/01/08 17:20:51Z martin
+ * MBG_TGT_POSIX
+ * Revision 1.8 2013/12/11 12:08:29 martin
+ * Fixed Windows build.
+ * Revision 1.7 2012/11/02 09:04:36Z martin
+ * Fix to have struct timeval defined under Windows.
+ * Revision 1.6 2012/03/16 11:56:23 martin
+ * Added mbg_tmo_delta_t().
+ * Revision 1.5 2011/11/28 15:26:47 martin
+ * Enabled mbgserio_msec_to_timeval() for Windows.
* Revision 1.4 2011/01/26 16:55:33Z martin
* Fixed compiler warnings with gcc/Linux.
* Revision 1.3 2010/06/02 12:29:44 daniel
@@ -40,8 +53,9 @@
/* Start of header body */
-#if defined( MBG_TGT_UNIX )
+#if defined( MBG_TGT_POSIX )
+ // TODO: eventually use timespec, if available
#include <stdlib.h>
#include <sys/time.h>
@@ -71,7 +85,7 @@
static __mbg_inline
void mbg_tmo_get_time( MBG_TMO_TIME *t )
{
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
gettimeofday( t, NULL );
@@ -100,12 +114,13 @@ void mbg_tmo_get_time( MBG_TMO_TIME *t )
#endif
+
#if defined( __mbg_inline )
static __mbg_inline
int mbg_tmo_time_is_set( const MBG_TMO_TIME *t )
{
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
return ( t->tv_sec != 0 ) || ( t->tv_usec != 0 );
@@ -134,6 +149,7 @@ int mbg_tmo_time_is_set( const MBG_TMO_TIME *t )
#endif
+
#if defined( __mbg_inline )
static __mbg_inline
@@ -141,7 +157,7 @@ void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec )
{
mbg_tmo_get_time( t_tmo );
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
t_tmo->tv_usec += msec * 1000;
@@ -177,12 +193,13 @@ void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec )
#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 )
+ #if defined( MBG_TGT_POSIX )
return ( t->tv_sec - t0->tv_sec ) * 1000
+ ( t->tv_usec - t0->tv_usec ) / 1000;
@@ -212,12 +229,49 @@ long mbg_tmo_time_diff_ms( const MBG_TMO_TIME *t, const MBG_TMO_TIME *t0 )
#endif
+
+#if defined( __mbg_inline )
+
+static __mbg_inline
+double mbg_tmo_delta_t( const MBG_TMO_TIME *t, const MBG_TMO_TIME *t0 )
+{
+ #if defined( MBG_TGT_POSIX )
+
+ return (double) ( t->tv_sec - t0->tv_sec )
+ + (double) ( t->tv_usec - t0->tv_usec ) / 1e6;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return ( (double) (int64_t) ( t->u64 - t0->u64 ) ) / 1e7;
+
+ #else // DOS, ...
+
+ return (double) ( *t - *t0 ) / (double) CLOCKS_PER_SEC;
+
+ #endif
+
+} // mbg_tmo_delta_t
+
+#elif defined( MBG_TGT_CVI )
+
+ #define mbg_tmo_delta_t( _t, _t0 ) \
+ ( (double) ( (_t)->u64 - (_t0)->u64 ) / (double) CLOCKS_PER_SEC )
+
+#else // DOS, ...
+
+ #define mbg_tmo_delta_t( _t, _t0 ) \
+ ( (double) ( *(_t) - *(_t0) ) / (double) 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 )
+ #if defined( MBG_TGT_POSIX )
return ( ( t_now->tv_sec > tmo->tv_sec ) ||
( ( t_now->tv_sec == tmo->tv_sec ) && ( t_now->tv_usec > tmo->tv_usec ) ) );
@@ -275,19 +329,19 @@ int mbg_tmo_curr_time_is_after( const MBG_TMO_TIME *tmo )
#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 );
+ void mbg_msec_to_timeval( ulong msec, struct timeval *tv );
-#elif defined( MBG_TGT_UNIX )
+#elif defined( MBG_TGT_POSIX ) || defined( MBG_TGT_WIN32 )
static __mbg_inline
-void mbgserio_msec_to_timeval( ulong msec, struct timeval *tv )
+void mbg_msec_to_timeval( ulong msec, struct timeval *tv )
{
tv->tv_sec = msec / 1000;
tv->tv_usec = ( msec % 1000 ) * 1000;
-} // mbgserio_msec_to_timeval
+} // mbg_msec_to_timeval
-#endif // defined( MBG_TGT_UNIX ) || defined( MBG_TGT_WIN32 )
+#endif // defined( MBG_TGT_POSIX ) || defined( MBG_TGT_WIN32 )
/* function prototypes: */
diff --git a/mbglib/common/mbgerror.c b/mbglib/common/mbgerror.c
new file mode 100644
index 0000000..576cae7
--- /dev/null
+++ b/mbglib/common/mbgerror.c
@@ -0,0 +1,413 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgerror.c 1.1.1.10 2015/05/20 12:34:03Z martin TEST $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg Library to communicate with USB devices from user space
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgerror.c $
+ * Revision 1.1.1.10 2015/05/20 12:34:03Z martin
+ * Revision 1.1.1.9 2014/10/28 15:19:17 martin
+ * Revision 1.1.1.8 2014/05/27 12:44:33Z martin
+ * Revision 1.1.1.7 2014/05/09 11:39:17 marvin
+ * Added access denied error to win32_to_mbg error handling.
+ * Revision 1.1.1.6 2014/03/18 11:25:54Z gregoire
+ * Fixed build errors fopr CVI, but this needs
+ * to be tested / improved.
+ * Revision 1.1.1.5 2014/03/12 09:01:56Z martin
+ * Revision 1.1.1.4 2014/03/11 14:12:29 martin
+ * Revision 1.1.1.3 2014/03/11 14:08:55Z martin
+ * Revision 1.1.1.2 2014/03/10 16:57:15Z martin
+ * Revision 1.1.1.1 2014/03/07 13:20:26 martin
+ * Tmp. saved changes.
+ * Revision 1.1 2014/03/07 12:08:14 martin
+ * Initial revision.
+ *
+**************************************************************************/
+
+#define _MBGERROR
+ #include <mbgerror.h>
+#undef _MBGERROR
+
+#include <mbg_tgt.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined( MBG_TGT_POSIX )
+ #include <errno.h>
+ #include <netdb.h>
+#endif
+
+
+
+#if defined( MBG_TGT_WIN32 )
+
+/*HDR*/
+/**
+ * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param last_err A Windows non-socket API error code as returned by GetLastError()
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) last_err );
+ #endif
+
+ //##++++++++++++++++ TODO check codes
+ switch ( last_err ) // codes usually defined in winerror.h
+ {
+ case ERROR_SUCCESS: return MBG_SUCCESS;
+ case ERROR_ACCESS_DENIED: return MBG_ERR_ACCESS;
+
+ case ERROR_PRIVILEGE_NOT_HELD: return MBG_ERR_PERM;
+
+ #if 0
+ case ERROR_INVALID_HANDLE:
+
+ case ERROR_NOT_ENOUGH_MEMORY:
+ case ERROR_OUTOFMEMORY:
+
+ case ERROR_WRITE_PROTECT:
+ case ERROR_BAD_UNIT:
+ case ERROR_NOT_READY:
+ case ERROR_WRITE_FAULT:
+ case ERROR_READ_FAULT:
+ case ERROR_GEN_FAILURE:
+ case ERROR_SHARING_VIOLATION:
+ case ERROR_LOCK_VIOLATION:
+ case ERROR_NOT_SUPPORTED:
+
+ case ERROR_DUP_NAME:
+ case ERROR_BAD_DEV_TYPE:
+ case ERROR_BUFFER_OVERFLOW:
+
+ case ERROR_BUSY:
+ case ERROR_NOACCESS:
+ #endif
+ }
+
+ return MBG_ERR_UNSPEC;
+
+} // mbg_win32_last_err_to_mbg
+
+
+
+/*HDR*/
+/**
+ * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param wsa_err A Windows socket API error code as returned by WSAGetLastError()
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) wsa_err );
+ #endif
+
+ //##++++++++++++++++ TODO check codes
+ switch ( wsa_err )
+ {
+ case WSAENOTSOCK:
+ return MBG_ERR_NOT_A_SOCKET;
+
+ case WSANOTINITIALISED:
+ return MBG_ERR_SOCK_INIT;
+
+ case WSAEFAULT:
+ case WSAENETDOWN:
+ case WSAEINVAL:
+ case WSAEINTR:
+ case WSAEINPROGRESS:
+ return MBG_ERR_SOCK_INIT;
+
+ case WSAEAFNOSUPPORT:
+ case WSAEMFILE:
+ case WSAEINVALIDPROVIDER:
+ case WSAEINVALIDPROCTABLE:
+ case WSAENOBUFS:
+ case WSAEPROTONOSUPPORT:
+ case WSAEPROTOTYPE:
+ case WSAEPROVIDERFAILEDINIT:
+ case WSAESOCKTNOSUPPORT:
+ return MBG_ERR_INV_SOCK_FD; //##++++++++++++++++
+
+#if 0
+ case WSAEALREADY:
+ case WSAEISCONN:
+ case WSAENETUNREACH:
+ return MBG_ERR_SOCKET_CFG; //##+++++
+ break;
+#endif
+ }
+
+ return MBG_ERR_UNSPEC;
+
+} // mbg_win32_wsa_err_to_mbg
+
+#endif // defined( MBG_TGT_WIN32 )
+
+
+
+#if defined( MBG_TGT_POSIX )
+
+/*HDR*/
+/**
+ * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param posix_errno A POSIX error code as usually defined in errno.h
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_posix_errno_to_mbg( int posix_errno, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s: %s (errno: %i)\n", info,
+ strerror( posix_errno ), posix_errno );
+ #endif
+
+ switch ( posix_errno )
+ {
+ case EPERM: return MBG_ERR_PERM;
+ case EINTR: return MBG_ERR_INTR;
+ case EIO: return MBG_ERR_IO;
+ case ENXIO: return MBG_ERR_NOT_FOUND;
+ case ENOMEM: return MBG_ERR_NO_MEM;
+ case EACCES: return MBG_ERR_ACCESS;
+ case EBUSY: return MBG_ERR_BUSY;
+ case ENODEV: return MBG_ERR_NO_DEV;
+ case EINVAL: return MBG_ERR_INV_PARM;
+ case EPIPE: return MBG_ERR_PIPE;
+ case EOVERFLOW: return MBG_ERR_OVERFLOW;
+ case ENOTSOCK: return MBG_ERR_NOT_A_SOCKET;
+ default: break;
+ }
+
+ return MBG_ERR_UNSPEC;
+
+} // mbg_posix_errno_to_mbg
+
+
+/*HDR*/
+/**
+ * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * This function is specific to translate error codes returned by
+ * gethostbyname() and gethostbyaddr(). In case of error these functions
+ * don't set errno but h_errno to a specific value.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param posix_h_errno An error code as usually defined in netdb.h
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s: %s (h_errno: %i)\n", info,
+ hstrerror( posix_h_errno ), posix_h_errno );
+ #endif
+
+ switch ( posix_h_errno )
+ {
+ case HOST_NOT_FOUND: // The specified host is unknown
+
+ // case NO_ADDRESS: // Usually same numeric value as NO_DATA
+ case NO_DATA: // The requested name is valid but does not have an IP address
+
+ case NO_RECOVERY: // A nonrecoverable name server error occurred
+
+ case TRY_AGAIN: // A temporary error occurred on an authoritative name server. Try again later.
+ return MBG_ERR_UNSPEC; //##++++++++++++++++++++++++
+ }
+
+ return MBG_ERR_UNSPEC;
+
+} // mbg_posix_h_errno_to_mbg
+
+#endif // defined( MBG_TGT_POSIX )
+
+
+
+/*HDR*/
+/**
+ * @brief Get and translate last error after non-socket function call
+ *
+ * Retrieve the "last error" code after a non-socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError(), whereas the "last error"
+ * code from non-socket POSIX-like functions has to be retrieved
+ * by calling GetLastError().
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_last_error( const char *info )
+{
+ #if defined( MBG_TGT_WIN32 )
+
+ // Under Windows the "last error" code after a non-socket function
+ // has to be retrieved by calling GetLastError(), whereas
+ // the "last error" code from POSIX-like socket functions
+ // is retrieved by calling WSAGetLastError().
+ return mbg_win32_wsa_err_to_mbg( GetLastError(), info );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ // On POSIX systems the "last error" code is always stored in errno.
+ return mbg_posix_errno_to_mbg( errno, info );
+
+ #else
+
+ #error This function is not supported for this target.
+
+ #endif
+
+} // mbg_get_last_error
+
+
+
+/*HDR*/
+/**
+ * @brief Get and translate last error after socket function call
+ *
+ * Retrieve the "last error" code after a socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError, whereas the "last error"
+ * code from non-socket POSIX-like functions is stored in errno as usual.
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_last_socket_error( const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ // Under Windows the "last error" code after a socket function
+ // has to be retrieved by calling WSAGetLastError, whereas
+ // the "last error" code from non-socket POSIX-like functions
+ // is stored in errno as usual.
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ // On POSIX systems the "last error" code is always stored in errno.
+ return mbg_posix_errno_to_mbg( errno, info );
+
+ #else
+
+ #error This function is not supported for this target.
+
+ #endif
+
+} // mbg_get_last_socket_error
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve and convert last error after gethostbyname()
+ *
+ * This function is specific to retrieve and translate error codes
+ * returned by gethostbyname() and gethostbyaddr(). In case of error
+ * these functions don't set errno but h_errno on POSIX systems, but
+ * under Windows the error code can be retrieved by WSAGetLastError()
+ * as usual.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_gethostbyname_error( const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ return mbg_posix_h_errno_to_mbg( h_errno, info );
+
+ #else
+
+ #error This function is not supported for this target.
+
+ #endif
+
+} // mbg_get_gethostbyname_error
+
+
+
+#if 0 // not yet finished
+// error handler for getaddressinfo()
+/*
+ * Handle specific error returned by getaddressinfo()
+ */
+ /*HDR*/
+int mbg_gai_error( int rc, const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ return mbg_posix_h_errno_to_mbg( h_errno, info );
+
+ #else
+
+ return MBG_ERR_UNSPEC;
+
+ #endif
+
+} // mbg_get_gai_error
+
+#endif
+
+
+
diff --git a/mbglib/common/mbgerror.h b/mbglib/common/mbgerror.h
new file mode 100644
index 0000000..2db8649
--- /dev/null
+++ b/mbglib/common/mbgerror.h
@@ -0,0 +1,326 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgerror.h 1.7.1.6 2015/05/20 12:33:17Z martin TEST $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Error codes used with Meinberg devices and drivers.
+ * The codes can be translated into an OS dependent error code.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgerror.h $
+ * Revision 1.7.1.6 2015/05/20 12:33:17Z martin
+ * Revision 1.7.1.5 2015/05/13 13:53:23 martin
+ * Revision 1.7.1.4 2014/10/30 11:15:36 martin
+ * Revision 1.7.1.3 2014/10/28 15:19:17 martin
+ * Revision 1.7.1.2 2014/09/26 11:45:34Z martin
+ * Revision 1.7.1.1 2014/06/25 08:52:50 martin
+ * Re-enabled some symbols which have been commented out..
+ * Revision 1.7 2014/05/27 13:32:47Z martin
+ * Defined additional common error codes which can be
+ * translated from OS specific codes.
+ * Function prototypes from new module mbgerror.c.
+ * Comments in doxygen style.
+ * Revision 1.6 2012/10/02 18:42:26Z martin
+ * New codes MBG_ERR_N_POUT_EXCEEDS_SUPP and
+ * MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP.
+ * Modified comments for doxygen.
+ * Revision 1.5 2011/03/31 10:56:17 martin
+ * Added MBG_ERR_COPY_TO_USER and MBG_ERR_COPY_FROM_USER.
+ * Revision 1.4 2008/12/05 13:28:50 martin
+ * Added new code MBG_ERR_IRQ_UNSAFE.
+ * Revision 1.3 2008/02/26 14:50:14Z daniel
+ * Added codes:
+ * MBG_ERR_NOT_SUPP_ON_OS, MBG_ERR_LIB_NOT_COMPATIBLE,
+ * MBG_ERR_N_COM_EXCEEDS_SUPP, MBG_ERR_N_STR_EXCEEDS_SUPP
+ * Added doxygen compatible comments.
+ * Revision 1.2 2007/09/27 07:26:22Z martin
+ * Define STATUS_SUCCESS for Windows if not in kernel mode.
+ * Revision 1.1 2007/09/26 08:08:54Z martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBGERROR_H
+#define _MBGERROR_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+
+#ifdef _MBGERROR
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if !defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_KERNEL )
+ //##++++ Surprisingly we need this also for Windows
+ // in kernel mode. This should be fixed.
+ #define DWORD uint32_t // just to avoid compiler errors
+#endif
+
+
+/**
+ * @brief Error codes used with Meinberg devices and drivers
+ *
+ * Some of the codes have to match codes which are defined in pcpsdefs.h
+ * and returned by the firmware of bus-level devices.
+ *
+ * The codes will be translated into an OS dependent error code
+ * when returned to the calling function.
+ *
+ * For Windows, these codes are made positive and or'ed with 0xE0000000 afterwards.
+ *
+ * Example: Code -19 (#MBG_ERR_GENERIC) will be converted to 0xE0000013 under Windows.
+ *
+ * @note Attention:
+ * The error codes below must match exactly the corresponding codes that are evaluated in user space.
+ * For Windows, they are located in messages.mc/.h in mbgsvctl.dll
+ *
+ * @anchor MBG_RETURN_CODES @{ */
+
+#define MBG_SUCCESS 0 ///< no error, must match ::PCPS_SUCCESS
+
+ /** @anchor MBG_ERROR_CODES @{ */
+
+// Other codes which have to match codes defined in pcpsdefs.h returned by bus-level devices
+#define MBG_ERR_STIME -1 ///< invalid date/time/status passed, must match ::PCPS_ERR_STIME
+#define MBG_ERR_CFG -2 ///< invalid params with a configuration cmd, must match ::PCPS_ERR_CFG
+
+
+// Codes returned by low level functions of the bus-level device driver
+#define MBG_ERR_GENERIC -19 ///< generic error
+#define MBG_ERR_TIMEOUT -20 ///< timeout accessing the device
+#define MBG_ERR_FW_ID -21 ///< invalid firmware ID
+#define MBG_ERR_NBYTES -22 ///< the number of parameter bytes passed to the device did not
+ ///< match the number of bytes expected by the device
+
+#define MBG_ERR_INV_TIME -23 ///< the device doesn't have valid time
+#define MBG_ERR_FIFO -24 ///< the data FIFO of a bus-level device is empty, though it shouldn't be
+#define MBG_ERR_NOT_READY -25 ///< bus-level device is temp. unable to respond e.g. during init. after RESET
+#define MBG_ERR_INV_TYPE -26 ///< bus-level device didn't recognize data type
+
+
+// Codes returned by the high level API functions
+#define MBG_ERR_NO_MEM -27 ///< failed to allocate memory
+#define MBG_ERR_CLAIM_RSRC -28 ///< failed to claim port or mem resource
+#define MBG_ERR_DEV_NOT_SUPP -29 ///< specified device type not supported by driver
+#define MBG_ERR_INV_DEV_REQUEST -30 ///< IOCTL call not supported by driver
+#define MBG_ERR_NOT_SUPP_BY_DEV -31 ///< cmd or feature not supported by device
+#define MBG_ERR_USB_ACCESS -32 ///< USB access failed
+#define MBG_ERR_CYCLIC_TIMEOUT -33 ///< cyclic event (IRQ, etc.) didn't occur
+#define MBG_ERR_NOT_SUPP_ON_OS -34 ///< function is not supported under this operating system
+#define MBG_ERR_LIB_NOT_COMPATIBLE -35 ///< installed shared lib. version not compat. with version used at build time
+#define MBG_ERR_N_COM_EXCEEDS_SUPP -36 ///< num. COM ports of the device exceeds max. supp. by driver
+#define MBG_ERR_N_STR_EXCEEDS_SUPP -37 ///< num. string formats of the device exceeds max. supp. by driver
+#define MBG_ERR_IRQ_UNSAFE -38 ///< enabled IRQ of bus-level device is unsafe with this firmware/ASIC version
+#define MBG_ERR_N_POUT_EXCEEDS_SUPP -39 ///< num. prog. outputs of the device exceeds max. supp. by driver
+
+// Legacy codes used with DOS TSRs only:
+#define MBG_ERR_INV_INTNO -40 ///< invalid interrupt number
+#define MBG_ERR_NO_DRIVER -41 ///< a driver could not be found
+#define MBG_ERR_DRV_VERSION -42 ///< the driver is too old
+
+
+#define MBG_ERR_COPY_TO_USER -43 ///< kernel driver failed to copy data from kernel to user space
+#define MBG_ERR_COPY_FROM_USER -44 ///< kernel driver failed to copy data from use to kernel space
+
+
+// More codes returned by the driver's high level functions:
+#define MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP -45 ///< num. PTP unicast masters of the device exceeds max. supp. by driver
+#define MBG_ERR_N_GNSS_EXCEEDS_SUPP -46 ///< num. of GNSS systems supp. by device exceeds max. supp. by driver
+#define MBG_ERR_N_GPIO_EXCEEDS_SUPP -47 ///< num. of GPIO ports supp. by device exceeds max. supp. by driver
+#define MBG_ERR_N_XMR_EXCEEDS_SUPP -48 ///< num. of XMR sources supp. by device exceeds max. supp. by driver
+
+#define MBG_ERR_UNSPEC -60 ///< unspecified error
+
+#define MBG_ERR_HDR_CSUM -61 ///< binary protocol header checksum error
+#define MBG_ERR_DATA_CSUM -62 ///< binary protocol data checksum error
+#define MBG_ERR_RCVD_NACK -63 ///< binary protocol received reply msg with a NACK code
+#define MBG_ERR_RCVD_NO_ACK -64 ///< binary protocol received reply msg without expected ACK code
+#define MBG_ERR_CONN_TYPE -65 ///< binary protocol no valid/supported connection type specified
+#define MBG_ERR_BYTES_WRITTEN -66 ///< binary protocol failed to write all bytes
+#define MBG_ERR_AUTH -67 ///< binary protocol failed authentication
+
+#define MBG_ERR_SOCK_INIT -68 ///< socket interface not initialized, or failed to initialize
+#define MBG_ERR_INV_SOCK_FD -69 ///< invalid socket when tried to open network socket
+#define MBG_ERR_NOT_A_SOCKET -70 ///< socket descriptor is not a socket
+#define MBG_ERR_NBLOCK_WAIT_SLCT -71 ///< select timed out when waiting for non-blocking network port to become ready
+#define MBG_ERR_NBLOCK_WAIT_WR_FD -72 ///< write fd not set after select when waiting for non-blocking network port to become ready
+
+#define MBG_ERR_IO -73 ///< generic I/O error
+#define MBG_ERR_INV_PARM -74 ///< invalid parameter
+#define MBG_ERR_NO_DEV -75 ///< specified device not found
+#define MBG_ERR_NOT_FOUND -76 ///< specified item not found
+
+#define MBG_ERR_OVERFLOW -77 ///< buffer overflow
+#define MBG_ERR_PIPE -78 ///< pipe error
+#define MBG_ERR_INTR -79 ///< interrupted system call
+#define MBG_ERR_ACCESS -80 ///< access denied, e.g. when trying to access a device
+#define MBG_ERR_PERM -81 ///< operation not permitted, e.g. when trying to set the system time
+#define MBG_ERR_BUSY -82 ///< device busy
+#define MBG_ERR_INV_HANDLE -83 ///< invalid file/device handle specified
+
+#define MBG_ERR_XBP_CASC_LVL -84 ///< too many XBP cascading levels
+#define MBG_ERR_ENCRYPT -85 ///< encryption failed
+#define MBG_ERR_DECRYPT -86 ///< decryption failed
+
+/** @} anchor MBG_ERROR_CODES */
+
+/** @} anchor MBG_RETURN_CODES */
+
+
+
+// Depending on the operating system, the codes above have to be converted before
+// they are sent up to user space
+#if defined( MBG_TGT_WIN32 )
+ #if !defined( STATUS_SUCCESS ) // not in kernel mode
+ #define STATUS_SUCCESS 0
+ #endif
+
+ #define _mbg_err_to_os( _c ) \
+ ( ( _c == MBG_SUCCESS ) ? STATUS_SUCCESS : ( abs( _c ) | 0xE0000000 ) )
+#endif
+
+
+// If no specific conversion has been defined
+// then use the original codes.
+#if !defined( _mbg_err_to_os )
+ #define _mbg_err_to_os( _c ) ( _c )
+#endif
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param wsa_err A Windows non-socket API error code as returned by GetLastError()
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_win32_last_err_to_mbg( DWORD wsa_err, const char *info ) ;
+
+ /**
+ * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param wsa_err A Windows socket API error code as returned by WSAGetLastError()
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info ) ;
+
+ /**
+ * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param posix_errno A POSIX error code as usually defined in errno.h
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) ;
+
+ /**
+ * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * This function is specific to translate error codes returned by
+ * gethostbyname() and gethostbyaddr(). In case of error these functions
+ * don't set errno but h_errno to a specific value.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param posix_h_errno An error code as usually defined in netdb.h
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) ;
+
+ /**
+ * @brief Get and translate last error after non-socket function call
+ *
+ * Retrieve the "last error" code after a non-socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError(), whereas the "last error"
+ * code from non-socket POSIX-like functions has to be retrieved
+ * by calling GetLastError().
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_last_error( const char *info ) ;
+
+ /**
+ * @brief Get and translate last error after socket function call
+ *
+ * Retrieve the "last error" code after a socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError, whereas the "last error"
+ * code from non-socket POSIX-like functions is stored in errno as usual.
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_last_socket_error( const char *info ) ;
+
+ /**
+ * @brief Retrieve and convert last error after gethostbyname()
+ *
+ * This function is specific to retrieve and translate error codes
+ * returned by gethostbyname() and gethostbyaddr(). In case of error
+ * these functions don't set errno but h_errno on POSIX systems, but
+ * under Windows the error code can be retrieved by WSAGetLastError()
+ * as usual.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_gethostbyname_error( const char *info ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGERROR_H */
diff --git a/mbglib/common/mbgextio.c b/mbglib/common/mbgextio.c
index 17322b0..182d27d 100644
--- a/mbglib/common/mbgextio.c
+++ b/mbglib/common/mbgextio.c
@@ -1,17 +1,111 @@
/**************************************************************************
*
- * $Id: mbgextio.c 1.11 2011/04/15 13:17:14Z martin REL_M $
+ * $Id: mbgextio.c 1.20.1.19 2015/07/22 16:02:07Z martin TEST martin $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* Meinberg extended I/O functions for the binary data protocol
- * via serial communication and network socket I/O.
+ * via serial communication, network socket I/O, or direct USB I/O.
+ *
+ * These functions can *not* be used to access LANTIME NTP servers,
+ * or the modules assembled within a LANTIME since LANTIMEs are using
+ * this kind of communication only internally.
+ *
+ * Also, standalone USB devices are usually handled by the driver
+ * software package for the given operating system and thus can be
+ * accessed in the same way as PCI cards, using the API functions
+ * provided by the mbgdevio library.
+ *
+ * These functions can be used, however, with standalone devices
+ * which are accessible either directly via a serial port, or via a
+ * special serial-to-LAN converter like the meinberg LAN_XPT module.
*
* -----------------------------------------------------------------------
* $Log: mbgextio.c $
- * Revision 1.11 2011/04/15 13:17:14Z martin
+ * Revision 1.20.1.19 2015/07/22 16:02:07Z martin
+ * Started to support variable USB endpoint numbers.
+ * Revision 1.20.1.18 2015/07/14 15:08:43 martin
+ * Unified parameter naming and updated doxygen comments.
+ * Revision 1.20.1.17 2015/07/14 14:05:55 martin
+ * Support XBP addressing.
+ * Added functions to read/send UTC parameters.
+ * Support for USB_DIRECT_IO
+ * Fixed dealloc_msg_ctl() where not all memory was freed.
+ * Reworked mbgextio_force_conn_serial_ftdi().
+ * Revision 1.20.1.16 2014/10/30 16:03:05 martin
+ * Doxygen fixes.
+ * Revision 1.20.1.15 2014/10/30 14:45:55 martin
+ * Generally return Meinberg error codes only.
+ * Do not use GPS_REQACK for secu_settings.
+ * Added FTDI support functions.
+ * Reworked "force connection" functions, also supporting high speed now.
+ * Updated libusb support.
+ * Many new API functions.
+ * Revision 1.20.1.14 2013/11/28 15:51:45Z marvin
+ * Added mbgextio_get_ntp_peer_state_idx.
+ * Revision 1.20.1.13 2013/11/26 16:06:43Z marvin
+ * Added mbgextio_get_ntp_sys_state.
+ * Revision 1.20.1.12 2013/11/21 07:46:44Z marvin
+ * Added mbgextio_xmt_secu_settings.
+ * Cleanup for socket port.
+ * Revision 1.20.1.11 2013/11/15 12:17:30Z marvin
+ * Added error return for TGT_LINUX if socket_opt_error detected.
+ * Revision 1.20.1.10 2013/11/15 11:49:12Z marvin
+ * Fixed: return 0 if non_blocking_socket is OK.
+ * check if received GPS_NACK for encryption mode (socket connection).
+ * Revision 1.20.1.9 2013/11/13 16:30:10Z martin
+ * Revision 1.20.1.8 2013/11/13 16:13:26 martin
+ * Revision 1.20.1.7 2013/11/13 16:05:52 marvin
+ * Revision 1.20.1.6 2013/11/13 15:14:17Z martin
+ * Cleaned up socket connection code.
+ * Revision 1.20.1.5 2013/11/12 12:12:02 marvin
+ * Changed calls for NTP info and settings.
+ * Revision 1.20.1.4 2013/11/11 11:30:27Z marvin
+ * Changed socket connection.
+ * Revision 1.20.1.3 2013/11/05 15:53:11Z marvin
+ * Changed connecting via socket.
+ * Revision 1.20.1.2 2013/10/14 08:54:19Z marvin
+ * Added mbgextio_set_ntp_clnt_mode_cfg.
+ * Revision 1.20.1.1 2013/09/25 11:09:53Z marvin
+ * Added NTP support and new support for PTP.
+ * Revision 1.20 2013/09/10 08:56:35Z marvin
+ * Changed Doxygen comments.
+ * Revision 1.19 2013/09/05 15:10:39Z marvin
+ * Added support for LAN interface setup
+ * Added support for PTP state
+ * Added support for XMR.
+ * Revision 1.18 2013/09/02 15:16:48Z marvin
+ * Added support for XMR (get multi ref info, set multi ref settings)
+ * Revision 1.17 2013/08/28 11:01:41Z marvin
+ * Added read and set tr_distance and gnss_mode.
+ * Revision 1.16.1.1 2013/06/05 09:17:54Z marvin
+ * Changed close_connection for socket.
+ * Revision 1.16 2013/04/11 14:18:33Z Gregoire
+ * new calls for sending havequick rx and tx settings to clock
+ * Revision 1.15 2013/02/14 14:42:13Z martin
+ * Fixed syntax err due to unintentionally pasted word.
+ * Revision 1.14 2013/02/06 15:43:54 martin
+ * Updated doxygen comments.
+ * Revision 1.13 2013/02/01 15:58:43 martin
+ * In mbgextio_force_connection() for Windows wait until all chars
+ * must have been sent since flushing output buffer doesn't work reliably.
+ * Added a number of new functions.
+ * Added doxygen comments.
+ * Revision 1.12 2012/10/30 16:17:30 martin
+ * Started to migrate to opaque stuctures.
+ * Conditionally let xmt routines request for ACK packet,
+ * though this is by default disabled.
+ * Support receiving NACK status.
+ * Support big endian target platforms.
+ * Merged and adapted Daniel's USB support functions.
+ * Support event log entries.
+ * Syntax workaround which is required until this module becomes a DLL.
+ * Added some new functions.
+ * Updated doxygen comments.
+ * Huge cleanup.
+ * Revision 1.11 2011/04/15 13:17:14 martin
* Use common mutex support macros from mbgmutex.h.
* Revision 1.10 2011/04/08 11:28:24 martin
* Modified mbgextio_get_ucap() to account for different device behaviour.
@@ -36,7 +130,7 @@
* 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
+ * 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,
@@ -60,30 +154,47 @@
#define _MBGEXTIO
#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 <mbg_arch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpsutils.h>
+#include <mbgerror.h>
-#if defined( MBG_TGT_UNIX )
- #include <unistd.h>
+#if defined( MBG_TGT_POSIX )
#include <fcntl.h>
+ #include <errno.h>
#else
typedef int ssize_t;
#endif
-#if !defined( MBGEXTIO_DIRECT_RC )
- #define _MBGEXTIO_DIRECT_RC 0 //##++ 1
+#if _USE_USB_IO
+ #include <mbgusbio.h>
+#endif
+
+#if _USE_USB_DIRECT_IO
+ #include <poll.h>
+#endif
+
+#if !defined( _MBGEXTIO_REQ_ACK )
+ // If _MBGEXTIO_REQ_ACK is != 0 then mbgextio_...() functions writing
+ // configuration parameters send the cmd code with the ACK request bit set
+ // which lets mbgextio_xmt_msg() try to receive a response from the device
+ // after the parameters have been sent.
+ #define _MBGEXTIO_REQ_ACK 0
+#endif
+
+#if _MBGEXTIO_REQ_ACK
+ #define OPT_GPS_ACK_CODE GPS_REQACK
+#else
+ #define OPT_GPS_ACK_CODE 0 // dummy
#endif
+#define DEBUG_SOCK_IO ( 1 && defined( DEBUG ) )
+
// default serial message timeout
#if !defined ( MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL )
@@ -96,6 +207,134 @@
#endif
+
+static const char force_conn_cmd_str[] = MBG_FORCE_CONN_CMD_STR;
+static const char force_conn_hs_cmd_str[] = MBG_FORCE_CONN_HS_CMD_STR;
+
+
+typedef struct
+{
+ int model_code;
+ long feature_mask;
+
+} BUILTIN_FEATURE_TABLE_ENTRY;
+
+static BUILTIN_FEATURE_TABLE_ENTRY builtin_feature_table[] = GPS_MODEL_BUILTIN_FEATURES;
+
+
+
+static /*HDR*/
+/**
+ * @brief Deallocate a message control structure
+ *
+ * Free the memory allocated for a message control structure
+ * and set the pointer to NULL.
+ *
+ * @param[in,out] ppmctl Address of a pointer to a message control structure
+ *
+ * @see ::alloc_msg_ctl
+ */
+void dealloc_msg_ctl( MBG_MSG_CTL **ppmctl )
+{
+ MBG_MSG_CTL *pmctl = *ppmctl;
+
+ if ( pmctl )
+ {
+ if ( pmctl->rcv.pmb )
+ {
+ free( pmctl->rcv.pmb );
+ pmctl->rcv.pmb = NULL;
+ }
+
+ pmctl->rcv.buf_size = 0;
+
+ if ( pmctl->xmt.pmb )
+ {
+ free( pmctl->xmt.pmb );
+ pmctl->xmt.pmb = NULL;
+ }
+
+ pmctl->xmt.buf_size = 0;
+
+ free( pmctl );
+ *ppmctl = NULL;
+ }
+
+} // dealloc_msg_ctl
+
+
+
+static /*HDR*/
+/**
+ * @brief Allocate a message control structure
+ *
+ * Allocate memory for a message control structure and associated
+ * message receive and transmit buffers.
+ *
+ * @param[out] ppmctl Address of a pointer to a message control structure to be allocated, set to NULL on error
+ *
+ * @return ::MBG_SUCCESS or one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::dealloc_msg_ctl
+ */
+int alloc_msg_ctl( MBG_MSG_CTL **ppmctl )
+{
+ int rc = MBG_ERR_UNSPEC;
+
+ MBG_MSG_CTL *pmctl = malloc( sizeof( *pmctl ) );
+
+ if ( pmctl == NULL )
+ {
+ #if defined( DEBUG )
+ fprintf( stderr, "failed to malloc control block in %s\n", __func__ );
+ #endif
+ goto fail;
+ }
+
+ memset( pmctl, 0, sizeof( *pmctl ) );
+
+ // allocate receive buffer
+ pmctl->rcv.buf_size = sizeof( *(pmctl->rcv.pmb) );
+ pmctl->rcv.pmb = malloc( pmctl->rcv.buf_size );
+
+ if ( pmctl->rcv.pmb == NULL )
+ {
+ #if defined( DEBUG )
+ fprintf( stderr, "failed to malloc rcv buffer in %s\n", __func__ );
+ #endif
+ goto fail;
+ }
+
+ // allocate transmit buffer
+ pmctl->xmt.buf_size = sizeof( *(pmctl->xmt.pmb) );
+ pmctl->xmt.pmb = malloc( pmctl->xmt.buf_size );
+
+ if ( pmctl->xmt.pmb == NULL )
+ {
+ #if defined( DEBUG )
+ fprintf( stderr, "failed to malloc xmt buffer in %s\n", __func__ );
+ #endif
+ goto fail;
+ }
+
+
+ // buffers allocated successfully
+ rc = MBG_SUCCESS;
+ goto out;
+
+
+fail: // if not all memory blocks could be allocated, clean up
+ dealloc_msg_ctl( &pmctl ); // also sets pmctl to NULL
+ rc = MBG_ERR_NO_MEM;
+
+out:
+ *ppmctl = pmctl;
+ return rc;
+
+} // alloc_msg_ctl
+
+
+
#if defined( MBG_TGT_WIN32 ) && _USE_SOCKET_IO
static /*HDR*/
@@ -134,25 +373,299 @@ void mbgextio_set_console_control_handler( void )
-
#if _USE_SOCKET_IO
static /*HDR*/
+/**
+ * @brief Set the blocking mode of a network socket
+ *
+ * @param[in] sock_fd The socket descriptor
+ * @param[in] blocking Blocking mode, 0: non-blocking, else blocking
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int set_socket_blocking_mode( MBG_SOCK_FD sock_fd, int blocking )
+{
+ int rc = MBG_ERR_UNSPEC;
+
+ if ( sock_fd == MBG_INVALID_SOCK_FD )
+ {
+ rc = MBG_ERR_INV_SOCK_FD;
+ goto out;
+ }
+
+ #if defined( MBG_TGT_WIN32 )
+ {
+ u_long mode = blocking ? 0 : 1; // ioctlsocket expects an (u_long *)
+
+ rc = ioctlsocket( sock_fd, FIONBIO, &mode ); // returns 0 on success
+
+ if ( rc != 0 ) // error
+ {
+ rc = mbg_get_last_socket_error( "ioctlsocket(FIONBIO) failed in set_socket_blocking_mode" );
+ goto out;
+ }
+ }
+ #elif defined( MBG_TGT_POSIX )
+ {
+ int val = fcntl( sock_fd, F_GETFL, 0 ); // returns -1 on error
+
+ if ( val == -1 )
+ {
+ rc = mbg_get_last_socket_error( "fcntl(F_GETFL) failed in set_socket_blocking_mode" );
+ goto out;
+ }
+
+ if ( blocking )
+ val &= ~O_NONBLOCK;
+ else
+ val |= O_NONBLOCK;
+
+ rc = fcntl( sock_fd, F_SETFL, val ); // returns -1 on error
+
+ if ( rc == -1 )
+ {
+ rc = mbg_get_last_socket_error( "fcntl(F_SETFL) failed in set_socket_blocking_mode" );
+ goto out;
+ }
+ }
+ #else
+ {
+ rc = MBG_ERR_NOT_SUPP_ON_OS;
+ goto out;
+ }
+ #endif
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // set_socket_blocking_mode
+
+
+
+static /*HDR*/
+/**
+ * @brief Get last socket error code converted to @ref MBG_RETURN_CODES
+ *
+ * @param[in] sock_fd The socket descriptor
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int get_sock_error( MBG_SOCK_FD sock_fd )
+{
+ int so_err = 0;
+ socklen_t so_err_sz = sizeof( so_err );
+ int rc = getsockopt( sock_fd, SOL_SOCKET, SO_ERROR, (void *) &so_err, &so_err_sz ); // returns 0 on success
+
+ if ( rc != 0 ) // error
+ {
+ rc = mbg_get_last_socket_error( "getsockopt SO_ERROR failed in get_sock_error" );
+ goto out;
+ }
+
+ if ( so_err_sz != sizeof( so_err ) ) // might have been modified by getsockopt()
+ {
+ fprintf( stderr, "Warning: getsockopt option size changed in get_sock_error: %li -> %li",
+ (long) sizeof( so_err ), (long) so_err_sz );
+ rc = MBG_ERR_UNSPEC;
+ goto out;
+ }
+
+ if ( so_err != 0 ) // error
+ {
+ #if defined( MBG_TGT_WIN32 )
+ rc = mbg_win32_wsa_err_to_mbg( so_err, "wait failed in wait_nonblocking_socket_ready" );
+ #elif defined( MBG_TGT_POSIX )
+ rc = mbg_posix_errno_to_mbg( so_err, "wait failed in wait_nonblocking_socket_ready" );
+ #else
+ #error This function is not supported for this target.
+ #endif
+ goto out;
+ }
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // get_sock_error
+
+
+
+static /*HDR*/
+/**
+ * @brief Wait for a non-blocking socket to get ready after a connect() call
+ *
+ * A connect() call to a socket which is not available can fail
+ * after a pretty long timeout which usually can't be changed.
+ *
+ * A workaround is to switch the socket to non-blocking mode,
+ * then call connect(), then do a select() with specified timeout,
+ * and finally switch the socket back to blocking mode.
+ *
+ * @param[in] sock_fd The socket descriptor
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int wait_nonblocking_socket_ready( MBG_SOCK_FD sock_fd, long timeout_msec )
+{
+ // At least under Windows a select call can set except_fds if
+ // the non-blocking attempt to connect fails.
+ // See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx
+ // Linux and FreeBSD suggest to use write_fds only.
+ #define USE_EXCEPT_FDS_WITH_CONNECT ( 1 || defined( MBG_TGT_WIN32 ) ) //##+++++++++++++++++++++++++++
+
+ fd_set write_fds;
+ #if USE_EXCEPT_FDS_WITH_CONNECT
+ fd_set except_fds;
+ #endif
+ int max_fd;
+ struct timeval tv_timeout;
+ int rc = MBG_ERR_UNSPEC;
+
+ mbg_msec_to_timeval( timeout_msec, &tv_timeout );
+
+ FD_ZERO( &write_fds );
+ FD_SET( sock_fd, &write_fds );
+
+ #if defined( MBG_TGT_WIN32 )
+ // Under Windows an fd is a handle which can't simply
+ // be converted to an int, but the first argument of
+ // select() is ignored under Windows anyway, so we just
+ // set max_fd to 0.
+ max_fd = 0;
+ #else
+ max_fd = sock_fd;
+ #endif
+
+ #if USE_EXCEPT_FDS_WITH_CONNECT
+ FD_ZERO( &except_fds );
+ FD_SET( sock_fd, &except_fds );
+ rc = select( max_fd + 1, NULL, &write_fds, &except_fds, &tv_timeout );
+ #else
+ rc = select( max_fd + 1, NULL, &write_fds, NULL, &tv_timeout );
+ #endif
+
+ if ( rc == MBG_SOCKET_ERR_RETVAL ) // < 0, error
+ {
+ rc = mbg_get_last_socket_error( "select failed in wait_nonblocking_socket_ready" );
+ goto out;
+ }
+
+ if ( rc == 0 ) // timeout
+ {
+ #if DEBUG_SOCK_IO
+ fprintf( stderr, "select timed out in wait_nonblocking_socket_ready" );
+ #endif
+ rc = MBG_ERR_NBLOCK_WAIT_SLCT;
+ goto out;
+ }
+
+ #if USE_EXCEPT_FDS_WITH_CONNECT
+ // The except_fds might be set if no connection could be
+ // established if e.g. the target socket is already busy.
+ if ( FD_ISSET( sock_fd, &except_fds ) )
+ {
+ rc = get_sock_error( sock_fd );
+ goto out;
+ }
+ #endif
+
+ // Usually the write_fds are checked to see if the
+ // non-blocking connect() call completed successfully,
+ // in which case the associated descriptor is set.
+ if ( !FD_ISSET( sock_fd, &write_fds ) )
+ {
+ #if DEBUG_SOCK_IO
+ fprintf( stderr, "write_fd is not set after select in wait_nonblocking_socket_ready" );
+ #endif
+ rc = MBG_ERR_NBLOCK_WAIT_WR_FD;
+ goto out;
+ }
+
+ #if defined( MBG_TGT_LINUX )
+ // From the connect(2) man page:
+ // After select(2) indicates writability, use getsockopt(2) to read
+ // the SO_ERROR option at level SOL_SOCKET to determine whether connect()
+ // completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR
+ // is one of the usual error codes, explaining the reason for the failure).
+ rc = get_sock_error( sock_fd );
+ goto out;
+ #endif
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // wait_nonblocking_socket_ready
+
+
+
+static /*HDR*/
+/**
+ * @brief Close a socket and make the socket descriptor invalid
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure containing the socket descriptor
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int socket_close( MBG_MSG_CTL *pmctl )
+{
+ int rc;
+
+ #if defined( MBG_TGT_CVI ) || defined( MBG_TGT_WIN32 )
+ rc = closesocket( pmctl->st.sockio.sockfd ); // returns 0 on success
+ #elif defined( MBG_TGT_POSIX )
+ rc = close( pmctl->st.sockio.sockfd ); // returns 0 on success
+ #else
+ #error close socket needs to be implemented for this target
+ #endif
+
+ pmctl->st.sockio.sockfd = MBG_INVALID_SOCK_FD;
+
+ if ( rc != 0 )
+ {
+ rc = mbg_get_last_socket_error( "failed to close socket socket_close" );
+ goto out;
+ }
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // socket_close
+
+
+
+static /*HDR*/
+/**
+ * @brief Initialize a socket connection to a specified host
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] host Host name or IP address of the target system
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
int socket_init( MBG_MSG_CTL *pmctl, const char *host )
{
struct hostent *hp;
struct sockaddr_in *paddr;
const struct sockaddr *p;
int sz;
- int rc;
+ int rc = MBG_ERR_UNSPEC;
+ //##++++++++ should use getaddrinfo() preferably
hp = gethostbyname( host );
#if defined( MBG_TGT_WIN32 )
+ // Under Windows the winsock2.dll may not yet have been initialized,
+ // so initialize now and try once more.
if ( hp == NULL )
{
- // The winsock2.dll may not yet have been initialized,
- // so try to initialize now.
WORD wVersionRequested;
WSADATA wsaData;
@@ -160,22 +673,37 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host )
rc = WSAStartup( wVersionRequested, &wsaData );
- // If initialization has succeeded, try again.
+ // If initialization has succeeded, try once more.
if ( rc == 0 )
hp = gethostbyname( host );
}
#endif // defined( MBG_TGT_WIN32 )
- if ( hp == NULL )
- return TR_OPEN_ERR;
-
+ if ( hp == NULL ) // error
+ {
+ rc = mbg_get_gethostbyname_error( "gethostbyname failed in socket_init" );
+ goto out;
+ }
- // create socket on which to send.
+ // Create socket on which to send.
pmctl->st.sockio.sockfd = socket( PF_INET, SOCK_STREAM, 0 );
- if ( pmctl->st.sockio.sockfd == INVALID_SOCKET )
- return TR_OPEN_ERR;
+ if ( pmctl->st.sockio.sockfd == MBG_INVALID_SOCK_FD )
+ {
+ rc = mbg_get_last_socket_error( "failed to create socket in socket_init" );
+ goto out;
+ }
+
+ // Set the socket to nonblocking mode to be able to
+ // reduce the timeout when connecting to a socket
+ // which is offline.
+ rc = set_socket_blocking_mode( pmctl->st.sockio.sockfd, 0 );
+
+ if ( rc != MBG_SUCCESS )
+ goto out_close;
+
+ // Now try to connect to the socket.
paddr = &pmctl->st.sockio.addr;
memset( paddr, 0, sizeof( *paddr ) );
@@ -186,65 +714,174 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host )
p = (const struct sockaddr *) paddr;
sz = sizeof( *paddr );
- rc = connect( pmctl->st.sockio.sockfd, p, sz );
+ rc = connect( pmctl->st.sockio.sockfd, p, sz ); // returns 0 on success on Windows and Linux
- if ( rc < 0 )
- return TR_OPEN_ERR;
+ // In nonblocking mode connect() might complete successfully
+ // if the destination socket is on the same machine (localhost)
+ // However, for remote connections the call usually returns
+ // immediately with WSAEWOULDBLOCK on Windows, or EINPROGRESS or
+ // EALREADY on POSIX systems. In the latter cases we need to wait
+ // and see if the connection can be established successfully.
+
+ if ( rc != 0 ) // eventually not (yet) completed in non-blocking mode
+ {
+ #if defined( MBG_TGT_WIN32 )
+ DWORD wsa_err = WSAGetLastError();
- return 0;
+ // WSAEWOULDBLOCK is actually not an error in non-blocking mode
+ if ( wsa_err != WSAEWOULDBLOCK )
+ {
+ rc = mbg_win32_wsa_err_to_mbg( wsa_err, "connect failed in socket_init" );
+ goto out_close;
+ }
+ #else // POSIX ...
+ int posix_errno = errno;
+
+ // EINPROGRESS and EALREADY are actually not errors in non-blocking mode
+ if ( ( posix_errno != EINPROGRESS ) && ( posix_errno != EALREADY ) )
+ {
+ rc = mbg_posix_errno_to_mbg( posix_errno, "connect failed in socket_init" );
+ goto out_close;
+ }
+ #endif
+
+ rc = wait_nonblocking_socket_ready( pmctl->st.sockio.sockfd, 1500 ); //##++++++++++++
+
+ if ( rc != MBG_SUCCESS )
+ goto out_close;
+ }
+
+ // Set the socket back to blocking mode.
+ rc = set_socket_blocking_mode( pmctl->st.sockio.sockfd, 1 );
+
+ if ( rc == MBG_SUCCESS )
+ goto out;
+
+ // error, fall through and close socket
+
+out_close:
+ socket_close( pmctl );
+
+out:
+ return rc;
} // socket_init
-static /*HDR*/
-int comm_init( MBG_MSG_CTL *pmctl, const char *passwd )
+/*HDR*/
+/**
+ * @brief Send security settings for the socket connection
+ *
+ * If new_passwd is not a NULL pointer, the old_passwd
+ * will be overwritten by the new_passwd.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] old_passwd Pointer to the current LAN port password of the device
+ * @param[in] new_passwd Pointer to the new LAN port password for the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_secu_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ const char *old_passwd, const char *new_passwd )
{
- SECU_SETTINGS *pss = &pmctl->secu_settings;
MBG_MSG_BUFF *pmb;
- int rc;
+ SECU_SETTINGS *pss = &pmctl->secu_settings;
+ GPS_CMD cmd = GPS_SECU_SETTINGS; // GPS_REQACK is not supported by LAN_XPT, so omit it
+ int rc = MBG_ERR_UNSPEC;
memset( pss, 0, sizeof *pss );
- strncpy( pss->password, passwd, sizeof( pss->password ) );
+ strncpy( pss->password, old_passwd, sizeof( pss->password ) );
- pmctl->conn_type = MBG_CONN_TYPE_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_ENCRYPTED, pss->password );
- set_encryption_mode( pmctl, MBG_XFER_MODE_ENCRYTED, pss->password );
+ if ( new_passwd )
+ {
+ if ( strlen( new_passwd ) > 0 )
+ strncpy( pss->new_password, new_passwd, sizeof( pss->new_password ) );
+
+ pss->flags |= MSK_FLAG_CHANGE_PASSWORD;
+ }
pmb = pmctl->xmt.pmb;
pmb->u.msg_data.secu_settings = *pss;
- pmb->hdr.cmd = GPS_SECU_SETTINGS;
+ pmb->hdr.cmd = cmd;
pmb->hdr.len = sizeof( pmb->u.msg_data.secu_settings );
- xmt_tbuff( pmctl );
- rc = mbgextio_rcv_msg( pmctl, GPS_SECU_SETTINGS );
+ rc = xmt_tbuff( pmctl, NULL ); //##++++++++++++++ TODO Use mbgextio_req_data instead? Is NULL OK?
- if ( rc != TR_COMPLETE )
- return -1; /* connection refused */
+ if ( rc != MBG_SUCCESS ) // error
+ goto out;
- pmb = pmctl->rcv.pmb;
+ rc = mbgextio_rcv_msg( pmctl, NULL, cmd ); //##++++++++++++++ TODO Is NULL OK?
- if ( !( pmb->hdr.cmd & GPS_ACK ) )
- return -2; /* authentication failed */
+ // With some devices a timeout may also occur
+ // if a wrong password has been used.
+ if ( rc != MBG_SUCCESS ) // error
+ goto out;
- return 0;
+ cmd = pmctl->rcv.pmb->hdr.cmd;
-} // comm_init
+ // If we either received a reply with GPS_NACK, or
+ // without GPS_ACK, the password was definitely wrong.
+ if ( ( cmd & GPS_NACK ) || !( cmd & GPS_ACK ) )
+ {
+ rc = MBG_ERR_AUTH;
+ goto out;
+ }
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // mbgextio_xmt_secu_settings
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
- const char *host, const char *passwd )
+/**
+ * @brief Open a binary communication channel via a LAN/socket connection
+ *
+ * @param[in] host DNS name or IP address of the target device
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call.
+ * Pointer is set to NULL on error.
+ * @param[in] passwd Password string for the encrypted communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_open_socket( const char *host, MBG_MSG_CTL **ppmctl, const char *passwd )
{
- int rc = socket_init( pmctl, host );
+ MBG_MSG_CTL *pmctl;
+ int rc = alloc_msg_ctl( &pmctl );
- if ( rc < 0 )
- return rc;
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+
+ pmctl->conn_type = MBG_CONN_TYPE_SOCKET;
+ pmctl->msg_rcv_timeout = MBGEXTIO_RCV_TIMEOUT_SOCKET;
+ // pmctl->char_rcv_timeout is not used with sockets
- comm_init( pmctl, passwd );
+ rc = socket_init( pmctl, host );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail_free;
+
+ rc = mbgextio_xmt_secu_settings( pmctl, NULL, passwd, NULL );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail_close;
#if defined( MBG_TGT_WIN32 )
mbgextio_set_console_control_handler();
@@ -254,6 +891,18 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
_mbg_mutex_init( &pmctl->xmt.xmt_mutex );
#endif
+ rc = MBG_SUCCESS;
+ goto out;
+
+fail_close:
+ socket_close( pmctl );
+
+fail_free:
+ dealloc_msg_ctl( &pmctl );
+
+out:
+ *ppmctl = pmctl;
+
return rc;
} // mbgextio_open_socket
@@ -265,10 +914,39 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_socket( MBG_MSG_CTL *pmctl,
#if _USE_SERIAL_IO
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char *dev,
- uint32_t baud_rate, const char *framing )
+/**
+ * @brief Open a binary communication channel using direct serial I/O
+ *
+ * Commonly used serial parameters are 19200/8N1, see
+ * ::MBG_DEFAULT_BAUDRATE and ::MBG_DEFAULT_FRAMING.
+ * Some newer devices may also support ::MBG_DEFAULT_BAUDRATE_HS.
+ *
+ * @param[in] dev Name of the serial port to which the device is connected,
+ * depending on the naming conventions of the host system.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ * @param[in] baud_rate Baud rate used for serial communication
+ * @param[in] framing Framing used for serial communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_force_conn_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_force_conn_serial_ftdi
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial( const char *dev, MBG_MSG_CTL **ppmctl,
+ uint32_t baud_rate, const char *framing )
{
- int rc;
+ MBG_MSG_CTL *pmctl;
+ int rc = alloc_msg_ctl( &pmctl );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
pmctl->conn_type = MBG_CONN_TYPE_SERIAL;
pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL;
@@ -276,16 +954,28 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char
rc = mbgserio_open( &pmctl->st.serio, dev );
- if ( rc < 0 ) //##++
- return rc;
+ if ( rc != MBG_SUCCESS )
+ goto fail_free;
- mbgserio_set_parms( &pmctl->st.serio, baud_rate, framing );
+ rc = mbgserio_set_parms( &pmctl->st.serio, baud_rate, framing );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail_free;
#if _USE_MUTEX
_mbg_mutex_init( &pmctl->xmt.xmt_mutex );
#endif
- return 0;
+ rc = MBG_SUCCESS;
+ goto out;
+
+fail_free:
+ dealloc_msg_ctl( &pmctl );
+
+out:
+ *ppmctl = pmctl;
+
+ return rc;
} // mbgextio_open_serial
@@ -293,56 +983,490 @@ _MBG_API_ATTR int _MBG_API mbgextio_open_serial( MBG_MSG_CTL *pmctl, const char
+#if _USE_SERIAL_IO_FTDI
+
/*HDR*/
-_MBG_API_ATTR void _MBG_API mbgextio_close_connection( MBG_MSG_CTL *pmctl )
+/**
+ * @brief Get the port handle of a serial FTDI device
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return the port handle retrieved from the message control structure
+ */
+_NO_MBG_API_ATTR FT_HANDLE _MBG_API mbgextio_get_serial_ftdi_port_handle( MBG_MSG_CTL *pmctl )
{
+ return pmctl->st.ftdiio.port_handle;
+
+} // mbgextio_get_serial_ftdi_port_handle
+
+
+
+/*HDR*/
+/**
+ * @brief Open a binary communication channel using serial FTDI D2xx port
+ *
+ * Commonly used serial parameters are 19200/8N1, see
+ * ::MBG_DEFAULT_BAUDRATE and ::MBG_DEFAULT_FRAMING.
+ * Some newer devices may also support ::MBG_DEFAULT_BAUDRATE_HS.
+ *
+ * @param[in] device_num device number from a list set up by FT_ListDevices()
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ * @param[in] baud_rate Baud rate used for serial communication
+ * @param[in] framing Framing used for serial communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_force_conn_serial_ftdi
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_force_conn_serial
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num,
+ MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing )
+{
+ FT_STATUS status;
+ ULONG ft_baud;
+ UCHAR ft_data_bits;
+ UCHAR ft_stopbits;
+ UCHAR ft_parity;
+ const char *cp;
+ MBG_MSG_CTL *pmctl;
+ int rc = alloc_msg_ctl( &pmctl );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+
+ pmctl->conn_type = MBG_CONN_TYPE_SERIAL_FTDI;
+ pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL;
+ pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL;
+
+ status = FT_Open( device_num, &pmctl->st.ftdiio.port_handle );
+
+ if ( status != FT_OK )
+ goto ft_fail_free;
+
+
+ // setup transmission speed
+ switch( baud_rate )
+ {
+ case 300: ft_baud = FT_BAUD_300; break;
+ case 600: ft_baud = FT_BAUD_600; break;
+ case 1200: ft_baud = FT_BAUD_1200; break;
+ case 2400: ft_baud = FT_BAUD_2400; break;
+ case 4800: ft_baud = FT_BAUD_4800; break;
+ case 9600: ft_baud = FT_BAUD_9600; break;
+ case 14400: ft_baud = FT_BAUD_14400; break;
+ case 19200: ft_baud = FT_BAUD_19200; break;
+ case 38400: ft_baud = FT_BAUD_38400; break;
+ case 57600: ft_baud = FT_BAUD_57600; break;
+ case 115200: ft_baud = FT_BAUD_115200; break;
+ case 230400: ft_baud = FT_BAUD_230400; break;
+ case 460800: ft_baud = FT_BAUD_460800; break;
+ case 921600: ft_baud = FT_BAUD_921600; break;
+
+ default:
+ rc = MBG_ERR_INV_PARM;
+ goto fail_free;
+ }
+
+
+ // setup framing
+ for ( cp = framing; *cp; cp++ )
+ {
+ char c = toupper( *cp );
+
+ switch ( c )
+ {
+ case '7': ft_data_bits = FT_BITS_7; break;
+ case '8': ft_data_bits = FT_BITS_8; break;
+
+ case 'N': ft_parity = FT_PARITY_NONE; break;
+ case 'E': ft_parity = FT_PARITY_EVEN; break;
+ case 'O': ft_parity = FT_PARITY_ODD; break;
+ // FT_PARITY_MARK and FT_PARITY_SPACE not supp. by Meinberg API
+
+ case '1': ft_stopbits = FT_STOP_BITS_1; break;
+ case '2': ft_stopbits = FT_STOP_BITS_2; break;
+
+ default:
+ rc = MBG_ERR_INV_PARM;
+ goto fail_free;
+ }
+ }
+
+
+ status = FT_SetBaudRate( pmctl->st.ftdiio.port_handle, ft_baud );
+
+ if ( status != FT_OK )
+ goto ft_fail_free;
+
+ status = FT_SetDataCharacteristics( pmctl->st.ftdiio.port_handle,
+ ft_data_bits, ft_stopbits, ft_parity );
+
+ if ( status != FT_OK )
+ goto ft_fail_free;
+
+
+ #if _USE_MUTEX
+ _mbg_mutex_init( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ rc = MBG_SUCCESS;
+ goto out;
+
+
+ft_fail_free:
+ rc = mbg_ftdi_ft_status_to_mbg( status );
+
+fail_free:
+ dealloc_msg_ctl( &pmctl );
+
+out:
+ *ppmctl = pmctl;
+
+ return rc;
+
+} // mbgextio_open_serial_ftdi
+
+#endif
+
+
+
+#if _USE_USB_IO
+
+/*HDR*/
+/**
+ * @brief Open a binary communication channel using direct USB I/O
+ *
+ * @param[in] usbdev The USB device to communicate with.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_close_connection
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEVICE *usbdev, MBG_MSG_CTL **ppmctl )
+{
+ MBG_MSG_CTL *pmctl;
+ int rc = alloc_msg_ctl( &pmctl );
+
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+
+ pmctl->conn_type = MBG_CONN_TYPE_USB;
+ pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL;
+ pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL;
+
+ pmctl->st.usbio = usbdev->iost;
+
+ rc = mbgusbio_open( &pmctl->st.usbio );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail_free;
+
+ #if _USE_MUTEX
+ _mbg_mutex_init( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ rc = MBG_SUCCESS;
+ goto out;
+
+
+fail_free:
+ dealloc_msg_ctl( &pmctl );
+
+out:
+ *ppmctl = pmctl;
+
+ return rc;
+
+} // mbgextio_open_usb
+
+#endif
+
+
+
+#if _USE_USB_DIRECT_IO
+
+/*HDR*/
+/**
+ * @brief Open a binary communication channel using direct USB I/O
+ *
+ * Currently it is only supported by Linux systems since a file like
+ * USB device (e.g. "/dev/mbgims") is required and needs to support
+ * basic I/O operations like write, read, etc...
+ *
+ * @param[in] dev Path to file like USB device
+ * @param[in] flags Bitwise OR flags of access modes like W,RW,RO,etc.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb_direct_io( const char *dev, int flags, MBG_MSG_CTL **ppmctl )
+{
+ MBG_MSG_CTL *pmctl;
+ int rc;
+
+ if ( dev == NULL )
+ return MBG_ERR_NO_DEV;
+
+ rc = alloc_msg_ctl( &pmctl );
+ if ( rc != MBG_SUCCESS )
+ goto out;
+
+ pmctl->conn_type = MBG_CONN_TYPE_USB_DIRECT_IO;
+ pmctl->msg_rcv_timeout = MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO;
+
+ pmctl->st.usbdio.usbdiofd = open(dev, flags);
+
+ if ( pmctl->st.usbdio.usbdiofd == MBG_USB_DIRECT_IO_INVALID_FD )
+ {
+ rc = mbg_get_last_error( "failed to open direct USB I/O device" );
+ goto fail_free;
+ }
+
+ rc = MBG_SUCCESS;
+ goto out;
+
+fail_free:
+ dealloc_msg_ctl( &pmctl );
+
+out:
+ *ppmctl = pmctl;
+
+ return rc;
+
+} // mbgextio_open_usb_direct_io
+
+#endif
+
+
+
+/*HDR*/
+/**
+ * @brief Close a binary communication channel and release resources
+ *
+ * Closes a binary communication channel which has been opened by one
+ * of the mbgextio_open_...() functions and releases the buffers which
+ * have been allocated when the channel was opened.
+ *
+ * The pointer to the message control structure passed by address is set
+ * to NULL after the channel has been closed and the resources have
+ * been released.
+ *
+ * @param[in,out] ppmctl Address of a pointer to a message control structure
+ * created when the communication channel was opened
+ * by one of the mbgextio_open_...() calls.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_close_connection( MBG_MSG_CTL **ppmctl )
+{
+ MBG_MSG_CTL *pmctl = *ppmctl;
+ int rc = MBG_ERR_UNSPEC;
+
switch ( pmctl->conn_type )
{
#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
+ rc = mbgserio_close( &pmctl->st.serio );
+ break;
+ #endif // _USE_SERIAL_IO
- mbgserio_close( &pmctl->st.serio );
+ #if _USE_SERIAL_IO_FTDI
+ case MBG_CONN_TYPE_SERIAL_FTDI:
+ {
+ FT_STATUS status = FT_Close( pmctl->st.ftdiio.port_handle );
+ pmctl->st.ftdiio.port_handle = MBG_INVALID_PORT_HANDLE;
+ rc = mbg_ftdi_ft_status_to_mbg( status );
} break;
- #endif // _USE_SERIAL_IO
+ #endif // _USE_SERIAL_IO_FTDI
#if _USE_SOCKET_IO
case MBG_CONN_TYPE_SOCKET:
- {
- _mbg_close( pmctl->st.sockio.sockfd );
- pmctl->st.sockio.sockfd = 0;
- } break;
+ rc = socket_close( pmctl );
+ break;
#endif // _USE_SOCKET_IO
- }; // switch
+ #if _USE_USB_IO
+ case MBG_CONN_TYPE_USB:
+ rc = mbgusbio_close( &pmctl->st.usbio );
+ break;
+ #endif // _USE_USB_IO
+
+ #if _USE_USB_DIRECT_IO
+ case MBG_CONN_TYPE_USB_DIRECT_IO:
+ if ( pmctl->st.usbdio.usbdiofd == MBG_USB_DIRECT_IO_INVALID_FD )
+ {
+ rc = MBG_SUCCESS;
+ break;
+ }
+
+ rc = close( pmctl->st.usbdio.usbdiofd );
+
+ if ( rc < 0 )
+ rc = mbg_get_last_error( "failed to close direct USB I/O device" );
+ else
+ rc = MBG_SUCCESS;
+ #endif // _USE_USB_DIRECT_IO
+
+ default:
+ rc = MBG_ERR_CONN_TYPE;
+
+ } // switch
#if _USE_MUTEX
_mbg_mutex_destroy( &pmctl->xmt.xmt_mutex );
#endif
+ dealloc_msg_ctl( ppmctl );
+
+ return rc;
+
} // mbgextio_close_connection
#if _USE_SERIAL_IO
-/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_force_connection( const char *dev )
+static /*HDR*/
+int do_force_conn_serial( const char *dev, const char *cmd_str, BAUD_RATE expected_baudrate )
{
- static const char *cmd_str = "\nDFC\n"; //##++
+ int i;
+ int j;
+ MBG_MSG_CTL *pmctl;
+ int len = (int) strlen( cmd_str );
+ int rc = MBG_ERR_UNSPEC;
- MBG_MSG_CTL mctl =
+ for ( i = 0; i < N_MBG_BAUD_RATES; i++ )
{
- { NULL, 0 },
- { NULL, 0 }
- };
+ for ( j = 0; j < N_MBG_FRAMINGS; j++ )
+ {
+ uint32_t baud_rate = mbg_baud_rates[i];
+ const char *framing = mbg_framing_strs[j];
+
+ rc = mbgextio_open_serial( dev, &pmctl, baud_rate, framing );
+
+ if ( rc != MBG_SUCCESS ) // failed to open port
+ goto out;
+
+ mbgserio_write( pmctl->st.serio.port_handle, cmd_str, len );
+ // should we check rc here or just continue?
+
+ #ifdef MBG_TGT_WIN32
+ // Flushing the output when the serial port is closed doesn't
+ // always work correctly under Windows, so we insert a delay
+ // here to make sure the string has been set.
+ // The required delay depends on the number of characters to
+ // send, and on the transmission speed (baud rate).
+ Sleep( ( ( 10 * 1000 * len ) / baud_rate ) + 1 );
+ #endif
+
+ mbgextio_close_connection( &pmctl );
+ }
+ }
+
+ rc = mbgextio_open_serial( dev, &pmctl, expected_baudrate, MBG_DEFAULT_FRAMING );
+
+ if ( rc != MBG_SUCCESS ) // failed to open port
+ goto out;
+
+ rc = mbgextio_get_receiver_info( pmctl, NULL, NULL );
+
+ mbgextio_close_connection( &pmctl);
+
+out:
+ return rc;
+
+} // do_force_conn_serial
+
+
+
+/*HDR*/
+/**
+ * @brief Try to force a serial connection to a device
+ *
+ * A device's serial port may have been configured to work by default
+ * in a way which is not appropriate for binary communication, e.g. using
+ * a low communication speed, or some framing like "7E2" which messes up
+ * binary data since the parity bit overrides a data bit.
+ *
+ * This function sends a special ASCII string to a device which lets the device
+ * temporarily switch to a specific baud rate and 8N1 framing which is usually
+ * used for binary communication, see ::MBG_DEFAULT_BAUDRATE,
+ * ::MBG_DEFAULT_BAUDRATE_HS, and ::MBG_DEFAULT_FRAMING.
+ *
+ * Since the current settings of the device's serial port are unknown this
+ * this command is sent in all common combinations of baud rates and
+ * framings.
+ *
+ * If the connected device supports this it should be possible to open
+ * the serial communication channel using the default parameters after
+ * this function has finished.
+ *
+ * @param[in] dev Name of the serial port to which the device is connected,
+ * depending on the naming conventions of the target system
+ *
+ * @return One of the negative @ref MBG_ERROR_CODES on error,
+ * else the determined baud rate.
+ *
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ */
+_NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial( const char *dev )
+{
+ long rc = do_force_conn_serial( dev, force_conn_hs_cmd_str, MBG_DEFAULT_BAUDRATE_HS );
+
+ if ( rc == MBG_SUCCESS )
+ return MBG_DEFAULT_BAUDRATE_HS;
+ rc = do_force_conn_serial( dev, force_conn_cmd_str, MBG_DEFAULT_BAUDRATE );
+
+ if ( rc == MBG_SUCCESS )
+ return MBG_DEFAULT_BAUDRATE;
+
+ return rc;
+
+} // mbgextio_force_conn_serial
+
+#endif // _USE_SERIAL_IO
+
+
+
+#if _USE_SERIAL_IO_FTDI
+
+static /*HDR*/
+int do_force_conn_serial_ftdi( int device_num, const char *cmd_str, BAUD_RATE expected_baudrate )
+{
int i;
int j;
- int len = strlen( cmd_str );
+ MBG_MSG_CTL *pmctl;
+ int len = (int) strlen( force_conn_cmd_str );
+ long rc = MBG_ERR_UNSPEC;
for ( i = 0; i < N_MBG_BAUD_RATES; i++ )
{
@@ -350,126 +1474,315 @@ _MBG_API_ATTR int _MBG_API mbgextio_force_connection( const char *dev )
{
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 );
+ DWORD bytes_written;
+ FT_HANDLE port_handle;
+ FT_STATUS status;
+
+ rc = mbgextio_open_serial_ftdi( device_num, &pmctl, baud_rate, framing );
+
+ if ( rc != MBG_SUCCESS ) // failed to open port
+ goto out;
+
+ port_handle = pmctl->st.ftdiio.port_handle;
- if ( rc != 0 ) // failed to open port
- return -1;
+ status = FT_Write( port_handle, (LPVOID) force_conn_cmd_str, len, &bytes_written );
- _mbgserio_write( mctl.st.serio.port_handle, cmd_str, len );
+ #if 0 //##+++++++++++ do we need some error checking here?
+ if ( status != FT_OK )
+ {
+ rc = mbg_ftdi_ft_status_to_mbg( status );
+ goto out;
+ }
- #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 );
+ if ( bytes_written != sizeof( len ) )
+ goto out_write_failed;
+ #endif
+
+ #ifdef MBG_TGT_WIN32
+ #if 1
+ // TODO Check if this works as expected
+ status = FT_Purge( port_handle, FT_PURGE_TX );
+ #else
+
+ // Flushing the output when the serial port is closed doesn't
+ // always work correctly under Windows, so we insert a delay
+ // here to make sure the string has been set.
+ // The required delay depends on the number of characters to
+ // send, and on the transmission speed (baud rate).
+ Sleep( ( ( 10 * 1000 * len ) / baud_rate ) + 1 );
+ #endif
#endif
- mbgextio_close_connection( &mctl );
+ mbgextio_close_connection( &pmctl );
}
}
- return 0;
+ rc = mbgextio_open_serial_ftdi( device_num, &pmctl, expected_baudrate, MBG_DEFAULT_FRAMING );
-} // mbgextio_force_connection
+ if ( rc != MBG_SUCCESS ) // failed to open port
+ goto out;
-#endif // _USE_SERIAL_IO
+ rc = mbgextio_get_receiver_info( pmctl, NULL, NULL );
+
+ mbgextio_close_connection( &pmctl );
+
+out:
+ return rc;
+
+} // do_force_conn_serial_ftdi
/*HDR*/
-_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+/**
+ * @brief Try to force a serial connection to a device via the FTDI API
+ *
+ * A device's serial port may have been configured to work by default
+ * in a way which is not appropriate for binary communication, e.g. using
+ * a low communication speed, or some framing like "7E2" which messes up
+ * binary data since the parity bit overrides a data bit.
+ *
+ * This function sends a special ASCII string to a device which lets the device
+ * temporarily switch to a specific baud rate and 8N1 framing which is usually
+ * used for binary communication, see ::MBG_DEFAULT_BAUDRATE,
+ * ::MBG_DEFAULT_BAUDRATE_HS, and ::MBG_DEFAULT_FRAMING.
+ *
+ * Since the current settings of the device's serial port are unknown this
+ * this command is sent in all common combinations of baud rates and
+ * framings.
+ *
+ * If the connected device supports this it should be possible to open
+ * the serial communication channel using the default parameters after
+ * this function has finished.
+ *
+ * @param[in] device_num device number from a list set up by FT_ListDevices()
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_serial_ftdi
+ */
+_NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial_ftdi( int device_num )
{
- pmctl->char_rcv_timeout = new_timeout;
+ long rc = do_force_conn_serial_ftdi( device_num, force_conn_hs_cmd_str, MBG_DEFAULT_BAUDRATE_HS );
-} // mbgextio_set_char_rcv_timeout
+ if ( rc == MBG_SUCCESS )
+ return MBG_DEFAULT_BAUDRATE_HS;
+
+ rc = do_force_conn_serial_ftdi( device_num, force_conn_cmd_str, MBG_DEFAULT_BAUDRATE );
+
+ if ( rc == MBG_SUCCESS )
+ return MBG_DEFAULT_BAUDRATE;
+
+ return rc;
+
+} // mbgextio_force_conn_serial_ftdi
+
+#endif // _USE_SERIAL_IO_FTDI
/*HDR*/
-_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl )
+/**
+ * @brief Retrieve address of the allocated receive buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Address of the allocated receive buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+_NO_MBG_API_ATTR MBG_MSG_BUFF * _MBG_API mbgextio_get_rcv_buffer_addr( MBG_MSG_CTL *pmctl )
{
- return pmctl->char_rcv_timeout;
+ if ( pmctl == NULL )
+ return NULL;
-} // mbgextio_get_char_rcv_timeout
+ return pmctl->rcv.pmb;
+
+} // mbgextio_get_rcv_buffer_addr
/*HDR*/
-_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+/**
+ * @brief Retrieve size of the allocated receive buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Size of the allocated receive buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+_NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_rcv_buffer_size( MBG_MSG_CTL *pmctl )
{
- pmctl->msg_rcv_timeout = new_timeout;
+ if ( pmctl == NULL )
+ return 0;
-} // mbgextio_set_msg_rcv_timeout
+ return sizeof( *pmctl->rcv.pmb );
+
+} // mbgextio_get_rcv_buffer_size
/*HDR*/
-_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl )
+/**
+ * @brief Retrieve address of the allocated transmit buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Address of the allocated transmit buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+_NO_MBG_API_ATTR MBG_MSG_BUFF * _MBG_API mbgextio_get_xmt_buffer_addr( MBG_MSG_CTL *pmctl )
{
- return pmctl->msg_rcv_timeout;
+ if ( pmctl == NULL )
+ return NULL;
-} // mbgextio_get_msg_rcv_timeout
+ return pmctl->xmt.pmb;
+
+} // mbgextio_get_xmt_buffer_addr
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
- const void *p, int n_bytes )
+/**
+ * @brief Retrieve size of the allocated transmit buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Size of the allocated transmit buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_addr
+ */
+_NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_xmt_buffer_size( MBG_MSG_CTL *pmctl )
{
- MBG_MSG_BUFF *pmb;
+ if ( pmctl == NULL )
+ return 0;
- if ( n_bytes > sizeof( pmb->u.msg_data ) )
- return -1; // bytes to send exceed buffer size
+ return sizeof( *pmctl->xmt.pmb );
+} // mbgextio_get_xmt_buffer_size
- #if _USE_MUTEX
- _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
- #endif
- pmb = pmctl->xmt.pmb;
- if ( p && n_bytes )
- memcpy( pmb->u.bytes, p, n_bytes );
+/*HDR*/
+/**
+ * @brief Set character receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] new_timeout New timeout value [ms]
+ *
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+_NO_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+{
+ pmctl->char_rcv_timeout = new_timeout;
- pmb->hdr.len = n_bytes;
- pmb->hdr.cmd = cmd;
- xmt_tbuff( pmctl );
+} // mbgextio_set_char_rcv_timeout
- #if _USE_MUTEX
- _mbg_mutex_release( &pmctl->xmt.xmt_mutex );
- #endif
- if ( cmd & GPS_REQACK )
- {
- int rc = mbgextio_rcv_msg( pmctl, (GPS_CMD) ( cmd & ~GPS_CTRL_MSK ) );
- if ( rc != TR_COMPLETE )
- return -2;
+/*HDR*/
+/**
+ * @brief Get character receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Current timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+_NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl )
+{
+ return pmctl->char_rcv_timeout;
- if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK )
- return -3;
+} // mbgextio_get_char_rcv_timeout
- if ( !(pmctl->rcv.pmb->hdr.cmd & GPS_ACK) )
- return -4;
- }
- return 0;
+/*HDR*/
+/**
+ * @brief Set message receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] new_timeout New timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+_NO_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout )
+{
+ pmctl->msg_rcv_timeout = new_timeout;
-} // mbgextio_xmt_msg
+} // mbgextio_set_msg_rcv_timeout
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
+/**
+ * @brief Get message receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Current timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ */
+_NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl )
+{
+ return pmctl->msg_rcv_timeout;
+
+} // mbgextio_get_msg_rcv_timeout
+
+
+
+/*HDR*/
+/**
+ * @brief Generic reception of a binary message
+ *
+ * @note A certain message type to be waited for can be specified by
+ * passing one of the ::GPS_CMD_CODES.
+ * If the special cmd code ::GPS_WILDCARD is specified the function returns
+ * successfully after *any* type of binary message has been received.
+ *
+ * //##++ TODO: callback function to handle asynchronous spontaneous messages
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_msg //##++++
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd )
{
MBG_MSG_RCV_CTL *prctl;
MBG_MSG_BUFF *pmb;
MBG_TMO_TIME msg_timeout;
char buff[MBGEXTIO_READ_BUFFER_SIZE];
- ssize_t n_bytes;
- int rc;
+ ssize_t n_bytes = 0;
+ int rc = MBG_ERR_UNSPEC;
int i;
mbg_tmo_set_timeout_ms( &msg_timeout, pmctl->msg_rcv_timeout );
@@ -479,61 +1792,164 @@ _MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
n_bytes = 0;
if ( mbg_tmo_curr_time_is_after( &msg_timeout ) )
- return TR_TIMEOUT;
+ {
+ rc = MBG_ERR_TIMEOUT;
+ goto out;
+ }
- #if _USE_SOCKET_IO
- if ( pmctl->conn_type == MBG_CONN_TYPE_SOCKET )
- {
- struct timeval tv_timeout;
- fd_set fds;
+ switch ( pmctl->conn_type )
+ {
+ #if _USE_SOCKET_IO
+ case MBG_CONN_TYPE_SOCKET:
+ {
+ struct timeval tv_timeout;
+ fd_set fds;
+ int max_fd;
+
+ mbg_msec_to_timeval( pmctl->msg_rcv_timeout, &tv_timeout );
+
+ FD_ZERO( &fds );
+ FD_SET( pmctl->st.sockio.sockfd, &fds );
+
+ #if defined( MBG_TGT_WIN32 )
+ // Under Windows an fd is a handle which can't simply
+ // be converted to an int, but the first argument of
+ // select() is ignored under Windows anyway, so we just
+ // set max_fd to 0.
+ max_fd = 0;
+ #else
+ max_fd = pmctl->st.sockio.sockfd;
+ #endif
+
+ rc = select( max_fd + 1, &fds, NULL, NULL, &tv_timeout );
- if ( pmctl->io_error )
- return TR_IO_ERR;
+ if ( rc == MBG_SOCKET_ERR_RETVAL ) // < 0, error
+ {
+ rc = mbg_get_last_socket_error( "select failed in mbgextio_rcv_msg" );
+ goto out;
+ }
+
+ if ( rc == 0 ) // timeout
+ {
+ rc = MBG_ERR_TIMEOUT;
+ goto out;
+ }
- mbgserio_msec_to_timeval( pmctl->msg_rcv_timeout, &tv_timeout );
+ // data is available
- FD_ZERO( &fds );
- FD_SET( pmctl->st.sockio.sockfd, &fds );
+ n_bytes = recv( pmctl->st.sockio.sockfd, buff, sizeof( buff ), 0 );
- rc = select( pmctl->st.sockio.sockfd + 1, &fds, NULL, NULL, &tv_timeout );
+ if ( n_bytes < 0 )
+ {
+ rc = mbg_get_last_socket_error( "recv failed in mbgextio_rcv_msg" );
+ goto out;
+ }
- if ( rc == 0 ) // timeout
- return TR_TIMEOUT;
+ } break;
+ #endif // _USE_SOCKET_IO
- if ( rc < 0 ) // error
+ #if _USE_SERIAL_IO
+ case MBG_CONN_TYPE_SERIAL:
{
- pmctl->io_error = 1;
- return TR_IO_ERR;
- }
+ n_bytes = mbgserio_read_wait( pmctl->st.serio.port_handle, &buff[0],
+ sizeof( buff[0] ), pmctl->char_rcv_timeout );
- // data is available
+ if ( n_bytes < 0 )
+ {
+ rc = n_bytes;
+ goto out;
+ }
- n_bytes = recv( pmctl->st.sockio.sockfd, buff, sizeof( buff ), 0 );
+ } break;
+ #endif // _USE_SERIAL_IO
- if ( n_bytes < 0 )
+ #if _USE_SERIAL_IO_FTDI
+ case MBG_CONN_TYPE_SERIAL_FTDI:
{
- pmctl->io_error = 1;
- return TR_IO_ERR;
- }
- }
- #endif // _USE_SOCKET_IO
+ DWORD bytes_read;
+ FT_STATUS status;
- #if _USE_SERIAL_IO
- if ( pmctl->conn_type == MBG_CONN_TYPE_SERIAL )
- {
- n_bytes = mbgserio_read_wait( pmctl->st.serio.port_handle, &buff[0],
- sizeof( buff[0] ), pmctl->char_rcv_timeout );
+ //##++++++ pmctl->char_rcv_timeout,
+ status = FT_Read( pmctl->st.ftdiio.port_handle, &buff[0],
+ sizeof( buff[0] ), &bytes_read );
- if ( n_bytes < 0 )
+ if ( status != FT_OK )
+ {
+ rc = mbg_ftdi_ft_status_to_mbg( status );
+ goto out;
+ }
+
+ n_bytes = bytes_read;
+
+ } break;
+ #endif // _USE_SERIAL_IO_FTDI
+
+ #if _USE_USB_IO
+ case MBG_CONN_TYPE_USB:
{
- if ( n_bytes == MBGSERIO_TIMEOUT )
- return TR_TIMEOUT;
+ rc = mbgusbio_read( &pmctl->st.usbio, (uint8_t *) buff, sizeof( buff ), 1000 );
- pmctl->io_error = 1;
- return TR_IO_ERR;
- }
- }
- #endif // _USE_SERIAL_IO
+ if ( rc < 0 )
+ goto out;
+
+ // data is available
+
+ n_bytes = rc;
+
+ } break;
+ #endif // _USE_USB_IO
+
+ #if _USE_USB_DIRECT_IO
+ case MBG_CONN_TYPE_USB_DIRECT_IO:
+ {
+ struct pollfd pfd;
+
+ pfd.fd = pmctl->st.usbdio.usbdiofd;
+ pfd.events = POLLIN | POLLRDNORM | POLLRDBAND;
+ pfd.revents = 0;
+
+ rc = poll( &pfd, 1, pmctl->msg_rcv_timeout);
+
+ if ( rc == 0 ) // timeout
+ {
+ rc = MBG_ERR_TIMEOUT;
+ goto out;
+ }
+
+ if ( rc < 0 ) // error
+ {
+ rc = mbg_get_last_error( "failed to poll direct USB I/O" );
+ goto out;
+ }
+
+ // Other stuff?
+ if ( pfd.revents & ( POLLERR | POLLHUP | POLLNVAL ) )
+ {
+ rc = MBG_ERR_UNSPEC;
+ goto out;
+ }
+
+ // Read data?
+ if ( pfd.revents & ( POLLIN | POLLRDNORM | POLLRDBAND ) )
+ {
+ rc = read( pmctl->st.usbdio.usbdiofd, (void*)buff, sizeof(buff) );
+
+ if ( rc < 0 )
+ {
+ rc = mbg_get_last_error( "failed to read direct USB I/O" );
+ goto out;
+ }
+
+ n_bytes = rc;
+ }
+ } break;
+ #endif
+
+ default:
+ rc = MBG_ERR_CONN_TYPE;
+ goto out;
+
+ } // switch
prctl = &pmctl->rcv;
pmb = prctl->pmb;
@@ -550,7 +1966,16 @@ _MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
case TR_WAITING: /* no data transfer sequence in progress */
#if _USE_CHK_TSTR
if ( prctl->chk_tstr_fnc ) /* optionally handle normal, non-protocol data */
- prctl->chk_tstr_fnc( c, prctl->chk_tstr_arg );
+ {
+ int tstr_rc = prctl->chk_tstr_fnc( c, prctl->chk_tstr_arg );
+
+ if ( tstr_rc > 0 ) // a valid time string has been received
+ {
+ // return only if the caller does not wait for a specific packet type
+ if ( cmd == GPS_WILDCARD )
+ return TR_COMPLETE_TSTR; //##++++++++++++++++++++ TODO better way to detect string
+ }
+ }
#endif
// intentional fall-through
@@ -559,10 +1984,27 @@ _MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
case TR_COMPLETE:
{
- uint16_t rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK;
+ GPS_CMD rcvd_cmd;
+
+ #if _USE_CHK_TSTR
+ //##+++++++++++++++++
+ // If a valid binary packet has been received then discard
+ // a partial time string possibly received before.
+ #endif
+
+ rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK;
if ( rcvd_cmd == cmd ) /* the received packet is what we've been waiting for */
- return TR_COMPLETE;
+ {
+ if ( pmb->hdr.cmd & GPS_NACK )
+ {
+ rc = MBG_ERR_RCVD_NACK;
+ goto out;
+ }
+
+ rc = MBG_SUCCESS;
+ goto out;
+ }
#if _USE_ENCRYPTION
/* if an encrypted packet has been received then decrypt it */
@@ -571,37 +2013,162 @@ _MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
rc = decrypt_message( pmctl );
if ( rc < 0 ) /* decryption error */
- return rc;
+ goto out;
rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK;
+ if ( pmb->hdr.cmd & GPS_NACK )
+ {
+ rc = MBG_ERR_RCVD_NACK;
+ goto out;
+ }
+
if ( rcvd_cmd == cmd ) /* the received packet is what we've been waiting for */
- return TR_COMPLETE;
+ {
+ rc = MBG_SUCCESS;
+ goto out;
+ }
}
#endif
/* not waiting for a specific packet, so return if any packet is complete */
- if ( cmd == (uint16_t) -1 )
- return TR_COMPLETE;
+ if ( cmd == GPS_WILDCARD )
+ {
+ rc = MBG_SUCCESS;
+ goto out;
+ }
//##++ received a msg which does not match the expected code
prctl->cnt = 0; /* restart receiving */
}
break;
+ case TR_CSUM_HDR:
+ rc = MBG_ERR_HDR_CSUM;
+ goto out;
+
+ case TR_CSUM_DATA:
+ rc = MBG_ERR_DATA_CSUM;
+ goto out;
+
default: /* any error condition */
- return rc;
+ rc = MBG_ERR_UNSPEC; //##+++++++++++++++++++++ use detailed rc
+ goto out;
} /* switch */
}
}
+out:
+ return rc;
+
} // mbgextio_rcv_msg
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
+/**
+ * @brief Set up and send a generic binary message
+ *
+ * @note This function should preferably be used only as low level function
+ * called from within more specific functions used to send specific data.
+ * If this function is called directly with a buffer to be sent then the
+ * transmit mutex is acquired by this function. However, other (higher level)
+ * API functions which set up the transmit buffer directly have to acquire
+ * the transmit mutex by themselves before they set up the transmit buffer,
+ * and pass a NULL pointer to indicate the transmit buffer has already been
+ * set up. The correct number of bytes to send (n_bytes) has to be specified
+ * anyway, though.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] p Address of a data structure according to the specified cmd parameter, or NULL
+ * @param[in] n_bytes Size of the data structure addressed by parameter p
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ GPS_CMD cmd, const void *p, uint16_t n_bytes )
+{
+ MBG_MSG_BUFF *pmb;
+ int rc = MBG_ERR_UNSPEC;
+
+ if ( n_bytes > sizeof( pmb->u.msg_data ) )
+ {
+ rc = MBG_ERR_OVERFLOW; // bytes to send exceed transmit buffer size
+ goto out;
+ }
+
+
+ pmb = pmctl->xmt.pmb;
+
+ if ( p )
+ {
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+ memcpy( pmb->u.bytes, p, n_bytes );
+ }
+
+ pmb->hdr.len = n_bytes;
+ pmb->hdr.cmd = cmd;
+ rc = xmt_tbuff( pmctl, p_addr );
+
+ #if _USE_MUTEX
+ _mbg_mutex_release( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ if ( rc != MBG_SUCCESS ) // error
+ goto out;
+
+
+ // If an acknowledge has been requested
+ // wait for a reply and check it.
+ if ( cmd & GPS_REQACK )
+ {
+ rc = mbgextio_rcv_msg( pmctl, p_addr, (GPS_CMD) ( cmd & ~GPS_CTRL_MSK ) );
+
+ if ( rc != MBG_SUCCESS )
+ {
+ //##++++++++++ rc = ... eventually return a different error code
+ goto out;
+ }
+
+ if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK )
+ {
+ rc = MBG_ERR_RCVD_NACK;
+ goto out;
+ }
+
+ if ( !(pmctl->rcv.pmb->hdr.cmd & GPS_ACK) )
+ rc = MBG_ERR_RCVD_NO_ACK;
+ }
+
+out:
+ return rc;
+
+} // mbgextio_xmt_msg
+
+
+
+/*HDR*/
+/**
+ * @brief Transmit a command-only message without additional data.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd )
{
int rc;
@@ -609,7 +2176,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
_mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
#endif
- rc = xmt_cmd( pmctl, cmd );
+ rc = xmt_cmd( pmctl, p_addr, cmd );
#if _USE_MUTEX
_mbg_mutex_release( &pmctl->xmt.xmt_mutex );
@@ -622,7 +2189,26 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t us )
+/**
+ * @brief Transmit a message without a single ushort (uint16_t) parameter
+ *
+ * The ushort parameter is often used to send an index value when requesting
+ * a certain element of an array of same data structures.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] us The ushort parameter for the command code
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_req_data_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us )
{
int rc;
@@ -630,7 +2216,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
_mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
#endif
- rc = xmt_cmd_us( pmctl, cmd, us );
+ rc = xmt_cmd_us( pmctl, p_addr, cmd, us );
#if _USE_MUTEX
_mbg_mutex_release( &pmctl->xmt.xmt_mutex );
@@ -643,34 +2229,110 @@ _MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, GPS_CMD cmd,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, GPS_CMD cmd )
+/**
+ * @brief Transmit a message without a single ushort (16 bit) parameter
+ *
+ * The ushort parameter is often used to send an index value when requesting
+ * a specific element of an array of data structures.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd )
{
- xmt_cmd( pmctl, cmd ); /* request a set of data */
+ int rc = xmt_cmd( pmctl, p_addr, cmd ); /* request a set of data */
+
+ if ( rc != MBG_SUCCESS ) // error
+ goto out;
- return mbgextio_rcv_msg( pmctl, cmd );
+ rc = mbgextio_rcv_msg( pmctl, p_addr, cmd );
+
+out:
+ return rc;
} // mbgextio_req_data
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, GPS_CMD cmd, uint16_t idx )
+/**
+ * @brief Read a specific element of an array of data structures
+ *
+ * The type of data is implicitely associated with the cmd parameter.
+ * Usually the number of supported array elements has to be determined
+ * by some other means, e.g. from a field in the ::RECEIVER_INFO structure.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] idx The index of the array element to read
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ GPS_CMD cmd, uint16_t idx )
{
- xmt_cmd_us( pmctl, cmd, idx ); /* request a set of data */
+ int rc = xmt_cmd_us( pmctl, p_addr, cmd, idx ); // send a request for a set of data
- return mbgextio_rcv_msg( pmctl, cmd );
+ if ( rc < 0 ) // error
+ goto out;
+
+ rc = mbgextio_rcv_msg( pmctl, p_addr, cmd ); // wait for the reply
+
+out:
+ return rc;
} // mbgextio_req_data_idx
+
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
+/**
+ * @brief Read a receiver info structure
+ *
+ * The ::RECEIVER_INFO should be read at first to identify the connected
+ * device and determine the basic features supported by the device.
+ *
+ * @note Some very old devices may not provide a ::RECEIVER_INFO,
+ * so ::mbgextio_setup_receiver_info should be called preferably
+ * to read the receiver info using this function, if supported,
+ * or set up a default structure for devices which don't provide
+ * a receiver info.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_setup_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, RECEIVER_INFO *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_RECEIVER_INFO );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_RECEIVER_INFO );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.receiver_info;
+ _mbg_swab_receiver_info( p );
+ }
return rc;
@@ -679,12 +2341,67 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, RECEI
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, SW_REV *p )
+/**
+ * @brief Setup a receiver info structure
+ *
+ * The ::RECEIVER_INFO should be read at first to identify the connected
+ * device and determine the basic features supported by the device.
+ *
+ * @note Some very old devices may not provide a ::RECEIVER_INFO.
+ * This function tries to read the ::RECEIVER_INFO from the device,
+ * and sets up a default structure if the device doesn't support this.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_setup_receiver_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, RECEIVER_INFO *p )
+{
+ int rc = mbgextio_get_receiver_info( pmctl, p_addr, p );
+
+ if ( rc == MBG_SUCCESS ) //##++++++++++++++ or in all cases except of MBG_ERR_TIMEOUT ?
+ goto out;
+
+ //##+++++++++++++ TODO try to read SW_REV, etc., evt. depending on p_addr == NULL or not
+
+out:
+ return rc;
+
+} // mbgextio_setup_receiver_info
+
+
+
+/*HDR*/
+/**
+ * @brief Read the software revision
+ *
+ * @deprecated This function is deprecated since the ::SW_REV structure
+ * is also a member of the ::RECEIVER_INFO. This call may be required,
+ * though, for very old devices which don't support the ::RECEIVER_INFO.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_setup_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, SW_REV *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_SW_REV );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_SW_REV );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.sw_rev;
+ _mbg_swab_sw_rev( p );
+ }
return rc;
@@ -693,12 +2410,27 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, SW_REV *p )
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, BVAR_STAT *p )
+/**
+ * @brief Read the status of buffered variables
+ *
+ * @note Only supported if ::GPS_MODEL_HAS_BVAR_STAT
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, BVAR_STAT *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_BVAR_STAT );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_BVAR_STAT );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.bvar_stat;
+ _mbg_swab_bvar_stat( p );
+ }
return rc;
@@ -707,12 +2439,30 @@ _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 )
+/**
+ * @brief Read the current time as ::TTM strucure
+ *
+ * @note This function is only supported by GPS receivers.
+ *
+ * The returned time is not very accurate since the response time
+ * transmission delay can't be determmined.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, TTM *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_TIME );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.ttm;
+ _mbg_swab_ttm( p );
+ }
return rc;
@@ -721,42 +2471,92 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, TTM *p )
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl, const TTM *p )
+/**
+ * @brief Set the device's time by sending a ::TTM strucure
+ *
+ * @note The function is not supported by all devices. Time has to be
+ * passed as local time according to the device's ::TZDL settings.
+ * New time is only set with some tens of ms accuracy.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const TTM *p )
{
- GPS_CMD cmd = GPS_TIME;
+ GPS_CMD cmd = GPS_TIME | OPT_GPS_ACK_CODE;
+ TTM *p_data = &pmctl->xmt.pmb->u.msg_data.ttm;
-#if _MBGEXTIO_DIRECT_RC
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ *p_data = *p;
+ _mbg_swab_ttm( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_time
-#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 ) )
+/*HDR*/
+/**
+ * @brief Set the device's position by sending an ::LLA array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] lla Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const LLA lla )
+{
+ GPS_CMD cmd = GPS_POS_LLA | OPT_GPS_ACK_CODE;
+ double *p_lla = pmctl->xmt.pmb->u.msg_data.lla;
+ int i;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ for ( i = 0; i < N_LLA; i++ )
{
- 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.
+ p_lla[i] = lla[i];
+ swap_double( &p_lla[i] );
+ _mbg_swab_double( &p_lla[i] );
}
- return 0;
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( LLA ) );
-#endif
-
-} // mbgextio_set_time
+} // mbgextio_set_pos_lla
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, LLA lla )
+/**
+ * @brief Read the current receiver position as ::LLA array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] lla Pointer to the data array to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, LLA lla )
{
- int rc = mbgextio_req_data( pmctl, GPS_POS_LLA );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_LLA );
- if ( rc == TR_COMPLETE )
+ if ( ( rc == MBG_SUCCESS ) && lla )
{
MSG_DATA *pmb = &pmctl->rcv.pmb->u.msg_data;
int i;
@@ -764,9 +2564,7 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, LLA lla )
for ( i = 0; i < N_LLA; i++ )
{
swap_double( &pmb->lla[i] );
-
- if ( lla )
- lla[i] = pmb->lla[i];
+ lla[i] = pmb->lla[i];
}
}
@@ -777,140 +2575,235 @@ _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 )
+/**
+ * @brief Read the current receiver position as ::XYZ array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] xyz Pointer to the data array to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_xyz( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XYZ xyz )
{
- GPS_CMD cmd = GPS_POS_LLA;
-
-#if _MBGEXTIO_DIRECT_RC
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_XYZ );
- 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 ) )
+ if ( ( rc == MBG_SUCCESS ) && xyz )
{
- 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.
- }
+ MSG_DATA *pmb = &pmctl->rcv.pmb->u.msg_data;
+ int i;
- return 0;
+ for ( i = 0; i < N_XYZ; i++ )
+ {
+ swap_double( &pmb->xyz[i] );
+ xyz[i] = pmb->xyz[i];
+ }
+ }
-#endif
+ return rc;
-} // mbgextio_set_pos_lla
+} // mbgextio_get_pos_xyz
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, TZDL *p )
+/**
+ * @brief Read the current receiver position as ::POS structure
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p_pos Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, POS *p_pos )
{
- int rc = mbgextio_req_data( pmctl, GPS_TZDL );
+ int rc = mbgextio_get_pos_xyz( pmctl, p_addr, p_pos->xyz );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.tzdl;
+ if ( rc != MBG_SUCCESS )
+ goto out;
- return rc;
-} // mbgextio_get_tzdl
+ rc = mbgextio_get_pos_lla( pmctl, p_addr, p_pos->lla );
+ if ( rc != MBG_SUCCESS )
+ goto out;
+ lla_to_dms( p_pos );
-/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, const TZDL *p )
-{
- GPS_CMD cmd = GPS_TZDL;
+out:
+ return rc;
-#if _MBGEXTIO_DIRECT_RC
+} // mbgextio_get_pos
- 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 );
+/*HDR*/
+/**
+ * @brief Read the local time conversion parameters in ::TZDL format
+ *
+ * @note Some devices may not support ::TZDL settings
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, TZDL *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_TZDL );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.tzdl;
+ _mbg_swab_tzdl( p );
}
- return 0;
-
-#endif
+ return rc;
} // mbgextio_get_tzdl
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p )
+/**
+ * @brief Set the local time conversion parameters in ::TZDL format
+ *
+ * @note Some devices may not support ::TZDL settings
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const TZDL *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_PORT_PARM );
+ GPS_CMD cmd = GPS_TZDL | OPT_GPS_ACK_CODE;
+ TZDL *p_data = &pmctl->xmt.pmb->u.msg_data.tzdl;
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.port_parm;
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- return rc;
+ *p_data = *p;
+ _mbg_swab_tzdl( p_data );
-} // mbgextio_get_port_parm
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_tzdl
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, const PORT_PARM *p )
+/**
+ * @brief Read serial port parameters in ::PORT_PARM format
+ *
+ * @deprecated This function is deprecated since the ::PORT_PARM structure
+ * supports only 2 serial ports, and does not not support configuration
+ * of a string type. The function ::mbgextio_get_serial_settings should
+ * be used instead.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_set_port_parm
+ * @see ::mbgextio_setup_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PORT_PARM *p )
{
- GPS_CMD cmd = GPS_PORT_PARM;
-
-#if _MBGEXTIO_DIRECT_RC
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_PORT_PARM );
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.port_parm;
+ _mbg_swab_port_parm( p );
+ }
-#else
+ return rc;
- MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
- int rc;
+} // mbgextio_get_port_parm
- 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 );
+/*HDR*/
+/**
+ * @brief Send serial port parameters in ::PORT_PARM format
+ *
+ * @deprecated This function is deprecated since the ::PORT_PARM structure
+ * supports only 2 serial ports, and does not not support configuration
+ * of a string type. The function ::mbgextio_save_serial_settings should
+ * be used instead.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_get_port_parm
+ * @see ::mbgextio_setup_receiver_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const PORT_PARM *p )
+{
+ GPS_CMD cmd = GPS_PORT_PARM | OPT_GPS_ACK_CODE;
+ PORT_PARM *p_data = &pmctl->xmt.pmb->u.msg_data.port_parm;
- 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.
- }
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- return 0;
+ *p_data = *p;
+ _mbg_swab_port_parm( p_data );
-#endif
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
} // mbgextio_set_port_parm
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, SYNTH *p )
+/**
+ * @brief Read the frequency synthesizer settings
+ *
+ * @note Some devices may not provide a frequency synthesizer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_synth
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, SYNTH *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_SYNTH );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_SYNTH );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.synth;
+ _mbg_swab_synth( p );
+ }
return rc;
@@ -919,43 +2812,60 @@ _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 )
+/**
+ * @brief Write the frequency synthesizer settings
+ *
+ * @note Some devices may not provide a frequency synthesizer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_synth
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const SYNTH *p )
{
- GPS_CMD cmd = GPS_SYNTH;
-
-#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 );
+ GPS_CMD cmd = GPS_SYNTH | OPT_GPS_ACK_CODE;
+ SYNTH *p_data = &pmctl->xmt.pmb->u.msg_data.synth;
- 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.
- }
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- return 0;
+ *p_data = *p;
+ _mbg_swab_synth( p_data );
-#endif
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
} // mbgextio_set_synth
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, ANT_INFO *p )
+/**
+ * @brief Read the GPS antenna info structure
+ *
+ * @note This is only supported by GPS receivers.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, ANT_INFO *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_ANT_INFO );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_INFO );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.ant_info;
+ _mbg_swab_ant_info( p );
+ }
return rc;
@@ -964,24 +2874,34 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, ANT_INFO *
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
+/**
+ * @brief Read a user capture event in ::TTM format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_ucap_buff
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, TTM *p )
{
- int rc;
+ int rc = xmt_cmd( pmctl, p_addr, GPS_UCAP ); /* request a set of data */
- xmt_cmd( pmctl, GPS_UCAP ); /* request a set of data */
+ if ( rc != MBG_SUCCESS )
+ goto out;
- // Attention: Older firmware versions may reply with GPS_TIME
- // messages instead of GPS_UCAP messages, and may not send a reply
+ // 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.
for (;;)
{
- rc = mbgextio_rcv_msg( pmctl, -1 );
-
- if ( rc < 0 )
- break;
+ rc = mbgextio_rcv_msg( pmctl, p_addr, -1 );
- if ( rc != TR_COMPLETE )
- continue;
+ if ( rc != MBG_SUCCESS )
+ goto out;
if ( pmctl->rcv.pmb->hdr.cmd == GPS_UCAP )
break;
@@ -998,11 +2918,15 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
// 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;
+ _mbg_swab_ttm( p );
+ }
else
_ttm_time_set_unavail( p ); // no capture event available
}
+out:
return rc;
} // mbgextio_get_ucap
@@ -1010,12 +2934,29 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, TTM *p )
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, ENABLE_FLAGS *p )
+/**
+ * @brief Read the enable flags controlling when output signals are enabled
+ *
+ * @note Some devices may not support ::ENABLE_FLAGS
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_enable_flags
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, ENABLE_FLAGS *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_ENABLE_FLAGS );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_ENABLE_FLAGS );
- if ( ( rc == TR_COMPLETE ) && p )
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
*p = pmctl->rcv.pmb->u.msg_data.enable_flags;
+ _mbg_swab_enable_flags( p );
+ }
return rc;
@@ -1024,487 +2965,2629 @@ _MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, ENABLE
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, const ENABLE_FLAGS *p )
+/**
+ * @brief Send the enable flags controlling when output signals are enabled
+ *
+ * @note Some devices may not support ::ENABLE_FLAGS
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_enable_flags
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const ENABLE_FLAGS *p )
{
- GPS_CMD cmd = GPS_ENABLE_FLAGS;
+ GPS_CMD cmd = GPS_ENABLE_FLAGS | OPT_GPS_ACK_CODE;
+ ENABLE_FLAGS *p_data = &pmctl->xmt.pmb->u.msg_data.enable_flags;
-#if _MBGEXTIO_DIRECT_RC
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ *p_data = *p;
+ _mbg_swab_enable_flags( p_data );
-#else
- int rc;
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
- rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
- rc = mbgextio_rcv_msg( pmctl, cmd );
+} // mbgextio_set_enable_flags
+
+
+
+/*HDR*/
+/**
+ * @brief Read GPS status info
+ *
+ * @note This is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, STAT_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_STAT_INFO );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.stat_info;
+ _mbg_swab_stat_info( p );
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_stat_info
-} // mbgextio_set_enable_flags
+
+
+/*HDR*/
+/**
+ * @brief Read the configured length of the antenna cable
+ *
+ * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+ *
+ * @note Some older devices may not reply to this request unless
+ * the application has registered itself as terminal application
+ * (GPS_AUTO_ON is not sufficient).
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ant_cable_len
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, ANT_CABLE_LEN *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_CABLE_LENGTH );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ant_cable_len;
+ _mbg_swab_ant_cable_len( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_ant_cable_len
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, STAT_INFO *p )
+/**
+ * @brief Send the GPS antenna cable length configuration
+ *
+ * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+
+ * @note Different devices may accept different maximum values, so the
+ * written value should be re-read using ::mbgextio_get_ant_cable_len
+ * to check if the parameter has been accepted.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ant_cable_len
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const ANT_CABLE_LEN *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_STAT_INFO );
+ GPS_CMD cmd = GPS_ANT_CABLE_LENGTH | OPT_GPS_ACK_CODE;
+ ANT_CABLE_LEN *p_data = &pmctl->xmt.pmb->u.msg_data.ant_cable_len;
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.stat_info;
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_ant_cable_len( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ant_cable_len
+
+
+
+/*HDR*/
+/**
+ * @brief Read configuration info and supported features of the device's IRIG output
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_TX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_irig_tx_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, IRIG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_TX_INFO );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.irig_tx_info;
+ _mbg_swab_irig_info( p );
+ }
return rc;
-} // mbgextio_get_stat_info
+} // mbgextio_get_irig_tx_info
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, ANT_CABLE_LEN *p )
+/**
+ * @brief Send new configuration settings for the device's IRIG output
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_TX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_irig_tx_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const IRIG_SETTINGS *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_ANT_CABLE_LENGTH );
+ GPS_CMD cmd = GPS_IRIG_TX_SETTINGS | OPT_GPS_ACK_CODE;
+ IRIG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.irig_tx_settings;
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.ant_cable_len;
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_irig_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_irig_tx_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read configuration info and supported features for the device's IRIG input
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_RX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_irig_rx_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, IRIG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_RX_INFO );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.irig_rx_info;
+ _mbg_swab_irig_info( p );
+ }
return rc;
-} // mbgextio_get_ant_cable_len
+} // mbgextio_get_irig_rx_info
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, const ANT_CABLE_LEN *p )
+/**
+ * @brief Send new configuration settings for the device's IRIG input
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_RX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_irig_rx_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const IRIG_SETTINGS *p )
{
- GPS_CMD cmd = GPS_ANT_CABLE_LENGTH;
+ GPS_CMD cmd = GPS_IRIG_RX_SETTINGS | OPT_GPS_ACK_CODE;
+ IRIG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.irig_rx_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
-#if _MBGEXTIO_DIRECT_RC
+ *p_data = *p;
+ _mbg_swab_irig_settings( p_data );
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
-#else
- int rc;
+} // mbgextio_set_irig_rx_settings
- 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 ) )
+
+/*HDR*/
+/**
+ * @brief Read current ref offset to %UTC configuration
+ *
+ * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ref_offs
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_REF_OFFS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_REF_OFFS );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.ref_offs;
+ _mbg_swab_mbg_ref_offs( p );
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_ref_offs
-} // mbgextio_set_ant_cable_len
+
+
+/*HDR*/
+/**
+ * @brief Send new ref offset to %UTC settings
+ *
+ * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ref_offs
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_REF_OFFS *p )
+{
+ GPS_CMD cmd = GPS_REF_OFFS | OPT_GPS_ACK_CODE;
+ MBG_REF_OFFS *p_data = &pmctl->xmt.pmb->u.msg_data.ref_offs;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_mbg_ref_offs( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ref_offs
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p )
+/**
+ * @brief Read current debug status
+ *
+ * @note This is only supported if ::GPS_HAS_DEBUG_STATUS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_DEBUG_STATUS *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_IRIG_TX_INFO );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_DEBUG_STATUS );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.irig_tx_info;
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.debug_status;
+ _mbg_swab_debug_status( p );
+ }
return rc;
-} // mbgextio_get_irig_tx_info
+} // mbgextio_get_debug_status
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p )
+/**
+ * @brief Read current optional settings and supported options
+ *
+ * @note This is only supported if ::GPS_HAS_OPT_SETTINGS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_opt_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_OPT_INFO *p )
{
- GPS_CMD cmd = GPS_IRIG_TX_SETTINGS;
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_OPT_INFO );
-#if _MBGEXTIO_DIRECT_RC
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.opt_info;
+ _mbg_swab_mbg_opt_info( p );
+ }
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ return rc;
-#else
- int rc;
+} // mbgextio_get_opt_info
+
+
+
+/*HDR*/
+/**
+ * @brief Send new optional settings flags
+ *
+ * @note This is only supported if ::GPS_HAS_OPT_SETTINGS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_opt_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_OPT_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_OPT_SETTINGS | OPT_GPS_ACK_CODE;
+ MBG_OPT_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.opt_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
- rc = mbgextio_rcv_msg( pmctl, cmd );
+ *p_data = *p;
+ _mbg_swab_mbg_opt_settings( p_data );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_opt_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read information on a specific supported string format
+ *
+ * Retrieve a single entry from an array of supported string types.
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_str_type_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX *p, uint16_t idx )
+{
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_STR_TYPE_INFO_IDX, idx );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.str_type_info_idx;
+ _mbg_swab_str_type_info_idx( p );
+
+ #if 0 //##++ TODO: check if received idx matches requested idx
+ if ( pii.idx != i )
+ {
+ printf( "** Info for port %i requested, but for %i received.\n",
+ pii.idx, i );
+ rc = ...;
+ }
+ #endif
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_str_type_info_idx
-} // mbgextio_set_irig_tx_settings
+
+
+/*HDR*/
+/**
+ * @brief Read an array of all supported string types
+ *
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_str_type_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[],
+ const RECEIVER_INFO *p_ri )
+{
+ int rc = MBG_SUCCESS;
+ uint16_t i;
+
+ for ( i = 0; i < p_ri->n_str_type; i++ )
+ {
+ rc = mbgextio_get_str_type_info_idx( pmctl, p_addr, &stii[i], i );
+
+ if ( rc != MBG_SUCCESS )
+ break;
+ }
+
+ return rc;
+
+} // mbgextio_get_all_str_type_info
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl, IRIG_INFO *p )
+/**
+ * @brief Read current settings and capabilities of a specific serial port
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_com_ports - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_port_info
+ * @see ::mbgextio_set_port_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PORT_INFO_IDX *p, uint16_t idx )
{
- int rc = mbgextio_req_data( pmctl, GPS_IRIG_RX_INFO );
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_PORT_INFO_IDX, idx );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.irig_rx_info;
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.port_info_idx;
+ _mbg_swab_port_info_idx( p );
+
+ #if 0 //##++ TODO: check if received idx matches requested idx
+ if ( pii.idx != i )
+ {
+ printf( "** Info for port %i requested, but for %i received.\n",
+ pii.idx, i );
+ rc = ...;
+ }
+ #endif
+ }
return rc;
-} // mbgextio_get_irig_rx_info
+} // mbgextio_get_port_info_idx
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, const IRIG_SETTINGS *p )
+/**
+ * @brief Read an array of current settings and capabilities of all serial ports
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_com_ports entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_port_info_idx
+ * @see ::mbgextio_set_port_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_port_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PORT_INFO_IDX pii[],
+ const RECEIVER_INFO *p_ri )
{
- GPS_CMD cmd = GPS_IRIG_RX_SETTINGS;
+ int rc = MBG_SUCCESS;
+ uint16_t i;
-#if _MBGEXTIO_DIRECT_RC
+ for ( i = 0; i < p_ri->n_com_ports; i++ )
+ {
+ rc = mbgextio_get_port_info_idx( pmctl, p_addr, &pii[i], i );
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ if ( rc != MBG_SUCCESS )
+ break;
+ }
-#else
- int rc;
+ return rc;
+
+} // mbgextio_get_all_port_info
+
+
+
+/*HDR*/
+/**
+ * @brief Send configuration settings for a specific serial port
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::RECEIVER_INFO::n_com_ports - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_port_info_idx
+ * @see ::mbgextio_get_all_port_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const PORT_SETTINGS *p, uint16_t idx )
+{
+ GPS_CMD cmd = GPS_PORT_SETTINGS_IDX | OPT_GPS_ACK_CODE;
+ PORT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.port_settings_idx;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- rc = mbgextio_xmt_msg( pmctl, (uint16_t) ( cmd | GPS_ACK ), (const uint8_t *) p, sizeof( *p ) );
- rc = mbgextio_rcv_msg( pmctl, cmd );
+ p_data->port_settings = *p;
+ p_data->idx = idx;
+ _mbg_swab_port_settings_idx( p_data );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_port_settings_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Read current settings and capabilities of a specific programmable pulse output
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_prg_out - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_pout_info
+ * @see ::mbgextio_set_pout_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, POUT_INFO_IDX *p, uint16_t idx )
+{
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_POUT_INFO_IDX, idx );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.pout_info_idx;
+ _mbg_swab_pout_info_idx_on_get( p );
+
+ #if 0 //##++ TODO: check if received idx matches requested idx
+ if ( pii.idx != i )
+ {
+ printf( "** Info for port %i requested, but for %i received.\n",
+ pii.idx, i );
+ rc = ...;
+ }
+ #endif
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_pout_info_idx
-} // mbgextio_set_irig_rx_settings
+
+
+/*HDR*/
+/**
+ * @brief Read an array of current settings and capabilities of all programmable pulse outputs
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_prg_out entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_pout_info_idx
+ * @see ::mbgextio_set_pout_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ POUT_INFO_IDX *pii, const RECEIVER_INFO *p_ri )
+{
+ int rc = MBG_SUCCESS;
+ uint16_t i;
+
+ memset( pii, 0, p_ri->n_prg_out * sizeof( *pii ) );
+
+ for ( i = 0; i < p_ri->n_prg_out; i++ )
+ {
+ rc = mbgextio_get_pout_info_idx( pmctl, p_addr, &pii[i], i );
+
+ if ( rc != MBG_SUCCESS )
+ break;
+ }
+
+ return rc;
+
+} // mbgextio_get_all_pout_info
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl, MBG_REF_OFFS *p )
+/**
+ * @brief Send configuration settings for a specific programmable pulse output
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the pulse output to be configured, 0..RECEIVER_INFO::n_prg_out - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_pout_info_idx
+ * @see ::mbgextio_get_all_pout_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const POUT_SETTINGS *p, uint16_t idx )
{
- int rc = mbgextio_req_data( pmctl, GPS_REF_OFFS );
+ GPS_CMD cmd = GPS_POUT_SETTINGS_IDX | OPT_GPS_ACK_CODE;
+ POUT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.pout_settings_idx;
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.ref_offs;
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ p_data->pout_settings = *p;
+ p_data->idx = idx;
+ _mbg_swab_pout_settings_idx_on_set( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_pout_settings_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Clear the user capture event buffer on-board the device
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ucap
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr )
+{
+ return mbgextio_xmt_cmd( pmctl, p_addr, GPS_CLR_UCAP_BUFF );
+
+} // mbgextio_clr_ucap_buff
+
+
+
+/*HDR*/
+/**
+ * @brief Read time scale configuration parameters
+ *
+ * @note Some devices may not support a configurable time scale
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_time_scale_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_TIME_SCALE_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME_SCALE );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.time_scale_info;
+ _mbg_swab_mbg_time_scale_info( p );
+ }
return rc;
-} // mbgextio_get_ref_offs
+} // mbgextio_get_time_scale_info
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, const MBG_REF_OFFS *p )
+/**
+ * @brief Send new time scale configuration settings
+ *
+ * @note Some devices may not support a configurable time scale
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_time_scale_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_TIME_SCALE_SETTINGS *p )
{
- GPS_CMD cmd = GPS_REF_OFFS;
+ GPS_CMD cmd = GPS_TIME_SCALE | OPT_GPS_ACK_CODE;
+ MBG_TIME_SCALE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.time_scale_settings;
-#if _MBGEXTIO_DIRECT_RC
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_mbg_time_scale_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_time_scale_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Clear the on-board event log
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_first_evt_log_entry
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_evt_log( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr )
+{
+ return mbgextio_xmt_cmd( pmctl, p_addr, GPS_CLR_EVT_LOG );
+
+} // mbgextio_clr_evt_log
- 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 );
+/*HDR*/
+/**
+ * @brief Read the current number of entries in the on-board event log
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_first_evt_log_entry
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_num_evt_log_entries( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_NUM_EVT_LOG_ENTRIES *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NUM_EVT_LOG_ENTRIES );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.num_evt_log_entries;
+ _mbg_swab_mbg_num_evt_log_entries( p );
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_num_evt_log_entries
-} // mbgextio_set_ref_offs
+
+
+/*HDR*/
+/**
+ * @brief Return the first entry from the on-board event log
+ *
+ * This resets an internal counter, so subsequent calls to
+ * ::mbgextio_get_next_evt_log_entry will retrieve the following entries.
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_first_evt_log_entry( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_FIRST_EVT_LOG_ENTRY );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.evt_log_entry;
+ _mbg_swab_mbg_evt_log_entry( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_first_evt_log_entry
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, MBG_DEBUG_STATUS *p )
+/**
+ * @brief Return the next entry from the on-board event log
+ *
+ * This increments an internal counter, so subsequent calls will
+ * return subsequent entries. ::mbgextio_get_first_evt_log_entry
+ * should be called first to reset the counter and retrieve the
+ * oldest log entry.
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_first_evt_log_entry
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_next_evt_log_entry( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_DEBUG_STATUS );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NEXT_EVT_LOG_ENTRY );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.debug_status;
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.evt_log_entry;
+ _mbg_swab_mbg_evt_log_entry( p );
+ }
return rc;
-} // mbgextio_get_debug_status
+} // mbgextio_get_next_evt_log_entry
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl, MBG_OPT_INFO *p )
+/**
+ * @brief Read the current IMS state and supported IMS features
+ *
+ * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ims_sensor_state_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_state( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_IMS_STATE *p )
{
- int rc = mbgextio_req_data( pmctl, GPS_OPT_INFO );
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_IMS_STATE );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.opt_info;
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ims_state;
+ _mbg_swab_mbg_ims_state( p );
+ }
return rc;
-} // mbgextio_get_opt_info
+} // mbgextio_get_ims_state
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, const MBG_OPT_SETTINGS *p )
+/**
+ * @brief Read sensor values from a specified sensor on the device
+ *
+ * Info on supported sensors can be retrieved using ::mbgextio_get_ims_state.
+ * Valid range for the sensor index is [0..::MBG_IMS_STATE::num_sensors - 1].
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx The index of the array element to read
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ims_state
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_sensor_state_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_IMS_SENSOR_STATE_IDX *p, uint16_t idx )
{
- GPS_CMD cmd = GPS_OPT_SETTINGS;
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IMS_SENSOR_STATE_IDX, idx );
-#if _MBGEXTIO_DIRECT_RC
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ims_sensor_state_idx;
+ _mbg_swab_mbg_ims_sensor_state_idx( p );
+ }
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ return rc;
-#else
- int rc;
+} // mbgextio_get_ims_sensor_state_idx
- 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 ) )
+
+/*HDR*/
+/**
+ * @brief Set the XMR holdover interval
+ *
+ * @todo In which case is this supported?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_holdover_interval_counter
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_holdover_interval( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const XMR_HOLDOVER_INTV *p )
+{
+ GPS_CMD cmd = GPS_XMR_HOLDOVER_INTV | OPT_GPS_ACK_CODE;
+ XMR_HOLDOVER_INTV *p_data = &pmctl->xmt.pmb->u.msg_data.xmr_holdover_intv;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_xmr_holdover_intv( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_holdover_interval
+
+
+
+/*HDR*/
+/**
+ * @brief Read the XMR holdover interval counter
+ *
+ * @todo In which case is this supported?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_holdover_interval
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XMR_HOLDOVER_INTV *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_XMR_HOLDOVER_INTV );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.xmr_holdover_intv;
+ _mbg_swab_xmr_holdover_intv( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_holdover_interval_counter
+
+
+
+/*HDR*/
+/**
+ * @brief Read the local time conversion configuration in ::TZCODE format
+ *
+ * @note Some devices may not support ::TZCODE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_tzcode
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzcode( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, TZCODE *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, PZF_TZCODE );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.tzcode;
+ _mbg_swab_tzcode( p );
}
- return 0;
+ return rc;
+
+} // mbgextio_get_tzcode
+
+
+
+/*HDR*/
+/**
+ * @brief Set the local time conversion configuration in ::TZCODE format
+ *
+ * @note Some devices may not support ::TZCODE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_tzcode
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzcode( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const TZCODE *p )
+{
+ GPS_CMD cmd = PZF_TZCODE | OPT_GPS_ACK_CODE;
+ TZCODE *p_data = &pmctl->xmt.pmb->u.msg_data.tzcode;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_tzcode( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+} // mbgextio_set_tzcode
+
+
+
+/*HDR*/
+/**
+ * @brief Send new configuration settings for the device's HAVEQUICK output
+ *
+ * @note This is only supported if ::GPS_HAS_HAVEQUICK is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_HAVEQUICK_TX_SETTINGS | OPT_GPS_ACK_CODE;
+ HAVEQUICK_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.havequick_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_havequick_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_hq_tx_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Send new configuration settings for the device's HAVEQUICK input
+ *
+ * @note This is only supported if ::MULTI_REF_HAVEQUICK is > 0 in ::XMULTI_REF_INSTANCES::n_inst //##+++++++++++++++++++++++ ???
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_HAVEQUICK_RX_SETTINGS | OPT_GPS_ACK_CODE;
+ HAVEQUICK_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.havequick_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_havequick_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_hq_rx_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read the distance from transmitter ::TR_DISTANCE format
+ *
+ * @note Some devices may not support ::TR_DISTANCE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_tr_distance
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_tr_distance( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, TR_DISTANCE *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, PZF_TR_DISTANCE );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.tr_distance;
+ _mbg_swab_tr_distance( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_tr_distance
+
+
+
+/*HDR*/
+/**
+ * @brief Set the transmitter distance (km) in ::TR_DISTANCE format
+ *
+ * @note Some devices may not support ::TR_DISTANCE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_tr_distance
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_tr_distance( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const TR_DISTANCE *p )
+{
+ GPS_CMD cmd = PZF_TR_DISTANCE | OPT_GPS_ACK_CODE;
+ TR_DISTANCE *p_data = &pmctl->xmt.pmb->u.msg_data.tr_distance;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_tr_distance( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_tr_distance
+
+
+
+/*HDR*/
+/**
+ * @brief Read current GNSS mode settings and supported features
+ *
+ * @note Some devices may not support GNSS configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_gnss_mode_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_mode_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_GNSS_MODE_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_GNSS_MODE );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.gnss_mode_info;
+ _mbg_swab_dummy( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_gnss_mode_info
+
+
+
+/*HDR*/
+/**
+ * @brief Write GNSS mode settings
+ *
+ * @note Some devices may not support GNSS configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] p Pointer to a ::MBG_GNSS_MODE_SETTINGS structure to be sent
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_gnss_mode_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_gnss_mode_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_GNSS_MODE_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_GNSS_MODE | OPT_GPS_ACK_CODE;
+ MBG_GNSS_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.gnss_mode_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_dummy( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_gnss_mode_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read an array of all supported string types //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO
+ *
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_str_type_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[],
+ const RECEIVER_INFO *p_ri )
+{
+ int rc = MBG_SUCCESS;
+ uint16_t i;
+
+ for ( i = 0; i < p_ri->n_str_type; i++ )
+ {
+ rc = mbgextio_get_str_type_info_idx( pmctl, p_addr, &stii[i], i );
+
+ if ( rc != MBG_SUCCESS )
+ break;
+ }
+
+ return rc;
+
+} // mbgextio_get_all_gnss_sat_info
+
+
+
+/*HDR*/
+/**
+ * @brief Fill up a GNSS info structure //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[out] p_si Pointer to a ::STAT_INFO the data structure to return the received data
+ * @param[out] p_gmi Index of the NTP peer state to be configured, 0..::NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ * @param[out] p_gsii Blah ... //##++++++++++ TODO
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_sys_state
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+int mbgextio_chk_get_gnss_info( MBG_MSG_CTL *pmctl, STAT_INFO *p_si,
+ MBG_GNSS_MODE_INFO *p_gmi, GNSS_SAT_INFO_IDX *p_gsii,
+ const RECEIVER_INFO *p_ri )
+{
+ int n_gnss_supp = 0;
+ int rc = -1;
+#if 0
+ int i = -1;
+
+#if 0 //##++++++++++++++
+ if ( !_pcps_has_stat_info( p_dev ) )
+ return 0;
#endif
-} // mbgextio_set_opt_settings
+ rc = mbgextio_get_stat_info( pmctl, p_si );
+
+ if ( rc < 0 )
+ goto fail;
+
+
+//##+++++++++++++ if ( _pcps_is_gnss( p_dev ) )
+ {
+ if ( ( rc = mbgextio_get_gnss_mode_info( pmctl, p_gmi ) ) < 0 )
+ goto fail;
+
+// mbgextio_get_all_gnss_sat_info
+ for ( i = 0; i < p_gmi-> ; i++ )
+ rc = mbgextio_get_all_gnss_sat_info( pmctl, p_gsii, p_gmi );
+
+ if ( rc < 0 )
+ goto fail;
+ }
+//##++++ else
+ {
+//##++++ if ( _pcps_has_stat_info_svs( p_dev ) ) // GPS is supported
+ {
+ GNSS_SAT_INFO *p_gsi;
+
+ // setup GNSS info from stat_info so we can use the same printing routine
+ p_gmi->supp_gnss_types = MBG_GNSS_TYPE_MSK_GPS;
+ p_gmi->settings.gnss_set = p_gmi->supp_gnss_types;
+
+ p_gsi = &p_gsii->gnss_sat_info;
+ p_gsi->gnss_type = GNSS_TYPE_GPS;
+ p_gsi->svs_in_view = p_si->svs_in_view;
+ p_gsi->good_svs = p_si->good_svs;
+ }
+ }
+
+ n_gnss_supp = num_bits_set( p_gmi->supp_gnss_types );
+
+ if ( n_gnss_supp > N_GNSS_TYPES )
+ {
+ //##++++ show warning: device supports more GNSS types than this program
+ n_gnss_supp = N_GNSS_TYPES;
+ }
+
+ return n_gnss_supp;
+
+
+fail:
+#endif
+ return rc;
+
+} // mbg_chk_get_gnss_info
/*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 )
+/**
+ * @brief Read the supported XMR features in ::XMULTI_REF_INFO_IDX format
+ *
+ * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xmr_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_info_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p )
{
- int rc;
+ uint16_t idx = p->idx;
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_INFO_IDX, idx );
- xmt_cmd_us( pmctl, GPS_STR_TYPE_INFO_IDX, idx );
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.xmulti_ref_info_idx;
+ _mbg_swab_dummy( p ); //##++++++ _mbg_xmr_info_idx( p );
+ }
+
+ return rc;
- rc = mbgextio_rcv_msg( pmctl, GPS_STR_TYPE_INFO_IDX );
+} // mbgextio_get_xmr_info_idx
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.str_type_info_idx;
+
+
+/*HDR*/
+/**
+ * @brief Read the supported XMR features ::XMULTI_REF_STATUS_IDX format
+ *
+ * @note Only for devices which supports Multi references
+ * @note GPS_HAS_XMULTI_REF feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xmr_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_status_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XMULTI_REF_STATUS_IDX *p )
+{
+ uint16_t idx = p->idx;
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_STATUS_IDX, idx );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.xmulti_ref_status_idx;
+ //##++++++ _mbg_xmr_status_idx( p );
+ }
return rc;
-} // mbgextio_get_str_type_info_idx
+} // mbgextio_get_xmr_status_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Save the supported XMR features ::XMULTI_REF_INFO_IDX format
+ *
+ * @note Some devices may not support Multi Refernce Sources
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const XMULTI_REF_SETTINGS_IDX *p )
+{
+ GPS_CMD cmd = GPS_XMR_SETTINGS_IDX | OPT_GPS_ACK_CODE;
+ XMULTI_REF_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.xmulti_ref_settings_idx;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ //##++++++ _mbg_swab_xmr_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_xmr_settings
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl,
- PORT_INFO_IDX *p, uint16_t idx )
+/**
+ * @brief Read the lan interface configuration ::LAN_IF_INFO format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_lan_if_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, LAN_IF_INFO *p )
{
int rc;
+ rc = mbgextio_req_data( pmctl, p_addr, GPS_LAN_IF_INFO );
- xmt_cmd_us( pmctl, GPS_PORT_INFO_IDX, idx );
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.lan_if_info;
+ //##++++++ _mbg_xmr_status_idx( p );
+ }
+
+ return rc;
- rc = mbgextio_rcv_msg( pmctl, GPS_PORT_INFO_IDX );
+} // mbgextio_get_lan_if_info
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.port_info_idx;
+
+
+/*HDR*/
+/**
+ * @brief Read the lan ipv4 configuration state ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, IP4_SETTINGS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_SETTINGS );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ip4_settings;
+ //##++++++ _mbg_xmr_status_idx( p );
+ }
return rc;
-} // mbgextio_get_port_info_idx
+} // mbgextio_get_ip4_settings
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl,
- const PORT_SETTINGS *p, uint16_t idx )
+/**
+ * @brief Save the current ipv4 settings ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ip4_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const IP4_SETTINGS *p )
{
- GPS_CMD cmd = GPS_PORT_SETTINGS_IDX;
- MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
- int rc;
+ GPS_CMD cmd = GPS_IP4_SETTINGS | OPT_GPS_ACK_CODE;
+ IP4_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ip4_settings;
- pmb->u.msg_data.port_settings_idx.port_settings = *p;
- pmb->u.msg_data.port_settings_idx.idx = idx;
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ //##++++++ _mbg_swab_xmr_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ip4_settings
- 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
+
+/*HDR*/
+/**
+ * @brief Read the current lan ipv4 state ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_state( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, IP4_SETTINGS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_STATE );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ip4_settings;
+ //##++++++ _mbg_xmr_status_idx( p );
+ }
return rc;
-#else
+} // mbgextio_get_ip4_state
- rc = mbgextio_rcv_msg( pmctl, cmd );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+
+/*HDR*/
+/**
+ * @brief Read the current state of PTP device ::PTP_STATE format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_state( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PTP_STATE *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_STATE);
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.ptp_state;
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_ptp_state
-} // mbgextio_set_port_settings_idx
+
+
+/*HDR*/
+/**
+ * @brief Read the ptp configuration ::PTP_CFG_INFO format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_cfg_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PTP_CFG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_CFG );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ptp_cfg_info;
+ }
+
+ return rc;
+
+} // mbgextio_get_ptp_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Read the ptp configuration ::PTP_UC_MASTER_CFG_LIMITS format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_uc_master_cfg_limits( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PTP_UC_MASTER_CFG_LIMITS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG_LIMITS );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ptp_uc_master_cfg_limits;
+ }
+
+ return rc;
+
+} // mbgextio_get_ptp_uc_master_cfg_limits
+
+
+
+/*HDR*/
+/**
+ * @brief Read the ptp configuration ::ALL_PTP_UC_MASTER_INFO_IDX format
+ *
+ * @note ptp feature must set and read number of ptp unicast masters before.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] ptp_uc_master_info_idx Pointer to an array of ::PTP_UC_MASTER_INFO_IDX structures to be filled up
+ * @param[in] ptp_uc_master_cfg_limits Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure read before
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++ TODO
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_uc_master_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, PTP_UC_MASTER_INFO_IDX *ptp_uc_master_info_idx,
+ const PTP_UC_MASTER_CFG_LIMITS *ptp_uc_master_cfg_limits )
+{
+ int rc= MBG_SUCCESS;
+ uint16_t i;
+
+ for ( i = 0; i < ptp_uc_master_cfg_limits->n_supp_master; i++ )
+ {
+ xmt_cmd_us( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG, i );
+
+ rc = mbgextio_rcv_msg( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG ); //##+++++++++++++++++++++++++
+
+ if ( ( rc == MBG_SUCCESS ) && ptp_uc_master_info_idx )
+ {
+ PTP_UC_MASTER_INFO_IDX *p = &ptp_uc_master_info_idx[i];
+ *p = pmctl->rcv.pmb->u.msg_data.ptp_uc_master_info_idx;
+ _mbg_swab_dummy( p );
+ }
+ else
+ break;
+ }
+
+ return rc;
+
+} // mbgextio_get_all_ptp_uc_master_info
+
+
+
+/*HDR*/
+/**
+ * @brief Send configuration settings for PTP
+ *
+ * @note This is only supported by PTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ptp_cfg_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const PTP_CFG_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_PTP_CFG | OPT_GPS_ACK_CODE;
+ PTP_CFG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_cfg_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_ptp_cfg_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ptp_cfg_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read the ntp global information ::NTP_GLB_INFO format
+ *
+ * @note ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_glb_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, NTP_GLB_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_GLB_CFG );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ntp_glb_info;
+ }
+
+ return rc;
+
+} // mbgextio_get_ntp_glb_info
+
+
+
+/*HDR*/
+/**
+ * @brief Send the NTP global configuration
+ *
+ * @note This is only supported by NTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ant_cable_len
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const NTP_GLB_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_NTP_GLB_CFG | OPT_GPS_ACK_CODE;
+ NTP_GLB_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_glb_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_ntp_glb_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ntp_glb_info
+
+
+
+/*HDR*/
+/**
+ * @brief Read the ntp global information ::NTP_CLNT_MODE_INFO format
+ *
+ * @note ntp feature must set
+ * @note ntp client mode must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_set_ntp_clnt_mode_cfg
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_clnt_mode_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, NTP_CLNT_MODE_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_CLNT_MODE_CFG );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ntp_clnt_mode_info;
+ }
+
+ return rc;
+
+} // mbgextio_get_ntp_clnt_mode_info
+
+
+
+/*HDR*/
+/**
+ * @brief Send the NTP client mode configuration
+ *
+ * @note This is only supported by NTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_clnt_mode_cfg( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const NTP_CLNT_MODE_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_NTP_CLNT_MODE_CFG | OPT_GPS_ACK_CODE;
+ NTP_CLNT_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_clnt_mode_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_ntp_clnt_mode_settings( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ntp_clnt_mode_cfg
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl,
- POUT_INFO_IDX *p, uint16_t idx )
+/**
+ * @brief Read the ntp peer settings of current idx ::NTP_PEER_SETTINGS format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the NTP peer settings to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_settings_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, NTP_PEER_SETTINGS_IDX *p, uint16_t idx )
{
int rc;
+ rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_SETTINGS_IDX, idx );
- xmt_cmd_us( pmctl, GPS_POUT_INFO_IDX, idx );
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ntp_peer_settings_idx;
+ }
- rc = mbgextio_rcv_msg( pmctl, GPS_POUT_INFO_IDX );
+ return rc;
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.pout_info_idx;
+} // mbgextio_get_ntp_peer_settings_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Send configuration settings for a specific NTP peer
+ *
+ * The number of supported NTP peers is specified in ::NTP_CLNT_MODE_INFO::n_supp_peers -1.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the NTP peer to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const NTP_PEER_SETTINGS *p, uint16_t idx )
+{
+ GPS_CMD cmd = GPS_NTP_PEER_SETTINGS_IDX | OPT_GPS_ACK_CODE;
+ NTP_PEER_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_peer_settings_idx;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ p_data->peer_settings = *p;
+ p_data->idx = idx;
+ _mbg_swab_ntp_peer_settings_idx( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_ntp_peer_settings_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Read the current system state of ntp device ::NTP_SYS_STATE format
+ *
+ * @note ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ntp_clnt_mode_cfg
+ * @see ::mbgextio_get_ntp_glb_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_sys_state( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, NTP_SYS_STATE *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_SYS_STATE);
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ntp_sys_state;
+ //##++++++ _mbg_xmr_status_idx( p );
+ }
return rc;
-} // mbgextio_get_pout_info_idx
+} // mbgextio_get_ntp_sys_state
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl,
- const POUT_SETTINGS *p, uint16_t idx )
+/**
+ * @brief Read the NTP peer state of current idx ::NTP_PEER_STATE format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the NTP peer state to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_sys_state
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_state_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, NTP_PEER_STATE_IDX *p, uint16_t idx )
{
- GPS_CMD cmd = GPS_POUT_SETTINGS_IDX;
- MBG_MSG_BUFF *pmb = pmctl->xmt.pmb;
int rc;
+ rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_STATE_IDX, idx );
- pmb->u.msg_data.pout_settings_idx.pout_settings = *p;
- pmb->u.msg_data.pout_settings_idx.idx = idx;
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ntp_peer_state_idx;
+ }
- pmb->hdr.len = sizeof( pmb->u.msg_data.pout_settings_idx );
- pmb->hdr.cmd = cmd | GPS_REQACK;
- rc = xmt_tbuff( pmctl );
+ return rc;
+
+} // mbgextio_get_ntp_peer_state_idx
+
+
+/*HDR*/
+/**
+ * @brief Read the network global config information ::MBG_NET_GLB_CFG_INFO format
+ *
+ * @note GPS_HAS_NET_CFG must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_glb_cfg_settings
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_glb_cfg_info( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_NET_GLB_CFG_INFO *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_NET_GLB_CFG);
-#if _MBGEXTIO_DIRECT_RC
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.net_glb_cfg_info;
+ _mbg_swab_dummy( p );
+ }
return rc;
-#else
+} // mbgextio_get_net_glb_cfg_info
+
+/*HDR*/
+/**
+ * @brief Set the device's global network configuration settings
+ *
+ * @note The function is not supported by all devices. //##++++++++++++
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_glb_cfg_info
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_NET_GLB_CFG_SETTINGS *p )
+{
+ GPS_CMD cmd = GPS_NET_GLB_CFG | OPT_GPS_ACK_CODE;
+ MBG_NET_GLB_CFG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.net_glb_cfg_settings;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_dummy( p );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
- rc = mbgextio_rcv_msg( pmctl, cmd );
+} // mbgextio_set_net_glb_cfg_settings
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+
+
+/*HDR*/
+/**
+ * @brief Read the network dns server ::MBG_IP_ADDR_IDX format
+ *
+ * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srvr_idx
+ * @see ::mbgextio_get_net_stat_dns_srvr_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srvr_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx )
+{
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRVR, idx );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.ip_addr_idx;
+ _mbg_swab_dummy( p );
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_net_dns_srvr_idx
-} // mbgextio_set_pout_settings_idx
+
+
+/*HDR*/
+/**
+ * @brief Send the network DNS server address in ::MBG_IP_ADDR format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srvr_idx
+ * @see ::mbgextio_get_net_stat_dns_srvr_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srvr_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_IP_ADDR *p, uint16_t idx )
+{
+ GPS_CMD cmd = GPS_NET_DNS_SRVR | OPT_GPS_ACK_CODE;
+ MBG_IP_ADDR_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ip_addr_idx;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ p_data->addr = *p;
+ p_data->idx = idx;
+ _mbg_swab_dummy( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, p_data, sizeof( *p_data ) );
+
+} // mbgextio_set_net_dns_srvr_idx
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl )
+/**
+ * @brief Read the network DNS search domain in ::MBG_NET_NAME_IDX format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srch_dom_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx )
{
- return mbgextio_xmt_cmd( pmctl, GPS_CLR_UCAP_BUFF );
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRCH_DOM, idx );
-} // mbgextio_clr_ucap_buff
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.net_name_idx;
+ _mbg_swab_dummy( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_net_dns_srch_dom_idx
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl,
- MBG_TIME_SCALE_INFO *p )
+/**
+ * @brief Send the network DNS search domain in ::MBG_NET_NAME format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srch_dom_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, const MBG_NET_NAME *p, uint16_t idx )
{
- int rc;
+ GPS_CMD cmd = GPS_NET_DNS_SRCH_DOM | OPT_GPS_ACK_CODE;
+ MBG_NET_NAME_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.net_name_idx;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
- xmt_cmd( pmctl, GPS_TIME_SCALE );
+ p_data->net_name = *p;
+ p_data->idx = idx;
+ _mbg_swab_dummy( p_data );
- rc = mbgextio_rcv_msg( pmctl, GPS_TIME_SCALE );
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, p_data, sizeof( *p_data ) );
- if ( ( rc == TR_COMPLETE ) && p )
- *p = pmctl->rcv.pmb->u.msg_data.time_scale_info;
+} // mbgextio_set_net_dns_srch_dom_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Read the current network DNS server in ::MBG_IP_ADDR_IDX format
+ *
+ * The number of DNS servers supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srvr_idx
+ * @see ::mbgextio_set_net_dns_srvr_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srvr_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx )
+{
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRVR, idx );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.ip_addr_idx;
+ _mbg_swab_dummy( p );
+ }
return rc;
-} // mbgextio_get_time_scale_info
+} // mbgextio_get_net_stat_dns_srvr_idx
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmctl,
- const MBG_TIME_SCALE_SETTINGS *p )
+/**
+ * @brief Read the current network DNS search domain in ::MBG_NET_NAME_IDX format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_dns_srch_dom_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx )
{
- GPS_CMD cmd = GPS_TIME_SCALE;
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRCH_DOM, idx );
-#if _MBGEXTIO_DIRECT_RC
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.net_name_idx;
+ _mbg_swab_dummy( p );
+ }
- return mbgextio_xmt_msg( pmctl, cmd, (const uint8_t *) p, sizeof( *p ) );
+ return rc;
-#else
+} // mbgextio_get_net_stat_dns_srch_dom_stat_idx
- 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 );
+/*HDR*/
+/**
+ * @brief Read the ::XBP_LIMITS to check which XBP features are supported
+ *
+ * @note Only supported if ::GPS_HAS_XBP is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_node_limits
+ * @see ::mbgextio_get_xbp_node_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_limits( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XBP_LIMITS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_LIMITS );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.xbp_limits;
+ _mbg_swab_dummy( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_xbp_limits
+
+
+/*HDR*/
+/**
+ * @brief Read the ::XBP_NODE_LIMITS to check how many ports are provided
+ *
+ * @note Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_limits
+ * @see ::mbgextio_get_xbp_node_info_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_limits( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XBP_NODE_LIMITS *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_NODE_LIMITS );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.xbp_node_limits;
+ _mbg_swab_dummy( p );
+ }
+
+ return rc;
- rc = mbgextio_rcv_msg( pmctl, cmd );
+} // mbgextio_get_xbp_node_limits
+
+
+/*HDR*/
+/**
+ * @brief Read the ::XBP_NODE_INFO for a specific node in ::XBP_NODE_INFO_IDX format
+ *
+ * The supported number of nodes is provided by ::XBP_NODE_LIMITS::node_count.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::XBP_NODE_LIMITS::node_count-1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_limits
+ * @see ::mbgextio_get_xbp_node_limits
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_info_idx( MBG_MSG_CTL *pmctl,
+ const XBP_ADDR *p_addr, XBP_NODE_INFO_IDX *p, uint16_t idx )
+{
+ int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XBP_NODE_INFO_IDX, idx );
- if ( ( rc != TR_COMPLETE ) || !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) )
+ if ( ( rc == MBG_SUCCESS ) && p )
{
- 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.
+ *p = pmctl->rcv.pmb->u.msg_data.xbp_node_info_idx;
+ _mbg_swab_dummy( p );
}
- return 0;
+ return rc;
-#endif
+} // mbgextio_get_xbp_node_info_idx
-} // mbgextio_set_time_scale_settings
+
+
+static /*HDR*/
+void handle_xbp_node( XBP_NODE_INFO *p_ni, long idx )
+{
+ XBP_ADDR * p_addr = &p_ni->addr;
+ RECEIVER_INFO *p_ri = &p_ni->ri;
+ int i;
+
+ printf( "Node info %li:", idx );
+
+ printf( " addr %02X:", p_addr->hop_count );
+
+ for ( i = 0; i < MAX_XBP_CASC_LVL; i++ )
+ printf( "%02X ", p_addr->addr[i] );
+
+ printf( ", state: %i", p_ni->state );
+
+ printf( ", name: \"%s\"", p_ri->model_name );
+
+ printf( "\n" );
+
+} // handle_xbp_node
+
+
+
+/*HDR*/
+/**
+ * @brief Read the ::XBP_NODE_INFO for a specific node in ::XBP_NODE_INFO_IDX format
+ * //##+++++++++++++++++++++++++
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr )
+{
+ static int recursion_count;
+
+ XBP_NODE_LIMITS node_limits;
+ int rc = MBG_SUCCESS;
+ int16_t i;
+
+ // This function can be called recursively, so first of all check the recursion level.
+ if ( recursion_count > MAX_XBP_CASC_LVL ) //##++++ TODO: or even ">=" ??
+ {
+ // This should never happen, but we check this anyway.
+ rc = MBG_ERR_XBP_CASC_LVL;
+ goto out;
+ }
+
+ recursion_count++;
+
+ rc = mbgextio_get_xbp_node_limits( pmctl, p_addr, &node_limits );
+
+ if ( rc != MBG_SUCCESS )
+ goto out_dec;
+
+ for ( i = 0; i < node_limits.node_count; i++ )
+ {
+ XBP_NODE_INFO_IDX node_info_idx;
+
+ rc = mbgextio_get_xbp_node_info_idx( pmctl, p_addr, &node_info_idx, i );
+
+ if ( rc != MBG_SUCCESS )
+ break;
+
+ #if 1 && DEBUG
+ if ( (ulong) node_info_idx.idx != (ulong) i )
+ printf( "** Warning: received XBP index %li for idx %li in %s\n",
+ (ulong) node_info_idx.idx, (ulong) i, __func__ );
+ #endif
+
+ handle_xbp_node( &node_info_idx.node_info, node_info_idx.idx );
+ }
+
+out_dec:
+ if ( recursion_count > 0 )
+ recursion_count--;
+ else
+ {
+ // recursion count is unexpectedly 0
+ }
+
+out:
+ return rc;
+
+} // mbgextio_setup_xbp_node_list
+
+
+
+/*HDR*/
+/**
+ * @brief Read a ::UTC parameter structure from a device.
+ *
+ * The ::UTC parameter structure contains the current UTC/GPS time offset
+ * as well as information on an eventually upcoming leap second.
+ *
+ * @note Only supported by GPS/GNSS and some PZF receivers //##+++++++ TODO Associated feature flag?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_utc_param
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, UTC *p )
+{
+ int rc = mbgextio_req_data( pmctl, p_addr, GPS_UTC );
+
+ if ( ( rc == MBG_SUCCESS ) && p )
+ {
+ *p = pmctl->rcv.pmb->u.msg_data.utc;
+ _mbg_swab_utc_parm( p );
+ }
+
+ return rc;
+
+} // mbgextio_get_utc_param
+
+
+
+/*HDR*/
+/**
+ * @brief Write a ::UTC parameter structure to a device.
+ *
+ * The ::UTC parameter structure contains the current UTC/GPS time offset
+ * as well as information on an eventually upcoming leap second.
+ *
+ * @note Only supported by GPS/GNSS and some PZF receivers //##+++++++ TODO Associated feature flag?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_utc_param
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p )
+{
+ GPS_CMD cmd = GPS_UTC | OPT_GPS_ACK_CODE;
+ UTC *p_data = &pmctl->xmt.pmb->u.msg_data.utc;
+
+ #if _USE_MUTEX
+ _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex );
+ #endif
+
+ *p_data = *p;
+ _mbg_swab_utc_parm( p_data );
+
+ return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) );
+
+} // mbgextio_set_utc_param
diff --git a/mbglib/common/mbgextio.h b/mbglib/common/mbgextio.h
index 53a21e6..1fd5b89 100644
--- a/mbglib/common/mbgextio.h
+++ b/mbglib/common/mbgextio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgextio.h 1.8 2011/04/08 11:26:09Z martin REL_M $
+ * $Id: mbgextio.h 1.16.1.11 2015/07/22 16:02:08Z martin TEST martin $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,69 @@
*
* -----------------------------------------------------------------------
* $Log: mbgextio.h $
- * Revision 1.8 2011/04/08 11:26:09Z martin
+ * Revision 1.16.1.11 2015/07/22 16:02:08Z martin
+ * Started to support variable USB endpoint numbers.
+ * Revision 1.16.1.10 2015/07/14 15:10:27 martin
+ * Updated function prototypes.
+ * Revision 1.16.1.9 2015/07/14 13:24:59 martin
+ * Updated function prototypes.
+ * Revision 1.16.1.8.1.10 2015/05/27 09:23:57 daniel
+ * Fixed USB_DIRECT_IO stuff
+ * Revision 1.16.1.8.1.9 2015/05/21 11:01:00 martin
+ * Updated function prototypes.
+ * Revision 1.16.1.8.1.8 2015/05/19 13:20:59 daniel
+ * Preliminary support for USB_DIRECT_IO
+ * Revision 1.16.1.8.1.6 2015/05/13 09:50:51 martin
+ * Added mbgextio_xmt_ack() and mbgextio_xmt_nack().
+ * Revision 1.16.1.8.1.5 2015/04/15 15:36:19 martin
+ * Doxygen fixes.
+ * Revision 1.16.1.8.1.4 2015/03/03 10:14:50 martin
+ * Updated function prototypes.
+ * Revision 1.16.1.8.1.3 2014/11/04 15:09:37 martin
+ * More XBP stuff.
+ * Revision 1.16.1.8.1.2 2014/11/04 11:31:17 martin
+ * Revision 1.16.1.8.1.1 2014/10/30 16:14:07 martin
+ * Started to support XBP addressing.
+ * Revision 1.16.1.8 2014/10/30 16:03:09 martin
+ * Doxygen fixes.
+ * Revision 1.16.1.7 2014/10/30 14:47:06 martin
+ * Support FTDI devices.
+ * Updated USB support.
+ * Updated function prototypes.
+ * Revision 1.16.1.6 2013/11/28 15:51:48Z marvin
+ * Added mbgextio_get_ntp_peer_state_idx.
+ * Revision 1.16.1.5 2013/11/26 16:06:48Z marvin
+ * Added mbgextio_get_ntp_sys_state.
+ * Revision 1.16.1.4 2013/11/21 07:46:52Z marvin
+ * Added mbgextio_xmt_secu_settings.
+ * Revision 1.16.1.3 2013/11/12 12:12:05Z marvin
+ * Changed calls for NTP info and settings.
+ * Revision 1.16.1.2 2013/10/14 08:54:22Z marvin
+ * Added mbgextio_set_ntp_clnt_mode_cfg.
+ * Revision 1.16.1.1 2013/09/25 11:10:10Z marvin
+ * Added support for NTP and PTP.
+ * Revision 1.16 2013/09/10 08:56:35Z marvin
+ * Changed Doxygen comments.
+ * Revision 1.15 2013/09/05 15:11:40Z marvin
+ * Added support for LAN interface setup.
+ * Added support for PTP state.
+ * Added support for XMR.
+ * Added support for NTP info.
+ * Revision 1.14 2013/09/02 15:16:49Z marvin
+ * Added support for XMR (get multi ref info, set multi ref settings)
+ * Revision 1.13 2013/08/28 11:01:42Z marvin
+ * Added read and set tr_distance and gnss_mode.
+ * Revision 1.12 2013/04/11 14:18:47Z Gregoire
+ * new prototypes for sending havequick rx and tx settings to clock
+ * Revision 1.11 2013/02/06 15:44:57Z martin
+ * Updated function prototypes.
+ * Revision 1.10 2013/02/01 15:59:42 martin
+ * Updated function prototypes.
+ * Revision 1.9 2012/10/30 16:19:19 martin
+ * Support USB I/O.
+ * Started to migrate to opaque stuctures.
+ * Updated function prototypes.
+ * Revision 1.8 2011/04/08 11:26:09 martin
* New macros _ttm_time_set_unavail() and _ttm_time_is_avail().
* Revision 1.7 2009/10/02 14:21:08 martin
* Updated function prototypes.
@@ -38,7 +100,10 @@
/* Other headers to be included */
+#include <mbg_arch.h>
#include <gpsserio.h>
+#include <mbggeo.h>
+
#include <time.h>
#ifdef _MBGEXTIO
@@ -48,7 +113,6 @@
#define _ext extern
#endif
-
/* Start of header body */
@@ -71,11 +135,34 @@
#endif // _USE_SERIAL_IO
+#if !_USE_SERIAL_IO_FTDI
+ // just to avoid build errors if USB not supported
+ #define FT_STATUS int
+ #define FT_HANDLE int
+#endif
+
+
+#if !_USE_USB_IO
+ // just to avoid build errors if USB not supported
+ struct usb_device
+ {
+ int dummy;
+ };
+
+ typedef int MBG_USB_DEVICE;
+
+#endif
+
+
#if !defined MBGEXTIO_READ_BUFFER_SIZE
- #if _USE_SOCKET_IO
+ #if _USE_SOCKET_IO || _USE_USB_IO
#define MBGEXTIO_READ_BUFFER_SIZE 1000
#else
- #define MBGEXTIO_READ_BUFFER_SIZE 10
+ #if defined _USE_USB_DIRECT_IO
+ #define MBGEXTIO_READ_BUFFER_SIZE 512 // Max. USB transfer buffer size
+ #else
+ #define MBGEXTIO_READ_BUFFER_SIZE 10
+ #endif
#endif
#endif
@@ -111,57 +198,1965 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
- _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_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_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 ) ;
+ /**
+ * @brief Send security settings for the socket connection
+ *
+ * If new_passwd is not a NULL pointer, the old_passwd
+ * will be overwritten by the new_passwd.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] old_passwd Pointer to the current LAN port password of the device
+ * @param[in] new_passwd Pointer to the new LAN port password for the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_secu_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *old_passwd, const char *new_passwd ) ;
+
+ /**
+ * @brief Open a binary communication channel via a LAN/socket connection
+ *
+ * @param[in] host DNS name or IP address of the target device
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call.
+ * Pointer is set to NULL on error.
+ * @param[in] passwd Password string for the encrypted communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_socket( const char *host, MBG_MSG_CTL **ppmctl, const char *passwd ) ;
+
+ /**
+ * @brief Open a binary communication channel using direct serial I/O
+ *
+ * Commonly used serial parameters are 19200/8N1, see
+ * ::MBG_DEFAULT_BAUDRATE and ::MBG_DEFAULT_FRAMING.
+ * Some newer devices may also support ::MBG_DEFAULT_BAUDRATE_HS.
+ *
+ * @param[in] dev Name of the serial port to which the device is connected,
+ * depending on the naming conventions of the host system.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ * @param[in] baud_rate Baud rate used for serial communication
+ * @param[in] framing Framing used for serial communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_force_conn_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_force_conn_serial_ftdi
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial( const char *dev, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) ;
+
+ /**
+ * @brief Get the port handle of a serial FTDI device
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return the port handle retrieved from the message control structure
+ */
+ _NO_MBG_API_ATTR FT_HANDLE _MBG_API mbgextio_get_serial_ftdi_port_handle( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Open a binary communication channel using serial FTDI D2xx port
+ *
+ * Commonly used serial parameters are 19200/8N1, see
+ * ::MBG_DEFAULT_BAUDRATE and ::MBG_DEFAULT_FRAMING.
+ * Some newer devices may also support ::MBG_DEFAULT_BAUDRATE_HS.
+ *
+ * @param[in] device_num device number from a list set up by FT_ListDevices()
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ * @param[in] baud_rate Baud rate used for serial communication
+ * @param[in] framing Framing used for serial communication
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_force_conn_serial_ftdi
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_force_conn_serial
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) ;
+
+ /**
+ * @brief Open a binary communication channel using direct USB I/O
+ *
+ * @param[in] usbdev The USB device to communicate with.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_close_connection
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEVICE *usbdev, MBG_MSG_CTL **ppmctl ) ;
+
+ /**
+ * @brief Open a binary communication channel using direct USB I/O
+ *
+ * Currently it is only supported by Linux systems since a file like
+ * USB device (e.g. "/dev/mbgims") is required and needs to support
+ * basic I/O operations like write, read, etc...
+ *
+ * @param[in] dev Path to file like USB device
+ * @param[in] flags Bitwise OR flags of access modes like W,RW,RO,etc.
+ * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure
+ * allocated and set up by this call. Set to NULL on error.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ * @see ::mbgextio_close_connection
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb_direct_io( const char *dev, int flags, MBG_MSG_CTL **ppmctl ) ;
+
+ /**
+ * @brief Close a binary communication channel and release resources
+ *
+ * Closes a binary communication channel which has been opened by one
+ * of the mbgextio_open_...() functions and releases the buffers which
+ * have been allocated when the channel was opened.
+ *
+ * The pointer to the message control structure passed by address is set
+ * to NULL after the channel has been closed and the resources have
+ * been released.
+ *
+ * @param[in,out] ppmctl Address of a pointer to a message control structure
+ * created when the communication channel was opened
+ * by one of the mbgextio_open_...() calls.
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_socket
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ * @see ::mbgextio_open_usb
+ * @see ::mbgextio_open_usb_direct_io
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_close_connection( MBG_MSG_CTL **ppmctl ) ;
+
+ /**
+ * @brief Try to force a serial connection to a device
+ *
+ * A device's serial port may have been configured to work by default
+ * in a way which is not appropriate for binary communication, e.g. using
+ * a low communication speed, or some framing like "7E2" which messes up
+ * binary data since the parity bit overrides a data bit.
+ *
+ * This function sends a special ASCII string to a device which lets the device
+ * temporarily switch to a specific baud rate and 8N1 framing which is usually
+ * used for binary communication, see ::MBG_DEFAULT_BAUDRATE,
+ * ::MBG_DEFAULT_BAUDRATE_HS, and ::MBG_DEFAULT_FRAMING.
+ *
+ * Since the current settings of the device's serial port are unknown this
+ * this command is sent in all common combinations of baud rates and
+ * framings.
+ *
+ * If the connected device supports this it should be possible to open
+ * the serial communication channel using the default parameters after
+ * this function has finished.
+ *
+ * @param[in] dev Name of the serial port to which the device is connected,
+ * depending on the naming conventions of the target system
+ *
+ * @return One of the negative @ref MBG_ERROR_CODES on error,
+ * else the determined baud rate.
+ *
+ * @see ::mbgextio_open_serial
+ * @see ::mbgextio_open_serial_ftdi
+ */
+ _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial( const char *dev ) ;
+
+ /**
+ * @brief Try to force a serial connection to a device via the FTDI API
+ *
+ * A device's serial port may have been configured to work by default
+ * in a way which is not appropriate for binary communication, e.g. using
+ * a low communication speed, or some framing like "7E2" which messes up
+ * binary data since the parity bit overrides a data bit.
+ *
+ * This function sends a special ASCII string to a device which lets the device
+ * temporarily switch to a specific baud rate and 8N1 framing which is usually
+ * used for binary communication, see ::MBG_DEFAULT_BAUDRATE,
+ * ::MBG_DEFAULT_BAUDRATE_HS, and ::MBG_DEFAULT_FRAMING.
+ *
+ * Since the current settings of the device's serial port are unknown this
+ * this command is sent in all common combinations of baud rates and
+ * framings.
+ *
+ * If the connected device supports this it should be possible to open
+ * the serial communication channel using the default parameters after
+ * this function has finished.
+ *
+ * @param[in] device_num device number from a list set up by FT_ListDevices()
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_open_serial_ftdi
+ */
+ _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial_ftdi( int device_num ) ;
+
+ /**
+ * @brief Retrieve address of the allocated receive buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Address of the allocated receive buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+ _NO_MBG_API_ATTR MBG_MSG_BUFF * _MBG_API mbgextio_get_rcv_buffer_addr( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Retrieve size of the allocated receive buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Size of the allocated receive buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_addr
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+ _NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_rcv_buffer_size( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Retrieve address of the allocated transmit buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Address of the allocated transmit buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_size
+ */
+ _NO_MBG_API_ATTR MBG_MSG_BUFF * _MBG_API mbgextio_get_xmt_buffer_addr( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Retrieve size of the allocated transmit buffer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Size of the allocated transmit buffer
+ *
+ * @see ::mbgextio_get_rcv_buffer_addr
+ * @see ::mbgextio_get_rcv_buffer_size
+ * @see ::mbgextio_get_xmt_buffer_addr
+ */
+ _NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_xmt_buffer_size( MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Set character receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] new_timeout New timeout value [ms]
+ *
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+ _NO_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ;
+
+ /**
+ * @brief Get character receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Current timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Set message receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] new_timeout New timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_get_msg_rcv_timeout
+ */
+ _NO_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ;
+
+ /**
+ * @brief Get message receive timeout value
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ *
+ * @return Current timeout value [ms]
+ *
+ * @see ::mbgextio_set_char_rcv_timeout
+ * @see ::mbgextio_get_char_rcv_timeout
+ * @see ::mbgextio_set_msg_rcv_timeout
+ */
+ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) ;
+
+ /**
+ * @brief Generic reception of a binary message
+ *
+ * @note A certain message type to be waited for can be specified by
+ * passing one of the ::GPS_CMD_CODES.
+ * If the special cmd code ::GPS_WILDCARD is specified the function returns
+ * successfully after *any* type of binary message has been received.
+ *
+ * //##++ TODO: callback function to handle asynchronous spontaneous messages
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_msg //##++++
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ;
+
+ /**
+ * @brief Set up and send a generic binary message
+ *
+ * @note This function should preferably be used only as low level function
+ * called from within more specific functions used to send specific data.
+ * If this function is called directly with a buffer to be sent then the
+ * transmit mutex is acquired by this function. However, other (higher level)
+ * API functions which set up the transmit buffer directly have to acquire
+ * the transmit mutex by themselves before they set up the transmit buffer,
+ * and pass a NULL pointer to indicate the transmit buffer has already been
+ * set up. The correct number of bytes to send (n_bytes) has to be specified
+ * anyway, though.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] p Address of a data structure according to the specified cmd parameter, or NULL
+ * @param[in] n_bytes Size of the data structure addressed by parameter p
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, const void *p, uint16_t n_bytes ) ;
+
+ /**
+ * @brief Transmit a command-only message without additional data.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ;
+
+ /**
+ * @brief Transmit a message without a single ushort (uint16_t) parameter
+ *
+ * The ushort parameter is often used to send an index value when requesting
+ * a certain element of an array of same data structures.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] us The ushort parameter for the command code
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_req_data_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us ) ;
+
+ /**
+ * @brief Transmit a message without a single ushort (16 bit) parameter
+ *
+ * The ushort parameter is often used to send an index value when requesting
+ * a specific element of an array of data structures.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_xmt_cmd_us
+ * @see ::mbgextio_req_data_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ;
+
+ /**
+ * @brief Read a specific element of an array of data structures
+ *
+ * The type of data is implicitely associated with the cmd parameter.
+ * Usually the number of supported array elements has to be determined
+ * by some other means, e.g. from a field in the ::RECEIVER_INFO structure.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES
+ * @param[in] idx The index of the array element to read
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_xmt_msg
+ * @see ::mbgextio_rcv_msg
+ * @see ::mbgextio_xmt_cmd
+ * @see ::mbgextio_req_data
+ * @see ::mbgextio_xmt_cmd_us
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t idx ) ;
+
+ /**
+ * @brief Read a receiver info structure
+ *
+ * The ::RECEIVER_INFO should be read at first to identify the connected
+ * device and determine the basic features supported by the device.
+ *
+ * @note Some very old devices may not provide a ::RECEIVER_INFO,
+ * so ::mbgextio_setup_receiver_info should be called preferably
+ * to read the receiver info using this function, if supported,
+ * or set up a default structure for devices which don't provide
+ * a receiver info.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_setup_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_INFO *p ) ;
+
+ /**
+ * @brief Setup a receiver info structure
+ *
+ * The ::RECEIVER_INFO should be read at first to identify the connected
+ * device and determine the basic features supported by the device.
+ *
+ * @note Some very old devices may not provide a ::RECEIVER_INFO.
+ * This function tries to read the ::RECEIVER_INFO from the device,
+ * and sets up a default structure if the device doesn't support this.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_receiver_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_INFO *p ) ;
+
+ /**
+ * @brief Read the software revision
+ *
+ * @deprecated This function is deprecated since the ::SW_REV structure
+ * is also a member of the ::RECEIVER_INFO. This call may be required,
+ * though, for very old devices which don't support the ::RECEIVER_INFO.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_setup_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SW_REV *p ) ;
+
+ /**
+ * @brief Read the status of buffered variables
+ *
+ * @note Only supported if ::GPS_MODEL_HAS_BVAR_STAT
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, BVAR_STAT *p ) ;
+
+ /**
+ * @brief Read the current time as ::TTM strucure
+ *
+ * @note This function is only supported by GPS receivers.
+ *
+ * The returned time is not very accurate since the response time
+ * transmission delay can't be determmined.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TTM *p ) ;
+
+ /**
+ * @brief Set the device's time by sending a ::TTM strucure
+ *
+ * @note The function is not supported by all devices. Time has to be
+ * passed as local time according to the device's ::TZDL settings.
+ * New time is only set with some tens of ms accuracy.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const TTM *p ) ;
+
+ /**
+ * @brief Set the device's position by sending an ::LLA array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] lla Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const LLA lla ) ;
+
+ /**
+ * @brief Read the current receiver position as ::LLA array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] lla Pointer to the data array to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, LLA lla ) ;
+
+ /**
+ * @brief Read the current receiver position as ::XYZ array
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] xyz Pointer to the data array to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_xyz( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XYZ xyz ) ;
+
+ /**
+ * @brief Read the current receiver position as ::POS structure
+ *
+ * @note This function is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p_pos Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POS *p_pos ) ;
+
+ /**
+ * @brief Read the local time conversion parameters in ::TZDL format
+ *
+ * @note Some devices may not support ::TZDL settings
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TZDL *p ) ;
+
+ /**
+ * @brief Set the local time conversion parameters in ::TZDL format
+ *
+ * @note Some devices may not support ::TZDL settings
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const TZDL *p ) ;
+
+ /**
+ * @brief Read serial port parameters in ::PORT_PARM format
+ *
+ * @deprecated This function is deprecated since the ::PORT_PARM structure
+ * supports only 2 serial ports, and does not not support configuration
+ * of a string type. The function ::mbgextio_get_serial_settings should
+ * be used instead.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_set_port_parm
+ * @see ::mbgextio_setup_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_PARM *p ) ;
+
+ /**
+ * @brief Send serial port parameters in ::PORT_PARM format
+ *
+ * @deprecated This function is deprecated since the ::PORT_PARM structure
+ * supports only 2 serial ports, and does not not support configuration
+ * of a string type. The function ::mbgextio_save_serial_settings should
+ * be used instead.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_serial_settings
+ * @see ::mbgextio_save_serial_settings
+ * @see ::mbgextio_get_port_parm
+ * @see ::mbgextio_setup_receiver_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const PORT_PARM *p ) ;
+
+ /**
+ * @brief Read the frequency synthesizer settings
+ *
+ * @note Some devices may not provide a frequency synthesizer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_synth
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SYNTH *p ) ;
+
+ /**
+ * @brief Write the frequency synthesizer settings
+ *
+ * @note Some devices may not provide a frequency synthesizer
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_synth
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const SYNTH *p ) ;
+
+ /**
+ * @brief Read the GPS antenna info structure
+ *
+ * @note This is only supported by GPS receivers.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ANT_INFO *p ) ;
+
+ /**
+ * @brief Read a user capture event in ::TTM format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_ucap_buff
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TTM *p ) ;
+
+ /**
+ * @brief Read the enable flags controlling when output signals are enabled
+ *
+ * @note Some devices may not support ::ENABLE_FLAGS
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_enable_flags
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ENABLE_FLAGS *p ) ;
+
+ /**
+ * @brief Send the enable flags controlling when output signals are enabled
+ *
+ * @note Some devices may not support ::ENABLE_FLAGS
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_enable_flags
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ENABLE_FLAGS *p ) ;
+
+ /**
+ * @brief Read GPS status info
+ *
+ * @note This is only supported by GPS receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STAT_INFO *p ) ;
+
+ /**
+ * @brief Read the configured length of the antenna cable
+ *
+ * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+ *
+ * @note Some older devices may not reply to this request unless
+ * the application has registered itself as terminal application
+ * (GPS_AUTO_ON is not sufficient).
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ant_cable_len
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ANT_CABLE_LEN *p ) ;
+
+ /**
+ * @brief Send the GPS antenna cable length configuration
+ *
+ * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+
+ * @note Different devices may accept different maximum values, so the
+ * written value should be re-read using ::mbgextio_get_ant_cable_len
+ * to check if the parameter has been accepted.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ant_cable_len
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ANT_CABLE_LEN *p ) ;
+
+ /**
+ * @brief Read configuration info and supported features of the device's IRIG output
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_TX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_irig_tx_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IRIG_INFO *p ) ;
+
+ /**
+ * @brief Send new configuration settings for the device's IRIG output
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_TX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_irig_tx_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IRIG_SETTINGS *p ) ;
+
+ /**
+ * @brief Read configuration info and supported features for the device's IRIG input
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_RX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_irig_rx_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IRIG_INFO *p ) ;
+
+ /**
+ * @brief Send new configuration settings for the device's IRIG input
+ *
+ * @note This is only supported if ::GPS_HAS_IRIG_RX is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_irig_rx_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IRIG_SETTINGS *p ) ;
+
+ /**
+ * @brief Read current ref offset to %UTC configuration
+ *
+ * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ref_offs
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_REF_OFFS *p ) ;
+
+ /**
+ * @brief Send new ref offset to %UTC settings
+ *
+ * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ref_offs
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_REF_OFFS *p ) ;
+
+ /**
+ * @brief Read current debug status
+ *
+ * @note This is only supported if ::GPS_HAS_DEBUG_STATUS is set in ::RECEIVER_INFO::features,
+ * usually with IRIG receivers
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_DEBUG_STATUS *p ) ;
+
+ /**
+ * @brief Read current optional settings and supported options
+ *
+ * @note This is only supported if ::GPS_HAS_OPT_SETTINGS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_opt_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_OPT_INFO *p ) ;
+
+ /**
+ * @brief Send new optional settings flags
+ *
+ * @note This is only supported if ::GPS_HAS_OPT_SETTINGS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_opt_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_OPT_SETTINGS *p ) ;
+
+ /**
+ * @brief Read information on a specific supported string format
+ *
+ * Retrieve a single entry from an array of supported string types.
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_str_type_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read an array of all supported string types
+ *
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_str_type_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Read current settings and capabilities of a specific serial port
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_com_ports - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_port_info
+ * @see ::mbgextio_set_port_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_INFO_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read an array of current settings and capabilities of all serial ports
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_com_ports entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_port_info_idx
+ * @see ::mbgextio_set_port_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_INFO_IDX pii[], const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Send configuration settings for a specific serial port
+ *
+ * The number of serial ports provided by the device is specified in ::RECEIVER_INFO::n_com_ports.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::RECEIVER_INFO::n_com_ports - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_port_info_idx
+ * @see ::mbgextio_get_all_port_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const PORT_SETTINGS *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read current settings and capabilities of a specific programmable pulse output
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_prg_out - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_all_pout_info
+ * @see ::mbgextio_set_pout_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POUT_INFO_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read an array of current settings and capabilities of all programmable pulse outputs
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_prg_out entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_pout_info_idx
+ * @see ::mbgextio_set_pout_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POUT_INFO_IDX *pii, const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Send configuration settings for a specific programmable pulse output
+ *
+ * The number of supported pulse outputs is specified in ::RECEIVER_INFO::n_prg_out.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the pulse output to be configured, 0..RECEIVER_INFO::n_prg_out - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_pout_info_idx
+ * @see ::mbgextio_get_all_pout_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const POUT_SETTINGS *p, uint16_t idx ) ;
+
+ /**
+ * @brief Clear the user capture event buffer on-board the device
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ucap
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ;
+
+ /**
+ * @brief Read time scale configuration parameters
+ *
+ * @note Some devices may not support a configurable time scale
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_time_scale_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TIME_SCALE_INFO *p ) ;
+
+ /**
+ * @brief Send new time scale configuration settings
+ *
+ * @note Some devices may not support a configurable time scale
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_time_scale_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_TIME_SCALE_SETTINGS *p ) ;
+
+ /**
+ * @brief Clear the on-board event log
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_first_evt_log_entry
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_clr_evt_log( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ;
+
+ /**
+ * @brief Read the current number of entries in the on-board event log
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_first_evt_log_entry
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_num_evt_log_entries( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NUM_EVT_LOG_ENTRIES *p ) ;
+
+ /**
+ * @brief Return the first entry from the on-board event log
+ *
+ * This resets an internal counter, so subsequent calls to
+ * ::mbgextio_get_next_evt_log_entry will retrieve the following entries.
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_next_evt_log_entry
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_first_evt_log_entry( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p ) ;
+
+ /**
+ * @brief Return the next entry from the on-board event log
+ *
+ * This increments an internal counter, so subsequent calls will
+ * return subsequent entries. ::mbgextio_get_first_evt_log_entry
+ * should be called first to reset the counter and retrieve the
+ * oldest log entry.
+ *
+ * @note Some devices don't provide an on-board event log
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_clr_evt_log
+ * @see ::mbgextio_get_num_evt_log_entries
+ * @see ::mbgextio_get_first_evt_log_entry
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_next_evt_log_entry( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p ) ;
+
+ /**
+ * @brief Read the current IMS state and supported IMS features
+ *
+ * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ims_sensor_state_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_STATE *p ) ;
+
+ /**
+ * @brief Read sensor values from a specified sensor on the device
+ *
+ * Info on supported sensors can be retrieved using ::mbgextio_get_ims_state.
+ * Valid range for the sensor index is [0..::MBG_IMS_STATE::num_sensors - 1].
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx The index of the array element to read
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ims_state
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_sensor_state_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_SENSOR_STATE_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Set the XMR holdover interval
+ *
+ * @todo In which case is this supported?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_holdover_interval_counter
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_holdover_interval( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const XMR_HOLDOVER_INTV *p ) ;
+
+ /**
+ * @brief Read the XMR holdover interval counter
+ *
+ * @todo In which case is this supported?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_holdover_interval
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_HOLDOVER_INTV *p ) ;
+
+ /**
+ * @brief Read the local time conversion configuration in ::TZCODE format
+ *
+ * @note Some devices may not support ::TZCODE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_tzcode
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzcode( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TZCODE *p ) ;
+
+ /**
+ * @brief Set the local time conversion configuration in ::TZCODE format
+ *
+ * @note Some devices may not support ::TZCODE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_tzcode
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzcode( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const TZCODE *p ) ;
+
+ /**
+ * @brief Send new configuration settings for the device's HAVEQUICK output
+ *
+ * @note This is only supported if ::GPS_HAS_HAVEQUICK is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) ;
+
+ /**
+ * @brief Send new configuration settings for the device's HAVEQUICK input
+ *
+ * @note This is only supported if ::MULTI_REF_HAVEQUICK is > 0 in ::XMULTI_REF_INSTANCES::n_inst //##+++++++++++++++++++++++ ???
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the distance from transmitter ::TR_DISTANCE format
+ *
+ * @note Some devices may not support ::TR_DISTANCE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_tr_distance
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tr_distance( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TR_DISTANCE *p ) ;
+
+ /**
+ * @brief Set the transmitter distance (km) in ::TR_DISTANCE format
+ *
+ * @note Some devices may not support ::TR_DISTANCE configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_tr_distance
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tr_distance( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const TR_DISTANCE *p ) ;
+
+ /**
+ * @brief Read current GNSS mode settings and supported features
+ *
+ * @note Some devices may not support GNSS configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_gnss_mode_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_GNSS_MODE_INFO *p ) ;
+
+ /**
+ * @brief Write GNSS mode settings
+ *
+ * @note Some devices may not support GNSS configuration
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[in] p Pointer to a ::MBG_GNSS_MODE_SETTINGS structure to be sent
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_gnss_mode_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_gnss_mode_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_GNSS_MODE_SETTINGS *p ) ;
+
+ /**
+ * @brief Read an array of all supported string types //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO
+ *
+ * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_str_type_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Fill up a GNSS info structure //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[out] p_si Pointer to a ::STAT_INFO the data structure to return the received data
+ * @param[out] p_gmi Index of the NTP peer state to be configured, 0..::NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ * @param[out] p_gsii Blah ... //##++++++++++ TODO
+ * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_sys_state
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+ int mbgextio_chk_get_gnss_info( MBG_MSG_CTL *pmctl, STAT_INFO *p_si, MBG_GNSS_MODE_INFO *p_gmi, GNSS_SAT_INFO_IDX *p_gsii, const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Read the supported XMR features in ::XMULTI_REF_INFO_IDX format
+ *
+ * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xmr_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p ) ;
+
+ /**
+ * @brief Read the supported XMR features ::XMULTI_REF_STATUS_IDX format
+ *
+ * @note Only for devices which supports Multi references
+ * @note GPS_HAS_XMULTI_REF feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xmr_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_STATUS_IDX *p ) ;
+
+ /**
+ * @brief Save the supported XMR features ::XMULTI_REF_INFO_IDX format
+ *
+ * @note Some devices may not support Multi Refernce Sources
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const XMULTI_REF_SETTINGS_IDX *p ) ;
+
+ /**
+ * @brief Read the lan interface configuration ::LAN_IF_INFO format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lan_if_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, LAN_IF_INFO *p ) ;
+
+ /**
+ * @brief Read the lan ipv4 configuration state ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IP4_SETTINGS *p ) ;
+
+ /**
+ * @brief Save the current ipv4 settings ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ip4_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IP4_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the current lan ipv4 state ::IP4_SETTINGS format
+ *
+ * @note ptp or xmr with ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IP4_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the current state of PTP device ::PTP_STATE format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_STATE *p ) ;
+
+ /**
+ * @brief Read the ptp configuration ::PTP_CFG_INFO format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_CFG_INFO *p ) ;
+
+ /**
+ * @brief Read the ptp configuration ::PTP_UC_MASTER_CFG_LIMITS format
+ *
+ * @note ptp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_uc_master_cfg_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_UC_MASTER_CFG_LIMITS *p ) ;
+
+ /**
+ * @brief Read the ptp configuration ::ALL_PTP_UC_MASTER_INFO_IDX format
+ *
+ * @note ptp feature must set and read number of ptp unicast masters before.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] ptp_uc_master_info_idx Pointer to an array of ::PTP_UC_MASTER_INFO_IDX structures to be filled up
+ * @param[in] ptp_uc_master_cfg_limits Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure read before
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see //##+++++++++++++ TODO
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_uc_master_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_UC_MASTER_INFO_IDX *ptp_uc_master_info_idx, const PTP_UC_MASTER_CFG_LIMITS *ptp_uc_master_cfg_limits ) ;
+
+ /**
+ * @brief Send configuration settings for PTP
+ *
+ * @note This is only supported by PTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ptp_cfg_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const PTP_CFG_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the ntp global information ::NTP_GLB_INFO format
+ *
+ * @note ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_GLB_INFO *p ) ;
+
+ /**
+ * @brief Send the NTP global configuration
+ *
+ * @note This is only supported by NTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ant_cable_len
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_GLB_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the ntp global information ::NTP_CLNT_MODE_INFO format
+ *
+ * @note ntp feature must set
+ * @note ntp client mode must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_set_ntp_clnt_mode_cfg
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_clnt_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_CLNT_MODE_INFO *p ) ;
+
+ /**
+ * @brief Send the NTP client mode configuration
+ *
+ * @note This is only supported by NTP devices
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_clnt_mode_cfg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_CLNT_MODE_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the ntp peer settings of current idx ::NTP_PEER_SETTINGS format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the NTP peer settings to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_set_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_PEER_SETTINGS_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Send configuration settings for a specific NTP peer
+ *
+ * The number of supported NTP peers is specified in ::NTP_CLNT_MODE_INFO::n_supp_peers -1.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the NTP peer to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_glb_info
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_PEER_SETTINGS *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the current system state of ntp device ::NTP_SYS_STATE format
+ *
+ * @note ntp feature must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_ntp_clnt_mode_cfg
+ * @see ::mbgextio_get_ntp_glb_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_sys_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SYS_STATE *p ) ;
+
+ /**
+ * @brief Read the NTP peer state of current idx ::NTP_PEER_STATE format
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the NTP peer state to be configured, 0 ... NTP_CLNT_MODE_INFO::n_supp_peers - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_ntp_sys_state
+ * @see ::mbgextio_get_ntp_peer_settings_idx
+ * @see ::mbgextio_get_ntp_clnt_mode_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_state_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_PEER_STATE_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the network global config information ::MBG_NET_GLB_CFG_INFO format
+ *
+ * @note GPS_HAS_NET_CFG must set
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_glb_cfg_settings
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_glb_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_GLB_CFG_INFO *p ) ;
+
+ /**
+ * @brief Set the device's global network configuration settings
+ *
+ * @note The function is not supported by all devices. //##++++++++++++
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_glb_cfg_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_GLB_CFG_SETTINGS *p ) ;
+
+ /**
+ * @brief Read the network dns server ::MBG_IP_ADDR_IDX format
+ *
+ * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srvr_idx
+ * @see ::mbgextio_get_net_stat_dns_srvr_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Send the network DNS server address in ::MBG_IP_ADDR format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srvr_idx
+ * @see ::mbgextio_get_net_stat_dns_srvr_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_IP_ADDR *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the network DNS search domain in ::MBG_NET_NAME_IDX format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srch_dom_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Send the network DNS search domain in ::MBG_NET_NAME format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srch_dom_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_NAME *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the current network DNS server in ::MBG_IP_ADDR_IDX format
+ *
+ * The number of DNS servers supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_net_dns_srvr_idx
+ * @see ::mbgextio_set_net_dns_srvr_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srvr_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the current network DNS search domain in ::MBG_NET_NAME_IDX format
+ *
+ * The number of DNS search domains supported by the device
+ * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_net_dns_srch_dom_idx
+ * @see ::mbgextio_get_net_dns_srch_dom_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the ::XBP_LIMITS to check which XBP features are supported
+ *
+ * @note Only supported if ::GPS_HAS_XBP is set in ::RECEIVER_INFO::features
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_node_limits
+ * @see ::mbgextio_get_xbp_node_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_LIMITS *p ) ;
+
+ /**
+ * @brief Read the ::XBP_NODE_LIMITS to check how many ports are provided
+ *
+ * @note Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_limits
+ * @see ::mbgextio_get_xbp_node_info_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_NODE_LIMITS *p ) ;
+
+ /**
+ * @brief Read the ::XBP_NODE_INFO for a specific node in ::XBP_NODE_INFO_IDX format
+ *
+ * The supported number of nodes is provided by ::XBP_NODE_LIMITS::node_count.
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ * @param[in] idx Index of the array element to be retrieved, 0..::XBP_NODE_LIMITS::node_count-1
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_xbp_limits
+ * @see ::mbgextio_get_xbp_node_limits
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_NODE_INFO_IDX *p, uint16_t idx ) ;
+
+ /**
+ * @brief Read the ::XBP_NODE_INFO for a specific node in ::XBP_NODE_INFO_IDX format
+ * //##+++++++++++++++++++++++++
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ;
+
+ /**
+ * @brief Read a ::UTC parameter structure from a device.
+ *
+ * The ::UTC parameter structure contains the current UTC/GPS time offset
+ * as well as information on an eventually upcoming leap second.
+ *
+ * @note Only supported by GPS/GNSS and some PZF receivers //##+++++++ TODO Associated feature flag?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to return the received data
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_set_utc_param
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, UTC *p ) ;
+
+ /**
+ * @brief Write a ::UTC parameter structure to a device.
+ *
+ * The ::UTC parameter structure contains the current UTC/GPS time offset
+ * as well as information on an eventually upcoming leap second.
+ *
+ * @note Only supported by GPS/GNSS and some PZF receivers //##+++++++ TODO Associated feature flag?
+ *
+ * @param[in,out] pmctl Pointer to a valid message control structure
+ * @param[in] p_addr Pointer to an XBP address specifier, or NULL
+ * @param[out] p Pointer to the data structure to be sent to the device
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_get_utc_param
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p ) ;
+
/* ----- function prototypes end ----- */
diff --git a/mbglib/common/mbggeo.h b/mbglib/common/mbggeo.h
index ca6414d..c3bdb40 100644
--- a/mbglib/common/mbggeo.h
+++ b/mbglib/common/mbggeo.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbggeo.h 1.10 2008/09/03 14:54:28Z martin REL_M $
+ * $Id: mbggeo.h 1.11 2011/06/22 10:18:10Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -22,7 +22,9 @@
*
* -----------------------------------------------------------------------
* $Log: mbggeo.h $
- * Revision 1.10 2008/09/03 14:54:28Z martin
+ * Revision 1.11 2011/06/22 10:18:10Z martin
+ * Cleaned up handling of pragma pack().
+ * 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.
@@ -62,8 +64,9 @@
/* Start of header body */
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
#endif
@@ -284,8 +287,9 @@ extern "C" {
#endif
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
#endif
/* End of header body */
diff --git a/mbglib/common/mbgmutex.h b/mbglib/common/mbgmutex.h
index 0a35494..700a73b 100644
--- a/mbglib/common/mbgmutex.h
+++ b/mbglib/common/mbgmutex.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgmutex.h 1.1 2011/04/15 12:26:59Z martin REL_M $
+ * $Id: mbgmutex.h 1.3.1.2 2014/03/04 12:08:12Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,17 @@
*
* -----------------------------------------------------------------------
* $Log: mbgmutex.h $
- * Revision 1.1 2011/04/15 12:26:59Z martin
+ * Revision 1.3.1.2 2014/03/04 12:08:12Z martin
+ * Revision 1.3.1.1 2014/01/08 17:20:57Z martin
+ * MBG_TGT_POSIX
+ * Revision 1.3 2013/04/11 13:46:58 martin
+ * Use non-specific spinlock function under Windows.
+ * Revision 1.2 2012/03/08 12:19:01Z martin
+ * Fixes for Linux kernel and FreeBSD.
+ * Fixed build under DOS and QNX usinc dummy defines.
+ * Don't define macros for semaphore destroy functions
+ * if not required/supported on the target OS.
+ * Revision 1.1 2011/04/15 12:26:59 martin
* Initial revision.
*
**************************************************************************/
@@ -41,16 +51,16 @@
typedef KSPIN_LOCK MBG_SPINLOCK;
#define _mbg_spin_lock_init( _spl ) KeInitializeSpinLock( _spl )
- #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
- #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLockAtDpcLevel( _spl )
- #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLockFromDpcLevel( _spl )
+ // _mbg_spin_lock_destroy is not supported
+ #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLock( _spl, &OldIrql )
+ #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLock( _spl, OldIrql )
- #define MBG_SPINLOCK_DEFINED 1
+ #define _MBG_SPINLOCK_DEFINED 1
typedef FAST_MUTEX MBG_MUTEX;
#define _mbg_mutex_init( _pmtx ) ExInitializeFastMutex( _pmtx )
- #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc()
+ // _mbg_mutex_destroy( _pmtx ) is not supported
#define _mbg_mutex_acquire( _pmtx ) ExAcquireFastMutex( _pmtx )
#define _mbg_mutex_release( _pmtx ) ExReleaseFastMutex( _pmtx )
@@ -59,20 +69,26 @@
#elif defined( MBG_TGT_LINUX ) // Linux kernel space
#include <linux/spinlock.h>
- #include <asm/semaphore.h>
+ #include <linux/version.h>
+
+ #if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 26 ) )
+ #include <linux/semaphore.h>
+ #else
+ #include <asm/semaphore.h>
+ #endif
typedef spinlock_t MBG_SPINLOCK;
#define _mbg_spin_lock_init( _spl ) spin_lock_init( _spl )
- #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
+ // _mbg_spin_lock_destroy is not supported
#define _mbg_spin_lock_acquire( _spl ) spin_lock( _spl )
#define _mbg_spin_lock_release( _spl ) spin_unlock( _spl )
- #define MBG_SPINLOCK_DEFINED 1
+ #define _MBG_SPINLOCK_DEFINED 1
typedef struct semaphore MBG_MUTEX;
#define _mbg_mutex_init( _pmtx ) sema_init( _pmtx, 1 )
- #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc()
+ // _mbg_mutex_destroy( _pmtx ) is not supported
#define _mbg_mutex_acquire( _pmtx ) down_interruptible( _pmtx )
#define _mbg_mutex_release( _pmtx ) up( _pmtx )
@@ -80,6 +96,7 @@
#elif defined( MBG_TGT_FREEBSD ) // FreeBSD kernel space
+ #include <sys/lock.h>
#include <sys/mutex.h>
typedef struct mtx MBG_SPINLOCK;
@@ -88,7 +105,7 @@
#define _mbg_spin_lock_acquire( _spl ) mtx_lock_spin( _spl )
#define _mbg_spin_lock_release( _spl ) mtx_unlock_spin( _spl )
- #define MBG_SPINLOCK_DEFINED 1
+ #define _MBG_SPINLOCK_DEFINED 1
typedef struct mtx MBG_MUTEX;
@@ -112,7 +129,7 @@
#define _mbg_spin_lock_acquire( _spl ) mutex_spin_enter( _spl )
#define _mbg_spin_lock_release( _spl ) mutex_spin_exit( _spl )
- #define MBG_SPINLOCK_DEFINED 1
+ #define _MBG_SPINLOCK_DEFINED 1
typedef kmutex_t MBG_MUTEX;
@@ -129,8 +146,6 @@
#if defined( MBG_TGT_WIN32 ) // Windows user space
- #include <windows.h>
-
// definitions used with mutexes
typedef HANDLE MBG_MUTEX;
#define _mbg_mutex_init( _pm ) *(_pm) = CreateMutex( NULL, FALSE, NULL )
@@ -149,7 +164,7 @@
#define _MBG_CRIT_SECT_DEFINED 1
- #elif defined( MBG_TGT_UNIX ) // Unix user space use pthread library
+ #elif defined( MBG_TGT_POSIX ) // Unix user space use pthread library
#include <pthread.h>
@@ -167,15 +182,21 @@
// For critical sections use defaults specified below
+ #elif defined( MBG_TGT_DOS ) || defined( MBG_TGT_QNX )
+
+ typedef int MBG_MUTEX; // just a dummy declaration
+
+ #define _MBG_MUTEX_DEFINED 1
+
#endif
#endif
-#if !defined( MBG_SPINLOCK_DEFINED )
+#if !defined( _MBG_SPINLOCK_DEFINED )
#define _mbg_spin_lock_init( _spl ) _nop_macro_fnc()
- #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc()
+ // _mbg_spin_lock_destroy is not supported
#define _mbg_spin_lock_acquire( _spl ) _nop_macro_fnc()
#define _mbg_spin_lock_release( _spl ) _nop_macro_fnc()
@@ -189,7 +210,7 @@
typedef MBG_CRIT_SECT MBG_MUTEX;
#define _mbg_mutex_init( _pm ) _nop_macro_fnc()
- #define _mbg_mutex_destroy( _pm ) _nop_macro_fnc()
+ // _mbg_mutex_destroy( _pmtx ) is not supported
#define _mbg_mutex_acquire( _pm ) _nop_macro_fnc()
#define _mbg_mutex_release( _pm ) _nop_macro_fnc()
@@ -203,10 +224,12 @@
#define _MBG_CRIT_SECT_DEFINED 1
typedef MBG_MUTEX MBG_CRIT_SECT;
- #define _mbg_crit_sect_init _mbg_mutex_init
- #define _mbg_crit_sect_destroy _mbg_mutex_destroy
- #define _mbg_crit_sect_enter _mbg_mutex_acquire
- #define _mbg_crit_sect_leave _mbg_mutex_release
+ #define _mbg_crit_sect_init _mbg_mutex_init
+ #if defined( _mbg_mutex_destroy )
+ #define _mbg_crit_sect_destroy _mbg_mutex_destroy
+ #endif
+ #define _mbg_crit_sect_enter _mbg_mutex_acquire
+ #define _mbg_crit_sect_leave _mbg_mutex_release
#endif
diff --git a/mbglib/common/mbgserio.c b/mbglib/common/mbgserio.c
index 04dc045..6f03dac 100644
--- a/mbglib/common/mbgserio.c
+++ b/mbglib/common/mbgserio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgserio.c 1.3 2009/09/01 10:49:30Z martin REL_M $
+ * $Id: mbgserio.c 1.6.1.17 2015/07/22 16:02:52Z martin TEST martin $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,52 @@
*
* -----------------------------------------------------------------------
* $Log: mbgserio.c $
- * Revision 1.3 2009/09/01 10:49:30Z martin
+ * Revision 1.6.1.17 2015/07/22 16:02:52Z martin
+ * Cleanup.
+ * Removed trailing whitespace.
+ * Revision 1.6.1.16 2014/05/27 11:26:24 martin
+ * Revision 1.6.1.15 2014/05/09 11:40:41 marvin
+ * Fixed port_str_list if current port already opened.
+ * Revision 1.6.1.14 2014/03/27 11:48:47Z martin
+ * Revision 1.6.1.13 2014/03/18 10:37:52 martin
+ * Revision 1.6.1.12 2014/03/14 15:41:58Z martin
+ * Revision 1.6.1.11 2014/03/13 14:31:44Z martin
+ * Fixed compiler warnings related to select() call.
+ * Revision 1.6.1.10 2014/03/11 14:08:57Z martin
+ * Revision 1.6.1.9 2014/03/07 13:20:55Z martin
+ * Tmp. saved changes.
+ * Revision 1.6.1.8 2014/03/06 15:25:19 martin
+ * Revision 1.6.1.7 2014/03/04 12:08:12 martin
+ * Revision 1.6.1.6 2014/03/04 11:56:33Z martin
+ * Revision 1.6.1.5 2014/01/31 08:49:00Z marvin
+ * Replaced MBG_ERR_CONNECT_DEF by MBG_ERR_OPEN.
+ * Revision 1.6.1.4 2014/01/08 17:19:41Z martin
+ * MBG_TGT_POSIX
+ * New libusb
+ * Revision 1.6.1.3 2014/01/07 17:00:18 martin
+ * Use common Meinberg error codes.
+ * Revision 1.6.1.2 2013/12/16 10:11:34 marvin
+ * Changed mbgerror return code.
+ * Revision 1.6.1.1 2013/12/13 13:08:19Z marvin
+ * Changed error codes. Get error codes from mbgerror.h
+ * Revision 1.6 2013/04/18 13:50:58Z udo
+ * use O_CLOEXEC on open serial port if defined
+ * Revision 1.5 2013/02/01 16:06:33 martin
+ * Always use mbgserio_read/write rather than the macros.
+ * Got rid of _mbg_open/close/read/write() macros.
+ * Check return code of tcgetattr() when opening port under Linux.
+ * Set up DCB under Windows when opening the port,
+ * not when setting parameters.
+ * Fixed setting up COM port list under Windows.
+ * Flush output on close.
+ * Debug code to test flush under Windows (doesn't seem
+ * to work properly).
+ * New code trying different ways to detect existing ports
+ * reliably under Linux.
+ * Syntax workaround which is required until this module becomes a DLL.
+ * Revision 1.4 2011/07/29 10:12:15 martin
+ * Allow baud rates 115200 and 230400 under Linux, if supported by the OS version.
+ * 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.
@@ -28,21 +73,23 @@
#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>
+#include <mbgerror.h>
-#if defined( MBG_TGT_UNIX )
- #include <unistd.h>
+#if defined( MBG_TGT_POSIX )
#include <fcntl.h>
+ #include <dirent.h>
+ #include <errno.h>
+#endif
+
+
+
+#if defined( MBG_TGT_POSIX )
+ static const char dev_dir[] = "/dev";
#endif
@@ -68,8 +115,8 @@ int v24open( char *portname, int mode );
* 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 O_DIRECT 0x0100 /* open port with direct access to the hardware */
+#define O_HIGHPRIO 0x2000 /* open port with high priority (fastopen) */
#define OPEN_MODE ( O_DIRECT | O_HIGHPRIO )
@@ -106,14 +153,156 @@ int v24close( int port );
+#if defined( MBG_TGT_WIN32 )
+
+static /*HDR*/
+/**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int win32_create_file( const char *dev, HANDLE *ph )
+{
+ static const char prefix[] = "\\\\.\\";
+
+ size_t len = strlen( prefix ) + strlen( dev ) + 1;
+ char *tmp_name;
+ int rc = MBG_ERR_UNSPEC;
+
+ tmp_name = (char *) malloc( len );
+
+ if ( tmp_name == NULL ) // unable to allocate memory
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+
+ strcpy( tmp_name, prefix );
+ strcat( tmp_name, dev );
+
+ *ph = CreateFile( tmp_name, GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, //##++++++++++++++ | FILE_FLAG_WRITE_THROUGH,
+ NULL );
+
+ if ( *ph == INVALID_HANDLE_VALUE )
+ {
+ rc = mbg_win32_last_err_to_mbg( GetLastError(), "CreateFile failed in win32_create_file" );
+ goto out_free;
+ }
+
+ rc = MBG_SUCCESS;
+
+out_free:
+ free( tmp_name );
+
+out:
+ return rc;
+
+} // win32_create_file
+
+#endif // defined( MBG_TGT_WIN32 )
+
+
+
+static /*HDR*/
+/**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgserio_close_port_by_handle( MBG_PORT_HANDLE *p )
+{
+ if ( *p != MBG_INVALID_PORT_HANDLE )
+ {
+ #if defined( MBG_TGT_CVI )
+
+ CloseCom( *p );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ CloseHandle( *p );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ close( *p );
+
+ #elif defined( MBG_TGT_DOS )
+ #if defined( _USE_V24TOOLS )
+
+ v24close( *p );
+
+ #else
+
+ #error Target DOS requires v24tools for serial I/O.
+
+ #endif
+
+ #else
+
+ #error This target OS is not supported.
+
+ #endif
+
+ *p = MBG_INVALID_PORT_HANDLE;
+ }
+
+ return MBG_SUCCESS;
+
+} // mbgserio_close_port_by_handle
+
+
+
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev )
+/**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst )
{
- MBG_PORT_HANDLE port_handle;
+ if ( pst->port_handle != MBG_INVALID_PORT_HANDLE )
+ {
+ MBG_PORT_HANDLE port_handle = pst->port_handle;
+
+ mbgserio_flush_tx( port_handle );
+
+ #if defined( MBG_TGT_WIN32 )
+
+ SetCommState( port_handle, &pst->old_dcb );
+ SetCommTimeouts( port_handle, &pst->old_commtimeouts );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ tcsetattr( port_handle, TCSANOW, &pst->old_tio );
+
+ #endif
+
+ return mbgserio_close_port_by_handle( &pst->port_handle );
+ }
+
+ return MBG_SUCCESS;
+
+} // mbgserio_close
+
+
+
+/*HDR*/
+/**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev )
+{
+ MBG_PORT_HANDLE port_handle = MBG_INVALID_PORT_HANDLE;
+ int rc = MBG_ERR_UNSPEC;
#if defined( MBG_TGT_CVI )
{
- int data_bits = 8; //##++
+ int data_bits = 8; //##+++++++++++++++
int parity_code = 0;
int baud_rate = 19200;
int stop_bits = 1;
@@ -124,102 +313,173 @@ _MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev
// 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
-
+ {
+ rc = MBG_ERR_INV_PARM; // no numeric substring found
+ goto out;
+ }
port_handle = atoi( &dev[i] );
- rc = OpenComConfig (port_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024); //##++
+ rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024 ); //##++
+
if ( rc < 0 )
- goto fail;
+ {
+ port_handle = MBG_INVALID_PORT_HANDLE;
+ rc = MBG_ERR_UNSPEC; // translate rc ?
+ goto out;
+ }
- pst->port_handle = port_handle;
+ rc = SetComTime( port_handle, 1.0 ); //##+++++++ WTF?
- SetComTime( port_handle, 1.0 ); //##++
- SetXMode( port_handle, 0 );
+ if ( rc < 0 )
+ {
+ rc = MBG_ERR_UNSPEC; //##+++++ translate rc ?
+ goto out_close;
+ }
+
+ rc = SetXMode( port_handle, 0 );
+
+ if ( rc < 0 )
+ {
+ rc = MBG_ERR_UNSPEC; //##+++++ translate rc ?
+ goto out_close;
+ }
}
#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;
+ DCB dcb;
+ rc = win32_create_file( dev, &port_handle );
- pst->port_handle = port_handle;
+ if ( rc != MBG_SUCCESS )
+ goto out;
- // save original settings
+ // save settings found at startup
pst->old_dcb.DCBlength = sizeof( pst->old_dcb );
GetCommState( port_handle, &pst->old_dcb );
GetCommTimeouts( port_handle, &pst->old_commtimeouts );
+ GetCommProperties( port_handle, &pst->comm_prop );
+
+ #if 0 // fields provided by the Windows DCB structure
+ DWORD DCBlength; /* sizeof(DCB) */
+ DWORD BaudRate; /* Baudrate at which running */
+ DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
+ DWORD fParity: 1; /* Enable parity checking */
+ DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
+ DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
+ DWORD fDtrControl:2; /* DTR Flow control */
+ DWORD fDsrSensitivity:1; /* DSR Sensitivity */
+ DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
+ DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
+ DWORD fInX: 1; /* Enable input X-ON/X-OFF */
+ DWORD fErrorChar: 1; /* Enable Err Replacement */
+ DWORD fNull: 1; /* Enable Null stripping */
+ DWORD fRtsControl:2; /* Rts Flow control */
+ DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
+ DWORD fDummy2:17; /* Reserved */
+ WORD wReserved; /* Not currently used */
+ WORD XonLim; /* Transmit X-ON threshold */
+ WORD XoffLim; /* Transmit X-OFF threshold */
+ BYTE ByteSize; /* Number of bits/byte, 4-8 */
+ BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
+ BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
+ char XonChar; /* Tx and Rx X-ON character */
+ char XoffChar; /* Tx and Rx X-OFF character */
+ char ErrorChar; /* Error replacement char */
+ char EofChar; /* End of Input character */
+ char EvtChar; /* Received Event character */
+ WORD wReserved1; /* Fill for now. */
+ #endif
// configure our settings
+ dcb = pst->old_dcb; // current settings as default
+ dcb.fOutxCtsFlow = FALSE; // CTS output flow control
+ dcb.fOutxDsrFlow = FALSE; // DSR output flow control
+ dcb.fDtrControl = DTR_CONTROL_ENABLE; // enable DTR
+ dcb.fDsrSensitivity = FALSE; // don't require DSR input active
+ //##++ TODO: more missing here
+ dcb.fRtsControl = RTS_CONTROL_ENABLE; // enable RTS for C28COM
+ dcb.fOutX = FALSE;
+
+ if ( !SetCommState( port_handle, &dcb ) )
+ {
+ rc = mbg_get_last_error( "SetCommState failed in mbgserio_open" );
+ goto out_close;
+ }
+
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 );
+ if ( !SetCommTimeouts( port_handle, &commtimeouts ) )
+ {
+ rc = mbg_get_last_error( "SetCommTimeout failed in mbgserio_open" );
+ goto out_close;
+ }
+
+ #if !defined( MBGSERIO_IN_BUFFER_SIZE )
+ #define MBGSERIO_IN_BUFFER_SIZE 2048
+ #endif
+
+ #if !defined( MBGSERIO_OUT_BUFFER_SIZE )
+ #define MBGSERIO_OUT_BUFFER_SIZE 2048
#endif
- PurgeComm( port_handle, PURGE_TXABORT|PURGE_TXCLEAR );
- PurgeComm( port_handle, PURGE_RXABORT|PURGE_RXCLEAR );
+ if ( !SetupComm( port_handle, MBGSERIO_IN_BUFFER_SIZE, MBGSERIO_OUT_BUFFER_SIZE ) )
+ {
+ rc = mbg_get_last_error( "SetupComm failed in mbgserio_open" );
+ goto out_close;
+ }
- //##++ mbgextio_set_console_control_handler();
+ PurgeComm( port_handle, PURGE_TXABORT | PURGE_TXCLEAR );
+ PurgeComm( port_handle, PURGE_RXABORT | PURGE_RXCLEAR );
+
+ //##++ TODO: mbgextio_set_console_control_handler() ?
}
- #elif defined( MBG_TGT_UNIX )
+ #elif defined( MBG_TGT_POSIX )
{
// 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 );
+ int flags = 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 defined( O_CLOEXEC )
+ flags |= O_CLOEXEC;
+ #endif
- if ( port_handle < 0 ) // check errno for the reason
- goto fail;
+ port_handle = open( dev, flags ); // returns -1 on error
+ if ( port_handle < 0 )
+ {
+ rc = mbg_get_last_error( "open failed in mbgserio_open" );
+ port_handle = MBG_INVALID_PORT_HANDLE;
+ goto out;
+ }
- pst->port_handle = port_handle;
+ //##++ 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()).
/* save current device settings */
- tcgetattr( port_handle, &pst->oldtio );
+ if ( tcgetattr( port_handle, &pst->old_tio ) < 0 )
+ {
+ rc = mbg_get_last_error( "tcgetattr failed in mbgserio_open" );
+ goto out_close;
+ }
- // atexit( port_deinit );
+ //##++ atexit( port_deinit );
fflush( stdout ); //##++
setvbuf( stdout, NULL, _IONBF, 0 );
@@ -230,9 +490,11 @@ _MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev
port_handle = v24open( (char *) dev, OPEN_MODE );
if ( port_handle < 0 )
- goto fail;
+ {
+ rc = MBG_ERR_UNSPEC; // translate rc ?
+ goto out;
+ }
- pst->port_handle = port_handle;
v24settimeout( port_handle, 1 );
}
#else
@@ -247,67 +509,81 @@ _MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev
#endif
- return 0;
+ rc = MBG_SUCCESS;
+ goto out;
+out_close:
+ mbgserio_close_port_by_handle( &port_handle ); // also sets port handle invalid
-fail:
- pst->port_handle = MBG_INVALID_PORT_HANDLE;
- return MBGSERIO_FAIL;
+out:
+ pst->port_handle = port_handle;
+ return rc;
} // mbgserio_open
-/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst )
+#if 0 && defined( MBG_TGT_POSIX )
+
+static /*HDR*/
+int scandir_filter_serial_port( const struct dirent *pde )
{
- if ( pst->port_handle != MBG_INVALID_PORT_HANDLE )
- {
- MBG_PORT_HANDLE port_handle = pst->port_handle;
+ static const char dev_name_1[] = "ttyS";
+ static const char dev_name_2[] = "ttyUSB";
+ char tmp_str[100];
+ SERIAL_IO_STATUS iost;
+ int rc;
- #if defined( MBG_TGT_CVI )
+ int l;
- CloseCom( port_handle );
+ l = strlen( dev_name_1 );
- #elif defined( MBG_TGT_WIN32 )
+ if ( strncmp( pde->d_name, dev_name_1, l ) == 0 )
+ goto check;
- SetCommState( port_handle, &pst->old_dcb );
- SetCommTimeouts( port_handle, &pst->old_commtimeouts );
- CloseHandle( port_handle );
- #elif defined( MBG_TGT_UNIX )
+ l = strlen( dev_name_2 );
- tcsetattr( port_handle, TCSANOW, &pst->oldtio );
- close( port_handle );
+ if ( strncmp( pde->d_name, dev_name_2, l ) == 0 )
+ goto check;
- #elif defined( MBG_TGT_DOS )
- #if defined( _USE_V24TOOLS )
+ return 0;
- v24close( port_handle );
+check:
+ // if the first character after the search string is not a digit
+ // then the search result is not what we want
+ if ( pde->d_name[l] < '0' || pde->d_name[l] > '9' )
+ return 0;
- #else
+ snprintf( tmp_str, sizeof( tmp_str ), "%s/%s", dev_dir, pde->d_name );
- #error Target DOS requires v24tools for serial I/O.
+ rc = mbgserio_open( &iost, tmp_str );
- #endif
+ if ( rc < 0 )
+ {
+ #if defined( DEBUG )
+ fprintf( stderr, "failed to open %s: %i\n", tmp_str, rc );
+ #endif
- #else
+ return 0;
+ }
- #error This target OS is not supported.
+ #if defined( DEBUG )
+ fprintf( stderr, "port %s opened successfully\n", tmp_str );
+ #endif
- #endif
+ mbgserio_close( &iost );
- pst->port_handle = MBG_INVALID_PORT_HANDLE;
- }
+ return 1;
- return 0;
+} // scandir_filter_serial_port
-} // mbgserio_close
+#endif // defined( MBG_TGT_POSIX )
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, int max_devs )
+_NO_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;
@@ -318,24 +594,94 @@ _MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, in
list_head = (*list);
+
+#if 0 && defined( MBG_TGT_POSIX )
+
+ struct dirent **namelist;
+
+ n = scandir( dev_dir, &namelist, scandir_filter_serial_port, versionsort );
+
+ if ( n < 0 )
+ perror( "scandir" );
+ else
+ {
+ for ( i = 0; i < n; i++ )
+ {
+ printf( "%s/%s\n", dev_dir, namelist[i]->d_name );
+ free( namelist[i] );
+ }
+
+ free( namelist );
+ }
+
+#elif 0 && defined( MBG_TGT_POSIX )
+
+ DIR *pd = opendir( dev_dir );
+
+ if ( pd )
+ {
+ struct dirent *pde;
+
+ while ( ( pde = readdir( pd ) ) != NULL )
+ {
+ if ( strncmp( pde->d_name, "ttyS", 4 ) == 0 )
+ goto found;
+
+ if ( strncmp( pde->d_name, "ttyUSB", 6 ) == 0 )
+ goto found;
+
+ continue;
+
+found:
+ fprintf( stderr, "found /dev/%s\n", pde->d_name );
+ }
+
+ closedir( pd );
+ }
+
+#else
+
for ( i = 0; i < max_devs; i++ )
{
- SERIAL_IO_STATUS iost;
char dev_name[100] = { 0 };
int rc;
#if defined( MBG_TGT_WIN32 )
+
+ HANDLE h = INVALID_HANDLE_VALUE;
+
sprintf( dev_name, "COM%i", i + 1 );
+ rc = win32_create_file( dev_name, &h );
+
+ // If access is denied then the port exists but is in use
+ if ( rc != MBG_SUCCESS && rc != MBG_ERR_ACCESS )
+ continue; // memory allocation error
+
+ if ( h != INVALID_HANDLE_VALUE )
+ CloseHandle( h );
+
#elif defined( MBG_TGT_LINUX )
+
+ SERIAL_IO_STATUS iost;
sprintf( dev_name, "/dev/ttyS%i", i );
- #endif
+ rc = mbgserio_open( &iost, dev_name );
- rc = mbgserio_open( &iost, dev_name );
+ if ( rc < 0 )
+ {
+ sprintf( dev_name, "/dev/ttyUSB%i", i );
+
+ rc = mbgserio_open( &iost, dev_name );
+
+ if ( rc < 0 )
+ continue;
+ }
+
+ mbgserio_close( &iost );
+
+ #endif
- if ( rc < 0 )
- continue;
- mbgserio_close( &iost );
+ // add the device name to the list
(*list)->s = (char *) malloc( strlen( dev_name ) + 1 );
strcpy( (*list)->s, dev_name );
@@ -355,6 +701,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, in
free( *list );
list_head = NULL;
}
+#endif
*list = list_head;
@@ -365,7 +712,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, in
/*HDR*/
-_MBG_API_ATTR void _MBG_API _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list )
+_NO_MBG_API_ATTR void _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list )
{
int i = 0;
@@ -406,18 +753,23 @@ _MBG_API_ATTR void _MBG_API _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
+/**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+_NO_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;
+ int rc = MBG_ERR_UNSPEC;
#if defined( MBG_TGT_CVI )
{
int data_bits = 8;
- int parity_code = 0;
+ int parity_code = 0;
int stop_bits = 1;
- int rc;
// setup framing.
for ( cp = framing; *cp; cp++ )
@@ -449,24 +801,31 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
break;
default:
- return MBGSERIO_INV_CFG; // invalid framing string
+ rc = MBG_ERR_INV_PARM; // invalid framing string
+ goto out;
}
}
- rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code,
- data_bits, stop_bits, 8192, 1024 );
+ rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code,
+ data_bits, stop_bits, 8192, 1024 );
if ( rc < 0 )
- return rc;
+ {
+ rc = MBG_ERR_INV_PARM;
+ goto out;
+ }
- SetComTime( port_handle, 1.0 ); //##++
+ SetComTime( port_handle, 1.0 ); //##++++++++ check rc ?
SetXMode( port_handle, 0 );
}
#elif defined( MBG_TGT_WIN32 )
{
DCB dcb;
- dcb.DCBlength = sizeof( DCB ) ;
- GetCommState( port_handle, &dcb ) ;
+ // get current settings
+ dcb.DCBlength = sizeof( DCB );
+ GetCommState( port_handle, &dcb ); //##++++++++++++++++ check rc?
+
+ // update changed settings
dcb.BaudRate = baud_rate;
@@ -503,27 +862,19 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
break;
default:
- return MBGSERIO_INV_CFG; // invalid framing string
+ rc = MBG_ERR_INV_PARM; // invalid framing string
+ goto out;
}
}
-
- 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 );
+ SetCommState( port_handle, &dcb ); //##++++++++ check rc
}
- #elif defined( MBG_TGT_UNIX )
+ #elif defined( MBG_TGT_POSIX )
{
tcflag_t c_cflag = 0;
struct termios tio;
- tcgetattr( port_handle, &tio );
+ rc = tcgetattr( port_handle, &tio ); //##+++++++++++++++++ check rc
// setup transmission speed
switch( baud_rate )
@@ -537,8 +888,16 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
case 19200: c_cflag = B19200; break;
case 38400: c_cflag = B38400; break;
case 57600: c_cflag = B57600; break;
+ #if defined( B115200 )
+ case 115200: c_cflag = B115200; break;
+ #endif
+ #if defined( B230400 )
+ case 230400: c_cflag = B230400; break;
+ #endif
- default: return MBGSERIO_INV_CFG; // invalid
+ default:
+ rc = MBG_ERR_INV_PARM; // invalid
+ goto out;
}
#if 0 //##++ This should be used preferably for portability reasons
@@ -549,7 +908,9 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// setup framing.
for ( cp = framing; *cp; cp++ )
{
- switch ( _toupper( *cp ) )
+ char c = toupper( *cp );
+
+ switch ( c )
{
case '7': c_cflag |= CS7; break;
case '8': c_cflag |= CS8; break;
@@ -561,7 +922,9 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
case '1': break;
case '2': c_cflag |= CSTOPB; break;
- default: return MBGSERIO_INV_CFG; // invalid framing string
+ default:
+ rc = MBG_ERR_INV_PARM; // invalid
+ goto out;
}
}
@@ -572,7 +935,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// (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,
+ // 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.
@@ -595,17 +958,17 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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
+ // 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
+ // 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
+ // 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.
@@ -636,14 +999,14 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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,
+ // 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
+ // 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.
+ // 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.
@@ -657,53 +1020,53 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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
+ // 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
+ // 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
+ // 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
+ // 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
+ // 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
+ // 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.
+ // 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,
+ // 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
+ // 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,
+ // 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
+ // 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,
@@ -722,9 +1085,9 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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
+ // 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
+ // 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
@@ -733,18 +1096,18 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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:
+ // 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
+ // 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
+ // 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
@@ -752,8 +1115,8 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
// 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
+ // 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
@@ -761,8 +1124,8 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
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 );
+ rc = tcflush( port_handle, TCIFLUSH );
+ rc = tcsetattr( port_handle, TCSANOW, &tio ); //##+++++++++ check rc ?
fflush( stdout );
setvbuf( stdout, NULL, _IONBF, 0 );
@@ -789,7 +1152,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
case 'N':
case 'E':
case 'O':
- parity = *cp;
+ parity = c;
break;
case '1':
@@ -798,11 +1161,12 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
break;
default:
- return MBGSERIO_INV_CFG; // invalid framing string
+ rc = MBG_ERR_INV_PARM; // invalid framing string
+ goto out;
}
}
- v24setparams( port_handle, baud_rate, datab, parity, stopb );
+ v24setparams( port_handle, baud_rate, datab, parity, stopb ); //##++++++++++++++ check rc?
}
#else
@@ -816,87 +1180,199 @@ _MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst,
#endif
- return 0;
+ rc = MBG_SUCCESS;
-} // mbgserio_set_parms
+out:
+ return rc;
+} // 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 )
+_NO_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;
+ #if defined( MBG_TGT_CVI )
- ClearCommError( h, &dwErrorFlags, &ComStat );
+ return ComRd( h, (char *) buffer, count );
- if ( dwErrorFlags ) // transmission error (parity, framing, etc.)
- return MBGSERIO_FAIL;
+ #elif defined( MBG_TGT_WIN32 )
+ BOOL fReadStat;
+ COMSTAT ComStat;
+ DWORD dwErrorFlags;
+ DWORD dwLength;
- dwLength = min( (DWORD) count, ComStat.cbInQue );
+ ClearCommError( h, &dwErrorFlags, &ComStat );
- if ( dwLength )
- {
- fReadStat = ReadFile( h, buffer, dwLength, &dwLength, NULL );
+ if ( dwErrorFlags ) // transmission error (parity, framing, etc.)
+ return MBG_ERR_IO; //##+++++++++++++++++++++++++
- if ( !fReadStat )
- return MBGSERIO_FAIL;
- }
- return dwLength;
+ dwLength = min( (DWORD) count, ComStat.cbInQue );
-} // mbgserio_read
+ if ( dwLength )
+ {
+ fReadStat = ReadFile( h, buffer, dwLength, &dwLength, NULL );
+
+ if ( !fReadStat )
+ return MBG_ERR_IO; //##++++++++++++++
+ }
+
+ return dwLength;
+ #elif defined( MBG_TGT_POSIX )
+
+ return read( h, buffer, count );
+
+ #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS )
+
+ return v24read( h, buffer, count );
+
+ #else
+
+ #error mbgserio_read() not implemented for this target
+
+ #endif
+
+} // mbgserio_read
+/* //##+++++++++++++++++ need to check all targets
+ * @return one of the MBG_ERROR_CODES on error, else number of bytes written
+ */
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count )
+_NO_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;
+ #if defined( MBG_TGT_CVI )
- while ( dwTotalBytesWritten < (DWORD) count )
- {
- dwThisBytesWritten = 0;
+ return ComWrt( h, (char *) buffer, count );
+
+ #elif defined( MBG_TGT_WIN32 )
- fWriteStat = WriteFile( h, ( (char *) buffer ) + dwTotalBytesWritten,
- count - dwTotalBytesWritten,
- &dwThisBytesWritten, NULL );
- if ( !fWriteStat )
+ BOOL fWriteStat;
+ COMSTAT ComStat;
+ DWORD dwErrorFlags;
+ DWORD dwThisBytesWritten;
+ DWORD dwTotalBytesWritten = 0;
+
+ while ( dwTotalBytesWritten < (DWORD) count )
{
- #if defined( _DEBUG )
- DWORD dw = GetLastError();
- #endif
- break; //##++ Error: Unable to write
+ dwThisBytesWritten = 0;
+
+ fWriteStat = WriteFile( h, ( (char *) buffer ) + dwTotalBytesWritten,
+ count - dwTotalBytesWritten,
+ &dwThisBytesWritten, NULL );
+ if ( !fWriteStat )
+ return mbg_get_last_error( "write failed in mbgserio_write" );
+
+ dwTotalBytesWritten += dwThisBytesWritten;
+
+ ClearCommError( h, &dwErrorFlags, &ComStat );
+
+ if ( dwErrorFlags )
+ {
+ // Possible errors:
+ //
+ // CE_RXOVER 0x0001 // Receive Queue overflow
+ // CE_OVERRUN 0x0002 // Receive Overrun Error, next character(s) lost
+ // CE_RXPARITY 0x0004 // Receive Parity Error
+ // CE_FRAME 0x0008 // Receive Framing error
+ // CE_BREAK 0x0010 // Break Detected
+ // CE_TXFULL 0x0100 // TX Queue is full
+ // CE_PTO 0x0200 // LPTx Timeout
+ // CE_IOE 0x0400 // LPTx I/O Error
+ // CE_DNS 0x0800 // LPTx Device not selected
+ // CE_OOP 0x1000 // LPTx Out-Of-Paper
+ // CE_MODE 0x8000 // Requested mode unsupported
+ //
+ // Except CE_TXFULL these are usually RX error flags,
+ // so we just ignore them.
+ }
}
- dwTotalBytesWritten += dwThisBytesWritten;
+ return dwTotalBytesWritten;
- ClearCommError( h, &dwErrorFlags, &ComStat );
+ #elif defined( MBG_TGT_POSIX )
- if ( dwErrorFlags )
- break; //#++ Error: Check flags
- }
+ int rc = write( h, buffer, count ); // returns -1 on error, else number of byte written
- return dwTotalBytesWritten;
+ if ( rc == -1 )
+ return mbg_get_last_error( "write failed in mbgserio_write" );
+
+ return rc;
+
+ #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS )
+
+ return v24write( h, buffer, count );
+
+ #else
+
+ #error mbgserio_write() not implemented for this target
+
+ #endif
} // mbgserio_write
-#endif // defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI )
+
+
+/*HDR*/
+_NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h )
+{
+ #if defined( MBG_TGT_CVI )
+
+ FlushOutQ( h );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #if defined( DEBUG )
+ printf( "Flushing TX buffers ...\n" );
+ #endif
+
+ FlushFileBuffers( h );
+
+ #if ( 1 && defined( DEBUG ) ) //##++++++++++++++
+ {
+ COMSTAT ComStat;
+ DWORD dwErrorFlags;
+
+ for (;;)
+ {
+ ClearCommError( h, &dwErrorFlags, &ComStat );
+
+ printf( "ErrFlags: %04X, out queue: %u\n", dwErrorFlags, ComStat.cbOutQue );
+
+ if ( ComStat.cbOutQue == 0 )
+ break;
+
+ Sleep( 1 );
+ }
+ }
+ #endif
+
+ //##++++ Sleep( 500 );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ tcdrain( h );
+
+ #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS )
+
+ v24flush( h, SND );
+
+ #else
+
+ #error mbgserio_flush_tx() not implemented for this target
+
+ #endif
+
+} // mbgserio_flush_tx
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
- uint count, ulong char_timeout )
+_NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
+ uint count, ulong char_timeout )
{
int n_bytes;
@@ -904,14 +1380,25 @@ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
struct timeval tv_char_timeout;
fd_set fds;
+ int max_fd;
int rc;
- mbgserio_msec_to_timeval( char_timeout, &tv_char_timeout );
+ mbg_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 defined( MBG_TGT_WIN32 )
+ // Under Windows an fd is a handle which can't simply
+ // be converted to an int, but the first argument of
+ // select() is ignored under Windows anyway, so we just
+ // set max_fd to 0.
+ max_fd = 0;
+ #else
+ max_fd = h;
+ #endif
+
+ rc = select( max_fd + 1, &fds, NULL, NULL, &tv_char_timeout );
if ( rc < 0 ) // error
goto fail;
@@ -920,7 +1407,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
goto timeout;
// data is available
- n_bytes = _mbgserio_read( h, buffer, count );
+ n_bytes = mbgserio_read( h, buffer, count );
#else
MBG_TMO_TIME tmo;
@@ -929,7 +1416,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
for (;;) // wait to read one new char
{
- n_bytes = _mbgserio_read( h, buffer, count );
+ n_bytes = mbgserio_read( h, buffer, count );
if ( n_bytes > 0 ) // new char(s) received
break;
@@ -940,7 +1427,7 @@ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
if ( mbg_tmo_curr_time_is_after( &tmo ) )
goto timeout;
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
usleep( 10 * 1000 );
#endif
}
@@ -949,10 +1436,10 @@ _MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer,
return n_bytes;
timeout:
- return MBGSERIO_TIMEOUT;
+ return MBG_ERR_TIMEOUT;
fail:
- return MBGSERIO_FAIL;
+ return MBG_ERR_IO;
} // mbgserio_read_wait
diff --git a/mbglib/common/mbgserio.h b/mbglib/common/mbgserio.h
index 28afa96..73a96e9 100644
--- a/mbglib/common/mbgserio.h
+++ b/mbglib/common/mbgserio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgserio.h 1.4 2009/09/01 10:54:29Z martin REL_M $
+ * $Id: mbgserio.h 1.7.1.4 2014/03/11 12:26:46Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,23 @@
*
* -----------------------------------------------------------------------
* $Log: mbgserio.h $
- * Revision 1.4 2009/09/01 10:54:29Z martin
+ * Revision 1.7.1.4 2014/03/11 12:26:46Z martin
+ * Revision 1.7.1.3 2014/03/04 12:08:13 martin
+ * Revision 1.7.1.2 2014/01/08 17:19:42Z martin
+ * MBG_TGT_POSIX
+ * New libusb
+ * Revision 1.7.1.1 2014/01/07 17:00:29 martin
+ * Use common Meinberg error codes.
+ * Revision 1.7 2013/02/01 16:10:45 martin
+ * Got rid of _mbg_open/close/read/write() macros.
+ * Functions are now used instead.
+ * Updated function prototypes.
+ * Revision 1.6 2011/08/23 10:15:25Z martin
+ * Updated function prototypes.
+ * Revision 1.5 2011/08/04 09:48:55 martin
+ * Support flushing output.
+ * Re-ordered some definitions.
+ * 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.
@@ -30,12 +46,14 @@
/* Other headers to be included */
+#include <mbg_tgt.h>
#include <mbg_tmo.h>
+#include <mbgerror.h>
#include <stdlib.h>
#include <string.h>
-#if defined( MBG_TGT_UNIX )
+#if defined( MBG_TGT_POSIX )
#include <termios.h>
#endif
@@ -44,7 +62,7 @@
#endif
#if !defined( _USE_SELECT_FOR_SERIAL_IO )
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
#define _USE_SELECT_FOR_SERIAL_IO 1
#else
#define _USE_SELECT_FOR_SERIAL_IO 0
@@ -62,11 +80,6 @@
/* 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"
@@ -94,61 +107,18 @@
#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
@@ -169,10 +139,11 @@ typedef struct
#if defined( MBG_TGT_WIN32 )
DCB old_dcb;
COMMTIMEOUTS old_commtimeouts;
+ COMMPROP comm_prop;
#endif
- #if defined( MBG_TGT_UNIX )
- struct termios oldtio;
- //##++ struct termios newtio;
+
+ #if defined( MBG_TGT_POSIX )
+ struct termios old_tio;
#endif
} SERIAL_IO_STATUS;
@@ -190,14 +161,33 @@ extern "C" {
/* 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 ) ;
+ /**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst ) ;
+
+ /**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev ) ;
+
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, int max_devs ) ;
+ _NO_MBG_API_ATTR void _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list ) ;
+ /**
+ * @brief
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, uint32_t baud_rate, const char *framing ) ;
+
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, unsigned int count ) ;
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count ) ;
+ _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) ;
+ _NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer, uint count, ulong char_timeout ) ;
/* ----- function prototypes end ----- */
diff --git a/mbglib/common/mbgtime.h b/mbglib/common/mbgtime.h
new file mode 100644
index 0000000..ebfc8e8
--- /dev/null
+++ b/mbglib/common/mbgtime.h
@@ -0,0 +1,372 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgtime.h 1.20.1.1 2014/10/28 08:32:52Z martin TEST $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for mbgtime.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgtime.h $
+ * Revision 1.20.1.1 2014/10/28 08:32:52Z martin
+ * Revision 1.20 2014/05/27 08:09:19 martin
+ * Added NTP_SEC_BIAS.
+ * Revision 1.19 2013/05/22 16:47:01 martin
+ * Added some useful macros.
+ * Revision 1.18 2012/10/02 18:51:11 martin
+ * Include <time.h> for WIN32 target and firmware only
+ * Fixed build under QNX, DOS, and FreeBSD.
+ * Revision 1.17 2010/08/06 13:03:03 martin
+ * Removed obsolete code.
+ * Revision 1.16 2010/07/16 10:22:07Z martin
+ * Moved definitions of HNS_PER_SEC and HNS_PER_MS here.
+ * Conditionally define FILETIME_1970.
+ * Defined MASK_CLOCK_T for ARM/Cortex.
+ * Revision 1.15 2009/10/23 09:55:21 martin
+ * Added MJD numbers for commonly used epochs.
+ * Revision 1.14 2009/08/12 10:28:12 daniel
+ * Added definition NSECS_PER_SEC.
+ * Revision 1.13 2009/06/12 13:31:44Z martin
+ * Fix build errors with arm-linux-gcc.
+ * Revision 1.12 2009/03/27 14:14:00 martin
+ * Cleanup for CVI.
+ * Revision 1.11 2009/03/13 09:30:06Z martin
+ * Include mystd.h in mbgtime.c rather than here. The bit type used
+ * here is now defined in words.h.
+ * Updated comments for GPS_SEC_BIAS.
+ * Revision 1.10 2008/12/11 10:45:41Z martin
+ * Added clock_t mask for gcc (GnuC).
+ * Revision 1.9 2006/08/25 09:33:46Z martin
+ * Updated function prototypes.
+ * Revision 1.8 2004/12/28 11:29:02Z martin
+ * Added macro _n_days.
+ * Updated function prototypes.
+ * Revision 1.7 2002/09/06 07:15:48Z martin
+ * Added MASK_CLOCK_T for Linux.
+ * Revision 1.6 2002/02/25 08:37:44 Andre
+ * definition MASK_CLOCK_T for ARM added
+ * Revision 1.5 2001/03/02 10:18:10Z MARTIN
+ * Added MASK_CLOCK_T for Watcom C.
+ * Revision 1.4 2000/09/15 07:57:53 MARTIN
+ * Removed outdated function prototypes.
+ * Revision 1.3 2000/07/21 14:05:18 MARTIN
+ * Defined some new constants.
+ *
+ **************************************************************************/
+
+#ifndef _MBGTIME_H
+#define _MBGTIME_H
+
+
+/* Other headers to be included */
+
+#include <gpsdefs.h>
+
+#if _IS_MBG_FIRMWARE \
+ || defined( MBG_TGT_WIN32 ) \
+ || defined( MBG_TGT_DOS ) \
+ || defined( MBG_TGT_QNX_NTO )
+ #include <time.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MBGTIME
+ #define _ext
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+
+/**
+ * @brief GPS epoch bias from ordinary time_t epoch
+ *
+ * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
+ * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years,
+ * plus 2 days due to leap years (1972 and 1976), plus the difference
+ * of the day-of-month (6 - 1), so:<br>
+ *
+ * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS
+ */
+#define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
+
+
+/**
+ * @brief NTP epoch bias from ordinary time_t epoch
+ *
+ * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
+ * the NTP epoch is 1900-01-01 00:00, so the difference is
+ * a constant number of seconds:<br>
+ *
+ * time_t t = ntp_time - ::NTP_SEC_BIAS
+ */
+#define NTP_SEC_BIAS 2208988800UL
+
+
+
+// Modified Julian Day (MJD) numbers for some commonly used epochs.
+// To compute the MJD for a given date just compute the days since epoch
+// and add the constant number of days according to the epoch, e.g.:
+// current_unix_mjd = ( time( NULL ) / SECS_PER_DAY ) + MJD_AT_UNIX_EPOCH;
+#define MJD_AT_GPS_EPOCH 44244UL // MJD at 1980-01-06
+#define MJD_AT_UNIX_EPOCH 40587UL // MJD at 1970-01-01
+#define MJD_AT_NTP_EPOCH 40587UL // MJD at 1900-01-01
+
+
+// The constant below defines the Windows FILETIME number (100 ns intervals
+// since 1601-01-01) for 1970-01-01, which is usually the epoche for the time_t
+// type used by the standard C library.
+#if !defined( FILETIME_1970 )
+ // FILETIME represents a 64 bit number, so we need to defined the
+ // constant with an appendix depending on the compiler.
+ #if MBG_TGT_C99 || defined( __GNUC__ )
+ // syntax introduced by C99 standard
+ #define FILETIME_1970 0x019db1ded53e8000ULL // Epoch offset from FILETIME to UNIX
+ #elif defined( MBG_TGT_WIN32 )
+ // MSC-specific syntax
+ #define FILETIME_1970 0x019db1ded53e8000ui64
+ #endif
+#endif
+
+
+#if defined( _C166 )
+ #if _C166 >= 50
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+ #else
+ #define MASK_CLOCK_T 0x7FFF /* time.h not shipped with compiler */
+ #endif
+#endif
+
+#if defined( __WATCOMC__ )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+#endif
+
+#if defined( _CVI ) || defined( _CVI_ )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+#endif
+
+#if defined( _MSC_VER )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+#endif
+
+#if defined( __NETWARE_386__ )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+#endif
+
+#if defined( __ARM )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+#endif
+
+#if defined( __ARMCC_VERSION )
+ #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
+#endif
+
+#if defined( __GNUC__ )
+ #if defined( __linux )
+ #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
+ #else // Windows / MinGW
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+ #endif
+#endif
+
+
+#if !defined( MASK_CLOCK_T )
+ #if sizeof( clock_t ) == sizeof( short )
+ #define MASK_CLOCK_T 0x7FFF
+ #elif sizeof( clock_t ) == sizeof( long )
+ #define MASK_CLOCK_T 0x7FFFFFFFL
+ #endif
+#endif
+
+typedef struct
+{
+ clock_t start;
+ clock_t stop;
+ short is_set;
+} TIMEOUT;
+
+
+#define DAYS_PER_WEEK 7
+
+#define SECS_PER_MIN 60
+#define MINS_PER_HOUR 60
+#define HOURS_PER_DAY 24
+#define DAYS_PER_WEEK 7
+
+#define MINS_PER_DAY ( MINS_PER_HOUR * HOURS_PER_DAY )
+
+#define SECS_PER_HOUR 3600
+#define SECS_PER_DAY 86400L
+#define SECS_PER_WEEK 604800L
+
+#define SEC100S_PER_SEC 100L
+#define SEC100S_PER_MIN ( SEC100S_PER_SEC * SECS_PER_MIN )
+#define SEC100S_PER_HOUR ( SEC100S_PER_SEC * SECS_PER_HOUR )
+#define SEC100S_PER_DAY ( SEC100S_PER_SEC * SECS_PER_DAY )
+
+#if !defined( MSEC_PER_SEC )
+ #define MSEC_PER_SEC 1000L
+#endif
+
+#define MSEC_PER_MIN ( MSEC_PER_SEC * SECS_PER_MIN )
+#define MSEC_PER_HOUR ( MSEC_PER_SEC * SECS_PER_HOUR )
+#define MSEC_PER_DAY ( MSEC_PER_SEC * SECS_PER_DAY )
+
+#define NSECS_PER_SEC 1000000000UL
+
+#if !defined( HNS_PER_SEC )
+ #define HNS_PER_SEC 10000000UL
+#endif
+
+#if !defined( HNS_PER_MS )
+ #define HNS_PER_MS 10000UL
+#endif
+
+
+/**
+ * @brief A table with the days of month
+ *
+ * First row is for standard years, second row is
+ * for leap years.
+ *
+ * @see DAYS_OF_MONTH_TABLE_INIT
+ */
+typedef char DAYS_OF_MONTH_TABLE[2][12];
+
+
+/**
+ * @brief An initializer for a ::DAYS_OF_MONTH_TABLE
+ */
+#define DAYS_OF_MONTH_TABLE_INIT \
+{ \
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, \
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } \
+}
+
+
+
+
+_ext TM_GPS dhms;
+_ext TM_GPS datum;
+
+
+_ext const char *short_time_fmt
+#ifdef _MBGTIME
+ = "%2i:%02i"
+#endif
+;
+
+_ext const char *time_fmt
+#ifdef _MBGTIME
+ = "%2i:%02i:%02i"
+#endif
+;
+
+_ext const char *long_time_fmt
+#ifdef _MBGTIME
+ = "%2i:%02i:%02i.%02i"
+#endif
+;
+
+_ext const char *date_fmt
+#ifdef _MBGTIME
+ = "%2i.%02i.%04i"
+#endif
+;
+
+_ext const char *day_date_fmt
+#ifdef _MBGTIME
+ = "%s, %2i.%02i.%04i"
+#endif
+;
+
+_ext const char *day_name_eng[]
+#ifdef _MBGTIME
+ = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }
+#endif
+;
+
+_ext const char *day_name_ger[]
+#ifdef _MBGTIME
+ = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }
+#endif
+;
+
+_ext const TM_GPS init_tm
+#ifdef _MBGTIME
+ = { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 }
+#endif
+;
+
+
+_ext DAYS_OF_MONTH_TABLE days_of_month
+#ifdef _MBGTIME
+ = DAYS_OF_MONTH_TABLE_INIT
+#endif
+;
+
+
+// simplify call to n_days with structures
+#define _n_days( _s ) \
+ n_days( (_s)->mday, (_s)->month, (_s)->year )
+
+
+#define _is_leap_year( _y ) \
+ ( ( ( ( (_y) % 4 ) == 0 ) && ( ( (_y) % 100 ) != 0 ) ) || ( ( (_y) % 400 ) == 0 ) )
+
+
+#define _get_days_of_month( _y, _m ) \
+ days_of_month[ _is_leap_year( _y ) ][_m]
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ;
+ void stretch_timeout( TIMEOUT *t, clock_t interval ) ;
+ bit check_timeout( TIMEOUT *t, clock_t clk ) ;
+ int err_tm( TM_GPS *tm ) ;
+ TM_GPS *clear_time( TM_GPS *tm ) ;
+ TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ;
+ long tm_to_wsec( TM_GPS *tm ) ;
+ int is_leap_year( int y ) ;
+ int day_of_year( int day, int month, int year ) ;
+ void date_of_year ( int year, int day_num, TM_GPS *tm ) ;
+ int day_of_week( int day, int month, int year ) ;
+ int days_to_years( long *day_num, int year ) ;
+ long n_days( ushort mday, ushort month, ushort year ) ;
+ double nano_time_to_double( const NANO_TIME *p ) ;
+ void double_to_nano_time( NANO_TIME *p, double d ) ;
+ int sprint_time( char *s, const TM_GPS *tm ) ;
+ int sprint_short_time( char *s, TM_GPS *time ) ;
+ int sprint_date( char *s, const TM_GPS *tm ) ;
+ int sprint_day_date( char *s, const TM_GPS *tm ) ;
+ int sprint_tm( char *s, const TM_GPS *tm ) ;
+ void sscan_time( char *s, TM_GPS *tm ) ;
+ void sscan_date( char *s, TM_GPS *tm ) ;
+
+/* ----- function prototypes end ----- */
+
+
+/* End of header body */
+
+
+#undef _ext
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _MBGTIME_H */
diff --git a/mbglib/common/myutil.c b/mbglib/common/myutil.c
new file mode 100644
index 0000000..a81759d
--- /dev/null
+++ b/mbglib/common/myutil.c
@@ -0,0 +1,68 @@
+
+/**************************************************************************
+ *
+ * $Id: myutil.c 1.3 2004/10/29 10:12:13Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Some miscellaneous utility functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: myutil.c $
+ * Revision 1.3 2004/10/29 10:12:13Z martin
+ * Removed obsolete inclusion of mystd.h.
+ * Revision 1.2 2000/07/21 13:52:01Z MARTIN
+ * Support for checksums on far data objects.
+ *
+ **************************************************************************/
+
+#define _MYUTIL
+ #include <myutil.h>
+#undef _MYUTIL
+
+
+
+/*HDR*/
+void spaces_to_zeros( char *s )
+{
+ char *cp;
+
+ for ( cp = s; *cp; cp++ )
+ if ( *cp == ' ' )
+ *cp = '0';
+
+} // spaces_to_zeros
+
+
+
+/*--------------------------------------------------------------*/
+/* Name: checksum() */
+/* */
+/* Purpose: */
+/* */
+/* */
+/* Input: -- */
+/* */
+/* Output: -- */
+/* */
+/* Ret value: -- */
+/*+-------------------------------------------------------------*/
+
+/*HDR*/
+CSUM checksum( const void _CSFAR *vp, int n )
+{
+ CSUM csum = 0x1234;
+ int i;
+
+ byte _CSFAR *p = ( (byte _CSFAR *) vp ) + sizeof( csum );
+ n -= sizeof( csum );
+
+ for ( i = 0; i < n; i++ )
+ csum += *p++;
+
+ return( csum );
+
+} // checksum
+
+
diff --git a/mbglib/common/myutil.h b/mbglib/common/myutil.h
new file mode 100644
index 0000000..9d41574
--- /dev/null
+++ b/mbglib/common/myutil.h
@@ -0,0 +1,238 @@
+
+/**************************************************************************
+ *
+ * $Id: myutil.h 1.18 2014/10/20 12:30:38Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for myutil.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: myutil.h $
+ * Revision 1.18 2014/10/20 12:30:38Z martin
+ * Moved macro _isdigit() to words.h.
+ * Revision 1.17 2014/07/15 06:19:48Z andre
+ * added function _sgn( _x ), returns sign of _x
+ * Revision 1.16 2013/12/16 13:32:57Z martin
+ * Don't redefine MIN and MAX.
+ * Revision 1.15 2012/10/02 18:51:52 martin
+ * Updated handling of pragma pack().
+ * Revision 1.14 2011/02/16 14:02:35 martin
+ * Added STRINGIFY() macro.
+ * Revision 1.13 2010/12/13 15:59:39 martin
+ * Moved definition of macro _frac() here.
+ * Revision 1.12 2008/01/30 10:28:17Z martin
+ * Moved some macro definitions to words.h.
+ * Revision 1.11 2004/11/09 14:20:24Z martin
+ * Redefined some data types using C99 fixed-size definitions.
+ * Removed duplicate definition of macro _mask().
+ * Revision 1.10 2004/04/14 08:57:59Z martin
+ * Pack structures 1 byte aligned.
+ * Revision 1.9 2003/05/20 10:22:25Z MARTIN
+ * Corrected endianess of union UL for CC51.
+ * Revision 1.8 2002/09/03 13:40:43 MARTIN
+ * New macros _memfill() and _memclr().
+ * Revision 1.7 2002/03/14 13:45:56 MARTIN
+ * Changed type CSUM from short to ushort.
+ * Revision 1.6 2002/03/05 14:14:21 MARTIN
+ * New macro _isdigit() to avoid inclusion of ctype.h.
+ * Revision 1.5 2002/01/25 10:54:26 MARTIN
+ * Added some useful macros.
+ * Revision 1.4 2001/03/30 09:07:52 Andre
+ * union UL byte order set to Big Endian if SH2 is used
+ * Revision 1.3 2000/08/18 07:22:07Z MARTIN
+ * Modified the _csum() macro to support far data objects.
+ * Revision 1.2 2000/07/21 13:50:49 MARTIN
+ * Added some definitions and macros.
+ *
+ **************************************************************************/
+
+#ifndef _MYUTIL_H
+#define _MYUTIL_H
+
+
+/* Other headers to be included */
+
+#include <words.h>
+#include <use_pack.h>
+
+
+// _CS_FAR should be define far if the csum of far data
+// structures must be computed
+#if !defined( _CSFAR )
+ #define _CSFAR
+#endif
+
+
+#ifdef _MYUTIL
+ #define _ext
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
+#endif
+
+
+// The two macros below can be used to define a constant string on the
+// compiler's command line, e.g. like -DVERSION_STRING="v1.0 BETA".
+// Source code like
+// const char version_string[] = VERSION_STRING;
+// may not work for every compiler since the double quotes
+// in VERSION_STRING may be removed when the definition is evaluated.
+// A proper solution is to use the STRINGIFY() macro below:
+// const char version_string[] = STRINGIFY( VERSION_STRING );
+// The XSTRINGIFY() macro is simply a helper macro which should not
+// be used alone.
+#define STRINGIFY(x) XSTRINGIFY(x)
+#define XSTRINGIFY(x) #x
+
+
+
+#if MBG_TGT_HAS_64BIT_TYPES
+ #define _frac( _x ) ( ( (_x) == 0.0 ) ? 0.0 : ( (_x) - (double) ( (int64_t) (_x) ) ) )
+#else
+ #define _frac( _x ) ( ( (_x) == 0.0 ) ? 0.0 : ( (_x) - (double) ( (long) (_x) ) ) )
+#endif
+
+
+#define _eos( _s ) ( &(_s)[strlen( _s )] )
+
+#if !defined( MIN )
+ #define MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) )
+#endif
+
+#if !defined( MAX )
+ #define MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) )
+#endif
+
+#define SWAP( _x, _y ) { temp = (_x); (_x) = (_y); (_y) = temp; }
+#define SQR( _x ) ( (_x) * (_x) )
+
+#define DP (double *)
+
+#define bcd_from_bin( _x ) ( ( ( (_x) / 10 ) << 4 ) | ( (_x) % 10 ) )
+#define bin_from_bcd( _x ) ( ( ( (_x) >> 4 ) * 10 ) + ( (_x) & 0x0F ) )
+
+
+typedef union
+{
+ uint32_t ul;
+
+ struct
+ {
+ #if defined( _CC51 ) || defined( _SH2 )
+ uint16_t hi; // big endian
+ uint16_t lo;
+ #else
+ uint16_t lo; // little endian
+ uint16_t hi;
+ #endif
+ } us;
+
+} UL;
+
+
+#ifndef _CSUM_DEFINED
+ typedef uint16_t CSUM;
+ #define _CSUM_DEFINED
+#endif
+
+
+// compute the csum of a structure
+#define _csum( _p ) checksum( (void _CSFAR *)(_p), sizeof( *(_p) ) )
+
+// set a structure's csum
+#define _set_csum( _p ) (_p)->csum = _csum( (_p) )
+
+// compare a structure's computed csum with its csum field
+#define _valid_csum( _p ) ( (_p)->csum == _csum( (_p) ) )
+
+// check if a value is in range
+#define _inrange( _val, _min, _max ) \
+ ( ( (_val) >= (_min) ) && ( (_val) <= (_max) ) )
+
+// Return a bit mask with (_n) LSBs set to 1
+#define _mask( _n ) \
+ ( ( 1UL << (_n) ) - 1 )
+
+// Return a bit mask with the (_i)th LSB set to 1
+#define _idx_bit( _i ) \
+ ( 1UL << (_i) )
+
+// Check if the (_i)th bit is set in a mask (_msk)
+#define _is_supported( _i, _msk ) \
+ ( ( (_msk) & _idx_bit( _i ) ) != 0 )
+
+// return the sign of a number
+#define _sgn( _x ) ( ( ( _x ) < 0 ) ? -1 : 1 )
+
+
+/*
+ * The macro below copies a string, taking care not to
+ * write past the end of the destination buffer, and
+ * making sure the string is terminated by 0.
+ */
+#define _strncpy_0( _dst, _src ) \
+{ \
+ int n = sizeof( _dst ) - 1; \
+ \
+ strncpy( _dst, _src, n ); \
+ (_dst)[n] = 0; \
+}
+
+
+/*
+ * The macros below set a memory range used by a variable
+ * to a specified value, avoiding the need to type the name
+ * twice for base address and size.
+ */
+#define _memfill( _p, _v ) \
+ memset( _p, _v, sizeof( *(_p) ) )
+
+#define _memclr( _p ) \
+ _memfill( _p, 0 )
+
+
+
+// generate a DOS idle interrupt to release CPU time
+#define _dos_idle() geninterrupt( 0x28 )
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ void spaces_to_zeros( char *s ) ;
+ CSUM checksum( const void _CSFAR *vp, int n ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+
+
+#endif /* _MYUTIL_H */
diff --git a/mbglib/common/pcpsdefs.h b/mbglib/common/pcpsdefs.h
index c30bffd..0c4dcd7 100644
--- a/mbglib/common/pcpsdefs.h
+++ b/mbglib/common/pcpsdefs.h
@@ -1,15 +1,53 @@
/**************************************************************************
*
- * $Id: pcpsdefs.h 1.46 2011/01/13 11:44:29Z martin REL_M $
+ * $Id: pcpsdefs.h 1.55.1.2 2014/10/17 13:28:29Z martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * General definitions for Meinberg plug-in radio clocks
+ * General definitions for Meinberg plug-in devices.
*
* -----------------------------------------------------------------------
* $Log: pcpsdefs.h $
+ * Revision 1.55.1.2 2014/10/17 13:28:29Z martin
+ * Revision 1.55.1.1 2014/10/17 11:36:44 martin
+ * Updated doxygen comments.
+ * Revision 1.55 2014/07/17 10:52:24 martin
+ * Increased safety of firmware builds.
+ * Revision 1.54 2014/07/17 09:54:19 martin
+ * New command codes PC_GPS_XMR_HOLDOVER_STATUS
+ * and PC_GPS_ALL_GPIO_STATUS.
+ * Huge update and cleanup on doxygen comments.
+ * Revision 1.53 2014/05/27 10:13:20 martin
+ * Support GPS180AMC.
+ * Moved some signal constant definitions to pcpsdefs.h.
+ * Simplified declaration of code/name tables.
+ * Huge rework of comments in doxygen format.
+ * Revision 1.52 2013/09/26 09:02:52Z martin
+ * Support GNSS API.
+ * Updated doxygen comments.
+ * Revision 1.51 2013/06/25 09:51:39 martin
+ * Support GLN180PEX.
+ * Revision 1.50 2013/01/30 15:59:54 martin
+ * Updated and fixed some doxygen comments.
+ * Revision 1.49 2012/10/02 18:53:02 martin
+ * Added structure PCPS_TIME_STATUS_X_MASKS.
+ * Added initializer for command names, useful for debugging.
+ * Revision 1.48 2011/11/25 15:02:28 martin
+ * Support on-board event logs.
+ * Revision 1.47 2011/11/25 10:22:44 martin
+ * Modified handling of pragma pack().
+ * Made command group codes obsolete. They are still supported
+ * when building firmware, though.
+ * Support PTP unicast configuration.
+ * Support GPIO configuration.
+ * Support PZF180PEX.
+ * Added commands to read CORR_INFO, read/write TR_DISTANCE,
+ * PCPS_SYNC_PZF status, and associated structures.
+ * Added an initializer for a table of GPS command code/names.
+ * Added definitions MBG_PCPS_FMT_STATUS.
+ * Updated some comments.
* Revision 1.46 2011/01/13 11:44:29Z martin
* Moved status port register definitions here.
* Revision 1.45 2010/09/06 07:36:24 martin
@@ -182,8 +220,8 @@
* Changes before put under RCS control:
*
* Revision 1.5 2000/03/24
- * Introduced PCPS_GIVE_SERNUM
- * Cleaned up for definitions for serial parameter byte
+ * Introduced PCPS_GIVE_SERNUM.
+ * Cleaned up for definitions for serial parameter byte.
* Reviewed and updated comments.
*
* 1998/07/22
@@ -192,7 +230,7 @@
* Reviewed and updated comments.
*
* 1997/06/12
- * GPS definitions added.
+ * Added GPS definitions.
*
* 1996/01/25
* PCPS_TIME redefined from an array of bytes to a structure.
@@ -208,37 +246,49 @@
#include <words.h>
#include <use_pack.h>
+#ifndef _USE_PCPSPRIV
+ #define _USE_PCPSPRIV _IS_MBG_FIRMWARE
+#endif
+
+#if _USE_PCPSPRIV
+ #include <pcpspriv.h>
+#endif
-/* Start of header body */
+/* Start of header body */
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
#endif
/**
- * The following codes enumerate the ref time sources
- * from which the clocks receive the reference time.
+ * @brief Enumeration of the ref time signal sources used by Meinberg devices
*/
-enum
+enum PCPS_REF_TYPES
{
- PCPS_REF_NONE, /**< (unknown or not defined) */
- PCPS_REF_DCF, /**< see http://www.meinberg.de/english/info/dcf77.htm */
- PCPS_REF_GPS, /**< see http://www.meinberg.de/english/info/gps.htm */
- PCPS_REF_IRIG, /**< see http://www.meinberg.de/english/info/irig.htm */
- PCPS_REF_MSF, /**< MSF Receiver (UK) */
- PCPS_REF_PTP, /**< PTP Timestamp card */
- PCPS_REF_FRC, /**< Free Running Clock */
- PCPS_REF_WWVB, /**< WWVB Receiver (US) */
- PCPS_REF_JJY, /**< JJY Receiver (Japan) */
- N_PCPS_REF /**< number of valid ref time sources */
+ PCPS_REF_NONE, ///< unknown, or not defined
+ PCPS_REF_DCF, ///< DCF77 long wave signal (Germany), see http://www.meinberg.de/english/info/dcf77.htm
+ PCPS_REF_GPS, ///< GPS satellite system, see http://www.meinberg.de/english/info/gps.htm
+ PCPS_REF_IRIG, ///< IRIG or similar time code, see http://www.meinberg.de/english/info/irig.htm
+ PCPS_REF_MSF, ///< MSF long wave signal (UK)
+ PCPS_REF_PTP, ///< PTP/IEEE1588 network protocol
+ PCPS_REF_FRC, ///< Free Running Clock
+ PCPS_REF_WWVB, ///< WWVB long wave signal (U.S.)
+ PCPS_REF_JJY, ///< JJY long wave signal (Japan)
+ N_PCPS_REF ///< number of defined ref time sources
};
-/* Initializers for the reference source names */
+/**
+ * @defgroup group_pcps_ref_type_names Reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ *
+ * @{ */
-#define PCPS_REF_NAME_NONE_ENG "unknown"
-#define PCPS_REF_NAME_NONE_GER "nicht bekannt"
+#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"
@@ -248,7 +298,14 @@ enum
#define PCPS_REF_NAME_WWVB "WWVB"
#define PCPS_REF_NAME_JJY "JJY"
+/** @} @defgroup group_pcps_ref_type_names */
+
+/**
+ * @brief Initializer for an array of English reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ */
#define PCPS_REF_NAMES_ENG \
{ \
PCPS_REF_NAME_NONE_ENG, \
@@ -263,6 +320,11 @@ enum
}
+/**
+ * @brief Initializer for a multi-language array of reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ */
#define PCPS_REF_NAMES_LSTR \
{ \
{ PCPS_REF_NAME_NONE_ENG, PCPS_REF_NAME_NONE_GER }, \
@@ -278,20 +340,30 @@ enum
-/**
- PCI vendor ID number (assigned by PCI SIG)
-*/
+/**
+ * @brief Meinberg PCI vendor ID (assigned by the PCI SIG)
+ *
+ * @see @ref MEINBERG_PCI_DEVICE_IDS
+ */
#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
- */
+
+/**
+ * @brief PCI device IDs assigned by Meinberg
+ *
+ * High byte: type of ref time source, see ::PCPS_REF_TYPES
+ * Low Byte: enumeration of device types
+ *
+ * @see ::PCI_VENDOR_MEINBERG
+ *
+ * @anchor MEINBERG_PCI_DEVICE_IDS @{ */
+
#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_PZF180PEX ( ( PCPS_REF_DCF << 8 ) | 0x06 )
#define PCI_DEV_GPS167PCI ( ( PCPS_REF_GPS << 8 ) | 0x01 )
#define PCI_DEV_GPS168PCI ( ( PCPS_REF_GPS << 8 ) | 0x02 )
@@ -299,6 +371,8 @@ enum
#define PCI_DEV_GPS170PCI ( ( PCPS_REF_GPS << 8 ) | 0x04 )
#define PCI_DEV_GPS170PEX ( ( PCPS_REF_GPS << 8 ) | 0x05 )
#define PCI_DEV_GPS180PEX ( ( PCPS_REF_GPS << 8 ) | 0x06 )
+#define PCI_DEV_GLN180PEX ( ( PCPS_REF_GPS << 8 ) | 0x07 )
+#define PCI_DEV_GPS180AMC ( ( PCPS_REF_GPS << 8 ) | 0x08 )
#define PCI_DEV_TCR510PCI ( ( PCPS_REF_IRIG << 8 ) | 0x01 )
#define PCI_DEV_TCR167PCI ( ( PCPS_REF_IRIG << 8 ) | 0x02 )
@@ -311,511 +385,556 @@ enum
#define PCI_DEV_FRC511PEX ( ( PCPS_REF_FRC << 8 ) | 0x01 )
+/** @} anchor MEINBERG_PCI_DEVICE_IDS */
-// definitions used for the status port register
-// (not to be intermixed with PCPS_TIME_STATUS)
-typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */
-/** @defgroup group_status_port Bit masks of PCPS_STATUS_PORT
+/**
+ * @defgroup group_status_port Definitions used with the status port
+ *
+ * The status port register on bus-level cards reflects some hardware
+ * signals (e.g. DCF-77 modulation), and flags used for communication
+ * with the card (e.g. the BUSY flag, ::PCPS_ST_BUSY).
+ *
+ * @note Must not be confused with ::PCPS_TIME_STATUS which returns
+ * the synchronization status and associated information
+ *
+ * @{ */
- Bit definitions used with the #PCPS_STATUS_PORT register.
+/**
+ * @brief Type of the status register port
+ */
+typedef uint8_t PCPS_STATUS_PORT; ///< see @ref PCPS_STATUS_PORT_BIT_MASKS
- The flags #PCPS_ST_SEC and #PCPS_ST_MIN are cleared whenever the clock
- is read, so they are not very reliable in multitasking environments.
- <b>NOTE</b>: The PCPS_ST_IRQF flag originates from old ISA cards.
- Some PCI cards also support this, but in case of PCI cards the
- associated flag of the PCI interface chip should be checked to see
- if a certain card has generated an IRQ on the PC bus.
+/**
+ * @brief Bit masks used with ::PCPS_STATUS_PORT
+ *
+ * The flags ::PCPS_ST_SEC and ::PCPS_ST_MIN are cleared whenever the clock
+ * is read, so they are not very reliable in multitasking environments.
+ *
+ * The ::PCPS_ST_IRQF flag originates from old ISA cards.
+ * Some PCI cards also support this, but in case of PCI cards the
+ * associated flag of the PCI interface chip should be checked to see
+ * if a particular card has generated an IRQ on the PC bus.
+ *
+ * The macro _pcps_ddev_has_gen_irq() cares about this and should be used
+ * to determine in a portable way whether a card has generated an IRQ.
+ *
+ * @anchor PCPS_STATUS_PORT_BIT_MASKS @{ */
- The macro _pcps_ddev_has_gen_irq() cares about this and should be used
- to determine in a portable way whether a card has generated an IRQ.
+#define PCPS_ST_BUSY 0x01 ///< the clock is busy filling the output FIFO
+#define PCPS_ST_IRQF 0x02 ///< the clock has generated an IRQ on the PC bus (ISA cards only)
+#define PCPS_ST_MOD 0x20 ///< the raw demodulated DCF77 signal
+#define PCPS_ST_SEC 0x40 ///< seconds have changed since last reading
+#define PCPS_ST_MIN 0x80 ///< minutes have changed since last reading
- * @{
- */
+/** @} anchor PCPS_STATUS_PORT_BIT_MASKS */
-#define PCPS_ST_BUSY 0x01 /**< the clock is busy filling the output FIFO */
-#define PCPS_ST_IRQF 0x02 /**< the clock has generated an IRQ on the PC bus (ISA only)*/
-#define PCPS_ST_MOD 0x20 /**< the raw demodulated DCF77 signal */
-#define PCPS_ST_SEC 0x40 /**< seconds have changed since last reading */
-#define PCPS_ST_MIN 0x80 /**< minutes have changed since last reading */
-
-/** @} */
-
-
-
-/** @defgroup group_cmd_bytes Command bytes used to access the device
-
- The commands described below can be used to access the Meinberg
- computer peripherals. However, some of the commands have not been
- implemented with older clock models, or firmware versions.
-
- The device driver library contains functions which detect the clocks
- and check which features are supported by a given clock model/firmware
- The header files pcpsdev.h and pcpsdrvr.h contain macros which can be
- used to query whether a detected clock supports a feature.
- If checking is required, the name of the macro is given in the
- comments below.
-
- Some commands expect parameters to be passed to the board. In that
- case, the board returns the number of parameter bytes expected when
- the command code is passed. Every parameter byte has to be supplied
- to the board exactly like a command byte.
- Refer to function pcps_write_data() and the macro _pcps_write_var()
- for details.
-
-
- - #PCPS_GIVE_TIME<br>
- Return a PCPS_TIME structure with current date,
- time and status. Supported by all clocks.
-
- - #PCPS_GIVE_TIME_NOCLEAR<br>
- Same as #PCPS_GIVE_TIME but the bits #PCPS_ST_SEC
- and #PCPS_ST_MIN (see pcpsdev.h) of the status
- port are not cleared.
- Supported by all clocks except PC31/PS31 with
- firmware version older than v3.0.
- This is mainly used by the DOS TSR and should
- not be used in other environments.
-
- - #PCPS_GIVE_SYNC_TIME<br>
- Return a ::PCPS_TIME structure with date and time
- of last synchronization of the clock or
- the last time set via the interface.
- _pcps_has_sync_time() checks whether supported.
-
- - #PCPS_GIVE_HR_TIME<br>
- Return a PCPS_HR_TIME structure with current
- date, time and status. This command should be
- used to read the clock with higher resolution.
- _pcps_has_hr_time() checks whether supported.
-
- - #PCPS_GIVE_IRIG_TIME<br>
- Return a PCPS_IRIG_TIME structure with day-of-year,
- time and status as decoded from the IRIG signal.
- _pcps_has_irig_time() checks whether supported.
-
- - #PCPS_SET_TIME<br>
- Set the board date, time and status. This
- command expects sizeof( ::PCPS_STIME ) parameter
- bytes.
- _pcps_can_set_time() checks whether supported.
-
- - #PCPS_SET_EVENT_TIME<br>
- Send a high resolution time stamp to the clock to
- configure a UTC time when the clock shall generate
- some event. This command expects a PCPS_TIME_STAMP
- parameter.
- _pcps_has_event_time() checks whether supported.
- (requires custom GPS CERN firmware)
-
- - #PCPS_IRQ_NONE<br>
- Disable the board's hardware IRQ<br>
- - #PCPS_IRQ_1_SEC<br>
- Enable hardware IRQs once per second<br>
- - #PCPS_IRQ_1_MIN<br>
- Enable hardware IRQs once per minute<br>
- - #PCPS_IRQ_10_MIN<br>
- Enable hardware IRQs once per 10 minutes<br>
- - #PCPS_IRQ_30_MIN<br>
- Enable hardware IRQs once per 30 minutes<br>
-
- - #PCPS_GET_SERIAL<br>
- #PCPS_SET_SERIAL<br>
- These commands read or set the configuration
- of a clock's serial port COM0. The commands
- expect PCPS_SERIAL_BYTES parameter bytes and
- should be used preferably with the DCF77
- clocks which have only one COM port.
- _pcps_has_serial() checks whether supported.
- Recent GPS clocks' COM ports should be cfg'd
- using the structures RECEIVER_INFO, PORT_INFO,
- and STR_TYPE_INFO.
- _pcps_has_receiver_info() checks whether
- these are supported. If they are not, then
- the code #PC_GPS_PORT_PARM together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands should be used.
-
- - #PCPS_GET_TZCODE<br>
- #PCPS_SET_TZCODE<br>
- These commands read or set a DCF77 clock's
- time zone code and should be used preferably
- with the newer DCF77 clocks which have limited
- support of different time zones.
- _pcps_has_tzcode() checks whether supported.
- A GPS clock's time zone must be cfg'd using
- the code #PC_GPS_TZDL together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands.
-
- - #PCPS_GET_PCPS_TZDL<br>
- #PCPS_SET_PCPS_TZDL<br>
- These commands read or set a DCF77 clock's
- time zone / daylight saving configuration.
- _pcps_has_pcps_tzdl() checks whether supported.
- A GPS clock's time zone must be cfg'd using
- the code #PC_GPS_TZDL together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands.
-
- - #PCPS_GET_REF_OFFS<br>
- #PCPS_SET_REF_OFFS<br>
- These commands can be used to configure the
- reference time offset from UTC for clocks
- which can't determine the offset automatically,
- e.g. from an IRIG input signal.
- _pcps_has_ref_offs() checks whether supported.
-
- - #PCPS_GET_OPT_INFO<br>
- #PCPS_SET_OPT_SETTINGS<br>
- These commands can be used to configure some
- optional settings, controlled by flags.
- When reading, the clock returns a MBG_OPT_INFO
- structure which contains the supported values,
- plus the current settings.
- When writing, clocks accepts a MBG_OPT_SETTINGS
- structure only which contain the desired settings
- of the supported flags only.
- _pcps_has_opt_flags() checks whether supported.
-
- - #PCPS_GET_IRIG_RX_INFO<br>
- #PCPS_SET_IRIG_RX_SETTINGS<br>
- #PCPS_GET_IRIG_TX_INFO<br>
- #PCPS_SET_IRIG_TX_SETTINGS<br>
- These commands can be used to configure IRIG
- inputs and outputs.<br>
- When reading, the clock returns an IRIG_INFO
- structure which contains the supported values,
- plus the current settings.<br>
- When writing, clocks accepts an IRIG_SETTINGS
- structure only which contain the desired settings
- only. _pcps_is_irig_rx() and _pcps_is_irig_tx()
- check whether supported.
-
- - #PCPS_GET_IRIG_CTRL_BITS<br>
- This command can be used to retrieve the control function
- bits of the latest IRIG input frame. Those bits may carry
- some well-known information as in the IEEE1344 code, but
- may also contain some customized information, depending on
- the IRIG frame type and the configuration of the IRIG generator.
- So these bits are returned as-is and must be interpreted
- by the application.
- _pcps_has_irig_ctrl_bits() checks whether supported.
-
- - #PCPS_GET_SYNTH<br>
- #PCPS_SET_SYNTH<br>
- #PCPS_GET_SYNTH_STATE<br>
- These commands can be used to configure an on-board
- frequency synthesizer and query the synthesizer
- status. The commands are only supported if the board
- supports the RECEIVER_INFO structure and the flag
- #GPS_HAS_SYNTH is set in the RECEIVER_INFO::features.
- _pcps_has_synth() checks whether supported.
- The structures SYNTH and SYNTH_STATE used with these
- commands are defined in gpsdefs.h.
-
- - #PCPS_GIVE_FW_ID_1<br>
- #PCPS_GIVE_FW_ID_2<br>
- Returns the first/second block of PCPS_FIFO_SIZE
- characters of the firmware ID string. These
- commands can be used to check if the board
- responds properly. This is done by the clock
- detection functions.
-
- - #PCPS_GIVE_SERNUM<br>
- Returns PCPS_FIFO_SIZE characters of the
- clock's serial number.
- _pcps_has_sernum() checks whether supported.
-
- - #PCPS_GENERIC_IO<br>
- Generic I/O read and write. Can be used to query
- specific data, e.g. a selected element of an array.
- _pcps_has_generic_io() checks whether supported.
-
- - #PCPS_GET_DEBUG_STATUS<br>
- This command reads a MBG_DEBUG_STATUS structure
- which represents the internal status of the
- IRIG decoder and some additional debug info.
- _pcps_has_debug_status() checks whether supported.
-
- - #PCPS_READ_GPS_DATA<br>
- #PCPS_WRITE_GPS_DATA<br>
- These commands are used by the functions
- pcps_read_gps_data() and pcps_write_gps_data()
- to read or write large data structures to
- Meinberg GPS plug-in clocks.
- _pcps_is_gps() checks whether supported.
-
- - #PCPS_CLR_UCAP_BUFF<br>
- Clear a clock's time capture buffer.
- _pcps_can_clr_ucap_buff() checks whether
- supported.
-
- - #PCPS_GIVE_UCAP_ENTRIES<br>
- Read a PCPS_UCAP_ENTRIES structure which
- reports the max number of entries and the
- currently used number of entries in the
- user capture buffer.
- _pcps_has_ucap() checks whether supported.
-
- - #PCPS_GIVE_UCAP_EVENT<br>
- Read capture events using a PCPS_HR_TIME
- structure. This is faster than reading using the
- GPS command #PC_GPS_UCAP. If no capture event is
- available then the structure is filled with 0s.
- _pcps_has_ucap() checks whether supported.
-
- - #PCPS_FORCE_RESET<br>
- Resets the microprocessor on the radio clock
- board. This is for debug purposes only and
- should not be used by standard applications.
-
- The command codes listed above are defined below. The commands are
- grouped for bytes having the same high nibble:
- @{
-*/
-#define PCPS_GIVE_TIME_GROUP 0x00
-#define PCPS_SET_TIME_GROUP 0x10
-#define PCPS_IRQ_GROUP 0x20
-#define PCPS_CFG_GROUP 0x30
-#define PCPS_GIVE_DATA_GROUP 0x40
-#define PCPS_GPS_DATA_GROUP 0x50
-#define PCPS_CTRL_GROUP 0x60
-#define PCPS_CFG2_GROUP 0x70
+/** @} defgroup group_status_port */
-/* 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()
+/**
+ * A format string to be used with snprintb() which is available on some Unix
+ * systems to print information held in a bit coded variable.
+ */
+#define MBG_PCPS_FMT_STATUS \
+ "\177\20b\0FREER\0b\1DL_ENB\0b\2SYNCD\0b\3DL_ANN\0b\4UTC\0b\5LS_ANN\0b\6IFTM\0b\7INVT" \
+ "\0b\x08LS_ENB\0b\11ANT_FAIL\0b\x0aLS_ANN_NEG\0b\x0bSCALE_GPS\0b\x0cSCALE_TAI\0\0"
-/* 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 )
+/**
+ * @brief Command codes used to communicate with bus level devices
+ *
+ * These commands are used for low level access to bus-level devices
+ * manufactured by Meinberg.
+ *
+ * Applications should instead use the API functions declared in mbgdevio.h.
+ *
+ * The header files pcpsdev.h and pcpsdrvr.h contain macros which can be
+ * used to check if a detected device supports a certain feature or command.
+ * If checking is required then the name of the macro is given in the
+ * comments associated with the command codes.
+ *
+ * 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_GET_CORR_INFO<br>
+ * Read PZF correlation info using a CORR_INFO
+ * structure.
+ * _pcps_has_pzf() checks whether supported.
+ *
+ * - #PCPS_GET_TR_DISTANCE<br>
+ * #PCPS_SET_TR_DISTANCE<br>
+ * Read or write distance from the RF transmitter.
+ * This is used to compensate the RF propagation delay
+ * for PZF receivers.
+ * _pcps_has_tr_distance() checks whether supported.
+ *
+ * - #PCPS_CLR_EVT_LOG<br>
+ * Clear on-board event log.
+ * _pcps_has_evt_log() checks whether supported.
+ *
+ * - #PCPS_NUM_EVT_LOG_ENTRIES<br>
+ * Read max number of num event log entries which can
+ * be saved on the board, and how many entries actually
+ * have been saved.
+ * _pcps_has_evt_log() checks whether supported.
+ *
+ * - #PCPS_FIRST_EVT_LOG_ENTRY<br>
+ * - #PCPS_NEXT_EVT_LOG_ENTRY<br>
+ * Read first (oldest) or next event log entry.
+ * _pcps_has_evt_log() checks whether supported.
+ *
+ * - #PCPS_FORCE_RESET<br>
+ * Resets the microprocessor on the device. This is
+ * for special test scenarios only and should not be
+ * used by standard applications since this may lock up
+ * the computer.
+ *
+ * @anchor PCPS_CMD_CODES @{ */
+#define PCPS_GIVE_TIME 0x00 ///< (r-) read current time in ::PCPS_TIME format
+#define PCPS_GIVE_TIME_NOCLEAR 0x01 ///< (r-) read current time in ::PCPS_TIME format, don't clear sec and min flags
+#define PCPS_GIVE_SYNC_TIME 0x02 ///< (r-) read last sync time as ::PCPS_TIME, only if ::_pcps_has_sync_time()
+#define PCPS_GIVE_HR_TIME 0x03 ///< (r-) read high res. time as ::PCPS_HR_TIME, only if ::_pcps_has_hr_time()
+#define PCPS_GIVE_IRIG_TIME 0x04 ///< (r-) read raw IRIG time as ::PCPS_IRIG_TIME, only if ::_pcps_has_irig_time()
-/* 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 )
+#define PCPS_SET_TIME 0x10 ///< (-w) set on-board time, see ::PCPS_STIME
+/* on error, return PCPS_ERR_STIME */
+#define PCPS_SET_EVENT_TIME 0x14 ///< (-w) write event time as ::PCPS_TIME_STAMP, only if ::_pcps_has_event_time()
-/* PCPS_CFG_GROUP */
+#define PCPS_IRQ_NONE 0x20 ///< (-w) disable IRQs
+#define PCPS_IRQ_1_SEC 0x21 ///< (-w) enable IRQ per 1 second
+#define PCPS_IRQ_1_MIN 0x22 ///< (-w) enable IRQ per 1 minute (deprecated)
+#define PCPS_IRQ_10_MIN 0x24 ///< (-w) enable IRQ per 10 minutes (deprecated)
+#define PCPS_IRQ_30_MIN 0x28 ///< (-w) enable IRQ per 10 minutes (deprecated)
-#define PCPS_GET_SERIAL ( PCPS_CFG_GROUP | 0x0 )
-#define PCPS_SET_SERIAL ( PCPS_CFG_GROUP | 0x1 )
+#define PCPS_GET_SERIAL 0x30 ///< (r-) read serial settings as ::PCPS_SERIAL, superseded by ::PC_GPS_ALL_PORT_INFO
+#define PCPS_SET_SERIAL 0x31 ///< (-w) write serial settings as ::PCPS_SERIAL, superseded by ::PC_GPS_PORT_SETTINGS_IDX
/* 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 )
+#define PCPS_GET_TZCODE 0x32 ///< (r-) read ::PCPS_TZCODE, only if ::_pcps_has_tzcode()
+#define PCPS_SET_TZCODE 0x33 ///< (-w) write ::PCPS_TZCODE, only if ::_pcps_has_tzcode()
/* 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 )
+#define PCPS_GET_PCPS_TZDL 0x34 ///< (r-) read ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl()
+#define PCPS_SET_PCPS_TZDL 0x35 ///< (-w) write ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl()
/* 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 0x36 ///< (r-) read ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs()
+#define PCPS_SET_REF_OFFS 0x37 ///< (-w) write ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs()
+/* on error, return PCPS_ERR_CFG */
-#define PCPS_GET_REF_OFFS ( PCPS_CFG_GROUP | 0x6 )
-#define PCPS_SET_REF_OFFS ( PCPS_CFG_GROUP | 0x7 )
+#define PCPS_GET_OPT_INFO 0x38 ///< (r-) read ::MBG_OPT_INFO, only if ::_pcps_has_opt_flags()
+#define PCPS_SET_OPT_SETTINGS 0x39 ///< (-w) write ::MBG_OPT_SETTINGS, only if ::_pcps_has_opt_flags()
/* on error, return PCPS_ERR_CFG */
-/* The associated type MBG_REF_OFFS is defined in gpsdefs.h. */
+#define PCPS_GET_IRIG_RX_INFO 0x3A ///< (r-) read ::IRIG_INFO, only if ::_pcps_is_irig_rx()
+#define PCPS_SET_IRIG_RX_SETTINGS 0x3B ///< (-w) write ::IRIG_SETTINGS, only if ::_pcps_is_irig_rx()
+/* on error, return PCPS_ERR_CFG */
+#define PCPS_GET_IRIG_TX_INFO 0x3C ///< (r-) read ::IRIG_INFO, only if ::_pcps_has_irig_tx()
+#define PCPS_SET_IRIG_TX_SETTINGS 0x3D ///< (-w) write ::IRIG_SETTINGS, only if ::_pcps_has_irig_tx()
+/* on error, return PCPS_ERR_CFG */
-#define PCPS_GET_OPT_INFO ( PCPS_CFG_GROUP | 0x8 )
-#define PCPS_SET_OPT_SETTINGS ( PCPS_CFG_GROUP | 0x9 )
+#define PCPS_GET_SYNTH 0x3E ///< (r-) read ::SYNTH, only if ::_pcps_has_synth()
+#define PCPS_SET_SYNTH 0x3F ///< (-w) write ::SYNTH, only if ::_pcps_has_synth()
/* on error, return PCPS_ERR_CFG */
-/* The associated structures MBG_OPT_INFO and MBG_OPT_SETTINGS
- are defined in gpsdefs.h. */
+#define PCPS_GIVE_FW_ID_1 0x40 ///< (r-) get first ::PCPS_FIFO_SIZE chars of firmware ID
+#define PCPS_GIVE_FW_ID_2 0x41 ///< (r-) get last ::PCPS_FIFO_SIZE chars of firmware ID
+#define PCPS_GIVE_SERNUM 0x42 ///< (r-) read serial number as ::PCPS_SN_STR, only if _pcps_has_sernum()
+#define PCPS_GENERIC_IO 0x43 ///< (rw) see pcps_generic_io() or _mbgdevio_gen_io()
+#define PCPS_GET_SYNTH_STATE 0x44 ///< (r-) read ::SYNTH_STATE, only if _pcps_has_synth()
+#define PCPS_GET_IRIG_CTRL_BITS 0x45 ///< (r-) read ::MBG_IRIG_CTRL_BITS, only if ::_pcps_has_irig_ctrl_bits()
+#define PCPS_GET_RAW_IRIG_DATA 0x46 ///< (r-) read ::MBG_RAW_IRIG_DATA, only if ::_pcps_has_raw_irig_data()
+#define PCPS_GET_STATUS_PORT 0x4B ///< (r-) read ::PCPS_STATUS_PORT
+#define PCPS_GET_DEBUG_STATUS 0x4C ///< (r-) read ::MBG_DEBUG_STATUS, only if _pcps_has_debug_status()
-#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 */
+// Command codes 0x4D, 0x4E, and 0x4F are reserved.
-#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 */
+#define PCPS_READ_GPS_DATA 0x50 ///< (r-) read large data structure, see ::PC_GPS_CMD_CODES
+#define PCPS_WRITE_GPS_DATA 0x51 ///< (-w) write large data structure, see ::PC_GPS_CMD_CODES
-/* The associated structures IRIG_INFO and IRIG_SETTINGS
- are defined in gpsdefs.h. */
+#define PCPS_CLR_UCAP_BUFF 0x60 ///< (-w) no param., clear on-board capture FIFO, only if ::_pcps_has_ucap()
+#define PCPS_GIVE_UCAP_ENTRIES 0x61 ///< (r-) read ::PCPS_UCAP_ENTRIES, only if ::_pcps_has_ucap()
+#define PCPS_GIVE_UCAP_EVENT 0x62 ///< (r-) return oldes event as ::PCPS_HR_TIME, only if ::_pcps_has_ucap()
+#define PCPS_GET_CORR_INFO 0x63 ///< (r-) read ::CORR_INFO structure, only if _pcps_has_pzf()
+#define PCPS_GET_TR_DISTANCE 0x64 ///< (r-) read ::TR_DISTANCE, only if _pcps_has_tr_distance()
+#define PCPS_SET_TR_DISTANCE 0x65 ///< (-w) write ::TR_DISTANCE, only if _pcps_has_tr_distance()
-#define PCPS_GET_SYNTH ( PCPS_CFG_GROUP | 0xE )
-#define PCPS_SET_SYNTH ( PCPS_CFG_GROUP | 0xF )
-/* on error, return PCPS_ERR_CFG */
+#define PCPS_CLR_EVT_LOG 0x66 ///< (-w) write clear on-board event log, only if _pcps_has_evt_log()
+#define PCPS_NUM_EVT_LOG_ENTRIES 0x67 ///< (r-) read ::MBG_NUM_EVT_LOG_ENTRIES, only if _pcps_has_evt_log()
+#define PCPS_FIRST_EVT_LOG_ENTRY 0x68 ///< (r-) read first (oldest) ::MBG_EVT_LOG_ENTRY, only if _pcps_has_evt_log()
+#define PCPS_NEXT_EVT_LOG_ENTRY 0x69 ///< (r-) read next ::MBG_EVT_LOG_ENTRY, only if _pcps_has_evt_log()
-/* The associated structure SYNTH is defined in gpsdefs.h. */
+#define PCPS_FORCE_RESET 0x80 ///< (-w) no param., reset the device (this can lockup the computer!!)
+/// @note Command codes 0xF0 through 0xFF are reserved.
+/** @} anchor PCPS_CMD_CODES */
-/* PCPS_GIVE_DATA_GROUP */
-#define PCPS_GIVE_FW_ID_1 ( PCPS_GIVE_DATA_GROUP | 0x0 )
-#define PCPS_GIVE_FW_ID_2 ( PCPS_GIVE_DATA_GROUP | 0x1 )
-#define PCPS_GIVE_SERNUM ( PCPS_GIVE_DATA_GROUP | 0x2 )
-#define PCPS_GENERIC_IO ( PCPS_GIVE_DATA_GROUP | 0x3 )
-#define PCPS_GET_SYNTH_STATE ( PCPS_GIVE_DATA_GROUP | 0x4 )
-#define PCPS_GET_IRIG_CTRL_BITS ( PCPS_GIVE_DATA_GROUP | 0x5 )
-#define PCPS_GET_RAW_IRIG_DATA ( PCPS_GIVE_DATA_GROUP | 0x6 )
+#if _IS_MBG_FIRMWARE
-#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
+/**
+ * @brief Deprecated command group codes
+ *
+ * @deprecated These group codes are deprecated.
+ * They should not be used anymore but removed
+ * from existing source code. The explicite command
+ * codes @ref PCPS_CMD_CODES should be used instead.
+ *
+ * @anchor PCPS_CMD_GROUP_CODES @{ */
-// PCPS_GIVE_DATA_GROUP codes 0x0D, 0x0E, and 0x0F are reserved.
+#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
+/** @} anchor PCPS_CMD_GROUP_CODES */
-/* PCPS_GPS_DATA_GROUP */
-#define PCPS_READ_GPS_DATA ( PCPS_GPS_DATA_GROUP | 0x0 )
-#define PCPS_WRITE_GPS_DATA ( PCPS_GPS_DATA_GROUP | 0x1 )
+#endif // _IS_MBG_FIRMWARE
-/* 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;
+#if !defined( MBG_CMD_TABLE_EXT )
+ #define MBG_CMD_TABLE_EXT _mbg_cn_table_end()
+#endif
-#define _mbg_swab_pcps_ucap_entries( _p ) \
-{ \
- _mbg_swab32( &(_p)->used ); \
- _mbg_swab32( &(_p)->max ); \
+/**
+ * @brief An initializer for a table of code/name entries of non-GPS commands.
+ *
+ * This can e.g. initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
+ * and may be helpful when debugging.
+ *
+ * @see @ref PCPS_CMD_CODES
+ */
+#define PCPS_CMD_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( PCPS_GIVE_TIME ), /* 0x00 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_TIME_NOCLEAR ), /* 0x01 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_SYNC_TIME ), /* 0x02 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_HR_TIME ), /* 0x03 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_IRIG_TIME ), /* 0x04 */ \
+ _mbg_cn_table_entry( PCPS_SET_TIME ), /* 0x10 */ \
+ _mbg_cn_table_entry( PCPS_SET_EVENT_TIME ), /* 0x14 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_NONE ), /* 0x20 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_1_SEC ), /* 0x21 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_1_MIN ), /* 0x22 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_10_MIN ), /* 0x24 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_30_MIN ), /* 0x28 */ \
+ _mbg_cn_table_entry( PCPS_GET_SERIAL ), /* 0x30 */ \
+ _mbg_cn_table_entry( PCPS_SET_SERIAL ), /* 0x31 */ \
+ _mbg_cn_table_entry( PCPS_GET_TZCODE ), /* 0x32 */ \
+ _mbg_cn_table_entry( PCPS_SET_TZCODE ), /* 0x33 */ \
+ _mbg_cn_table_entry( PCPS_GET_PCPS_TZDL ), /* 0x34 */ \
+ _mbg_cn_table_entry( PCPS_SET_PCPS_TZDL ), /* 0x35 */ \
+ _mbg_cn_table_entry( PCPS_GET_REF_OFFS ), /* 0x36 */ \
+ _mbg_cn_table_entry( PCPS_SET_REF_OFFS ), /* 0x37 */ \
+ _mbg_cn_table_entry( PCPS_GET_OPT_INFO ), /* 0x38 */ \
+ _mbg_cn_table_entry( PCPS_SET_OPT_SETTINGS ), /* 0x39 */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_RX_INFO ), /* 0x3A */ \
+ _mbg_cn_table_entry( PCPS_SET_IRIG_RX_SETTINGS ), /* 0x3B */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_TX_INFO ), /* 0x3C */ \
+ _mbg_cn_table_entry( PCPS_SET_IRIG_TX_SETTINGS ), /* 0x3D */ \
+ _mbg_cn_table_entry( PCPS_GET_SYNTH ), /* 0x3E */ \
+ _mbg_cn_table_entry( PCPS_SET_SYNTH ), /* 0x3F */ \
+ _mbg_cn_table_entry( PCPS_GIVE_FW_ID_1 ), /* 0x40 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_FW_ID_2 ), /* 0x41 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_SERNUM ), /* 0x42 */ \
+ _mbg_cn_table_entry( PCPS_GENERIC_IO ), /* 0x43 */ \
+ _mbg_cn_table_entry( PCPS_GET_SYNTH_STATE ), /* 0x44 */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_CTRL_BITS ), /* 0x45 */ \
+ _mbg_cn_table_entry( PCPS_GET_RAW_IRIG_DATA ), /* 0x46 */ \
+ _mbg_cn_table_entry( PCPS_GET_STATUS_PORT ), /* 0x4B */ \
+ _mbg_cn_table_entry( PCPS_GET_DEBUG_STATUS ), /* 0x4C */ \
+ _mbg_cn_table_entry( PCPS_READ_GPS_DATA ), /* 0x50 */ \
+ _mbg_cn_table_entry( PCPS_WRITE_GPS_DATA ), /* 0x51 */ \
+ _mbg_cn_table_entry( PCPS_CLR_UCAP_BUFF ), /* 0x60 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_UCAP_ENTRIES ), /* 0x61 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_UCAP_EVENT ), /* 0x62 */ \
+ _mbg_cn_table_entry( PCPS_GET_CORR_INFO ), /* 0x63 */ \
+ _mbg_cn_table_entry( PCPS_GET_TR_DISTANCE ), /* 0x64 */ \
+ _mbg_cn_table_entry( PCPS_SET_TR_DISTANCE ), /* 0x65 */ \
+ _mbg_cn_table_entry( PCPS_CLR_EVT_LOG ), /* 0x66 */ \
+ _mbg_cn_table_entry( PCPS_NUM_EVT_LOG_ENTRIES ), /* 0x67 */ \
+ _mbg_cn_table_entry( PCPS_FIRST_EVT_LOG_ENTRY ), /* 0x68 */ \
+ _mbg_cn_table_entry( PCPS_NEXT_EVT_LOG_ENTRY ), /* 0x69 */ \
+ _mbg_cn_table_entry( PCPS_FORCE_RESET ), /* 0x80 */ \
+ MBG_CMD_TABLE_EXT, \
+ _mbg_cn_table_end() \
}
/**
- special -- use with care !
-*/
-#define PCPS_FORCE_RESET 0x80
+ * @brief Bus level command return codes
+ *
+ * @deprecated These codes are deprecated and @ref MBG_RETURN_CODES should be used
+ * instead which provide corresponding symbols with same numeric values.
+ *
+ * @anchor PCPS_LEVEL_CMD_RETURN_CODES @{ */
-/** @} */
+#define PCPS_SUCCESS 0 ///< OK, no error (see ::MBG_SUCCESS)
+#define PCPS_ERR_STIME -1 ///< invalid date/time/status passed (see ::MBG_ERR_STIME)
+#define PCPS_ERR_CFG -2 ///< invalid parms for a cmd writing config parameters (see ::MBG_ERR_CFG)
-/* 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 */
+/** @} anchor PCPS_LEVEL_CMD_RETURN_CODES */
-#ifndef BITMASK
+#if !defined( BITMASK )
#define BITMASK( b ) ( ( 1 << b ) - 1 )
#endif
-/** The size of the plug-in radio clock's on-board FIFO: */
+/** @brief The size of a bus level device's command/data FIFO */
#define PCPS_FIFO_SIZE 16
+/** @brief A data buffer for a bus level device's command/data */
typedef int8_t PCPS_BUFF[PCPS_FIFO_SIZE];
-#define PCPS_ID_SIZE ( 2 * PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
+/** @brief The maximum length of an ID string, including terminating 0 */
+#define PCPS_ID_SIZE ( 2 * PCPS_FIFO_SIZE + 1 ) ///< ASCIIZ string
+
+/** @brief A buffer for an ID string, including terminating 0 */
typedef char PCPS_ID_STR[PCPS_ID_SIZE];
-#define PCPS_SN_SIZE ( PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
+/** @brief The maximum length of a serial number string, including terminating 0 */
+#define PCPS_SN_SIZE ( PCPS_FIFO_SIZE + 1 ) ///< ASCIIZ string
+
+/** @brief A buffer for a serial number string, including terminating 0 */
typedef char PCPS_SN_STR[PCPS_SN_SIZE];
+
/**
- * The structure has been introduced to be able to handle
- * high resolution time stamps.
+ * @brief A high resolution time stamp
*/
typedef struct
{
- uint32_t sec; /**< seconds since 1970 (UTC) */
- uint32_t frac; /**< fractions of second ( 0xFFFFFFFF == 0.9999.. sec) */
+ uint32_t sec; ///< seconds since 1970, usually %UTC scale
+ uint32_t frac; ///< binary fractions of second (0x80000000 == 0.5 s, 0xFFFFFFFF == 0.9999999.. s)
+
} PCPS_TIME_STAMP;
#define _mbg_swab_pcps_time_stamp( _p ) \
@@ -829,59 +948,123 @@ typedef struct
// 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
+#if defined( MBG_TGT_MISSING_64_BIT_TYPES )
#define PCPS_HRT_FRAC_CONVERSION_TYPE double
+#else
+ #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
#endif
-// Max value of PCPS_TIME_STAMP::frac + 1 used for scaling
+/**
+ * @brief Constant used to convert ::PCPS_TIME_STAMP::frac values
+ *
+ * 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
+ /**
+ * @brief Scale to be used to print ::PCPS_TIME_STAMP::frac values
+ *
+ * The function ::frac_sec_from_bin can be used for the conversion.
+ *
+ * @see ::PCPS_HRT_FRAC_SCALE_FMT
+ */
#define PCPS_HRT_FRAC_SCALE 10000000UL
#endif
#ifndef PCPS_HRT_FRAC_SCALE_FMT
+ /**
+ * @brief Format specifier used to print ::PCPS_TIME_STAMP::frac values
+ *
+ * Used to print values scaled with ::frac_sec_from_bin called
+ * with ::PCPS_HRT_FRAC_SCALE.
+ *
+ * @see ::PCPS_HRT_FRAC_SCALE
+ */
#define PCPS_HRT_FRAC_SCALE_FMT "%07lu"
#endif
-typedef uint16_t PCPS_TIME_STATUS_X; /**< extended status */
+/**
+ * @brief Extended status code
+ *
+ * Low byte corresponds to ::PCPS_TIME_STATUS, high byte
+ * contains additional flags.
+ *
+ * @see ::PCPS_TIME_STATUS
+ * @see @ref PCPS_TIME_STATUS_FLAGS
+ */
+typedef uint16_t PCPS_TIME_STATUS_X;
#define _mbg_swab_pcps_time_status_x( _p ) _mbg_swab16( _p )
+typedef struct
+{
+ PCPS_TIME_STATUS_X set_mask;
+ PCPS_TIME_STATUS_X clr_mask;
+
+} PCPS_TIME_STATUS_X_MASKS;
+
+#define _mbg_swab_pcps_time_status_x_masks( _p ) \
+{ \
+ _mbg_swab_pcps_time_status_x( &(_p)->set_mask ); \
+ _mbg_swab_pcps_time_status_x( &(_p)->clr_mask ); \
+}
+
+
+
/**
- * 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.
+ * @brief Definitions used to report a signal strength
+ *
+ * @anchor PCPS_SIG_VAL_DEFS @{ */
+
+/**
+ * @brief A data type used to report the signal value
+ */
+typedef uint8_t PCPS_SIG_VAL;
+
+// The following constants are used to draw a signal bar
+// depending on a DCF77 clock's signal value:
+#define PCPS_SIG_BIAS 55
+#define PCPS_SIG_ERR 1
+#define PCPS_SIG_MIN 20
+#define PCPS_SIG_MAX 68
+
+// These constants are used by non-DCF77 devices to indicate
+// if an input signal is available or not:
+#define PCPS_SIG_LVL_SIG_NOT_AVAIL 0
+#define PCPS_SIG_LVL_SIG_AVAIL 128
+
+/** @} anchor PCPS_SIG_VAL_DEFS */
+
+
+
+/**
+ * @brief High resolution time including status and local time offset
+ *
+ * Used to read time with high resolution of fractions of seconds and
+ * more detailed information on the local time offset and status.
+ * Should be prefered over ::PCPS_TIME.
+ *
+ * ::_pcps_has_hr_time checks whether the command ::PCPS_GIVE_TIME is
+ * supported to read a device's current time using this format.
+ *
+ * Newer devices providing time capture input may also accept the
+ * ::PCPS_GIVE_UCAP_EVENT command to read 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 this is 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_TIME_STAMP tstamp; ///< High resolution time stamp (%UTC)
+ int32_t utc_offs; ///< %UTC offs [sec] (loc_time = tstamp + utc_offs)
+ PCPS_TIME_STATUS_X status; ///< status bits, see @ref PCPS_TIME_STATUS_FLAGS
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS, or capture input channel number
+
} PCPS_HR_TIME;
#define _mbg_swab_pcps_hr_time( _p ) \
@@ -892,46 +1075,73 @@ typedef struct
}
+/**
+ * @brief Time synchronization status
+ *
+ * Used by legacy API calls. New API calls provide
+ * an extended status word ::PCPS_TIME_STATUS_X.
+ *
+ * @see ::PCPS_TIME_STATUS_FLAGS_COMMON
+ * @see ::PCPS_TIME_STATUS_X
+ */
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
+
+
+/**
+ * @brief Local calendar date and time, plus sync status
+ *
+ * This legacy structure is supported by all bus level devices but
+ * has a time resultion of 10 ms only. For more accurate time stamps
+ * the structures ::PCPS_HR_TIME and ::PCPS_TIME_STAMP should be
+ * used preferably.
+ *
+ * @see ::PCPS_HR_TIME
+ * @see ::PCPS_TIME_STAMP
+ * @see ::PCPS_STIME
+ */
+typedef struct
{
- 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() */
+ uint8_t sec100; ///< hundredths of seconds, 0..99, 10 ms resolution
+ 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 ::PCPS_TIME_STATUS_FLAGS_COMMON
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+ int8_t offs_utc; ///< [hours], 0 if not ::_pcps_has_utc_offs
+
} PCPS_TIME;
-/**
- The structure is passed as parameter with the PCPS_SET_TIME cmd
-*/
-typedef struct PCPS_STIME_s
+
+/**
+ * @brief Date time and status used with the ::PCPS_SET_TIME command
+ *
+ * Similar to ::PCPS_TIME, but missing the ::PCPS_TIME::signal
+ * and ::PCPS_TIME::offs_utc fields.
+ *
+ * @see ::PCPS_TIME
+ */
+typedef struct
{
- 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 sec100; ///< hundredths of seconds, 0..99, 10 ms resolution
+ 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
- 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 ::PCPS_TIME_STATUS_FLAGS_COMMON
- PCPS_TIME_STATUS status; /**< status bits, see below */
} PCPS_STIME;
#ifdef _C166
@@ -950,32 +1160,35 @@ 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
+ * @brief Raw IRIG time
+ *
+ * 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 ::PCPS_IRIG_TIME::frac field
+ * depends on the update interval at which the structure is updated
+ * by the firmeware. I.e., if the raw IRIG time is updated only
+ * once per second, the ::PCPS_IRIG_TIME::frac value can always be 0.
+ */
+typedef struct
{
- 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_TIME_STATUS_X status; ///< status bits, see @ref PCPS_TIME_STATUS_FLAGS
+ int16_t offs_utc; ///< [minutes], 0 unless supported by the code format, see ::ICODE_RX_CODES and @ref group_icode
+ 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 time code, see ::ICODE_RX_CODES and @ref group_icode
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+ uint8_t reserved; ///< currently not used, always 0
+
} PCPS_IRIG_TIME;
#define _mbg_swab_pcps_irig_time( _p ) \
@@ -988,81 +1201,120 @@ typedef struct PCPS_IRIG_TIME_s
+/**
+ * @brief Time status flags
+ *
+ * @anchor PCPS_TIME_STATUS_FLAGS @{ */
-/* 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 */
+/**
+ * @brief Legacy time status flags
+ *
+ * Bit masks used with both ::PCPS_TIME_STATUS and ::PCPS_TIME_STATUS_X
+ */
+enum PCPS_TIME_STATUS_FLAGS_COMMON
+{
+ PCPS_FREER = 0x01, ///< long wave or time code receiver running on xtal, satellite receiver has not verified its position
+ PCPS_DL_ENB = 0x02, ///< daylight saving currently enabled
+ PCPS_SYNCD = 0x04, ///< long wave or time code receiver has sync'ed at least once after pwr up, sat receiver is synchronized
+ PCPS_DL_ANN = 0x08, ///< a change in daylight saving status is announced
+ PCPS_UTC = 0x10, ///< returned time is always %UTC instead of some local time
+ PCPS_LS_ANN = 0x20, ///< leap second announced, for *very* old clocks see ::REV_PCPS_LS_ANN_PC31PS31
+ PCPS_IFTM = 0x40, ///< the current time has been set by an API call, for *very* old clocks see ::REV_PCPS_IFTM_PC31PS31
+ PCPS_INVT = 0x80 ///< invalid time because battery had been disconnected, or absolute time can't be decoded safely
+};
-#define PCPS_DL_ANN 0x08 /**< a change in daylight saving is announced */
-#define PCPS_UTC 0x10 /**< a special UTC firmware is installed */
+/**
+ * @brief Extended time status flags
+ *
+ * Bit masks used with ::PCPS_TIME_STATUS_X only
+ */
+enum PCPS_TIME_STATUS_FLAGS_EXT
+{
+ PCPS_LS_ENB = 0x0100, ///< current second is leap second
+ PCPS_ANT_FAIL = 0x0200, ///< antenna failure
+ PCPS_LS_ANN_NEG = 0x0400, ///< announced leap second is negative
+ PCPS_SCALE_GPS = 0x0800, ///< time stamp is GPS scale
+ PCPS_SCALE_TAI = 0x1000, ///< time stamp is TAI scale
+
+ PCPS_UCAP_OVERRUN = 0x2000, ///< events interval too short (capture events only)
+ PCPS_UCAP_BUFFER_FULL = 0x4000, ///< events read too slow (capture events only)
+
+ /**
+ * Bit masks used only with time stamps representing the current board time.
+ * A DCF77 PZF receiver can set this bit if it is actually synchronized
+ * using PZF correlation and thus provides higher accuracy than AM receivers.
+ * Same numeric code as ::PCPS_UCAP_OVERRUN
+ */
+ PCPS_SYNC_PZF = 0x2000,
+
+ /**
+ * Immediately after a clock has been accessed, subsequent accesses
+ * may be 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 eventually set if a program tries to read ::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.
+ */
+ PCPS_IO_BLOCKED = 0x8000
+};
-#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 */
+/**
+ * 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 )
-/* Bit masks used only with PCPS_TIME_STATUS_X */
+/** @} anchor PCPS_TIME_STATUS_FLAGS */
-#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 )
-
+ * @brief Legacy definitions used to configure a device's serial port
+ *
+ * @deprecated This structure and the associated command codes
+ * are deprecated. ::PORT_SETTINGS, ::PORT_INFO and associated
+ * definitions should be used instead, if supported.
+ *
+ * @anchor PCPS_OLD_SERIAL_CFG @{ */
/**
- * 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.
+ * @brief Configuration information for a device's serial port
+ *
+ * Used with ::PCPS_GET_SERIAL and ::PCPS_SET_SERIAL
+ *
+ * The serial interface on some old DCF77 clocks can be configured
+ * 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 assembled
+ * using the constants defined in ::PCPS_BD_CODES, ::PCPS_FR_CODES,
+ * and ::PCPS_MOD_CODES, 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
+ * For old GPS clocks refer to the comments for the ::PCPS_GET_SERIAL
* command.
*/
+typedef uint8_t PCPS_SERIAL;
+
/**
- * 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.
+ * @brief Deprecated baud rate indices
+ *
+ * @deprecated These values are deprecated.
+ * ::MBG_BAUD_RATE_CODES and associated structures
+ * should be used preferably.
+ *
+ * The sequence of codes matches the sequence
+ * defined in ::MBG_BAUD_RATE_CODES.
*/
-enum
+enum PCPS_BD_CODES
{
PCPS_BD_300,
PCPS_BD_600,
@@ -1071,202 +1323,428 @@ enum
PCPS_BD_4800,
PCPS_BD_9600,
PCPS_BD_19200,
- N_PCPS_BD /* number of codes */
+ 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 */
+#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.
+ * @brief Deprecated framing code indices
+ *
+ * @deprecated These values are deprecated.
+ * ::MBG_FRAMING_CODES and associated structures
+ * should be used preferably.
+ *
+ * Unfortunately, these framing codes can *not* simply
+ * be replaced by the newer MBG_FRAMING_... definitions
+ * since the order of indices doesn't match.
*/
-enum
+enum PCPS_FR_CODES
{
PCPS_FR_8N1,
PCPS_FR_7E2,
PCPS_FR_8N2,
PCPS_FR_8E1,
- N_PCPS_FR_DCF /* number of valid codes */
+ 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 */
+#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.
+/**
+ * @brief Deprecated codes for modes of operation
+ *
+ * @deprecated These values are deprecated.
+ * ::STR_MODES and associated structures
+ * should be used preferably.
+ *
+ * The sequence of codes matches the sequence
+ * defined in ::STR_MODES.
*/
+enum PCPS_MOD_CODES
+{
+ 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
-/**
- Modes of operation
+/** @} anchor PCPS_OLD_SERIAL_CFG */
- * 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.
+
+
+/**
+ * @brief Type of variable to hold a TZ code
+ *
+ * This is used with the PCI interface but differs from ::TZCODE
+ * which is used with the binary protocol.
+ *
+ * @see ::TZCODE
+ * @see ::TZCODE_UNION
*/
-enum
+typedef uint8_t PCPS_TZCODE;
+
+
+/**
+ * @brief Enumeration of codes used with PCPS_TZCODE
+ */
+enum PCPS_TZCODES
{
- 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 */
+ 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
};
-#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 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
+
+
+/**
+ * @brief Daylight changeover specification
+ *
+ * Used as member field of ::PCPS_TZDL only. Most devices supporting
+ * conversion to local time support the ::TZDL structure instead.
+ *
+ * @see ::TZDL
+ */
+typedef struct
+{
+ uint16_t year_or_wday; ///< The full year number, or 0..6 == Sun..Sat if the ::DL_AUTO_FLAG is set
+ uint8_t month; ///< [1..12]
+ uint8_t mday; ///< [1..31]
+ uint8_t hour; ///< [0..23]
+ uint8_t min; ///< [0..59]
+
+} PCPS_DL_ONOFF;
+
+#define _mbg_swab_pcps_dl_onoff( _p ) \
+{ \
+ _mbg_swab16( &(_p)->year_or_wday ); \
+}
+
+/**
+ * @brief A flag indicating if DST changeovers are to be computed automatically
+ *
+ * If ::PCPS_DL_ONOFF::year_or_wday is or'ed with the constant ::DL_AUTO_FLAG
+ * then 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 ::PCPS_DL_ONOFF::mday and ::PCPS_DL_ONOFF::month values specify
+ * the exact date of that year. Most devices supporting conversion to local time
+ * support the ::TZDL structure instead.
+ *
+ * @see ::TZDL
+ * @see ::PCPS_TZDL
+ */
+#define DL_AUTO_FLAG 0x8000 // also defined in gpsdefs.h
+
/**
- * 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
+ * @brief Specification of a local time zone
+ *
+ * Most devices supporting conversion to local time support
+ * the ::TZDL structure instead.
+ *
+ * @see ::DL_AUTO_FLAG
+ * @see ::TZDL
*/
+typedef struct
+{
+ int16_t offs; ///< offset from %UTC to local time [min] (local time = %UTC + offs)
+ int16_t offs_dl; ///< additional offset if DST enabled [min] (DST time = local time + offs_dl)
+ 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 ); \
+}
+
+
+
+/**
+ * @brief Status of the time capture FIFO buffer
+ *
+ * Only supported if ::RECEIVER_INFO::n_ucaps > 0.
+ */
+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 ); \
+}
+
+/**
+ * @defgroup group_pzf_supp Definitions used with PZF receivers
+ *
+ * @{ */
/**
- * Some definitions used with PZF receivers
+ * @brief Receiver distance from transmitter [km]
*/
+typedef uint16_t TR_DISTANCE; ///< Range may vary with receiver type
+
+#define _mbg_swab_tr_distance( _p ) \
+ _mbg_swab16( _p )
-/* receiver distance from transmitter [km] */
-typedef uint16_t TR_DISTANCE;
-/* correlation status info */
+/**
+ * @brief PZF correlation status info
+ */
typedef struct
{
- uint8_t val; /**< correlation value, or check count if status == PZF_CORR_CHECK */
- uint8_t status; /**< status codes, see below */
- char corr_dir; /**< space, '<', or '>' */
- uint8_t signal; /**< signal level, may always be 0 for devices which do not support this */
+ uint8_t val; ///< correlation value, or check count if status ==:: PZF_CORR_CHECK
+ uint8_t status; ///< status codes, see ::PZF_CORR_STATES
+ char corr_dir; ///< space, '<', or '>', just for information
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+
} CORR_INFO;
-/** Codes used with CORR_INFO::status: */
-enum
+#define _mbg_swab_corr_info( _p ) \
+ _nop_macro_fnc()
+
+
+/**
+ * @brief Codes used with ::CORR_INFO::status
+ */
+enum PZF_CORR_STATES
{
- PZF_CORR_RAW, /**< trying raw correlation, combi receivers running in AM mode */
- PZF_CORR_CHECK, /**< raw correlation achieved, doing plausibility checks */
- PZF_CORR_FINE, /**< fine correlation achieved */
+ PZF_CORR_RAW, ///< trying raw correlation, combi receivers running in AM mode
+ PZF_CORR_CHECK, ///< raw correlation achieved, doing plausibility checks
+ PZF_CORR_FINE, ///< fine correlation achieved
N_PZF_CORR_STATE
};
+#define PZF_CORR_STATE_NAME_RAW_ENG "Searching"
+#define PZF_CORR_STATE_NAME_CHECK_ENG "Correlating"
+#define PZF_CORR_STATE_NAME_FINE_ENG "Locked"
+
+#define PZF_CORR_STATE_NAME_RAW_GER "suchen"
+#define PZF_CORR_STATE_NAME_CHECK_GER "korrelieren"
+#define PZF_CORR_STATE_NAME_FINE_GER "eingerastet"
+
+
+#define PZF_CORR_STATE_NAMES_ENG \
+{ \
+ PZF_CORR_STATE_NAME_RAW_ENG, \
+ PZF_CORR_STATE_NAME_CHECK_ENG, \
+ PZF_CORR_STATE_NAME_FINE_ENG \
+}
+
+
+#define PZF_CORR_STATE_NAMES_LSTR \
+{ \
+ { PZF_CORR_STATE_NAME_RAW_ENG, PZF_CORR_STATE_NAME_RAW_GER }, \
+ { PZF_CORR_STATE_NAME_CHECK_ENG, PZF_CORR_STATE_NAME_CHECK_GER }, \
+ { PZF_CORR_STATE_NAME_FINE_ENG, PZF_CORR_STATE_NAME_FINE_GER } \
+}
+
+/** @} defgroup group_pzf_supp */
+
+
+
/**
- * @defgroup gps_cmds_bus GPS commands passed via the system bus
+ * @brief GPS Command codes passed via the system bus
*
- * This enumeration defines the various types of data that can be read
- * from or written to Meinberg bus level devices which support this.
- * Access should be done using the functions ::pcps_read_gps_data()
- * and ::pcps_write_gps_data() since the size of some of the structures
- * exceeds the size of the devices's I/O buffer and must therefore be
- * accessed in several portions.
+ * Codes specifying various types of data that can be read from or
+ * written to Meinberg bus level devices which support this.
+ * Access is done using the low level functions ::pcps_read_gps
+ * and ::pcps_write_gps since the size of some of the structures
+ * exceeds the size of the device's I/O buffer and must therefore be
+ * accessed in several blocks.
+ *
+ * Applications should instead use the API functions declared in mbgdevio.h.
*
* The structures to be used are defined in gpsdefs.h. Not all structures
- * are supportet, yet. Check the R/W indicators for details.
+ * are supported, yet. Check the r/w indicators for details.
+ *
+ * @see @ref PCPS_CMD_CODES
+ * @see ::PC_GPS_CMD_CODES_TABLE
*/
-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
+enum PC_GPS_CMD_CODES
+{
+ // system data
+ PC_GPS_TZDL = 0, ///< (r/w) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL
+ PC_GPS_SW_REV, ///< (r/-) ::SW_REV, software revision, deprecated by ::PC_GPS_RECEIVER_INFO
+ PC_GPS_BVAR_STAT, ///< (r/-) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT
+ PC_GPS_TIME, ///< (r/w) ::TTM, current time, deprecated by ::PCPS_GIVE_HR_TIME
+ PC_GPS_POS_XYZ, ///< (-/w) ::XYZ, current position in ECEF coordinates, only if ::GPS_MODEL_HAS_POS_XYZ
+ PC_GPS_POS_LLA, ///< (-/w) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA
+ PC_GPS_PORT_PARM, ///< (r/w) ::PORT_PARM, param. of the serial ports, deprecated by ::PC_GPS_ALL_PORT_INFO
+ PC_GPS_ANT_INFO, ///< (r/-) ::ANT_INFO, time diff at sync. after antenna had been disconn., only if ::GPS_MODEL_HAS_ANT_INFO
+ PC_GPS_UCAP, ///< (r/-) ::TTM, user capture events, deprecated by ::PCPS_GIVE_UCAP_EVENT
+ PC_GPS_ENABLE_FLAGS, ///< (r/w) ::ENABLE_FLAGS, when to enable serial, pulses, and synth, only if ::GPS_MODEL_HAS_ENABLE_FLAGS
+ PC_GPS_STAT_INFO, ///< (r/-) ::GPS_STAT_INFO, satellite info, mode of operation, and DAC info, only if ::GPS_MODEL_HAS_STAT_INFO
+ PC_GPS_CMD, ///< (-/w) ::GPS_CMD, send one of the ::PC_GPS_COMMANDS
+ PC_GPS_IDENT, ///< (r/-) ::IDENT, serial number, deprecated by ::PC_GPS_RECEIVER_INFO
+ PC_GPS_POS, ///< (r/-) ::POS, position ::XYZ, ::LLA, and ::DMS combined, only if ::GPS_MODEL_HAS_POS
+ PC_GPS_ANT_CABLE_LEN, ///< (r/w) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LENGTH
+ PC_GPS_RECEIVER_INFO, ///< (r/-) ::RECEIVER_INFO, rcvr model info, only if ::PCPS_HAS_RECEIVER_INFO
+ PC_GPS_ALL_STR_TYPE_INFO, ///< (r/-) n * ::STR_TYPE_INFO_IDX, names and capabilities of all supp. string types, only if ::RECEIVER_INFO::n_str_type > 0
+ PC_GPS_ALL_PORT_INFO, ///< (r/-) n * ::PORT_INFO_IDX, settings and capabilities of all serial ports, only if ::RECEIVER_INFO::n_com_ports > 0
+ PC_GPS_PORT_SETTINGS_IDX, ///< (-/w) ::PORT_SETTINGS_IDX, settings for specified serial port, only if ::RECEIVER_INFO::n_com_ports > 0
+
+ PC_GPS_ALL_POUT_INFO, ///< (r/-) n * ::POUT_INFO_IDX, all programmable output info
+ PC_GPS_POUT_SETTINGS_IDX, ///< (-/w) ::POUT_SETTINGS_IDX, settings for one programmable output
+ PC_GPS_TIME_SCALE, ///< (r/w) ::MBG_TIME_SCALE_SETTINGS / ::MBG_TIME_SCALE_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 / ::PTP_CFG_INFO, only if ::PCPS_HAS_PTP
+ PC_GPS_PTP_UC_MASTER_CFG_LIMITS, ///< (r/-) ::PTP_UC_MASTER_CFG_LIMITS, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_ALL_PTP_UC_MASTER_INFO, ///< (r/-) n * ::PTP_UC_MASTER_INFO_IDX, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, ///< (-/w) ::PTP_UC_MASTER_SETTINGS_IDX, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_GPIO_CFG_LIMITS, ///< (r/-) ::MBG_GPIO_CFG_LIMITS, only if ::GPS_HAS_GPIO
+ PC_GPS_ALL_GPIO_INFO, ///< (r/-) n * ::MBG_GPIO_INFO_IDX, all GPIO info, only if ::GPS_HAS_GPIO
+ PC_GPS_GPIO_SETTINGS_IDX, ///< (-/w) ::MBG_GPIO_SETTINGS_IDX, settings for a specific port, only if ::GPS_HAS_GPIO
+ PC_GPS_GNSS_MODE, ///< (r/w) ::MBG_GNSS_MODE_INFO / ::MBG_GNSS_MODE_SETTINGS, only if ::PCPS_IS_GNSS
+ PC_GPS_ALL_GNSS_SAT_INFO, ///< (r/-) n * ::GNSS_SAT_INFO_IDX, satellite info, only if ::PCPS_IS_GNSS
+ PC_GPS_XMR_INSTANCES, ///< (r/-) ::XMULTI_REF_INSTANCES, only if ::GPS_HAS_XMULTI_REF and ::GPS_HAS_XMRS_MULT_INSTC
+ PC_GPS_XMR_SETTINGS_IDX, ///< (-/w) ::XMULTI_REF_SETTINGS_IDX, idx 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_ALL_XMR_INFO, ///< (r/-) n * ::XMULTI_REF_INFO_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_ALL_XMR_STATUS, ///< (r/w) n * ::XMULTI_REF_STATUS_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, one structure on write, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_XMR_HOLDOVER_STATUS, ///< (r/-) ::XMR_HOLDOVER_STATUS, only if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP
+ PC_GPS_ALL_GPIO_STATUS, ///< (r/-) n * ::MBG_GPIO_STATUS_IDX, where n == ::MBG_GPIO_CFG_LIMITS::num_io, only if ::MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP
// 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
+ PC_GPS_CFGH = 0x80, ///< (-/-) ::CFGH, SVs' config. and health codes (yet not used)
+ PC_GPS_ALM, ///< (-/-) ::SV_ALM, one SV's num and almanac (yet not used)
+ PC_GPS_EPH, ///< (-/-) ::SV_EPH, one SV's num and ephemeris (yet not used)
+ PC_GPS_UTC, ///< (r/w) ::UTC, %UTC corr. param., only if ::PCPS_HAS_UTC_PARM
+ PC_GPS_IONO, ///< (-/-) ::IONO, ionospheric corr. param. (yet not used)
+ PC_GPS_ASCII_MSG ///< (-/-) ::ASCII_MSG, the GPS ASCII message (yet not used)
};
-/** codes used with PC_GPS_CMD */
-enum
+
+/**
+ * @brief An initializer for a table of code/name entries of GPS commands.
+ *
+ * This can e.g. be assigned to an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
+ * and may be helpful when debugging.
+ *
+ * @see ::PC_GPS_CMD_CODES
+ */
+#define PC_GPS_CMD_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( PC_GPS_TZDL ), \
+ _mbg_cn_table_entry( PC_GPS_SW_REV ), \
+ _mbg_cn_table_entry( PC_GPS_BVAR_STAT ), \
+ _mbg_cn_table_entry( PC_GPS_TIME ), \
+ _mbg_cn_table_entry( PC_GPS_POS_XYZ ), \
+ _mbg_cn_table_entry( PC_GPS_POS_LLA ), \
+ _mbg_cn_table_entry( PC_GPS_PORT_PARM ), \
+ _mbg_cn_table_entry( PC_GPS_ANT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_UCAP ), \
+ _mbg_cn_table_entry( PC_GPS_ENABLE_FLAGS ), \
+ _mbg_cn_table_entry( PC_GPS_STAT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_CMD ), \
+ _mbg_cn_table_entry( PC_GPS_IDENT ), \
+ _mbg_cn_table_entry( PC_GPS_POS ), \
+ _mbg_cn_table_entry( PC_GPS_ANT_CABLE_LEN ), \
+ _mbg_cn_table_entry( PC_GPS_RECEIVER_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_STR_TYPE_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_PORT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_PORT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_POUT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_POUT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_TIME_SCALE ), \
+ _mbg_cn_table_entry( PC_GPS_LAN_IF_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_IP4_STATE ), \
+ _mbg_cn_table_entry( PC_GPS_IP4_SETTINGS ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_STATE ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_CFG ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_UC_MASTER_CFG_LIMITS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_PTP_UC_MASTER_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_UC_MASTER_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_GPIO_CFG_LIMITS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GPIO_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_GPIO_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_GNSS_MODE ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GNSS_SAT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_INSTANCES ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_XMR_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_XMR_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_HOLDOVER_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GPIO_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_CFGH ), \
+ _mbg_cn_table_entry( PC_GPS_ALM ), \
+ _mbg_cn_table_entry( PC_GPS_EPH ), \
+ _mbg_cn_table_entry( PC_GPS_UTC ), \
+ _mbg_cn_table_entry( PC_GPS_IONO ), \
+ _mbg_cn_table_entry( PC_GPS_ASCII_MSG ), \
+ _mbg_cn_table_end() \
+}
+
+
+
+/**
+ * @brief Codes used with ::PC_GPS_CMD
+ *
+ * @note These commands should only used with care, in very rare cases!
+ */
+enum PC_GPS_COMMANDS //##++++++++++++++
{
- 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 */
+ PC_GPS_CMD_BOOT = 1, ///< force a GPS receiver 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_CODES ///< 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.
+
+
+/**
+ * @brief A type used to store an unambiguous command code
+ *
+ * In case of the standard @ref PCPS_CMD_CODES 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 type code from ::PC_GPS_CMD_CODES.
+ *
+ * Used internally by the firmware only.
+ */
typedef uint16_t PCPS_CMD_INFO;
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
#endif
+#define _PCPSDEFS_H_INCLUDED
+
/* End of header body */
#endif /* _PCPSDEFS_H */
diff --git a/mbglib/common/use_pack.h b/mbglib/common/use_pack.h
index 16950fa..cef3d97 100644
--- a/mbglib/common/use_pack.h
+++ b/mbglib/common/use_pack.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: use_pack.h 1.3 2011/01/26 10:01:41Z martin REL_M $
+ * $Id: use_pack.h 1.5 2012/10/12 12:40:01Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,7 +11,11 @@
*
* -----------------------------------------------------------------------
* $Log: use_pack.h $
- * Revision 1.3 2011/01/26 10:01:41Z martin
+ * Revision 1.5 2012/10/12 12:40:01Z martin
+ * Removed temporary changes.
+ * Revision 1.4 2012/10/02 18:06:25 martin
+ * Temporary changes to test alignment under Linux/Sparc.
+ * Revision 1.3 2011/01/26 10:01:41 martin
* Provided a way to suppress packing of structures on a project base.
* Revision 1.2 2002/02/25 08:50:33 Andre
* query __ARM added, __SH2 removed
diff --git a/mbglib/common/words.h b/mbglib/common/words.h
index cdb8ab3..fc35469 100644
--- a/mbglib/common/words.h
+++ b/mbglib/common/words.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: words.h 1.26 2011/04/06 10:23:03Z martin REL_M $
+ * $Id: words.h 1.34 2014/10/20 12:31:20Z martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,30 @@
*
* -----------------------------------------------------------------------
* $Log: words.h $
- * Revision 1.26 2011/04/06 10:23:03Z martin
+ * Revision 1.34 2014/10/20 12:31:20Z martin
+ * Moved macro _isdigit() here.
+ * Revision 1.33 2014/05/27 10:18:35Z martin
+ * Finer control of which types are required for or already
+ * available on particular target systems.
+ * Added macros helpful to simplify declarations of code/name tables.
+ * Revision 1.32 2014/01/07 15:43:52 martin
+ * Define __mbg_inline for ARM firmware targets.
+ * Revision 1.31 2012/11/29 11:54:39Z martin
+ * Removed #if sizeof() definitions which may cause build errors
+ * with some older compilers.
+ * Include stdbool.h for __ARMCC_VERSION targets.
+ * Moved _nop_macro_fnc() definition here.
+ * Revision 1.30 2012/11/02 09:12:29Z martin
+ * Moved most feature detection code to mbg_tgt.h.
+ * Tried to define missing features most flexibly and portably.
+ * Revision 1.29 2012/07/11 16:45:45Z martin
+ * New macros to access individual bytes of long constants.
+ * Revision 1.28 2012/04/05 14:36:18Z martin
+ * Support CVI 2010 compiler which provides C99 types.
+ * Revision 1.27 2011/07/18 10:21:38Z martin
+ * Added definition for MBG_CODE_NAME_TABLE_ENTRY which can
+ * be used to define tables assigning strings to numeric codes.
+ * Revision 1.26 2011/04/06 10:23:03 martin
* Added FBYTE_OF() and FWORD_OF() macros.
* Modifications required for *BSD.
* Revision 1.25 2010/11/17 10:23:09 martin
@@ -82,23 +105,33 @@
#if !defined( _IS_MBG_FIRMWARE )
-#if defined( _C166 ) || \
- defined( _CC51 ) || \
- defined( __ARM ) || \
- defined( __ARMCC_VERSION )
- #define _IS_MBG_FIRMWARE 1
-#else
- #define _IS_MBG_FIRMWARE 0
-#endif
-
+ #if defined( _C166 ) || \
+ defined( _CC51 ) || \
+ defined( __ARM ) || \
+ defined( __ARMCC_VERSION )
+ #define _IS_MBG_FIRMWARE 1
+ #else
+ #define _IS_MBG_FIRMWARE 0
+ #endif
#endif
+
#if !_IS_MBG_FIRMWARE
#include <mbg_tgt.h>
+#else
+ #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
+ #define __mbg_inline __inline
+ #include <stdint.h>
+ #include <stdbool.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #endif
#endif
+
#ifdef _WORDS
#define _ext
#else
@@ -108,117 +141,60 @@
/* Start of header body */
-
-// The compilers below support native bit types.
-
-#if defined( _C166 ) || defined( _CC51 )
- #define _BIT_DEFINED 1
+#if defined( _C166 ) \
+ || defined( _CC51 )
+ #define _BIT_DEFINED 1 // these compilers natively support the "bit" type
+ #define USE_LONG_FOR_INT32 1
#endif
-// 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>
- #else
- #include <stdint.h>
- #include <sys/types.h>
- #endif
-
- #define _C99_BIT_TYPES_DEFINED 1
-
-#elif defined( MBG_TGT_BSD )
+#if !defined( MBG_TGT_HAS_EXACT_SIZE_TYPES )
- #include <sys/types.h>
+ #if defined( MBG_TGT_HAS_INT_8_16_32 )
- #define _C99_BIT_TYPES_DEFINED 1
+ // Define C99 exact size types using non-standard exact-size types
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
- // avoid inclusion of stdbool.h later
- #define bit int
- #define _BIT_DEFINED 1
-
-#elif defined( MBG_TGT_QNX ) // QNX 4.x or QNX 6.x
-
- #if defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino) with gcc
- #include <stdint.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
-
-#endif
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ #else
-// If it's not yet clear whether fixed-size types are supported,
-// check the build environment which may be multi-platform.
+ // Assume a 16 or 32 bit compiler which doesn't
+ // support exact-size types.
-#if !defined( _C99_BIT_TYPES_DEFINED )
+ typedef char int8_t;
+ typedef unsigned char uint8_t;
- #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;
+ typedef short int16_t;
+ typedef unsigned short uint16_t;
- #define _C99_BIT_TYPES_DEFINED 1
- #endif
- #endif
+ // Using #if sizeof() to determine the size of a type may not
+ // be supported by all preprocessors, and may even result in
+ // build errors if used in a conditional preprocessor section,
+ // so we can't use this here without compatibility problems.
- #if defined( __BORLANDC__ )
- #if ( __BORLANDC__ >= 0x570 ) // at least Borland Developer Studio 2006
- #define _C99_BIT_TYPES_DEFINED 1
+ #if defined( USE_LONG_FOR_INT32 )
+ typedef long int32_t;
+ typedef unsigned long uint32_t;
+ #elif defined( USE_INT_FOR_INT32 )
+ typedef int int32_t;
+ typedef unsigned int uint32_t;
+ #else
+ #error Need to define int32_t and uint32_t
#endif
- #endif
-
- #if defined( __GNUC__ )
- #include <stdint.h>
- #define _C99_BIT_TYPES_DEFINED 1
- #endif
- #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
- #include <stdint.h>
- #define _C99_BIT_TYPES_DEFINED 1
#endif
-#endif
-
-
-// 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_MISSING_64_BIT_TYPES )
-
- #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
+ // The build environment does not support 64 bit types. However,
+ // 64 bit types need to be defined 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
@@ -226,45 +202,102 @@
// platform which does not support 64 bit types.
typedef void *int64_t;
typedef void *uint64_t;
+
+ #else
+
+ // Define C99 types using non-standard exact-size types
+ // which are usually supported by build envonronments
+ // supporting 64 bit types but no C99 types.
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
#endif
#endif
-#if !defined( MBG_TGT_HAS_64BIT_TYPES )
+#if defined( MBG_TGT_MISSING_64_BIT_TYPES )
#define MBG_TGT_HAS_64BIT_TYPES 0
+#else
+
+ #define MBG_TGT_HAS_64BIT_TYPES 1
+
#endif
// Some commonly used types
-typedef unsigned char uchar;
+#if !defined( _UCHAR_DEFINED )
+ typedef unsigned char uchar;
+ #define uchar uchar
+#endif
-#if !defined( MBG_TGT_LINUX ) && !( defined ( MBG_TGT_NETBSD ) && defined ( MBG_TGT_KERNEL ) )
+#if !defined( _USHORT_DEFINED )
typedef unsigned short ushort;
+ #define ushort ushort
+#endif
+
+#if !defined( _UINT_DEFINED )
typedef unsigned int uint;
+ #define uint uint
+#endif
+
+#if !defined( _ULONG_DEFINED )
typedef unsigned long ulong;
+ #define ulong ulong
+#endif
+
+#if !defined( _UDOUBLE_DEFINED )
+ typedef double udouble;
+ #define udouble udouble
+#endif
+
+#if !defined( _BYTE_DEFINED )
+ typedef unsigned char byte;
+ #define byte byte
+#endif
+
+#if !defined( _WORD_DEFINED )
+ typedef unsigned short word;
+ #define word word
#endif
-typedef double udouble;
+#if !defined( _LONGWORD_DEFINED )
+ typedef unsigned long longword;
+ #define longword longword
+#endif
+
+#if !defined( _DWORD_DEFINED )
+// typedef unsigned long dword;
+// #define dword dword
+#endif
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long longword;
-typedef unsigned long dword;
#if !defined( _BIT_DEFINED )
- #if _C99_BIT_TYPES_DEFINED
- #include <stdbool.h>
+ // We need to implement a "bit" type. Preferably we use "bool"
+ // to do this, but this is only supported by C++ compilers, and
+ // by C compilers supporting the C99 standard.
+
+ #if !defined( MBG_TGT_MISSING_BOOL_TYPE ) && \
+ ( defined( __cplusplus ) || defined( __bool_true_false_are_defined ) )
typedef bool bit;
- #else
+ #define bit bit
+
+ #else // C99 types not supported
+
+ // Falling back to use "int" for "bit". This prevents error
+ // messages if "bit" is used in function prototypes, but may
+ // yield unexpected results for code like:
+ // return (bit) ( val & 0x10 );
typedef int bit;
+ #define bit bit
+
#endif
#define _BIT_REDEFINED 1
@@ -272,11 +305,17 @@ typedef unsigned long dword;
#endif
-#define HI_BYTE( _x ) ( (_x) >> 8 )
-#define LO_BYTE( _x ) ( (_x) & 0xFF )
+#define BYTE_0( _x ) ( (uint8_t ) ( (_x) & 0xFF ) )
+#define BYTE_1( _x ) ( (uint8_t ) ( ( ( (uint16_t) (_x) ) >> 8 ) & 0xFF ) )
+#define BYTE_2( _x ) ( (uint8_t ) ( ( ( (uint32_t) (_x) ) >> 16 ) & 0xFF ) )
+#define BYTE_3( _x ) ( (uint8_t ) ( ( ( (uint32_t) (_x) ) >> 24 ) & 0xFF ) )
-#define HI_WORD( _x ) ( (_x) >> 16 )
-#define LO_WORD( _x ) ( (_x) & 0xFFFF )
+
+#define HI_BYTE( _x ) ( (uint8_t ) ( (_x) >> 8 ) )
+#define LO_BYTE( _x ) ( (uint8_t ) ( (_x) & 0xFF ) )
+
+#define HI_WORD( _x ) ( (uint16_t ) ( (_x) >> 16 ) )
+#define LO_WORD( _x ) ( (uint16_t ) ( (_x) & 0xFFFF ) )
// the macros below assume little endianess
// these macros expect the name of a variable
@@ -332,6 +371,45 @@ typedef unsigned long dword;
#define _hilo_32( _x ) (_x)
#endif
+
+#define _isdigit( _c ) ( (_c) >= '0' && (_c) <= '9' )
+
+
+// A macro function which can safely be used without
+// side effects as a macro doing nothing.
+// This is useful to define debug macros away in
+// release builds, etc.
+#if !defined( _nop_macro_fnc )
+ #define _nop_macro_fnc() do {} while (0)
+#endif
+
+
+/**
+ * @brief A table entry which can be used to map codes to names.
+ */
+typedef struct
+{
+ ulong code;
+ const char *name;
+} MBG_CODE_NAME_TABLE_ENTRY;
+
+/**
+ * @brief A macro defining a ::MBG_CODE_NAME_TABLE_ENTRY
+ *
+ * The stringified parameter is used for the name.
+ *
+ * @param _n The symbolic name of the numeric code
+ */
+#define _mbg_cn_table_entry( _n ) { _n, #_n }
+
+/**
+ * @brief A macro defining an empty ::MBG_CODE_NAME_TABLE_ENTRY
+ *
+ * This is used to terminate a table.
+ */
+#define _mbg_cn_table_end() { 0, NULL }
+
+
/* End of header body */
#undef _ext