summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2009-01-22 12:01:00 +0100
committerMartin Burnicki <martin.burnicki@meinberg.de>2009-01-22 12:01:00 +0100
commitd2cb34a07d87f9c4876b03c43c830c8509589523 (patch)
treea51d74629e886efad95a965b882cd2b07563fb82
parentfd4cbd96b62f656c2328fa9e902993c7a2b0d0a6 (diff)
downloadmbgsdk-win-d2cb34a07d87f9c4876b03c43c830c8509589523.tar.gz
mbgsdk-win-d2cb34a07d87f9c4876b03c43c830c8509589523.zip
Update mbgdevio demo C files
-rw-r--r--c/demo/mbgdevio/hrtime.c41
-rw-r--r--c/demo/mbgdevio/mbgdevio_demo.c92
-rw-r--r--c/demo/mbgdevio/xhrtime.c134
-rw-r--r--c/demo/mbgdevio/xhrtime.exebin49152 -> 0 bytes
4 files changed, 195 insertions, 72 deletions
diff --git a/c/demo/mbgdevio/hrtime.c b/c/demo/mbgdevio/hrtime.c
index d76846c..94eea4b 100644
--- a/c/demo/mbgdevio/hrtime.c
+++ b/c/demo/mbgdevio/hrtime.c
@@ -1,13 +1,14 @@
/**************************************************************************
*
- * $Id: hrtime.c 1.4 2009/01/07 15:22:36Z daniel TRASH $
- * $Name: $
+ * $Id: hrtime.c 1.5 2009/01/23 08:31:28Z daniel REL_M $
+ * $Name: MBGDEVIO_HRTIME_100 $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* -----------------------------------------------------------------------
* $Log: hrtime.c $
+ * Revision 1.5 2009/01/23 08:31:28Z daniel
* Revision 1.4 2009/01/07 15:22:36Z daniel
* Cleaned up source code.
* Revision 1.3 2008/01/16 08:48:24Z daniel
@@ -17,11 +18,47 @@
*
**************************************************************************/
+/*! \defgroup group_hrt Getting high resolution time stamps
+
+ The structure PCPS_HR_TIME is read using
+ the mbg_get_hr_time() call and contains the system time in seconds since
+ 1970 (standard time_t format), the fractions of a second, plus status
+ and UTC offset.
+
+ The device driver checks whether a particular feature like HR time is
+ supported by a particular device and returns an error if it is not.
+ Also the latest driver software should be used since older
+ versions of the driver don't check for HR time support.
+
+ With our GPS cards, the effictive resolution of the HR time is better
+ than 1 microsecond. For the IRIG receivers, the resolution is 400
+ microseconds which is still much better than 10/15 milliseconds provided
+ by the Windows system clock.
+
+ To get most accuracy for time stamps, a program can read the PC's
+ performance counter, and then call mbg_get_time_cycles() which returns
+ the HR time plus the performance counter value which matches that HR
+ time stamp. The difference between the two performance counter values
+ can be used to compensate the program execution time delay.
+
+ The way to access the time on the board is to write a command to the
+ board's microcontroller which in turn makes the requested data available
+ for reading. The advantage of this is that the interface is very
+ flexible, but the disadvantage is that the on-board microcontroller is
+ involved in any access to the board. In order to prevent applications
+ from overruning the on-board microcontroller by countinuous accesses to
+ the board the card has a limitation which limits the time between two
+ accesses to 200 microseconds and 1 millisecond depending on the device.
+
+*/
+
/**
\file
Example program to read the high resolution time from
Meinberg computer peripherals
using the mbgdevio (Meinberg Device I/O) DLL.
+
+ \copydoc group_hrt
Build environment settings:
diff --git a/c/demo/mbgdevio/mbgdevio_demo.c b/c/demo/mbgdevio/mbgdevio_demo.c
index 7039f6b..0df7655 100644
--- a/c/demo/mbgdevio/mbgdevio_demo.c
+++ b/c/demo/mbgdevio/mbgdevio_demo.c
@@ -1,25 +1,16 @@
/**************************************************************************
*
- * $Id: mbgdevio_demo.c 1.5 2009/01/08 07:52:59Z daniel TRASH $
- * $Name: $
+ * $Id: mbgdevio_demo.c 1.7 2009/01/23 08:31:28Z daniel REL_M $
+ * $Name: MBGDEVIO_DEMO_100 $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
- * Description:
- * Example program to access Meinberg computer peripherals
- * using the mbgdevio (Meinberg Device I/O) DLL.
- *
- * Build environment settings:
- * Add "mbglib\include" directory to the include search path.
- * Link the main file plus the required import libraries,
- * in this case mbgdevio.lib and mbgutil.lib.
- * The import libraries are located:
- * in mbglib\lib\msc for Microsoft C compilers
- * in mbglib\lib\bc for Inprise/Borland compilers
- *
* -----------------------------------------------------------------------
* $Log: mbgdevio_demo.c $
+ * Revision 1.7 2009/01/23 08:31:28Z daniel
+ * Revision 1.6 2009/01/20 11:13:26Z daniel
+ * Added comments.
* Revision 1.5 2009/01/08 07:52:59Z daniel
* Code cleanup
* Revision 1.4 2008/12/04 13:39:04Z daniel
@@ -31,6 +22,26 @@
* Initial revision
*
**************************************************************************/
+
+/**
+ \file
+ Example program to access Meinberg computer peripherals
+ using the mbgdevio (Meinberg Device I/O) DLL.<br>
+ The program checks first whether a certain feature like high
+ resolution time, Memory Mapped I/O or user capture is
+ supported by the device.
+
+ Build environment settings:
+
+ Add "mbglib\include" directory to the include search path.
+ Link the main file plus the required import libraries,
+ in this case mbgdevio.lib and mbgutil.lib.
+
+ The import libraries are located:<br>
+ <B>"mbglib\lib\msc"</B> for Microsoft C compilers<br>
+ <B>"mbglib\lib\bc"</B> for Inprise/Borland compilers
+ */
+
#include <mbgdevio.h>
#include <mbgutil.h>
@@ -38,9 +49,10 @@
#include <stdio.h>
-static int n_sec_change = 10;
+static int n_sec_change = 0;
+
+#define MAX_MEM_MAPPED_CNT 20 /** Number of memory mapped time reads */
-#define MAX_MEM_MAPPED_CNT 20
static /*HDR*/
void err_msg( const char *msg )
@@ -132,6 +144,7 @@ void print_date_time_status( MBG_DEV_HANDLE dh )
PCPS_TIME t;
+ // Read a simple time stamp with 10 ms resolution.
if ( PCPS_SUCCESS == mbg_get_time( dh, &t ) )
{
print_date_time( &t, " " );
@@ -194,6 +207,7 @@ void print_hr_time( MBG_DEV_HANDLE dh )
printf( " HR time (raw): %s, latency: %i hns\n", sprint_hr_time( ws, &hr_t ), latency );
+ // Format function taken from mbgutil.h
mbg_str_pcps_hr_tstamp_utc( ws, sizeof( ws ), &hr_t );
printf( " HR time (utc): %s, latency=%i hns\n", ws, latency );
}
@@ -223,6 +237,7 @@ void print_sec_changes( MBG_DEV_HANDLE dh )
PCPS_TIME t;
BOOL rc;
+ // This IOCTL call blocks until a second change is detected.
rc = mbg_get_time_sec_change( dh, &t );
if ( rc == PCPS_SUCCESS )
@@ -284,6 +299,35 @@ void print_sv_info( MBG_DEV_HANDLE dh )
static /*HDR*/
+/**
+ There are 3 functions to deal with the capture events:
+
+ \li mbg_clr_ucap_buff() clears the on-board FIFO buffer
+ \li mbg_get_ucap_entries() returns the maximum number of entries
+ and the currently saved number of entries in the buffer
+ \li mbg_get_ucap_event() retrieves a capture event from the
+ on-board FIFO, or 0000.0000 if the FIFO buffer is empty.
+
+ When using the time capture inputs the following hints might be helpful:
+
+ \li The corresponding DIP switches on the card must be set to the "ON"
+ position in order to wire the input pins to the capture circuitry. See
+ the user manual for the correct DIP switches.
+ \li Capture events are stored in the on-board FIFO, and entries can be
+ retrieved from the FIFO in different ways. Once an entry has been
+ retrieved it is removed from the FIFO, so if several ways or
+ applications are used at the same time to retrieve capture events from
+ the FIFO then capture events may be missed by one application since they
+ have already been retrieved by another application.
+ \li The card provides 2 physical serial interfaces either of which may
+ have been configured to send a serial ASCII string automatically
+ whenever a capture event has occurred. Of course this would also remove
+ those capture events from the FIFO buffer. So the settings of both
+ serial ports should be checked to make sure none of the serial ports
+ have been configured to send the capture string automatically. This has
+ to be done only once for a card since the setting is saved in
+ non-volatile memory.
+*/
void check_user_captures( MBG_DEV_HANDLE dh, PCPS_DEV *pdev )
{
unsigned int ucaps_read = 0;
@@ -461,30 +505,36 @@ int main( int argc, char* argv[] )
check_user_captures( dh, &dev );
}
+
//***********
- // Loop some seconds to wait for second changes
+ // Loop some seconds waiting for second to change
// Uncomment the line below if required:
// print_sec_changes( dh );
//***********
- // Check if device has memory mapped I/O support
- // and read fast HR timestamps.
+
+ // Check if device has support for memory mapped I/O
+ // and read a couple of time stamps.
if ( _pcps_has_asic_version( &dev ) )
{
PCI_ASIC_FEATURES asic_features;
rc = mbg_get_asic_features( dh, &asic_features );
- if ( rc == PCPS_SUCCESS && asic_features >= 1 )
+ if ( rc == PCPS_SUCCESS && asic_features >= PCI_ASIC_HAS_MM_IO )
{
PCPS_HR_TIME hrtime[MAX_MEM_MAPPED_CNT] = { 0 };
uint32_t latency[MAX_MEM_MAPPED_CNT];
-
+
+ // Read some memory mapped time stamps
+ // as fast as possible
for(j = 0; j < MAX_MEM_MAPPED_CNT; j++)
mbg_get_fast_hr_timestamp_comp( dh, &hrtime[j].tstamp, &latency[j] );
+
+ // Print time stamps
for(j = 0; j < MAX_MEM_MAPPED_CNT; j++)
{
char ws[200];
diff --git a/c/demo/mbgdevio/xhrtime.c b/c/demo/mbgdevio/xhrtime.c
index 89d64e8..f71c869 100644
--- a/c/demo/mbgdevio/xhrtime.c
+++ b/c/demo/mbgdevio/xhrtime.c
@@ -1,44 +1,78 @@
/**************************************************************************
*
- * $Id: xhrtime.c 1.2 2009/01/15 15:59:09Z daniel TRASH $
- *
- * 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.
+ * $Id: xhrtime.c 1.4 2009/01/23 08:31:28Z daniel REL_M $
*
* -----------------------------------------------------------------------
* $Log: xhrtime.c $
+ * Revision 1.4 2009/01/23 08:31:28Z daniel
+ * Revision 1.3 2009/01/20 11:13:26Z daniel
+ * Added comments.
* Revision 1.2 2009/01/15 15:59:09Z daniel
* Revision 1.1 2009/01/07 15:21:48Z daniel
* Initial revision
*
**************************************************************************/
+/*! \defgroup group_xhrt Getting extrapolated high resolution time stamps
+
+ To retrieve extrapolated time stamps a polling thread
+ inside the mbgdevio.dll is started which
+ reads a high resolution time stamp and an 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 device for every
+ single time stamp.
+
+ On systems where the cycles counter is implemented by a CPU's time stamp
+ counter (TSC) it maybe required to set the thread or process affinity to a
+ single CPU to get reliable cycles counts. In this case also care should be
+ taken that the CPU's clock frequency is not stepped up and down e.g. due
+ to power saving mechanisms (e.g. Intel SpeedStep, or AMD Cool'n'Quiet).
+ Otherwise time interpolation may be messed up.
+
+ <b>Notes:</b>
+ \li This approach works / makes sense only with cards which support
+ high resolution time stamps (PCPS_HR_TIME). If a card doesn't support
+ that then this program prints a warning.
+
+ \li 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.
+
+ Associated functions:
+
+ \li mbg_xhrt_poll_thread_create()
+ \li mbg_get_xhrt_cycles_frequency()
+ \li mbg_get_xhrt_time_as_pcps_hr_time()
+ \li mbg_get_xhrt_time_as_filetime()
+ \li mbg_xhrt_poll_thread_stop()
+
+ */
+
+ /**
+ \file
+ \copydoc group_xhrt
+
+ Build environment settings:
+
+ Add "mbglib\include" directory to the include search path.
+ Link the main file plus the required import libraries,
+ in this case mbgdevio.lib and mbgutil.lib.
+
+ The import libraries are located:<br>
+ <B>"mbglib\lib\msc"</B> for Microsoft C compilers<br>
+ <B>"mbglib\lib\bc"</B> for Inprise/Borland compilers
+
+ */
+
#include <mbgdevio.h>
#include <mbgutil.h>
@@ -47,12 +81,16 @@
// 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.
+#define N_LOOPS 30 /** Number of time stamps */
+#define USE_PCPS_HR_TIME 1 /** Select 1 to use PCPS_HR_TIME as output format. Select 0 to use Windows FILETIME. */
+/**
+ Union to do a simple conversion between
+ a Windows FILETIME to a 64 Bit value.
+*/
typedef union
{
- FILETIME ft;
+ FILETIME ft;
DWORDLONG dwl;
} FT_DWL;
@@ -79,7 +117,6 @@ void print_drvr_info( void )
exit( 1 );
}
-
rc = mbg_get_drvr_info( dh, &drvr_info );
mbg_close_device( &dh );
@@ -114,12 +151,12 @@ void print_dev_info( MBG_DEV_HANDLE dh,
if ( rc == PCPS_SUCCESS )
{
_pcps_port_base( p_dev, 0 ) ?
- printf( " %s at port %03Xh\n",
- _pcps_fw_id( p_dev ),
+ printf( " %s, SN: %s at port %03Xh\n",
+ _pcps_fw_id( p_dev ), _pcps_sernum( p_dev ),
_pcps_port_base( p_dev, 0 )
) :
- printf( " %s\n",
- _pcps_fw_id( p_dev )
+ printf( " %s, SN: %s\n",
+ _pcps_fw_id( p_dev ), _pcps_sernum( p_dev )
);
}
else
@@ -187,15 +224,15 @@ int main( int argc, char* argv[] )
printf( "\n" );
- // Only clocks with HR time support the extrapolation feature
+ // Start a polling thread and get extrapolated time stamps from the DLL.
+ // Only devices which support PCPS_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
+ // Start the polling thread.
rc = mbg_xhrt_poll_thread_create( &poll_thread_info, dh, 0, 0 );
if ( rc != MBG_SUCCESS )
@@ -218,7 +255,8 @@ int main( int argc, char* argv[] )
TIME_ZONE_INFORMATION tzi;
#endif
- // The frequency of the PC's cycles counter has to be computed.
+ // Calculate the cycles frequency with high accuracy with the help
+ // of the reference clock.
rc = mbg_get_xhrt_cycles_frequency( &poll_thread_info.xhrt_info, &freq_hz );
if ( rc != MBG_SUCCESS )
@@ -244,13 +282,11 @@ int main( int argc, char* argv[] )
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
+
+ // Get PC cycles to compute the access time.
mbg_get_pc_cycles( &cyc_1 );
+ // Request a time stamp
#if USE_PCPS_HR_TIME
rc = mbg_get_xhrt_time_as_pcps_hr_time( &poll_thread_info.xhrt_info, &hrt );
#else
@@ -262,12 +298,12 @@ int main( int argc, char* argv[] )
if ( rc != MBG_SUCCESS )
goto fail;
- // compute the access_time
+ // 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.
+ // Convert PCPS_HR_TIME into a readable time stamp 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 );
diff --git a/c/demo/mbgdevio/xhrtime.exe b/c/demo/mbgdevio/xhrtime.exe
deleted file mode 100644
index 2aafa3a..0000000
--- a/c/demo/mbgdevio/xhrtime.exe
+++ /dev/null
Binary files differ