summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2009-01-21 12:33:02 +0100
committerMartin Burnicki <martin.burnicki@meinberg.de>2009-01-21 12:33:02 +0100
commit27fbb6b9322f93e8c2c99d6f22329cd337fd655f (patch)
tree491494ba366a5bf38e55ae46f0d993753b2b12f6
parent85253751f4a8d87c1afcf7fe96608913db6006b1 (diff)
parent3cd4e43019a50a584480fc88c9de8fb0b41a0b68 (diff)
downloadmbgsdk-win-27fbb6b9322f93e8c2c99d6f22329cd337fd655f.tar.gz
mbgsdk-win-27fbb6b9322f93e8c2c99d6f22329cd337fd655f.zip
Merge branch 'mbgxhrt-demo-c'
-rw-r--r--c/demo/mbgdevio/vc6/mbgdevio.dsw29
-rw-r--r--c/demo/mbgdevio/vc6/xhrtime.dsp150
-rw-r--r--c/demo/mbgdevio/xhrtime.c327
-rw-r--r--c/demo/mbgdevio/xhrtime.exebin0 -> 49152 bytes
-rw-r--r--c/mbglib/include/gpsdefs.h3215
-rw-r--r--c/mbglib/include/gpsutils.h94
-rw-r--r--c/mbglib/include/mbgdevio.h2672
-rw-r--r--c/mbglib/include/mbgerror.h156
-rw-r--r--c/mbglib/include/mbggeo.h297
-rw-r--r--c/mbglib/include/mbgutil.h174
-rw-r--r--c/mbglib/include/pci_asic.h322
-rw-r--r--c/mbglib/include/pcpsdev.h945
-rw-r--r--c/mbglib/include/usbdefs.h114
-rw-r--r--c/mbglib/lib/msc/mbgdevio.libbin0 -> 172746 bytes
-rw-r--r--c/mbglib/lib/msc/mbgutil.libbin0 -> 45034 bytes
15 files changed, 8495 insertions, 0 deletions
diff --git a/c/demo/mbgdevio/vc6/mbgdevio.dsw b/c/demo/mbgdevio/vc6/mbgdevio.dsw
new file mode 100644
index 0000000..a862826
--- /dev/null
+++ b/c/demo/mbgdevio/vc6/mbgdevio.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "xhrtime"=.\xhrtime.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/c/demo/mbgdevio/vc6/xhrtime.dsp b/c/demo/mbgdevio/vc6/xhrtime.dsp
new file mode 100644
index 0000000..84f9582
--- /dev/null
+++ b/c/demo/mbgdevio/vc6/xhrtime.dsp
@@ -0,0 +1,150 @@
+# Microsoft Developer Studio Project File - Name="xhrtime" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=xhrtime - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "xhrtime.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "xhrtime.mak" CFG="xhrtime - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "xhrtime - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "xhrtime - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "xhrtime - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\mbglib\include" /I "..\..\mbglib\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib mbgdevio.lib mbgutil.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\mbglib\lib" /libpath:"..\..\mbglib\lib\msc"
+
+!ELSEIF "$(CFG)" == "xhrtime - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\mbglib\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mbgdevio.lib mbgutil.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\mbglib\lib\msc"
+
+!ENDIF
+
+# Begin Target
+
+# Name "xhrtime - Win32 Release"
+# Name "xhrtime - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\xhrtime.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\gpsdefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\mbg_tgt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\mbgdevio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\mbgerror.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\mbggeo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\mbgutil.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\pci_asic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\pcpsdefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\pcpsdev.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\usbdefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\use_pack.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\mbglib\include\words.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/c/demo/mbgdevio/xhrtime.c b/c/demo/mbgdevio/xhrtime.c
new file mode 100644
index 0000000..291785e
--- /dev/null
+++ b/c/demo/mbgdevio/xhrtime.c
@@ -0,0 +1,327 @@
+/**************************************************************************
+ *
+ * $Id: xhrtime.c 1.1 2009/01/07 15:21:48Z daniel TRASH daniel $
+ *
+ * Description:
+ * Main file for mbgxhrtime program which demonstrates how to retrieve
+ * fast and accurate timestamps.
+ *
+ * This program starts a polling thread which reads a high resolution
+ * time stamp and associated CPU cycles counter value once per second
+ * and saves that data pair.
+ *
+ * Current time stamps are then computed by taking the current CPU
+ * cycles value and extrapolating the time from the last data pair.
+ *
+ * This is very much faster than accessing the PCI card for every
+ * single time stamp.
+ *
+ * Notes:
+ *
+ * 1.) This approach works / makes sense only with cards which support
+ * high resolution time stamps (HR time). If a card doesn't support
+ * that then this program prints a warning.
+ *
+ * 2.) Extrapolation is done using the time stamp counter (TSC) registers
+ * provided by Pentium CPUs and newer/compatible
+ * types as the cycles counter. On SMP / multicore CPUs those
+ * counters may not be synchronized, so this works only correctly
+ * if all cycles counter values are taken from the same CPU.
+ * To achieve this the process CPU affinity is by default set to
+ * the first CPU at program start, which means all threads of this
+ * process are executed only on that CPU.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: xhrtime.c $
+ * Revision 1.1 2009/01/07 15:21:48Z daniel
+ * Initial revision
+ *
+ **************************************************************************/
+
+
+#include <mbgdevio.h>
+#include <mbgutil.h>
+
+#include <stdio.h>
+
+
+// Configuration
+#define N_LOOPS 30 // Number of time stamps
+#define USE_PCPS_HR_TIME 1 // if 1, use PCPS_HR_TIME as output format, if 0, use FILETIME.
+
+typedef union
+{
+ FILETIME ft;
+ DWORDLONG dwl;
+} FT_DWL;
+
+
+static /*HDR*/
+void err_msg( const char *msg )
+{
+ fprintf( stderr, "** %s: %i\n", msg, GetLastError() );
+
+} // err_msg
+
+
+
+static /*HDR*/
+void print_drvr_info( void )
+{
+ int rc;
+ PCPS_DRVR_INFO drvr_info;
+ MBG_DEV_HANDLE dh = mbg_open_device( 0 );
+
+ if ( dh == MBG_INVALID_DEV_HANDLE )
+ {
+ err_msg( "Unable to open device" );
+ exit( 1 );
+ }
+
+
+ rc = mbg_get_drvr_info( dh, &drvr_info );
+
+ mbg_close_device( &dh );
+
+
+ if ( rc != PCPS_SUCCESS )
+ {
+ err_msg( "Failed to read driver info" );
+ exit( 1 );
+ }
+
+ printf( "Kernel driver: %s v%i.%02i, %i device%s\n\n",
+ drvr_info.id_str,
+ drvr_info.ver_num / 100,
+ drvr_info.ver_num % 100,
+ drvr_info.n_devs,
+ ( drvr_info.n_devs == 1 ) ? "" : "s"
+ );
+
+} // print_drvr_info
+
+
+
+static /*HDR*/
+void print_dev_info( MBG_DEV_HANDLE dh,
+ PCPS_DEV *p_dev )
+{
+ int rc;
+
+ rc = mbg_get_device_info( dh, p_dev );
+
+ if ( rc == PCPS_SUCCESS )
+ {
+ _pcps_port_base( p_dev, 0 ) ?
+ printf( " %s at port %03Xh\n",
+ _pcps_fw_id( p_dev ),
+ _pcps_port_base( p_dev, 0 )
+ ) :
+ printf( " %s\n",
+ _pcps_fw_id( p_dev )
+ );
+ }
+ else
+ err_msg( "Failed to read device info" );
+
+} // print_dev_info
+
+
+
+int main( int argc, char* argv[] )
+{
+ int i;
+ int rc = 0;
+ int devices_found;
+
+ if ( mbgdevio_check_version( MBGDEVIO_VERSION ) != PCPS_SUCCESS )
+ {
+ printf( "The MBGDEVIO DLL API version %X which is installed is not compatible\n"
+ "with API version %X required by this program.\n",
+ mbgdevio_get_version(),
+ MBGDEVIO_VERSION
+ );
+ exit( 1 );
+ }
+
+ devices_found = mbg_find_devices();
+
+ if ( devices_found == 0 )
+ {
+ printf( "No radio clock found.\n" );
+ return 1;
+ }
+
+
+ printf( "Found %i radio clock%s\n",
+ devices_found,
+ ( devices_found == 1 ) ? "" : "s"
+ );
+
+
+ print_drvr_info();
+
+
+ // There may be several radio clock devices installed.
+ // Try to get information from each of the devices.
+ for ( i = 0; i < devices_found; i++ )
+ {
+ static PCPS_DEV dev;
+
+ MBG_DEV_HANDLE dh;
+
+
+ printf( "Radio clock %i:\n", i );
+
+ dh = mbg_open_device( i );
+
+ if ( dh == MBG_INVALID_DEV_HANDLE )
+ {
+ err_msg( "Unable to open device" );
+ continue;
+ }
+
+
+ print_dev_info( dh, &dev );
+ printf( "\n" );
+
+
+ // Only clocks with HR time support the extrapolation feature
+ if ( _pcps_has_hr_time( &dev ) )
+ {
+ int rc;
+ int this_loops = N_LOOPS;
+ MBG_POLL_THREAD_INFO poll_thread_info = { { { { 0 } } } };
+
+
+ // Try to start the polling thread in mbgdevio.dll
+ rc = mbg_xhrt_poll_thread_create( &poll_thread_info, dh, 0, 0 );
+
+ if ( rc != MBG_SUCCESS )
+ return -1;
+
+ for (;;)
+ {
+ static int has_printed_msg = 0;
+ MBG_PC_CYCLES cyc_1;
+ MBG_PC_CYCLES cyc_2;
+ MBG_PC_CYCLES_FREQUENCY freq_hz;
+ double access_time;
+
+ #if USE_PCPS_HR_TIME
+ PCPS_HR_TIME hrt;
+ char ws[80];
+ #else
+ FT_DWL tstamp_ft;
+ SYSTEMTIME tstamp_st, tstamp_lt;
+ TIME_ZONE_INFORMATION tzi;
+ #endif
+
+ // The frequency of the PC's cycles counter has to be computed.
+ rc = mbg_get_xhrt_cycles_frequency( &poll_thread_info.xhrt_info, &freq_hz );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail;
+
+ // As long as the frequency is 0, no valid time stamps can be received.
+ // For the caclulation of the frequency at least 2 polling cycles are needed
+ // which last 1 second by default.
+ if ( freq_hz == 0 )
+ {
+ if ( !has_printed_msg )
+ {
+ printf( "Waiting until frequency has been computed ... " );
+ has_printed_msg = 1;
+ }
+
+ Sleep( 50 );
+ continue;
+ }
+
+ if ( has_printed_msg )
+ {
+ printf( "\n" );
+ has_printed_msg = 0;
+ }
+
+ // Now the frequency is computed, we can start to get the time stamps.
+
+ // Get an extrapolated time stamp bracketed by
+ // mbg_get_pc_cycles() calls to compute the access time
+ mbg_get_pc_cycles( &cyc_1 );
+
+ #if USE_PCPS_HR_TIME
+ rc = mbg_get_xhrt_time_as_pcps_hr_time( &poll_thread_info.xhrt_info, &hrt );
+ #else
+ rc = mbg_get_xhrt_time_as_filetime( &poll_thread_info.xhrt_info, &tstamp_ft.ft );
+ #endif
+
+ mbg_get_pc_cycles( &cyc_2 );
+
+ if ( rc != MBG_SUCCESS )
+ goto fail;
+
+ // compute the access_time
+ access_time = ( (double) cyc_2 - (double) cyc_1 ) / (double) ( (int64_t) freq_hz ) * (double) 1E6;
+
+ #if USE_PCPS_HR_TIME
+
+ // Convert PCPS_HR_TIME into a readable timestamp with fractions as local time.
+ mbg_str_pcps_hr_tstamp_utc( ws, sizeof( ws ), &hrt );
+ printf( "Extrapolated ref time (UTC) : %s (%.3f us)\n", ws, access_time );
+
+ mbg_str_pcps_hr_tstamp_loc( ws, sizeof( ws ), &hrt );
+ printf( "Extrapolated ref time (LOCAL): %s (%.3f us)\n\n", ws, access_time );
+
+ #else
+
+ // Convert the FILETIME timestamps into a readable format
+ FileTimeToSystemTime( &tstamp_ft.ft, &tstamp_st );
+
+ printf("Extrapolated ref time (UTC) : %02d:%02d:%02d.%07d (%.3f us)\n",
+ tstamp_st.wHour,tstamp_st.wMinute,tstamp_st.wSecond,
+ (DWORD) ( tstamp_ft.dwl % 10000000UL ), access_time ) ;
+
+ // Convert the UTC time to local time if necessary
+ GetTimeZoneInformation( &tzi );
+
+ SystemTimeToTzSpecificLocalTime( &tzi, &tstamp_st, &tstamp_lt );
+
+ printf("Extrapolated ref time (LOCAL): %02d:%02d:%02d.%07d (%.3f us)\n\n",
+ tstamp_lt.wHour,tstamp_lt.wMinute,tstamp_lt.wSecond,
+ (DWORD) ( tstamp_ft.dwl % 10000000UL), access_time) ;
+
+ #endif
+
+ if ( this_loops > 0 )
+ this_loops--;
+
+ if ( this_loops == 0 )
+ break;
+
+ // if this_loops is < 0 then loop forever
+ }
+
+ goto done;
+
+ fail:
+ printf("** Aborting: xhrt function returned %i\n", rc );
+
+ done:
+ mbg_xhrt_poll_thread_stop( &poll_thread_info );
+
+ mbg_close_device( &dh );
+ printf( "\n" );
+ }
+ else
+ printf( "High resolution time not supported by this device.\n" );
+
+ }
+
+ printf ( "\n" );
+
+ return rc;
+}
+
+
+
diff --git a/c/demo/mbgdevio/xhrtime.exe b/c/demo/mbgdevio/xhrtime.exe
new file mode 100644
index 0000000..2aafa3a
--- /dev/null
+++ b/c/demo/mbgdevio/xhrtime.exe
Binary files differ
diff --git a/c/mbglib/include/gpsdefs.h b/c/mbglib/include/gpsdefs.h
new file mode 100644
index 0000000..c638841
--- /dev/null
+++ b/c/mbglib/include/gpsdefs.h
@@ -0,0 +1,3215 @@
+
+/**************************************************************************
+ *
+ * $Id: gpsdefs.h 1.72 2008/11/28 09:26:21Z daniel 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
+ * these definitions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: gpsdefs.h $
+ * Revision 1.72 2008/11/28 09:26:21Z daniel
+ * Added definitions to support WWVB511
+ * Revision 1.71 2008/10/31 14:31:44Z martin
+ * Added definitions for TCR170PEX.
+ * Revision 1.70 2008/09/18 11:14:39 martin
+ * Added definitions to support GEN170.
+ * Revision 1.69 2008/09/15 14:16:17 martin
+ * Added more macros to convert the endianess of structures.
+ * Added N_COM_HS to the enumeration of handshake modes.
+ * Added MBG_PS_... codes.
+ * Revision 1.68 2008/08/25 10:51:13 martin
+ * Added definitions for PTP270PEX and FRC511PEX.
+ * Revision 1.67 2008/07/17 08:54:52Z martin
+ * Added macros to convert the endianess of structures.
+ * Added multiref fixed frequency source.
+ * Revision 1.66 2008/05/19 14:49:07 daniel
+ * Renamed s_addr to start_addr in FPGA_INFO.
+ * Revision 1.65 2008/05/19 09:00:01Z martin
+ * Added definitions for GPS162.
+ * Added FPGA_INFO and GPS_HAS_FPGA.
+ * Added FPGA_START_INFO and associated definitions.
+ * Added new XMRS status XMRS_..._NOT_SETTLED.
+ * Added initializer XMULTI_REF_STATUS_INVALID.
+ * Revision 1.64 2008/01/17 11:50:33Z daniel
+ * Made IGNORE_LOCK bit maskable.
+ * Revision 1.63 2008/01/17 11:42:09Z daniel
+ * Made comments compatible for Doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.62 2007/11/15 13:23:33Z martin
+ * Decide whether other Meinberg headers are to be included depending on whether
+ * CLOCK_MEINBERG is defined (as with NTP) or not. Previous versions checked
+ * for "PACKAGE" which is also defined by the Borland C++ build environment, though.
+ * Revision 1.61 2007/11/13 13:28:54 daniel
+ * Added definitions to support GPS170PEX.
+ * Revision 1.60 2007/09/13 12:37:35Z martin
+ * Modified and added initializers for TZDL.
+ * Added multiref source PTP over E1.
+ * Added codes for MSF511 and GRC170 devices.
+ * Modified XMULTI_REF_SETTINGS and XMULTI_REF_STATUS structures.
+ * Avoid inclusion of other Meinberg headers in non-Meinberg projects.
+ * Added device classification macros _mbg_rcvr_is_...().
+ * Modified feature name string initializer for non-GPS devices.
+ * Updated some comments.
+ * Removed some obsolete comments.
+ * Revision 1.59 2007/07/19 07:41:56Z martin
+ * Added symbol MBG_REF_OFFS_NOT_CFGD.
+ * Revision 1.58 2007/05/21 15:46:44Z martin
+ * Fixed a typo.
+ * Revision 1.57 2007/03/29 12:20:43 martin
+ * Fixed some TZDL initializers.
+ * Revision 1.56 2007/02/14 14:17:10Z andre
+ * bug fixed in mask XMRS_MSK_NO_CONN
+ * Revision 1.55 2007/02/06 16:23:18Z martin
+ * Added definitions for AM511.
+ * Made SVNO unsigned.
+ * Added support for OPT_SETTINGS.
+ * Added XMULTI_REF_... definitions.
+ * Added string initializer DEFAULT_FREQ_RANGES.
+ * Revision 1.54 2007/01/04 11:39:39Z martin
+ * Added definitions for TCR511.
+ * Added definition GPS_FEAT_5_MHZ.
+ * Updated some comments related to duplicate features/options
+ * IGNORE_LOCK and EMU_SYNC.
+ * Revision 1.53 2006/12/13 09:31:49 martin
+ * Added feature flag for ignore_lock.
+ * Revision 1.52 2006/12/12 15:47:18 martin
+ * Added MBG_DEBUG_STATUS type and associated definitions.
+ * Added definition GPS_HAS_REF_OFFS.
+ * Moved PCPS_REF_OFFS and associated definitions from pcpsdefs.h here
+ * and renamed them to MBG_REF_OFFS, etc.
+ * Revision 1.51 2006/10/23 15:31:27 martin
+ * Added definitions for GPS170.
+ * Added definitions for new multi_ref sources IRIG, NTP, and PTP.
+ * Added some definitions useful when editing synth frequency.
+ * Revision 1.50 2006/08/25 09:29:28Z martin
+ * Added structure NANO_TIME.
+ * Revision 1.49 2006/08/09 07:06:42Z martin
+ * New TM_GPS status flag TM_EXT_SYNC.
+ * Revision 1.48 2006/08/08 12:51:20Z martin
+ * Added definitions for IRIG codes B006/B126 and B007/B127.
+ * Revision 1.47 2006/07/06 08:41:45Z martin
+ * Added definition of MEINBERG_MAGIC.
+ * Revision 1.46 2006/06/21 14:08:53Z martin
+ * Added masks of IRIG codes which contain time zone information.
+ * Revision 1.45 2006/06/15 12:13:32Z martin
+ * Added MULTI_REF_STATUS and associated flags.
+ * 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:
+ * Units are minutes, not seconds.
+ * Added definition for MAX_POUT_TIME_STR_PORTS.
+ * Added definitions for POUT mode 10MHz.
+ * Added hint strings for POUT modes.
+ * Added definitions for PZF511.
+ * Revision 1.43 2006/01/24 07:53:29Z martin
+ * New TM_GPS status flag TM_HOLDOVER.
+ * Revision 1.42 2005/11/24 14:53:22Z martin
+ * Added definitions for manchester encoded DC IRIG frames.
+ * Added POUT_TIMESTR and related definitions.
+ * Revision 1.41 2005/11/03 15:06:59Z martin
+ * Added definitions to support GPS170PCI.
+ * Revision 1.40 2005/10/28 08:58:29Z martin
+ * Added definitions for OCXO_DHQ.
+ * Revision 1.39 2005/09/08 14:06:00Z martin
+ * Added definition SYNTH_PHASE_SYNC_LIMIT.
+ * Revision 1.38 2005/08/18 10:27:35 andre
+ * added definitions for GPS164,
+ * added POUT_TIMECODE,
+ * struct SCU_STAT changed,
+ * ulong flags changed into two byte clk_info and ushort flags
+ * Revision 1.37 2005/05/02 14:44:55Z martin
+ * Added structure SYNTH_STATE and associated definitions.
+ * Revision 1.36 2005/03/29 12:44:07Z martin
+ * New RECEIVER_INFO::flags code: GPS_IRIG_FO_IN
+ * Revision 1.35 2004/12/09 14:04:38Z martin
+ * Changed max synth freq from 12 MHz to 10 MHz.
+ * Revision 1.34 2004/11/23 16:20:09Z martin
+ * Added bit definitions for the existing TTM status bit masks.
+ * Revision 1.33 2004/11/09 12:39:59Z martin
+ * Redefined interface data types using C99 fixed-size definitions.
+ * Added model code and name for TCR167PCI.
+ * New type GPS_CMD.
+ * Defined type BVAR_STAT and associated flags.
+ * Revision 1.32 2004/09/20 12:46:25 andre
+ * Added structures and definitions for SCU board.
+ * Revision 1.31 2004/07/08 08:30:36Z martin
+ * Added feature GPS_FEAT_RCV_TIMEOUT.
+ * Revision 1.30 2004/06/21 13:38:42 martin
+ * New flag MBG_OPT_BIT_EMU_SYNC/MBG_OPT_FLAG_EMU_SYNC
+ * lets the receicer emulate/pretend to be always synchronized.
+ * Revision 1.30 2004/06/21 13:35:46Z martin
+ * Revision 1.29 2004/06/16 12:47:53Z martin
+ * Moved OPT_SETTINGS related definitions from pcpsdefs.h
+ * here and renamed symbols from PCPS_.. to to MBG_...
+ * Revision 1.28 2004/03/26 10:37:00Z martin
+ * Added definitions to support multiple ref sources.
+ * 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
+ * renamed to GPS_FEAT_IRIG_TX.
+ * Added feature GPS_FEAT_IRIG_RX.
+ * Added IPv4 LAN interface feature flags.
+ * Renamed IFLAGS_IGNORE_TFOM to IFLAGS_DISABLE_TFOM.
+ * Revision 1.26 2003/12/05 12:28:20Z martin
+ * Added some codes used with IRIG cfg.
+ * Revision 1.25 2003/10/29 16:18:14Z martin
+ * Added 7N2 to DEFAULT_GPS_FRAMINGS_GP2021.
+ * Revision 1.24 2003/09/30 08:49:48Z martin
+ * New flag TM_LS_ANN_NEG which is set in addition to
+ * TM_LS_ANN if next leap second is negative.
+ * Revision 1.23 2003/08/26 14:32:33Z martin
+ * Added some initializers for commonly used
+ * TZDL configurations.
+ * Revision 1.22 2003/04/25 10:18:11 martin
+ * Fixed typo inside an IRIG name string initializer.
+ * Revision 1.21 2003/04/15 09:18:48 martin
+ * New typedef ANT_CABLE_LEN.
+ * 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.
+ * 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
+ * Renamed some symbols related to programmable outputs.
+ * Revision 1.16 2002/08/29 08:04:47 martin
+ * Renamed structure POUT_PROG to POUT_SETTINGS.
+ * New structures POUT_SETTINGS_IDX, POUT_INFO,
+ * POUT_INFO_IDX and associated definitions.
+ * Updated some comments.
+ * Revision 1.15 2002/07/17 07:39:39Z Andre
+ * comma added in definition DEFAULT_GPS_OSC_NAMES
+ * Revision 1.14 2002/06/27 12:17:29Z MARTIN
+ * Added new oscillator code TCXO_MQ.
+ * Added initializer for oscillator names.
+ * Added initializer for oscillator list ordered by quality.
+ * Revision 1.13 2002/05/08 08:16:03 MARTIN
+ * Added GPS_OSC_CFG_SUPP for RECEIVER_INFO.flags.
+ * Fixed some comments.
+ * Revision 1.12 2002/03/14 13:45:56 MARTIN
+ * Changed type CSUM from short to ushort.
+ * Revision 1.11 2002/03/01 12:29:30 Andre
+ * Added GPS_MODEL_GPS161 and GPS_MODEL_NAME_GPS161.
+ * Revision 1.10 2002/02/25 08:02:33Z MARTIN
+ * Added array of chars to union IDENT.
+ * Revision 1.9 2002/01/29 15:21:46 MARTIN
+ * Added new field "reserved" to struct SW_REV to fix C166 data
+ * alignment/structure size. Converted structure IDENT to a union.
+ * The changes above should not affect existing monitoring programs.
+ * New status flag TM_ANT_SHORT.
+ * New structure RECEIVER_INFO and associated definitions to
+ * enhance control from monitoring programs.
+ * New structures PORT_INFO, STR_TYPE_INFO, and associated
+ * definitions to simplify and unify configuration from external programs.
+ * New structures IRIG_INFO and POUT_PROG_IDX to configure an
+ * optional IRIG interface and programmable pulse outputs.
+ * Modified some comments.
+ * Revision 1.8 2001/03/30 11:44:11 MARTIN
+ * Control alignment of structures from new file use_pack.h.
+ * Defined initializers with valid baud rate and framing parameters.
+ * Modified some comments.
+ * Revision 1.7 2001/03/01 08:09:22 MARTIN
+ * Modified preprocessor syntax.
+ * Revision 1.6 2000/07/21 14:04:33 MARTIN
+ * Added som #if directives to protect structures against being multiply
+ * defined.
+ * Modified some comments.
+ * Comments using characters for +/- and degree now include ASCII
+ * characters only.
+ *
+ **************************************************************************/
+
+#ifndef _GPSDEFS_H
+#define _GPSDEFS_H
+
+
+/* Other headers to be included */
+
+#if defined( HAVE_CONFIG_H )
+ // this is mainly to simplify usage in non-Meinberg projects
+ #include <config.h>
+#endif
+
+// CLOCK_MEINBERG is defined in NTP's config.h if configured
+// to support Meinberg clocks.
+#if !defined( CLOCK_MEINBERG )
+ // avoid having to use these headers in non-Meinberg projects
+ #include <words.h>
+ #include <use_pack.h>
+#endif
+
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#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 */
+
+
+#define GPS_ID_STR_LEN 16
+#define GPS_ID_STR_SIZE ( GPS_ID_STR_LEN + 1 )
+
+#define GPS_EPLD_STR_LEN 8
+#define GPS_EPLD_STR_SIZE ( GPS_EPLD_STR_LEN + 1 )
+
+
+#define DEFAULT_GPS_TICKS_PER_SEC 10000000L /* system time base */
+
+#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
+ * the actual value.
+ */
+ #define GPS_TICKS_PER_SEC 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 */
+
+
+/* the type of various checksums */
+
+#ifndef _CSUM_DEFINED
+ typedef uint16_t CSUM;
+ #define _CSUM_DEFINED
+#endif
+
+
+/**
+ The type which is used to pass a cmd code via serial port, or bus.
+ The cmd codes are defined in gpsserio.h and pcpsdefs.h.
+*/
+typedef uint16_t GPS_CMD;
+
+#define _mbg_swab_gps_cmd( _p ) _mbg_swab16( _p )
+
+
+/**
+ A struct used to hold the software revision information
+ */
+typedef struct
+{
+ uint16_t code; /**< e.g. 0x0120 means rev. 1.20 */
+ char name[GPS_ID_STR_SIZE]; /**< used to identify customized versions */
+ uint8_t reserved; /**< yield even structure size */
+} SW_REV;
+
+#define _mbg_swab_sw_rev( _p ) \
+{ \
+ _mbg_swab16( &(_p)->code ); \
+}
+
+
+
+typedef uint16_t BVAR_STAT; /**< holds status of battery buffered vars */
+
+#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) )
+
+/**
+ The bits defined below are set in BVAR_STAT if the corresponding
+ parameters are NOT valid and complete:
+*/
+enum
+{
+ BVAR_BIT_CFGH_INVALID,
+ BVAR_BIT_ALM_NOT_COMPLETE,
+ BVAR_BIT_UTC_INVALID,
+ BVAR_BIT_IONO_INVALID,
+ BVAR_BIT_RCVR_POS_INVALID,
+ N_BVAR_BIT // number of defined bits
+};
+
+#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID )
+#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE )
+#define BVAR_UTC_INVALID ( 1UL << BVAR_BIT_UTC_INVALID )
+#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID )
+#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID )
+
+/**< bit mask for all defined bits */
+#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 )
+
+
+
+/* a struct used to hold a fixed frequency value */
+/* 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 */
+} FIXED_FREQ_INFO;
+
+#define _mbg_swab_fixed_freq_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->khz_val ); \
+ _mbg_swab16( &(_p)->range ); \
+}
+
+
+
+/*
+ * 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 */
+ uint32_t features; /**< optional features, see below */
+ FIXED_FREQ_INFO fixed_freq; /**< optional non-standard fixed frequency */
+ uint8_t osc_type; /**< type of installed oscillator, see below */
+ uint8_t osc_flags; /**< oscillator flags, see below */
+ uint8_t n_ucaps; /**< number of user time capture inputs */
+ uint8_t n_com_ports; /**< number of on-board serial ports */
+ uint8_t n_str_type; /**< max num of string types supported by any port */
+ uint8_t n_prg_out; /**< number of programmable pulse outputs */
+ uint16_t flags; /**< additional information, see below */
+} RECEIVER_INFO;
+
+#define _mbg_swab_receiver_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->model_code ); \
+ _mbg_swab_sw_rev( &(_p)->sw_rev ); \
+ _mbg_swab16( &(_p)->ticks_per_sec ); \
+ _mbg_swab32( &(_p)->features ); \
+ _mbg_swab_fixed_freq_info( &(_p)->fixed_freq ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
+
+
+/**
+ * Valid codes for RECEIVER_INFO.model_code:
+ */
+enum
+{
+ GPS_MODEL_UNKNOWN,
+ GPS_MODEL_GPS166,
+ GPS_MODEL_GPS167,
+ GPS_MODEL_GPS167SV,
+ GPS_MODEL_GPS167PC,
+ GPS_MODEL_GPS167PCI,
+ GPS_MODEL_GPS163,
+ GPS_MODEL_GPS168PCI,
+ GPS_MODEL_GPS161,
+ GPS_MODEL_GPS169PCI,
+ GPS_MODEL_TCR167PCI,
+ GPS_MODEL_GPS164,
+ GPS_MODEL_GPS170PCI,
+ GPS_MODEL_PZF511,
+ GPS_MODEL_GPS170,
+ GPS_MODEL_TCR511,
+ GPS_MODEL_AM511,
+ GPS_MODEL_MSF511,
+ GPS_MODEL_GRC170,
+ GPS_MODEL_GPS170PEX,
+ GPS_MODEL_GPS162,
+ GPS_MODEL_PTP270PEX,
+ GPS_MODEL_FRC511PEX,
+ GPS_MODEL_GEN170,
+ GPS_MODEL_TCR170PEX,
+ GPS_MODEL_WWVB511,
+ N_GPS_MODEL
+ /* If new model codes are added then care must be taken
+ * to update the associated string initializers below
+ * accordingly, and to check whether the classification macros
+ * also cover the new model names. */
+};
+
+
+
+
+/*
+ * String initializers for each of the GPS
+ * receiver models enum'ed above:
+ */
+#define GPS_MODEL_NAME_UNKNOWN "(unknown)"
+#define GPS_MODEL_NAME_GPS166 "GPS166"
+#define GPS_MODEL_NAME_GPS167 "GPS167"
+#define GPS_MODEL_NAME_GPS167SV "GPS167SV"
+#define GPS_MODEL_NAME_GPS167PC "GPS167PC"
+#define GPS_MODEL_NAME_GPS167PCI "GPS167PCI"
+#define GPS_MODEL_NAME_GPS163 "GPS163"
+#define GPS_MODEL_NAME_GPS168PCI "GPS168PCI"
+#define GPS_MODEL_NAME_GPS161 "GPS161"
+#define GPS_MODEL_NAME_GPS169PCI "GPS169PCI"
+#define GPS_MODEL_NAME_TCR167PCI "TCR167PCI"
+#define GPS_MODEL_NAME_GPS164 "GPS164"
+#define GPS_MODEL_NAME_GPS170PCI "GPS170PCI"
+#define GPS_MODEL_NAME_PZF511 "PZF511"
+#define GPS_MODEL_NAME_GPS170 "GPS170"
+#define GPS_MODEL_NAME_TCR511 "TCR511"
+#define GPS_MODEL_NAME_AM511 "AM511"
+#define GPS_MODEL_NAME_MSF511 "MSF511"
+#define GPS_MODEL_NAME_GRC170 "GRC170"
+#define GPS_MODEL_NAME_GPS170PEX "GPS170PEX"
+#define GPS_MODEL_NAME_GPS162 "GPS162"
+#define GPS_MODEL_NAME_PTP270PEX "PTP270PEX"
+#define GPS_MODEL_NAME_FRC511PEX "FRC511PEX"
+#define GPS_MODEL_NAME_GEN170 "GEN170"
+#define GPS_MODEL_NAME_TCR170PEX "TCR170PEX"
+#define GPS_MODEL_NAME_WWVB511 "WWVB511"
+
+
+/*
+ * 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.
+ */
+#define DEFAULT_GPS_MODEL_NAMES \
+{ \
+ GPS_MODEL_NAME_UNKNOWN, \
+ GPS_MODEL_NAME_GPS166, \
+ GPS_MODEL_NAME_GPS167, \
+ GPS_MODEL_NAME_GPS167SV, \
+ GPS_MODEL_NAME_GPS167PC, \
+ GPS_MODEL_NAME_GPS167PCI, \
+ GPS_MODEL_NAME_GPS163, \
+ GPS_MODEL_NAME_GPS168PCI, \
+ GPS_MODEL_NAME_GPS161, \
+ GPS_MODEL_NAME_GPS169PCI, \
+ GPS_MODEL_NAME_TCR167PCI, \
+ GPS_MODEL_NAME_GPS164, \
+ GPS_MODEL_NAME_GPS170PCI, \
+ GPS_MODEL_NAME_PZF511, \
+ GPS_MODEL_NAME_GPS170, \
+ GPS_MODEL_NAME_TCR511, \
+ GPS_MODEL_NAME_AM511, \
+ GPS_MODEL_NAME_MSF511, \
+ GPS_MODEL_NAME_GRC170, \
+ GPS_MODEL_NAME_GPS170PEX, \
+ GPS_MODEL_NAME_GPS162, \
+ GPS_MODEL_NAME_PTP270PEX, \
+ GPS_MODEL_NAME_FRC511PEX, \
+ GPS_MODEL_NAME_GEN170, \
+ GPS_MODEL_NAME_TCR170PEX, \
+ GPS_MODEL_NAME_WWVB511 \
+}
+
+
+/*
+ * The macros below can be used to classify a receiver,
+ * e.g. depending on the time source and/or depending on
+ * whether it's a plug-in card or an external device.
+ */
+
+#define _mbg_rcvr_is_plug_in( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "PC" ) || \
+ ( strstr( (_p_ri)->model_name, "PEX" ) )
+
+#define _mbg_rcvr_is_gps( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "GPS" ) )
+
+#define _mbg_rcvr_is_gps_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_gps( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_irig( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "TCR" ) )
+
+#define _mbg_rcvr_is_irig_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_irig( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_dcf77_am( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "AM" ) )
+
+#define _mbg_rcvr_is_dcf77_am_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_am( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_dcf77_pzf( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "PZF" ) )
+
+#define _mbg_rcvr_is_dcf77_pzf_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_pzf( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_any_dcf77( _p_ri ) \
+ ( _mbg_rcvr_is_dcf77_am( _p_ri ) || \
+ _mbg_rcvr_is_dcf77_pzf( _p_ri ) )
+
+#define _mbg_rcvr_is_any_dcf77_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_any_dcf77( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_msf( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "MSF" ) )
+
+#define _mbg_rcvr_is_msf_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_msf( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_glonass( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "GRC" ) )
+
+#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_glonass( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+#define _mbg_rcvr_is_wwvb( _p_ri ) \
+ ( strstr( (_p_ri)->model_name, "WWVB" ) )
+
+#define _mbg_rcvr_is_wwvb_plug_in( _p_ri ) \
+ ( _mbg_rcvr_is_wwvb( _p_ri ) && \
+ _mbg_rcvr_is_plug_in( _p_ri ) )
+
+
+/**
+ * The classification codes for oscillators below
+ * are used with RECEIVER_INFO.osc_type. New codes
+ * must be appended to the enumeration, so the sequence
+ * of codes does NOT reflect the order of quality:
+ */
+enum
+{
+ GPS_OSC_UNKNOWN,
+ GPS_OSC_TCXO_LQ,
+ GPS_OSC_TCXO_HQ,
+ GPS_OSC_OCXO_LQ,
+ GPS_OSC_OCXO_MQ,
+ GPS_OSC_OCXO_HQ,
+ GPS_OSC_OCXO_XHQ,
+ GPS_OSC_RUBIDIUM,
+ GPS_OSC_TCXO_MQ,
+ GPS_OSC_OCXO_DHQ,
+ N_GPS_OSC
+};
+
+
+/*
+ * The sequence and number of oscillator names
+ * listed below must correspond to the enumeration
+ * above:
+ */
+#define DEFAULT_GPS_OSC_NAMES \
+{ \
+ "- unknown -", \
+ "TCXO LQ", \
+ "TCXO HQ", \
+ "OCXO LQ", \
+ "OCXO MQ", \
+ "OCXO HQ", \
+ "OCXO XHQ", \
+ "RUBIDIUM", \
+ "TCXO MQ", \
+ "OCXO DHQ" \
+}
+
+
+/*
+ * 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:
+ */
+#define DEFAULT_GPS_OSC_QUALITY_IDX \
+{ \
+ GPS_OSC_UNKNOWN, \
+ GPS_OSC_TCXO_LQ, \
+ GPS_OSC_TCXO_MQ, \
+ GPS_OSC_TCXO_HQ, \
+ GPS_OSC_OCXO_LQ, \
+ GPS_OSC_OCXO_MQ, \
+ GPS_OSC_OCXO_HQ, \
+ GPS_OSC_OCXO_DHQ, \
+ GPS_OSC_OCXO_XHQ, \
+ GPS_OSC_RUBIDIUM \
+}
+
+
+
+/*
+ * 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.
+ */
+enum
+{
+ GPS_FEAT_PPS, /* has pulse per second output */
+ GPS_FEAT_PPM, /* has pulse per minute output */
+ GPS_FEAT_SYNTH, /* has programmable synthesizer output */
+ GPS_FEAT_DCFMARKS, /* has DCF77 compatible time mark output */
+ GPS_FEAT_IRIG_TX, /* has on-board IRIG output */
+ GPS_FEAT_IRIG_RX, /* has on-board IRIG input */
+ GPS_FEAT_LAN_IP4, /* has LAN IPv4 interface */
+ GPS_FEAT_MULTI_REF, /* has multiple input sources with priorities */
+ GPS_FEAT_RCV_TIMEOUT, /* timeout after GPS reception has stopped */
+ GPS_FEAT_IGNORE_LOCK, /* supports "ignore lock", alternatively */
+ /* MBG_OPT_BIT_EMU_SYNC may be supported */
+ GPS_FEAT_5_MHZ, /* output 5 MHz rather than 100 kHz */
+ GPS_FEAT_XMULTI_REF, /* has extended multiple input source configuration */
+ GPS_FEAT_OPT_SETTINGS, /* supports MBG_OPT_SETTINGS */
+ N_GPS_FEATURE /* the number of valid features */
+};
+
+
+#define DEFAULT_GPS_FEATURE_NAMES \
+{ \
+ "Pulse Per Second", \
+ "Pulse Per Minute", \
+ "Programmable Synth.", \
+ "DCF77 Time Marks", \
+ "IRIG Out", \
+ "IRIG In", \
+ "IPv4 LAN Interface", \
+ "Multiple Ref. Sources", \
+ "Receive Timeout", \
+ "Ignore Lock", \
+ "5 MHz Output", \
+ "Ext. Multiple Ref. Src. Cfg.", \
+ "Supp. Optional Settings" \
+}
+
+
+/*
+ * 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_REF_OFFS GPS_HAS_IRIG_RX
+
+
+/*
+ * The features below are supported by default by older
+ * C166 based GPS receivers:
+ */
+#define DEFAULT_GPS_FEATURES_C166 \
+{ \
+ GPS_HAS_PPS | \
+ GPS_HAS_PPM | \
+ GPS_HAS_SYNTH | \
+ GPS_HAS_DCFMARKS \
+}
+
+
+/*
+ * Codes to be used with RECEIVER_INFO.flags:
+ */
+#define GPS_OSC_CFG_SUPP 0x0001 // GPS_OSC_CFG supported
+#define GPS_IRIG_FO_IN 0x0002 // IRIG input via fiber optics
+#define GPS_HAS_FPGA 0x0004 // device provides on-board FPGA
+
+
+/*
+ * If the GPS_HAS_FPGA flag is set in RECEIVER_INFO::flags then the card
+ * provides an FPGA and the following information about the FPGA is available:
+ */
+#define FPGA_NAME_LEN 31 // max name length
+#define FPGA_NAME_SIZE ( FPGA_NAME_LEN + 1 ) // size including trailing 0
+
+#define FPGA_INFO_SIZE 128
+
+typedef union
+{
+ struct
+ {
+ CSUM csum;
+ uint32_t fsize;
+ uint32_t start_addr;
+ char name[FPGA_NAME_SIZE];
+ } hdr;
+
+ char b[FPGA_INFO_SIZE];
+
+} FPGA_INFO;
+
+
+
+/*
+ * The definitions below are used to specify where a FPGA image is located
+ * in the flash memory:
+ */
+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
+
+#define DEFAULT_FPGA_START_INFO \
+{ \
+ 0x1234 + DEFAULT_FPGA_START_SEG, \
+ DEFAULT_FPGA_START_SEG \
+}
+
+
+
+/* Date and time referred to the linear time scale defined by GPS. */
+/* GPS time is defined by the number of weeks since midnight from */
+/* January 5, 1980 to January 6, 1980 plus the number of seconds of */
+/* the current week plus fractions of a second. GPS time differs from */
+/* UTC because UTC is corrected with leap seconds while GPS time scale */
+/* is continuous. */
+
+typedef struct
+{
+ uint16_t wn; /* the week number since GPS has been installed */
+ uint32_t sec; /* the second of that week */
+ uint32_t tick; /* fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
+} T_GPS;
+
+#define _mbg_swab_t_gps( _p ) \
+{ \
+ _mbg_swab16( &(_p)->wn ); \
+ _mbg_swab32( &(_p)->sec ); \
+ _mbg_swab32( &(_p)->tick ); \
+}
+
+
+/* Local date and time computed from GPS time. The current number */
+/* of leap seconds have to be added to get UTC from GPS time. */
+/* Additional corrections could have been made according to the */
+/* time zone/daylight saving parameters (TZDL, see below) defined */
+/* by the user. The status field can be checked to see which corrections */
+/* have been applied. */
+
+typedef struct
+{
+ int16_t year; /* 0..9999 */
+ int8_t month; /* 1..12 */
+ int8_t mday; /* 1..31 */
+ int16_t yday; /* 1..366 */
+ int8_t wday; /* 0..6 == Sun..Sat */
+ int8_t hour; /* 0..23 */
+ int8_t min; /* 0..59 */
+ int8_t sec; /* 0..59 */
+ int32_t frac; /* fractions of a second; scale: 1/GPS_TICKS_PER_SEC*/
+ int32_t offs_from_utc; /* local time's offset from UTC */
+ uint16_t status; /* flags */
+} TM_GPS;
+
+#define _mbg_swab_tm_gps( _p ) \
+{ \
+ _mbg_swab16( &(_p)->year ); \
+ _mbg_swab16( &(_p)->yday ); \
+ _mbg_swab32( &(_p)->frac ); \
+ _mbg_swab32( &(_p)->offs_from_utc ); \
+ _mbg_swab16( &(_p)->status ); \
+}
+
+
+/* status flag bits used with conversion from GPS time to local time */
+
+enum
+{
+ 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 */
+ /* Bit 7 is reserved and not used, yet. */
+
+ TM_BIT_EXT_SYNC = 8, /* 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 */
+};
+
+
+/* bit masks corresponding to the flag bits above */
+
+#define TM_UTC ( 1U << TM_BIT_UTC )
+#define TM_LOCAL ( 1U << TM_BIT_LOCAL )
+#define TM_DL_ANN ( 1U << TM_BIT_DL_ANN )
+#define TM_DL_ENB ( 1U << TM_BIT_DL_ENB )
+#define TM_LS_ANN ( 1U << TM_BIT_LS_ANN )
+#define TM_LS_ENB ( 1U << TM_BIT_LS_ENB )
+#define TM_LS_ANN_NEG ( 1U << TM_BIT_LS_ANN_NEG )
+
+#define TM_EXT_SYNC ( 1U << TM_BIT_EXT_SYNC )
+#define TM_HOLDOVER ( 1U << TM_BIT_HOLDOVER )
+#define TM_ANT_SHORT ( 1U << TM_BIT_ANT_SHORT )
+#define TM_NO_WARM ( 1U << TM_BIT_NO_WARM )
+#define TM_ANT_DISCONN ( 1U << TM_BIT_ANT_DISCONN )
+#define TM_SYN_FLAG ( 1U << TM_BIT_SYN_FLAG )
+#define TM_NO_SYNC ( 1U << TM_BIT_NO_SYNC )
+#define TM_NO_POS ( 1U << TM_BIT_NO_POS )
+
+
+/**
+ This structure is used to transmit information on date and time
+ */
+typedef struct
+{
+ int16_t channel; /**< -1: the current time; 0, 1: capture 0, 1 */
+ T_GPS t; /**< time in GPS format */
+ TM_GPS tm; /**< that time converted to local time */
+} TTM;
+
+#define _mbg_swab_ttm( _p ) \
+{ \
+ _mbg_swab16( &(_p)->channel ); \
+ _mbg_swab_t_gps( &(_p)->t ); \
+ _mbg_swab_tm_gps( &(_p)->tm ); \
+}
+
+
+
+typedef struct
+{
+ int32_t nano_secs; // [nanoseconds]
+ int32_t secs; // [seconds]
+} NANO_TIME;
+
+#define _mbg_swab_nano_time( _p ) \
+{ \
+ _mbg_swab32( &(_p)->nano_secs ); \
+ _mbg_swab32( &(_p)->secs ); \
+}
+
+
+/* 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). */
+
+#ifndef _XYZ_DEFINED
+ /* sequence and number of components of a cartesian position */
+ enum { XP, YP, ZP, N_XYZ };
+
+ /** a type of array holding a cartesian position */
+ typedef double XYZ[N_XYZ]; /**< values are in [m] */
+
+ #define _XYZ_DEFINED
+#endif
+
+#define _mbg_swab_xyz( _p ) _mbg_swab_doubles( _p, N_XYZ )
+
+
+#ifndef _LLA_DEFINED
+ /* sequence and number of components of a geographic position */
+ enum { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
+
+ /** a type of array holding a geographic position */
+ typedef double LLA[N_LLA]; /**< lon, lat in [rad], alt in [m] */
+
+ #define _LLA_DEFINED
+#endif
+
+#define _mbg_swab_lla( _p ) _mbg_swab_doubles( _p, N_LLA )
+
+
+/**
+ @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.
+ @{
+*/
+
+#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 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 */
+/* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */
+
+/**
+ The synthesizer phase will only be synchronized if the frequency
+ is below this limit: */
+#define SYNTH_PHASE_SYNC_LIMIT 10000UL /**< 10 kHz */
+
+/**
+ the position of the decimal point if the frequency is
+ printed as 4 digit value */
+#define _synth_dp_pos_from_range( _r ) \
+ ( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 )
+
+/**
+ An initializer for commonly displayed synthesizer frequency units
+ (N_SYNTH_RANGE strings) */
+#define DEFAULT_FREQ_RANGES \
+{ \
+ "Hz", \
+ "kHz", \
+ "kHz", \
+ "kHz", \
+ "MHz", \
+ "MHz", \
+}
+
+
+
+typedef struct
+{
+ int16_t freq; /**< four digits used; scale: 0.1; e.g. 1234 -> 123.4 Hz */
+ int16_t range; /**< scale factor for freq; 0..MAX_SYNTH_RANGE */
+ int16_t phase; /**< -MAX_SYNTH_PHASE..+MAX_SYNTH_PHASE; >0 -> pulses later */
+} SYNTH;
+
+#define _mbg_swab_synth( _p ) \
+{ \
+ _mbg_swab16( &(_p)->freq ); \
+ _mbg_swab16( &(_p)->range ); \
+ _mbg_swab16( &(_p)->phase ); \
+}
+
+
+/**
+ The definitions below can be used to query the
+ current synthesizer state.
+ */
+enum
+{
+ SYNTH_DISABLED, /**< disbled by cfg, i.e. freq == 0.0 */
+ SYNTH_OFF, /**< not enabled after power-up */
+ SYNTH_FREE, /**< enabled, but not synchronized */
+ SYNTH_DRIFTING, /**< has initially been sync'd, but now running free */
+ SYNTH_SYNC, /**< fully synchronized */
+ N_SYNTH_STATE /**< the number of known states */
+};
+
+typedef struct
+{
+ uint8_t state; /**< state code as enumerated above */
+ uint8_t flags; /**< reserved, currently always 0 */
+} SYNTH_STATE;
+
+#define _mbg_swab_synth_state( _p ) _nop_macro_fnc()
+
+#define SYNTH_FLAG_PHASE_IGNORED 0x01
+
+/** @} */ // endgroup
+
+/**
+ @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 */
+typedef char TZ_NAME[6];
+
+typedef struct
+{
+ int32_t offs; /**< offset from UTC to local time [sec] */
+ int32_t offs_dl; /**< additional offset if daylight saving enabled [sec] */
+ TM_GPS tm_on; /**< date/time when daylight saving starts */
+ TM_GPS tm_off; /**< date/time when daylight saving ends */
+ TZ_NAME name[2]; /**< names without and with daylight saving enabled */
+} TZDL;
+
+#define _mbg_swab_tzdl( _p ) \
+{ \
+ _mbg_swab32( &(_p)->offs ); \
+ _mbg_swab32( &(_p)->offs_dl ); \
+ _mbg_swab_tm_gps( &(_p)->tm_on ); \
+ _mbg_swab_tm_gps( &(_p)->tm_off ); \
+}
+
+
+/**
+ If the year in tzdl.tm_on and tzdl.tm_off is or'ed with that constant,
+ the receiver automatically generates daylight saving year by year.
+ */
+#define DL_AUTO_FLAG 0x8000
+
+
+
+// Below there are some initializers for commonly used TZDL configurations:
+
+#define DEFAULT_TZDL_AUTO_YEAR ( 2007 | DL_AUTO_FLAG )
+
+#define DEFAULt_TZDL_OFFS_DL 3600L /**< usually DST is +1 hour */
+
+
+/**
+ The symbol below can be used to initialize both the tm_on
+ and tm_off fields for time zones which do not switch to DST:
+ */
+#define DEFAULT_TZDL_TM_ON_OFF_NO_DST \
+ { DEFAULT_TZDL_AUTO_YEAR, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+
+// Settings used with UTC:
+
+#define TZ_INFO_UTC "UTC (Universal Time, Coordinated)"
+
+#define DEFAULT_TZDL_NAMES_UTC { "UTC ", "UTC " }
+
+#define DEFAULT_TZDL_UTC \
+{ \
+ 0L, /**< offs */ \
+ 0L, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_UTC /**< name[] */ \
+}
+
+
+/**
+ The symbols below specify beginning and end of DST for
+ Central Europe, as constituted by the European Parliament:
+ */
+
+#define DEFAULT_TZDL_TM_ON_CET_CEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 }
+
+#define DEFAULT_TZDL_TM_OFF_CET_CEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
+
+
+// Settings used with Central European Time:
+
+#define TZ_INFO_CET_CEST_EN "CET/CEST (Central Europe)"
+#define TZ_INFO_CET_CEST_DE "MEZ/MESZ (Mitteleuropa)"
+
+#define DEFAULT_TZDL_NAMES_CET_CEST_EN { "CET ", "CEST " }
+#define DEFAULT_TZDL_NAMES_CET_CEST_DE { "MEZ ", "MESZ " }
+
+#define DEFAULT_TZDL_OFFS_CET 3600L
+
+#define DEFAULT_TZDL_CET_CEST_EN \
+{ \
+ DEFAULT_TZDL_OFFS_CET, /**< offs */ \
+ DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_EN /**< name[] */ \
+}
+
+#define DEFAULT_TZDL_CET_CEST_DE \
+{ \
+ DEFAULT_TZDL_OFFS_CET, /**< offs */ \
+ DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_DE /**< name[] */ \
+}
+
+
+// The symbols below specify beginning and end of DST for
+// Easter Europe, as constituted by the European Parliament:
+
+#define DEFAULT_TZDL_TM_ON_EET_EEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
+
+#define DEFAULT_TZDL_TM_OFF_EET_EEST \
+ { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 4, 0, 0, 0L, 0L, 0 }
+
+
+// Settings used with Eastern European Time:
+
+#define TZ_INFO_EET_EEST_EN "EET/EEST (East Europe)"
+#define TZ_INFO_EET_EEST_DE "OEZ/OEST (Osteuropa)"
+
+#define DEFAULT_TZDL_NAMES_EET_EEST_EN { "EET ", "EEST " }
+#define DEFAULT_TZDL_NAMES_EET_EEST_DE { "OEZ ", "OESZ " }
+
+#define DEFAULT_TZDL_OFFS_EET 7200L
+
+#define DEFAULT_TZDL_EET_EEST_EN \
+{ \
+ DEFAULT_TZDL_OFFS_EET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_EN /* name[] */ \
+}
+
+#define DEFAULT_TZDL_EET_EEST_DE \
+{ \
+ DEFAULT_TZDL_OFFS_EET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_DE /* name[] */ \
+}
+
+/** @} */ // endgroup
+
+/**
+ * The structure below reflects the status of the antenna,
+ * the times of last disconnect/reconnect, and the board's
+ * clock offset after the disconnection interval.
+ */
+typedef struct
+{
+ int16_t status; /**< current status of antenna */
+ TM_GPS tm_disconn; /**< time of antenna disconnect */
+ TM_GPS tm_reconn; /**< time of antenna reconnect */
+ int32_t delta_t; /**< clock offs. at reconn. time in #GPS_TICKS_PER_SEC */
+} ANT_INFO;
+
+#define _mbg_swab_ant_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->status ); \
+ _mbg_swab_tm_gps( &(_p)->tm_disconn ); \
+ _mbg_swab_tm_gps( &(_p)->tm_reconn ); \
+ _mbg_swab32( &(_p)->delta_t ); \
+}
+
+
+/**
+ The status field may be set to one of the values below:
+*/
+enum
+{
+ ANT_INVALID, /**< struct not set yet because ant. has not been disconn. */
+ ANT_DISCONN, /**< ant. now disconn., tm_reconn and delta_t not set */
+ ANT_RECONN /**< ant. has been disconn. and reconn., all fields valid */
+};
+
+/* 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.
+*/
+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 */
+} ENABLE_FLAGS;
+
+#define _mbg_swab_enable_flags( _p ) \
+{ \
+ _mbg_swab16( &(_p)->serial ); \
+ _mbg_swab16( &(_p)->pulses ); \
+ _mbg_swab16( &(_p)->freq ); \
+ _mbg_swab16( &(_p)->synth ); \
+}
+
+
+/* A struct used to hold the settings of a serial port: */
+
+#ifndef _COM_HS_DEFINED
+ /* types of handshake */
+ enum { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
+ #define _COM_HS_DEFINED
+#endif
+
+#ifndef _COM_PARM_DEFINED
+ typedef int32_t BAUD_RATE;
+
+ /* indices used to identify a parameter in the framing string */
+ enum { F_DBITS, F_PRTY, F_STBITS };
+
+ 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 */
+ } COM_PARM;
+
+ #define _COM_PARM_DEFINED
+#endif
+
+#define _mbg_swab_baud_rate( _p ) _mbg_swab32( _p )
+
+#define _mbg_swab_com_parm( _p ) \
+{ \
+ _mbg_swab_baud_rate( &(_p)->baud_rate ); \
+ _mbg_swab16( &(_p)->handshake ); \
+}
+
+
+/*
+ * Indices of any supported baud rates.
+ * Note that not each baud rate must be supported by
+ * any clock model and/or port:
+ */
+enum
+{
+ MBG_BAUD_RATE_300,
+ MBG_BAUD_RATE_600,
+ MBG_BAUD_RATE_1200,
+ MBG_BAUD_RATE_2400,
+ MBG_BAUD_RATE_4800,
+ MBG_BAUD_RATE_9600,
+ MBG_BAUD_RATE_19200,
+ MBG_BAUD_RATE_38400,
+ N_MBG_BAUD_RATES /* the number of supported baud rates */
+};
+
+/*
+ * An initializer for a table of baud rate values.
+ * The values must correspond to the enumeration above.
+ */
+#define MBG_BAUD_RATES \
+{ \
+ 300L, \
+ 600L, \
+ 1200L, \
+ 2400L, \
+ 4800L, \
+ 9600L, \
+ 19200L, \
+ 38400L \
+}
+
+/*
+ * An initializer for a table of baud rate strings.
+ * The values must correspond to the enumeration above.
+ */
+#define MBG_BAUD_STRS \
+{ \
+ "300", \
+ "600", \
+ "1200", \
+ "2400", \
+ "4800", \
+ "9600", \
+ "19200", \
+ "38400" \
+}
+
+/*
+ * 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 )
+
+
+/*
+ * Indices of any supported framings.
+ * Note that not each framing must be supported by
+ * any clock model and/or port:
+ */
+enum
+{
+ MBG_FRAMING_7N2,
+ MBG_FRAMING_7E1,
+ MBG_FRAMING_7E2,
+ MBG_FRAMING_8N1,
+ MBG_FRAMING_8N2,
+ MBG_FRAMING_8E1,
+ MBG_FRAMING_7O1,
+ MBG_FRAMING_7O2,
+ MBG_FRAMING_8O1,
+ N_MBG_FRAMINGS /* the number of supported framings */
+};
+
+/*
+ * An initializer for a table of framing strings.
+ * The values must correspond to the enumeration above.
+ */
+#define MBG_FRAMING_STRS \
+{ \
+ "7N2", \
+ "7E1", \
+ "7E2", \
+ "8N1", \
+ "8N2", \
+ "8E1", \
+ "7O1", \
+ "7O2", \
+ "8O1" \
+}
+
+/*
+ * 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:
+ */
+#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 )
+
+
+
+/*
+ * By default, the baud rates and framings below
+ * are supported by the UARTs integrated into
+ * the C166 microcontroller:
+ */
+#define DEFAULT_GPS_BAUD_RATES_C166 \
+( \
+ MBG_PORT_HAS_300 | \
+ MBG_PORT_HAS_600 | \
+ MBG_PORT_HAS_1200 | \
+ MBG_PORT_HAS_2400 | \
+ MBG_PORT_HAS_4800 | \
+ MBG_PORT_HAS_9600 | \
+ MBG_PORT_HAS_19200 \
+)
+
+#define DEFAULT_GPS_FRAMINGS_C166 \
+( \
+ MBG_PORT_HAS_7N2 | \
+ MBG_PORT_HAS_7E1 | \
+ MBG_PORT_HAS_7E2 | \
+ MBG_PORT_HAS_8N1 | \
+ MBG_PORT_HAS_8N2 | \
+ MBG_PORT_HAS_8E1 \
+)
+
+
+/*
+ * By default, the baud rates and framings below
+ * are supported by the UARTs integrated into
+ * the GP2021 chipset:
+ */
+#define DEFAULT_GPS_BAUD_RATES_GP2021 \
+( \
+ MBG_PORT_HAS_300 | \
+ MBG_PORT_HAS_600 | \
+ MBG_PORT_HAS_1200 | \
+ MBG_PORT_HAS_2400 | \
+ MBG_PORT_HAS_4800 | \
+ MBG_PORT_HAS_9600 | \
+ MBG_PORT_HAS_19200 \
+)
+
+#define DEFAULT_GPS_FRAMINGS_GP2021 \
+( \
+ MBG_PORT_HAS_7N2 | \
+ MBG_PORT_HAS_7E2 | \
+ MBG_PORT_HAS_8N1 | \
+ MBG_PORT_HAS_8E1 | \
+ MBG_PORT_HAS_8O1 \
+)
+
+
+/*
+ * 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.
+ */
+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 */
+} PORT_SETTINGS;
+
+#define _mbg_swab_port_settings( _p ) \
+{ \
+ _mbg_swab_com_parm( &(_p)->parm ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/*
+ * The definitions below can be used to mark specific fields of a
+ * PORT_SETTINGS structure, e.g. when editing build a mask indicating
+ * which of the fields have changed or which are not valid.
+ */
+enum
+{
+ MBG_PS_BIT_BAUD_RATE_OVR_SW, /* Baud rate index exceeds num supp by driver SW */
+ MBG_PS_BIT_BAUD_RATE_OVR_DEV, /* Baud rate index exceeds num supp by device */
+ MBG_PS_BIT_BAUD_RATE, /* Baud rate not supp by given port */
+ MBG_PS_BIT_FRAMING_OVR_SW, /* Framing index exceeds num supp by driver SW */
+ MBG_PS_BIT_FRAMING_OVR_DEV, /* Framing index exceeds num supp by device */
+ MBG_PS_BIT_FRAMING, /* Framing not supp by given port */
+ MBG_PS_BIT_HS_OVR_SW, /* Handshake index exceeds num supp by driver SW */
+ MBG_PS_BIT_HS, /* Handshake mode not supp by given port */
+ MBG_PS_BIT_STR_TYPE_OVR_SW, /* String type index exceeds num supp by driver SW */
+ MBG_PS_BIT_STR_TYPE_OVR_DEV, /* String type index exceeds num supp by device */
+ MBG_PS_BIT_STR_TYPE, /* String type not supp by given port */
+ MBG_PS_BIT_STR_MODE_OVR_SW, /* String mode index exceeds num supp by driver SW */
+ MBG_PS_BIT_STR_MODE_OVR_DEV, /* String mode index exceeds num supp by device */
+ MBG_PS_BIT_STR_MODE, /* String mode not supp by given port and string type */
+ MBG_PS_BIT_FLAGS_OVR_SW, /* Flags not supp by driver SW */
+ MBG_PS_BIT_FLAGS, /* Flags not supp by device */
+ N_MBG_PS_BIT
+};
+
+#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW )
+#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV )
+#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE )
+#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW )
+#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV )
+#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING )
+#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW )
+#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS )
+#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW )
+#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV )
+#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE )
+#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW )
+#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV )
+#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE )
+#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW )
+#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS )
+
+
+
+/*
+ * The structure below adds an index number to the structure
+ * above to allow addressing of several instances:
+ */
+typedef struct
+{
+ uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ PORT_SETTINGS port_settings;
+} PORT_SETTINGS_IDX;
+
+#define _mbg_swab_port_settings_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_port_settings( &(_p)->port_settings ); \
+}
+
+
+/*
+ * The structure below holds the current settings
+ * 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.
+ */
+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_INFO;
+
+#define _mbg_swab_port_info( _p ) \
+{ \
+ _mbg_swab_port_settings( &(_p)->port_settings ); \
+ _mbg_swab32( &(_p)->supp_baud_rates ); \
+ _mbg_swab32( &(_p)->supp_framings ); \
+ _mbg_swab32( &(_p)->supp_str_types ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+/*
+ * The structure below adds an index number to the structure
+ * above to allow addressing of several instances:
+ */
+typedef struct
+{
+ uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ PORT_INFO port_info;
+} PORT_INFO_IDX;
+
+#define _mbg_swab_port_info_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_port_info( &(_p)->port_info ); \
+}
+
+
+/*
+ * The structure below keeps information for a given
+ * string type, e.g. which modes can be used with that
+ * string type:
+ */
+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 */
+} STR_TYPE_INFO;
+
+#define _mbg_swab_str_type_info( _p ) \
+{ \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
+
+
+
+/*
+ * The structure below adds an index number to the structure
+ * above to allow addressing of several instances:
+ */
+typedef struct
+{
+ uint16_t idx; /* 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 ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_str_type_info( &(_p)->str_type_info ); \
+}
+
+
+/*
+ * The codes below define valid modes for time strings,
+ * i.e. the condition when a string is being sent
+ * via the serial port:
+ */
+enum
+{
+ 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 */
+};
+
+
+#define DEFAULT_SHORT_MODE_NAMES \
+{ \
+ "'?'", \
+ "1 sec", \
+ "1 min", \
+ "auto", \
+ "'?' sec" \
+}
+
+
+/*
+ * Default initializers for English mode string names. Initializers
+ * for multi-language strings can be found in pcpslstr.h.
+ */
+#define ENG_MODE_NAME_STR_ON_REQ "on request '?' only"
+#define ENG_MODE_NAME_STR_PER_SEC "per second"
+#define ENG_MODE_NAME_STR_PER_MIN "per minute"
+#define ENG_MODE_NAME_STR_AUTO "automatically"
+#define ENG_MODE_NAME_STR_ON_REQ_SEC "sec after request"
+
+#define DEFAULT_ENG_MODE_NAMES \
+{ \
+ ENG_MODE_NAME_STR_ON_REQ, \
+ ENG_MODE_NAME_STR_PER_SEC, \
+ ENG_MODE_NAME_STR_PER_MIN, \
+ ENG_MODE_NAME_STR_AUTO, \
+ 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:
+ */
+#define DEFAULT_STR_MODES \
+( \
+ MSK_STR_ON_REQ | \
+ MSK_STR_PER_SEC | \
+ MSK_STR_PER_MIN \
+)
+
+
+/*
+ * The modes below can be used with the capture string:
+ */
+#define DEFAULT_STR_MODES_UCAP \
+( \
+ MSK_STR_ON_REQ | \
+ MSK_STR_AUTO \
+)
+
+
+
+/**
+ * The number of serial ports which were available
+ * with all GPS receiver models:
+ */
+#define DEFAULT_N_COM 2
+
+/*
+ * By default that's also the number of ports
+ * currently available:
+ */
+#ifndef N_COM
+ #define N_COM DEFAULT_N_COM
+#endif
+
+/**
+ * The structure used to store the modes of both serial ports:<br>
+ * <b>(now obsolete)</b>
+ */
+typedef struct
+{
+ COM_PARM com[DEFAULT_N_COM]; /**< COM0 and COM1 settings */
+ uint8_t mode[DEFAULT_N_COM]; /**< COM0 and COM1 output mode */
+} PORT_PARM;
+
+#define _mbg_swab_port_parm( _p ) \
+{ \
+ int i; \
+ for ( i = 0; i < DEFAULT_N_COM; i++ ) \
+ { \
+ _mbg_swab_com_parm( &(_p)->com[i] ); \
+ /* no need to swap mode byte */ \
+ } \
+}
+
+
+/*
+ * The codes below were used with the obsolete
+ * PORT_PARM.mode above. They are defined for
+ * compatibility with older devices only:
+ */
+enum
+{
+ /* STR_ON_REQ, defined above */
+ /* STR_PER_SEC, defined above */
+ /* STR_PER_MIN, defined above */
+ N_STR_MODE_0 = STR_AUTO, /* COM0 and COM1 */
+ STR_UCAP = N_STR_MODE_0,
+ STR_UCAP_REQ,
+ N_STR_MODE_1 /* COM1 only */
+};
+
+
+
+/**
+ @defgroup group_icode Irig Codes
+
+ The following definitions are used to configure an optional
+ on-board IRIG input or output.
+
+ A GPS device can generate an IRIG output signal if the bit
+ #GPS_HAS_IRIG_TX is set in the RECEIVER_INFO.features field.
+ If a device has an optional IRIG input then the bit
+ #GPS_HAS_IRIG_RX is set.
+
+
+ - Supported IRIG signal code types:
+ - \b A002: 1000 bps, DC shift, time-of-year
+ - \b A003: 1000 bps, DC shift, time-of-year, SBS
+ - \b A132: 1000 bps, 10 kHz carrier, time-of-year
+ - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
+ - \b B002: 100 bps, DC shift, time-of-year
+ - \b B003: 100 bps, DC shift, time-of-year, SBS
+ - \b B122: 100 bps, 1 kHz carrier, time-of-year
+ - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
+ - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
+ - <b> AFNOR DC:</b> 100 bps, DC shift, SBS, complete date
+ - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE1344 extensions (B120)
+ - <b> IEEE1344 DC:</b> 100 bps, DC shift, time-of-year, SBS, IEEE1344 extensions (B000)
+ - \b B220/1344: 100 bps, DC shift, manchester encoded, IEEE1344 extensions
+ - \b B222: 100 bps, DC shift, manchester encoded, time-of-year
+ - \b B223: 100 bps, DC shift, manchester encoded, time-of-year, SBS
+
+ - time-of-year: day-of-year, hours, minutes, seconds
+ - SBS: straight binary seconds, second-of-day
+ - IEEE1344 extensions: time zone info
+ - AFNOR: french standard AFNOR NFS-87500
+
+ @{
+ */
+
+/**
+ * Definitions used with IRIG transmitters which generate
+ * the same IRIG code both with and without carrier signal
+ * at the same time. */
+enum
+{
+ ICODE_TX_B002_B122,
+ ICODE_TX_B003_B123,
+ ICODE_TX_A002_A132,
+ ICODE_TX_A003_A133,
+ ICODE_TX_AFNOR,
+ ICODE_TX_IEEE1344,
+ ICODE_TX_B220_1344,
+ ICODE_TX_B222,
+ ICODE_TX_B223,
+ ICODE_TX_B006_B126,
+ ICODE_TX_B007_B127,
+ N_ICODE_TX /**< number of code types */
+};
+
+
+/**
+ * Initializers for format name strings.
+ */
+#define DEFAULT_ICODE_TX_NAMES \
+{ \
+ "B002+B122", \
+ "B003+B123", \
+ "A002+A132", \
+ "A003+A133", \
+ "AFNOR NFS-87500", \
+ "IEEE1344", \
+ "B220/1344+IEEE1344", \
+ "B222+B122", \
+ "B223+B123", \
+ "B006+B126", \
+ "B007+B127" \
+}
+
+/**
+ * Initializers for English format description strings.
+ */
+#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \
+{ \
+ "100 bps, DC or 1 kHz carrier", \
+ "100 bps, DC or 1 kHz carrier, SBS", \
+ "1000 bps, DC or 10 kHz carrier", \
+ "1000 bps, DC or 10 kHz carrier, SBS", \
+ "100 bps, DC or 1 kHz carrier, SBS, complete date", \
+ "100 bps, DC or 1 kHz carrier, SBS, time zone info", \
+ "100 bps, DC manchester enc. or 1kHz carrier, SBS, time zone info", \
+ "100 bps, DC manchester enc. or 1kHz carrier, time-of-year", \
+ "100 bps, DC manchester enc. or 1kHz carrier, time-of-year, SBS", \
+ "100 bps, DC or 1 kHz carrier, complete date", \
+ "100 bps, DC or 1 kHz carrier, complete date, SBS" \
+}
+
+/*
+ * The definitions below are used to set up bit masks
+ * which restrict the IRIG formats which are supported
+ * by a given IRIG transmitter device:
+ */
+#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 )
+#define MSK_ICODE_TX_A003_A133 ( 1UL << ICODE_TX_A003_A133 )
+#define MSK_ICODE_TX_AFNOR ( 1UL << ICODE_TX_AFNOR )
+#define MSK_ICODE_TX_IEEE1344 ( 1UL << ICODE_TX_IEEE1344 )
+#define MSK_ICODE_TX_B220_1344 ( 1UL << ICODE_TX_B220_1344 )
+#define MSK_ICODE_TX_B222 ( 1UL << ICODE_TX_B222 )
+#define MSK_ICODE_TX_B223 ( 1UL << ICODE_TX_B223 )
+#define MSK_ICODE_TX_B006_B126 ( 1UL << ICODE_TX_B006_B126 )
+#define MSK_ICODE_TX_B007_B127 ( 1UL << ICODE_TX_B007_B127 )
+
+/**
+ * A mask of IRIG formats with manchester encoded DC output:
+ */
+#define MSK_ICODE_TX_DC_MANCH \
+( \
+ MSK_ICODE_TX_B220_1344 | \
+ MSK_ICODE_TX_B222 | \
+ MSK_ICODE_TX_B223 \
+)
+
+/**
+ * A mask of IRIG formats with 1 kHz carrier:
+ */
+#define MSK_ICODE_TX_1KHZ \
+( \
+ MSK_ICODE_TX_B002_B122 | \
+ MSK_ICODE_TX_B003_B123 | \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_B220_1344 | \
+ MSK_ICODE_TX_B222 | \
+ MSK_ICODE_TX_B223 | \
+ MSK_ICODE_TX_B006_B126 | \
+ MSK_ICODE_TX_B007_B127 \
+)
+
+/**
+ * A mask of IRIG formats with 10 kHz carrier:
+ */
+#define MSK_ICODE_TX_10KHZ \
+( \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 \
+)
+
+/**
+ * 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 \
+)
+
+/**
+ * A mask of IRIG formats with 1000 bps data rate:
+ */
+#define MSK_ICODE_TX_1000BPS \
+( \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 \
+)
+
+/**
+ * A mask of IRIG formats which support TFOM:
+ */
+#define MSK_ICODE_TX_HAS_TFOM \
+( \
+ MSK_ICODE_TX_IEEE1344 \
+)
+
+/**
+ * A mask of IRIG formats which support time zone information:
+ */
+#define MSK_ICODE_TX_HAS_TZI \
+( \
+ MSK_ICODE_TX_IEEE1344 \
+)
+
+/**
+ * The default mask of IRIG formats supported by
+ * IRIG transmitters:
+ */
+#if !defined( SUPP_MSK_ICODE_TX )
+ #define SUPP_MSK_ICODE_TX \
+ ( \
+ MSK_ICODE_TX_B002_B122 | \
+ MSK_ICODE_TX_B003_B123 | \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 | \
+ MSK_ICODE_TX_AFNOR \
+ )
+#endif
+
+
+
+/**
+ * Definitions used with IRIG receivers which decode
+ * two similar IRIG codes
+ * at the same time.
+ */
+enum
+{
+ ICODE_RX_B122_B123,
+ ICODE_RX_A132_A133,
+ ICODE_RX_B002_B003,
+ ICODE_RX_A002_A003,
+ ICODE_RX_AFNOR,
+ ICODE_RX_AFNOR_DC,
+ ICODE_RX_IEEE1344,
+ ICODE_RX_IEEE1344_DC,
+ ICODE_RX_B126_B127,
+ ICODE_RX_B006_B007,
+ N_ICODE_RX /* the number of valid signal code types */
+};
+
+/**
+ * Initializers for format name strings.
+ */
+#define DEFAULT_ICODE_RX_NAMES \
+{ \
+ "B122/B123", \
+ "A132/A133", \
+ "B002/B003 (DC)", \
+ "A002/A003 (DC)", \
+ "AFNOR NFS-87500", \
+ "AFNOR NFS-87500 (DC)", \
+ "IEEE1344", \
+ "IEEE1344 (DC)", \
+ "B126/B127", \
+ "B006/B007 (DC)" \
+}
+
+/**
+ * Initializers for English format description strings.
+ */
+#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
+{ \
+ "100 bps, 1 kHz carrier, SBS optionally", \
+ "1000 bps, 10 kHz carrier, SBS optionally", \
+ "100 bps, DC shift, SBS optionally", \
+ "1000 bps, DC shift, SBS optionally", \
+ "100 bps, 1 kHz carrier, SBS, complete date", \
+ "100 bps, DC shift, SBS, complete date", \
+ "100 bps, 1 kHz carrier, SBS, time zone info", \
+ "100 bps, DC shift, SBS, time zone info", \
+ "100 bps, 1 kHz carrier, complete date, SBS optionally", \
+ "100 bps, DC shift, complete date, SBS optionally" \
+}
+
+/*
+ * Bit masks corresponding to the enumeration above:
+ */
+#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 )
+#define MSK_ICODE_RX_A002_A003 ( 1UL << ICODE_RX_A002_A003 )
+#define MSK_ICODE_RX_AFNOR ( 1UL << ICODE_RX_AFNOR )
+#define MSK_ICODE_RX_AFNOR_DC ( 1UL << ICODE_RX_AFNOR_DC )
+#define MSK_ICODE_RX_IEEE1344 ( 1UL << ICODE_RX_IEEE1344 )
+#define MSK_ICODE_RX_IEEE1344_DC ( 1UL << ICODE_RX_IEEE1344_DC )
+#define MSK_ICODE_RX_B126_B127 ( 1UL << ICODE_RX_B126_B127 )
+#define MSK_ICODE_RX_B006_B007 ( 1UL << ICODE_RX_B006_B007 )
+
+/**
+ * A mask of IRIG formats which have DC shift:
+ */
+#define MSK_ICODE_RX_DC \
+( \
+ MSK_ICODE_RX_B002_B003 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B006_B007 \
+)
+
+/**
+ * A mask of IRIG formats with 1 kHz carrier:
+ */
+#define MSK_ICODE_RX_1KHZ \
+( \
+ MSK_ICODE_RX_B122_B123 | \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_B126_B127 \
+)
+
+/**
+ * A mask of IRIG formats with 10 kHz carrier:
+ */
+#define MSK_ICODE_RX_10KHZ \
+( \
+ MSK_ICODE_RX_A132_A133 \
+)
+
+/**
+ * A mask of IRIG formats with 100 bps data rate:
+ */
+#define MSK_ICODE_RX_100BPS \
+( \
+ MSK_ICODE_RX_B122_B123 | \
+ MSK_ICODE_RX_B002_B003 | \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B126_B127 | \
+ MSK_ICODE_RX_B006_B007 \
+)
+
+/**
+ * A mask of IRIG formats with 1000 bps data rate:
+ */
+#define MSK_ICODE_RX_1000BPS \
+( \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A002_A003 \
+)
+
+/**
+ * A mask of IRIG formats which support TFOM:
+ */
+#define MSK_ICODE_RX_HAS_TFOM \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC \
+)
+
+/**
+ * A mask of IRIG formats which support time zone information:
+ */
+#define MSK_ICODE_RX_HAS_TZI \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC \
+)
+
+/**
+ * The default mask of IRIG formats supported by
+ * IRIG receivers:
+ */
+#if !defined( SUPP_MSK_ICODE_RX )
+ #define SUPP_MSK_ICODE_RX \
+ ( \
+ MSK_ICODE_RX_B122_B123 | \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_B002_B003 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC \
+ )
+#endif
+/** @} */
+
+/**
+ * The structure below is used to configure an optional
+ * on-board IRIG output:
+ */
+typedef struct
+{
+ uint16_t icode; /**< IRIG signal code, see \ref group_icode */
+ uint16_t flags; /**< see \ref group_irig_flags */
+} IRIG_SETTINGS;
+
+#define _mbg_swab_irig_settings( _p ) \
+{ \
+ _mbg_swab16( &(_p)->icode ); \
+ _mbg_swab16( &(_p)->flags ); \
+}
+
+
+/**
+ @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS.flags
+
+ (others are reserved)
+* @{
+ */
+#define IFLAGS_DISABLE_TFOM 0x0001 /**< RX ignore/TX don't gen TFOM */
+#define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /**< gen local time, not UTC */
+
+#define IFLAGS_MASK 0x0003 /**< flags above or'ed */
+
+/** @} */
+
+/**
+ * The structure is used to query the IRIG configuration
+ * plus the supported codes:
+ */
+typedef struct
+{
+ IRIG_SETTINGS settings;
+ uint32_t supp_codes; /**< bit mask of supported codes */
+} IRIG_INFO;
+
+#define _mbg_swab_irig_info( _p ) \
+{ \
+ _mbg_swab_irig_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_codes ); \
+}
+
+
+// The type below is used to read the board's debug status
+// which also include IRIG decoder status:
+typedef uint32_t MBG_DEBUG_STATUS;
+
+// The debug status is bit coded as defined below:
+enum
+{
+ MBG_IRIG_BIT_WARMED_UP, /**< Osc has warmed up */
+ MBG_IRIG_BIT_PPS_ACTIVE, /**< PPS output is active */
+ MBG_IRIG_BIT_INV_CONFIG, /**< Invalid config, e.g. data csum error */
+ MBG_IRIG_BIT_MSG_DECODED, /**< IRIG msg could be decoded */
+ MBG_IRIG_BIT_MSG_INCONSISTENT, /**< IRIG msg contains inconsistent data */
+ MBG_IRIG_BIT_LOOP_LOCKED, /**< Decoder control loop is locked */
+ MBG_IRIG_BIT_JITTER_TOO_LARGE, /**< Phase jitter too large */
+ MBG_IRIG_BIT_INV_REF_OFFS, /**< UTC ref offset not configured */
+
+ MBG_SYS_BIT_INV_TIME, /**< Internal time not valid/set */
+ MBG_SYS_BIT_TIME_SET_VIA_API, /**< On board time set externally */
+ MBG_SYS_BIT_INV_RTC, /**< On board RTC invalid */
+ MBG_SYS_BIT_CPU_PLL_FAILED, /**< The CPU's PLL watchdog */
+
+ N_MBG_DEBUG_BIT
+};
+
+/*
+ * Initializers for IRIG status bit strings.
+ */
+#define MBG_DEBUG_STATUS_STRS \
+{ \
+ "Osc has warmed up", \
+ "PPS output is active", \
+ "Config set to default", \
+ "IRIG msg decoded", \
+ "IRIG msg not consistent", \
+ "Decoder control loop locked", \
+ "Phase jitter too large", \
+ "Invalid ref offset" \
+ \
+ "Internal time not valid" \
+ "On board time set via API" \
+ "On board RTC invalid" \
+ "CPU PLL failure, needs restart" \
+}
+
+
+
+#define MBG_IRIG_MSK_WARMED_UP ( 1UL << MBG_IRIG_BIT_WARMED_UP )
+#define MBG_IRIG_MSK_PPS_ACTIVE ( 1UL << MBG_IRIG_BIT_PPS_ACTIVE )
+#define MBG_IRIG_MSK_INV_CONFIG ( 1UL << MBG_IRIG_BIT_INV_CONFIG )
+#define MBG_IRIG_MSK_MSG_DECODED ( 1UL << MBG_IRIG_BIT_MSG_DECODED )
+#define MBG_IRIG_MSK_MSG_INCONSISTENT ( 1UL << MBG_IRIG_BIT_MSG_INCONSISTENT )
+#define MBG_IRIG_MSK_LOOP_LOCKED ( 1UL << MBG_IRIG_BIT_LOOP_LOCKED )
+#define MBG_IRIG_MSK_JITTER_TOO_LARGE ( 1UL << MBG_IRIG_BIT_JITTER_TOO_LARGE )
+#define MBG_IRIG_MSK_INV_REF_OFFS ( 1UL << MBG_IRIG_BIT_INV_REF_OFFS )
+
+#define MBG_SYS_MSK_INV_TIME ( 1UL << MBG_SYS_BIT_INV_TIME )
+#define MBG_SYS_MSK_TIME_SET_VIA_API ( 1UL << MBG_SYS_BIT_TIME_SET_VIA_API )
+#define MBG_SYS_MSK_INV_RTC ( 1UL << MBG_SYS_BIT_INV_RTC )
+#define MBG_SYS_MSK_CPU_PLL_FAILED ( 1UL << MBG_SYS_BIT_CPU_PLL_FAILED )
+
+
+
+typedef int16_t MBG_REF_OFFS; /**< -MBG_REF_OFFS_MAX..MBG_REF_OFFS_MAX */
+
+#define _mbg_swab_mbg_ref_offs( _p ) _mbg_swab16( (_p) )
+
+
+/** the maximum allowed positive / negative offset */
+#define MBG_REF_OFFS_MAX ( ( 12L * 60 ) + 30 ) // [minutes]
+
+/**
+ * the following value is used to indicate that the ref offset
+ * value has not yet been configured
+ */
+#define MBG_REF_OFFS_NOT_CFGD 0x8000
+
+
+typedef struct
+{
+ uint32_t flags;
+} MBG_OPT_SETTINGS;
+
+#define _mbg_swab_mbg_opt_settings( _p ) \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+}
+
+
+typedef struct
+{
+ MBG_OPT_SETTINGS settings;
+ uint32_t supp_flags;
+} MBG_OPT_INFO;
+
+#define _mbg_swab_mbg_opt_info( _p ) \
+{ \
+ _mbg_swab_mbg_opt_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+}
+
+
+enum
+{
+ MBG_OPT_BIT_STR_UTC, /**< serial string contains UTC time */
+ MBG_OPT_BIT_EMU_SYNC, /**< emulate/pretend to be synchronized, */
+ /**< alternatively GPS_FEAT_IGNORE_LOCK may be supported */
+ N_MBG_OPT_BIT
+};
+
+/*
+ * Bit masks corresponding to the enumeration above:
+ */
+#define MBG_OPT_FLAG_STR_UTC ( 1UL << MBG_OPT_BIT_STR_UTC )
+#define MBG_OPT_FLAG_EMU_SYNC ( 1UL << MBG_OPT_BIT_EMU_SYNC )
+
+
+/*
+ * 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.
+ */
+
+/**
+ * The structure is used to define a date of year:
+ */
+typedef struct
+{
+ 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 ) \
+{ \
+ _mbg_swab16( &(_p)->year ); \
+}
+
+
+/**
+ * The structure is used to define a time of day:
+ */
+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 */
+} MBG_TIME;
+
+#define _mbg_swab_mbg_time( _p ) \
+ _nop_macro_fnc() // nothing to swap
+
+
+/**
+ * The structure defines a single date and time
+ * 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_TIME;
+
+#define _mbg_swab_mbg_date_time( _p ) \
+{ \
+ _mbg_swab_mbg_date( &(_p)->d ); \
+ _mbg_swab_mbg_time( &(_p)->t ); \
+}
+
+
+/**
+ * The structure defines times and dates
+ * for an on/off cycle:
+ */
+typedef struct
+{
+ MBG_DATE_TIME on; /* time and date to switch on */
+ MBG_DATE_TIME off; /* time and date to switch off */
+} POUT_TIME;
+
+#define _mbg_swab_pout_time( _p ) \
+{ \
+ _mbg_swab_mbg_date_time( &(_p)->on ); \
+ _mbg_swab_mbg_date_time( &(_p)->off ); \
+}
+
+
+/**
+ * The number of POUT_TIMEs for each programmable pulse output
+ */
+#define N_POUT_TIMES 3
+
+/**
+ * The structure is used to configure a single programmable
+ * pulse output.
+ */
+typedef struct
+{
+ uint16_t mode; /**< mode of operation, codes defined below */
+ uint16_t pulse_len; /**< 10 msec units, or COM port number */
+ uint16_t timeout; /**< [min], for dcf_mode */
+ uint16_t flags; /**< see below */
+ POUT_TIME tm[N_POUT_TIMES]; /**< switching times */
+} 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] ); \
+}
+
+
+#define MAX_POUT_PULSE_LEN 1000 /**< 10 secs, in 10 msec units */
+#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) /**< 48 hours, in minutes */
+
+
+/**
+ * These codes are defined for POUT_SETTINGS.mode to setup
+ * the basic mode of operation for a single programmable pulse
+ * output:
+ */
+enum
+{
+ POUT_IDLE, /**< always off, or on if POUT_INVERTED */
+ POUT_TIMER, /**< switch on/off at configured times */
+ POUT_SINGLE_SHOT, /**< pulse at time POUT_SETTINGS.tm[0].on */
+ POUT_CYCLIC_PULSE, /**< pulse every POUT_SETTINGS.tm[0].on.t interval */
+ POUT_PER_SEC, /**< pulse if second changes */
+ POUT_PER_MIN, /**< pulse if minute changes */
+ POUT_PER_HOUR, /**< pulse if hour changes */
+ POUT_DCF77, /**< emulate DCF77 signal */
+ POUT_POS_OK, /**< on if pos. OK (nav_solved) */
+ POUT_TIME_SYNC, /**< on if time sync (time_syn) */
+ POUT_ALL_SYNC, /**< on if pos. OK and time sync */
+ POUT_TIMECODE, /**< IRIG/AFNOR DCLS output */
+ POUT_TIMESTR, /**< COM port number in pulse_len field */
+ POUT_10MHZ, /**< 10 MHz fixed frequency */
+ N_POUT_MODES
+};
+
+
+/*
+ * Default initializers for English pulse mode names. Initializers
+ * for multi-language strings can be found in pcpslstr.h.
+ */
+#define ENG_POUT_NAME_IDLE "Idle"
+#define ENG_POUT_NAME_TIMER "Timer"
+#define ENG_POUT_NAME_SINGLE_SHOT "Single Shot"
+#define ENG_POUT_NAME_CYCLIC_PULSE "Cyclic Pulse"
+#define ENG_POUT_NAME_PER_SEC "Pulse Per Second"
+#define ENG_POUT_NAME_PER_MIN "Pulse Per Min"
+#define ENG_POUT_NAME_PER_HOUR "Pulse Per Hour"
+#define ENG_POUT_NAME_DCF77 "DCF77 Marks"
+#define ENG_POUT_NAME_POS_OK "Position OK"
+#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_10MHZ "10 MHz Frequency"
+
+#define DEFAULT_ENG_POUT_NAMES \
+{ \
+ ENG_POUT_NAME_IDLE, \
+ ENG_POUT_NAME_TIMER, \
+ ENG_POUT_NAME_SINGLE_SHOT, \
+ ENG_POUT_NAME_CYCLIC_PULSE, \
+ ENG_POUT_NAME_PER_SEC, \
+ ENG_POUT_NAME_PER_MIN, \
+ ENG_POUT_NAME_PER_HOUR, \
+ ENG_POUT_NAME_DCF77, \
+ ENG_POUT_NAME_POS_OK, \
+ ENG_POUT_NAME_TIME_SYNC, \
+ ENG_POUT_NAME_ALL_SYNC, \
+ ENG_POUT_NAME_TIMECODE, \
+ ENG_POUT_NAME_TIMESTR, \
+ ENG_POUT_NAME_10MHZ \
+}
+
+
+#define ENG_POUT_HINT_IDLE "Constant output level"
+#define ENG_POUT_HINT_TIMER "Switch based on configured on/off times"
+#define ENG_POUT_HINT_SINGLE_SHOT "Generate a single pulse of determined length"
+#define ENG_POUT_HINT_CYCLIC_PULSE "Generate cyclic pulses of determined length"
+#define ENG_POUT_HINT_PER_SEC "Generate pulse at beginning of new second"
+#define ENG_POUT_HINT_PER_MIN "Generate pulse at beginning of new minute"
+#define ENG_POUT_HINT_PER_HOUR "Generate pulse at beginning of new hour"
+#define ENG_POUT_HINT_DCF77 "DCF77 compatible time marks"
+#define ENG_POUT_HINT_POS_OK "Switch if receiver position has been verified"
+#define ENG_POUT_HINT_TIME_SYNC "Switch if time is synchronized"
+#define ENG_POUT_HINT_ALL_SYNC "Switch if full sync"
+#define ENG_POUT_HINT_TIMECODE "Duplicate IRIG time code signal"
+#define ENG_POUT_HINT_TIMESTR "Duplicate serial time string of specified port"
+#define ENG_POUT_HINT_10MHZ "10 MHz fixed output frequency"
+
+#define DEFAULT_ENG_POUT_HINTS \
+{ \
+ ENG_POUT_HINT_IDLE, \
+ ENG_POUT_HINT_TIMER, \
+ ENG_POUT_HINT_SINGLE_SHOT, \
+ ENG_POUT_HINT_CYCLIC_PULSE, \
+ ENG_POUT_HINT_PER_SEC, \
+ ENG_POUT_HINT_PER_MIN, \
+ ENG_POUT_HINT_PER_HOUR, \
+ ENG_POUT_HINT_DCF77, \
+ ENG_POUT_HINT_POS_OK, \
+ ENG_POUT_HINT_TIME_SYNC, \
+ ENG_POUT_HINT_ALL_SYNC, \
+ ENG_POUT_HINT_TIMECODE, \
+ ENG_POUT_HINT_TIMESTR, \
+ ENG_POUT_HINT_10MHZ \
+}
+
+
+/*
+ * 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 )
+
+
+/*
+ * The codes below are used with POUT_SETTINGS.flags:
+ */
+#define POUT_INVERTED 0x0001
+
+
+/**
+ Since a clock may support more than one programmable
+ pulse output, setup tools must use the structure below
+ to read/set pulse output configuration.
+ The number of outputs supported by a receiver model
+ can be queried using the RECEIVER_INFO structure.
+ */
+typedef struct
+{
+ uint16_t idx; /**< 0..RECEIVER_INFO.n_prg_out-1 */
+ POUT_SETTINGS pout_settings;
+} POUT_SETTINGS_IDX;
+
+#define _mbg_swab_pout_settings_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings( &(_p)->pout_settings ); \
+}
+
+
+/**
+ The structure below holds the current settings
+ for a programmable pulse output, plus additional
+ informaton on the output's capabilities.
+ This can be read by setup programs to allow setup
+ of supported features only.
+ */
+typedef struct
+{
+ POUT_SETTINGS pout_settings;
+ uint32_t supp_modes; /**< bit mask of modes supp. by this output */
+ uint8_t timestr_ports; /**< bit mask of COM ports supported for POUT_TIMESTR */
+ uint8_t reserved_0; /**< reserved for future use, currently 0 */
+ uint16_t reserved_1; /**< reserved for future use, currently 0 */
+ uint32_t flags; /**< reserved for future use, currently 0 */
+} 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 ); \
+}
+
+
+/** The max number of COM ports that can be handled by POUT_INFO::timestr_ports */
+#define MAX_POUT_TIMESTR_PORTS 8
+
+/**
+ The structure below adds an index number to the structure
+ above to allow addressing of several instances:
+ */
+typedef struct
+{
+ 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 ); \
+}
+
+
+/*
+ * 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.
+ */
+
+
+/*
+ * All possibly supported ref time sources
+ */
+enum
+{
+ MULTI_REF_NONE = -1, // nothing, undefined
+ MULTI_REF_GPS = 0, // standard GPS
+ MULTI_REF_10MHZ, // 10 MHz input frequency
+ MULTI_REF_PPS, // 1 PPS input signal
+ MULTI_REF_10MHZ_PPS, // combined 10 MHz plus PPS
+ MULTI_REF_IRIG, // IRIG input
+ MULTI_REF_NTP, // Network Time Protocol (NTP)
+ MULTI_REF_PTP, // Precision Time Protocol (PTP, IEEE1588)
+ MULTI_REF_PTP_E1, // PTP over E1
+ MULTI_REF_FREQ, // fixed frequency
+ N_MULTI_REF // the number of defined sources
+};
+
+
+/*
+ * Names of supported ref time sources
+ */
+#define DEFAULT_MULTI_REF_NAMES \
+{ \
+ "GPS", \
+ "10 MHz freq in", \
+ "PPS in", \
+ "10 MHz + PPS in", \
+ "IRIG", \
+ "NTP", \
+ "PTP (IEEE1588)", \
+ "PTP over E1", \
+ "Fixed Freq. in" \
+}
+
+
+/*
+ * Bit masks used to indicate supported reference sources
+ */
+#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 )
+
+
+/*
+ * There are 2 different ways to configure multi ref support
+ * provided by some devices.
+ *
+ * Newer devices which have the GPS_FEAT_XMULTI_REF flag set
+ * in RECEIVER_INFO::features support the newer XMULTI_REF_...
+ * structures which provide a more flexible interface.
+ *
+ * Older devices which have the GPS_FEAT_MULTI_REF flag set
+ * support these MULTI_REF_... structures below where
+ * the number of supported input sources and priorities
+ * is limited to N_MULTI_REF_PRIO.
+ */
+
+#define N_MULTI_REF_PRIO 4
+
+
+/**
+ The structure below is used to configure the priority of
+ the supported ref sources.
+
+ The number stored in prio[0] of the array indicates the ref time
+ source with highest priority. If that source fails, the device
+ falls back to the source indicated by prio[1]. Each field of
+ the prio[] array must be set to one of the values 0..N_MULTI_REF-1,
+ or to -1 (0xFF) if the value is not assigned.
+ */
+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.
+ */
+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_INFO;
+
+
+/*
+ * The type below is used to query the MULTI_REF status information,
+ */
+typedef uint16_t MULTI_REF_STATUS; /* flag bits as defined below */
+
+
+/*
+ * The bits and associated bit masks below are used with the
+ * MULTI_REF_STATUS type. Each bit is set if the associated
+ * condition is true and is reset if the condition is not true:
+ */
+enum
+{
+ WRN_MODULE_MODE, /* selected input mode was invalid, set to default */
+ 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
+};
+
+#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 )
+
+
+
+/*
+ * If the RECEIVER_INFO::features flag GPS_FEAT_XMULTI_REF is set
+ * then the following XMULTI_REF_... data structures must be used
+ * instead of the older MULTI_REF_... structures above.
+ *
+ * Those devices support a number of priority levels addressed by
+ * the priority index, starting at 0 for highest priority. A single
+ * reference time source from the set of supported sources can be
+ * assigned to each priority level.
+ *
+ * The structures below are used to configure the individual
+ * time source for each priority level, and retrieve the status
+ * of the time source at each priority level.
+ */
+
+typedef struct
+{
+ uint8_t type; /* 0..N_MULTI_REF-1 from the enum above */
+ uint8_t instance; /* reserved, currently always 0 */
+} XMULTI_REF_ID;
+
+typedef struct
+{
+ XMULTI_REF_ID id; /* time source identifier */
+ uint16_t flags; /* reserved, currently always 0 */
+ NANO_TIME bias; /* time bias, e.g. path delay */
+ NANO_TIME precision; /* precision of the time source */
+ uint32_t fine_limit; /* smooth control if below this limit */
+} XMULTI_REF_SETTINGS;
+
+
+/*
+ * The structure below is used to retrieve or configure the time source
+ * for a specific priority level.
+ * After configuring, a structure with idx == 0xFFFF (-1) must be sent
+ * to let the changes become effective.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_SETTINGS settings; /* the settings configured for this level */
+
+} XMULTI_REF_SETTINGS_IDX;
+
+
+/*
+ * The structure below contains the XMULTI_REF configuration
+ * for a single priority level, plus information on supported
+ * ref time sources, and the number of supported priority levels.
+ */
+typedef struct
+{
+ XMULTI_REF_SETTINGS settings; /* current settings */
+ uint32_t supp_ref; /* supp. HAS_MULTI_REF_... codes or'ed */
+ uint8_t n_supp_ref; /* number of supported ref time sources */
+ uint8_t n_prio; /* number of supported priority levels */
+ uint16_t flags; /* reserved, currently 0, e.g. multiple instance support */
+
+} XMULTI_REF_INFO;
+
+
+/*
+ * The structure below is used to retrieve the XMULTI_REF configuration
+ * information for a specific priority level.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_INFO info;
+
+} XMULTI_REF_INFO_IDX;
+
+
+/*
+ * The structure below contains status information on a single
+ * ref time source.
+ */
+typedef struct
+{
+ XMULTI_REF_ID id; /* time source identifier */
+ uint16_t status; /* flag bits as defined below */
+ NANO_TIME offset; /* time offset from main time base */
+ uint32_t reserved; /* reserved, currently always 0 */
+
+} XMULTI_REF_STATUS;
+
+
+/*
+ * The structure below is used to retrieve the the status information
+ * of the time source at a specific priority level.
+ */
+typedef struct
+{
+ uint16_t idx; /* the priority level index, highest == 0 */
+ XMULTI_REF_STATUS status;
+
+} XMULTI_REF_STATUS_IDX;
+
+
+/*
+ * Bits used with XMULTI_REF_STATUS.
+ */
+enum
+{
+ XMRS_BIT_NOT_SUPP, /* ref type cfg'd for this level is not supported */
+ XMRS_BIT_NO_CONN, /* input signal is disconnected */
+ XMRS_BIT_NO_SIGNAL, /* no input signal */
+ XMRS_BIT_IS_MASTER, /* reference is master source */
+ XMRS_BIT_IS_LOCKED, /* locked to input signal */
+ XMRS_BIT_IS_ACCURATE, /* oscillator control has reached full accuracy */
+ XMRS_BIT_NOT_SETTLED, /* reference time signal not settled */
+ N_XMRS_BITS
+};
+
+
+/* bit masks corresponding to the flag bits above */
+
+#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP )
+#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN )
+#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL )
+#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER )
+#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED )
+#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE )
+#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED )
+
+
+
+/*
+ * An initializer for a XMULTI_REF_STATUS variable
+ * with status invalid / not used
+ */
+#define XMULTI_REF_STATUS_INVALID \
+{ \
+ { (uint8_t) MULTI_REF_NONE, 0 }, /* id; instance 0 ? */ \
+ XMRS_MSK_NO_CONN | XMRS_MSK_NO_SIGNAL, /* status */ \
+ { 0 }, /* offset */ \
+ 0 /* reserved */ \
+}
+
+
+
+/*------------------------------------------------------------------------*/
+
+/*
+ * The types below are not used with all devices:
+ */
+
+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) */
+
+/*
+ * Originally IGNORE_LOG above has been a boolean value (equal or
+ * not equal 0) which was evaluated the same way for all ports.
+ *
+ * Due to special firmware requirements it has been changed to a
+ * bit maskable property in order to be able to specify the behaviour
+ * for individual ports.
+ *
+ * In order to keep compatibility with older versions the LSB is used
+ * to specify ignore_lock for all ports. The next higher bits are used
+ * to specify ignore_lock for an individual port, where the bit position
+ * depends on the port number, e.g. 0x02 for COM0, 0x04 for COM1, etc.
+ * The macros below can be used to simplify the code:
+ */
+
+/* return a bit mask depending on the port number */
+#define IGNORE_LOCK_FOR_ALL_PORTS 0x01
+
+#define _ignore_lock_for_all_ports() ( IGNORE_LOCK_FOR_ALL_PORTS )
+
+#define _ignore_lock_for_port( _n ) ( 0x02 << (_n) )
+
+/* check if all ports are ignore_lock'ed */
+#define _is_ignore_lock_all_ports( _il ) ( (_il) & IGNORE_LOCK_FOR_ALL_PORTS )
+
+/* check if a specific port is ignore_lock'ed */
+#define _is_ignore_lock_for_port( _il, _n ) \
+ ( (_il) & ( _ignore_lock_for_port(_n) | IGNORE_LOCK_FOR_ALL_PORTS ) )
+
+
+/*------------------------------------------------------------------------*/
+
+/*
+ * The structures below are used with the SCU multiplexer board
+ * in a redundant system:
+ */
+
+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
+} SCU_STAT_INFO;
+
+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
+} 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
+
+
+#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:
+ */
+enum
+{
+ 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
+};
+
+
+
+/*------------------------------------------------------------------------*/
+
+/*
+ * 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 )
+
+typedef struct
+{
+ uint16_t mode; /**< Mode of operation. */
+ uint16_t good_svs; /**< No. of satellites that are currently used by the receiver */
+ uint16_t svs_in_view; /**< No. of satellites that are in view according to the almanac data */
+ int16_t dac_val; /**< Oscillator fine DAC value */
+ int16_t dac_cal; /**< Calibration DAC value of oscillator ( see #OSC_DAC_RANGE, #OSC_DAC_BIAS ) */
+} STAT_INFO;
+
+#define _mbg_swab_stat_info( _p ) \
+{ \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->good_svs ); \
+ _mbg_swab16( &(_p)->svs_in_view ); \
+ _mbg_swab16( &(_p)->dac_val ); \
+ _mbg_swab16( &(_p)->dac_cal ); \
+}
+
+
+#define OSC_DAC_RANGE 4096UL
+#define OSC_DAC_BIAS ( OSC_DAC_RANGE / 2 )
+
+
+#ifndef _IDENT_DEFINED
+
+ typedef union
+ {
+ char c[16]; // as string which may NOT be terminated
+ int16_t wrd[8];
+ uint32_t lw[4];
+ } IDENT;
+
+ #define _IDENT_DEFINED
+#endif
+
+#define _mbg_swab_ident( _p ) \
+{ \
+ int i; \
+ for ( i = 0; i < 4; i++ ) \
+ _mbg_swab32( &(_p)->lw[i] ); \
+}
+
+/**
+ * The type below is used to configure the length of the
+ * antenna cable in [m]:
+ */
+typedef uint16_t ANT_CABLE_LEN;
+
+#define _mbg_swab_ant_cable_len( _p ) _mbg_swab16( _p )
+
+
+/*------------------------------------------------------------------------*/
+
+/* 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;
+
+
+
+/* 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. */
+
+typedef struct
+{
+ CSUM csum; /* checksum of the remaining bytes */
+ int16_t valid; /* flag data are valid */
+
+ HEALTH health; /* [---] */
+ T_GPS t0a; /* Reference Time Almanac [sec] */
+
+ 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;
+
+
+
+/* Summary of configuration and health data of all SVs. */
+
+typedef struct
+{
+ 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 */
+
+ CFG cfg[N_SVNO]; /* SV configuration from page 63 */
+ HEALTH health[N_SVNO]; /* SV health from pages 51, 63 */
+} CFGH;
+
+
+
+/* UTC correction parameters */
+
+typedef struct
+{
+ CSUM csum; /* checksum of the remaining bytes */
+ int16_t valid; /* flag data are valid */
+
+ T_GPS t0t; /* Reference Time UTC Parameters [sec] */
+ double A0; /* +- Clock Correction Coefficient 0 [sec] */
+ double A1; /* +- Clock Correction Coefficient 1 [sec/sec] */
+
+ uint16_t WNlsf; /* week number of nearest leap second */
+ int16_t DNt; /* the day number at the end of which LS is inserted */
+ int8_t delta_tls; /* */
+ int8_t delta_tlsf; /* */
+} UTC;
+
+
+
+/* Ionospheric correction parameters */
+
+typedef struct
+{
+ 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 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 */
+
+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 */
+} ASCII_MSG;
+
+
+/* End of header body */
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+
+#endif /* _GPSDEFS_H */
diff --git a/c/mbglib/include/gpsutils.h b/c/mbglib/include/gpsutils.h
new file mode 100644
index 0000000..d57085b
--- /dev/null
+++ b/c/mbglib/include/gpsutils.h
@@ -0,0 +1,94 @@
+
+/**************************************************************************
+ *
+ * $Id: gpsutils.h 1.6 2005/02/18 10:32:33Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for gpsutils.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: gpsutils.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.
+ * Updated function prototypes.
+ * Revision 1.3 2001/02/05 09:40:42Z MARTIN
+ * New file header.
+ * Source code cleanup.
+ *
+ **************************************************************************/
+
+#ifndef _GPSUTILS_H
+#define _GPSUTILS_H
+
+
+/* Other headers to be included */
+
+#include <mbggeo.h>
+
+
+#ifdef _GPSUTILS
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#define ANSI_C_DEGREE '°' // single char
+#define ANSI_S_DEGREE "°" // string
+
+#if defined( _Windows ) || defined( _WINDOWS ) \
+ || defined( WIN32 ) || defined( __linux )
+ #define C_DEGREE ANSI_C_DEGREE
+ #define S_DEGREE ANSI_S_DEGREE
+#else
+ #define C_DEGREE 'ø'
+ #define S_DEGREE "ø"
+#endif
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ void swap_double( double *d ) ;
+ void swap_eph_doubles( EPH *ephp ) ;
+ void swap_alm_doubles( ALM *almp ) ;
+ void swap_utc_doubles( UTC *utcp ) ;
+ 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 ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _GPSUTILS_H */
+
diff --git a/c/mbglib/include/mbgdevio.h b/c/mbglib/include/mbgdevio.h
new file mode 100644
index 0000000..e75e2c7
--- /dev/null
+++ b/c/mbglib/include/mbgdevio.h
@@ -0,0 +1,2672 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgdevio.h 1.32 2008/12/17 10:43:30Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes used with Meinberg device driver I/O.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgdevio.h $
+ * Revision 1.32 2008/12/17 10:43:30Z martin
+ * New version code 303, compatibility version still 210.
+ * Increased MBG_MAX_DEVICES from 5 to 8.
+ * Added macros to read the time stamp counter (cycles), and
+ * added an inline rdtscll() call for user space Linux.
+ * Added some inline functions to deal with cycles and timestamps.
+ * Generic support for threads and process/thread affinity controlled
+ * by symbol MBGDEVIO_USE_THREAD_API.
+ * New preprocessor symbol MBGDEVIO_HAVE_THREAD_AFFINITY.
+ * Support extrapolated time stamps controlled
+ * by symbol MBGDEVIO_XHRT_API.
+ * Removed definition of MBG_TGT_SUPP_MMAP.
+ * Updated function prototypes and doxygen comments.
+ * Revision 1.31 2008/02/26 16:57:38Z martin
+ * Updated function prototypes and doxygen comments.
+ * Revision 1.30 2008/02/04 13:33:15Z martin
+ * New preprocessor symbol MBG_TGT_SUPP_MMAP.
+ * Revision 1.29 2008/01/31 08:55:39Z daniel
+ * Renamed functions related to mapped memory support
+ * Revision 1.28 2008/01/31 08:36:22Z martin
+ * Picked up changes from 1.24.1.1:
+ * Added default preprocessor symbol MBGDEVIO_SIMPLE.
+ * Revision 1.27 2008/01/17 15:56:37Z daniel
+ * New version code 302, compatibility version still 210.
+ * Added structure MBG_MAPPED_MEM_INFO.
+ * Updated function prototypes.
+ * Revision 1.26 2007/10/16 10:11:42Z daniel
+ * New version code 301, compatibility version still 210.
+ * Revision 1.25 2007/09/26 14:10:34Z martin
+ * New version code 300, compatibility version still 210.
+ * Added MBG_MAX_DEVICES.
+ * Added enum SELECTION_MODE.
+ * Added structures MBG_DEVICE_LIST and MBG_DEVICE_NAME_LIST.
+ * Updated function prototypes.
+ * Revision 1.24 2007/03/22 10:14:16Z martin
+ * New version code 219, compatibility version still 210.
+ * Revision 1.23 2007/03/02 10:18:10Z martin
+ * Updated function prototypes due to renamed data structures.
+ * Use new definitions of generic handle types.
+ * Preliminary support for *BSD.
+ * Revision 1.22 2006/08/09 13:47:29 martin
+ * New version code 218, compatibility version still 210.
+ * Revision 1.21 2006/06/08 12:30:22Z martin
+ * New version code 217, compatibility version still 210.
+ * Revision 1.20 2006/05/02 13:14:27Z martin
+ * New version code 216, compatibility version still 210.
+ * Updated function prototypes.
+ * Revision 1.19 2006/01/11 12:14:53Z martin
+ * New version code 215, compatibility version still 210.
+ * Revision 1.18 2005/12/15 09:38:39Z martin
+ * New version 214, compatibility version still 210.
+ * Revision 1.17 2005/06/02 11:54:40Z martin
+ * Updated function prototypes.
+ * Revision 1.16 2005/02/16 15:13:00Z martin
+ * New MBGDEVIO_VERSION 0x0212.
+ * Updated function prototypes.
+ * Revision 1.15 2005/01/14 10:22:44Z martin
+ * Updated function prototypes.
+ * Revision 1.14 2004/12/09 11:24:00Z martin
+ * Support configuration of on-board frequency synthesizer.
+ * Revision 1.13 2004/11/09 14:13:00Z martin
+ * Updated function prototypes.
+ * Revision 1.12 2004/08/17 11:13:46Z martin
+ * Account for renamed symbols.
+ * Revision 1.11 2004/04/14 09:34:23Z martin
+ * New definition MBGDEVIO_COMPAT_VERSION.
+ * Pack structures 1 byte aligned.
+ * Revision 1.10 2003/12/22 15:35:10Z martin
+ * New revision 2.03.
+ * Moved some definitions to pcpsdev.h.
+ * New structures to read device time together with associated
+ * PC high resolution timer cycles.
+ * Updated function prototypes.
+ * Revision 1.9 2003/06/19 08:50:05Z martin
+ * Definition of MBGDEVIO_VERSION number to allow DLL
+ * API version checking.
+ * Replaced some defines by typedefs.
+ * Renamed USE_DOS_TSR to MBG_USE_DOS_TSR.
+ * New preprocessor symbol MBG_USE_KERNEL_DRIVER which
+ * is defined only for targets which use IOCTLs.
+ * Don't include pcps_dos.h here.
+ * Updated function prototypes.
+ * Revision 1.8 2003/05/16 08:44:26 MARTIN
+ * Cleaned up inclusion of headers.
+ * Removed obsolete definitions.
+ * Changes for direct access targets.
+ * Revision 1.7 2003/04/25 10:16:00 martin
+ * Updated inclusion of headers.
+ * Made prototypes available for all targets.
+ * Revision 1.6 2003/04/15 19:38:05Z martin
+ * Updated function prototypes.
+ * Revision 1.5 2003/04/09 13:44:53Z martin
+ * Use new common IOCTL codes from mbgioctl.h.
+ * Updated function prototypes.
+ * Revision 1.4 2002/09/06 11:06:35Z martin
+ * Updated function prototypes for Win32 API..
+ * Win32 compatibility macros to use old APIs with new functions.
+ * Support targets OS/2 and NetWare.
+ * Revision 1.3 2002/02/28 10:08:54Z MARTIN
+ * Syntax cleanup for Win32.
+ * Revision 1.2 2002/02/26 14:40:47 MARTIN
+ * Source code cleanup.
+ * Changes for DOS with and without TSR.
+ * Revision 1.1 2002/02/19 13:48:21 MARTIN
+ * Initial revision
+ *
+ **************************************************************************/
+
+#ifndef _MBGDEVIO_H
+#define _MBGDEVIO_H
+
+
+/* Other headers to be included */
+
+#include <mbggeo.h>
+#include <mbg_tgt.h>
+#include <mbgerror.h>
+#include <pcpsdev.h>
+#include <pci_asic.h>
+#include <use_pack.h>
+#include <time.h>
+
+
+#define MBGDEVIO_VERSION 0x0303
+
+#define MBGDEVIO_COMPAT_VERSION 0x0210
+
+#define MBG_MAX_DEVICES 8
+
+#if defined( MBG_TGT_WIN32 )
+
+ #if !defined( MBGDEVIO_XHRT_API )
+ #define MBGDEVIO_XHRT_API 1
+ #endif
+
+ #if !defined( MBGDEVIO_USE_THREAD_API )
+ #define MBGDEVIO_USE_THREAD_API 1
+ #endif
+
+ #if !defined( MBGDEVIO_HAVE_THREAD_AFFINITY )
+ #define MBGDEVIO_HAVE_THREAD_AFFINITY 1
+ #endif
+
+ #define MBG_USE_KERNEL_DRIVER 1
+ #include <windows.h>
+
+#elif defined( MBG_TGT_LINUX )
+
+ #if !defined( MBGDEVIO_XHRT_API )
+ #define MBGDEVIO_XHRT_API 1
+ #endif
+
+ // Thread support under Linux depends strongly on
+ // the versions of some libraries, so the symbols
+ // MBGDEVIO_USE_THREAD_API and MBGDEVIO_HAVE_THREAD_AFFINITY
+ // should be set in the project's Makefile, depending on the
+ // target envionment. Otherwise thread support is disabled
+ // as per default.
+
+ #define MBG_USE_KERNEL_DRIVER 1
+ #include <fcntl.h>
+
+#elif defined( MBG_TGT_BSD )
+
+ #define MBG_USE_KERNEL_DRIVER 1
+ #include <fcntl.h>
+
+#elif defined( MBG_TGT_OS2 )
+
+ #define MBG_USE_KERNEL_DRIVER 1
+
+#elif defined( MBG_TGT_DOS )
+
+ #if !defined( MBG_USE_DOS_TSR )
+ #define MBG_USE_DOS_TSR 1
+ #endif
+
+ #include <pcpsdrvr.h>
+
+#else // other target OSs which access the hardware directly
+
+ #include <pcpsdrvr.h>
+
+#endif
+
+
+#if !defined( MBGDEVIO_XHRT_API )
+ #define MBGDEVIO_XHRT_API 0
+#endif
+
+#if !defined( MBGDEVIO_USE_THREAD_API )
+ #define MBGDEVIO_USE_THREAD_API 0
+#endif
+
+#if !defined( MBGDEVIO_HAVE_THREAD_AFFINITY )
+ #define MBGDEVIO_HAVE_THREAD_AFFINITY 0
+#endif
+
+#ifdef _MBGDEVIO
+ #define _ext
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+// If MBGDEVIO_SIMPLE != 0 then some complex configuration
+// API calls are excluded from build, which would otherwise
+// require some additional mbglib modules to be linked
+// to the application.
+#if !defined( MBGDEVIO_SIMPLE )
+ #define MBGDEVIO_SIMPLE 0
+#endif
+
+
+#if defined( MBG_USE_KERNEL_DRIVER )
+
+ typedef MBG_HANDLE MBG_DEV_HANDLE ;
+
+ #define MBG_INVALID_DEV_HANDLE MBG_INVALID_HANDLE
+
+#else // other target OSs which access the hardware directly
+
+ typedef PCPS_DDEV *MBG_DEV_HANDLE;
+
+ #define MBG_INVALID_DEV_HANDLE NULL
+
+#endif
+
+
+
+#if defined( MBG_TGT_LINUX )
+
+ #include <sched.h>
+
+ #define MBG_PROCESS_ID pid_t
+ #define _mbg_get_current_process() 0
+
+ #define MBG_CPU_SET cpu_set_t
+ #define MBG_CPU_SET_SIZE CPU_SETSIZE
+ #define _mbg_cpu_clear( _ps ) CPU_ZERO( (_ps) )
+ #define _mbg_cpu_set( _i, _ps ) CPU_SET( (_i), (_ps) )
+ #define _mbg_cpu_isset( _i, _ps ) CPU_ISSET( (_i), (_ps) )
+
+ #if MBGDEVIO_USE_THREAD_API
+
+ #include <pthread.h>
+
+ #define MBG_THREAD_ID pthread_t
+ #define _mbg_get_current_thread() 0
+ #define MBG_THREAD_FNC_ATTR // empty
+ #define MBG_THREAD_FNC_RET_VAL void *
+ #define _mbg_thread_exit( _v ) return (void *) (_v)
+
+ #define MBG_MUTEX pthread_mutex_t
+ #define _mbg_mutex_init( _pm ) pthread_mutex_init( (_pm), NULL )
+ #define _mbg_mutex_deinit( _pm ) _nop_macro_fnc()
+ #define _mbg_mutex_lock( _pm ) pthread_mutex_lock( (_pm) )
+ #define _mbg_mutex_unlock( _pm ) pthread_mutex_unlock( (_pm) )
+
+ #endif
+
+#elif defined( MBG_TGT_WIN32 )
+
+ #define MBG_PROCESS_ID HANDLE
+ #define _mbg_get_current_process() GetCurrentProcess()
+
+ #define MBG_CPU_SET DWORD_PTR // Attention: this is not used as pointer!
+ #define MBG_CPU_SET_SIZE ( sizof( MBG_CPU_SET ) * 8 )
+
+ #define MBG_THREAD_ID HANDLE
+ #define _mbg_get_current_thread() GetCurrentThread()
+ #define MBG_THREAD_FNC_ATTR WINAPI
+ #define MBG_THREAD_FNC_RET_VAL DWORD
+ #define _mbg_thread_exit( _v ) ExitThread( _v )
+
+ #define MBG_MUTEX CRITICAL_SECTION
+ #define _mbg_mutex_init( _pm ) InitializeCriticalSection( (_pm) )
+ #define _mbg_mutex_deinit( _pm ) DeleteCriticalSection( (_pm) )
+ #define _mbg_mutex_lock( _pm ) EnterCriticalSection( (_pm) )
+ #define _mbg_mutex_unlock( _pm ) LeaveCriticalSection( (_pm) )
+
+#endif // target specific
+
+
+#if !defined( MBG_TGT_WIN32 )
+
+ #define FILETIME int // just a dummy to avoid build errors
+
+#endif
+
+
+#if !defined( MBG_PROCESS_ID )
+ #define MBG_PROCESS_ID int
+#endif
+
+#if !defined( _mbg_get_current_process )
+ #define _mbg_get_current_process() 0
+#endif
+
+#if !defined( MBG_CPU_SET )
+ #define MBG_CPU_SET int
+#endif
+
+#if !defined( MBG_CPU_SET_SIZE )
+ #define MBG_CPU_SET_SIZE ( sizof( MBG_CPU_SET ) * 8 )
+#endif
+
+#if !defined( _mbg_cpu_clear )
+ #define _mbg_cpu_clear( _ps ) ( *(_ps) = 0 )
+#endif
+
+#if !defined( _mbg_cpu_set )
+ #define _mbg_cpu_set( _i, _ps ) ( *(_ps) |= ( 1UL << (_i) ) )
+#endif
+
+#if !defined( _mbg_cpu_isset )
+ #define _mbg_cpu_isset( _i, _ps ) ( *(_ps) & ( 1UL << (_i) ) )
+#endif
+
+
+#if !defined( MBG_THREAD_ID )
+ #define MBG_THREAD_ID int
+#endif
+
+#if !defined( _mbg_get_current_thread )
+ #define _mbg_get_current_thread() 0
+#endif
+
+#if !defined( MBG_THREAD_FNC_ATTR )
+ #define MBG_THREAD_FNC_ATTR // empty
+#endif
+
+#if !defined( MBG_THREAD_FNC_RET_VAL )
+ #define MBG_THREAD_FNC_RET_VAL void
+#endif
+
+#if !defined( _mbg_thread_exit )
+ #define _mbg_thread_exit( _v ) _nop_macro_fnc()
+#endif
+
+
+#if !defined( MBG_MUTEX )
+ #define MBG_MUTEX int
+#endif
+
+#if !defined( _mbg_mutex_init )
+ #define _mbg_mutex_init( _pm ) _nop_macro_fnc()
+#endif
+
+#if !defined( _mbg_mutex_deinit )
+ #define _mbg_mutex_deinit( _pm ) _nop_macro_fnc()
+#endif
+
+#if !defined( _mbg_mutex_lock )
+ #define _mbg_mutex_lock( _pm ) _nop_macro_fnc()
+#endif
+
+#if !defined( _mbg_mutex_unlock )
+ #define _mbg_mutex_unlock( _pm ) _nop_macro_fnc()
+#endif
+
+typedef struct
+{
+ MBG_THREAD_ID thread_id;
+ #if defined( MBG_TGT_WIN32 )
+ HANDLE exit_request;
+ #endif
+} MBG_THREAD_INFO;
+
+
+
+typedef struct
+{
+ PCPS_HR_TIME_CYCLES htc;
+ uint64_t tstamp64;
+} MBG_XHRT_VARS;
+
+
+typedef struct
+{
+ MBG_XHRT_VARS vars;
+ MBG_XHRT_VARS prv_vars;
+ MBG_PC_CYCLES_FREQUENCY freq_hz;
+ int ioctl_status;
+ int sleep_ms;
+ MBG_MUTEX mutex;
+ MBG_DEV_HANDLE dh;
+} MBG_XHRT_INFO;
+
+
+typedef struct
+{
+ MBG_XHRT_INFO xhrt_info;
+ MBG_THREAD_INFO ti;
+} MBG_POLL_THREAD_INFO;
+
+
+
+/**
+ Match modes to decide how to proceed if a certain
+ model type with certain serial number can not be found
+ */
+enum MBG_MATCH_MODE
+{
+ MBG_MATCH_ANY, /**< open the next available device on the system */
+ MBG_MATCH_MODEL, /**< open the next available device on the system with the same clock type */
+ MBG_MATCH_EXACTLY, /**< force opening exactly the requested device otherwise exit with failure */
+ N_MBG_MATCH_MODE /**< number of known modes */
+};
+
+
+
+typedef struct _MBG_DEVICE_LIST
+{
+ char *device_path; /**< Hardware ID depending on the calling function */
+ struct _MBG_DEVICE_LIST *next;
+
+} MBG_DEVICE_LIST;
+
+
+
+typedef struct _MBG_DEVICENAME_LIST
+{
+ char device_name[40]; /**< readable name */
+ struct _MBG_DEVICENAME_LIST *next;
+
+} MBG_DEVICENAME_LIST;
+
+
+
+#define _mbg_generic_read_var( _dh, _cmd, _s ) \
+ mbg_generic_read( _dh, _cmd, &(_s), sizeof( (_s) ) )
+
+#define _mbg_generic_write_var( _dh, _cmd, _s ) \
+ mbg_generic_write( _dh, _cmd, &(_s), sizeof( (_s) ) )
+
+#define _mbg_generic_read_gps_var( _dh, _cmd, _s ) \
+ mbg_generic_read_gps( _dh, _cmd, &(_s), sizeof( (_s) ) )
+
+#define _mbg_generic_write_gps_var( _dh, _cmd, _s ) \
+ mbg_generic_write_gps( _dh, _cmd, &(_s), sizeof( (_s) ) )
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ Get the version number of the compiled mbgdevio library.
+ If the mbgdevio library is built as a DLL/shared object then
+ the version number of the compiled library may differ from
+ the version number of the import library and header files
+ which have been used to build an application.
+
+ @return The version number
+
+ @see ::MBGDEVIO_VERSION defined in mbgdevio.h.
+ */
+ _MBG_API_ATTR int _MBG_API mbgdevio_get_version( void ) ;
+
+ /**
+ Check if the version of the compiled mbgdevio library is compatible
+ with a certain version which is passed as parameter.
+
+ @param header_version Version number to be checked, should be ::MBGDEVIO_VERSION
+ defined in mbgdevio.h.
+
+ @return ::MBG_SUCCESS if compatible, ::MBG_ERR_LIB_NOT_COMPATIBLE if not.
+
+ @see ::MBGDEVIO_VERSION defined in mbgdevio.h.
+ */
+ _MBG_API_ATTR int _MBG_API mbgdevio_check_version( int header_version ) ;
+
+ /**
+ Open a device by index, starting from 0.
+ This function is <b>out of date</b>, mbg_open_device_by_name()
+ should be used instead.
+
+ See the <b>note</b> for mbg_find_device() for details.
+
+ @param device_index Index of the device, use 0 for the first device.
+ */
+ _MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device( unsigned int device_index ) ;
+
+ /**
+ Get the number of supported devices installed on the computer.
+ This function is <b>out of date</b>, mbg_find_devices_with_names()
+ should be used instead.
+
+ <b>Note:</b> This function is out of date since it may not work
+ correctly for Meinberg devices which are disconnected and reconnected
+ while the system is running (e.g. USB devices). However, the function
+ will be kept for compatibility reasons and works correctly if all
+ Meinberg devices are connected at system boot and are not disconnected
+ and reconnected during operation
+
+ @return The number of devices found.
+
+ @see mbg_find_devices_with_names()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_find_devices( void ) ;
+
+ /**
+ Return the number of supported devices installed on the system and
+ set up a list of unique names of those devices.
+
+ This function should be used preferably instead of mbg_find_devices().
+
+ @param device_list Pointer to a linked list of type ::MBG_DEVICENAME_LIST
+ with device names. The list will be allocated by this
+ function and has to be freed after usage by calling
+ mbg_free_device_name_list().
+ @param max_devices Maximum number of devices the function should look for
+ (can not exceed ::MBG_MAX_DEVICES).
+
+ @return Number of present devices
+
+ @see ::MBG_HW_NAME for the format of the unique names
+ @see mbg_free_device_name_list()
+ @see mbg_find_devices()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_find_devices_with_names( MBG_DEVICENAME_LIST **device_list, int max_devices ) ;
+
+ /**
+ Free the memory of the ::MBG_DEVICENAME_LIST that has been allocated before
+ by mbg_find_devices_with_names().
+
+ @param *list Linked list of type ::MBG_DEVICENAME_LIST
+
+ @see mbg_find_devices_with_names()
+ */
+ _MBG_API_ATTR void _MBG_API mbg_free_device_name_list( MBG_DEVICENAME_LIST *list) ;
+
+ /**
+ Return a handle to a device with a certain unique name.
+ The names of the devices that are installed on the system can be retrieved by
+ the function mbg_find_devices_with_names().
+
+ This function should be used preferably instead of mbg_open_device().
+
+ @param hw_name String with the unique name of the device to be opened
+ @param selection_mode One of the enum values of ::MBG_MATCH_MODE
+
+ @return On success, the function returns a handle to the device, otherwise ::MBG_INVALID_DEV_HANDLE
+
+ @see ::MBG_HW_NAME for the format of the unique names.
+ @see ::MBG_MATCH_MODE
+ @see mbg_find_devices_with_names()
+ */
+ _MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device_by_name( const char* hw_name, int selection_mode ) //##++++
+;
+
+ /**
+ Close a handle to a device and set the handle value to ::MBG_INVALID_DEV_HANDLE.
+ If required, unmap mapped memory.
+
+ @param dev_handle Handle to a Meinberg device.
+ */
+ _MBG_API_ATTR void _MBG_API mbg_close_device( MBG_DEV_HANDLE *dev_handle ) ;
+
+ /**
+ Return a ::PCPS_DRVR_INFO structure that provides information
+ about the kernel device driver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_DRVR_INFO structure which is filled up.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_drvr_info( MBG_DEV_HANDLE dh, PCPS_DRVR_INFO *p ) ;
+
+ /**
+ Return a ::PCPS_DEV structure that provides detailed information about the device.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_DEV structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_device_info( MBG_DEV_HANDLE dh, PCPS_DEV *p ) ;
+
+ /**
+ Return the current state of the on-board::PCPS_STATUS_PORT.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_STATUS_PORT value to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function
+
+ @see \ref group_status_port "bitmask"
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_status_port( MBG_DEV_HANDLE dh, PCPS_STATUS_PORT *p ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Generic read function which writes a command code to the device
+ and reads a number of replied data to a generic buffer.
+
+ <b>Warning</b>: This is for debugging purposes only!
+ The specialized API calls should be used preferably.
+ A specific device may not support any command code.
+
+ @param dh Valid handle to a Meinberg device
+ @param cmd Can be any \ref group_cmd_bytes "command byte" supported by the device
+ @param *p Pointer to a buffer to be filled up
+ @param size Size of the buffer *p
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_generic_write()
+ @see mbg_generic_read_gps()
+ @see mbg_generic_write_gps()
+ @see mbg_generic_io()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_generic_read( MBG_DEV_HANDLE dh, int cmd, void *p, int size ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Generic read function which writes a GPS command code to the device
+ and reads a number of replied data to a generic buffer.
+ The macro _pcps_has_gps_data() or the API call mbg_dev_has_gps_data()
+ check whether this call is supported by a specific card.
+
+ <b>Warning</b>: This is for debugging purposes only!
+ The specialized API calls should be used preferably.
+ A specific device may not support any GPS command code.
+
+ @param dh Valid handle to a Meinberg device
+ @param cmd Can be any \ref group_cmd_bytes "command byte" supported by the device.
+ @param *p Pointer to a buffer to be filled up
+ @param size Size of the buffer *p
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_gps_data()
+ @see mbg_generic_write_gps()
+ @see mbg_generic_read()
+ @see mbg_generic_write()
+ @see mbg_generic_io()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_generic_read_gps( MBG_DEV_HANDLE dh, int cmd, void *p, int size ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Generic write function which writes a command code plus an
+ associated number of data bytes to the device.
+
+ <b>Warning</b>: This is for debugging purposes only!
+ The specialized API calls should be used preferably.
+ A specific device may not support any command code.
+
+ @param dh Valid handle to a Meinberg device
+ @param cmd Can be any \ref group_cmd_bytes "command byte" supported by the device.
+ @param *p Pointer to a buffer to be written
+ @param size Size of the buffer *p
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_generic_read()
+ @see mbg_generic_read_gps()
+ @see mbg_generic_write_gps()
+ @see mbg_generic_io()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_generic_write( MBG_DEV_HANDLE dh, int cmd, const void *p, int size ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Generic write function which writes a GPS command code plus an
+ associated number of data bytes to the device.
+ The macro _pcps_has_gps_data() or the API call mbg_dev_has_gps_data()
+ check whether this call is supported by a specific card.
+
+ <b>Warning</b>: This is for debugging purposes only!
+ The specialized API calls should be used preferably.
+ A specific device may not support any GPS command code.
+
+ @param dh Valid handle to a Meinberg device
+ @param cmd Can be any \ref group_cmd_bytes "command byte" supported by the device.
+ @param *p Pointer to a buffer to be written
+ @param size Size of the buffer *p
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_gps_data()
+ @see mbg_generic_read_gps()
+ @see mbg_generic_read()
+ @see mbg_generic_write()
+ @see mbg_generic_io()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_generic_write_gps( MBG_DEV_HANDLE dh, int cmd, const void *p, int size ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Write and/or read generic data to/from a device.
+ The macro _pcps_has_generic_io() or the API call mbg_dev_has_generic_io()
+ check whether this call is supported by a specific card.
+
+ <b>Warning</b>: This call is for debugging purposes and internal use only!
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_generic_io()
+ @see mbg_generic_read()
+ @see mbg_generic_write()
+ @see mbg_generic_read_gps()
+ @see mbg_generic_write_gps()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_generic_io( MBG_DEV_HANDLE dh, int type, const void *in_p, int in_sz, void *out_p, int out_sz ) ;
+
+ /**
+ Read a ::PCPS_TIME structure returning the current date/time/status.
+ The returned time is local time according to the card's time zone setting,
+ with a resolution of 10 ms (i.e. 10ths of seconds).
+
+ This call is supported by any device manufactured by Meinberg. However,
+ for higher accuracy and resolution the mbg_get_hr_time..() group of calls
+ should be used preferably if supported by the specific device.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_hr_time()
+ @see mbg_set_time()
+ @see mbg_get_sync_time()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_time( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
+
+ /**
+ Set a device's on-board clock manually by passing a ::PCPS_STIME structure
+ The macro _pcps_can_set_time() checks whether this call
+ is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_STIME structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_time()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_time( MBG_DEV_HANDLE dh, const PCPS_STIME *p ) ;
+
+ /**
+ Read a ::PCPS_TIME structure returning the date/time/status reporting
+ when the device was synchronized the last time to its time source,
+ e.g. the DCF77 signal or the GPS satellites.
+ The macro _pcps_has_sync_time() or the API call mbg_dev_has_sync_time()
+ check whether this call is supported by a specific card.
+
+ The macro _pcps_has_sync_time() checks whether this call
+ is supported by a specific card.
+
+ <b>Note:</b> If that information is not available on the board then
+ the value of the returned ::PCPS_TIME::sec field is set to 0xFF.
+ The macro _pcps_time_is_read() can be used to check whether the
+ returned information is valid, or not available.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_time()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_sync_time( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
+
+ /**
+ Wait until the next second change, then return a ::PCPS_TIME
+ structure similar to mbg_get_time().
+
+ <b>Note:</b> This API call is supported under Windows only.
+ The call blocks until the kernel driver detects a second change
+ reported by the device.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_time()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_time_sec_change( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
+
+ /**
+ Read a ::PCPS_HR_TIME (High Resolution time) structure returning
+ the current %UTC time (seconds since 1970), %UTC offset, and status.
+ The macro _pcps_has_hr_time() or the API call mbg_dev_has_hr_time()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This API call provides a higher accuracy and resolution
+ than mbg_get_time(). However, it does not account for the latency
+ which is introduced when accessing the board.
+ The mbg_get_hr_time_cycles() and mbg_get_hr_time_comp() calls
+ provides mechanisms to account for and/or compensate the latency.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_HR_TIME structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_hr_time()
+ @see mbg_get_time()
+ @see mbg_get_hr_time_cycles()
+ @see mbg_get_hr_time_comp()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_hr_time( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p ) ;
+
+ /* (Intentionally excluded from Doxygen )
+ Write a high resolution time stamp ::PCPS_TIME_STAMP to the clock
+ to configure a %UTC time when the clock shall generate an event.
+ The macro _pcps_has_event_time() or the API call mbg_dev_has_event_time()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This is only supported by some special firmware.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME_STAMP structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_event_time()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_event_time( MBG_DEV_HANDLE dh, const PCPS_TIME_STAMP *p ) ;
+
+ /**
+ Read the configuration of a device's serial port.
+ The macro _pcps_has_serial() checks whether this call
+ is supported by a specific card.
+
+ <b>Note:</b> This function is supported only by a certain class
+ of devices, so it should not be called directly. The generic
+ function mbg_get_serial_settings() should be used instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_SERIAL structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see \ref group_cmd_bytes
+ @see mbg_get_serial_settings()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_serial( MBG_DEV_HANDLE dh, PCPS_SERIAL *p ) ;
+
+ /**
+ Write the configuration of a device's serial port.
+ The macro _pcps_has_serial() checks whether this call
+ is supported by a specific card.
+
+ <b>Note:</b> This function is supported only by a certain class
+ of devices, so it should not be called directly. The generic
+ function mbg_save_serial_settings() should be used instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_SERIAL structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see \ref group_cmd_bytes
+ @see mbg_save_serial_settings()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_serial( MBG_DEV_HANDLE dh, const PCPS_SERIAL *p ) ;
+
+ /**
+ Read the card's time zone/daylight saving configuration code.
+ That tzcode is supported by some simpler cards and only allows only
+ a very basic configuration.
+ The macro _pcps_has_tzcode() or the API call mbg_dev_has_tzcode()
+ check whether this call is supported by a specific card.
+ Other cards may support the mbg_get_pcps_tzdl() or mbg_get_gps_tzdl()
+ calls instead which allow for a more detailed configuration of the
+ time zone and daylight saving settings.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TZCODE structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_tzcode()
+ @see mbg_set_tzcode()
+ @see mbg_get_pcps_tzdl()
+ @see mbg_get_gps_tzdl()
+ @see \ref group_cmd_bytes
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_tzcode( MBG_DEV_HANDLE dh, PCPS_TZCODE *p ) ;
+
+ /**
+ Write the card's time zone/daylight saving configuration code.
+ That tzcode is supported by some simpler cards and only allows only
+ a very basic configuration.
+ The macro _pcps_has_tzcode() or the API call mbg_dev_has_tzcode()
+ check whether this call is supported by a specific card.
+ Other cards may support the mbg_set_pcps_tzdl() or mbg_set_gps_tzdl()
+ calls instead which allow for a more detailed configuration of the
+ time zone and daylight saving settings.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TZCODE structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_tzcode()
+ @see mbg_get_tzcode()
+ @see mbg_set_pcps_tzdl()
+ @see mbg_set_gps_tzdl()
+ @see \ref group_cmd_bytes
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_tzcode( MBG_DEV_HANDLE dh, const PCPS_TZCODE *p ) ;
+
+ /**
+ Read the card's time zone/daylight saving parameters using the
+ ::PCPS_TZDL structure.
+ The macro _pcps_has_pcps_tzdl() or the API call mbg_dev_has_pcps_tzdl()
+ check whether this call is supported by a specific card.
+ Other cards may support the mbg_get_tzcode() or mbg_get_gps_tzdl()
+ calls instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TZDL structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_pcps_tzdl()
+ @see mbg_set_pcps_tzdl()
+ @see mbg_get_tzcode()
+ @see mbg_get_gps_tzdl()
+ @see \ref group_cmd_bytes
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_pcps_tzdl( MBG_DEV_HANDLE dh, PCPS_TZDL *p ) ;
+
+ /**
+ Write the card's time zone/daylight saving parameters using the
+ ::PCPS_TZDL structure.
+ The macro _pcps_has_pcps_tzdl() or the API call mbg_dev_has_pcps_tzdl()
+ check whether this call is supported by a specific card.
+ Other cards may support the mbg_set_tzcode() or mbg_set_gps_tzdl()
+ calls instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TZDL structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_pcps_tzdl()
+ @see mbg_get_pcps_tzdl()
+ @see mbg_set_tzcode()
+ @see mbg_set_gps_tzdl()
+ @see \ref group_cmd_bytes
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_pcps_tzdl( MBG_DEV_HANDLE dh, const PCPS_TZDL *p ) ;
+
+ /**
+ Read the reference time offset from %UTC for clocks which can't determine
+ that offset automatically, e.g. from an IRIG input signal.
+ The macro _pcps_has_ref_offs() or the API call mbg_dev_has_ref_offs()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::MBG_REF_OFFS value to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_ref_offs()
+ @see mbg_set_ref_offs()
+ @see ::PCPS_GET_REF_OFFS
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_ref_offs( MBG_DEV_HANDLE dh, MBG_REF_OFFS *p ) ;
+
+ /**
+ Write the reference time offset from %UTC for clocks which can't determine
+ that offset automatically, e.g. from an IRIG input signal.
+ The macro _pcps_has_ref_offs() or the API call mbg_dev_has_ref_offs()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::MBG_REF_OFFS value to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_ref_offs()
+ @see mbg_get_ref_offs()
+ @see ::PCPS_SET_REF_OFFS
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_ref_offs( MBG_DEV_HANDLE dh, const MBG_REF_OFFS *p ) ;
+
+ /**
+ Read a ::MBG_OPT_INFO structure containing optional settings, controlled by flags.
+ The ::MBG_OPT_INFO structure contains a mask of supported flags plus the current
+ settings of those flags.
+ The macro _pcps_has_opt_flags() or the API call mbg_dev_has_opt_flags()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::MBG_OPT_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_opt_flags()
+ @see mbg_set_opt_settings()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_opt_info( MBG_DEV_HANDLE dh, MBG_OPT_INFO *p ) ;
+
+ /**
+ Write a ::MBG_OPT_SETTINGS structure contains optional settings, controlled by flags.
+ The macro _pcps_has_opt_flags() or the API call mbg_dev_has_opt_flags()
+ check whether this call is supported by a specific card.
+ The ::MBG_OPT_INFO structure should be read first to check which of the specified
+ flags is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::MBG_OPT_SETTINGS structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_opt_flags()
+ @see mbg_get_opt_info()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_opt_settings( MBG_DEV_HANDLE dh, const MBG_OPT_SETTINGS *p ) ;
+
+ /**
+ Read an ::IRIG_INFO structure containing the configuration of an IRIG input
+ plus the possible settings supported by that input.
+ The macro _pcps_is_irig_rx() or the API call mbg_dev_is_irig_rx()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an ::IRIG_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_irig_rx_settings()
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig_tx()
+ @see mbg_dev_has_irig()
+ @see \ref group_icode
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_irig_rx_info( MBG_DEV_HANDLE dh, IRIG_INFO *p ) ;
+
+ /**
+ Write an ::IRIG_SETTINGS structure containing the configuration of an IRIG input.
+ The macro _pcps_is_irig_rx() or the API call mbg_dev_is_irig_rx()
+ check whether this call is supported by a specific card.
+ The ::IRIG_INFO structure should be read first to determine the possible
+ settings supported by this card's IRIG input.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::IRIG_SETTINGS structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_irig_rx_info()
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig_tx()
+ @see mbg_dev_has_irig()
+ @see \ref group_icode
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_irig_rx_settings( MBG_DEV_HANDLE dh, const IRIG_SETTINGS *p ) ;
+
+ /**
+ Clear the card's on-board time capture FIFO buffer.
+ The macro _pcps_can_clr_ucap_buff() or the API call mbg_dev_can_clr_ucap_buff()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_can_clr_ucap_buff()
+ @see mbg_get_ucap_entries()
+ @see mbg_get_ucap_event()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_clr_ucap_buff( MBG_DEV_HANDLE dh ) ;
+
+ /**
+ Read a ::PCPS_UCAP_ENTRIES structure to retrieve the number of saved
+ user capture events and the maximum capture buffer size.
+ The macro _pcps_has_ucap() or the API call mbg_dev_has_ucap()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_UCAP_ENTRIES structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_ucap()
+ @see mbg_get_ucap_entries()
+ @see mbg_get_ucap_event()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_ucap_entries( MBG_DEV_HANDLE dh, PCPS_UCAP_ENTRIES *p ) ;
+
+ /**
+ Retrieve a single time capture event from the on-board FIFO buffer
+ using a ::PCPS_HR_TIME structure. The oldest entry of the FIFO is retrieved
+ and then removed from the FIFO.
+ If no capture event is available in the FIFO buffer then both the seconds
+ and the fractions of the returned timestamp are 0.
+ The macro _pcps_has_ucap() or the API call mbg_dev_has_ucap()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This call is very much faster than the older mbg_get_gps_ucap()
+ call which is obsolete but still supported for compatibility with
+ older cards.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_HR_TIME structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_ucap()
+ @see mbg_get_ucap_entries()
+ @see mbg_clr_ucap_buff()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_ucap_event( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p ) ;
+
+ /**
+ Read the card's time zone/daylight saving parameters using the ::TZDL
+ structure.
+ The macro _pcps_has_tzdl() or the API call mbg_dev_has_tzdl()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> In spite of the function name this call may also be
+ supported by non-GPS cards. Other cards may support the mbg_get_tzcode()
+ or mbg_get_pcps_tzdl() calls instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::TZDL structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_tzdl()
+ @see mbg_set_gps_tzdl()
+ @see mbg_get_tzcode()
+ @see mbg_get_pcps_tzdl()
+ @see \ref group_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_tzdl( MBG_DEV_HANDLE dh, TZDL *p ) ;
+
+ /**
+ Write the card's time zone/daylight saving parameters using the ::TZDL
+ structure.
+ The macro _pcps_has_tzdl() or the API call mbg_dev_has_tzdl()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> In spite of the function name this call may also be
+ supported by non-GPS cards. Other cards may support the mbg_set_tzcode()
+ or mbg_set_pcps_tzdl() calls instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::TZDL structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_tzdl()
+ @see mbg_get_gps_tzdl()
+ @see mbg_set_tzcode()
+ @see mbg_set_pcps_tzdl()
+ @see \ref group_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_tzdl( MBG_DEV_HANDLE dh, const TZDL *p ) ;
+
+ /**
+ Retrieve the software revision of a GPS receiver.
+ This call is obsolete but still supported for compatibility
+ with older GPS cards.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> The function mbg_get_gps_receiver_info() should
+ be used instead, if supported by the card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::SW_REV structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_is_gps()
+ @see mbg_get_gps_receiver_info()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_sw_rev( MBG_DEV_HANDLE dh, SW_REV *p ) ;
+
+ /**
+ Retrieve the status of the battery buffered GPS variables.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+ The GPS receiver stays in cold boot mode until all of the
+ data sets are valid.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::BVAR_STAT structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_bvar_stat( MBG_DEV_HANDLE dh, BVAR_STAT *p ) ;
+
+ /**
+ Read the current board time using a ::TTM structure.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This call is pretty slow, so the mbg_get_hr_time_..()
+ group of calls should be used preferably.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::TTM structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_time( MBG_DEV_HANDLE dh, TTM *p ) ;
+
+ /**
+ Write a ::TTM structure to a GPS receiver in order to set the
+ on-board date and time.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::TTM structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_time( MBG_DEV_HANDLE dh, const TTM *p ) ;
+
+ /**
+ Read a ::PORT_PARM structure to retrieve the configuration
+ of the device's serial ports.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This function is obsolete since it is only
+ supported by a certain class of devices and can handle only
+ up to 2 ports. The generic function mbg_get_serial_settings()
+ should be used instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PORT_PARM structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_serial_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_port_parm( MBG_DEV_HANDLE dh, PORT_PARM *p ) ;
+
+ /**
+ Write a ::PORT_PARM structure to configure the on-board
+ serial ports.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This function is obsolete since it is only
+ supported by a certain class of devices and can handle only
+ up to 2 ports. The generic function mbg_save_serial_settings()
+ should be used instead.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PORT_PARM structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_save_serial_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_parm( MBG_DEV_HANDLE dh, const PORT_PARM *p ) ;
+
+ /**
+ Read an ::ANT_INFO structure to retrieve status information of the GPS antenna.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> Normally the antenna connection status can also be
+ determined by evaluation of the ::PCPS_TIME::signal or ::PCPS_HR_TIME::signal
+ fields.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ANT_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_ant_info( MBG_DEV_HANDLE dh, ANT_INFO *p ) ;
+
+ /**
+ Read a time capture event from the on-board FIFO buffer using a ::TTM structure.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> This call is pretty slow and has been obsoleted by
+ mbg_get_ucap_event() which should be used preferably, if supported
+ by the card. Anyway, this call is still supported for compatibility
+ with older cards.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::TTM structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_ucap_entries()
+ @see mbg_get_ucap_event()
+ @see mbg_clr_ucap_buff()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_ucap( MBG_DEV_HANDLE dh, TTM *p ) ;
+
+ /**
+ Read an ::ENABLE_FLAGS structure reporting whether certain outputs
+ shall be enabled immediately after the card's power-up, or only
+ after the card has synchronized to its input signal.
+ The macro _pcps_has_gps_data() or the API call mbg_dev_has_gps_data()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> Not all of the input signals specified for the
+ ::ENABLE_FLAGS structure can be modified individually.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::ENABLE_FLAGS structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see ::ENABLE_FLAGS
+ @see mbg_set_gps_enable_flags()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_enable_flags( MBG_DEV_HANDLE dh, ENABLE_FLAGS *p ) ;
+
+ /**
+ Write an ENABLE_FLAGS structure to configure whether certain outputs
+ shall be enabled immediately after the card's power-up, or only
+ after the card has synchronized to its input signal.
+ The macro _pcps_has_gps_data() or the API call mbg_dev_has_gps_data()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> Not all of the input signals specified for the
+ ENABLE_FLAGS structure can be modified individually.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ENABLE_FLAGS structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see ENABLE_FLAGS
+ @see mbg_get_gps_enable_flags()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_enable_flags( MBG_DEV_HANDLE dh, const ENABLE_FLAGS *p ) ;
+
+ /**
+ Read a ::STAT_INFO structure to retrieve the status of the
+ GPS receiver, including mode of operation and numer of
+ visible/usable satellites.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::STAT_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see ::STAT_INFO
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_stat_info( MBG_DEV_HANDLE dh, STAT_INFO *p ) ;
+
+ /**
+ Sends a ::GPS_CMD to a GPS receiver.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::GPS_CMD
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see ::PC_GPS_CMD_BOOT, ::PC_GPS_CMD_INIT_SYS, ::PC_GPS_CMD_INIT_USER, ::PC_GPS_CMD_INIT_DAC
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_cmd( MBG_DEV_HANDLE dh, const GPS_CMD *p ) ;
+
+ /**
+ Read the current GPS receiver position using the ::POS structure
+ which contains different coordinate formats.
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::POS structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_gps_pos_xyz()
+ @see mbg_set_gps_pos_lla()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_pos( MBG_DEV_HANDLE dh, POS *p ) ;
+
+ /**
+ Preset the GPS receiver position using ::XYZ coordinates
+ (ECEF: WGS84 "Earth Centered, Earth fixed" kartesian coordinates).
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param p Position in ::XYZ format to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_gps_pos_lla()
+ @see mbg_get_gps_pos()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_xyz( MBG_DEV_HANDLE dh, const XYZ p ) ;
+
+ /**
+ Preset the GPS receiver position using ::LLA coordinates
+ (longitude, latitude, altitude)
+ The macro _pcps_is_gps() or the API call mbg_dev_is_gps()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param p Position in ::LLA format to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_gps_pos_xyz()
+ @see mbg_get_gps_pos()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_lla( MBG_DEV_HANDLE dh, const LLA p ) ;
+
+ /**
+ Read the configured length of the GPS antenna cable (::ANT_CABLE_LEN).
+ The cable delay is internally compensated by 5ns per meter cable.
+ The macro _pcps_has_cab_len() or the API call mbg_dev_has_cab_len()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p ::ANT_CABLE_LEN structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_cab_len()
+ @see mbg_set_gps_ant_cable_len()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_ant_cable_len( MBG_DEV_HANDLE dh, ANT_CABLE_LEN *p ) ;
+
+ /**
+ Write the length of the GPS antenna cable (::ANT_CABLE_LEN).
+ The cable delay is internally compensated by 5ns per meter cable.
+ The macro _pcps_has_cab_len() or the API call mbg_dev_has_cab_len()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p ::ANT_CABLE_LEN structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_cab_len()
+ @see mbg_get_gps_ant_cable_len()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_ant_cable_len( MBG_DEV_HANDLE dh, const ANT_CABLE_LEN *p ) ;
+
+ /**
+ Read a ::RECEIVER_INFO structure from a card.
+ The macro _pcps_has_receiver_info() or the API call mbg_dev_has_receiver_info()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> Applications should call mbg_setup_receiver_info()
+ preferably, which also sets up a basic ::RECEIVER_INFO structure
+ for card which don't provide that structure by themselves.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::RECEIVER_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_setup_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_receiver_info( MBG_DEV_HANDLE dh, RECEIVER_INFO *p ) ;
+
+ /**
+ Write the configuration for a single serial port using the ::PORT_SETTINGS_IDX
+ structure which contains both the ::PORT_SETTINGS and the port index value.
+ Except for the parameter types, this call is equivalent to mbg_set_gps_port_settings().
+ The macro _pcps_has_receiver_info() or the API call mbg_dev_has_receiver_info()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> The function mbg_save_serial_settings() should be used preferably
+ to write new port configuration to the board.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::PORT_SETTINGS_IDX structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_save_serial_settings()
+ @see mbg_set_gps_port_settings()
+ @see mbg_dev_has_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_settings_idx( MBG_DEV_HANDLE dh, const PORT_SETTINGS_IDX *p ) ;
+
+ /**
+ Write the configuration for a single serial port using the ::PORT_SETTINGS
+ structure plus the port index.
+ Except for the parameter types, this call is equivalent to mbg_set_gps_port_settings_idx().
+ The macro _pcps_has_receiver_info() or the API call mbg_dev_has_receiver_info()
+ check whether this call is supported by a specific card.
+
+ <b>Note:</b> The function mbg_save_serial_settings() should be used preferably
+ to write new port configuration to the board.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::PORT_SETTINGS structure to be filled up
+ @param idx Index of the serial port to be configured (starting from 0 ).
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_save_serial_settings()
+ @see mbg_set_gps_port_settings_idx()
+ @see mbg_dev_has_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_settings( MBG_DEV_HANDLE dh, const PORT_SETTINGS *p, int idx ) ;
+
+ /**
+ Set up a ::RECEIVER_INFO structure for a device.
+ If the device supports the ::RECEIVER_INFO structure then the structure
+ is read from the device, otherwise a structure is set up using
+ default values depending on the device type.
+ The function mbg_get_device_info() must have been called before,
+ and the returned PCPS_DEV structure passed to this function.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *pdev Pointer to a ::PCPS_DEV structure returned by mbg_get_device_info()
+ @param *p Pointer to a ::RECEIVER_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_device_info()
+ @see mbg_dev_has_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_setup_receiver_info( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, RECEIVER_INFO *p ) ;
+
+ /**
+ Read all serial port settings and supported configuration parameters.
+
+ The functions mbg_get_device_info() and mbg_setup_receiver_info()
+ must have been called before, and the returned ::PCPS_DEV and
+ ::RECEIVER_INFO structures must be passed to this function.
+
+ The complementary function mbg_save_serial_settings() should be used
+ to write the modified serial port configuration back to the board.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *pdev Pointer to a ::PCPS_DEV structure.
+ @param *pcfg Pointer to a ::RECEIVER_PORT_CFG structure to be filled up.
+ @param *p_ri Pointer to a ::RECEIVER_INFO structure.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_device_info()
+ @see mbg_setup_receiver_info()
+ @see mbg_save_serial_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_serial_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, RECEIVER_PORT_CFG *pcfg, const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ Write the configuration settings for a single serial port to the board.
+
+ Modifications to the serial port configuration should be made only
+ after mbg_get_serial_settings() had been called to read all serial port
+ settings and supported configuration parameters.
+ This function has finally to be called once for every serial port
+ the configuration of which has been modified.
+
+ As also required by mbg_get_serial_settings(), the functions
+ mbg_get_device_info() and mbg_setup_receiver_info() must have been
+ called before, and the returned ::PCPS_DEV and ::RECEIVER_INFO structures
+ must be passed to this function.
+
+ @param dh Valid handle to a Meinberg device
+ @param *pdev Pointer to a ::PCPS_DEV structure
+ @param *pcfg Pointer to a ::RECEIVER_PORT_CFG structure
+ @param port_num Index of the ::serial port to be saved
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_serial_settings()
+ @see mbg_get_device_info()
+ @see mbg_setup_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_save_serial_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, RECEIVER_PORT_CFG *pcfg, int port_num ) ;
+
+ /**
+ Read the version code of the on-board PCI/PCIe interface ASIC.
+ The macro _pcps_has_asic_version() or the API call mbg_dev_has_asic_version()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCI_ASIC_VERSION type to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function
+
+ @see mbg_dev_has_asic_version()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_asic_version( MBG_DEV_HANDLE dh, PCI_ASIC_VERSION *p ) ;
+
+ /**
+ Read the features of the on-board PCI/PCIe interface ASIC.
+ The macro _pcps_has_asic_features() or the API call mbg_dev_has_asic_features()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::PCI_ASIC_FEATURES type to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_asic_features()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_asic_features( MBG_DEV_HANDLE dh, PCI_ASIC_FEATURES *p ) ;
+
+ /**
+ Read a ::PCPS_TIME_CYCLES structure that contains a ::PCPS_TIME structure
+ and a PC cycle counter value which can be used to compensate the latency
+ of the call, i.e. the program execution time until the time stamp has actually
+ been read from the board.
+
+ This call is supported for any card, similar to mbg_get_time(). However,
+ the mbg_get_hr_time_cyles() call should be used preferably if supported by
+ the specific card since that call provides much better accuracy than this one.
+
+ The cycle counter value corresponds to a value returned by QueryPerformanceCounter()
+ under Windows, and get_cycles() under Linux. On other operating systems the returned
+ cycles value is always 0.
+
+ Applications should first pick up their own cycle counter value and then call
+ this function. The difference of the cycle counter values corresponds to the
+ latency of the call in units of the cycle counter clock frequency, e.g as reported
+ by QueryPerformanceFrequency() under Windows.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME_CYCLES structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_hr_time_cycles()
+ @see mbg_get_hr_time_comp()
+ @see mbg_get_hr_time()
+ @see mbg_get_time()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_time_cycles( MBG_DEV_HANDLE dh, PCPS_TIME_CYCLES *p ) ;
+
+ /**
+ Read a ::PCPS_HR_TIME_CYCLES structure that contains a ::PCPS_HR_TIME structure
+ and a PC cycle counter value which can be used to compensate the latency
+ of the call, i.e. the program execution time until the time stamp has actually
+ been read from the board.
+
+ The macro _pcps_has_hr_time() or the API call mbg_dev_has_hr_time()
+ check whether this call is supported by a specific card.
+
+ The cycle counter value corresponds to a value returned by QueryPerformanceCounter()
+ under Windows, and get_cycles() under Linux. On other operating systems the returned
+ cycles value is always 0.
+
+ Applications should first pick up their own cycle counter value and then call
+ this function. The difference of the cycle counter values corresponds to the
+ latency of the call in units of the cycle counter clock frequency, e.g as reported
+ by QueryPerformanceFrequency() under Windows.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_HR_TIME_CYCLES structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_hr_time_comp()
+ @see mbg_get_hr_time()
+ @see mbg_get_time_cycles()
+ @see mbg_get_time()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_cycles( MBG_DEV_HANDLE dh, PCPS_HR_TIME_CYCLES *p ) ;
+
+ /**
+ Read a ::PCPS_HR_TIME structure plus cycle counter value, and correct the
+ time stamp for the latency of the call as described for mbg_get_hr_time_cycles(),
+ then return the compensated time stamp and optionally the latency.
+
+ The macro _pcps_has_hr_time() or the API call mbg_dev_has_hr_time()
+ check whether this call is supported by a specific card.
+
+ The cycle counter value corresponds to a value returned by QueryPerformanceCounter()
+ under Windows, and get_cycles() under Linux. On other operating systems the returned
+ cycles value is always 0.
+
+ Applications should first pick up their own cycle counter value and then call
+ this function. The difference of the cycle counter values corresponds to the
+ latency of the call in units of the cycle counter clock frequency, e.g as reported
+ by QueryPerformanceFrequency() under Windows.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ @param *hns_latency Optional pointer to an int32_t value to return
+ the latency in 100ns units. Pass NULL if not used.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_hr_time_comp()
+ @see mbg_get_hr_time()
+ @see mbg_get_time_cycles()
+ @see mbg_get_time()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_comp( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p, int32_t *hns_latency ) ;
+
+ /**
+ Read an ::IRIG_INFO structure containing the configuration of an IRIG output
+ plus the possible settings supported by that output.
+ The macro _pcps_has_irig_tx() or the API call mbg_dev_has_irig_tx()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an ::IRIG_INFO structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_irig_tx_settings()
+ @see mbg_dev_has_irig_tx()
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig()
+ @see \ref group_icode
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_irig_tx_info( MBG_DEV_HANDLE dh, IRIG_INFO *p ) ;
+
+ /**
+ Write an ::IRIG_SETTINGS structure containing the configuration of an IRIG output.
+ The macro _pcps_has_irig_tx() or the API call mbg_dev_has_irig_tx()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an ::IRIG_INFO structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_irig_tx_info()
+ @see mbg_dev_has_irig_tx()
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig()
+ @see \ref group_icode
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_irig_tx_settings( MBG_DEV_HANDLE dh, const IRIG_SETTINGS *p ) ;
+
+ /**
+ Read a ::SYNTH structure containing the configuration of an optional
+ on-board programmable frequency synthesizer.
+ The macro _pcps_has_synth() or the API call mbg_dev_has_synth()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::SYNTH structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_synth()
+ @see mbg_set_synth()
+ @see mbg_get_synth_state()
+ @see \ref group_synth
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_synth( MBG_DEV_HANDLE dh, SYNTH *p ) ;
+
+ /**
+ Write a ::SYNTH structure containing the configuration of an optional
+ on-board programmable frequency synthesizer.
+ The macro _pcps_has_synth() or the API call mbg_dev_has_synth()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::SYNTH structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_synth()
+ @see mbg_get_synth()
+ @see mbg_get_synth_state()
+ @see \ref group_synth
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_synth( MBG_DEV_HANDLE dh, const SYNTH *p ) ;
+
+ /**
+ Read a ::SYNTH_STATE structure reporting the current state
+ of an optional on-board programmable frequency synthesizer.
+ The macro _pcps_has_synth() or the API call mbg_dev_has_synth()
+ check whether this call is supported by a specific card.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::SYNTH_STATE structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_synth()
+ @see mbg_get_synth()
+ @see mbg_set_synth()
+ @see \ref group_synth
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_synth_state( MBG_DEV_HANDLE dh, SYNTH_STATE *p ) ;
+
+ /**
+ Check if a specific device supports the mbg_get_fast_hr_timestamp_...() calls.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_fast_hr_timestamp_cycles()
+ @see mbg_get_fast_hr_timestamp_comp()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Read a high resolution ::PCPS_TIME_STAMP_CYCLES structure via memory mapped access.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME_STAMP_CYCLES structure to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_fast_hr_timestamp()
+ @see mbg_get_fast_hr_timestamp_comp()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_cycles( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP_CYCLES *p ) ;
+
+ /**
+ Read a high resolution ::PCPS_TIME_STAMP via memory mapped access,
+ and compensate the latency of the time stamp before it is returned.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_TIME_STAMP structure to be filled up
+ @param *hns_latency Optionally receive the latency in hectonanoseconds
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_fast_hr_timestamp()
+ @see mbg_get_fast_hr_timestamp_comp()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP *p, int32_t *hns_latency ) ;
+
+ /**
+ Check if a specific device is a GPS receiver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_gps( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device is a DCF77 receiver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_dcf( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device is a MSF receiver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_msf( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device is a WWVB receiver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_wwvb( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device is a long wave signal receiver, e.g. DCF77, MSF or WWVB.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_lwr( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device is an IRIG receiver which supports
+ configuration of the IRIG input.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_irig_rx_info()
+ @see mbg_set_irig_rx_settings()
+ @see mbg_dev_has_irig_tx()
+ @see mbg_dev_has_irig()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_is_irig_rx( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the HR_TIME functions.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_hr_time()
+ @see mbg_get_hr_time_cycles()
+ @see mbg_get_hr_time_comp()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_hr_time( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports configuration of antenna cable length.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_gps_ant_cable_len()
+ @see mbg_set_gps_ant_cable_len()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_cab_len( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports timezone / daylight saving configuration
+ using the ::TZDL structure.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_gps_tzdl()
+ @see mbg_set_gps_tzdl()
+ @see mbg_dev_has_tz()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_tzdl( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports timezone / daylight saving configuration
+ using the ::PCPS_TZDL structure.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_pcps_tzdl()
+ @see mbg_set_pcps_tzdl()
+ @see mbg_dev_has_tz()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_pcps_tzdl( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports timezone configuration
+ using the ::PCPS_TZCODE type.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_tzcode()
+ @see mbg_set_tzcode()
+ @see mbg_dev_has_tz()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_tzcode( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports any kind of timezone configuration.
+ This can be used e.g. to check if a specifig dialog or menu has to
+ be displayed.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_has_tzdl()
+ @see mbg_dev_has_pcps_tzdl()
+ @see mbg_dev_has_tzcode()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_tz( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Check if a specific device supports setting an event time, i.e.
+ configure a %UTC time when the clock shall generate an event.
+
+ <b>Note:</b> This is only supported by some special firmware.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_event_time()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_event_time( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the ::RECEIVER_INFO structure and related calls.
+ Older GPS devices may not support that structure.
+
+ The mbg_get_gps_receiver_info() call uses this call to decide whether a
+ ::RECEIVER_INFO can be read directly from a device, or whether a default
+ structure has to be set up using default values depending on the device type.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_gps_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_receiver_info( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the mbg_clr_ucap_buff() call
+ used to clear a card's on-board time capture FIFO buffer.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_clr_ucap_buff()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_can_clr_ucap_buff( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the mbg_get_ucap_entries() and
+ mbg_get_ucap_event() calls.
+
+ If the card does not but it is a GPS card then the card provides
+ a time capture FIFO buffer and the obsolete mbg_get_gps_ucap()
+ call can be used to retrieve entries from the FIFO buffer.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_ucap_entries()
+ @see mbg_get_ucap_event()
+ @see mbg_clr_ucap_buff()
+ @see mbg_get_gps_ucap()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_ucap( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides an IRIG output which can
+ be configured.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_irig_tx_info()
+ @see mbg_set_irig_tx_settings()
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig()
+ @see \ref group_icode
+
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_irig_tx( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Check if a specific device provides a serial output supporting
+ higher baud rates than older cards, i.e. ::DEFAULT_BAUD_RATES_DCF_HS
+ rather than ::DEFAULT_BAUD_RATES_DCF.
+
+ The mbg_get_serial_settings() takes care of this, so applications
+ which use that call as suggested won't need to use this call directly.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_serial_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_serial_hs( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides an input signal level value which
+ may be displayed, e.g. DCF77 or IRIG cards.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_signal( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides an modulation signal which may be
+ displayed, e.g. the second marks of a DCF77 AM receiver.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_mod( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides either an IRIG input or output.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_dev_is_irig_rx()
+ @see mbg_dev_has_irig_tx()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_irig( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides a configurable ref time offset
+ required to convert the received time to %UTC.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_ref_offs()
+ @see mbg_set_ref_offs()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_ref_offs( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the ::MBG_OPT_INFO/::MBG_OPT_SETTINGS
+ structures containing optional settings, controlled by flags.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_opt_info()
+ @see mbg_set_opt_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_opt_flags( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports large configuration data structures
+ as have been introducesde with the GPS receivers.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_gps_data( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device provides a programmable frequency synthesizer.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_synth()
+ @see mbg_set_synth()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_synth( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /* (Intentionally excluded from Doxygen)
+ Check if a specific device supports the mbg_generic_io() call.
+
+ <b>Warning</b>: That call is for debugging purposes and internal use only!
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_generic_io()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_generic_io( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the mbg_get_asic_version() call.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_asic_version()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_asic_version( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Check if a specific device supports the mbg_get_asic_features() call.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_asic_features()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_dev_has_asic_features( MBG_DEV_HANDLE dh, int *p ) ;
+
+ /**
+ Read a ::POUT_INFO_IDX array of current settings and configuration
+ options of a card's programmable pulse outputs.
+ The function mbg_setup_receiver_info() must have been called before,
+ and the returned ::RECEIVER_INFO structure passed to this function.
+ The function should only be called if the ::RECEIVER_INFO::n_prg_out
+ field (i.e. the number of programmable outputs on the board) is not 0.
+
+ The array passed to this function to receive the returned data
+ must be able to hold at least ::RECEIVER_INFO::n_prg_out elements.
+
+ @param dh Valid handle to a Meinberg device.
+ @param pii Pointer to a an array of ::POUT_INFO_IDX structures to be filled up
+ @param *p_ri Pointer to a ::RECEIVER_INFO structure returned by mbg_setup_receiver_info()
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_set_gps_pout_settings_idx()
+ @see mbg_set_gps_pout_settings()
+ @see mbg_setup_receiver_info()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_pout_info( MBG_DEV_HANDLE dh, POUT_INFO_IDX pii[], const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ Write the configuration for a single programmable pulse output using
+ the ::POUT_SETTINGS_IDX structure which contains both the ::POUT_SETTINGS
+ and the output index value.
+ Except for the parameter types, this call is equivalent to
+ mbg_set_gps_pout_settings().
+ The function should only be called if the ::RECEIVER_INFO::n_prg_out field
+ (i.e. the number of programmable outputs on the board) is not 0, and the
+ output index value must be in the range 0..::RECEIVER_INFO::n_prg_out.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::POUT_SETTINGS_IDX structure to be written
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_gps_all_pout_info()
+ @see mbg_set_gps_pout_settings()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_pout_settings_idx( MBG_DEV_HANDLE dh, const POUT_SETTINGS_IDX *p ) ;
+
+ /**
+ Write the configuration for a single programmable pulse output using
+ the ::POUT_SETTINGS structure plus the index of the output to be configured.
+ Except for the parameter types, this call is equivalent to
+ mbg_set_gps_pout_settings_idx().
+ The function should only be called if the ::RECEIVER_INFO::n_prg_out field
+ (i.e. the number of programmable outputs on the board) is not 0, and the
+ output index value must be in the range 0..::RECEIVER_INFO::n_prg_out.
+
+ @param dh Valid handle to a Meinberg device.
+ @param *p Pointer to a ::POUT_SETTINGS structure to be written
+ @param idx Index of the programmable pulse output to be configured (starting from 0 ).
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_gps_all_pout_info()
+ @see mbg_set_gps_pout_settings_idx()
+*/
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_pout_settings( MBG_DEV_HANDLE dh, const POUT_SETTINGS *p, int idx ) ;
+
+ /**
+ Read a card's IRQ status information which includes flags indicating
+ whether IRQs are currently enabled, and whether IRQ support by a card
+ is possibly unsafe due to the firmware and interface chip version.
+
+ @param dh Valid handle to a Meinberg device
+ @param *p Pointer to a ::PCPS_IRQ_STAT_INFO variable to be filled up
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_irq_stat_info( MBG_DEV_HANDLE dh, PCPS_IRQ_STAT_INFO *p ) ;
+
+ /**
+ Read the CPU affinity of a process, i.e. on which of the available
+ CPUs the process can be executed.
+
+ @param pid The process ID.
+ @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_set_process_affinity()
+ @see mbg_set_current_process_affinity_to_cpu()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_process_affinity( MBG_PROCESS_ID pid, MBG_CPU_SET *p ) ;
+
+ /**
+ Set the CPU affinity of a process, i.e. on which of the available
+ CPUs the process is allowed to be executed.
+
+ @param pid The process ID.
+ @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_get_process_affinity()
+ @see mbg_set_current_process_affinity_to_cpu()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_process_affinity( MBG_PROCESS_ID pid, MBG_CPU_SET *p ) ;
+
+ /**
+ Set the CPU affinity of a process for a single CPU only, i.e. the process
+ may only be executed on that single CPU.
+
+ @param pid The process ID.
+ @param cpu_num The number of the CPU.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_get_process_affinity()
+ @see mbg_set_process_affinity()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_current_process_affinity_to_cpu( int cpu_num ) ;
+
+ /**
+ Create a new execution thread for the current process.
+ This function is only implemented for targets which support threads.
+
+ @param p_ti Pointer to a ::MBG_THREAD_INFO structure to be filled up.
+ @param fnc The name of the thread function to be started.
+ @param arg A generic argument passed to the thread function.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_thread_stop()
+ @see mbg_thread_sleep_interruptible()
+ @see mbg_thread_set_affinity()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_thread_create( MBG_THREAD_INFO *p_ti, MBG_THREAD_FNC_RET_VAL (MBG_THREAD_FNC_ATTR *fnc)(void *), void *arg ) ;
+
+ /**
+ Stop a thread which has been created by mbg_thread_create(). Wait
+ until the thread has finished and release all resources.
+ This function is only implemented for targets which support threads.
+
+ @param p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_thread_create()
+ @see mbg_thread_sleep_interruptible()
+ @see mbg_thread_set_affinity()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_thread_stop( MBG_THREAD_INFO *p_ti ) ;
+
+ /**
+ Let the current thread sleep for a certain interval unless a signal is
+ received indicating the thread should terminate.
+ This function is only implemented for targets which support threads.
+
+ @param p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ @param sleep_ms The number of milliseconds to sleep
+ @return 0 if the sleep interval has expired normally
+ 1 if a signal to terminate has been received
+ <0 if an error has occurred
+
+ @see mbg_thread_create()
+ @see mbg_thread_stop()
+ @see mbg_thread_set_affinity()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_thread_sleep_interruptible( MBG_THREAD_INFO *p_ti, ulong sleep_ms ) ;
+
+ /**
+ Set the CPU affinity of a single thread, i.e. on which of the available
+ CPUs the thread is allowed to be executed.
+ This function is only implemented for targets which support thread affinity.
+
+ @param p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+
+ @return ::MBG_SUCCESS or error code returned by the system call.
+
+ @see mbg_thread_create()
+ @see mbg_thread_stop()
+ @see mbg_thread_sleep_interruptible()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_thread_set_affinity( MBG_THREAD_INFO *p_ti, MBG_CPU_SET *p ) ;
+
+ /**
+ Set up a ::MBG_POLL_THREAD_INFO structure and start a new thread
+ which runs the mbg_xhrt_poll_thread_fnc() function.
+ This function is only implemented for targets which support threads.
+
+ @param *p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ @param dh the handle of the device to be polled.
+ @param freq_hz The initial cycles frequency, if known, in Hz.
+ @param sleep_ms the sleep interval for the poll thread function in ms.
+ If this parameter is 0 then the default sleep interval is used.
+
+ @return ::MBG_SUCCESS on success,
+ ::MBG_ERR_NOT_SUPP_BY_DEV if the device to poll does not support HR time
+ else the result of mbg_thread_create()
+
+ @see mbg_xhrt_poll_thread_fnc()
+ @see mbg_xhrt_poll_thread_stop()
+ @see mbg_get_xhrt_time_as_pcps_hr_time()
+ @see mbg_get_xhrt_time_as_filetime()
+ @see mbg_get_xhrt_cycles_frequency()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_create( MBG_POLL_THREAD_INFO *p_pti, MBG_DEV_HANDLE dh, MBG_PC_CYCLES_FREQUENCY freq_hz, int sleep_ms ) ;
+
+ /**
+ Stop a polling thread started by mbg_xhrt_poll_thread_create()
+ and release all associated resources.
+
+ @param *p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+
+ @return the result of mbg_thread_stop()
+
+ @see mbg_xhrt_poll_thread_fnc()
+ @see mbg_xhrt_poll_thread_create()
+ @see mbg_get_xhrt_time_as_pcps_hr_time()
+ @see mbg_get_xhrt_time_as_filetime()
+ @see mbg_get_xhrt_cycles_frequency()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_stop( MBG_POLL_THREAD_INFO *p_pti ) ;
+
+ /**
+ Retrieve a time stamp in PCPS_HR_TIME format which is extrapolated
+ using the system's current cycles counter value and a time stamp
+ plus associated cycles counter value saved by the polling thread.
+ See mbg_xhrt_poll_thread_fnc() for details and limitations.
+ This function is only implemented for targets which support threads.
+
+ @param *p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ @param *p_hrt Pointer to a ::PCPS_HR_TIME structure to be filled up.
+
+ @return MBG_SUCCESS or another return value from the polling thread's IOCTL call.
+
+ @see mbg_xhrt_poll_thread_fnc()
+ @see mbg_xhrt_poll_thread_create()
+ @see mbg_xhrt_poll_thread_stop()
+ @see mbg_get_xhrt_time_as_filetime()
+ @see mbg_get_xhrt_cycles_frequency()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_pcps_hr_time( MBG_XHRT_INFO *p, PCPS_HR_TIME *p_hrt ) ;
+
+ /**
+ Retrieve a time stamp in FILETIME format which is extrapolated
+ using the system's current cycles counter value and a time stamp
+ plus associated cycles counter value saved by the polling thread.
+ See mbg_xhrt_poll_thread_fnc() for details and limitations.
+ Since FILETIME is a Windows specific type this function is only
+ implemented under Windows.
+
+ @param *p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ @param *p_ft Pointer to a ::FILETIME structure to be filled up.
+
+ @return MBG_SUCCESS or another return value from the polling thread's IOCTL call.
+
+ @see mbg_xhrt_poll_thread_fnc()
+ @see mbg_xhrt_poll_thread_create()
+ @see mbg_xhrt_poll_thread_stop()
+ @see mbg_get_xhrt_time_as_pcps_hr_time()
+ @see mbg_get_xhrt_cycles_frequency()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_filetime( MBG_XHRT_INFO *p, FILETIME *p_ft ) ;
+
+ /**
+ Retrieve the frequency of the system's cycles counter as determined
+ by the device polling thread.
+ See mbg_xhrt_poll_thread_fnc() for details and limitations.
+ This function is only implemented for targets which support threads.
+
+ @param *p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ @param *p_freq_hz Pointer to a ::MBG_PC_CYCLES_FREQUENCY variable in which the frequency is returned.
+ @return a status code from the polling thread: MBG_SUCCESS or an IOCTL error code.
+
+ @see mbg_xhrt_poll_thread_fnc()
+ @see mbg_xhrt_poll_thread_create()
+ @see mbg_xhrt_poll_thread_stop()
+ @see mbg_get_xhrt_time_as_pcps_hr_time()
+ @see mbg_get_xhrt_time_as_filetime()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_cycles_frequency( MBG_XHRT_INFO *p, MBG_PC_CYCLES_FREQUENCY *p_freq_hz ) ;
+
+ /**
+ Retrieve the default system's cycles counter frequency from the kernel driver.
+
+ @param dh handle of the device to which the IOCTL call is sent.
+ @param *p Pointer of a ::MBG_PC_CYCLES_FREQUENCY variable to be filled up.
+
+ @return ::MBG_SUCCESS or error code returned by device I/O control function.
+
+ @see mbg_get_default_cycles_frequency()
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_default_cycles_frequency_from_dev( MBG_DEV_HANDLE dh, MBG_PC_CYCLES_FREQUENCY *p ) ;
+
+ /**
+ Retrieve the default system's cycles counter frequency.
+ This may not be supported on all taget platforms, in which case the
+ returned frequency is 0 and the mbg_get_default_cycles_frequency_from_dev()
+ call should be used.
+
+ @param dh handle of the device to which the IOCTL call is sent.
+ @param *p Pointer of a ::MBG_PC_CYCLES_FREQUENCY variable to be filled up.
+
+ @return the default cycles counter frequency in Hz, or 0 if the value is not available.
+
+ @see mbg_get_default_cycles_frequency()
+ */
+ _MBG_API_ATTR MBG_PC_CYCLES_FREQUENCY _MBG_API mbg_get_default_cycles_frequency( void ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#if defined( MBG_TGT_LINUX ) && defined( MBG_ARCH_I386 )
+
+ static __mbg_inline unsigned long long int mbg_rdtscll( void )
+ {
+ // The code below is a hack to get around issues with
+ // different versions of gcc.
+ //
+ // Normally the inline asm code could look similar to:
+ //
+ // __asm__ volatile ( "rdtsc" : "=A" (x) )
+ //
+ // which would copy the output regs edx:eax as a 64 bit
+ // number to a variable x.
+ //
+ // The "=A" expression should implicitely tell the compiler
+ // the edx and eax registers have been clobbered. However,
+ // this does not seem to work properly at least with gcc 4.1.2
+ // shipped with Centos 5.
+ //
+ // If optimization level 1 or higher is used then function
+ // parameters are also passed in registers. If the inline
+ // code above is used inside a function then the edx register
+ // is clobbered but the gcc 4.1.2 is not aware of this and
+ // assumes edx is unchanged, which may yield faulty results
+ // or even lead to segmentation faults.
+ //
+ // A possible workaround could be to mark edx explicitely as
+ // being clobbered in the asm inline code, but unfortunately
+ // other gcc versions report an error if a register which is
+ // implicitely (by "=A") known to be clobbered is also listed
+ // explicitely to be clobbered.
+ //
+ // So the code below is a workaround which tells the compiler
+ // implicitely that the eax ("=a") and edx ("=d") registers
+ // are being used and thus clobbered.
+
+ union
+ {
+ struct
+ {
+ uint32_t lo;
+ uint32_t hi;
+ } u32;
+
+ uint64_t u64;
+
+ } tsc_val;
+
+ __asm__ __volatile__( "rdtsc" : "=a" (tsc_val.u32.lo), "=d" (tsc_val.u32.hi) );
+
+ return tsc_val.u64;
+
+ }
+
+#endif
+
+
+
+static __mbg_inline
+void mbg_init_pc_cycles_frequency( MBG_DEV_HANDLE dh, MBG_PC_CYCLES_FREQUENCY *p )
+{
+ if ( *p == 0 )
+ mbg_get_default_cycles_frequency_from_dev( dh, p );
+
+} // mbg_init_pc_cycles_frequency
+
+
+
+static __mbg_inline
+void mbg_get_pc_cycles( MBG_PC_CYCLES *p )
+{
+ #if defined( MBG_TGT_WIN32 )
+ QueryPerformanceCounter( (LARGE_INTEGER *) p );
+ #elif defined( MBG_TGT_LINUX ) && defined( MBG_ARCH_I386 )
+ *p = mbg_rdtscll();
+ #else
+ *p = 0;
+ #endif
+} // mbg_get_pc_cycles
+
+
+
+static __mbg_inline
+MBG_PC_CYCLES mbg_delta_pc_cycles( const MBG_PC_CYCLES *p1, const MBG_PC_CYCLES *p2 )
+{
+ return *p1 - *p2;
+
+} // mbg_delta_pc_cycles
+
+
+
+#if MBG_TGT_HAS_64BIT_TYPES
+
+static __mbg_inline
+uint64_t pcps_time_stamp_to_uint64( const PCPS_TIME_STAMP *ts )
+{
+ return ( ( (uint64_t) ts->sec ) << 32 ) + ts->frac;
+
+} // pcps_time_stamp_to_uint64
+
+
+
+static __mbg_inline
+void uint64_to_pcps_time_stamp( PCPS_TIME_STAMP *ts, uint64_t n )
+{
+ ts->sec = (uint32_t) ( n >> 32 );
+ ts->frac = (uint32_t) ( n & 0xFFFFFFFFUL );
+
+} // uint64_to_pcps_time_stamp
+
+#endif
+
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+
+#endif /* _MBGDEVIO_H */
+
diff --git a/c/mbglib/include/mbgerror.h b/c/mbglib/include/mbgerror.h
new file mode 100644
index 0000000..f51636c
--- /dev/null
+++ b/c/mbglib/include/mbgerror.h
@@ -0,0 +1,156 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgerror.h 1.4 2008/12/05 13:28:50Z martin REL_M $
+ * $Name: $
+ *
+ * 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.4 2008/12/05 13:28:50Z 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 */
+
+/**
+ @defgroup group_error_codes Error codes
+
+ Error codes used with Meinberg devices and drivers.
+ The codes will be translated into an OS dependent error code,
+ when they are 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.
+
+ @{
+*/
+
+// Attention!!
+// These error codes below must fit exactly to the corresponding codes that are evaluated in user space.
+// For Windows, they are located in messages.mc/.h in mbgsvctl.dll
+
+#define MBG_SUCCESS PCPS_SUCCESS /**< 0, no error */
+
+// The codes below are defined in pcpsdefs.h and returned by the firmware:
+#define MBG_ERR_STIME PCPS_ERR_STIME /**< -1, invalid date/time/status passed */
+#define MBG_ERR_CFG PCPS_ERR_CFG /**< -2, invalid parms with a PCPS_CFG_GROUP cmd */
+
+// Codes returned by the driver's low level functions:
+#define MBG_ERR_GENERIC -19 /**< Generic error */
+#define MBG_ERR_TIMEOUT -20 /**< Timeout accessing the board */
+#define MBG_ERR_FW_ID -21 /**< Invalid firmware ID */
+#define MBG_ERR_NBYTES -22 /**< The number of parameter bytes
+ passed to the board did not match
+ the number of bytes expected. */
+#define MBG_ERR_INV_TIME -23 /**< The device's time is not valid */
+#define MBG_ERR_FIFO -24 /**< The device's FIFO is empty, though
+ it shouldn't be */
+#define MBG_ERR_NOT_READY -25 /**< Board is temporary unable to respond
+ (during initialization after RESET) */
+#define MBG_ERR_INV_TYPE -26 /**< Board did not recognize data type */
+
+
+// Codes returned by the driver's high level 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 /**< The function is not supported on this operating system */
+#define MBG_ERR_LIB_NOT_COMPATIBLE -35 /**< The installed version of the DLL/shared object is not
+ compatible with version used to build the application */
+#define MBG_ERR_N_COM_EXCEEDS_SUPP -36 /**< The number of COM ports provided by the device
+ exceeds the maximum supported by the driver */
+#define MBG_ERR_N_STR_EXCEEDS_SUPP -37 /**< The number of string formats supported by the device
+ exceeds the maximum supported by the driver */
+#define MBG_ERR_IRQ_UNSAFE -38 /**< The enabled IRQs are unsafe with this firmware/ASIC version */
+
+
+// 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 */
+
+/** @} */ // endgroup
+
+// 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. */
+
+/* (no header definitions found) */
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGERROR_H */
diff --git a/c/mbglib/include/mbggeo.h b/c/mbglib/include/mbggeo.h
new file mode 100644
index 0000000..ca6414d
--- /dev/null
+++ b/c/mbglib/include/mbggeo.h
@@ -0,0 +1,297 @@
+
+/**************************************************************************
+ *
+ * $Id: mbggeo.h 1.10 2008/09/03 14:54:28Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for mbggeo.c.
+ *
+ * Terms used:
+ *
+ * WGS84 world geodetic system of 1984
+ *
+ * XYZ WGS84 earth centered, earth fixed (ECEF) kartesian
+ * coordinates
+ *
+ * LLA longitude, latitude, altitude depending on the reference
+ * ellipsoid used.
+ *
+ * DMS degrees, minutes, seconds
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbggeo.h $
+ * Revision 1.10 2008/09/03 14:54:28Z martin
+ * Added macros to swap endianess of structures.
+ * Revision 1.9 2008/01/17 09:31:33 daniel
+ * Made comments compatible for doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.8 2004/11/09 14:16:00Z martin
+ * Redefined interface data types using C99 fixed-size definitions.
+ * Revision 1.7 2003/02/14 13:23:04Z martin
+ * Omit inclusion of mystd.h.
+ * Revision 1.6 2003/01/13 15:17:15 martin
+ * Structures were defined with default alignment which
+ * could result in different data sizes on different platforms.
+ * Revision 1.5 2002/12/18 14:46:41Z martin
+ * Removed variable USER_POS meinberg.
+ * Updated function prototypes.
+ * Revision 1.4 2002/12/12 12:04:25Z martin
+ * Moved some definitions here.
+ * Use standard file format.
+ *
+ **************************************************************************/
+
+#ifndef _MBGGEO_H
+#define _MBGGEO_H
+
+
+/* Other headers to be included */
+
+#include <gpsdefs.h>
+#include <use_pack.h>
+
+#ifdef _MBGGEO
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+/**
+ Geographic longitude or latitude in [degrees, minutes, seconds]
+ longitude East latitude North and positve, South or West angles negative
+ */
+typedef struct
+{
+ uint16_t prefix; /**< 'N', 'E', 'S' or 'W' */
+ uint16_t deg; /**< [0...90 (lat) or 0...180 (lon)] */
+ uint16_t min; /**< [0...59] */
+ double sec; /**< [0...59.999] */
+} DMS;
+
+// The corresponding macro _mbg_swab_dms() is defined in gpsdefs.h.
+#define _mbg_swab_dms( _p ) \
+{ \
+ _mbg_swab16( &(_p)->prefix ); \
+ _mbg_swab16( &(_p)->deg ); \
+ _mbg_swab16( &(_p)->min ); \
+ _mbg_swab_double( &(_p)->sec ); \
+}
+
+
+
+typedef struct
+{
+ XYZ xyz; /**< always WGS84 ECEF coordinates */
+ LLA lla; /**< depending on the ellipsoid used for reference */
+ DMS longitude; /**< longitude in degrees, minutes, seconds */
+ DMS latitude; /**< latitude in degrees, minutes, seconds */
+ int16_t ellipsoid; /**< ellipsoid used for reference */
+} POS;
+
+#define _mbg_swab_pos( _p ) \
+{ \
+ _mbg_swab_xyz( (_p)->xyz ); \
+ _mbg_swab_lla( (_p)->lla ); \
+ _mbg_swab_dms( &(_p)->longitude ); \
+ _mbg_swab_dms( &(_p)->latitude ); \
+ _mbg_swab16( &(_p)->ellipsoid ); \
+}
+
+
+
+typedef struct
+{
+ CSUM csum; /* checksum of the remaining bytes */
+ int16_t valid; /* flag data are valid */
+
+ char name[40];
+ POS pos; /* the position in WGS84 ECEF coords and LLA */
+ double det;
+
+
+/* The components below hold the results of intermediate terms */
+/* computed in complete_user_pos(). */
+
+/* The sin.., cos.., nt.. and ut.. variables are used to compute the */
+/* enu_dcos[] parameters of a SV structure in xyz_to_ead(). */
+
+/* The e_radius.. variables are used to compute the latitude, longitude */
+/* and altitude from ECEF coordinates in lla_to_xyz(). */
+
+ double sin_lat; /* sin( latitude ) */
+ double cos_lat; /* cos( latitude ) */
+ double sin_lon; /* sin( longitude ) */
+ double cos_lon; /* cos( longitude ) */
+
+ double nt1; /* -sin_lat * cos_lon */
+ double nt2; /* -sin_lat * sin_lon */
+ double utx; /* cos_lat * cos_lon */
+ double uty; /* cos_lat * sin_lon */
+
+ double e_radius; /* N */
+ double e_radius_alt; /* N + h */
+
+} USER_POS;
+
+
+
+typedef struct
+{
+ CSUM csum; /* checksum of the remaining bytes */
+ int16_t valid; /* flag data are valid */
+
+ char name[40];
+ XYZ dxyz; /* offset from the WGS84 ECEF coords */
+ double a; /* semi major axis */
+ double rcp_f; /* reciproke of flatness */
+
+/* the variables below will be computed in the init_mbggeo() function: */
+
+ double f; /* flatness */
+ double b; /* semi minor axis */
+ double sqr_e; /* square of numerical eccentricity */
+} ELLIPSOID;
+
+
+
+enum { WGS84, BESSEL, N_ELLIPSOIDS };
+
+_ext ELLIPSOID ellipsoid[N_ELLIPSOIDS]
+#ifdef _DO_INIT
+ = { { 0, 0,
+ "WGS 84",
+ { 0.0, 0.0, 0.0 },
+ 6378137.0,
+ 298.257223563
+ },
+
+ { 0, 0,
+ "Bessel",
+ { -128.0, 481.0, 664.0 },
+ 6377397.0,
+ 299.15
+ }
+
+ }
+#endif
+;
+
+
+/* WGS84 constants used */
+
+_ext double OMEGADOTe /* earth's rotation rate [rad/sec] */
+#ifdef _DO_INIT
+ = 7.2921151467e-5
+#endif
+;
+
+_ext double mue /* earth's gravitational constant [m^3/sec^2] */
+#ifdef _DO_INIT
+ = 3.986005e14
+#endif
+;
+
+
+
+_ext double vr_to_doppler;
+
+
+_ext double gps_pi
+#ifdef _DO_INIT
+ = 3.1415926535898
+#endif
+;
+
+_ext double gps_c0
+#ifdef _DO_INIT
+ = 2.99792458e8
+#endif
+;
+
+
+#ifndef PI
+ #define PI 3.1415926535897932
+#endif
+
+
+_ext double pi
+#ifdef _DO_INIT
+ = PI
+#endif
+;
+
+
+_ext double r2d
+#ifdef _DO_INIT
+ = 180.0 / PI
+#endif
+;
+
+
+_ext double d2r
+#ifdef _DO_INIT
+ = PI / 180.0
+#endif
+;
+
+
+/* variables for simplifying computations */
+
+_ext double gps_two_pi;
+_ext double sqrt_mue; /* sqrt( mue ) */
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ void dms_to_rad( const DMS *dms, double *rad ) ;
+ void rad_to_dms( const double *rad, DMS *dms, const char prefix ) ;
+ void dms_to_lla( POS *pos ) ;
+ void lla_to_dms( POS *pos ) ;
+ void lla_to_xyz( USER_POS *pos ) ;
+ void xyz_to_lla( POS *pos, void (*cyclic_func)( void ) ) ;
+ void dms_to_xyz( USER_POS *pos ) ;
+ void setup_user_pos_from_dms( USER_POS *user ) ;
+ void setup_user_pos_from_lla( USER_POS *user ) ;
+ void setup_user_pos_from_xyz( USER_POS *user, void (*cyclic_func)( void ) ) ;
+ double distance( XYZ xyz_1, XYZ xyz_2 ) ;
+ void init_mbggeo( void ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGGEO_H */
+
diff --git a/c/mbglib/include/mbgutil.h b/c/mbglib/include/mbgutil.h
new file mode 100644
index 0000000..b821f1b
--- /dev/null
+++ b/c/mbglib/include/mbgutil.h
@@ -0,0 +1,174 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgutil.h 1.13 2009/01/12 09:35:41Z daniel REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions used with mbgutil.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgutil.h $
+ * Revision 1.13 2009/01/12 09:35:41Z daniel
+ * New version code 303, compatibility version still 110.
+ * Updated function prototypes.
+ * Revision 1.12 2008/01/17 10:15:26Z daniel
+ * New version code 302, compatibility version still 110.
+ * Revision 1.11 2007/10/16 10:01:17Z daniel
+ * New version code 301, compatibility version still 110.
+ * Revision 1.9 2007/03/21 16:48:31Z martin
+ * New version code 219, compatibility version still 110.
+ * Revision 1.8 2006/08/09 13:18:18Z martin
+ * New version code 218, compatibility version still 110.
+ * Revision 1.7 2006/06/08 10:48:52Z martin
+ * New version code 217, compatibility version still 110.
+ * Added macro _mbg_strncpy().
+ * Revision 1.6 2006/05/10 10:56:54Z martin
+ * Updated function prototypes.
+ * Revision 1.5 2006/05/02 13:24:49Z martin
+ * New version code 216, compatibility version still 110.
+ * Revision 1.4 2006/01/11 12:24:05Z martin
+ * New version code 215, compatibility version still 110.
+ * Revision 1.3 2005/12/15 10:01:51Z martin
+ * New version 214, compatibility version still 110.
+ * Revision 1.2 2005/02/18 15:13:42Z martin
+ * Updated function prototypes.
+ * Revision 1.1 2005/02/18 10:39:49Z martin
+ * Initial revision
+ *
+ **************************************************************************/
+
+#ifndef _MBGUTIL_H
+#define _MBGUTIL_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+#include <use_pack.h>
+#include <pcpsdefs.h>
+#include <mbggeo.h>
+#include <pci_asic.h>
+
+
+#define MBGUTIL_VERSION 0x0303
+
+#define MBGUTIL_COMPAT_VERSION 0x0110
+
+
+#if defined( MBG_TGT_WIN32 )
+
+ #include <windows.h>
+
+#elif defined( MBG_TGT_LINUX )
+
+
+#elif defined( MBG_TGT_OS2 )
+
+
+#elif defined( MBG_TGT_DOS )
+
+ #if !defined( MBG_USE_DOS_TSR )
+ #endif
+
+#else
+
+#endif
+
+#ifdef _MBGUTIL
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+#if defined( MBG_TGT_WIN32 )
+
+#elif defined( MBG_TGT_LINUX )
+
+#elif defined( MBG_TGT_OS2 )
+
+#else
+
+#endif
+
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The macro below can be used to simplify the API call if
+// a string variable is used rather than a char *.
+#define _mbg_strncpy( _s, _src ) \
+ mbg_strncpy( _s, sizeof( _s ), _src )
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ _MBG_API_ATTR int _MBG_API mbgutil_get_version( void ) ;
+ _MBG_API_ATTR int _MBG_API mbgutil_check_version( int header_version ) ;
+ _MBG_API_ATTR int _MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... ) ;
+ _MBG_API_ATTR int _MBG_API mbg_strncpy( char *s, size_t max_len, const char *src ) ;
+ _MBG_API_ATTR int _MBG_API mbg_strchar( char *s, size_t max_len, char c, size_t n ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len, int mday, int month ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len, int mday, int month, int year ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len, int hour, int min ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_time( char *s, int max_len, int hour, int min, int sec ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_time_long( char *s, int max_len, int hour, int min, int sec, int sec100 ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_tm_gps_date_time( char *s, int max_len, const TM_GPS *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len, const PCPS_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len, const PCPS_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_time_short( char *s, int max_len, const PCPS_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_time( char *s, int max_len, const PCPS_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_time_long( char *s, int max_len, const PCPS_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len, const PCPS_TIME *pt, const char *tz_str ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len, uint32_t sec ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len, uint32_t sec ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len, uint32_t frac ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_offs( char *s, int max_len, const PCPS_HR_TIME *pt, const char *info ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len, const PCPS_TIME_STAMP *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len, const DMS *pdms, int prec ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pos_alt( char *s, int max_len, double alt ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len, const POS *ppos, int prec ) ;
+ _MBG_API_ATTR int _MBG_API mbg_str_dev_name( char *s, int max_len, const char *short_name, uint16_t fw_rev_num, PCI_ASIC_VERSION asic_version_num ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGUTIL_H */
+
diff --git a/c/mbglib/include/pci_asic.h b/c/mbglib/include/pci_asic.h
new file mode 100644
index 0000000..b7bf3a7
--- /dev/null
+++ b/c/mbglib/include/pci_asic.h
@@ -0,0 +1,322 @@
+
+/**************************************************************************
+ *
+ * $Id: pci_asic.h 1.13 2008/12/05 12:28:18Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions for the Meinberg PCI interface ASIC.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: pci_asic.h $
+ * Revision 1.13 2008/12/05 12:28:18Z martin
+ * Modified syntax of macro _convert_asic_version_number().
+ * Added macros to deal with the ASIC version number.
+ * Added definition PCI_ASIC_HAS_PGMB_IRQ.
+ * Added ASIC revision numbers for PEX511, TCR511PEX, and GPS170PEX
+ * which fix an IRQ bug with these cards.
+ * Added definitions for PTP270PEX, FRC511PEX, and TCR170PEX.
+ * Revision 1.12 2008/07/21 10:30:00Z martin
+ * Added macros to convert the endianess of data types.
+ * Added PCI_ASIC_CURRENT_MINOR_... symbols.
+ * Revision 1.11 2008/06/11 09:49:43 martin
+ * Added definitions and comments how to handle version numbers
+ * of the PCI and PEX interface chips and EPLDs.
+ * Revision 1.10 2008/02/29 15:21:48Z martin
+ * Added definition PCI_ASIC_HAS_MM_IO.
+ * Revision 1.9 2008/01/17 09:51:05 daniel
+ * Added macro _convert_asic_version_number().
+ * Cleanup for PCI ASIC version and features.
+ * Revision 1.8 2006/06/14 12:59:12Z martin
+ * Added support for TCR511PCI.
+ * Revision 1.7 2006/03/10 10:47:03 martin
+ * Added support for PCI511.
+ * Revision 1.6 2005/11/03 15:30:44Z martin
+ * Added support for GPS170PCI.
+ * Revision 1.5 2004/11/09 12:51:56Z martin
+ * Redefined fixed width data types using standard C99 types.
+ * Defined some constants unsigned.
+ * Revision 1.4 2004/10/14 15:01:23 martin
+ * Added support for TCR167PCI.
+ * Revision 1.3 2003/05/13 14:38:55Z MARTIN
+ * Added ushort fields to unions PCI_ASIC_REG and
+ * PCI_ASIC_ADDON_DATA.
+ * Revision 1.2 2003/04/03 10:56:38 martin
+ * Use unions for registers.
+ * Modified BADR0 initializer due to fixed size of address decoder.
+ * Revision 1.1 2003/02/07 11:42:52 MARTIN
+ * Initial revision
+ *
+ **************************************************************************/
+
+#ifndef _PCI_ASIC_H
+#define _PCI_ASIC_H
+
+
+/* Other headers to be included */
+
+#include <words.h>
+#include <use_pack.h>
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+#ifdef _PCI_ASIC
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+
+typedef struct
+{
+ uint32_t cfg_class_rev_id;
+ uint16_t cfg_badr_0;
+ uint16_t cfg_dev_id;
+} PCI_ASIC_CFG;
+
+
+typedef union
+{
+ uint32_t ul;
+ uint16_t us[2];
+ uint8_t b[4];
+} PCI_ASIC_REG;
+
+
+typedef uint32_t PCI_ASIC_VERSION;
+#define _mbg_swab_asic_version( _p ) _mbg_swab32( _p )
+
+typedef uint32_t PCI_ASIC_FEATURES;
+#define _mbg_swab_asic_features( _p ) _mbg_swab32( _p )
+
+#define PCI_ASIC_HAS_MM_IO 0x0001
+#define PCI_ASIC_HAS_PGMB_IRQ 0x0002
+
+
+typedef union
+{
+ uint32_t ul[4];
+ uint16_t us[8];
+ uint8_t b[16];
+} PCI_ASIC_ADDON_DATA;
+
+
+typedef struct
+{
+ PCI_ASIC_CFG cfg; // writeable from add-on once after power-up
+ PCI_ASIC_VERSION raw_version;
+ PCI_ASIC_FEATURES features;
+ PCI_ASIC_REG status_port;
+ PCI_ASIC_REG control_status; // codes defined below
+ PCI_ASIC_REG pci_data; // pass byte from PCI bus to add-on
+ PCI_ASIC_REG reserved_1;
+
+ PCI_ASIC_ADDON_DATA addon_data; // returns data from add-on to PCI bus
+ PCI_ASIC_ADDON_DATA reserved_2; // currently not implemented
+} PCI_ASIC;
+
+
+// The following bits are used with the control_status register.
+// All other bits are reserved for future use.
+
+// The IRQ flag for the add-on side is set whenever data is
+// written to the cmd register. It is cleared if the add-on
+// microcontroller writes this bit back to the control_status
+// register. If the bit is set, the add-on signals /ADD_ON_IRQ
+// and ADD_ON_BUSY are asserted.
+#define PCI_ASIC_ADD_ON_IRQF 0x00000001UL
+
+// The IRQ flag for the PCI bus is set whenever the add-on
+// microcontroller asserts the ASIC's /PCI_IRQ line, or the
+// add-on microcontroller sets this bit to 1. It is cleared
+// if this bit is written back from the PCI side. If the bit
+// is set, an IRQ is asserted on the PCI bus.
+#define PCI_ASIC_PCI_IRQF 0x00010000UL
+
+
+// The ASIC's address decoder always decodes 8 bits, so
+// each device must request at least that number of
+// addresses from the PCI BIOS:
+#define PCI_ASIC_ADDR_RANGE 0x100U
+
+
+// Initializers for device configurations
+
+#define PCPS_DEV_CLASS_CODE 0x08800000UL
+#define PCI_ASIC_BADR0_INIT ( ~( PCI_ASIC_ADDR_RANGE - 1 ) | 0x01 )
+
+
+#define PCI_ASIC_CFG_PCI510 \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_PCI510 ) \
+}
+
+#define PCI_ASIC_CFG_GPS169PCI \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_GPS169PCI ) \
+}
+
+#define PCI_ASIC_CFG_TCR510PCI \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_TCR510PCI ) \
+}
+
+#define PCI_ASIC_CFG_TCR167PCI \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_TCR167PCI ) \
+}
+
+#define PCI_ASIC_CFG_GPS170PCI \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_GPS170PCI ) \
+}
+
+#define PCI_ASIC_CFG_PCI511 \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_PCI511 ) \
+}
+
+#define PCI_ASIC_CFG_TCR511PCI \
+{ \
+ _hilo_32( PCPS_DEV_CLASS_CODE ), \
+ _hilo_16( PCI_ASIC_BADR0_INIT ), \
+ _hilo_16( PCI_DEV_TCR511PCI ) \
+}
+
+/*
+ Handling of the version numbers of the PCI interface
+ chips has changed between the ASICs used for standard PCI
+ and the EPLDs used to configure the PEX8311 chip
+ for a specific device.
+
+ The macro below can be used to convert both types
+ of version number into the same format so that the
+ version numbers can be handled in the same way:
+*/
+#define _convert_asic_version_number( _n ) \
+ ( ( (_n) < 0x100 ) ? ( (_n) << 8 ) : (_n) )
+
+
+
+/*
+ * Macros to extract the major and minor part of an ASIC version number */
+
+#define _pcps_asic_version_major( _v ) \
+ ( ( (_v) >> 8 ) & 0xFF )
+
+#define _pcps_asic_version_minor( _v ) \
+ ( (_v) & 0xFF )
+
+
+/*
+ * Macros to check whether a version number is correct
+ * and matches a required minimum version
+ */
+#define _pcps_asic_version_greater_equal( _v, _v_major, _v_minor ) \
+ ( \
+ ( _pcps_asic_version_major( _v ) == (_v_major) ) && \
+ ( _pcps_asic_version_minor( _v ) >= (_v_minor) ) \
+ )
+
+
+/*
+ The low byte of the converted version number is handled
+ as a minor version, whereas the remaining upper bytes are
+ interpreted as a major number which may be specific
+ for a device.
+*/
+enum
+{
+ PCI_ASIC_MAJOR_PCI_0, // PCI ASIC with CRC bug
+ PCI_ASIC_MAJOR_PCI_1, // fixed version of PCI ASIC
+ PCI_ASIC_MAJOR_PEX511, // PEX EPLD for PEX_511
+ PCI_ASIC_MAJOR_GPS170PEX, // PEX EPLD for GPS170PEX
+ PCI_ASIC_MAJOR_TCR511PEX, // PEX EPLD for TCR511PEX
+ PCI_ASIC_MAJOR_PTP270PEX, // PEX EPLD for PTP270PEX
+ PCI_ASIC_MAJOR_FRC511PEX, // PEX EPLD for FRC511PEX
+ PCI_ASIC_MAJOR_TCR170PEX, // PEX EPLD for TCR170PEX
+ N_PCI_ASIC_MAJOR // the number of known codes
+};
+
+/*
+ The minor number increases when a new EPLD image is released.
+ At least EPLD images with the following "required minor" numbers
+ should be installed for proper operation. The "current minor"
+ numbers can be used to check if a newer EPLD image is available:
+*/
+#define PCI_ASIC_CURRENT_MINOR_PEX511 0x04
+#define PCI_ASIC_REQUIRED_MINOR_PEX511 0x03
+#define PCI_ASIC_HRT_FIX_MINOR_PEX511 0x04 // increases HRT accuracy
+#define PCI_ASIC_IRQ_FIX_MINOR_PEX511 0x03 // fixes IRQ problem
+#define PCI_ASIC_HR_TIME_MINOR_PEX511 0x02 // supports HR time with PEX511
+
+#define PCI_ASIC_CURRENT_MINOR_GPS170PEX 0x04
+#define PCI_ASIC_REQUIRED_MINOR_GPS170PEX 0x03
+#define PCI_ASIC_HRT_FIX_MINOR_PEX511 0x04 // increases MM HRT accuracy
+#define PCI_ASIC_IRQ_FIX_MINOR_GPS170PEX 0x03 // fixes IRQ problem
+
+#define PCI_ASIC_CURRENT_MINOR_TCR511PEX 0x03
+#define PCI_ASIC_REQUIRED_MINOR_TCR511PEX 0x03
+#define PCI_ASIC_IRQ_FIX_MINOR_TCR511PEX 0x03 // fixes IRQ problem, increases HRT accuracy
+
+#define PCI_ASIC_CURRENT_MINOR_PTP270PEX 0x01
+#define PCI_ASIC_REQUIRED_MINOR_PTP270PEX 0x01
+
+#define PCI_ASIC_CURRENT_MINOR_FRC511PEX 0x01
+#define PCI_ASIC_REQUIRED_MINOR_FRC511PEX 0x01
+
+#define PCI_ASIC_CURRENT_MINOR_TCR170PEX 0x01
+#define PCI_ASIC_REQUIRED_MINOR_TCR170PEX 0x01
+
+
+/* function prototypes: */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+/* (no header definitions found) */
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _PCI_ASIC_H */
+
diff --git a/c/mbglib/include/pcpsdev.h b/c/mbglib/include/pcpsdev.h
new file mode 100644
index 0000000..b065d46
--- /dev/null
+++ b/c/mbglib/include/pcpsdev.h
@@ -0,0 +1,945 @@
+
+/**************************************************************************
+ *
+ * $Id: pcpsdev.h 1.39 2008/12/05 16:24:24Z martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions used to share information on radio clock devices
+ * between device drivers which have direct access to the hardware
+ * devices and user space programs which evaluate and present that
+ * information.
+ *
+ * At the bottom of the file there are some macros defined which
+ * should be used to access the structures to extract characteristics
+ * of an individual clock.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: pcpsdev.h $
+ * Revision 1.39 2008/12/05 16:24:24Z martin
+ * Changed MAX_PARM_STR_TYPE from 10 to 20.
+ * Added support for WWVB signal source.
+ * Support new devices PTP270PEX, FRC511PEX, TCR170PEX, and WWVB51USB.
+ * Added macros _pcps_is_ptp(), _pcps_is_frc(), and _pcps_is_wwvb().
+ * Defined firmware version numbers which fix an IRQ problem with PEX511,
+ * TCR511PEX, and GPS170PEX cards. The fix also requires specific ASIC
+ * versions specified in pci_asic.h.
+ * Defined firmware versions at which PCI511 and PEX511 start
+ * to support HR time.
+ * Support mapped I/O resources.
+ * Changed MBG_PC_CYCLES type for Windows to int64_t.
+ * Renamed MBG_VIRT_ADDR to MBG_MEM_ADDR.
+ * Added MBG_PC_CYCLES_FREQUENCY type.
+ * Added definition of PCPS_TIME_STAMP_CYCLES.
+ * Added PCPS_IRQ_STAT_INFO type and associated flags.
+ * Added macros to convert the endianess of structures.
+ * Added macros _pcps_fw_rev_num_major() and _pcps_fw_rev_num_minor().
+ * Made irq_num signed to use -1 for unassigned IRQ numbers.
+ * Revision 1.38 2008/01/17 10:12:34 daniel
+ * Added support for TCR51USB and MSF51USB.
+ * New type MBG_VIRT_ADDR to specify virtual address values.
+ * New struct PCPS_MAPPED_MEM
+ * Cleanup for PCI ASIC version and features.
+ * Added macros _pcps_is_msf(), _pcps_is_lwr(),
+ * _psps_has_asic_version(), _pcps_has_asic_features().
+ * Revision 1.37 2008/01/17 09:58:11Z daniel
+ * Made comments compatible for doxygen parser.
+ * No sourcecode changes.
+ * Revision 1.36 2007/09/26 09:34:38Z martin
+ * Added support for USB in general and new USB device USB5131.
+ * Added new types PCPS_DEV_ID and PCPS_REF_TYPE.
+ * Removed old PCPS_ERR_... codes. Use MBG_ERR_... codes
+ * from mbgerror.h instead. The old values haven't changed.
+ * Revision 1.35 2007/07/17 08:22:47Z martin
+ * Added support for TCR511PEX and GPS170PEX.
+ * Revision 1.34 2007/07/16 12:50:41Z martin
+ * Added support for PEX511.
+ * Modified/renamed some macros and symbols.
+ * Revision 1.33 2007/03/02 09:40:04Z martin
+ * Changes due to renamed library symbols.
+ * Removed obsolete inclusion of headers.
+ * Preliminary support for *BSD.
+ * Preliminary support for USB.
+ * Revision 1.32 2006/10/23 08:47:55Z martin
+ * Don't use abs() in _pcps_ref_offs_out_of_range() since this might
+ * not work properly for 16 bit integers and value 0x8000.
+ * Revision 1.31 2006/06/14 12:59:13Z martin
+ * Added support for TCR511PCI.
+ * Revision 1.30 2006/04/05 14:58:41 martin
+ * Support higher baud rates for PCI511.
+ * Revision 1.29 2006/04/03 07:29:07Z martin
+ * Added a note about the missing PCPS_ST_IRQF signal
+ * on PCI510 cards.
+ * Revision 1.28 2006/03/10 10:32:56Z martin
+ * Added support for PCI511.
+ * Added support for programmable pulse outputs.
+ * Revision 1.27 2005/11/04 08:48:00Z martin
+ * Added support for GPS170PCI.
+ * Revision 1.26 2005/06/02 08:34:38Z martin
+ * New types MBG_DBG_PORT, MBG_DBG_DATA.
+ * Revision 1.25 2005/05/03 10:04:14 martin
+ * Added macro _pcps_is_pci_amcc().
+ * Revision 1.24 2005/03/29 12:58:19Z martin
+ * Support GENERIC_IO feature.
+ * Revision 1.23 2004/12/09 11:03:37Z martin
+ * Support configuration of on-board frequency synthesizer.
+ * Revision 1.22 2004/11/09 12:57:52Z martin
+ * Redefined interface data types using C99 fixed-size definitions.
+ * Added support for TCR167PCI.
+ * New macro _pcps_has_gps_data().
+ * New type PCPS_STATUS_PORT.
+ * Removed obsolete inclusion of asm/timex.h for Linux.
+ * Revision 1.21 2004/09/06 15:19:49Z martin
+ * Support a GPS_DATA interface where sizes are specified
+ * by 16 instead of the original 8 bit quantities, thus allowing
+ * to transfer data blocks which exceed 255 bytes.
+ * Modified inclusion of header files under Linux.
+ * Modified definition of MBG_PC_CYCLES for Linux.
+ * Revision 1.20 2004/04/14 09:09:11 martin
+ * Source code cleanup.
+ * Revision 1.19 2004/04/07 09:49:14Z martin
+ * Support new feature PCPS_HAS_IRIG_TX.
+ * New macros _pcps_has_irig(), _pcps_has_irig_tx().
+ * Revision 1.18 2004/01/14 11:02:14Z MARTIN
+ * Added formal type MBG_PC_CYCLES for OS/2,
+ * though it's not really required or used.
+ * Revision 1.17 2003/12/22 15:40:16 martin
+ * Support higher baud rates for TCR510PCI and PCI510.
+ * Supports PCPS_HR_TIME for TCR510PCI.
+ * New structures used to read device time together with associated
+ * PC CPU cycles.
+ * For Win32, differentiate between kernel mode and non-kernel mode.
+ * Moved some definitions here from mbgdevio.h.
+ * New type PCPS_ASIC_VERSION.
+ * New macro _pcps_ref_offs_out_of_range().
+ * Revision 1.16 2003/06/19 09:48:30Z MARTIN
+ * Renamed symbols ..clr_cap_buffer to ..clr_ucap_buffer.
+ * New macro _pcps_has_ucap().
+ * New definitions to support cmds PCPS_GIVE_UCAP_ENTRIES
+ * and PCPS_GIVE_UCAP_EVENT.
+ * Revision 1.15 2003/04/15 09:57:25 martin
+ * New typedefs ALL_STR_TYPE_INFO, ALL_PORT_INFO,
+ * RECEIVER_PORT_CFG.
+ * Revision 1.14 2003/04/09 14:07:01Z martin
+ * Supports PCI510, GPS169PCI, and TCR510PCI,
+ * and new PCI_ASIC used by those devices.
+ * Renamed macro _pcps_is_irig() to _pcps_is_irig_rx().
+ * New macros _pcps_has_ref_offs(), _pcps_has_opt_flags().
+ * Fixed macro _pcps_has_hr_time().
+ * New type PCPS_BUS_FLAGS.
+ * Preliminary support for PCPS_TZDL.
+ * Revision 1.13 2002/08/09 07:19:49 MARTIN
+ * Moved definition of ref time sources to pcpsdefs.h.
+ * New feature PCPS_CAN_CLR_CAP_BUFF and
+ * associated macro _pcps_can_clr_cap_buff().
+ * New macros _pcps_is_irig(), _pcps_has_signal(),
+ * _pcps_has_mod().
+ * Revision 1.12 2002/02/19 09:22:53 MARTIN
+ * Added definitions for the maximum number of clocks' serial ports
+ * and string types that can be handled by the configuration programs.
+ * Revision 1.11 2002/02/01 11:36:58 MARTIN
+ * Added new definitions for GPS168PCI.
+ * Inserted definitions of firmware REV_NUMs for supported features
+ * which had previously been defined in pcpsdefs.h.
+ * Include use_pack.h.
+ * Updated comments.
+ * Source code cleanup.
+ * Revision 1.10 2001/11/30 09:52:48 martin
+ * Added support for event_time which, however, requires
+ * a custom GPS firmware.
+ * Revision 1.9 2001/10/16 10:11:14 MARTIN
+ * New Macro _pcps_has_serial_hs() which determines whether
+ * DCF77 clock supports baud rate higher than default.
+ * Re-arranged order of macro definitions.
+ * Revision 1.8 2001/09/03 07:15:05 MARTIN
+ * Added macro to access the firmware revision number.
+ * Cleaned up macro syntax.
+ * Added some comments.
+ * Revision 1.7 2001/08/30 13:20:04 MARTIN
+ * New macro to mark a PCPS_TIME variable as unread.
+ * New macro to check if a PCPS_TIME variable is unread.
+ * Revision 1.6 2001/03/15 15:45:01 MARTIN
+ * Added types PCPS_ERR_FLAGS, PCPS_BUS_NUM, PCPS_SLOT_NUM.
+ * Revision 1.5 2001/03/01 13:53:10 MARTIN
+ * Initial version for the new driver library.
+ *
+ **************************************************************************/
+
+#ifndef _PCPSDEV_H
+#define _PCPSDEV_H
+
+#include <pcpsdefs.h>
+#include <gpsdefs.h>
+#include <usbdefs.h>
+#include <mbg_tgt.h>
+#include <use_pack.h>
+
+#if defined( MBG_TGT_WIN32 )
+
+ //##++ ntddk.h or windows.h is now already included from mbg_tgt.h.
+
+#elif defined( MBG_TGT_LINUX )
+
+ //##++ #include <asm/timex.h>
+
+#elif defined( MBG_TGT_BSD )
+
+ //##++ #include <machine/bus.h>
+
+#endif
+
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK ) // set byte alignment
+ #pragma pack( 1 )
+#endif
+
+
+#if defined( MBG_TGT_WIN32 )
+
+ // used with QueryPerformanceCounter()
+ typedef int64_t MBG_PC_CYCLES;
+ typedef uint64_t MBG_PC_CYCLES_FREQUENCY;
+
+#elif defined( MBG_TGT_LINUX )
+
+ typedef uint64_t MBG_PC_CYCLES;
+ typedef uint64_t MBG_PC_CYCLES_FREQUENCY;
+
+#elif defined( MBG_TGT_OS2 )
+
+ typedef uint32_t MBG_PC_CYCLES; //##++ should differentiate more
+ typedef uint32_t MBG_PC_CYCLES_FREQUENCY;
+
+#elif defined( MBG_TGT_DOS )
+
+ typedef uint32_t MBG_PC_CYCLES; //##++ should differentiate more
+ typedef uint32_t MBG_PC_CYCLES_FREQUENCY;
+ #define MBG_MEM_ADDR uint32_t // 64 bit not supported, nor required.
+
+#else // other target OSs which access the hardware directly
+
+ typedef uint32_t MBG_PC_CYCLES; //##++ should differentiate more
+ typedef uint32_t MBG_PC_CYCLES_FREQUENCY;
+
+#endif
+
+
+// MBG_PC_CYCLES is always read in native machine endianess,
+// so no endianess conversion is required.
+#define _mbg_swab_mbg_pc_cycles( _p ) \
+ _nop_macro_fnc()
+
+
+#if !defined( MBG_MEM_ADDR )
+ // By default a memory address is stored
+ // as a 64 bit quantitiy.
+ #define MBG_MEM_ADDR uint64_t
+#endif
+
+
+typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */
+typedef uint8_t MBG_DBG_DATA;
+typedef uint16_t MBG_DBG_PORT;
+
+
+// ------ definitions used when accessing a clock -------------------
+// (also refer to pcpsdefs.h for more common definitions)
+
+/** @defgroup group_status_port Bit masks of PCPS_STATUS_PORT
+
+ These bits are ored with the #PCPS_STATUS_PORT byte.
+
+ The flags #PCPS_ST_SEC and #PCPS_ST_MIN are cleared whenever the clock
+ is read, so they are very unreliable in multitasking environments
+ and should therefore be ignored.
+
+ <b>NOTE</b>: On the PCI510 card the signal #PCPS_ST_IRQF has unintentionally
+ not been wired. Functions which check if a card has triggered an IRQ
+ should check the PCI_ASIC_PCI_IRQF flag provided by the PCI interface.
+ The macros used by the mbglib driver library already do so.
+ * @{
+ */
+
+#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 */
+#define PCPS_ST_MOD 0x20 /**< the DCF77 modulation */
+#define PCPS_ST_SEC 0x40 /**< Seconds have changed since last reading */
+#define PCPS_ST_MIN 0x80 /**< Minutes have changed since last reading */
+
+/** @} */
+
+// The following flags describe the bus types which are
+// supported by the plugin clocks.
+#define PCPS_BUS_ISA 0x0001 // IBM compatible PC/AT ISA bus
+#define PCPS_BUS_MCA 0x0002 // IBM PS/2 micro channel
+#define PCPS_BUS_PCI 0x0004 // PCI
+#define PCPS_BUS_USB 0x0008 // USB
+
+// The flags below are or'ed to the PC_BUS_PCI code
+// in order to indicate which PCI interface chip is used
+// on a PCI card. If no flag is set then the S5933 chip is
+// installed which has been used for the first generation
+// of Meinberg PCI cards.
+
+// S5920 PCI interface chip.
+#define PCPS_BUS_PCI_CHIP_S5920 0x8000
+
+// Meinberg's own PCI interface chip.
+#define PCPS_BUS_PCI_CHIP_ASIC 0x4000
+
+// PEX8311 PCI Express interface chip
+#define PCPS_BUS_PCI_CHIP_PEX8311 0x2000
+
+
+// The constant below combines the PCI bus flags.
+#define PCPS_BUS_PCI_S5933 ( PCPS_BUS_PCI )
+#define PCPS_BUS_PCI_S5920 ( PCPS_BUS_PCI | PCPS_BUS_PCI_CHIP_S5920 )
+#define PCPS_BUS_PCI_ASIC ( PCPS_BUS_PCI | PCPS_BUS_PCI_CHIP_ASIC )
+#define PCPS_BUS_PCI_PEX8311 ( PCPS_BUS_PCI | PCPS_BUS_PCI_CHIP_PEX8311 )
+
+
+
+/** A list of known radio clocks. */
+enum PCPS_TYPES
+{
+ PCPS_TYPE_PC31,
+ PCPS_TYPE_PS31_OLD,
+ PCPS_TYPE_PS31,
+ PCPS_TYPE_PC32,
+ PCPS_TYPE_PCI32,
+ PCPS_TYPE_GPS167PC,
+ PCPS_TYPE_GPS167PCI,
+ PCPS_TYPE_PCI509,
+ PCPS_TYPE_GPS168PCI,
+ PCPS_TYPE_PCI510,
+ PCPS_TYPE_GPS169PCI,
+ PCPS_TYPE_TCR510PCI,
+ PCPS_TYPE_TCR167PCI,
+ PCPS_TYPE_GPS170PCI,
+ PCPS_TYPE_PCI511,
+ PCPS_TYPE_TCR511PCI,
+ PCPS_TYPE_PEX511,
+ PCPS_TYPE_TCR511PEX,
+ PCPS_TYPE_GPS170PEX,
+ PCPS_TYPE_USB5131,
+ PCPS_TYPE_TCR51USB,
+ PCPS_TYPE_MSF51USB,
+ PCPS_TYPE_PTP270PEX,
+ PCPS_TYPE_FRC511PEX,
+ PCPS_TYPE_TCR170PEX,
+ PCPS_TYPE_WWVB51USB,
+ N_PCPS_DEV_TYPE
+};
+
+
+#define PCPS_CLOCK_NAME_SZ 10 // including terminating 0
+
+typedef uint16_t PCPS_DEV_ID;
+typedef uint16_t PCPS_REF_TYPE;
+typedef uint16_t PCPS_BUS_FLAGS;
+
+/**
+ The structure contains the characteristics of each
+ of the clocks listed above. These fields are always the
+ same for a single type of clock and do not change with
+ firmware version, port address, etc.
+ */
+typedef struct
+{
+ uint16_t num;
+ char name[PCPS_CLOCK_NAME_SZ];
+ PCPS_DEV_ID dev_id;
+ PCPS_REF_TYPE ref_type;
+ PCPS_BUS_FLAGS bus_flags;
+} PCPS_DEV_TYPE;
+
+
+
+#if MBG_USE_MM_IO_FOR_PCI
+ typedef uint64_t PCPS_PORT_ADDR;
+#else
+ typedef uint16_t PCPS_PORT_ADDR;
+#endif
+
+
+
+/**
+ The structure below describes an I/O port resource
+ used by a clock.
+*/
+typedef struct
+{
+ PCPS_PORT_ADDR base;
+ uint16_t num;
+} PCPS_PORT_RSRC;
+
+/** The max number of I/O port resources used by a clock. */
+#define N_PCPS_PORT_RSRC 2
+
+
+
+typedef struct
+{
+ MBG_MEM_ADDR user_virtual_address;
+ ulong len;
+ #if defined( MBG_TGT_LINUX )
+ uint32_t pfn_offset;
+ #endif
+} PCPS_MAPPED_MEM;
+
+
+
+typedef uint32_t PCPS_ERR_FLAGS; /**< see \ref group_err_flags "Error flags" */
+typedef uint32_t PCPS_FEATURES; /**< see \ref group_features "Features" */
+typedef uint16_t PCPS_BUS_NUM;
+typedef uint16_t PCPS_SLOT_NUM;
+
+/**
+ The structure below contains data which depends
+ on a individual instance of the clock, e.g.
+ the firmware which is currently installed, the
+ port address which has been configured, etc.
+*/
+typedef struct
+{
+ PCPS_ERR_FLAGS err_flags; /**< See \ref group_err_flags "Error flags" */
+ PCPS_BUS_NUM bus_num;
+ PCPS_SLOT_NUM slot_num;
+ PCPS_PORT_RSRC port[N_PCPS_PORT_RSRC];
+ uint16_t status_port;
+ int16_t irq_num;
+ uint32_t timeout_clk;
+ uint16_t fw_rev_num;
+ PCPS_FEATURES features; /**< See \ref group_features "Feature flags" */
+ PCPS_ID_STR fw_id;
+ PCPS_SN_STR sernum;
+} PCPS_DEV_CFG;
+
+/** @defgroup group_err_flags Error flags in PCPS_DEV_CFG
+ Flags used with PCPS_DEV_CFG::err_flags
+ @{
+*/
+#define PCPS_EF_TIMEOUT 0x00000001 /**< timeout occured */
+#define PCPS_EF_INV_EPROM_ID 0x00000002 /**< invalid EPROM ID */
+#define PCPS_EF_IO_INIT 0x00000004 /**< I/O intf not init'd */
+#define PCPS_EF_IO_CFG 0x00000008 /**< I/O intf not cfg'd */
+#define PCPS_EF_IO_ENB 0x00000010 /**< I/O intf not enabled */
+#define PCPS_EF_IO_RSRC 0x00000020 /**< I/O not registered w/ rsrcmgr */
+/** @} */
+
+/** @defgroup group_features Feature flags used with PCPS_FEATURES
+
+ Some features of the radio clocks have been introduced with
+ specific firmware versions, so depending on the firmware version
+ a clock may support a feature or not. The clock detection function
+ checks the clock model and firmware version and updates the field
+ PCPS_DEV_CFG::features accordingly. There are some macros which
+ can easily be used to query whether a clock device actually
+ supports a function, or not. The definitions define
+ the possible features.
+ @{
+*/
+#define PCPS_CAN_SET_TIME 0x00000001UL
+#define PCPS_HAS_SERIAL 0x00000002UL
+#define PCPS_HAS_SYNC_TIME 0x00000004UL
+#define PCPS_HAS_TZDL 0x00000008UL
+#define PCPS_HAS_IDENT 0x00000010UL
+#define PCPS_HAS_UTC_OFFS 0x00000020UL
+#define PCPS_HAS_HR_TIME 0x00000040UL
+#define PCPS_HAS_SERNUM 0x00000080UL
+#define PCPS_HAS_TZCODE 0x00000100UL
+#define PCPS_HAS_CABLE_LEN 0x00000200UL
+#define PCPS_HAS_EVENT_TIME 0x00000400UL // custom GPS firmware only
+#define PCPS_HAS_RECEIVER_INFO 0x00000800UL
+#define PCPS_CAN_CLR_UCAP_BUFF 0x00001000UL
+#define PCPS_HAS_PCPS_TZDL 0x00002000UL
+#define PCPS_HAS_UCAP 0x00004000UL
+#define PCPS_HAS_IRIG_TX 0x00008000UL
+#define PCPS_HAS_GPS_DATA_16 0x00010000UL // use 16 bit size specifiers
+#define PCPS_HAS_SYNTH 0x00020000UL
+#define PCPS_HAS_GENERIC_IO 0x00040000UL
+/** @} */
+
+// The constants below define those features which are available
+// in ALL firmware versions which have been shipped with a
+// specific clock.
+
+#define PCPS_FEAT_PC31PS31 0
+
+// Some of the features are available in all newer clocks,
+// so these have been put together in one definition:
+#define PCPS_FEAT_LVL2 ( PCPS_CAN_SET_TIME \
+ | PCPS_HAS_SERIAL \
+ | PCPS_HAS_SYNC_TIME \
+ | PCPS_HAS_UTC_OFFS )
+
+#define PCPS_FEAT_PC32 ( PCPS_FEAT_LVL2 )
+
+#define PCPS_FEAT_PCI32 ( PCPS_FEAT_LVL2 )
+
+#define PCPS_FEAT_PCI509 ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_TZCODE )
+
+#define PCPS_FEAT_PCI510 ( PCPS_FEAT_PCI509 )
+
+#define PCPS_FEAT_PCI511 ( PCPS_FEAT_PCI510 )
+
+#define PCPS_FEAT_GPS167PC ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_TZDL \
+ | PCPS_HAS_IDENT )
+
+#define PCPS_FEAT_GPS167PCI ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_TZDL \
+ | PCPS_HAS_IDENT \
+ | PCPS_HAS_HR_TIME )
+
+#define PCPS_FEAT_GPS168PCI ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_TZDL \
+ | PCPS_HAS_IDENT \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_HAS_CABLE_LEN \
+ | PCPS_HAS_RECEIVER_INFO )
+
+#define PCPS_FEAT_GPS169PCI ( PCPS_FEAT_GPS168PCI \
+ | PCPS_CAN_CLR_UCAP_BUFF \
+ | PCPS_HAS_UCAP )
+
+#define PCPS_FEAT_GPS170PCI ( PCPS_FEAT_GPS169PCI \
+ | PCPS_HAS_IRIG_TX \
+ | PCPS_HAS_GPS_DATA_16 \
+ | PCPS_HAS_GENERIC_IO )
+
+#define PCPS_FEAT_TCR510PCI ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_SERNUM )
+
+#define PCPS_FEAT_TCR167PCI ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_TZDL \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_HAS_RECEIVER_INFO \
+ | PCPS_CAN_CLR_UCAP_BUFF \
+ | PCPS_HAS_UCAP \
+ | PCPS_HAS_IRIG_TX \
+ | PCPS_HAS_GPS_DATA_16 \
+ | PCPS_HAS_GENERIC_IO )
+
+#define PCPS_FEAT_TCR511PCI ( PCPS_FEAT_TCR510PCI \
+ | PCPS_HAS_HR_TIME )
+
+#define PCPS_FEAT_PEX511 ( PCPS_FEAT_PCI511 )
+
+#define PCPS_FEAT_TCR511PEX ( PCPS_FEAT_TCR511PCI )
+
+#define PCPS_FEAT_GPS170PEX ( PCPS_FEAT_GPS170PCI )
+
+#define PCPS_FEAT_USB5131 ( PCPS_HAS_UTC_OFFS \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_SYNC_TIME \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_CAN_SET_TIME \
+ | PCPS_HAS_TZCODE )
+
+#define PCPS_FEAT_TCR51USB ( PCPS_HAS_UTC_OFFS \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_SYNC_TIME \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_CAN_SET_TIME )
+
+#define PCPS_FEAT_MSF51USB ( PCPS_HAS_UTC_OFFS \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_SYNC_TIME \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_CAN_SET_TIME )
+
+#define PCPS_FEAT_PTP270PEX ( PCPS_HAS_SERNUM \
+ | PCPS_HAS_SYNC_TIME \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_HAS_RECEIVER_INFO \
+ | PCPS_CAN_SET_TIME \
+ | PCPS_CAN_CLR_UCAP_BUFF \
+ | PCPS_HAS_UCAP \
+ | PCPS_HAS_GPS_DATA_16 )
+
+#define PCPS_FEAT_FRC511PEX ( PCPS_HAS_SERNUM \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_HAS_RECEIVER_INFO \
+ | PCPS_CAN_SET_TIME \
+ | PCPS_CAN_CLR_UCAP_BUFF \
+ | PCPS_HAS_UCAP \
+ | PCPS_HAS_GPS_DATA_16 )
+
+#define PCPS_FEAT_TCR170PEX ( PCPS_FEAT_TCR167PCI )
+
+#define PCPS_FEAT_WWVB51USB ( PCPS_FEAT_MSF51USB )
+
+// Some features of the API used to access Meinberg plug-in radio clocks
+// have been implemented starting with the special firmware revision
+// numbers defined below.
+//
+// If no number is specified for a feature/clock model then the feature
+// is either always supported by that clock model, or not at all.
+
+
+// There are some versions of PCI Express cards out there which do not
+// safely support hardware IRQs. The following firmware versions are required
+// for safe IRQ operation:
+#define REV_HAS_IRQ_FIX_MINOR_PEX511 0x0106
+#define REV_HAS_IRQ_FIX_MINOR_TCR511PEX 0x0105
+#define REV_HAS_IRQ_FIX_MINOR_GPS170PEX 0x0104
+// Additionally there are certain revisions of the bus interface logic
+// required. The associated version codes are defined in pci_asic.h.
+
+// The macro below can be used to check whether the required versions are there:
+#define _pcps_pex_irq_is_safe( _curr_fw_ver, _req_fw_ver, _curr_asic_ver, \
+ _req_asic_ver_major, _req_asic_ver_minor ) \
+ ( ( (_curr_fw_ver) >= (_req_fw_ver) ) && _pcps_asic_version_greater_equal( \
+ (_curr_asic_ver), (_req_asic_ver_major), (_req_asic_ver_minor ) ) \
+ )
+
+
+
+/* This board uses the GPS_DATA interface with 16 bit buffer sizes
+ instead of the original 8 bit sizes, thus allowing to transfer
+ data blocks which exceed 255 bytes (PCPS_HAS_GPS_DATA_16) */
+#define REV_HAS_GPS_DATA_16_GPS169PCI 0x0202
+
+/* the clock supports a higher baud rate than N_PCPS_BD_DCF */
+#define REV_HAS_SERIAL_HS_PCI509 0x0104
+
+/* commands PCPS_GIVE_UCAP_ENTRIES, PCPS_GIVE_UCAP_EVENT */
+#define REV_HAS_UCAP_GPS167PCI 0x0421
+#define REV_HAS_UCAP_GPS168PCI 0x0104
+
+/* command PCPS_CLR_UCAP_BUFF */
+#define REV_CAN_CLR_UCAP_BUFF_GPS167PCI 0x0419
+#define REV_CAN_CLR_UCAP_BUFF_GPS168PCI 0x0101
+
+/* commands PCPS_READ_GPS_DATA and PCPS_WRITE_GPS_DATA with */
+/* code PC_GPS_ANT_CABLE_LEN */
+#define REV_HAS_CABLE_LEN_GPS167PCI 0x0411
+#define REV_HAS_CABLE_LEN_GPS167PC 0x0411
+
+/* command PCPS_GIVE_HR_TIME, structure PCPS_HR_TIME */
+#define REV_HAS_HR_TIME_GPS167PC 0x0305
+#define REV_HAS_HR_TIME_TCR510PCI 0x0200
+#define REV_HAS_HR_TIME_PEX511 0x0105 // This also requires a certain ASIC version.
+#define REV_HAS_HR_TIME_PCI511 0x0103
+
+/* field offs_utc in structure PCPS_TIME */
+#define REV_HAS_UTC_OFFS_PC31PS31 0x0300
+
+/* command PCPS_GIVE_SYNC_TIME: */
+#define REV_HAS_SYNC_TIME_PC31PS31 0x0300
+
+/* command PCPS_GET_SERIAL, PCPS_SET_SERIAL: */
+#define REV_HAS_SERIAL_PC31PS31 0x0300
+
+/* command PCPS_GIVE_TIME_NOCLEAR: */
+#define REV_GIVE_TIME_NOCLEAR_PC31PS31 0x0300
+
+/* status bit PCPS_LS_ANN: */
+#define REV_PCPS_LS_ANN_PC31PS31 0x0300
+
+/* status bit PCPS_IFTM: */
+#define REV_PCPS_IFTM_PC31PS31 0x0300
+
+/* command PCPS_SET_TIME: */
+#define REV_CAN_SET_TIME_PC31PS31 0x0240
+
+/* command PCPS_GIVE_TIME_NOCLEAR: */
+// This is supported by all clocks but PC31/PS31 with
+// firmware versions before v3.0. If such a card shall
+// be used then the firmware should be updated to the
+// last recent version.
+
+
+/**
+ The structure has been defined to pass all
+ information on a clock device from a device driver
+ to a user program. */
+typedef struct
+{
+ PCPS_DEV_TYPE type;
+ PCPS_DEV_CFG cfg;
+} PCPS_DEV;
+
+
+// The macros below simplify access to the data
+// stored in PCPS_DEV structure and should be used
+// to extract the desired information.
+// If the formal parameter is called _d then a pointer
+// to device structure PCPS_DEV is expected.
+// If the formal parameter is called _c then a pointer
+// to configuration structure PCPS_DEV_CFG is expected.
+
+// Access device type information:
+#define _pcps_type_num( _d ) ( (_d)->type.num )
+#define _pcps_type_name( _d ) ( (_d)->type.name )
+#define _pcps_dev_id( _d ) ( (_d)->type.dev_id )
+#define _pcps_ref_type( _d ) ( (_d)->type.ref_type )
+#define _pcps_bus_flags( _d ) ( (_d)->type.bus_flags )
+
+// Query device type features:
+#define _pcps_is_gps( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_GPS )
+#define _pcps_is_dcf( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_DCF )
+#define _pcps_is_msf( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_MSF )
+#define _pcps_is_wwvb( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_WWVB )
+#define _pcps_is_irig_rx( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_IRIG )
+#define _pcps_is_ptp( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_PTP )
+#define _pcps_is_frc( _d ) ( _pcps_ref_type( _d ) == PCPS_REF_FRC )
+
+#define _pcps_is_lwr( _d ) ( _pcps_is_dcf( _d ) || _pcps_is_msf( _d ) || _pcps_is_wwvb( _d ) )
+
+#define _pcps_is_isa( _d ) ( _pcps_bus_flags( _d ) & PCPS_BUS_ISA )
+#define _pcps_is_mca( _d ) ( _pcps_bus_flags( _d ) & PCPS_BUS_MCA )
+#define _pcps_is_pci( _d ) ( _pcps_bus_flags( _d ) & PCPS_BUS_PCI )
+#define _pcps_is_usb( _d ) ( _pcps_bus_flags( _d ) & PCPS_BUS_USB )
+
+#define _pcps_is_pci_s5933( _d ) ( _pcps_bus_flags( _d ) == PCPS_BUS_PCI_S5933 )
+#define _pcps_is_pci_s5920( _d ) ( _pcps_bus_flags( _d ) == PCPS_BUS_PCI_S5920 )
+#define _pcps_is_pci_amcc( _d ) ( _pcps_is_pci_s5920( _d ) || _pcps_is_pci_s5933( _d ) )
+#define _pcps_is_pci_asic( _d ) ( _pcps_bus_flags( _d ) == PCPS_BUS_PCI_ASIC )
+#define _pcps_is_pci_pex8311( _d ) ( _pcps_bus_flags( _d ) == PCPS_BUS_PCI_PEX8311 )
+
+
+// Access device configuration information:
+#define _pcps_bus_num( _d ) ( (_d)->cfg.bus_num )
+#define _pcps_slot_num( _d ) ( (_d)->cfg.slot_num )
+
+#define _pcps_cfg_port_rsrc( _c, _n ) ( (_c)->port[_n] )
+#define _pcps_port_rsrc( _d, _n ) _pcps_cfg_port_rsrc( &(_d)->cfg, (_n) )
+#define _pcps_port_rsrc_unused( _d ) ( (_d)->base == 0 || (_d)->num == 0 )
+
+#define _pcps_cfg_port_base( _c, _n ) ( _pcps_cfg_port_rsrc( (_c), (_n) ).base )
+#define _pcps_port_base( _d, _n ) ( _pcps_port_rsrc( (_d), (_n) ).base )
+
+#define _pcps_cfg_irq_num( _c ) ( (_c)->irq_num )
+#define _pcps_irq_num( _d ) _pcps_cfg_irq_num( &(_d)->cfg )
+
+#define _pcps_cfg_timeout_clk( _c ) ( (_c)->timeout_clk )
+#define _pcps_timeout_clk( _d ) _pcps_cfg_timeout_clk( &(_d)->cfg )
+
+#define _pcps_fw_rev_num( _d ) ( (_d)->cfg.fw_rev_num )
+#define _pcps_fw_id( _d ) ( (_d)->cfg.fw_id )
+#define _pcps_sernum( _d ) ( (_d)->cfg.sernum )
+
+
+// The macros below handle the clock device's err_flags.
+#define _pcps_err_flags( _d ) ( (_d)->cfg.err_flags )
+#define _pcps_chk_err_flags( _d, _msk ) ( _pcps_err_flags( _d ) & (_msk) )
+#define _pcps_set_err_flags( _d, _msk ) ( _pcps_err_flags( _d ) |= (_msk) )
+#define _pcps_clr_err_flags( _d, _msk ) ( _pcps_err_flags( _d ) &= ~(_msk) )
+
+
+// Query whether a special feature is supported:
+#define _pcps_has_feature( _d, _f ) ( ( (_d)->cfg.features & (_f) ) != 0 )
+#define _pcps_can_set_time( _d ) _pcps_has_feature( (_d), PCPS_CAN_SET_TIME )
+#define _pcps_has_serial( _d ) _pcps_has_feature( (_d), PCPS_HAS_SERIAL )
+#define _pcps_has_sync_time( _d ) _pcps_has_feature( (_d), PCPS_HAS_SYNC_TIME )
+#define _pcps_has_ident( _d ) _pcps_has_feature( (_d), PCPS_HAS_IDENT )
+#define _pcps_has_utc_offs( _d ) _pcps_has_feature( (_d), PCPS_HAS_UTC_OFFS )
+#define _pcps_has_hr_time( _d ) _pcps_has_feature( (_d), PCPS_HAS_HR_TIME )
+#define _pcps_has_sernum( _d ) _pcps_has_feature( (_d), PCPS_HAS_SERNUM )
+#define _pcps_has_cab_len( _d ) _pcps_has_feature( (_d), PCPS_HAS_CABLE_LEN )
+#define _pcps_has_tzdl( _d ) _pcps_has_feature( (_d), PCPS_HAS_TZDL )
+#define _pcps_has_pcps_tzdl( _d ) _pcps_has_feature( (_d), PCPS_HAS_PCPS_TZDL )
+#define _pcps_has_tzcode( _d ) _pcps_has_feature( (_d), PCPS_HAS_TZCODE )
+#define _pcps_has_tz( _d ) _pcps_has_feature( (_d), PCPS_HAS_TZDL \
+ | PCPS_HAS_PCPS_TZDL \
+ | PCPS_HAS_TZCODE )
+// The next one is supported only with a certain GPS firmware version:
+#define _pcps_has_event_time( _d ) _pcps_has_feature( (_d), PCPS_HAS_EVENT_TIME )
+#define _pcps_has_receiver_info( _d ) _pcps_has_feature( (_d), PCPS_HAS_RECEIVER_INFO )
+#define _pcps_can_clr_ucap_buff( _d ) _pcps_has_feature( (_d), PCPS_CAN_CLR_UCAP_BUFF )
+#define _pcps_has_ucap( _d ) _pcps_has_feature( (_d), PCPS_HAS_UCAP )
+#define _pcps_has_irig_tx( _d ) _pcps_has_feature( (_d), PCPS_HAS_IRIG_TX )
+
+// The macro below determines whether a DCF77 clock
+// supports a higher baud rate than standard
+#define _pcps_has_serial_hs( _d ) \
+ ( ( _pcps_type_num( _d ) == PCPS_TYPE_TCR511PEX ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_PEX511 ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_TCR511PCI ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_TCR510PCI ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_PCI511 ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_PCI510 ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_PCI509 && \
+ _pcps_fw_rev_num( _d ) >= REV_HAS_SERIAL_HS_PCI509 ) )
+
+
+#define _pcps_has_signal( _d ) \
+ ( _pcps_is_dcf( _d ) || _pcps_is_msf( _d ) || _pcps_is_wwvb( _d ) || _pcps_is_irig_rx( _d ) )
+
+#define _pcps_has_mod( _d ) \
+ ( _pcps_is_dcf( _d ) || _pcps_is_msf( _d ) || _pcps_is_wwvb( _d ) )
+
+
+#define _pcps_has_irig( _d ) \
+ ( _pcps_is_irig_rx( _d ) || _pcps_has_irig_tx( _d ) )
+
+#define _pcps_has_ref_offs( _d ) \
+ _pcps_is_irig_rx( _d )
+
+#define _pcps_ref_offs_out_of_range( _n ) \
+ ( ( (_n) > MBG_REF_OFFS_MAX ) || ( (_n) < -MBG_REF_OFFS_MAX ) )
+
+#define _pcps_has_opt_flags( _d ) \
+ _pcps_is_irig_rx( _d )
+
+#define _pcps_has_gps_data_16( _d ) _pcps_has_feature( (_d), PCPS_HAS_GPS_DATA_16 )
+
+#define _pcps_has_gps_data( _d ) \
+ ( _pcps_is_gps( _d ) || _pcps_has_gps_data_16( _d ) )
+
+#define _pcps_has_synth( _d ) _pcps_has_feature( (_d), PCPS_HAS_SYNTH )
+
+#define _pcps_has_generic_io( _d ) _pcps_has_feature( (_d), PCPS_HAS_GENERIC_IO )
+
+#define _pcps_has_asic_version( _d ) ( _pcps_is_pci_asic( _d ) || _pcps_is_pci_pex8311( _d ) )
+
+#define _pcps_has_asic_features( _d ) _pcps_has_asic_version( _d )
+
+
+/**
+ The structure is used to return info
+ on the device driver.*/
+typedef struct
+{
+ uint16_t ver_num; /**< the device driver's version number */
+ uint16_t n_devs; /**< the number of radio clocks handled by the driver */
+ PCPS_ID_STR id_str; /**< the device driver's ID string */
+} PCPS_DRVR_INFO;
+
+
+
+/*
+ * The definitions and types below are used to collect
+ * all configuration parameters of a clock's serial ports
+ * that can be handled by this library:
+ */
+
+// The maximum number of clocks' serial ports and string types
+// that can be handled by the configuration programs:
+#define MAX_PARM_PORT 4
+#define MAX_PARM_STR_TYPE 20
+
+typedef PORT_INFO_IDX ALL_PORT_INFO[MAX_PARM_PORT];
+typedef STR_TYPE_INFO_IDX ALL_STR_TYPE_INFO[MAX_PARM_STR_TYPE];
+
+typedef struct
+{
+ ALL_PORT_INFO pii;
+ ALL_STR_TYPE_INFO stii;
+ PORT_PARM tmp_pp;
+
+} RECEIVER_PORT_CFG;
+
+
+
+/*
+ * The definitions and types below are used to collect
+ * all configuration parameters of a clock's programmable
+ * pulse outputs that can be handled by this library:
+ */
+
+#define MAX_PARM_POUT 4
+
+typedef POUT_INFO_IDX ALL_POUT_INFO[MAX_PARM_POUT];
+
+
+
+// The macros below can be used to mark a PCPS_TIME variable
+// as unread, i.e. its contents have not been read from the clock,
+// and to check if such a variable is marked as unread.
+#define _pcps_time_set_unread( _t ); { (_t)->sec = 0xFF; }
+#define _pcps_time_is_read( _t ) ( (uchar) (_t)->sec != 0xFF )
+
+
+
+/**
+ The structure is used to read current time from
+ a device, combined with an associated PC cycle counter value
+ to compensate program execution time. The cycle counter value
+ is usually derived from the PC CPU's TSC and the type is
+ redefined to a common type, depending on the operating system.
+ The cycle counter clock frequency usually corresponds to the
+ PC CPU clock frequency.*/
+typedef struct
+{
+ MBG_PC_CYCLES cycles;
+ PCPS_TIME t;
+} PCPS_TIME_CYCLES;
+
+
+
+/**
+ The structure is used to read a high resolution UTC time stamp
+ plus associated PC cycles counter value to compensate the latency.
+ */
+typedef struct
+{
+ MBG_PC_CYCLES cycles;
+ PCPS_TIME_STAMP tstamp; /**< High resolution time stamp (UTC) */
+} PCPS_TIME_STAMP_CYCLES;
+
+#define _mbg_swab_pcps_time_stamp_cycles( _p ) \
+{ \
+ _mbg_swab_mbg_pc_cycles( &(_p)->cycles ); \
+ _mbg_swab_pcps_time_stamp( &(_p)->tstamp ); \
+}
+
+
+
+/**
+ The structure is used to read current high resolution time from
+ a device, combined with an associated PC cycle counter value
+ to compensate program execution time. The cycle counter value
+ is usually derived from the PC CPU's TSC and the type is
+ redefined to a common type, depending on the operating system.
+ The cycle counter clock frequency usually corresponds to the
+ PC CPU clock frequency.*/
+typedef struct
+{
+ MBG_PC_CYCLES cycles;
+ PCPS_HR_TIME t;
+} PCPS_HR_TIME_CYCLES;
+
+#define _mbg_swab_pcps_hr_time_cycles( _p ) \
+{ \
+ _mbg_swab_mbg_pc_cycles( &(_p)->cycles ); \
+ _mbg_swab_pcps_hr_time( &(_p)->t ); \
+}
+
+
+
+typedef uint32_t PCPS_IRQ_STAT_INFO;
+
+// Flags used with PCPS_IRQ_STAT_INFO:
+#define PCPS_IRQ_STAT_ENABLE_CALLED 0x01
+#define PCPS_IRQ_STAT_ENABLED 0x02
+#define PCPS_IRQ_STAT_UNSAFE 0x04 // IRQs unsafe with this firmeware version / ASIC
+
+#define PCPS_IRQ_STATE_DANGER ( PCPS_IRQ_STAT_ENABLED | PCPS_IRQ_STAT_UNSAFE )
+
+#define _pcps_fw_rev_num_major( _v ) \
+ ( ( (_v) >> 8 ) & 0xFF )
+
+#define _pcps_fw_rev_num_minor( _v ) \
+ ( (_v) & 0xFF )
+
+
+#if defined( _USE_PACK ) // set default alignment
+ #pragma pack()
+#endif
+
+/* End of header body */
+
+#undef _ext
+
+#endif /* _PCPSDEV_H */
+
diff --git a/c/mbglib/include/usbdefs.h b/c/mbglib/include/usbdefs.h
new file mode 100644
index 0000000..921b514
--- /dev/null
+++ b/c/mbglib/include/usbdefs.h
@@ -0,0 +1,114 @@
+
+/**************************************************************************
+ *
+ * $Id: usbdefs.h 1.7 2008/11/28 07:45:30Z daniel REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions used with USB devices.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: usbdefs.h $
+ * Revision 1.7 2008/11/28 07:45:30Z daniel
+ * Added new class code and device ID for WWVB51USB
+ * Revision 1.6 2008/01/09 10:39:18Z daniel
+ * Added new class code and device ID for MSF51USB
+ * Revision 1.5 2007/10/29 08:23:26Z daniel
+ * Added new class code and device ID for TCR51USB
+ * Revision 1.4 2007/09/25 09:59:50Z daniel
+ * Added indices for endpoint definitions.
+ * Added timeout definitions.
+ * Revision 1.3 2006/12/20 16:11:36Z daniel
+ * Added new device class and device_id for nCipher CMC-device.
+ * Revision 1.2 2006/12/07 09:10:57Z daniel
+ * Added new class code and device ID for USB5131.
+ * Revision 1.1 2006/04/21 08:14:56Z martin
+ * Initial revision
+ *
+ **************************************************************************/
+
+#ifndef _USBDEFS_H
+#define _USBDEFS_H
+
+
+/* Other headers to be included */
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Meinberg's USB vendor ID number (assigned by USB-IF Administration) */
+#define USB_VENDOR_MEINBERG 0x1938
+
+
+/*
+ * USB device class codes (assigned by Meinberg)
+ */
+enum
+{
+ MBG_USB_CLASS_NONE, // (unknown or not defined)
+ MBG_USB_CLASS_CPC, // Control Panel Controller
+ MBG_USB_CLASS_TSU, // Time Stamp Unit
+ MBG_USB_CLASS_DCF, // DCF77 Radio Clock
+ MBG_USB_CLASS_CMC, // nCipher Crypto Module Carrier
+ MBG_USB_CLASS_TCR, // IRIG Time Code Receiver
+ MBG_USB_CLASS_MSF, // MSF Radio Clock
+ MBG_USB_CLASS_WWVB, // WWVB Radio Clock
+ N_MBG_USB_CLASS // number of known device class codes
+};
+
+
+/*
+ * USB device ID numbers (assigned by Meinberg)
+ * High byte: USB device class as specified above
+ * Low byte: enumeration of device of a class
+ */
+#define USB_DEV_CPC_01 ( ( MBG_USB_CLASS_CPC << 8 ) | 0x01 )
+
+#define USB_DEV_TSU_01 ( ( MBG_USB_CLASS_TSU << 8 ) | 0x01 )
+
+#define USB_DEV_USB5131 ( ( MBG_USB_CLASS_DCF << 8 ) | 0x01 )
+
+#define USB_DEV_CMC ( ( MBG_USB_CLASS_CMC << 8 ) | 0x01 )
+
+#define USB_DEV_TCR51USB ( ( MBG_USB_CLASS_TCR << 8 ) | 0x01 )
+
+#define USB_DEV_MSF51USB ( ( MBG_USB_CLASS_MSF << 8 ) | 0x01 )
+
+#define USB_DEV_WWVB51USB ( ( MBG_USB_CLASS_WWVB << 8 ) | 0x01 )
+
+enum
+{
+ MBGUSB_EP_IDX_HOST_IN, // transfers from device to host
+ MBGUSB_EP_IDX_HOST_OUT, // transfers from host to device
+ MBGUSB_EP_IDX_HOST_IN_CYCLIC, // cyclic auto-transfer to host
+ MBGUSB_MAX_ENDPOINTS // max number of supported endpoints
+};
+
+
+#ifndef MBGUSB_TIMEOUT_SEND_MS
+ #define MBGUSB_TIMEOUT_SEND_MS 500 // [ms]
+#endif
+
+#ifndef MBGUSB_TIMEOUT_RECEIVE_MS
+ #define MBGUSB_TIMEOUT_RECEIVE_MS 500 // [ms]
+#endif
+
+#ifndef MBGUSB_TIMEOUT_RECEIVE_CYCLIC_MS
+ #define MBGUSB_TIMEOUT_RECEIVE_CYCLIC_MS 2000 // [ms]
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#endif /* _USBDEFS_H */
diff --git a/c/mbglib/lib/msc/mbgdevio.lib b/c/mbglib/lib/msc/mbgdevio.lib
new file mode 100644
index 0000000..218352b
--- /dev/null
+++ b/c/mbglib/lib/msc/mbgdevio.lib
Binary files differ
diff --git a/c/mbglib/lib/msc/mbgutil.lib b/c/mbglib/lib/msc/mbgutil.lib
new file mode 100644
index 0000000..6070da5
--- /dev/null
+++ b/c/mbglib/lib/msc/mbgutil.lib
Binary files differ