summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2017-07-26 12:00:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2017-07-26 12:00:00 +0200
commitbd8c46abdb579b8c7871b9ff22a2555c2211e110 (patch)
tree501778613366a983fd1d039e9dc08ce52d3b79bd
parent9fd30c3e28e55927b786f742fee14b3a03c8cd32 (diff)
downloadmbgtools-nbsd-bd8c46abdb579b8c7871b9ff22a2555c2211e110.tar.gz
mbgtools-nbsd-bd8c46abdb579b8c7871b9ff22a2555c2211e110.zip
Update files from mbgtools-nbsd-dev-2017-07-26.tar.gzmbgtools-nbsd-dev-2017-07-26
-rwxr-xr-xsrc/external/bsd/meinberg/Makefile6
-rwxr-xr-xsrc/external/bsd/meinberg/Makefile.inc30
-rwxr-xr-xsrc/external/bsd/meinberg/dist/Makefile21
-rwxr-xr-xsrc/external/bsd/meinberg/dist/README2
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgctrl/Makefile20
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgctrl/mbgctrl.c1580
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgfasttstamp/Makefile13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgfasttstamp/mbgfasttstamp.c117
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbggpscap/Makefile15
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbggpscap/mbggpscap.c138
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbghrtime/Makefile13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbghrtime/mbghrtime.c91
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgirigcfg/Makefile14
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgirigcfg/mbgirigcfg.c215
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/bsd/mbg_bsd.h49
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/bsd/pci_bsd.h13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c56
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.h5
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/amccdefs.h14
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.c1518
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.h1217
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/charcode.h275
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/chk_time_info.c163
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/chk_time_info.h113
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/cnv_wday.h19
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ctry.c1
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ctry.h16
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ctrydttm.c111
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ctrydttm.h24
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/deviohlp.c1717
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/deviohlp.h415
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/gpsdefs.h20024
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/gpsutils.c454
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/gpsutils.h185
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/identdec.h11
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/lan_util.c1883
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/lan_util.h696
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/macioctl.h611
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbg_arch.h50
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbg_cof.h83
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbg_tgt.h675
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgddmsg.h215
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgdevio.c10007
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgdevio.h6971
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgerror.c793
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgerror.h623
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbggenio.h13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbggeo.h147
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgioctl.h555
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgklist.h318
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgmktm.c87
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgmktm.h32
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgmutex.h40
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgpccyc.h71
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgsystm.h494
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgtime.h486
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgutil.c817
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/mbgutil.h484
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/myutil.h59
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/nanotime.c312
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/nanotime.h148
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ntp_shm.c93
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ntp_shm.h151
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/parmgps.c242
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/parmgps.h138
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/parmpcps.c115
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/parmpcps.h159
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pci.h23
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pci_asic.h315
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcidefs.h54
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsdefs.h2047
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsdev.h1081
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c3014
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.h980
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsirq.h93
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpslstr.c259
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpslstr.h353
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.c31
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.h38
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsutil.c162
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/pcpsutil.h115
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/plxdefs.h144
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/ptp_util.h190
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/rsrc.h27
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/str_util.c449
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/str_util.h269
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/timeutil.c164
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/timeutil.h129
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/toolutil.c904
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/toolutil.h358
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/usbdefs.h365
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/use_pack.h6
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/words.h566
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbglib/common/xdevfeat.h893
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgsetsystime/Makefile15
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgsetsystime/mbgsetsystime.c277
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgshowsignal/Makefile13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgshowsignal/mbgshowsignal.c70
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgstatus/Makefile27
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgstatus/mbgstatus.c821
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgsvcd/Makefile24
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgsvcd/mbgsvcd.c458
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgversion.h8
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgxhrtime/Makefile13
-rwxr-xr-xsrc/external/bsd/meinberg/dist/mbgxhrtime/mbgxhrtime.c47
-rwxr-xr-xsrc/external/bsd/meinberg/mbgclock/Makefile1
-rwxr-xr-xsrc/external/bsd/meinberg/mbgclock/Makefile.kmod20
-rwxr-xr-xsrc/external/bsd/meinberg/mbgclock/files.mbgclock13
-rwxr-xr-xsrc/external/bsd/meinberg/mbgclock/mbgclock_main.c1134
109 files changed, 57423 insertions, 14790 deletions
diff --git a/src/external/bsd/meinberg/Makefile b/src/external/bsd/meinberg/Makefile
new file mode 100755
index 0000000..346d99a
--- /dev/null
+++ b/src/external/bsd/meinberg/Makefile
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.2 2010/08/28 15:42:46 kardel Exp $
+
+SUBDIR+= mbgclock
+SUBDIR+= dist
+
+.include <bsd.subdir.mk>
diff --git a/src/external/bsd/meinberg/Makefile.inc b/src/external/bsd/meinberg/Makefile.inc
new file mode 100755
index 0000000..f169b5c
--- /dev/null
+++ b/src/external/bsd/meinberg/Makefile.inc
@@ -0,0 +1,30 @@
+# $NetBSD: Makefile.inc,v 1.5 2010/12/04 23:08:32 christos Exp $
+
+.if !defined(MEINBERG_MAKEFILE_INC)
+MEINBERG_MAKEFILE_INC=yes
+
+USE_FORT?= yes # network client/server
+
+# WARNS?= 5
+
+.include <bsd.own.mk>
+
+IDIST= ${NETBSDSRCDIR}/external/bsd/meinberg/dist
+MBG_LIB_COMMON= ${IDIST}/mbglib/common
+MBG_LIB_BSD= ${IDIST}/mbglib/bsd
+
+CPPFLAGS+=-I${MBG_LIB_COMMON} -I${MBG_LIB_BSD}
+
+.if defined(DEBUG)
+CPPFLAGS+=-DDEBUG=${DEBUG}
+.endif
+
+.if defined(MBG_DEBUG)
+CPPFLAGS+=-DMBG_DEBUG=${MBG_DEBUG}
+.endif
+
+.if exists(${.CURDIR}/../../Makefile.inc)
+.include "${.CURDIR}/../../Makefile.inc"
+.endif
+
+.endif
diff --git a/src/external/bsd/meinberg/dist/Makefile b/src/external/bsd/meinberg/dist/Makefile
index de11e0e..e1a79f8 100755
--- a/src/external/bsd/meinberg/dist/Makefile
+++ b/src/external/bsd/meinberg/dist/Makefile
@@ -1,13 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.1.1.2 2011/07/08 12:10:09 martin TRASH $
+# $Id: Makefile 1.1.1.4 2017/07/26 14:31:06 martin TEST $
#
# Description:
# Makefile for mbgtools which recurses into the subdirectories.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
+# Revision 1.1.1.4 2017/07/26 14:31:06 martin
+# Removed trailing spaces.
+# Revision 1.1.1.3 2011/11/24 13:59:58 martin
# Revision 1.1.1.2 2011/07/08 12:10:09 martin
# Revision 1.1.1.1 2011/03/29 13:54:39 martin
# Revision 1.1.1.6.1.1 2011/03/28 09:36:56 martin
@@ -120,6 +123,7 @@ chk_subdir = $(shell test -f $(strip $(1))/Makefile && echo "$(1)" )
SUBDIRS += $(call chk_subdir, "mbgfasttstamp" )
SUBDIRS += $(call chk_subdir, "mbgsvcd" )
SUBDIRS += $(call chk_subdir, "mbgxhrtime" )
+ SUBDIRS += $(call chk_subdir, "test/mbgtestcalrec" )
SUBDIRS += $(call chk_subdir, "test/mbgtestio" )
SUBDIRS += $(call chk_subdir, "test/mbgtestmmio" )
SUBDIRS += $(call chk_subdir, "test/mbgtestxhrt" )
@@ -157,11 +161,12 @@ SUBDIRS += mbggpscap
SUBDIRS += mbghrtime
SUBDIRS += mbgfasttstamp
# SUBDIRS += mbgxhrtime ## not yet tested
-SUBDIRS += test/mbgtestio
-SUBDIRS += test/mbgtestmmio
-SUBDIRS += test/mbgtestxhrt
-SUBDIRS += test/mbgchksystime
-# SUBDIRS += mbgclock
+SUBDIRS += test/mbgtestcalrec
+# SUBDIRS += test/mbgtestio
+# SUBDIRS += test/mbgtestmmio
+# SUBDIRS += test/mbgtestxhrt
+# SUBDIRS += test/mbgchksystime
+## SUBDIRS += mbgclock #out of tree in this project
.PHONY: all clean distclean install uninstall
all clean distclean install uninstall:
@@ -298,8 +303,8 @@ VPATH = $(BASEDIR)/mbglib/common:$(BASEDIR)/mbglib/bsd
# Check whether thread affinity is supported by the installed pthread library.
# Newer versions of glibc/pthread (at least glibc 2.5) supports this natively.
# Older versions of glibc/pthread (e.g. glibc 2.3) may not support this natively
- # but may provide a NPTL (New Posix Thread Library) library located under separate
- # include and lib paths. We try to detect NPTL and add those paths to the search
+ # but may provide a NPTL (New Posix Thread Library) library located under separate
+ # include and lib paths. We try to detect NPTL and add those paths to the search
# paths only if USE_NTPL has been defined e.g. on the make command line.
# Check whether pthread_getaffinity is supported by the standard pthread.h
diff --git a/src/external/bsd/meinberg/dist/README b/src/external/bsd/meinberg/dist/README
index 4167efb..e6c42d4 100755
--- a/src/external/bsd/meinberg/dist/README
+++ b/src/external/bsd/meinberg/dist/README
@@ -1,4 +1,4 @@
-$Id: README 1.1 2011/03/29 13:35:05 martin TRASH $
+$Id: README 1.1 2011/03/29 13:35:05 martin TEST $
This is the README file for mbgtools-fbsd-dev-2011-02-04
--------------------------------------------------------
diff --git a/src/external/bsd/meinberg/dist/mbgctrl/Makefile b/src/external/bsd/meinberg/dist/mbgctrl/Makefile
index 01e3abf..367960d 100755
--- a/src/external/bsd/meinberg/dist/mbgctrl/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgctrl/Makefile
@@ -1,19 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.7.1.2.1.2 2011/04/20 09:34:06 martin TRASH $
+# $Id: Makefile 1.8 2017/07/05 18:51:21 martin REL_M $
#
# Description:
# Makefile for mbgctrl.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.7.1.2.1.2 2011/04/20 09:34:06 martin
-# Added module lan_util.
-# Revision 1.7.1.2.1.1 2010/09/20 12:06:15 stefan
-# Updated for use with latest base Makefile.
-# Revision 1.7.1.2 2010/08/30 09:05:22 martin
-# Revision 1.7.1.1 2010/08/30 08:20:54 martin
+# Revision 1.8 2017/07/05 18:51:21 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.7 2009/07/24 10:31:16 martin
# Moved declarations to a common file which is now included.
# Revision 1.6 2008/12/22 11:54:31 martin
@@ -39,11 +36,14 @@ MBGDEVIO_SIMPLE = 0
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += mbgutil.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
+OBJS += deviohlp.o
OBJS += gpsutils.o
-OBJS += pcpsutil.o
-OBJS += parmgps.o
-OBJS += parmpcps.o
OBJS += lan_util.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbgctrl/mbgctrl.c b/src/external/bsd/meinberg/dist/mbgctrl/mbgctrl.c
index 18e8644..ea9e250 100755
--- a/src/external/bsd/meinberg/dist/mbgctrl/mbgctrl.c
+++ b/src/external/bsd/meinberg/dist/mbgctrl/mbgctrl.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgctrl.c 1.22.1.7.1.24 2011/07/19 15:49:42 martin TRASH $
+ * $Id: mbgctrl.c 1.23 2017/07/05 19:10:07 martin REL_M $
*
* Description:
* Main file for mbgctrl program which sends commands and
@@ -9,53 +9,18 @@
*
* -----------------------------------------------------------------------
* $Log: mbgctrl.c $
- * Revision 1.22.1.7.1.24 2011/07/19 15:49:42 martin
- * Warn if trying to handle serial port cfg but no serial port is supported.
- * Revision 1.22.1.7.1.23 2011/07/19 13:08:08 martin
- * Revision 1.22.1.7.1.22 2011/07/08 11:20:15 martin
- * More PTP stuff ...
- * Revision 1.22.1.7.1.21 2011/07/08 09:04:46 martin
- * More PTP stuff ...
- * Revision 1.22.1.7.1.20 2011/07/07 15:08:57 martin
- * Started simulation of PTP configuration.
- * Revision 1.22.1.7.1.19 2011/07/06 09:48:01 martin
- * Revision 1.22.1.7.1.18 2011/07/05 15:35:53 martin
- * Modified version handling.
- * Revision 1.22.1.7.1.17 2011/07/05 14:35:17 martin
+ * Revision 1.23 2017/07/05 19:10:07 martin
* New way to maintain version information.
- * Revision 1.22.1.7.1.16 2011/06/27 13:03:19 martin
- * Use O_RDWR flag when opening a device.
- * Revision 1.22.1.7.1.15 2011/05/04 14:53:18 martin
- * Fixed compiler warning.
- * Revision 1.22.1.7.1.14 2011/05/03 15:43:12 martin
- * Revision 1.22.1.7.1.13 2011/04/21 11:09:42 martin
- * Revision 1.22.1.7.1.12 2011/04/21 10:16:03 martin
- * Revision 1.22.1.7.1.11 2011/04/21 08:49:09 martin
- * Revision 1.22.1.7.1.10 2011/04/21 08:40:19 martin
- * Revision 1.22.1.7.1.9 2011/04/21 07:51:05 martin
- * Revision 1.22.1.7.1.8 2011/04/20 16:07:41 martin
- * Revision 1.22.1.7.1.7 2011/04/20 14:49:31 martin
- * Revision 1.22.1.7.1.6 2011/04/20 14:43:00 martin
- * Revision 1.22.1.7.1.5 2011/04/20 14:13:36 martin
- * Revision 1.22.1.7.1.4 2011/04/20 13:32:52 martin
- * Revision 1.22.1.7.1.3 2011/04/20 11:34:28 martin
- * Revision 1.22.1.7.1.2 2011/04/20 11:32:36 martin
- * Revision 1.22.1.7.1.1 2011/04/19 15:31:31 martin
- * Started modifications for PTP unicast master cfg.
- * Revision 1.22.1.7 2011/04/19 10:02:37 martin
- * Syntax fix.
- * Revision 1.22.1.6 2011/04/19 09:57:00 martin
- * Untabbified and removed trailing spaces.
- * Revision 1.22.1.5 2011/03/21 08:32:18 martin
- * Fixed compiler warning.
- * Revision 1.22.1.4 2011/03/03 10:01:00 daniel
- * Support configuring PTP roles.
- * Revision 1.22.1.3 2011/02/18 13:35:59 daniel
- * Revision 1.22.1.2 2011/02/18 13:35:11 daniel
- * Revision 1.22.1.1 2011/02/18 11:27:29 daniel
- * Preliminary support for configuring PTP parameters incl. Unicast
+ * Support build under Windows.
* Bugfix: accept parameter keyword only when substring is found at the
* start of the parameter string.
+ * Support configuring PTP parameters incl. unicast
+ * Warn if trying to handle serial port cfg but no serial port is supported.
+ * Basic support for programmable pulse outputs, including pulse shift feature.
+ * Yet incomplete support for synthesizer output.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.22 2009/09/29 14:58:18 martin
* Unified and simplified parameter evaluation.
* Updated version number to 3.4.0.
@@ -126,15 +91,17 @@
// include Meinberg headers
#include <mbgdevio.h>
+#include <deviohlp.h>
#include <pcpsmktm.h>
#include <pcpsutil.h>
-#include <parmpcps.h>
-#include <parmgps.h>
+#include <cfg_hlp.h>
#include <myutil.h>
#include <gpsutils.h>
#include <cnv_wday.h>
#include <toolutil.h>
+#include <ptp_util.h>
#include <lan_util.h>
+#include <str_util.h>
// include system headers
#include <stdio.h>
@@ -148,14 +115,17 @@
#define MBG_FIRST_COPYRIGHT_YEAR 2001
#define MBG_LAST_COPYRIGHT_YEAR 0 // use default
-static const char *pname = "mbgctrl";
+#define RC_USAGE 1
-#define SIM_PTP_CFG ( 0 && DEBUG ) //##+++
+static const char *pname = "mbgctrl";
static char *dev_name;
static int err_unicast_nsupp;
-static const char str_unknown[] = "(unknown)";
+
+static const char str_spc_not[] = " not";
+static const char str_spc_not_supp[] = " (not supported)";
+static const char str_spc_wildcard[] = " (wildcard)";
static TZDL tzdl_utc = DEFAULT_TZDL_UTC;
static TZDL tzdl_cet_cest = DEFAULT_TZDL_CET_CEST_EN;
@@ -167,158 +137,115 @@ static const char tz_info_cet_cest[] = TZ_INFO_CET_CEST_EN;
static const char tz_info_eet_eest[] = TZ_INFO_EET_EEST_EN;
static const char *mode_names[N_STR_MODE] = DEFAULT_ENG_MODE_NAMES;
-static const char *time_scale_name[N_MBG_TIME_SCALE] = MBG_TIME_SCALE_STRS;
+
+static const char *time_scale_names[N_MBG_TIME_SCALE] = MBG_TIME_SCALE_STRS;
#define _get_time_scale_name( _i ) \
- ( ( (_i) < N_MBG_TIME_SCALE ) ? time_scale_name[_i] : str_unknown )
+ ( ( (_i) < N_MBG_TIME_SCALE ) ? time_scale_names[_i] : str_unknown )
+
+static const char * const pout_mode_names_eng[N_POUT_MODES] = DEFAULT_ENG_POUT_NAMES;
+
+#define _get_pout_mode_name( _i ) \
+ ( ( (_i) < N_POUT_MODES ) ? pout_mode_names_eng[_i] : str_unknown )
static const char no_gps_cmd[] = "does not support GPS commands";
static const char no_tzdl[] = "does not support configurable time zone";
static const char no_tz[] = "does not support time zones";
+static const char no_synth[] = "has no synthesizer output";
static const char no_event_time[] = "does not support event times";
static const char no_enable_flags[] = "does not support enable flags";
static const char no_time_scale[] = "does not support a configurable time scale";
-static const char no_lan_intf[] = "does not provide a LAN interface";
+static const char no_lan_intf[] = "has no LAN interface";
static const char no_ptp[] = "does not provide PTP";
static const char no_cab_len[] = "does not support antenna signal delay compensation";
-#define N_SUPP_UNICAST_MASTER 1
-
-
-#define DEFAULT_MC_SYNC_INTV_MIN -6 // [log2 s]
-#define DEFAULT_MC_SYNC_INTV_MAX 6 // [log2 s]
-
-#define DEFAULT_MC_ANN_INTV_MIN -6 // [log2 s]
-#define DEFAULT_MC_ANN_INTV_MAX 6 // [log2 s]
-
-#define DEFAULT_MC_DELAY_REQ_INTV_MIN -6 // [log2 s]
-#define DEFAULT_MC_DELAY_REQ_INTV_MAX 6 // [log2 s]
-
-
-#define DEFAULT_UC_SYNC_INTV_MIN -6 // [log2 s]
-#define DEFAULT_UC_SYNC_INTV_MAX 6 // [log2 s]
-
-#define DEFAULT_UC_ANN_INTV_MIN -6 // [log2 s]
-#define DEFAULT_UC_ANN_INTV_MAX 6 // [log2 s]
-
-#define DEFAULT_UC_DELAY_REQ_INTV_MIN -6 // [log2 s]
-#define DEFAULT_UC_DELAY_REQ_INTV_MAX 6 // [log2 s]
+/**
+ * @brief A type used to pass print control flags to functions
+ *
+ * @see ::CTRL_FLAG_MASKS
+ */
+typedef int CTRL_FLAGS;
-#define DEFAULT_MC_SYNC_INTV 0 // [log2 s]
-#define DEFAULT_MC_ANN_INTV 1 // [log2 s]
-#define DEFAULT_MC_DELAY_REQ_INTV 3 // [log2 s]
-#define DEFAULT_UC_SYNC_INTV 0 // [log2 s]
-#define DEFAULT_UC_ANN_INTV 1 // [log2 s]
-#define DEFAULT_UC_DELAY_REQ_INTV 3 // [log2 s]
-#define DEFAULT_UC_MSG_DURATION 300 // [s]
+/**
+ * @brief flag masks used with ::CTRL_FLAGS
+ *
+ * @see ::CTRL_FLAGS
+ */
+enum CTRL_FLAG_MASKS
+{
+ CTRL_PRINT_ALL = 0x01,
+ CTRL_PRINT_NEWLINES = 0x02,
+ CTRL_PRINT_IDX = 0x04,
+ CTRL_PRINT_ERR = 0x08,
+ CTRL_PRINT_PLUS = 0x10,
+ CTRL_NOT_SUPP = 0x20
+};
+struct OPT_HANDLER_SPEC_S;
-#define DEFAULT_PTP_CFG_SETTINGS \
-{ \
- PTP_NW_PROT_BIT_UDP_IPV4, /* nw_prot */ \
- 0, /* profile */ \
- 0, /* domain_number */ \
- PTP_DELAY_MECH_BIT_E2E, /* delay_mech */ \
- PTP_ROLE_MULTICAST_SLAVE, /* ptp_role */ \
- 128, /* priority_1 */ \
- 128, /* priority_2 */ \
- 52, /* dflt_clk_class_unsync_cold */ \
- 7, /* dflt_clk_class_unsync_warm */ \
- 6, /* dflt_clk_class_sync_cold */ \
- 6, /* dflt_clk_class_sync_warm */ \
- 0, /* reserved_1 */ \
- 0, /* reserved_2 */ \
- DEFAULT_MC_SYNC_INTV, /* sync_intv [log2 s]*/ \
- DEFAULT_MC_ANN_INTV, /* ann_intv [log2 s] */ \
- DEFAULT_MC_DELAY_REQ_INTV, /* delay_req_intv [log2 s] */ \
- 0, /* upper_bound, not used */ \
- 0, /* lower_bound, not used */ \
- 0, /* reserved_3 */ \
- 0 /* flags */ \
-}
+typedef int HELP_FNC( MBG_DEV_HANDLE, const PCPS_DEV *, const struct OPT_HANDLER_SPEC_S *, CTRL_FLAGS );
+typedef int SET_FNC( MBG_DEV_HANDLE, const char *, int );
+typedef int SHOW_FNC( MBG_DEV_HANDLE, const struct OPT_HANDLER_SPEC_S *, const PCPS_DEV *, const char * );
-//##++++++++++
-#define DEFAULT_PTP_SLAVE_SUPP_FLAGS 0
-#define DEFAULT_PTP_SLAVE_SUPP_NW_PROT 0
-#define DEFAULT_PTP_SLAVE_SUPP_PROFILES 0
-#define DEFAULT_PTP_SLAVE_SUPP_DELAY_MECH 0
-
-#define DEFAULT_PTP_CFG_INFO_SLAVE \
-{ \
- DEFAULT_PTP_CFG_SETTINGS, /* ptp_cfg_settings */ \
- 2, /* ptp_proto_version */ \
- 0, /* reserved_1 */ \
- 0, /* reserved_2 */ \
- DEFAULT_MC_SYNC_INTV_MIN, /* sync_intv_min */ \
- DEFAULT_MC_SYNC_INTV_MAX, /* sync_intv_max */ \
- DEFAULT_MC_ANN_INTV_MIN, /* ann_intv_min */ \
- DEFAULT_MC_ANN_INTV_MIN, /* ann_intv_max */ \
- DEFAULT_MC_DELAY_REQ_INTV_MIN, /* delay_req_intv_min */ \
- DEFAULT_MC_DELAY_REQ_INTV_MIN, /* delay_req_intv_max */ \
- DEFAULT_PTP_SLAVE_SUPP_FLAGS, /* supp_flags */ \
- DEFAULT_PTP_SLAVE_SUPP_NW_PROT, /* supp_nw_prot */ \
- DEFAULT_PTP_SLAVE_SUPP_PROFILES, /* supp_profiles */ \
- DEFAULT_PTP_SLAVE_SUPP_DELAY_MECH /* supp_delay_mech */ \
-}
+typedef struct OPT_HANDLER_SPEC_S
+{
+ const char *cmd_name;
+ MBG_CHK_SUPP_FNC *chk_supp_fnc;
+ HELP_FNC *help_fnc;
+ SET_FNC *set_fnc;
+ SHOW_FNC *show_fnc;
+ const char *cmd_info;
+ const char *not_supp_msg;
+ uint32_t flags; ///< see ::OPT_FLAG_MASKS
-#define DEFAULT_PTP_UC_MASTER_CFG_LIMITS \
-{ \
- 1, /* n_supp_master */ \
- -6, /* sync_intv_min */ \
- 6, /* sync_intv_max */ \
- -6, /* ann_intv_min */ \
- 6, /* ann_intv_max */ \
- -6, /* delay_req_intv_min */ \
- 6, /* delay_req_intv_max */ \
- 0, /* reserved_0 */ \
- 0, /* supp_flags */ \
- 0 /* reserved_1 */ \
-}
+} OPT_HANDLER_SPEC;
-#define DEFAULT_PTP_UC_MASTER_SETTINGS \
-{ \
- "0.0.0.0", /* gm_host */ \
- PTP_CLOCK_ID_WILDCARD, /* gm_clock_id */ \
- PTP_PORT_ID_WILDCARD, /* gm_port_id */ \
- DEFAULT_UC_SYNC_INTV, /* sync_intv [log2 s] */ \
- DEFAULT_UC_ANN_INTV, /* ann_intv [log2 s] */ \
- DEFAULT_UC_DELAY_REQ_INTV, /* delay_req_intv [log2 s] */ \
- 0, /* fix_offset, [ns] */ \
- DEFAULT_UC_MSG_DURATION, /* message_duration [s] */ \
- 0, /* reserved_1 */ \
- 0 /* flags */ \
-}
+enum OPT_FLAG_BITS
+{
+ OPT_SUPP_CMD_IDX_BIT, ///< e.g. COM0=, COM1=, etc. vs. TZ=
+ N_OPT_FLAG_BITS
+};
+enum OPT_FLAG_MASKS
+{
+ OPT_SUPP_CMD_IDX = ( 1UL << OPT_SUPP_CMD_IDX_BIT ) ///< see ::OPT_SUPP_CMD_IDX_BIT
+};
-#define DEFAULT_PTP_UC_MASTER_INFO \
-{ \
- DEFAULT_PTP_UC_MASTER_SETTINGS, /* settings */ \
- 0, /* reserved */ \
- 0 /* flags */ \
-}
+OPT_HANDLER_SPEC ohs_pout =
+{
+ "POUT", // cmd_name
+ NULL, // chk_supp_fnc
+ NULL, // help_fnc
+ NULL, // set_fnc
+ NULL, // show_fnc
+ NULL, // cmd_info
+ NULL, // not_supp_msg
+ OPT_SUPP_CMD_IDX // flags
+};
-#if SIM_PTP_CFG
- static PTP_CFG_INFO sim_ptp_cfg_info = DEFAULT_PTP_CFG_INFO_SLAVE;
- static PTP_UC_MASTER_CFG_LIMITS sim_ptp_uc_master_cfg_limits = DEFAULT_PTP_UC_MASTER_CFG_LIMITS;
- static PTP_UC_MASTER_INFO sim_ptp_uc_master_info[N_SUPP_UNICAST_MASTER] = { DEFAULT_PTP_UC_MASTER_INFO };
-#endif
+typedef struct
+{
+ int indent_1;
+ int indent_2;
+ int indent_3;
+ int comm_col_x;
+} INDENTS;
+const INDENTS usage_indents = { 2, 4, 6, 30 };
+const INDENTS usage_indents_detailed = { 4, 6, 8, 30 };
+const INDENTS show_indents = { 2, 4, 0, 0 };
-typedef struct
-{
- PTP_CFG_INFO ptp_cfg_info;
- PTP_UC_MASTER_CFG_LIMITS ptp_uc_master_cfg_limits;
- ALL_PTP_UC_MASTER_INFO all_ptp_uc_master_info;
-} ALL_PTP_CFG_INFO;
+#define SHOW_INDENT_1 " "
+#define SHOW_INDENT_2 " "
@@ -372,6 +299,9 @@ static const char *nw_prot_short[] = PTP_NW_PROT_STRS_SHORT;
static const char *ptp_roles[] = PTP_ROLE_STRS;
static const char *ptp_roles_short[] = PTP_ROLE_STRS_SHORT;
+static const PTP_CLOCK_ID clock_id_wildcard = PTP_CLOCK_ID_WILDCARD;
+
+//##+++++++++++++++++++
// If unicast is not supported for a PTP device then the device is definitely
// a multicast slave, in which case index 0 returns the correct role name.
#define _ptp_role_name( _i ) \
@@ -381,6 +311,194 @@ static const char *ptp_roles_short[] = PTP_ROLE_STRS_SHORT;
( ( (_i) < N_PTP_ROLES ) ? ptp_roles_short[_i] : str_unknown )
+static const char pout_name_mode[] = "MODE";
+static const char pout_name_len[] = "LEN";
+static const char pout_name_inv[] = "INV";
+static const char pout_name_ois[] = "OIS";
+static const char pout_name_shift[] = "SHIFT";
+
+
+
+
+
+static /*HDR*/
+__attribute__( ( format( printf, 4, 5 ) ) )
+int usage_line( const INDENTS *p_ind, const OPT_HANDLER_SPEC *p_opt,
+ const char *cmd_parm, const char *cmd_comment_fmt, ... )
+{
+ int n = 0;
+
+ // print left margin, if not 0
+ if ( p_ind->indent_1 )
+ n += printf( "%*s", p_ind->indent_1, str_empty );
+
+ // print command name
+ if ( p_opt )
+ n += printf( "%s", p_opt->cmd_name );
+
+ // print the command parameters, if specified
+ if ( cmd_parm )
+ {
+ if ( p_opt && ( p_opt->flags & OPT_SUPP_CMD_IDX ) )
+ n+= printf( "%s", "<n>" );
+
+ n += printf( "=%s", cmd_parm );
+ }
+
+ // print command comment which can be a format string
+ // expecting additional parameters
+ if ( cmd_comment_fmt )
+ {
+ va_list arg_list;
+
+ // indent the comment string
+ if ( p_ind->indent_2 )
+ {
+ int w = p_ind->indent_2 - n;
+
+ while ( w < 0 )
+ w += 8;
+
+ n += printf( "%*s", w, str_empty );
+ }
+
+ va_start( arg_list, cmd_comment_fmt );
+ n += vprintf( cmd_comment_fmt, arg_list );
+ va_end( arg_list );
+ }
+
+ n += printf( "\n" );
+
+ return n;
+
+} // usage_line
+
+
+
+static /*HDR*/
+int print_indent( int i )
+{
+ int n = printf( "%*s", i, str_empty );
+
+ return n;
+
+} // print_indent
+
+
+
+static /*HDR*/
+__attribute__( ( format( printf, 2, 3 ) ) )
+int usage_note( int indent, const char *fmt, ... )
+{
+ // print left margin, if not 0
+ int n = print_indent( indent );
+
+ if ( fmt )
+ {
+ va_list arg_list;
+
+ va_start( arg_list, fmt );
+ n += vprintf( fmt, arg_list );
+ n += printf( "\n" );
+ va_end( arg_list );
+ }
+
+ return n;
+
+} // usage_note
+
+
+
+typedef const char *(STR_FNC)( int idx );
+
+
+static /*HDR*/
+void print_bit_mask_list( const char *info_1, const char *info_2, uint32_t supp_mask,
+ int n_known, const char * const names[], STR_FNC *s_fnc,
+ int inst_idx, CTRL_FLAGS ctrl_flags, const INDENTS *p_ind )
+{
+ const char *str_s_fnc = s_fnc ? s_fnc( inst_idx ) : str_empty;
+
+ print_indent( p_ind->indent_2 );
+
+ if ( ctrl_flags & CTRL_PRINT_ALL )
+ {
+ supp_mask = ( 1UL << n_known ) - 1;
+
+ if ( supp_mask )
+ printf( "Known %s%s: ", info_1, str_s_fnc );
+ else
+ printf( "No %s%s known.", info_1, str_s_fnc );
+ }
+ else
+ {
+ if ( supp_mask )
+ {
+ printf( "%s", info_1 );
+
+ if ( info_2 )
+ printf( " %s", info_2 );
+
+ #if defined( DEBUG )
+ printf( " (%04lX)", (ulong) supp_mask );
+ #endif
+
+ printf( ":" );
+ }
+ else
+ {
+ printf( "No %s.", info_1 );
+
+ if ( info_2 )
+ printf( " %s", info_2 );
+
+ printf( "." );
+ }
+ }
+
+
+ if ( supp_mask )
+ {
+ int n_printed = 0;
+ int i;
+ const char *str_sep = ( ctrl_flags & CTRL_PRINT_PLUS ) ? "+" : ", ";
+
+ for ( i = 0; i < n_known; i++ )
+ {
+ const char *cp;
+
+ if ( ( supp_mask & ( 1UL << i ) ) == 0 )
+ continue;
+
+ if ( names )
+ cp = names[i];
+ else
+ if ( s_fnc )
+ cp = s_fnc( i );
+ else
+ cp = str_empty;
+
+ if ( ctrl_flags & ( CTRL_PRINT_NEWLINES | CTRL_PRINT_IDX ) )
+ {
+ printf( "\n" );
+ print_indent( p_ind->indent_3 );
+
+ if ( ctrl_flags & CTRL_PRINT_IDX )
+ printf( "%i: ", i );
+
+ printf( "%s", cp );
+ }
+ else
+ printf( "%s%s", n_printed ? str_sep : str_empty, cp );
+
+ n_printed++;
+ }
+ }
+
+ printf( "\n" );
+
+} // print_bit_mask_list
+
static /*HDR*/
@@ -397,7 +515,7 @@ int set_tz_code( MBG_DEV_HANDLE dh, PCPS_TZCODE tzcode, const char *s )
{
int rc = mbg_set_tzcode( dh, &tzcode );
- if ( mbg_ioctl_err( rc, "mbg_set_tzcode" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_tzcode" ) )
return rc;
printf( "The clock's time zone setting has been set to %s.\n", s );
@@ -413,7 +531,7 @@ int set_gps_tzdl( MBG_DEV_HANDLE dh, const TZDL *tzdl, const char *info )
{
int rc = mbg_set_gps_tzdl( dh, tzdl );
- if ( mbg_ioctl_err( rc, "set_gps_tzdl" ) )
+ if ( mbg_cond_err_msg( rc, "set_gps_tzdl" ) )
return rc;
if ( info )
@@ -454,7 +572,7 @@ int set_timezone( MBG_DEV_HANDLE dh, const char *tz_name, const PCPS_DEV *p_dev
else
{
printf( "** Unknown timezone name %s\n", tz_name );
- rc = 1;
+ rc = RC_USAGE;
}
if ( tz_info )
@@ -480,7 +598,7 @@ int show_tzdl_offs( MBG_DEV_HANDLE dh, const char *info )
TZDL tzdl;
int rc = mbg_get_gps_tzdl( dh, &tzdl );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_tzdl" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_tzdl" ) )
return rc;
printf( "%s timezone offset: UTC%+lis", info, (long) tzdl.offs );
@@ -513,6 +631,60 @@ int set_tzdl_offs( MBG_DEV_HANDLE dh, const char *s )
static /*HDR*/
+int show_synth( MBG_DEV_HANDLE dh, const char *info )
+{
+ SYNTH synth;
+ int rc = mbg_get_synth( dh, &synth );
+
+ if ( mbg_cond_err_msg( rc, "mbg_get_synth" ) )
+ return rc;
+
+ printf( "%s synthesizer settings: freq %i.%iE%i Hz, phase %+i.%i deg", info,
+ synth.freq / 10, synth.freq % 10, synth.range,
+ synth.phase / 10, abs( synth.phase ) % 10 );
+
+/*
+ int16_t freq; ///< four digits used; scale: 0.1 Hz; e.g. 1234 -> 123.4 Hz
+ int16_t range; ///< scale factor for freq; 0..::MAX_SYNTH_RANGE
+ int16_t phase; ///< -::MAX_SYNTH_PHASE..+::MAX_SYNTH_PHASE; >0 -> pulses later
+*/
+ return MBG_SUCCESS;
+
+} // show_synth
+
+
+
+static /*HDR*/
+int set_synth( MBG_DEV_HANDLE dh, const char *s )
+{
+ SYNTH synth = { 0 };
+ char *cp;
+
+ long freq = strtol( s, &cp, 10 ) * 10;
+
+ if ( *cp == '.' )
+ {
+ long frac = strtol( ++cp, NULL, 10 );
+ if ( frac < 0 || frac > 9 )
+ goto fail;
+
+ freq += frac;
+ }
+
+ synth.freq = (int16_t) freq;
+ synth.range = 0;
+ synth.phase = 0;
+
+ return mbg_set_synth( dh, &synth );
+
+fail:
+ return MBG_ERR_INV_PARM;
+
+} // set_synth
+
+
+
+static /*HDR*/
int show_lan_intf( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info )
{
IP4_SETTINGS ip4_settings;
@@ -520,7 +692,7 @@ int show_lan_intf( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info )
int rc = mbg_get_ip4_settings( dh, &ip4_settings );
- if ( mbg_ioctl_err( rc, "mbg_get_ip4_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ip4_settings" ) )
return rc;
printf( "On-board LAN interface settings:" );
@@ -551,66 +723,24 @@ int show_lan_intf( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info )
static /*HDR*/
-int mbg_get_all_ptp_cfg_info( MBG_DEV_HANDLE dh, ALL_PTP_CFG_INFO *p )
+const char *intv_str( int i )
{
- int rc = MBG_SUCCESS;
+ static char s[20];
- memset( p, 0, sizeof( *p ) );
-
-#if SIM_PTP_CFG
- p->ptp_cfg_info = sim_ptp_cfg_info;
-#else
- rc = mbg_get_ptp_cfg_info( dh, &p->ptp_cfg_info );
-#endif
-
- if ( mbg_ioctl_err( rc, "mbg_get_ptp_cfg_info" ) )
- goto ret;
-
-
- if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST )
- {
- #if SIM_PTP_CFG
- p->ptp_uc_master_cfg_limits = sim_ptp_uc_master_cfg_limits;
- #else
- rc = mbg_get_ptp_uc_master_cfg_limits( dh, &p->ptp_uc_master_cfg_limits );
- #endif
-
- if ( mbg_ioctl_err( rc, "mbg_get_ptp_uc_master_cfg_limits" ) )
- goto ret;
-
-
- if ( p->ptp_uc_master_cfg_limits.n_supp_master > MAX_PARM_PTP_UC_MASTER )
- {
- printf( "The number of PTP unicast masters supported by this device (%i)\n"
- "exceeds the number of unicast masters supporterd by this driver (%i)\n",
- p->ptp_uc_master_cfg_limits.n_supp_master, MAX_PARM_PTP_UC_MASTER );
- rc = MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP;
- goto ret;
- }
+ int abs_i = abs( i );
+ ulong ul;
+ // Currently the valid range is [-7:+7]
+ if ( abs_i > 7 )
+ return str_empty;
- #if SIM_PTP_CFG
- {
- int i;
+ ul = 1UL << abs_i;
- for ( i = 0; i < p->ptp_uc_master_cfg_limits.n_supp_master; i++ )
- {
- PTP_UC_MASTER_INFO_IDX *pi = &p->all_ptp_uc_master_info[i];
- pi->idx = i;
- pi->info = sim_ptp_uc_master_info[i];
- }
- }
- #else
- rc = mbg_get_all_ptp_uc_master_info( dh, p->all_ptp_uc_master_info, &p->ptp_uc_master_cfg_limits );
- #endif
- if ( mbg_ioctl_err( rc, "mbg_get_all_ptp_uc_master_info" ) )
- goto ret;
- }
+ snprintf_safe( s, sizeof( s ), " (%s%lu s)", ( i < 0 ) ? "1/" : str_empty, ul );
-ret:
- return rc;
+ return s;
-} // mbg_get_all_ptp_cfg_info
+} // intv_str
@@ -618,28 +748,34 @@ static /*HDR*/
int show_ptp_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info )
{
ALL_PTP_CFG_INFO all_ptp_cfg_info;
+ PTP_CFG_INFO *pi = &all_ptp_cfg_info.ptp_cfg_info;
+ PTP_CFG_SETTINGS *ps = &pi->settings;
char ws[256];
int unicast_supported;
int idx;
int rc = mbg_get_all_ptp_cfg_info( dh, &all_ptp_cfg_info );
- if ( rc < 0 )
+ if ( mbg_cond_err_msg( rc, "mbg_get_all_ptp_cfg_info" ) )
return rc;
- unicast_supported = ( all_ptp_cfg_info.ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) != 0;
+ unicast_supported = ( pi->supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) != 0;
printf( "\nPTP configuration:\n");
- idx = all_ptp_cfg_info.ptp_cfg_info.settings.ptp_role;
+ idx = ps->ptp_role;
printf( " PTP Role : %s (%s)\n", _ptp_role_name_short( idx ), _ptp_role_name( idx ) );
- idx = all_ptp_cfg_info.ptp_cfg_info.settings.nw_prot;
+ idx = ps->nw_prot;
printf( " Network Protocol: %s (%s)\n", nw_prot_short[idx], nw_prot[idx] );
- printf( " Delay Mechanism : %s\n", delay_mech[all_ptp_cfg_info.ptp_cfg_info.settings.delay_mech] );
- printf( " Domain Number : %d\n", all_ptp_cfg_info.ptp_cfg_info.settings.domain_number );
- printf( " V1 HW Compat. : %d\n", ( all_ptp_cfg_info.ptp_cfg_info.settings.flags & PTP_CFG_MSK_V1_HW_COMPAT ) ? 1 : 0 );
+ printf( " Delay Mechanism : %s\n", delay_mech[ps->delay_mech] );
+ printf( " Domain Number : %d\n", ps->domain_number );
+ printf( " V1 HW Compat. : %d\n", ( ps->flags & PTP_CFG_MSK_V1_HW_COMPAT ) ? 1 : 0 );
+
+ printf( " Sync Msg Intv. : % i%s\n", ps->sync_intv, intv_str( ps->sync_intv) );
+ printf( " Ann. Msg Intv. : % i%s\n", ps->ann_intv, intv_str( ps->ann_intv ) );
+ printf( " Dly. Req. Intv. : % i%s\n", ps->delay_req_intv, intv_str( ps->delay_req_intv ) );
if ( unicast_supported )
{
@@ -648,27 +784,33 @@ int show_ptp_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info )
for ( i = 0; i < p_uc_limits->n_supp_master; i++ )
{
- PTP_UC_MASTER_SETTINGS *p = &all_ptp_cfg_info.all_ptp_uc_master_info[i].info.settings;
+ PTP_UC_MASTER_SETTINGS *p = &all_ptp_cfg_info.all_ptp_uc_master_info_idx[i].info.settings;
- printf( "\nPTP unicast master" );
+ printf( "\nConfigured PTP unicast master" );
if ( p_uc_limits->n_supp_master > 1 )
printf( " %i", i );
+ if ( ps->ptp_role == PTP_ROLE_MULTICAST_SLAVE )
+ printf( " (not used for this role)" );
+
printf( ":\n");
printf( " GM Host: %s\n", p->gm_host );
snprint_octets( ws, sizeof( ws ), p->gm_clock_id.b, sizeof( p->gm_clock_id.b ), MAC_SEP_CHAR, NULL );
- printf( " GM Clock ID: %s\n", ws );
+ printf( " GM Clock ID: %s%s\n", ws,
+ ( memcmp( &p->gm_clock_id, &clock_id_wildcard, sizeof( p->gm_clock_id ) ) == 0 ) ?
+ str_spc_wildcard : str_empty );
- printf( " GM Port ID: %d\n\n", p->gm_port_id );
- printf( " Sync Msg Interval [2^x s]: %i\n", p->sync_intv );
- printf( " Ann. Msg Interval [2^x s]: %i\n", p->ann_intv );
- printf( " DelReq Msg Interval [2^x s]: %i\n", p->delay_req_intv );
- printf( " Message Duration: %i s\n", p->message_duration );
- }
+ printf( " GM Port ID: %d%s\n", p->gm_port_id,
+ ( p->gm_port_id == PTP_PORT_ID_WILDCARD ) ? str_spc_wildcard : str_empty );
+ printf( " Sync Msg Intv. : % i%s\n", p->sync_intv, intv_str( p->sync_intv ) );
+ printf( " Ann. Msg Intv. : % i%s\n", p->ann_intv, intv_str( p->ann_intv ) );
+ printf( " Dly. Req. Intv. : % i%s\n", p->delay_req_intv, intv_str( p->delay_req_intv ) );
+ printf( " Message Duration: %i s\n", p->message_duration );
+ }
}
return MBG_SUCCESS;
@@ -726,9 +868,9 @@ static /*HDR*/
* @param p A pointer to a (char *) which is set to the beginning
* of the value part of a parameter string
*
- * @return <0 Syntax error, i.e. missing colon
- * 0 No error. If parameter has been found then *p set
- * to the parameter value, else to NULL.
+ * @return ::MBG_SUCCESS on success. If parameter has been found then
+ * @p *p is set to the parameter value, else to NULL.
+ * ::MBG_ERR_PARM_FMT if syntax error, i.e. missing colon.
*/
int chk_parm_name( const char *arg, const char *id, char **p )
{
@@ -739,7 +881,7 @@ int chk_parm_name( const char *arg, const char *id, char **p )
cp += strlen( id );
if ( *cp != ':' )
- return -1;
+ return MBG_ERR_PARM_FMT;
cp++;
}
@@ -747,7 +889,7 @@ int chk_parm_name( const char *arg, const char *id, char **p )
if ( p )
*p = cp; // may be NULL
- return 0;
+ return MBG_SUCCESS;
} // chk_parm_name
@@ -821,8 +963,8 @@ int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_m
char *cp;
int idx = chk_parm_name( arg, id, &cp );
- if ( idx < 0 ) // parameter error
- return -1;
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ return idx;
if ( cp ) // parameter found
{
@@ -835,7 +977,7 @@ int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_m
if ( ( tmp < range_min ) || ( tmp > range_max ) )
{
printf( "error: %s %i out of range (%i..%i)\n", info, tmp, range_min, range_max );
- return -1;
+ return MBG_ERR_RANGE;
}
*p = tmp;
@@ -852,7 +994,7 @@ int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_m
static /*HDR*/
int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
{
- ALL_PTP_CFG_INFO all_ptp_cfg_info;
+ ALL_PTP_CFG_INFO all_ptp_cfg_info = { { { 0 } } };
ALL_PTP_CFG_INFO prv_all_ptp_cfg_info;
PTP_CFG_INFO *p_info;
PTP_CFG_SETTINGS *p_settings;
@@ -866,8 +1008,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
int idx;
int unicast_supported;
int uc_master_idx = 0;
- int16_t tmp_int16;
-
+ const char *err_info = NULL;
int rc = mbg_get_all_ptp_cfg_info( dh, &all_ptp_cfg_info );
if ( rc < 0 )
@@ -884,8 +1025,8 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
unicast_supported = ( p_info->supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) != 0;
p_uc_limits = &all_ptp_cfg_info.ptp_uc_master_cfg_limits;
- // The pointers below need to be updated wnenever uc_master_idx is changed
- p_uc_info = &all_ptp_cfg_info.all_ptp_uc_master_info[uc_master_idx].info;
+ // The pointers below need to be updated whenever uc_master_idx is changed
+ p_uc_info = &all_ptp_cfg_info.all_ptp_uc_master_info_idx[uc_master_idx].info;
p_uc_settings = &p_uc_info->settings;
@@ -896,8 +1037,10 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
p_settings->nw_prot = idx;
else
if ( idx < -1 )
+ {
+ err_info = ptp_name_net;
goto fail;
-
+ }
// Delay Mechanism
idx = chk_tbl_parm( arg, ptp_name_del, delay_mech, N_PTP_DELAY_MECH, p_info->supp_delay_mech, "delay mechanism" );
@@ -906,19 +1049,25 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
p_settings->delay_mech = idx;
else
if ( idx < -1 )
+ {
+ err_info = ptp_name_del;
goto fail;
+ }
// Domain Number
idx = chk_parm_name( arg, ptp_name_dom, &cp );
- if ( idx < 0 ) // parameter error
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = ptp_name_dom;
goto fail;
+ }
if ( cp ) // parameter found
{
idx = atoi( cp );
- //##+++++ must check range!!
+ // TODO Must check range!!
p_settings->domain_number = idx;
}
@@ -926,8 +1075,11 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
// V1 Hardware compatibility flag
idx = chk_parm_name( arg, ptp_name_v1, &cp );
- if ( idx < 0 ) // parameter error
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = ptp_name_v1;
goto fail;
+ }
if ( cp ) // parameter found
{
@@ -953,7 +1105,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
//---- unicast stuff ----
// PTP role
- supp_mask = _get_supp_ptp_role_idx_msk( p_info->supp_flags );
+ supp_mask = get_supp_ptp_role_mask( p_info->supp_flags );
idx = chk_tbl_parm( arg, ptp_name_role, ptp_roles_short, N_PTP_ROLES, supp_mask, "PTP role" );
if ( idx >= 0 ) // valid parameter found
@@ -965,14 +1117,20 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
}
else
if ( idx < -1 ) // parameter error
+ {
+ err_info = ptp_name_role;
goto fail;
+ }
// GM Host
idx = chk_parm_name( arg, ptp_name_gmip, &cp );
- if ( idx < 0 ) // parameter error
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = ptp_name_gmip;
goto fail;
+ }
if ( cp ) // parameter found
{
@@ -982,7 +1140,7 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
{
// currently IP addresses are accepted only, so check for
// a valid IPv4 address
- if ( str_to_ip4_addr( &ip4addr, cp ) )
+ if ( str_to_ip4_addr( &ip4addr, cp ) > 0 )
{
snprint_ip4_addr( ws, sizeof( ws ), &ip4addr, NULL );
printf( " GM IP Address: %s\n", ws );
@@ -991,7 +1149,10 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
strcpy( p_uc_settings->gm_host, ws );
}
else
+ {
+ err_info = ptp_name_gmip;
goto fail;
+ }
}
}
@@ -999,8 +1160,11 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
// GM Clock ID
idx = chk_parm_name( arg, ptp_name_gmid, &cp );
- if ( idx < 0 ) // parameter error
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = ptp_name_gmid;
goto fail;
+ }
if ( cp ) // parameter found
{
@@ -1009,21 +1173,27 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
else
{
PTP_CLOCK_ID gm_clock_id;
- idx = str_to_octets( gm_clock_id.b, sizeof( gm_clock_id.b ), cp );
+
+ // Check if specified GM ID is wildcard.
+ if ( *cp == '*' ) // TODO check if next char is separator
+ {
+ gm_clock_id = clock_id_wildcard;
+ idx = sizeof( gm_clock_id );
+ }
+ else
+ idx = str_to_octets( gm_clock_id.b, sizeof( gm_clock_id.b ), cp );
if ( idx != sizeof( gm_clock_id ) )
{
printf( "Syntax error in specified GM clock ID\n" );
goto fail;
}
- else
- {
- p_uc_settings->gm_clock_id = gm_clock_id;
- snprint_octets( ws, sizeof( ws ), p_uc_settings->gm_clock_id.b,
- sizeof( p_uc_settings->gm_clock_id.b ), MAC_SEP_CHAR, NULL );
- printf( " setting GM Clock ID: %s\n", ws );
- }
+ p_uc_settings->gm_clock_id = gm_clock_id;
+
+ snprint_octets( ws, sizeof( ws ), p_uc_settings->gm_clock_id.b,
+ sizeof( p_uc_settings->gm_clock_id.b ), MAC_SEP_CHAR, NULL );
+ printf( " setting GM Clock ID: %s\n", ws );
}
}
@@ -1031,8 +1201,11 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
// GM Target Port ID
idx = chk_parm_name( arg, ptp_name_pid, &cp );
- if ( idx < 0 ) // parameter error
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = ptp_name_pid;
goto fail;
+ }
if ( cp ) // parameter found
{
@@ -1040,95 +1213,87 @@ int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
err_unicast_nsupp = 1;
else
{
- p_uc_settings->gm_port_id = strtoul( cp, NULL, 0 );
- printf( " setting GM port id: %d\n", p_uc_settings->gm_port_id );
+ // Check if specified Port ID is wildcard.
+ if ( *cp == '*' ) // TODO check if next char is separator
+ p_uc_settings->gm_port_id = PTP_PORT_ID_WILDCARD;
+ else
+ p_uc_settings->gm_port_id = (PTP_PORT_ID) strtoul( cp, NULL, 0 );
+
+ printf( " setting GM port id: %d%s\n", p_uc_settings->gm_port_id,
+ ( p_uc_settings->gm_port_id == PTP_PORT_ID_WILDCARD ) ? str_spc_wildcard : str_empty );
}
}
// Sync Message Rate
- idx = chk_int16_parm( arg, ptp_name_smi, &p_uc_settings->sync_intv,
+ idx = chk_int16_parm( arg, ptp_name_smi,
+ ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ?
+ &p_settings->sync_intv : &p_uc_settings->sync_intv,
p_uc_limits->sync_intv_min, p_uc_limits->sync_intv_max,
- unicast_supported, "sync intv." );
+ 1, "sync intv." );
if ( idx < 0 )
+ {
+ err_info = ptp_name_smi;
goto fail;
+ }
// Announce Message Rate
- idx = chk_int16_parm( arg, ptp_name_ami, &p_uc_settings->ann_intv,
+ idx = chk_int16_parm( arg, ptp_name_ami,
+ ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ?
+ &p_settings->ann_intv : &p_uc_settings->ann_intv,
p_uc_limits->ann_intv_min, p_uc_limits->ann_intv_max,
- unicast_supported, "ann. intv." );
+ 1, "ann. intv." );
if ( idx < 0 )
+ {
+ err_info = ptp_name_ami;
goto fail;
+ }
- // Delay Message Rate
- idx = chk_int16_parm( arg, ptp_name_dri, &p_uc_settings->delay_req_intv,
+ // Delay Request Interval Rate
+ idx = chk_int16_parm( arg, ptp_name_dri,
+ ( p_settings->ptp_role == PTP_ROLE_MULTICAST_SLAVE ) ?
+ &p_settings->delay_req_intv : &p_uc_settings->delay_req_intv,
p_uc_limits->delay_req_intv_min, p_uc_limits->delay_req_intv_max,
- unicast_supported, "delay req. intv." );
+ 1, "delay req. intv." );
if ( idx < 0 )
+ {
+ err_info = ptp_name_dri;
goto fail;
+ }
+
// Message Duration
- tmp_int16 = p_uc_settings->message_duration;
- idx = chk_int16_parm( arg, ptp_name_dur, &tmp_int16,
+ idx = chk_int16_parm( arg, ptp_name_dur, (int16_t *) &p_uc_settings->message_duration,
PTP_UC_MSG_DURATION_MIN, PTP_UC_MSG_DURATION_MAX,
unicast_supported, "msg. duration" );
if ( idx < 0 )
+ {
+ err_info = ptp_name_dur;
goto fail;
-
- p_uc_settings->message_duration = tmp_int16;
-
-#if 0 //##++++++++++++
-
- cp = strstr( arg, ptp_name_dur );
-
- if ( cp != NULL )
- {
- l = strlen( ptp_name_dur );
-
- if ( *(cp+l) != ':' )
- goto fail; // parameter syntax error: name not followed by colon
-
- l++;
-
- ptp_unicast_settings.message_duration = atoi( cp+l );
- printf( " setting message duration: %i seconds\n", ptp_unicast_settings.message_duration );
- }
-#endif
-
-
-#if SIM_PTP_CFG
- sim_ptp_cfg_info.settings = *p_settings;
- rc = 0;
-#else
- rc = mbg_set_ptp_cfg_settings( dh, p_settings );
-#endif
-
- if ( mbg_ioctl_err( rc, "mbg_set_ptp_cfg_settings" ) )
- return rc;
+ }
-#if 0 //##+++++++++
- if ( unicast_supported )
+ if ( memcmp( &all_ptp_cfg_info, &prv_all_ptp_cfg_info, sizeof( all_ptp_cfg_info ) ) != 0 )
{
- #if SIM_PTP_CFG
- #error test
- rc = MBG_SUCCESS;
- #else
- rc = mbg_set_ptp_unicast_cfg_settings( dh, &ptp_unicast_settings );
- #endif
- if ( mbg_ioctl_err( rc, "mbg_set_ptp_unicast_cfg_settings" ) )
+ rc = mbg_save_all_ptp_cfg_info( dh, &all_ptp_cfg_info );
+
+ if ( mbg_cond_err_msg( rc, "mbg_save_all_ptp_cfg_info" ) )
return rc;
}
-#endif
return MBG_SUCCESS;
fail:
- printf( "Syntax error in argument!\n" );
+ printf( "Invalid parameter in argument" );
+
+ if ( err_info )
+ printf( " %s", err_info );
+
+ printf( "!\n" );
return MBG_ERR_CFG;
@@ -1181,7 +1346,7 @@ int set_lan_intf( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
int rc = mbg_get_ip4_settings( dh, &prv_ip4_settings );
- if ( mbg_ioctl_err( rc, "mbg_get_ip4_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ip4_settings" ) )
return rc;
if ( strcmp( arg, "DHCP" ) == 0 )
@@ -1262,7 +1427,7 @@ done: // now check static configuration
save:
rc = mbg_set_ip4_settings( dh, &ip4_settings );
- if ( mbg_ioctl_err( rc, "mbg_set_ip4_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_ip4_settings" ) )
return rc;
return MBG_SUCCESS;
@@ -1312,7 +1477,7 @@ int set_gps_pos( MBG_DEV_HANDLE dh, const char *gp )
rc = mbg_set_gps_pos_lla ( dh, new_pos_lla );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_pos_lla" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_pos_lla" ) )
return rc;
printf( "The clock's receiver position has been set to lat=%+.4f, lon=%+.4f, alt=%.0fm\n",
@@ -1353,7 +1518,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
{
rc = mbg_get_time( dh, &u.t );
- if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_time" ) )
return rc;
}
@@ -1439,7 +1604,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
rc = mbg_set_gps_time( dh, &ttm );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_time" ) )
return rc;
}
else // is not a GPS card
@@ -1475,7 +1640,7 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
rc = mbg_set_time( dh, &u.stime );
- if ( mbg_ioctl_err( rc, "mbg_set_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_time" ) )
return rc;
}
@@ -1488,26 +1653,34 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
static /*HDR*/
-void check_setup_receiver_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
- RECEIVER_INFO *p_ri )
+int check_setup_receiver_info( MBG_DEV_HANDLE dh, RECEIVER_INFO *p_ri )
{
+ int rc = MBG_SUCCESS;
+
// Set up the RECEIVER_INFO structure only if this has not been done
// before. Check the ticks_per_sec field to see if the structure
// has already been set up or not.
- if ( p_ri->ticks_per_sec == 0 )
- mbg_setup_receiver_info( dh, p_dev, p_ri );
+ if ( p_ri->ticks_per_sec == 0 && p_ri->model_code == 0 )
+ {
+ rc = mbg_setup_receiver_info( dh, NULL, p_ri );
+ mbg_cond_err_msg( rc, "mbg_setup_receiver_info" );
+ }
+
+ return rc;
} // check_setup_receiver_info
static /*HDR*/
+// returns a negative error code on failure, or the number of supported COM ports on success
int check_get_receiver_port_cfg( MBG_DEV_HANDLE dh, RECEIVER_PORT_CFG *p_rpcfg,
const PCPS_DEV *p_dev, RECEIVER_INFO *p_ri )
{
- int rc = MBG_SUCCESS;
+ int rc = check_setup_receiver_info( dh, p_ri );
- check_setup_receiver_info( dh, p_dev, p_ri );
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
// Set up the RECEIVER_PORT_CFG structure only if this has not been done
// before. Check whether the number of ports is > 0 and the first port's
@@ -1516,10 +1689,13 @@ int check_get_receiver_port_cfg( MBG_DEV_HANDLE dh, RECEIVER_PORT_CFG *p_rpcfg,
( p_rpcfg->pii[0].port_info.port_settings.parm.baud_rate == 0 ) )
{
rc = mbg_get_serial_settings( dh, p_dev, p_rpcfg, p_ri );
-
- mbg_ioctl_err( rc, "mbg_get_serial_settings" );
+ mbg_cond_err_msg( rc, "mbg_get_serial_settings" );
}
+ if ( mbg_rc_is_success( rc ) )
+ rc = p_ri->n_com_ports;
+
+out:
return rc;
} // check_get_receiver_port_cfg
@@ -1638,7 +1814,7 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char *
// load current settings and supported settings
rc = mbg_get_serial_settings( dh, p_dev, &rpcfg, p_ri );
- if ( mbg_ioctl_err( rc, "mbg_get_serial_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_serial_settings" ) )
return rc;
@@ -1676,7 +1852,7 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char *
ul = strtoul( cp, &p_tail, 10 );
if ( p_tail != cp )
- p_ps->str_type = ul;
+ p_ps->str_type = (uint8_t) ul; // TODO check range ?
cp = p_tail;
@@ -1689,7 +1865,7 @@ int save_serial_settings( MBG_DEV_HANDLE dh, unsigned int port_num, const char *
ul = strtoul( cp, &p_tail, 10 );
if ( p_tail != cp )
- p_ps->mode = ul;
+ p_ps->mode = (uint8_t) ul; // TODO check range ?
done_parm_str:
@@ -1706,7 +1882,7 @@ done_parm_str:
// save new parameters
rc = mbg_save_serial_settings( dh, p_dev, &rpcfg, port_num );
- if ( mbg_ioctl_err( rc, "mbg_save_serial_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_save_serial_settings" ) )
return rc;
@@ -1725,6 +1901,479 @@ invalid:
static /*HDR*/
+// returns a negative error code on failure, or the number of supported programmable pulse outputs on success
+int check_get_pout_cfg( MBG_DEV_HANDLE dh, ALL_POUT_INFO_IDX api, RECEIVER_INFO *p_ri )
+{
+ int rc = check_setup_receiver_info( dh, p_ri );
+
+ // Set up the ALL_POUT_INFO_IDX structure only if this has not been done
+ // before. Check whether the number of ports is > 0 and the first port's
+ // baud rate is still 0 to see if the structure has already been set up.
+ if ( ( p_ri->n_prg_out > 0 ) &&
+ ( api[0].pout_info.supp_modes == 0 ) )
+ {
+ rc = mbg_get_gps_all_pout_info( dh, api, p_ri );
+ mbg_cond_err_msg( rc, "mbg_get_gps_all_pout_info" );
+ }
+
+ if ( mbg_rc_is_success( rc ) )
+ rc = p_ri->n_prg_out;
+
+ return rc;
+
+} // check_get_pout_cfg
+
+
+
+static /*HDR*/
+int help_pout_arg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
+ const OPT_HANDLER_SPEC *p_opt, CTRL_FLAGS ctrl_flags )
+{
+ const INDENTS *p_ind = &usage_indents;
+ const INDENTS *p_ind_detailed = &usage_indents_detailed;
+ int rc = MBG_SUCCESS;
+ int i;
+
+ usage_line( p_ind, p_opt, NULL, "Show settings of the programmable output(s)" );
+ usage_line( p_ind, p_opt, "MODE:<m>[,LEN:<l>][,INV:<i>][,OIS:<o>][,SHIFT:<s>]", "Configure programmable output <n>" ); // ### TODO
+
+ printf( "\n"
+ " where:\n" );
+
+ printf( " MODE:<m> Specifies the programmable output mode with index <m>, see mbgctrl -?.\n"
+ " Please note that subsequent parameters may only be appropriate for specific modes.\n\n" );
+
+ printf( " LEN:<l> Specifies the pulse lenght for modes that support this.\n"
+ " <l> is an integer value in 10 ms units, i.e. <l> = 20 yields 200 ms.\n\n" );
+
+ printf( " INV:<i> \"Inverted\" flag specifying if the output level is to be inverted,\n"
+ " if the output supports this.\n"
+ " Values for <i>: 1 invert output level, 0 don't invert.\n\n" );
+
+ printf( " OIS:<o> \"Only If Sync\" flag specifying if the output is to be enabled ONLY\n"
+ " while the device is synchronized, if the output supports this.\n"
+ " Values for <o>: 1 enable this feature, 0 disable this feature\n"
+ " NOTE: This overrides the Enable Flags settings (parameter \"EF\").\n"
+ " The output is enabled ONLY when the device state changes to \"synchronized\"\n"
+ " after power-up, and is disabled again when the device enters holdover mode,\n"
+ " i.e. the reference signal is lost.\n\n" );
+
+ printf( " SHIFT:<s> Specifies a phase shift of the output slope, if the output supports this.\n"
+ " <s> is an integer value, in nanoseconds.\n"
+ " The maximum range is %+li to %+li ns,\n"
+ " corresponding to %+li to %+li ms.\n"
+ " The effective resolution depends on the resolution of the device's internal clock,\n"
+ " which may be e.g. 10 or 20 ns, depending on the device type. See mbgctrl -?.\n\n",
+ (long) DEFAULT_POUT_PULSE_SHIFT_MIN, (long) DEFAULT_POUT_PULSE_SHIFT_MAX,
+ (long) DEFAULT_POUT_PULSE_SHIFT_MIN / 1000L, (long) DEFAULT_POUT_PULSE_SHIFT_MAX / 1000L );
+
+
+ if ( dh != MBG_INVALID_DEV_HANDLE )
+ {
+ RECEIVER_INFO ri = { 0 };
+ ALL_POUT_INFO_IDX api = { { 0 } };
+ int n_pout;
+
+ rc = check_get_pout_cfg( dh, api, &ri );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ n_pout = rc;
+
+ for ( i = 0; i < n_pout; i++ )
+ {
+ const POUT_INFO *pi = &api[i].pout_info;
+
+ printf( "%*s", p_ind->indent_2, str_empty );
+ printf( "Programmable output %i:\n", i );
+
+ print_bit_mask_list( "Supported modes", NULL, pi->supp_modes,
+ N_POUT_MODES, pout_mode_names_eng, NULL, 0,
+ ctrl_flags | CTRL_PRINT_IDX, p_ind_detailed );
+
+ // ### TODO evaluate more properties
+ usage_note( p_ind_detailed->indent_2, "Output level can%s be inverted.",
+ ( pi->flags & POUT_NOT_INVERTIBLE ) ? str_spc_not : str_empty );
+
+ if ( pi->flags & POUT_FIXED_PULSE_LEN )
+ usage_note( p_ind_detailed->indent_2, "Pulse length is fixed and can't be changed." );
+
+ if ( pi->flags & POUT_SUPP_PULSE_SHIFT )
+ usage_note( p_ind_detailed->indent_2, "Output supports pulse shift with resolution %u ns.",
+ pi->pulse_shift_res );
+
+ printf( "\n" );
+ }
+ }
+ else
+ {
+#if 0 // ### TODO
+ print_bit_mask_list( "modes", str_supp_by_dev, tsi.supp_scales,
+ N_MBG_TIME_SCALE, time_scale_names, NULL, ctrl_flags | CTRL_PRINT_IDX );
+#endif
+ }
+
+out:
+ return rc;
+
+} // help_pout_arg
+
+
+
+static /*HDR*/
+int eval_pout( MBG_DEV_HANDLE dh, const char *s, int inst_num )
+{
+ RECEIVER_INFO ri = { 0 };
+ ALL_POUT_INFO_IDX api = { { 0 } };
+ ALL_POUT_INFO_IDX prv_api;
+ POUT_INFO *p_pi = &api[inst_num].pout_info; // ### TODO check inst_num range?
+ POUT_SETTINGS *p_ps = &p_pi->pout_settings;
+ const char *err_info = NULL;
+ char *cp;
+ int n_pout;
+ int idx;
+ int i;
+ int rc = check_get_pout_cfg( dh, api, &ri );
+
+ if ( mbg_cond_err_msg( rc, "check_get_pout_cfg" ) )
+ return rc;
+
+ n_pout = rc; // Contains now the number of programmable pulse outputs
+
+ // save current settings
+ memcpy( prv_api, api, sizeof( prv_api ) );
+
+ // Mode
+ idx = chk_parm_name( s, pout_name_mode, &cp );
+
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = pout_name_mode;
+ goto fail;
+ }
+
+ if ( cp ) // parameter found
+ {
+ idx = atoi( cp );
+
+ if ( idx < 0 || idx >= N_POUT_MODES )
+ {
+ printf( "Programmable output mode %i out of range (0..%i)\n", idx, N_POUT_MODES - 1 );
+ goto fail;
+ }
+
+ if ( !_is_supported( idx, p_pi->supp_modes ) )
+ {
+ printf( "Programmable output mode %i (%s) not supported for output %i\n",
+ idx, _get_pout_mode_name( idx ), inst_num );
+ goto fail;
+ }
+
+ p_ps->mode = idx;
+ printf( "Programmable output mode for output %i changed to %s (%i)\n",
+ inst_num, _get_pout_mode_name( p_ps->mode ), p_ps->mode );
+ }
+
+
+ // Pulse len
+ idx = chk_parm_name( s, pout_name_len, &cp );
+
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = pout_name_len;
+ goto fail;
+ }
+
+ if ( cp ) // parameter found
+ {
+ idx = atoi( cp );
+
+ if ( !_is_supported( p_ps->mode, POUT_MODES_MODE_PARAM_AS_PULSE_LEN ) )
+ {
+ printf( "Pulse length parameter not supported for mode \"%s\"\n",
+ _get_pout_mode_name( p_ps->mode ) );
+ goto fail;
+ }
+
+ if ( idx < 0 || idx >= MAX_POUT_PULSE_LEN )
+ {
+ printf( "Pulse length %i out of range (1..%i)\n", idx, MAX_POUT_PULSE_LEN );
+ goto fail;
+ }
+
+ if ( p_pi->flags & POUT_FIXED_PULSE_LEN )
+ {
+ if ( idx != p_ps->mode_param )
+ printf( "Warning. pulse length %i (%i ms) is fix and can't be changed!\n",
+ p_ps->mode_param, p_ps->mode_param * 10 );
+ }
+ else
+ {
+ p_ps->mode_param = idx;
+ printf( "Pulse length for programmable output %i changed to %i (%i ms)\n",
+ inst_num, p_ps->mode_param, p_ps->mode_param * 10 );
+ }
+ }
+
+
+ // "Inverted" flag
+ idx = chk_parm_name( s, pout_name_inv, &cp );
+
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = pout_name_inv;
+ goto fail;
+ }
+
+ if ( cp ) // parameter found
+ {
+ idx = atoi( cp );
+
+ if ( idx < 0 || idx > 1 )
+ {
+ printf( "Invalid flag value %i for parameter %s, must be 0 or 1\n", idx, pout_name_inv );
+ goto fail;
+ }
+
+ if ( p_pi->flags & POUT_NOT_INVERTIBLE )
+ {
+ if ( idx )
+ {
+ printf( "Warning: Output level can't be inverted for output %i\n", inst_num );
+ goto fail;
+ }
+ }
+
+ if ( idx )
+ p_ps->flags |= POUT_INVERTED;
+ else
+ p_ps->flags &= ~POUT_INVERTED;
+
+ printf( "Output level for output %i%s inverted\n",
+ inst_num, idx ? str_empty : str_spc_not );
+ }
+
+
+ // "Only If Sync" flag
+ idx = chk_parm_name( s, pout_name_ois, &cp );
+
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = pout_name_ois;
+ goto fail;
+ }
+
+ if ( cp ) // parameter found
+ {
+ idx = atoi( cp );
+
+ if ( idx < 0 || idx > 1 )
+ {
+ printf( "Invalid flag value %i for parameter %s, must be 0 or 1\n", idx, pout_name_ois );
+ goto fail;
+ }
+
+ if ( !( p_pi->flags & POUT_SUPP_IF_SYNC_ONLY ) )
+ {
+ if ( idx )
+ {
+ printf( "Warning: \"Only if sync\" flag not supported for output %i\n", inst_num );
+ goto fail;
+ }
+ }
+
+ if ( idx )
+ p_ps->flags |= POUT_IF_SYNC_ONLY;
+ else
+ p_ps->flags &= ~POUT_IF_SYNC_ONLY;
+
+ printf( "\"Only if sync\" flag%s set for output %i\n",
+ idx ? str_empty : str_spc_not, inst_num );
+ }
+
+
+ // "Pulse Shift" parameter
+ idx = chk_parm_name( s, pout_name_shift, &cp );
+
+ if ( mbg_rc_is_error( idx ) ) // parameter error
+ {
+ err_info = pout_name_shift;
+ goto fail;
+ }
+
+ if ( cp ) // parameter found
+ {
+ long pulse_shift = atol( cp );
+
+ if ( !( p_pi->flags & POUT_SUPP_PULSE_SHIFT ) )
+ {
+ printf( "Warning: pulse shift not supported for output %i\n", inst_num );
+ goto fail;
+ }
+
+ if ( !_is_supported( p_ps->mode, POUT_MODES_DATA_PULSE_SHIFT ) )
+ {
+ printf( "Pulse shift not supported for mode \"%s\"\n",
+ _get_pout_mode_name( p_ps->mode ) );
+ goto fail;
+ }
+
+
+ if ( ( pulse_shift < DEFAULT_POUT_PULSE_SHIFT_MIN ) ||
+ ( pulse_shift > DEFAULT_POUT_PULSE_SHIFT_MAX ) )
+ {
+ printf( "Pulse shift %li ns out of range (%+li..%+li ns)\n", pulse_shift,
+ (long) DEFAULT_POUT_PULSE_SHIFT_MIN, (long) DEFAULT_POUT_PULSE_SHIFT_MAX );
+ goto fail;
+ }
+
+ if ( p_pi->pulse_shift_res )
+ {
+ long rem = pulse_shift % p_pi->pulse_shift_res;
+ long l = pulse_shift - rem;
+
+ #if 0 && defined( DEBUG )
+ printf( "DEBUG: s %li, rem %li, l %li\n", pulse_shift, rem, l );
+ #endif
+
+ if ( l != pulse_shift )
+ {
+ printf( "Warning: pulse shift %+li ns not appropriate for resolution %u ns, truncating to %li ns.\n",
+ pulse_shift, p_pi->pulse_shift_res, l );
+ pulse_shift = l;
+ }
+ }
+
+ p_ps->pout_data.pulse_shift = pulse_shift;
+
+ printf( "Pulse shift for programmable output %i changed to %li ns\n",
+ inst_num, (long) p_ps->pout_data.pulse_shift );
+ }
+
+
+ for ( i = 0; i < n_pout; i++ )
+ {
+ POUT_SETTINGS *p_ps = &api[i].pout_info.pout_settings;
+
+ if ( memcmp( p_ps, &prv_api[i].pout_info.pout_settings, sizeof( *p_ps ) ) )
+ {
+ // settings for this output have changed
+ rc = mbg_set_gps_pout_settings( dh, p_ps, i );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+ }
+ }
+
+ return MBG_SUCCESS;
+
+fail:
+ printf( "Invalid parameter in argument" );
+
+ if ( err_info )
+ printf( " %s", err_info );
+
+ printf( "!\n" );
+
+ return MBG_ERR_CFG;
+
+} // eval_pout
+
+
+
+static /*HDR*/
+int show_pout( MBG_DEV_HANDLE dh, const OPT_HANDLER_SPEC *p_opt, const PCPS_DEV *p_devx, const char *cmd_info )
+{
+ const INDENTS *p_ind = &show_indents;
+ RECEIVER_INFO ri = { 0 };
+ ALL_POUT_INFO_IDX api = { { 0 } };
+ int i;
+ int n_pout;
+ int rc = check_get_pout_cfg( dh, api, &ri );
+
+ if ( mbg_cond_err_msg( rc, "check_get_pout_cfg" ) )
+ return rc;
+
+ n_pout = rc; // Contains now the number of programmable pulse outputs
+
+ print_indent( p_ind->indent_1 );
+ printf( "%s:", cmd_info );
+
+ if ( n_pout )
+ {
+ for ( i = 0; i < n_pout; i++ )
+ {
+ const POUT_INFO *pi = &api[i].pout_info;
+ const POUT_SETTINGS *ps = &pi->pout_settings;
+
+ // TODO: Actually the code below only shows the current mode,
+ // and whether the output signal is inverted, or not.
+ // Full featured code should also display additional parameters
+ // depending the selected mode.
+
+ printf( "\n" );
+ print_indent( p_ind->indent_2 );
+ printf( "Output %i: ", i );
+ printf( "%s", _get_pout_mode_name( ps->mode ) );
+
+ // Print pulse len, if supported by the mode
+ if ( _is_supported( ps->mode, POUT_MODES_MODE_PARAM_AS_PULSE_LEN ) )
+ {
+ // pulse len is 10 ms units, so multiply by 10 to get ms
+ printf( ", len %u ms", (unsigned int) ps->mode_param * 10 );
+
+ if ( pi->flags & POUT_FIXED_PULSE_LEN )
+ printf( " (fix)" );
+ }
+
+ // ### FIXME check more mode_param usage, times etc.
+
+ // If outputs can be inverted then this doesn't depend on the current mode
+ if ( !( pi->flags & POUT_NOT_INVERTIBLE ) )
+ printf( ", %sinverted", ( ps->flags & POUT_INVERTED ) ? str_empty : str_not_spc );
+
+
+
+ if ( _is_supported( ps->mode, POUT_MODES_SUPP_IF_SYNC_ONLY ) )
+ {
+ char ws[80];
+ const char *cp = NULL;
+
+ if ( _is_supported( ps->mode, POUT_MODES_TIMEOUT ) &&
+ ( ( pi->flags & POUT_SUPP_IF_SYNC_ONLY ) == 0 ) &&
+ ( ps->timeout != 0 ) )
+ {
+ snprintf_safe( ws, sizeof( ws ), "after timeout %i min ", ps->timeout );
+ cp = ws;
+ }
+
+ if ( pi->flags & POUT_SUPP_IF_SYNC_ONLY )
+ printf( ", %sdisabled %sif sync. lost",
+ ( ps->flags & POUT_IF_SYNC_ONLY ) ? str_empty : str_not_spc,
+ cp ? cp : str_empty );
+ }
+
+
+
+
+ if ( pi->flags & POUT_SUPP_PULSE_SHIFT )
+ if ( _is_supported( ps->mode, POUT_MODES_DATA_PULSE_SHIFT ) )
+ printf( ", shift %li ns, res. %li ns", (long) ps->pout_data.pulse_shift, (long) pi->pulse_shift_res );
+ }
+ }
+ else
+ printf( str_spc_not_supp );
+
+ printf( "\n" );
+
+ return MBG_SUCCESS;
+
+} // show_pout
+
+
+
+static /*HDR*/
void printf_ef( uint16_t flag, const char *info )
{
printf( "%s:%u", info, ( flag == EF_OFF ) ? 0 : 1 );
@@ -1741,7 +2390,7 @@ int show_enable_flags( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *inf
rc = mbg_get_gps_enable_flags( dh, &ef );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_enable_flags" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_enable_flags" ) )
return rc;
printf( "%s enable flags: ", info );
@@ -1809,7 +2458,7 @@ int set_enable_flags( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev
rc = mbg_get_gps_enable_flags( dh, &ef );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_enable_flags" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_enable_flags" ) )
return rc;
// Scan input parameters
@@ -1842,7 +2491,7 @@ int set_enable_flags( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev
save:
rc = mbg_set_gps_enable_flags( dh, &ef );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_enable_flags" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_enable_flags" ) )
return rc;
return MBG_SUCCESS;
@@ -1856,7 +2505,7 @@ int send_gps_cmd( MBG_DEV_HANDLE dh, ushort cmd )
{
int rc = mbg_set_gps_cmd( dh, &cmd );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_cmd" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_cmd" ) )
return rc;
printf( "NOTE: the command code %u has been sent to the GPS clock.\n", cmd );
@@ -1873,7 +2522,7 @@ int show_ant_cable_len( MBG_DEV_HANDLE dh, const char *info )
ANT_CABLE_LEN len;
int rc = mbg_get_gps_ant_cable_len( dh, &len );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_ant_cable_len" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_ant_cable_len" ) )
return rc;
printf( "%s antenna cable length: %u meter(s)", info, len );
@@ -1887,10 +2536,10 @@ int show_ant_cable_len( MBG_DEV_HANDLE dh, const char *info )
static /*HDR*/
int set_ant_cable_len( MBG_DEV_HANDLE dh, const char *s )
{
- ANT_CABLE_LEN len = atol( s );
+ ANT_CABLE_LEN len = (ANT_CABLE_LEN) atol( s ); // TODO check range ?
int rc = mbg_set_gps_ant_cable_len( dh, &len );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_ant_cable_len" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_ant_cable_len" ) )
return rc;
return MBG_SUCCESS;
@@ -1909,15 +2558,15 @@ int set_event_time( MBG_DEV_HANDLE dh, const char *s )
// set event at current system time + number of seconds
event_time = time( NULL ) + strtol( s, NULL, 10 );
- event_ts.sec = event_time; // Unix UTC seconds
+ event_ts.sec = (uint32_t) event_time; // Unix UTC seconds // TODO: check range / conversion
event_ts.frac = 0; // fraction of second, 0xFFFFFFFF == 0.99.. sec
rc = mbg_set_event_time( dh, &event_ts );
- if ( mbg_ioctl_err( rc, "mbg_set_event_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_event_time" ) )
return rc;
- mbg_snprint_hr_tstamp( ws, sizeof( ws ), &event_ts );
+ mbg_snprint_hr_tstamp( ws, sizeof( ws ), &event_ts, 0, 0 ); // raw timestamp?
printf( "Event time set to UTC %s\n", ws );
return MBG_SUCCESS;
@@ -1931,12 +2580,18 @@ int get_n_time_scale( MBG_DEV_HANDLE dh, MBG_TIME_SCALE_INFO *p_tsci )
{
MBG_TIME_SCALE_INFO tsci = { { 0 } };
int rc;
- int i;
- rc = mbg_dev_has_time_scale( dh, &i );
+ rc = mbg_chk_dev_has_time_scale( dh );
- if ( ( rc != MBG_SUCCESS ) || ( i == 0 ) )
- goto done; // failed or not supported
+ if ( mbg_rc_is_error( rc ) )
+ {
+ if ( rc == MBG_ERR_NOT_SUPP_BY_DEV )
+ printf( "This device does not support a configurable time scale.\n" );
+ else
+ mbg_cond_err_msg( rc, "mbg_chk_dev_has_time_scale" );
+
+ goto done;
+ }
rc = mbg_get_time_scale_info( dh, &tsci );
@@ -1961,7 +2616,7 @@ int show_time_scale( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info
rc = mbg_get_time_scale_info( dh, &tsci );
- if ( mbg_ioctl_err( rc, "mbg_get_time_scale_info" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_time_scale_info" ) )
return rc;
printf( "%s time scale index: %u (%s)", info, tsci.settings.scale,
@@ -1983,7 +2638,7 @@ int set_time_scale( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
rc = mbg_get_time_scale_info( dh, &tsci );
- if ( mbg_ioctl_err( rc, "mbg_get_time_scale_info" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_time_scale_info" ) )
return rc;
@@ -2005,7 +2660,7 @@ int set_time_scale( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
rc = mbg_set_time_scale_settings( dh, &tsci.settings );
- if ( mbg_ioctl_err( rc, "mbg_set_time_scale_settings" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_set_time_scale_settings" ) )
return rc;
return MBG_SUCCESS;
@@ -2015,17 +2670,14 @@ int set_time_scale( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev )
static /*HDR*/
-void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
+void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
RECEIVER_PORT_CFG *p_rpcfg )
{
int i;
int n_time_scale;
if ( p_dev )
- {
- check_setup_receiver_info( dh, p_dev, p_ri );
check_get_receiver_port_cfg( dh, p_rpcfg, p_dev, p_ri );
- }
printf( "Usage: %s cmd [dev]\n"
"\n"
@@ -2121,6 +2773,10 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
printf( "\n" );
+ help_pout_arg( dh, p_dev, &ohs_pout, 0 );
+
+ printf( "\n" );
+
printf( " EF show clock's enable flags\n"
" EF=SERIAL:0,PULSES:1,SYNTH:0 modify clock's enable flags\n"
"\n"
@@ -2132,7 +2788,7 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
" 0: only after the card has synchronized to its incoming signal\n"
" 1: immediately after power-up\n"
"\n"
- " Please note enable flags may not be supported by any device\n"
+ " Please note that not every device supports enable flags.\n"
"\n"
);
@@ -2149,7 +2805,7 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
" If no broadcast address is specified then the default broadcast address\n"
" is computed from the IP address and the network mask.\n"
"\n"
- " Please note a LAN interface may not be provided by any board type.\n"
+ " Please note that not every device provides a LAN interface.\n"
" Also, the IP values above are examples only. The real values to be used\n"
" depend on the settings of the network to which the card is attached.\n"
"\n"
@@ -2171,17 +2827,17 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri,
printf( " If the PTP device supports unicast slave mode then the following parameters\n"
" can be specified to configure a unicast master to be queried:\n"
- " PTP=ROLE:<rl>[,GMIP:<ip>][,GMID:<id>][,PID:<po>][,SMI:<sr>][,AMI:<ar>][,DMI:<dr>][,DUR:<du>] set PTP unicast parameters\n"
+ " PTP=ROLE:<rl>[,GMIP:<ip>][,GMID:<id>][,PID:<po>][,SMI:<sr>][,AMI:<ar>][,DRI:<dr>][,DUR:<du>] set PTP unicast parameters\n"
"\n"
" where, e.g.:\n"
" ROLE:MCS specifies \"Multicast Slave\" PTP role\n"
" ROLE:UCS specifies \"Unicast Slave\" PTP role\n"
" GMIP:192.168.1.115 specifies the IP address of the grandmaster\n"
- " GMID:FF:FF:FF:FF:FF:FF:FF:FF specifies the Clock ID of the grandmaster, or '*' as wildcard for all FF\n"
- " PID:1 specifies the target port ID of the grandmaster port to be used, or '*' for wildcard\n"
- " SMI:0 specifies the Sync message interval requested from the grandmaster in 2^x seconds [-6..6]\n"
- " AMI:1 specifies the Announce message interval requested from the grandmaster in 2^x seconds [-6..6]\n"
- " DMI:1 specifies the DelayRequest message interval requested from the grandmaster in 2^x seconds [-6..6]\n"
+ " GMID:FF:FF:FF:FF:FF:FF:FF:FF specifies the Clock ID of the grandmaster, or '*' as wildcard for all 'FF'\n"
+ " PID:1 specifies the target Port ID of the grandmaster port to be used, or '*' for wildcard\n"
+ " SMI:0 specifies the Sync Message Interval requested from the grandmaster in 2^x seconds [-6..6]\n"
+ " AMI:1 specifies the Announce Message Interval requested from the grandmaster in 2^x seconds [-6..6]\n"
+ " DRI:1 specifies the Delay Request Interval requested from the grandmaster in 2^x seconds [-6..6]\n"
" DUR:300 specifies the duration in seconds how long the master shall send messages to the slave until a timeout or renewal occurs\n"
"\n"
);
@@ -2219,27 +2875,27 @@ const char *str_parm_p( const char *s, const char *keyword )
static /*HDR*/
-int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
+int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
RECEIVER_INFO *p_ri, RECEIVER_PORT_CFG *p_rpcfg )
{
const char *sdate = NULL;
const char *stime = NULL;
const char *cp;
int i;
- int rc = 0;
+ int rc = MBG_SUCCESS;
int error_occurred = 0;
must_print_usage = 0;
for ( i = 1; i < argc; i++ )
{
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
error_occurred = 1;
- if ( rc > 0 )
+ if ( rc == RC_USAGE )
must_print_usage = 1;
- rc = 0;
+ rc = MBG_SUCCESS;
if ( ( strcmp( argv[i], "-?" ) == 0 ) ||
( strcmp( argv[i], "-h" ) == 0 ) ||
@@ -2312,11 +2968,16 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
if ( p_dev )
{
- check_setup_receiver_info( dh, p_dev, p_ri );
- if ( p_ri->n_com_ports )
+ int rc = check_get_receiver_port_cfg( dh, p_rpcfg, p_dev, p_ri );
+
+ if ( mbg_rc_is_error( rc ) )
{
- check_get_receiver_port_cfg( dh, p_rpcfg, p_dev, p_ri );
+ // ### TODO print another error?
+ continue;
+ }
+ if ( p_ri->n_com_ports )
+ {
if ( *cp != 0 )
{
printf( "** Invalid parameter: %s\n", argv[i] );
@@ -2343,8 +3004,13 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
char *p_tail;
ulong port_num;
- check_setup_receiver_info( dh, p_dev, p_ri );
- check_get_receiver_port_cfg( dh, p_rpcfg, p_dev, p_ri );
+ rc = check_get_receiver_port_cfg( dh, p_rpcfg, p_dev, p_ri );
+
+ if ( mbg_rc_is_error( rc ) )
+ {
+ // ### TODO print another error?
+ continue;
+ }
port_num = strtoul( cp, &p_tail, 10 );
@@ -2359,7 +3025,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
if ( port_num >= (ulong) p_ri->n_com_ports )
{
- printf( "** COM port number %lu exceeds maximum %u\n",
+ printf( "** COM port number %lu exceeds maximum %u\n",
port_num, p_ri->n_com_ports );
must_print_usage = 1;
continue;
@@ -2378,6 +3044,58 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
}
+ cp = str_parm_p( argv[i], "POUT" );
+
+ if ( cp )
+ {
+ if ( p_dev )
+ {
+ ulong n_pout;
+ ulong pout_num;
+ char *p_tail;
+
+ check_setup_receiver_info( dh, p_ri );
+ n_pout = p_ri->n_prg_out;
+
+ if ( n_pout == 0 )
+ {
+ printf( "Programmable outputs not supported!\n" );
+ continue;
+ }
+
+ pout_num = strtoul( cp, &p_tail, 10 );
+
+ if ( p_tail == cp ) // no POUT number specified
+ {
+ show_pout( dh, &ohs_pout, p_dev, "Current programmable outputs settings" );
+ continue;
+ }
+
+ cp = p_tail;
+
+ if ( pout_num >= n_pout )
+ {
+ printf( "** Programmable output number %lu exceeds maximum %lu\n",
+ pout_num, n_pout );
+ must_print_usage = 1;
+ continue;
+ }
+
+ if ( *cp != '=' )
+ {
+ printf( "** Invalid programmable output specification: %s\n", argv[i] );
+ must_print_usage = 1;
+ continue;
+ }
+
+ rc = eval_pout( dh, ++cp, (unsigned) pout_num );
+ printf( "\n" );
+ show_pout( dh, &ohs_pout, p_dev, "Current programmable outputs settings" );
+ }
+ continue;
+ }
+
+
cp = str_parm_p( argv[i], "EF" );
if ( cp )
@@ -2396,7 +3114,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_enable_flags( dh, ++cp, p_dev );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
printf( "*** Warning: invalid enable flag parameter syntax\n" );
must_print_usage = 1;
@@ -2430,7 +3148,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_time_scale( dh, ++cp, p_dev );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
must_print_usage = 1;
continue;
@@ -2463,7 +3181,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_tzdl_offs( dh, ++cp );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
must_print_usage = 1;
continue;
@@ -2478,6 +3196,39 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
}
+ cp = str_parm_p( argv[i], "SYNTH" );
+
+ if ( cp )
+ {
+ if ( p_dev )
+ {
+ char *info = "Current";
+
+ if ( !_pcps_has_synth( p_dev ) )
+ {
+ err_msg( p_dev, no_synth );
+ continue;
+ }
+
+ if ( *cp == '=' )
+ {
+ rc = set_synth( dh, ++cp );
+
+ if ( mbg_rc_is_error( rc ) )
+ {
+ must_print_usage = 1;
+ continue;
+ }
+
+ info = "New";
+ }
+
+ show_synth( dh, info );
+ }
+ continue;
+ }
+
+
cp = str_parm_p( argv[i], "LAN" );
if ( cp )
@@ -2496,7 +3247,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_lan_intf( dh, ++cp, p_dev );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
must_print_usage = 1;
continue;
@@ -2529,11 +3280,8 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_ptp_cfg( dh, ++cp, p_dev );
- if ( rc < 0 )
- {
- must_print_usage = 1;
+ if ( mbg_rc_is_error( rc ) )
continue;
- }
info = "New";
}
@@ -2561,7 +3309,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
{
rc = set_ant_cable_len( dh, ++cp );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
must_print_usage = 1;
continue;
@@ -2587,9 +3335,9 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
if ( *cp == '=' )
rc = set_event_time( dh, ++cp );
else
- rc = -1;
+ rc = MBG_ERR_PARM_FMT;
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
printf( "*** Warning: invalid event time parameter\n" );
}
else
@@ -2613,13 +3361,18 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p
if ( p_dev )
if ( sdate || stime )
+ {
rc = set_date_time( dh, p_dev, sdate, stime );
+ if ( mbg_rc_is_error( rc ) )
+ error_occurred = 1;
+ }
+
if ( error_occurred )
- return -1;
+ return MBG_ERR_GENERIC;
if ( must_print_usage )
- return 1;
+ return RC_USAGE;
return MBG_SUCCESS;
@@ -2634,6 +3387,7 @@ int main( int argc, char *argv[] )
PCPS_DEV dev = { { 0 } };
PCPS_DEV *pdev = NULL;
MBG_DEV_HANDLE dh = MBG_INVALID_DEV_HANDLE;
+ MBG_DEV_FN tmp_dev_fn;
int rc;
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
@@ -2646,34 +3400,22 @@ int main( int argc, char *argv[] )
// pass a device handle, so commands are not evaluated.
check_cmd_line( argc, argv, dh, NULL, &ri, &rpcfg );
- if ( dev_name )
- dh = open( dev_name, O_RDWR ); // open specific device
- else
- dh = mbg_open_device( 0 ); // open first device found
+ rc = mbg_open_device_by_param( &dh, dev_name, 0, 0,
+ tmp_dev_fn, sizeof( tmp_dev_fn ), 0 );
- if ( dh == MBG_INVALID_DEV_HANDLE )
- {
- //##++++++++++++++++++++++
- if ( dev_name )
- fprintf( stderr, "%s: ", dev_name );
-
- perror( "Unable to open device" );
+ if ( mbg_rc_is_error( rc ) )
goto fail;
- }
+
// get information about the device
- rc = mbg_get_show_dev_info( dh, dev_name, &dev );
+ rc = mbg_get_show_dev_info( dh, NULL, &dev );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
goto fail;
pdev = &dev;
- #if SIM_PTP_CFG
- pdev->cfg.features |= PCPS_HAS_PTP;
- #endif
-
rc = check_cmd_line( argc, argv, dh, pdev, &ri, &rpcfg );
if ( rc < 0 )
@@ -2686,13 +3428,13 @@ int main( int argc, char *argv[] )
mbg_close_device( &dh );
- return 0;
+ return MBG_EXIT_CODE_SUCCESS;
show_usage:
usage( dh, pdev, &ri, &rpcfg );
- return 1;
+ return MBG_EXIT_CODE_USAGE;
fail:
- return 2;
+ return MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbgfasttstamp/Makefile b/src/external/bsd/meinberg/dist/mbgfasttstamp/Makefile
index 92cfa46..4eb3b9c 100755
--- a/src/external/bsd/meinberg/dist/mbgfasttstamp/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgfasttstamp/Makefile
@@ -1,15 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.2.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.3 2017/07/05 18:50:00 martin REL_M $
#
# Description:
# Makefile for mbgfasttstamp.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.2.1.2 2010/08/30 09:05:23 martin
-# Revision 1.2.1.1 2010/08/30 08:21:01 martin
+# Revision 1.3 2017/07/05 18:50:00 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.2 2009/07/24 10:31:16 martin
# Moved declarations to a common file which is now included.
# Revision 1.1 2008/12/22 11:45:01 martin
@@ -18,11 +19,15 @@
#########################################################################
TARGET = mbgfasttstamp
-INST_DIR = /usr/local/bin
+INST_TO_BIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
+OBJS += cfg_hlp.o
OBJS += toolutil.o
+OBJS += mbgerror.o
OBJS += gpsutils.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbgfasttstamp/mbgfasttstamp.c b/src/external/bsd/meinberg/dist/mbgfasttstamp/mbgfasttstamp.c
index f9eefc2..ea5e5a3 100755
--- a/src/external/bsd/meinberg/dist/mbgfasttstamp/mbgfasttstamp.c
+++ b/src/external/bsd/meinberg/dist/mbgfasttstamp/mbgfasttstamp.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgfasttstamp.c 1.6.1.3.1.3 2011/07/05 15:35:54 martin TRASH martin $
+ * $Id: mbgfasttstamp.c 1.7 2017/07/05 18:55:22 martin REL_M $
*
* Description:
* Main file for mbgfasttstamp program which demonstrates how to access
@@ -9,16 +9,16 @@
*
* -----------------------------------------------------------------------
* $Log: mbgfasttstamp.c $
- * Revision 1.6.1.3.1.3 2011/07/05 15:35:54 martin
- * Modified version handling.
- * Revision 1.6.1.3.1.2 2011/07/05 14:35:17 martin
+ * Revision 1.7 2017/07/05 18:55:22 martin
* New way to maintain version information.
- * Revision 1.6.1.3.1.1 2011/05/13 18:52:12 martin
- * Started to support signal handler to catch CTRL-C.
- * Revision 1.6.1.3 2011/01/28 12:04:07 martin
- * Revision 1.6.1.2 2011/01/28 11:51:13 martin
- * Revision 1.6.1.1 2011/01/28 11:17:00 martin
+ * Support build under Windows.
* Abort if MM access not supported on the target OS.
+ * Support signal handler to catch CTRL-C.
+ * Added options to sleep between calls.
+ * Parameters -u and -s imply -c.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.6 2010/05/21 12:54:33 martin
* Print warning if no cycles supported on the target platform
* and thus latencies can not be computed.
@@ -43,13 +43,11 @@
// include Meinberg headers
#include <mbgdevio.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
// include system headers
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#define MBG_MICRO_VERSION 0
@@ -64,20 +62,8 @@ static const char *pname = "mbgfasttstamp";
static int loops;
static int burst_read;
static int read_raw;
-static int exit_requested;
-
-
-
-static /*HDR*/
-void sighandler( int sig )
-{
- #if defined( DEBUG )
- printf( "Caught signal %i, exiting.\n", sig );
- #endif
-
- exit_requested = 1;
-
-} // sighandler
+static long sleep_secs;
+static long sleep_usecs;
@@ -98,10 +84,10 @@ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh )
int rc = read_raw ? mbg_get_fast_hr_timestamp( dh, &ts ) :
mbg_get_fast_hr_timestamp_comp( dh, &ts, &hns_latency );
- if ( mbg_ioctl_err( rc, "mbg_get_fast_hr_timestamp..." ) )
- goto fail;
+ if ( mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp..." ) )
+ return rc;
- mbg_print_hr_timestamp( &ts, hns_latency, NULL, read_raw );
+ mbg_print_hr_timestamp( &ts, hns_latency, NULL, read_raw, 1 ); // raw timestamp?
if ( this_loops > 0 )
this_loops--;
@@ -109,13 +95,16 @@ int show_fast_hr_timestamp( MBG_DEV_HANDLE dh )
if ( this_loops == 0 )
break;
+ if ( sleep_secs )
+ sleep( sleep_secs );
+ else
+ if ( sleep_usecs )
+ usleep( sleep_usecs );
+
// if this_loops is < 0 then loop forever
}
- return 0;
-
-fail:
- return -1;
+ return MBG_SUCCESS;
} // show_fast_hr_timestamp
@@ -145,8 +134,8 @@ int show_fast_hr_timestamp_burst( MBG_DEV_HANDLE dh )
{
int rc = mbg_get_fast_hr_timestamp( dh, &ts[i] );
- if ( mbg_ioctl_err( rc, "mbg_get_fast_hr_timestamp" ) )
- goto fail;
+ if ( mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp" ) )
+ return rc;
}
}
else
@@ -154,21 +143,17 @@ int show_fast_hr_timestamp_burst( MBG_DEV_HANDLE dh )
{
int rc = mbg_get_fast_hr_timestamp_comp( dh, &ts[i], &hns_latency[i] );
- if ( mbg_ioctl_err( rc, "mbg_get_fast_hr_timestamp_comp" ) )
- goto fail;
+ if ( mbg_cond_err_msg( rc, "mbg_get_fast_hr_timestamp_comp" ) )
+ return rc;
}
for ( i = 0; i < this_loops; i++ )
{
PCPS_TIME_STAMP *p_prv_ts = i ? &ts[i - 1] : NULL;
- mbg_print_hr_timestamp( &ts[i], hns_latency[i], p_prv_ts, read_raw );
+ mbg_print_hr_timestamp( &ts[i], hns_latency[i], p_prv_ts, read_raw, 0 ); // raw timestamp?
}
- return 0;
-
-
-fail:
- return -1;
+ return MBG_SUCCESS;
} // show_fast_hr_timestamp_burst
@@ -177,16 +162,13 @@ fail:
static /*HDR*/
int do_mbgfasttstamp( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
- int supported = 0;
- int rc = mbg_dev_has_fast_hr_timestamp( dh, &supported );
-
- if ( mbg_ioctl_err( rc, "mbg_has_fast_hr_timestamp" ) )
- goto done;
+ int rc = mbg_chk_dev_has_fast_hr_timestamp( dh );
- if ( !supported )
+ if ( mbg_rc_is_error( rc ) )
{
- printf( "This device does not support fast (memory mapped) time stamps.\n" );
- goto done;
+ mbg_cond_err_msg_info( rc, "mbg_chk_dev_has_fast_hr_timestamp",
+ "support fast (memory mapped) time stamps" );
+ return rc;
}
if ( burst_read )
@@ -194,13 +176,12 @@ int do_mbgfasttstamp( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
else
show_fast_hr_timestamp( dh );
-done:
- mbg_close_device( &dh );
-
- return rc;
+ return MBG_SUCCESS;
} // do_mbgfasttstamp
+static MBG_DEV_HANDLER_FNC do_mbgfasttstamp;
+
static /*HDR*/
@@ -217,6 +198,8 @@ void usage( void )
mbg_print_opt_info( "-n num", "run num loops" );
mbg_print_opt_info( "-b", "burst read" );
mbg_print_opt_info( "-r", "read raw time stamps, no cycles" );
+ mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" );
+ mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" );
mbg_print_device_options();
puts( "" );
@@ -232,7 +215,7 @@ int main( int argc, char *argv[] )
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
// check command line parameters
- while ( ( c = getopt( argc, argv, "bcn:rh?" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "bcn:rs:u:h?" ) ) != -1 )
{
switch ( c )
{
@@ -252,6 +235,16 @@ int main( int argc, char *argv[] )
read_raw = 1;
break;
+ case 's':
+ sleep_secs = atoi( optarg );
+ loops = -1;
+ break;
+
+ case 'u':
+ sleep_usecs = atoi( optarg );
+ loops = -1;
+ break;
+
case 'h':
case '?':
default:
@@ -262,7 +255,7 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
#if !MBG_TGT_SUPP_MEM_ACC
@@ -270,7 +263,7 @@ int main( int argc, char *argv[] )
return 1;
#endif
- #if !defined( MBG_PC_CYCLES_SUPPORTED )
+ #if !MBG_PC_CYCLES_SUPPORTED
printf( "** Warning: No cycles support to compute real latencies on this platform!\n" );
if ( !read_raw )
@@ -282,12 +275,8 @@ int main( int argc, char *argv[] )
printf( "\n" );
#endif
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbgfasttstamp );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbgfasttstamp, 0 );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbggpscap/Makefile b/src/external/bsd/meinberg/dist/mbggpscap/Makefile
index 6564761..7f511e3 100755
--- a/src/external/bsd/meinberg/dist/mbggpscap/Makefile
+++ b/src/external/bsd/meinberg/dist/mbggpscap/Makefile
@@ -1,15 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.7.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.8 2017/07/05 18:50:00 martin REL_M $
#
# Description:
# Makefile for mbggpscap.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.7.1.2 2010/08/30 09:05:23 martin
-# Revision 1.7.1.1 2010/08/30 08:21:32 martin
+# Revision 1.8 2017/07/05 18:50:00 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.7 2009/07/24 10:31:16 martin
# Moved declarations to a common file which is now included.
# Revision 1.6 2008/12/22 11:56:58 martin
@@ -28,12 +29,16 @@
#########################################################################
TARGET = mbggpscap
-INST_DIR = /usr/local/bin
+INST_TO_BIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
-OBJS += gpsutils.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
+OBJS += gpsutils.o
BASEDIR := ..
include $(BASEDIR)/Makefile
diff --git a/src/external/bsd/meinberg/dist/mbggpscap/mbggpscap.c b/src/external/bsd/meinberg/dist/mbggpscap/mbggpscap.c
index a440f87..80c591e 100755
--- a/src/external/bsd/meinberg/dist/mbggpscap/mbggpscap.c
+++ b/src/external/bsd/meinberg/dist/mbggpscap/mbggpscap.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbggpscap.c 1.10.1.4 2011/07/05 15:35:54 martin TRASH martin $
+ * $Id: mbggpscap.c 1.11 2017/07/05 18:59:14 martin REL_M $
*
* Description:
* Main file for mbggpscap program which demonstrates how to access
@@ -13,15 +13,21 @@
*
* -----------------------------------------------------------------------
* $Log: mbggpscap.c $
- * Revision 1.10.1.4 2011/07/05 15:35:54 martin
- * Modified version handling.
- * Revision 1.10.1.3 2011/07/05 14:35:18 martin
+ * Revision 1.11 2017/07/05 18:59:14 martin
* New way to maintain version information.
- * Revision 1.10.1.2 2010/11/12 12:27:17 martin
+ * Support build under Windows.
+ * Improved code execution paths.
* Improved reading capture events arriving at a high rate.
* Support validation of capture signals arriving at a constant rate.
- * Revision 1.10.1.1 2010/03/10 16:42:33 martin
- * Improved code execution paths.
+ * Fixed a bug when displaying the capture event status. TTM and
+ * PCPS_HR_TIME are using different sets of status flags.
+ * New option -r which displays raw timestamps and raw status.
+ * New option -o which forces usage of old API.
+ * New command line option to clear buffer.
+ * Account for PCPS_HRT_BIN_FRAC_SCALE renamed to MBG_FRAC32_UNITS_PER_SEC.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.10 2009/09/29 15:02:15 martin
* Updated version number to 3.4.0.
* Revision 1.9 2009/07/24 09:50:08 martin
@@ -53,13 +59,11 @@
// include Meinberg headers
#include <mbgdevio.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
// include system headers
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <time.h>
@@ -76,27 +80,17 @@ static const char *pname = "mbggpscap";
static int continuous;
static double nom_cap_intv; // nominal capture interval to check [s]
static double max_cap_jitter; // max allowed jitter [s]
+static int raw;
+static int force_old_api;
+static int clear_buffer;
static int has_been_called;
static int must_check_intv;
+static int query_only;
static ulong err_cnt;
static PCPS_HR_TIME prv_ucap;
-static /*HDR*/
-void show_ucap_status( ulong status )
-{
- // status bit definitions can be found in pcpsdefs.h.
-
- if ( status & PCPS_UCAP_OVERRUN ) // capture events have occurred too fast
- printf( " << CAP OVR" );
-
- if ( status & PCPS_UCAP_BUFFER_FULL ) // capture buffer has been full, events lost
- printf( " << BUF OVR" );
-
-} // show_ucap_status
-
-
static /*HDR*/
void show_ucap_event( const PCPS_HR_TIME *ucap )
@@ -104,16 +98,17 @@ void show_ucap_event( const PCPS_HR_TIME *ucap )
char ws[80];
// Print converted date and time to a string:
- mbg_snprint_hr_time( ws, sizeof( ws ), ucap );
+ mbg_snprint_hr_time( ws, sizeof( ws ), ucap, raw );
// Print the time stamp, ucap->signal contains the channel number:
printf( "New capture: CH%i: %s", ucap->signal, ws );
if ( must_check_intv && has_been_called )
{
+ int jitter_exceeded;
double abs_delta;
double d = ucap->tstamp.sec - prv_ucap.tstamp.sec;
- d += ( (double) ucap->tstamp.frac - prv_ucap.tstamp.frac ) / PCPS_HRT_BIN_FRAC_SCALE;
+ d += ( (double) ucap->tstamp.frac - prv_ucap.tstamp.frac ) / MBG_FRAC32_UNITS_PER_SEC;
printf( " %+.6f", d );
@@ -122,14 +117,28 @@ void show_ucap_event( const PCPS_HR_TIME *ucap )
if ( abs_delta < 0.0 )
abs_delta = -abs_delta;
+ jitter_exceeded = 0;
+
if ( abs_delta > max_cap_jitter )
+ {
+ jitter_exceeded = 1;
err_cnt++;
+ }
if ( err_cnt )
- printf( " ** %lu", err_cnt );
+ printf( " %lu%s", err_cnt, jitter_exceeded ? " <<" : "" );
}
- show_ucap_status( ucap->status );
+ // status bit definitions can be found in pcpsdefs.h.
+
+ if ( raw )
+ printf( ", st: 0x%04X", ucap->status );
+
+ if ( ucap->status & PCPS_UCAP_OVERRUN ) // capture events have occurred too fast
+ printf( " << CAP OVR" );
+
+ if ( ucap->status & PCPS_UCAP_BUFFER_FULL ) // capture buffer has been full, events lost
+ printf( " << BUF OVR" );
prv_ucap = *ucap;
has_been_called = 1;
@@ -158,7 +167,8 @@ void show_gps_ucap( const TTM *ucap )
(ulong) ucap->tm.frac
);
- show_ucap_status( ucap->tm.status );
+ if ( raw )
+ printf( ", st: 0x%04lX", (ulong) ucap->tm.status );
printf( "\n" );
@@ -176,7 +186,7 @@ void check_serial_mode( MBG_DEV_HANDLE dh )
// read the clock's current port settings
int rc = mbg_get_gps_port_parm( dh, &port_parm );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_port_parm" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_port_parm" ) )
return;
@@ -198,7 +208,10 @@ void check_serial_mode( MBG_DEV_HANDLE dh )
rc = mbg_set_gps_port_parm( dh, &port_parm );
- if ( mbg_ioctl_err( rc, "mbg_set_gps_port_parm" ) )
+ // ### TODO FIXME The call above requires root permissions, so
+ // print a more appropriate message if the call failed.
+
+ if ( mbg_cond_err_msg( rc, "mbg_set_gps_port_parm" ) )
return;
printf( "NOTE: the clock's serial port mode has been changed.\n" );
@@ -211,11 +224,13 @@ static /*HDR*/
int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
int rc;
+ int this_clear_buffer = clear_buffer;
must_check_intv = continuous && ( nom_cap_intv != 0 );
has_been_called = 0;
err_cnt = 0;
+
if ( !_pcps_has_ucap( p_dev ) && !_pcps_is_gps( p_dev ) )
{
printf( "This device type does not provide time capture inputs.\n" );
@@ -233,7 +248,7 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
// The new API calls are supported by all supported by all newer boards which
// provide user capture inputs, and also for older boards with a firmware update.
- if ( _pcps_has_ucap( p_dev ) ) // check if the new API is supported
+ if ( !force_old_api && _pcps_has_ucap( p_dev ) ) // check if the new API is supported
{
// The new API provides the following functions:
// mbg_clr_ucap_buff() clear the on-board FIFO buffer
@@ -259,9 +274,16 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
ucap_entries.used, ucap_entries.max );
}
+ if ( this_clear_buffer )
+ {
+ printf( "Clearing on-board FIFO buffer\n" );
+ mbg_clr_ucap_buff( dh );
+ this_clear_buffer = 0;
+ }
+
// If the program is not to run continuously and no
// capture events are available then we're through.
- if ( !continuous && ucap_entries.used == 0 )
+ if ( query_only || ( !continuous && ucap_entries.used == 0 ) )
return 0;
@@ -270,6 +292,10 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
"Reading capture events:\n"
);
+ if ( must_check_intv )
+ if ( max_cap_jitter == 0.0 )
+ max_cap_jitter = 0.1e-6;
+
// Now read out all events from the FIFO and wait
// for new events if the FIFO is empty.
for (;;)
@@ -278,7 +304,7 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
rc = mbg_get_ucap_event( dh, &ucap_event );
- if ( mbg_ioctl_err( rc, "mbg_get_ucap_event" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ucap_event" ) )
break; // an error has occurred
// If a user capture event has been read then it
@@ -296,7 +322,7 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
}
else // use the old API
{
- printf( "Checking for capture events:\n" );
+ printf( "Checking for capture events using the old API:\n" );
for (;;)
{
@@ -304,7 +330,7 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
rc = mbg_get_gps_ucap( dh, &ucap_ttm );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_ucap" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_ucap" ) )
break; // an error has occurred
@@ -330,6 +356,8 @@ int do_mbggpscap( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
} // do_mbggpscap
+static MBG_DEV_HANDLER_FNC do_mbggpscap;
+
static /*HDR*/
@@ -341,8 +369,12 @@ void usage( void )
);
mbg_print_help_options();
mbg_print_opt_info( "-c", "run continuously" );
+ mbg_print_opt_info( "-C", "clear capture buffer" );
mbg_print_opt_info( "-i val", "check interval between captures events [s]" );
mbg_print_opt_info( "-j val", "max allowed jitter of capture interval [s]" );
+ mbg_print_opt_info( "-q", "query FIFO buffer status only" );
+ mbg_print_opt_info( "-r", "show raw (hex) timestamp and status)" );
+ mbg_print_opt_info( "-o", "force usage of old API (for testing only)" );
mbg_print_device_options();
puts( "" );
@@ -358,7 +390,7 @@ int main( int argc, char *argv[] )
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
// check command line parameters
- while ( ( c = getopt( argc, argv, "ci:j:h?" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "cCi:j:qroh?" ) ) != -1 )
{
switch ( c )
{
@@ -366,6 +398,10 @@ int main( int argc, char *argv[] )
continuous = 1;
break;
+ case 'C':
+ clear_buffer = 1;
+ break;
+
case 'i':
nom_cap_intv = atof( optarg );
break;
@@ -374,6 +410,18 @@ int main( int argc, char *argv[] )
max_cap_jitter = atof( optarg );
break;
+ case 'q':
+ query_only = 1;
+ break;
+
+ case 'r':
+ raw = 1;
+ break;
+
+ case 'o':
+ force_old_api = 1;
+ break;
+
case 'h':
case '?':
default:
@@ -384,15 +432,17 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
+ }
+
+ if ( nom_cap_intv != 0.0 )
+ {
+ printf( "Nominal capture interval: %f s\n", nom_cap_intv );
+ printf( "Maximum allowed capture jitter: %f s\n", max_cap_jitter );
}
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbggpscap );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbggpscap, 0 );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbghrtime/Makefile b/src/external/bsd/meinberg/dist/mbghrtime/Makefile
index e332204..48e5a14 100755
--- a/src/external/bsd/meinberg/dist/mbghrtime/Makefile
+++ b/src/external/bsd/meinberg/dist/mbghrtime/Makefile
@@ -1,15 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.7.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.8 2017/07/05 18:50:00 martin REL_M $
#
# Description:
# Makefile for mbghrtime.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.7.1.2 2010/08/30 09:05:23 martin
-# Revision 1.7.1.1 2010/08/30 08:21:39 martin
+# Revision 1.8 2017/07/05 18:50:00 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.7 2009/07/24 10:31:16 martin
# Moved declarations to a common file which is now included.
# Revision 1.6 2008/12/22 11:56:59 martin
@@ -28,11 +29,15 @@
#########################################################################
TARGET = mbghrtime
-INST_DIR = /usr/local/bin
+INST_TO_BIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbghrtime/mbghrtime.c b/src/external/bsd/meinberg/dist/mbghrtime/mbghrtime.c
index c209612..2b0f4cd 100755
--- a/src/external/bsd/meinberg/dist/mbghrtime/mbghrtime.c
+++ b/src/external/bsd/meinberg/dist/mbghrtime/mbghrtime.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbghrtime.c 1.11.1.6 2011/07/05 15:35:54 martin TRASH martin $
+ * $Id: mbghrtime.c 1.12 2017/07/05 19:02:13 martin REL_M $
*
* Description:
* Main file for mbghrtime program which demonstrates how to access
@@ -10,15 +10,15 @@
*
* -----------------------------------------------------------------------
* $Log: mbghrtime.c $
- * Revision 1.11.1.6 2011/07/05 15:35:54 martin
- * Modified version handling.
- * Revision 1.11.1.5 2011/07/05 14:35:18 martin
+ * Revision 1.12 2017/07/05 19:02:13 martin
* New way to maintain version information.
- * Revision 1.11.1.4 2011/01/28 12:04:08 martin
- * Revision 1.11.1.3 2011/01/28 11:52:51 martin
- * Revision 1.11.1.2 2011/01/28 11:51:13 martin
- * Revision 1.11.1.1 2011/01/28 11:17:33 martin
- * Starrted to support raw and burst.
+ * Support build under Windows.
+ * Support raw and burst mode.
+ * New options -s, -u, -v.
+ * Parameters -u and -s imply -c.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.11 2010/05/21 12:54:33 martin
* Print warning if no cycles supported on the target platform
* and thus latencies can not be computed.
@@ -53,15 +53,12 @@
// include Meinberg headers
#include <mbgdevio.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
// include system headers
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h> // gettimeofday()
@@ -77,6 +74,9 @@ static const char *pname = "mbghrtime";
static int loops;
static int burst_read;
static int read_raw;
+static long sleep_secs;
+static long sleep_usecs;
+static int verbose;
@@ -99,10 +99,10 @@ int show_hr_timestamp( MBG_DEV_HANDLE dh )
int rc = read_raw ? mbg_get_hr_time( dh, &ht ) :
mbg_get_hr_time_comp( dh, &ht, &hns_latency );
- if ( mbg_ioctl_err( rc, "mbg_get_hr_time_..." ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_hr_time_..." ) )
goto fail;
- mbg_print_hr_timestamp( &ht.tstamp, hns_latency, p, read_raw );
+ mbg_print_hr_time( &ht, hns_latency, p, read_raw, verbose, verbose );
prv_ht = ht;
p = &prv_ht.tstamp;
@@ -113,6 +113,12 @@ int show_hr_timestamp( MBG_DEV_HANDLE dh )
if ( this_loops == 0 )
break;
+ if ( sleep_secs )
+ sleep( sleep_secs );
+ else
+ if ( sleep_usecs )
+ usleep( sleep_usecs );
+
// if this_loops is < 0 then loop forever
}
@@ -149,7 +155,7 @@ int show_hr_timestamp_burst( MBG_DEV_HANDLE dh )
{
int rc = mbg_get_hr_time( dh, &ht[i] );
- if ( mbg_ioctl_err( rc, "mbg_get_hr_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_hr_time" ) )
goto fail;
}
}
@@ -158,14 +164,14 @@ int show_hr_timestamp_burst( MBG_DEV_HANDLE dh )
{
int rc = mbg_get_hr_time_comp( dh, &ht[i], &hns_latency[i] );
- if ( mbg_ioctl_err( rc, "mbg_get_hr_time_comp" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_hr_time_comp" ) )
goto fail;
}
for ( i = 0; i < this_loops; i++ )
{
PCPS_HR_TIME *p_prv_ht = i ? &ht[i - 1] : NULL;
- mbg_print_hr_timestamp( &ht[i].tstamp, hns_latency[i], &p_prv_ht->tstamp, read_raw );
+ mbg_print_hr_time( &ht[i], hns_latency[i], &p_prv_ht->tstamp, read_raw, verbose, verbose );
}
return 0;
@@ -181,15 +187,15 @@ fail:
static /*HDR*/
int do_mbghrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
- int supported = 0;
- int rc = mbg_dev_has_hr_time( dh, &supported );
-
- if ( mbg_ioctl_err( rc, "mbg_dev_has_hr_time" ) )
- goto done;
+ int rc = mbg_chk_dev_has_hr_time( dh );
- if ( !supported )
+ if ( mbg_rc_is_error( rc ) )
{
- printf( "High resolution time not supported by this device.\n" );
+ if ( rc == MBG_ERR_NOT_SUPP_BY_DEV ) // ### TODO not_supp
+ printf( "High resolution time not supported by this device.\n" );
+ else
+ mbg_cond_err_msg( rc, "mbg_chk_dev_has_hr_time" );
+
goto done;
}
@@ -199,12 +205,12 @@ int do_mbghrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
show_hr_timestamp( dh );
done:
- mbg_close_device( &dh );
-
return rc;
} // do_mbghrtime
+static MBG_DEV_HANDLER_FNC do_mbghrtime;
+
static /*HDR*/
@@ -220,6 +226,9 @@ void usage( void )
mbg_print_opt_info( "-n num", "run num loops" );
mbg_print_opt_info( "-b", "burst read" );
mbg_print_opt_info( "-r", "read raw time stamps, no cycles" );
+ mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" );
+ mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" );
+ mbg_print_opt_info( "-v", "increase verbosity" );
mbg_print_device_options();
puts( "" );
@@ -235,7 +244,7 @@ int main( int argc, char *argv[] )
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
// check command line parameters
- while ( ( c = getopt( argc, argv, "bcn:rh?" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "bcn:rs:u:vh?" ) ) != -1 )
{
switch ( c )
{
@@ -255,6 +264,20 @@ int main( int argc, char *argv[] )
read_raw = 1;
break;
+ case 's':
+ sleep_secs = atoi( optarg );
+ loops = -1;
+ break;
+
+ case 'u':
+ sleep_usecs = atoi( optarg );
+ loops = -1;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
case 'h':
case '?':
default:
@@ -265,11 +288,11 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
- #if !defined( MBG_PC_CYCLES_SUPPORTED )
+ #if !MBG_PC_CYCLES_SUPPORTED
printf( "** Warning: No cycles support to compute real latencies on this platform!\n" );
if ( !read_raw )
@@ -282,12 +305,8 @@ int main( int argc, char *argv[] )
#endif
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbghrtime );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbghrtime, 0 );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbgirigcfg/Makefile b/src/external/bsd/meinberg/dist/mbgirigcfg/Makefile
index fbeb4b5..9639209 100755
--- a/src/external/bsd/meinberg/dist/mbgirigcfg/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgirigcfg/Makefile
@@ -1,15 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.5.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.6 2017/07/05 18:50:01 martin REL_M $
#
# Description:
# Makefile for mbgirigcfg.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.5.1.2 2010/08/30 09:05:23 martin
-# Revision 1.5.1.1 2010/08/30 08:21:45 martin
+# Revision 1.6 2017/07/05 18:50:01 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.5 2009/07/24 10:31:17 martin
# Moved declarations to a common file which is now included.
# Revision 1.4 2008/12/22 11:56:59 martin
@@ -24,11 +25,16 @@
#########################################################################
TARGET = mbgirigcfg
-INST_DIR = /usr/local/sbin
+INST_TO_SBIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += mbgutil.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbgirigcfg/mbgirigcfg.c b/src/external/bsd/meinberg/dist/mbgirigcfg/mbgirigcfg.c
index b55e3f9..c3a89c8 100755
--- a/src/external/bsd/meinberg/dist/mbgirigcfg/mbgirigcfg.c
+++ b/src/external/bsd/meinberg/dist/mbgirigcfg/mbgirigcfg.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgirigcfg.c 1.10.1.12 2011/07/19 12:59:06 martin TRASH $
+ * $Id: mbgirigcfg.c 1.11 2017/07/05 19:05:27 martin REL_M $
*
* Description:
* Main file for the mbgirigcfg program which can be used to configure
@@ -10,26 +10,19 @@
*
* -----------------------------------------------------------------------
* $Log: mbgirigcfg.c $
- * Revision 1.10.1.12 2011/07/19 12:59:06 martin
- * Revision 1.10.1.11 2011/07/07 15:08:35 martin
- * Removed obsolete code.
- * Revision 1.10.1.10 2011/07/06 14:53:50 martin
- * Revision 1.10.1.9 2011/07/05 15:35:54 martin
- * Modified version handling.
- * Revision 1.10.1.8 2011/07/05 14:35:18 martin
+ * Revision 1.11 2017/07/05 19:05:27 martin
* New way to maintain version information.
- * Revision 1.10.1.7 2011/07/05 12:24:58 martin
- * Revision 1.10.1.6 2011/07/04 10:30:29 martin
+ * Support build under Windows.
+ * New parameter -i to let incoming TFOM flag be ignored.
+ * Accept parameter -? to print usage.
* Use getopt() for option processing.
* Support multiple devices.
- * Revision 1.10.1.5 2011/07/01 13:49:47 martin
- * bug fixes.
- * Revision 1.10.1.4 2011/02/02 12:28:44 martin
- * Revision 1.10.1.3 2010/08/30 08:22:24 martin
- * Revision 1.10.1.2 2010/08/19 13:57:42 martin
- * Revision 1.10.1.1 2010/08/19 11:26:12 martin
- * Accept parameter -? to print usage.
- * New parameter -i to let incoming TFOM flag be ignored.
+ * New parameter -X which set ref offs to 'unconfigured'.
+ * Support specification of minutes for ref offset.
+ * Use safe string functions.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.10 2009/09/29 15:02:15 martin
* Updated version number to 3.4.0.
* Revision 1.9 2009/07/24 09:50:08 martin
@@ -62,9 +55,9 @@
// include Meinberg headers
#include <mbgdevio.h>
+#include <mbgutil.h>
#include <mbgtime.h>
#include <pcpsmktm.h>
-#include <pcpsutil.h>
#include <pcpslstr.h>
#include <myutil.h>
#include <toolutil.h>
@@ -74,7 +67,6 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <unistd.h>
#define MBG_MICRO_VERSION 0
@@ -116,7 +108,28 @@ static const char *icode_rx_descr[N_ICODE_RX] = DEFAULT_ICODE_RX_DESCRIPTIONS_EN
static const char *icode_tx_names[N_ICODE_TX] = DEFAULT_ICODE_TX_NAMES;
static const char *icode_tx_descr[N_ICODE_TX] = DEFAULT_ICODE_TX_DESCRIPTIONS_ENG;
-static int max_ref_offs_h = MBG_REF_OFFS_MAX / MINS_PER_HOUR;
+static char str_ref_offs_min[16]; // need to be snprint_hours_mins'ed with -MBG_REF_OFFS_MAX
+static char str_ref_offs_max[16]; // need to be snprint_hours_mins'ed with +MBG_REF_OFFS_MAX
+
+
+
+static /*HDR*/
+size_t snprint_hours_mins( char *s, size_t max_len, long num_minutes )
+{
+ ldiv_t ldt = ldiv( labs( num_minutes ), MINS_PER_HOUR );
+
+ size_t n = mbg_snprintf( s, max_len, "%c%li",
+ ( num_minutes < 0 ) ? '-' : '+', ldt.quot );
+
+ if ( ldt.rem )
+ n += mbg_snprintf( &s[n], max_len - n, ":%02li", ldt.rem );
+
+ n += mbg_snprintf( &s[n], max_len - n, "h" );
+
+ return n;
+
+} // snprint_hours_mins
+
static /*HDR*/
@@ -126,20 +139,11 @@ int get_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev )
int rc_tx = MBG_SUCCESS;
if ( _pcps_is_irig_rx( pdev ) )
- {
- rc_rx = mbg_get_irig_rx_info( dh, &irig_rx_info );
-
- if ( rc_rx == MBG_SUCCESS && _pcps_has_ref_offs( pdev ) )
- rc_rx = mbg_get_ref_offs( dh, &ref_offs );
-
- if ( rc_rx == MBG_SUCCESS && _pcps_has_opt_flags( pdev ) )
- rc_rx = mbg_get_opt_info( dh, &opt_info );
- }
+ rc_rx = mbg_get_all_irig_rx_info( dh, pdev, &irig_rx_info,
+ &ref_offs, &opt_info );
if ( _pcps_has_irig_tx( pdev ) )
- {
rc_tx = mbg_get_irig_tx_info( dh, &irig_tx_info );
- }
if ( rc_rx != MBG_SUCCESS )
@@ -164,20 +168,10 @@ int save_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev )
int rc_tx = MBG_SUCCESS;
if ( _pcps_is_irig_rx( pdev ) )
- {
- rc_rx = mbg_set_irig_rx_settings( dh, &irig_rx_info.settings );
-
- if ( rc_rx == MBG_SUCCESS && _pcps_has_ref_offs( pdev ) )
- rc_rx = mbg_set_ref_offs( dh, &ref_offs );
-
- if ( rc_rx == MBG_SUCCESS && _pcps_has_opt_flags( pdev ) )
- rc_rx = mbg_set_opt_settings( dh, &opt_info.settings );
- }
-
+ rc_rx = mbg_save_all_irig_rx_settings( dh, pdev, &irig_rx_info.settings,
+ &ref_offs, &opt_info.settings );
if ( rc_rx == MBG_SUCCESS && _pcps_has_irig_tx( pdev ) )
- {
rc_tx = mbg_set_irig_tx_settings( dh, &irig_tx_info.settings );
- }
if ( rc_rx != MBG_SUCCESS )
printf( "** Error writing IRIG RX configuration.\n" );
@@ -186,7 +180,7 @@ int save_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev )
printf( "** Error writing IRIG TX configuration.\n" );
if ( rc_rx != MBG_SUCCESS || rc_tx != MBG_SUCCESS )
- return -1;
+ return -1; //##++
return MBG_SUCCESS;
@@ -198,7 +192,8 @@ static /*HDR*/
void print_cfg_rx( const char *info, const char *msg )
{
int idx = irig_rx_info.settings.icode;
- int ref_offs_h = ref_offs / MINS_PER_HOUR;
+ char ws[16];
+ const char *cp = NULL;
printf( "%s %s configuration:\n", info, msg );
@@ -213,10 +208,20 @@ void print_cfg_rx( const char *info, const char *msg )
printf( " " DEFAULT_STR_IRIG_OFFS_EN ": " );
- if ( abs( ref_offs_h ) > max_ref_offs_h )
- printf( "** not configured **\n" );
+ if ( labs( ref_offs ) > MBG_REF_OFFS_MAX )
+ cp = "** not configured **";
else
- printf( "%+i h\n", ref_offs_h );
+ {
+ snprint_hours_mins( ws, sizeof( ws ), ref_offs );
+ cp = ws;
+ }
+
+ printf( "%s", cp );
+
+ if ( ( 1UL << idx ) & MSK_ICODE_RX_HAS_TZI )
+ printf( " (ignored with code %s)", icode_rx_names[idx] );
+
+ printf( "\n" );
if ( opt_info.supp_flags & MBG_OPT_FLAG_STR_UTC )
printf( " " DEFAULT_STR_IRIG_TIMESTR_UTC_EN ": %s\n",
@@ -284,27 +289,69 @@ void set_new_icode_rx( char *s )
static /*HDR*/
void set_new_ref_offs( char *s )
{
- int new_ref_offs_h;
+ long new_ref_offs;
+ char *cp = s;
+ int is_negative = 0;
+
+ // expected format: [-]hh[:mm]
+
+ // In case of e.g. "-0:30" conversion of the first part "-0" would yield
+ // 0 and thus the sign would get lost, so we check the sign explicitly.
+ if ( *cp == '-' )
+ is_negative = 1;
+
+ new_ref_offs = strtol( cp, &cp, 10 );
+
+ if ( cp == s ) // no number found at beginning
+ goto invalid;
- new_ref_offs_h = atoi( s );
+ new_ref_offs *= MINS_PER_HOUR;
- if ( abs( new_ref_offs_h ) > max_ref_offs_h )
+ if ( *cp++ == ':' ) // offset minutes seem to follow
{
- printf( "** New IRIG time offset %ih exceeds range (%+ih..%+ih).\n",
- new_ref_offs_h, -max_ref_offs_h, max_ref_offs_h );
- cfg_err_rx = 1;
+ long tmp = strtol( cp, &cp, 10 );
+
+ // the value behind the colon should always be positive
+ if ( tmp < 0 || tmp >= MINS_PER_HOUR )
+ goto invalid;
+
+ // apply the minutes offset according to the sign
+ new_ref_offs += is_negative ? -tmp : tmp;
}
- else
+
+ if ( labs( new_ref_offs ) > MBG_REF_OFFS_MAX )
{
- ref_offs = new_ref_offs_h * MINS_PER_HOUR;
- changed_cfg_rx = 1;
+ char ws[16];
+ snprint_hours_mins( ws, sizeof( ws ), new_ref_offs );
+ printf( "** New IRIG time offset %s exceeds range (%s..%s).\n",
+ ws, str_ref_offs_min, str_ref_offs_max );
+ goto invalid;
}
+ ref_offs = (MBG_REF_OFFS) new_ref_offs;
+ changed_cfg_rx = 1;
+
+ return;
+
+
+invalid:
+ cfg_err_rx = 1;
+
} // set_new_ref_offs
static /*HDR*/
+void set_ref_offs_not_cfgd( void )
+{
+ ref_offs = MBG_REF_OFFS_NOT_CFGD;
+ changed_cfg_rx = 1;
+
+} // set_ref_offs_not_cfgd
+
+
+
+static /*HDR*/
void set_new_str_utc( char *s )
{
int this_cfg_err;
@@ -461,7 +508,7 @@ void check_cmd_line( int argc, char *argv[], const PCPS_DEV *pdev )
// force checking all parameters since this may be called several times
optind = 1;
- while ( ( c = getopt( argc, argv, "h?" "r:o:u:i:" "t:l:s:" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "h?" "r:o:u:i:X" "t:l:s:" ) ) != -1 )
{
switch ( c )
{
@@ -493,6 +540,11 @@ void check_cmd_line( int argc, char *argv[], const PCPS_DEV *pdev )
set_new_tfom_flag( optarg, &irig_rx_info.settings, &changed_cfg_rx, &cfg_err_rx );
break;
+ case 'X': // set UTC ref_offs to "not configured"
+ if ( chk_dev_rx( pdev ) )
+ set_ref_offs_not_cfgd();
+ break;
+
// IRIG output options
@@ -553,10 +605,20 @@ void usage( void )
printf( "\n" );
printf(
- " -o offs specifies the IRIG input time offset from UTC, in hours,\n"
- " where \"offs\" can be a value in the range %+i..%+i\n"
+ " -o offs specifies the IRIG input time offset from UTC, in hours and optional minute,\n"
+ " where \"offs\" can be a value in the range %s .. %s.\n"
+ " When the device is shipped this parameter is set to \"not configured\"\n"
+ " to prevent the receiver from synchronizing to an IRIG input signal with\n"
+ " unknown UTC offset immediately after installation, which could cause\n"
+ " the system time to be set wrong by the time synchronization software.\n"
"\n",
- -max_ref_offs_h, max_ref_offs_h
+ str_ref_offs_min, str_ref_offs_max
+ );
+
+ printf(
+ " -X set the IRIG input time offset from UTC to \"not configured\".\n"
+ " See also the -o option.\n"
+ "\n"
);
printf(
@@ -576,6 +638,7 @@ void usage( void )
"\n"
);
+
printf(
"Options supported by IRIG transmitters:\n"
"\n"
@@ -634,13 +697,17 @@ int do_mbgirigcfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
printf( "** This device does not provide an IRIG input or output.\n" );
must_print_help_info = 1;
- return rc;
+ goto done;
}
check_cmd_line( glb_argc, glb_argv, p_dev );
if ( cfg_err_rx || cfg_err_tx )
+ {
+ printf( "** Invalid configuration options specified.\n" );
must_print_help_info = 1;
+ goto done;
+ }
if ( changed_cfg_rx || changed_cfg_tx )
{
@@ -653,7 +720,7 @@ int do_mbgirigcfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
rc = save_cfg( dh, p_dev );
- if ( mbg_ioctl_err( rc, "save IRIG configuration" ) )
+ if ( mbg_cond_err_msg( rc, "save IRIG configuration" ) )
goto done;
}
else
@@ -672,6 +739,8 @@ done:
} // do_mbgirigcfg
+static MBG_DEV_HANDLER_FNC do_mbgirigcfg;
+
int main( int argc, char *argv[] )
@@ -680,28 +749,28 @@ int main( int argc, char *argv[] )
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
+ snprint_hours_mins( str_ref_offs_min, sizeof( str_ref_offs_min ), -MBG_REF_OFFS_MAX );
+ snprint_hours_mins( str_ref_offs_max, sizeof( str_ref_offs_max ), MBG_REF_OFFS_MAX );
+
check_cmd_line( argc, argv, NULL );
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
+ // We work with copies of the arguments here since the arguments
+ // are evaluated once more for each device.
glb_argc = argc;
glb_argv = argv;
-
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( glb_argc, glb_argv, optind, do_mbgirigcfg );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( glb_argc, glb_argv, optind, do_mbgirigcfg, 0 );
if ( must_print_help_info )
printf( "For help type \"%s -h\"\n\n", pname );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbglib/bsd/mbg_bsd.h b/src/external/bsd/meinberg/dist/mbglib/bsd/mbg_bsd.h
deleted file mode 100755
index 9efef59..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/bsd/mbg_bsd.h
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: mbg_bsd.h 1.1.1.1 2011/02/04 14:44:33 martin TEST $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * OS dependend definitions/redefinitions for *BSD.
- *
- * -----------------------------------------------------------------------
- * $Log: mbg_bsd.h $
- * Revision 1.1.1.1 2011/02/04 14:44:33 martin
- * Revision 1.1 2011/01/26 16:09:33 martin
- * Initial revision.
- *
- **************************************************************************/
-
-#ifndef _MBG_BSD_H
-#define _MBG_BSD_H
-
-
-/* Other headers to be included */
-
-#include <sys/types.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-
-#ifdef _MBG_BSD
- #define _ext
-#else
- #define _ext extern
-#endif
-
-
-/* Start of header body */
-
-// definitions for clock() support in kernel drivers
-// extern unsigned long volatile jiffies; //##++ this is just a workaround to build without errors
-// #define clock() jiffies
-
-
-/* End of header body */
-
-#undef _ext
-
-#endif /* _MBG_BSD_H */
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/bsd/pci_bsd.h b/src/external/bsd/meinberg/dist/mbglib/bsd/pci_bsd.h
index f032234..7ac79e9 100755
--- a/src/external/bsd/meinberg/dist/mbglib/bsd/pci_bsd.h
+++ b/src/external/bsd/meinberg/dist/mbglib/bsd/pci_bsd.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pci_bsd.h 1.1 2011/01/26 16:09:33 martin TEST $
+ * $Id: pci_bsd.h 1.2 2012/11/07 10:23:46 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,6 +11,8 @@
*
* -----------------------------------------------------------------------
* $Log: pci_bsd.h $
+ * Revision 1.2 2012/11/07 10:23:46 martin
+ * Cleanup.
* Revision 1.1 2011/01/26 16:09:33 martin
* Initial revision.
*
@@ -24,9 +26,6 @@
#include <pcidefs.h>
-#include <mbg_bsd.h>
-//##++ #include <linux/pci.h>
-
#ifdef _PCI_BSD
#define _ext
@@ -37,12 +36,6 @@
/* Start of header body */
-//##++ update comment
-// The pcibios_..() calls use below are not supported by
-// recent 2.6.x kernels. However, those kernels should use
-// the PNP PCI interface anyway, whereas the functions below
-// are only used by non-PNP environments.
-
#define _mbg_pci_find_bios( _p1, _p2, _p3 ) \
( pcibios_present() ? PCI_SUCCESS : PCI_NO_SUCCESS )
diff --git a/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c b/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c
index a1b14d1..1f81e6f 100755
--- a/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c
+++ b/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: rsrc_bsd.c 1.1.1.1 2011/02/07 15:28:32 martin TEST $
+ * $Id: rsrc_bsd.c 1.2 2017/07/06 09:05:19 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,8 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: rsrc_bsd.c $
- * Revision 1.1.1.1 2011/02/07 15:28:32 martin
- * Removed obsolete code; more cleanup required.
+ * Revision 1.2 2017/07/06 09:05:19 martin
+ * Removed obsolete code.
+ * Cleanup.
* Revision 1.1 2011/01/26 16:09:33 martin
* Initial revision.
*
@@ -22,48 +23,16 @@
#undef _RSRC_BSD
-// extern const char *pcps_driver_name;
-
-
-#if 1 //##++ ||defined( KERNEL_VERSION ) && ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 0 ) )
-
- // check_region(), request_region(), and release_region() used in 2.2.x and
- // maybe early 2.4.x kernels have been replaced by more versatile functions.
- // Additionally, there have been defined some macros with the names
- // of the old functions, but calling the new functions. Those macros are still
- // supported by early 2.6.x kernels, but may not be supported anymore in the future.
- // So if those macros don't exist then only the old functions can be used and we
- // use some macros with the new names and call the old functions.
-
- #if !defined( request_region )
- #define __check_region( _rsrc, _start, _n ) \
- check_region( (_start), (_n) )
-
- #define __request_region( _rsrc, _start, _n, _name ) \
- request_region( (_start), (_n), (_name) )
-
- #define __release_region( _rsrc, _start, _n ) \
- release_region( (_start), (_n) )
- #endif
-
-#endif
-
-
/*HDR*/
int rsrc_alloc_ports( ushort port, ushort n, ushort decode_width )
{
-#if 0 //##++
- int rc = __check_region( &ioport_resource, port, n );
-
- if ( rc < 0 )
- return( rc );
+ // Nothing to do; just avoid "unused variable" warnings
+ (void) port;
+ (void) n;
+ (void) decode_width;
-
- __request_region( &ioport_resource, port, n, pcps_driver_name );
-#endif
-
- return 0;
+ return 0; // success
} // rsrc_alloc_ports
@@ -72,11 +41,10 @@ int rsrc_alloc_ports( ushort port, ushort n, ushort decode_width )
/*HDR*/
void rsrc_dealloc_ports( ushort port, ushort n )
{
-#if 0 //##++
- __release_region( &ioport_resource, port, n );
-#endif
+ // Nothing to do; just avoid "unused variable" warnings
+ (void) port;
+ (void) n;
} // rsrc_dealloc_ports
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.h b/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.h
index ba1af48..80ea291 100755
--- a/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.h
+++ b/src/external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: rsrc_bsd.h 1.1 2011/01/26 16:09:34 martin TEST $
+ * $Id: rsrc_bsd.h 1.2 2012/11/07 10:24:10 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,8 @@
*
* -----------------------------------------------------------------------
* $Log: rsrc_bsd.h $
+ * Revision 1.2 2012/11/07 10:24:10 martin
+ * Removed obsolete include.
* Revision 1.1 2011/01/26 16:09:34 martin
* Initial revision.
*
@@ -21,7 +23,6 @@
/* Other headers to be included */
-#include <mbg_bsd.h>
#include <rsrc.h>
#include <words.h>
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/amccdefs.h b/src/external/bsd/meinberg/dist/mbglib/common/amccdefs.h
index 1d68cbe..3aeba78 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/amccdefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/amccdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: amccdefs.h 1.2 2007/06/06 10:16:53 martin REL_M $
+ * $Id: amccdefs.h 1.3 2017/05/10 15:21:33 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,8 @@
*
* -----------------------------------------------------------------------
* $Log: amccdefs.h $
+ * Revision 1.3 2017/05/10 15:21:33 martin
+ * Tiny cleanup.
* Revision 1.2 2007/06/06 10:16:53 martin
* Moved some IRQ bit masks here.
* Revision 1.1 2000/07/20 09:19:39Z MARTIN
@@ -33,6 +35,10 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// The following operation registers are implemented
// in the S5933. The registers can be accessed via port
@@ -88,12 +94,6 @@
#undef _ext
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.c b/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.c
new file mode 100755
index 0000000..4a9c674
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.c
@@ -0,0 +1,1518 @@
+
+/**************************************************************************
+ *
+ * $Id: cfg_hlp.c 1.2 2017/07/05 12:17:38 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg device configuration helper functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: cfg_hlp.c $
+ * Revision 1.2 2017/07/05 12:17:38 martin
+ * Support functions for TLV, IMS, GPIO, and
+ * mbg_snprint_revision() provided by philipp.
+ * Support functions for network configuration,
+ * NTP configuration, ALL_UCAP stuff, SNMP and
+ * MONITORING, as well as ALL_PTP_V2_COMMON_DATASETS
+ * and ALL_PTP_V1_COMMON_DATASETS provided by thomas-b.
+ * Support functions for xmulti_ref and IO PORT stuff
+ * provided by philipp and thomas-b.
+ * More common GNSS support.
+ * New functions alloc_dev_hw_id() and chk_free_dev_hw_id().
+ * Tried portable printing of int64_t types.
+ * Account for frac_sec_from_bin() obsoleted by
+ * bin_frac_32_to_dec_frac().
+ * Revision 1.1 2014/04/25 09:14:49 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _CFG_HLP
+ #include <cfg_hlp.h>
+#undef _CFG_HLP
+
+#include <mbgerror.h>
+#include <timeutil.h>
+#include <str_util.h>
+#include <myutil.h>
+#include <mbgtime.h>
+
+#if defined( _PRELIMINARY_CODE )
+ #include <mbgmktm.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a software revision name should be displayed
+ *
+ * The software revision name is usually empty, except if the
+ * firmware is a customized version, in which case the field
+ * contains an identifier string.
+ *
+ * There are some standard firmware versions where this string
+ * is not empty but padded with spaces, etc., so we try to
+ * clean this up and display the string properly, if appropriate.
+ *
+ * @param[in,out] p The ::SW_REV name to check
+ * @param[in] verbose The app's verbosity level
+ *
+ * @return != 0 if SW name should be displayed
+ */
+int chk_sw_rev_name( SW_REV *p, int verbose )
+{
+ if ( verbose > 1 ) // more than just verbose
+ return 1; // just return raw string
+
+ trim_whitespace( p->name );
+
+ // Some firmware versions have "CC_STANDARD" in their standard version,
+ // which doesn't provide any valuable information.
+ // We discard this by default.
+ if ( strstr( p->name, "CC_STANDARD" ) )
+ p->name[0] = 0;
+
+ if ( verbose )
+ return 1; // calling app should display string, even if empty
+
+ // calling app should display string only if not empty
+ return strlen( p->name ) != 0;
+
+} // chk_sw_rev_name
+
+
+
+/*HDR*/
+int get_str_idx( const char *search,
+ const char *str_table[],
+ int n_entries )
+{
+ int i;
+
+ for ( i = 0; i < n_entries; i++ )
+ if ( strcmp( search, str_table[i] ) == 0 )
+ return i;
+
+ return -1;
+
+} // get_str_idx
+
+
+
+/*HDR*/
+int get_baud_rate_idx( BAUD_RATE baud_rate )
+{
+ int i;
+
+ for ( i = 0; i < N_MBG_BAUD_RATES; i++ )
+ if ( baud_rate == mbg_baud_rate[i] )
+ return i;
+
+ return -1;
+
+} // get_baud_rate_idx
+
+
+
+/*HDR*/
+int get_framing_idx( const char *framing )
+{
+ return get_str_idx( framing, mbg_framing_str, N_MBG_FRAMINGS );
+
+} // get_framing_idx
+
+
+
+/*HDR*/
+void port_settings_from_port_parm_mode(
+ PORT_SETTINGS *p_ps,
+ uint8_t pp_mode,
+ int str_type_cap
+ )
+{
+ if ( pp_mode >= STR_UCAP )
+ {
+ p_ps->str_type = str_type_cap;
+ p_ps->mode = ( pp_mode == STR_UCAP ) ? STR_AUTO : STR_ON_REQ;
+ }
+ else
+ {
+ p_ps->str_type = 0;
+ p_ps->mode = pp_mode;
+ }
+
+} // port_settings_from_port_parm_mode
+
+
+
+/*HDR*/
+void port_parm_mode_from_port_settings(
+ uint8_t *pp_mode,
+ const PORT_SETTINGS *p_ps,
+ int str_type_cap
+ )
+{
+ if ( p_ps->str_type == str_type_cap )
+ *pp_mode = ( p_ps->mode == STR_ON_REQ ) ? STR_UCAP_REQ : STR_UCAP;
+ else
+ *pp_mode = p_ps->mode;
+
+} // port_parm_mode_from_port_settings
+
+
+
+/*HDR*/
+void port_settings_from_port_parm(
+ PORT_SETTINGS *p_ps,
+ int port_num,
+ const PORT_PARM *p_pp,
+ int cap_str_idx
+)
+{
+ p_ps->parm = p_pp->com[port_num];
+
+ port_settings_from_port_parm_mode( p_ps, p_pp->mode[port_num],
+ cap_str_idx );
+
+} // port_info_from_port_parm
+
+
+
+/*HDR*/
+void port_parm_from_port_settings(
+ PORT_PARM *p_pp,
+ int port_num,
+ const PORT_SETTINGS *p_ps,
+ int cap_str_idx
+)
+{
+ p_pp->com[port_num] = p_ps->parm;
+
+ port_parm_mode_from_port_settings( &p_pp->mode[port_num],
+ p_ps, cap_str_idx );
+
+} // port_parm_from_port_settings
+
+
+
+/*HDR*/
+uint32_t check_valid_port_info( const PORT_INFO *p_pi,
+ const STR_TYPE_INFO_IDX str_type_info_idx[],
+ int n_str_type )
+{
+ const PORT_SETTINGS *p_ps = &p_pi->port_settings;
+ int idx;
+ uint32_t flags = 0;
+
+
+ if ( p_pi->supp_baud_rates & ~_mask( N_MBG_BAUD_RATES ) )
+ flags |= MBG_PS_MSK_BAUD_RATE_OVR_SW; // dev. supports more baud rates than driver
+
+ idx = get_baud_rate_idx( p_ps->parm.baud_rate );
+
+ if ( !_inrange( idx, 0, N_MBG_BAUD_RATES ) ||
+ !_is_supported( idx, p_pi->supp_baud_rates ) )
+ flags |= MBG_PS_MSK_BAUD_RATE;
+
+
+ if ( p_pi->supp_framings & ~_mask( N_MBG_FRAMINGS ) )
+ flags |= MBG_PS_MSK_FRAMING_OVR_SW; // dev. supports more framings than driver
+
+ idx = get_framing_idx( p_ps->parm.framing );
+
+ if ( !_inrange( idx, 0, N_MBG_FRAMINGS ) ||
+ !_is_supported( idx, p_pi->supp_framings ) )
+ flags |= MBG_PS_MSK_FRAMING;
+
+
+ if ( p_ps->parm.handshake >= N_COM_HS )
+ flags |= MBG_PS_MSK_HS_OVR_SW; // handshake index exceeds max.
+
+ if ( p_ps->parm.handshake != HS_NONE ) // currently no device supports any handshake
+ flags |= MBG_PS_MSK_HS; // handshake mode not supp. by dev.
+
+
+ if ( p_pi->supp_str_types & ~_mask( n_str_type ) )
+ flags |= MBG_PS_MSK_STR_TYPE_OVR_SW; // firmware error: more string types supported than reported
+
+ idx = p_ps->str_type;
+
+ if ( idx >= n_str_type )
+ flags |= MBG_PS_MSK_STR_TYPE_OVR_DEV; // string type index exceeds max.
+ else
+ {
+ if ( !_is_supported( idx, p_pi->supp_str_types ) )
+ flags |= MBG_PS_MSK_STR_TYPE; // string type not supported by this port
+ else
+ {
+ // Use the str_type index to get the supported output mode mask
+ // from the string type info table. This is required to check
+ // whether the selected mode is supported by the selected
+ // string type.
+ ulong supp_modes = str_type_info_idx[idx].str_type_info.supp_modes;
+
+ if ( supp_modes & ~_mask( N_STR_MODE ) )
+ flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // dev. supports more string modes than driver
+
+ idx = p_ps->mode;
+
+ if ( idx >= N_STR_MODE ) // mode is always >= 0
+ flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // string mode index exceeds max.
+ else
+ if ( !_is_supported( idx, supp_modes ) )
+ flags |= MBG_PS_MSK_STR_MODE; // string mode not supp. by this string type and port
+ }
+ }
+
+
+ if ( p_ps->flags != 0 ) /* currently always 0 */
+ flags |= MBG_PS_MSK_FLAGS_OVR_SW | MBG_PS_MSK_FLAGS;
+
+
+ return flags;
+
+} // check_valid_port_info
+
+
+
+/*HDR*/
+int valid_port_info( const PORT_INFO *p_pi,
+ const STR_TYPE_INFO_IDX str_type_info_idx[],
+ int n_str_type )
+{
+ return check_valid_port_info( p_pi, str_type_info_idx, n_str_type ) == 0;
+
+} // valid_port_info
+
+
+
+/*HDR*/
+int setup_port_info_from_port_settings( PORT_INFO_IDX pii[], const PORT_PARM *p_pp,
+ const RECEIVER_INFO *p_ri )
+{
+ int i;
+
+ for ( i = 0; i < p_ri->n_com_ports; i++ )
+ {
+ PORT_INFO_IDX *p_pii = &pii[i];
+ PORT_INFO *p_pi = &p_pii->port_info;
+
+ p_pii->idx = i;
+ port_settings_from_port_parm( &p_pi->port_settings, i, p_pp, 1 );
+
+ p_pi->supp_baud_rates = DEFAULT_GPS_BAUD_RATES_C166;
+ p_pi->supp_framings = DEFAULT_GPS_FRAMINGS_C166;
+ p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_GPS;
+ }
+
+ return MBG_SUCCESS;
+
+} // setup_port_info_from_port_settings
+
+
+
+/*HDR*/
+int setup_default_str_type_info_idx( STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri )
+{
+ int i;
+
+ for ( i = 0; i < p_ri->n_str_type; i++ )
+ {
+ STR_TYPE_INFO_IDX *stip = &stii[i];
+ stip->idx = i;
+ stip->str_type_info = default_str_type_info[i];
+ }
+
+ return MBG_SUCCESS;
+
+} // setup_default_str_type_info_idx
+
+
+
+/*HDR*/
+int chk_set_n_gnss_supp( ALL_GNSS_INFO *p_agi )
+{
+ p_agi->n_gnss_supp = num_bits_set( p_agi->gnss_mode_info.supp_gnss_types );
+
+ if ( p_agi->n_gnss_supp > N_GNSS_TYPES )
+ return MBG_ERR_N_GNSS_EXCEEDS_SUPP;
+
+ return MBG_SUCCESS;
+
+} // chk_set_n_gnss_supp
+
+
+
+/*HDR*/
+/**
+ * @brief
+ *
+ * ### Setup GNSS info from stat_info so we can use the same printing routine
+ */
+void setup_gps_only_sat_info_idx_from_statinfo( ALL_GNSS_INFO *p_agi )
+{
+ STAT_INFO *p_si = &p_agi->stat_info;
+ GNSS_SAT_INFO_IDX *p_gsii = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GPS];
+ GNSS_SAT_INFO *p_gsi = &p_gsii->gnss_sat_info;
+
+ memset( p_gsii, 0, sizeof( *p_gsii ) );
+ p_gsii->idx = GNSS_TYPE_GPS;
+
+ p_gsi->gnss_type = GNSS_TYPE_GPS;
+ p_gsi->svs_in_view = p_si->svs_in_view;
+ p_gsi->good_svs = p_si->good_svs;
+
+} // setup_gps_only_sat_info_idx_from_statinfo
+
+
+
+/*HDR*/
+/**
+ * @brief
+ *
+ * Setup GNSS info from stat_info so we can use the same printing routine
+ */
+int setup_gps_only_gnss_info_from_statinfo( ALL_GNSS_INFO *p_agi )
+{
+ MBG_GNSS_MODE_INFO *p_gmi = &p_agi->gnss_mode_info;
+
+ memset( p_gmi, 0, sizeof( *p_gmi ) );
+
+ p_gmi->supp_gnss_types = MBG_GNSS_TYPE_MSK_GPS;
+ p_gmi->settings.gnss_set = p_gmi->supp_gnss_types;
+
+ memset( p_agi->gnss_sat_info_idx, 0, sizeof( p_agi->gnss_sat_info_idx ) );
+
+ setup_gps_only_sat_info_idx_from_statinfo( p_agi );
+
+ return chk_set_n_gnss_supp( p_agi );
+
+} // setup_gps_only_gnss_info_from_statinfo
+
+
+
+/*HDR*/
+void chk_free_dev_hw_id( DEVICE_INFO *p )
+{
+ if ( p->hw_id )
+ {
+ free( p->hw_id );
+ p->hw_id = NULL;
+ }
+
+} // chk_free_dev_hw_id
+
+
+
+/*HDR*/
+int alloc_dev_hw_id( DEVICE_INFO *p, size_t len )
+{
+ if ( p->hw_id )
+ return MBG_ERR_ALREADY_ALLOC;
+
+
+ p->hw_id = (char *) malloc( len );
+
+ if ( p->hw_id == NULL )
+ return MBG_ERR_NO_MEM;
+
+ return MBG_SUCCESS;
+
+} // alloc_dev_hw_id
+
+
+
+/*HDR*/
+const char *get_fw_id_from_hw_id( const char *hw_id )
+{
+ int i;
+
+ for ( i = 0; i < N_SUPP_DEV_TOTAL; i++ )
+ {
+ DEVICE_INFO *p = &device_list[i];
+
+ if ( strlen( p->fw_id ) && p->hw_id ) //### TODO check if this still works as expected
+ {
+ if ( strcmp( hw_id, p->hw_id ) == 0 )
+ {
+ if ( strlen( p->fw_id ) > 0 )
+ return p->fw_id;
+
+ #if defined( DEBUG )
+ fprintf( stderr, "Length of fw_id is 0 in %s for device %i (%s)\n",
+ __func__, i, p->hw_id );
+ #endif
+ }
+ }
+ }
+
+ return NULL;
+
+} // get_fw_id_from_hw_id
+
+
+
+/*HDR*/
+const char *get_hw_id_from_fw_id( const char *fw_id )
+{
+ int i;
+
+ for ( i = 0; i < N_SUPP_DEV_TOTAL; i++ )
+ {
+ DEVICE_INFO *p = &device_list[i];
+
+ if ( strlen( p->fw_id ) && p->hw_id ) //### TODO check if this still works as expected
+ {
+ if ( strcmp( fw_id, p->fw_id ) == 0 )
+ {
+ if ( strlen( p->hw_id ) > 0 )
+ return p->hw_id;
+
+ #if defined( DEBUG )
+ fprintf( stderr, "Length of hw_id is 0 in %s for device %i (%s)\n",
+ __func__, i, p->fw_id );
+ #endif
+ }
+ }
+ }
+
+ return NULL;
+
+} // get_hw_id_from_fw_id
+
+
+
+/*HDR*/
+/**
+ * @brief Returns the currently used ::MBG_IO_PORT_TYPE_INFO_IDX for the appropriate ::MBG_IO_PORT_INFO_IDX
+ *
+ * @param[in] all_io_port_info Pointer to the ::ALL_IO_PORT_INFO, containing the current configuration
+ * @param[in] io_port_info_idx Pointer to the ::MBG_IO_PORT_INFO_IDX, for which the ::MBG_IO_PORT_TYPE_INFO_IDX shall be found
+ *
+ * @return Pointer to the ::MBG_IO_PORT_TYPE_INFO_IDX found, or NULL
+ */
+MBG_IO_PORT_TYPE_INFO_IDX *get_io_port_type_info_idx( ALL_IO_PORT_INFO *all_io_port_info, MBG_IO_PORT_INFO_IDX *io_port_info_idx )
+{
+ uint8_t i;
+
+ if ( !all_io_port_info || !io_port_info_idx )
+ return NULL;
+
+ for ( i = 0; i < io_port_info_idx->info.num_types; ++i )
+ {
+ MBG_IO_PORT_TYPE_INFO_IDX *ptii = &all_io_port_info->pt_infos[io_port_info_idx->idx][i];
+ MBG_IO_PORT_TYPE_INFO *pti = &ptii->info;
+
+ if ( pti->port_type == io_port_info_idx->info.settings.port_type )
+ {
+ if ( pti->port_type == MBG_IO_PORT_TYPE_GPIO )
+ {
+ if ( pti->data.gpio_limits.type == io_port_info_idx->info.settings.data.gpio_settings.type )
+ return ptii;
+ }
+ else
+ return ptii;
+ }
+ }
+
+ return NULL;
+
+} // get_io_port_type_info_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Initializes a ::MBG_TLV_ANNOUNCE structure
+ *
+ * @param[out] tlv Pointer to a ::MBG_TLV_ANNOUNCE structure
+ * @param[in] uid Unique sender ID used as identifier with all
+ * subsequent messages related to this transaction.
+ * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES
+ * @param[in] total_bytes Total number of bytes of all upcoming TLVs
+ */
+void mbg_tlv_announce_init( MBG_TLV_ANNOUNCE *tlv, MBG_TLV_UID uid,
+ MBG_TLV_TYPE tlv_feat_type, uint32_t total_bytes )
+{
+ memset( tlv, 0, sizeof( *tlv ) );
+ tlv->data.uid = uid;
+ tlv->data.type = tlv_feat_type;
+ tlv->data.total_bytes = total_bytes;
+ tlv->data.reserved_1 = 0;
+ tlv->reserved_1 = 0;
+ tlv->reserved_2 = 0;
+
+} // mbg_tlv_announce_init
+
+
+
+/*HDR*/
+/**
+ * @brief Initializes a ::MBG_TLV
+ *
+ * @param[out] tlv Pointer to a valid ::MBG_TLV structure
+ * @param[in] uid Unique sender ID used as identifier for each further
+ * TLV message related to this type.
+ * @param[in] tlv_type Type identifier, see ::MBG_TLV_TYPES
+ * @param[in] total_bytes Total number of bytes belonging to this
+ * TLV transaction (which is very likely split into several TLVs)
+ */
+void mbg_tlv_init( MBG_TLV *tlv, MBG_TLV_UID uid,
+ MBG_TLV_TYPE tlv_type, uint32_t total_bytes )
+{
+ memset( tlv, 0, sizeof( *tlv ) );
+ tlv->hdr.uid = uid;
+ tlv->hdr.tlv_type = tlv_type;
+ tlv->hdr.cur_bytes = 0;
+ tlv->hdr.trans_bytes = 0;
+ tlv->hdr.total_bytes = total_bytes;
+ tlv->hdr.reserved_1 = 0;
+ tlv->hdr.reserved_2 = 0;
+ tlv->hdr.reserved_3 = 0;
+
+} // mbg_tlv_init
+
+
+
+/*HDR*/
+/**
+ * @brief Initializes ::MBG_TLV_RCV_STATE structure
+ *
+ * @param[in,out] state Pointer to ::MBG_TLV_RCV_STATE structure
+ * @param[in] uid Unique sender ID used as identifier for each further
+ * TLV message related to this type.
+ * @param[in] total_bytes Total number of bytes belonging to this
+ * TLV transaction (which is very likely split into several TLVS)
+ */
+void mbg_tlv_rcv_state_init( MBG_TLV_RCV_STATE *state, MBG_TLV_UID uid, uint32_t total_bytes )
+{
+ state->data.uid = uid;
+ state->data.type = 0;
+ state->data.total_bytes = total_bytes;
+ state->data.reserved_1 = 0;
+ state->read_bytes = 0;
+ state->reserved_1 = 0;
+
+} // mbg_tlv_state_init
+
+
+
+/*HDR*/
+int mbg_snprint_revision( char *buf, size_t buflen,
+ const char *prefix, const char *suffix,
+ uint32_t rev)
+{
+ size_t bytes = 0;
+ uint32_t major, minor, patch;
+
+ if ( prefix )
+ bytes += snprintf_safe( &buf[bytes], buflen, "%s", prefix );
+
+ _mbg_decode_revision( rev, major, minor, patch );
+ bytes += snprintf_safe( &buf[bytes], buflen - bytes, "%u.%u.%u",
+ major, minor, patch);
+
+ if ( suffix )
+ bytes += snprintf_safe( &buf[bytes], buflen - bytes, "%s", suffix );
+
+ return _int_from_size_t( bytes );
+
+} // mbg_snprint_revision
+
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xbp_supp_nodes( const ALL_XBP_INFO *info )
+{
+ if ( info )
+ {
+ if ( ( info->limits.features & XBP_FEAT_MASK_NODES ) == XBP_FEAT_MASK_NODES )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+ }
+
+ return MBG_ERR_INV_PARM;
+
+} // chk_dev_xbp_supp_nodes
+
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_net_cfg_supp_stage_2( const ALL_NET_CFG_INFO *info )
+{
+ if ( info->glb_cfg_info.feat_flags & MBG_NET_GLB_SUPP_STAGE_2_MASK )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_net_cfg_supp_stage_2
+
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_client( const ALL_NTP_CFG_INFO *info )
+{
+ if ( ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT ) == NTP_MSK_ROLE_CLIENT ) ||
+ ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ntp_supp_client
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_server( const ALL_NTP_CFG_INFO *info )
+{
+ if ( ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_SERVER ) == NTP_MSK_ROLE_SERVER ) ||
+ ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ntp_supp_server
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_mrf_none( const ALL_XMULTI_REF_INFO *info )
+{
+ if ( ( info->instances.flags & XMRIF_MSK_MRF_NONE_SUPP ) == XMRIF_MSK_MRF_NONE_SUPP )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_xmulti_ref_supp_mrf_none
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_src_info( const ALL_XMULTI_REF_INFO *info )
+{
+ if ( ( info->instances.flags & XMRIF_MSK_EXT_SRC_INFO_SUPP ) == XMRIF_MSK_EXT_SRC_INFO_SUPP )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_xmulti_ref_supp_ext_src_info
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_holdover_status( const ALL_XMULTI_REF_INFO *info )
+{
+ if ( ( info->instances.flags & XMRIF_MSK_HOLDOVER_STATUS_SUPP ) == XMRIF_MSK_HOLDOVER_STATUS_SUPP )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_xmulti_ref_supp_holdover_status
+
+
+/*HDR*/
+/*
+ * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings,
+ * but of ::MULTI_REF_TYPES.
+ * Depends on chk_dev_supp_xmulti_ref_ext_src_info.
+ * @see chk_dev_supp_xmulti_ref_ext_src_info
+ */
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_stats( const ALL_XMULTI_REF_INFO *info, int type )
+{
+ if (
+ ( type < N_MULTI_REF ) &&
+ (( info->ext_src_infos[type].info.feat_flags & XMR_EXT_SRC_FEAT_FLAG_MSK_STATS ) == XMR_EXT_SRC_FEAT_FLAG_MSK_STATS )
+ ) return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_xmulti_ref_supp_ext_source_stats
+
+
+/*HDR*/
+/*
+ * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings,
+ * but of ::MULTI_REF_TYPES.
+ * Depends on chk_dev_supp_xmulti_ref_ext_src_info.
+ * @see chk_dev_supp_xmulti_ref_ext_src_info
+ */
+_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_metrics( const ALL_XMULTI_REF_INFO *info, int type )
+{
+ if (
+ ( type < N_MULTI_REF ) &&
+ (( info->ext_src_infos[type].info.feat_flags & XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS ) == XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS )
+ ) return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_xmulti_ref_supp_ext_source_metrics
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_has_fdm( const ALL_IMS_INFO *info )
+{
+ if ( ( info->state.flags & MBG_IMS_STATE_FLAG_MSK_HAS_FDM ) == MBG_IMS_STATE_FLAG_MSK_HAS_FDM )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ims_has_fdm
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_enabled( const ALL_IMS_STATE *ims_state, unsigned idx )
+{
+ const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state;
+
+ if (
+ ( sstate->type == MBG_IMS_SENSOR_VOLTAGE ) &&
+ ( ( sstate->flags & MBG_IMS_SENSOR_VOLTAGE_OUT_ENB ) == MBG_IMS_SENSOR_VOLTAGE_OUT_ENB )
+ ) return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ims_is_volt_out_enabled
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_overload( const ALL_IMS_STATE *ims_state, unsigned idx )
+{
+ const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state;
+
+ if (
+ ( sstate->type == MBG_IMS_SENSOR_VOLTAGE ) &&
+ ( ( sstate->flags & MBG_IMS_SENSOR_VOLTAGE_OUT_OVR ) == MBG_IMS_SENSOR_VOLTAGE_OUT_OVR )
+ ) return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ims_is_volt_out_overload
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_pll_locked( const ALL_IMS_STATE *ims_state, unsigned idx )
+{
+ const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state;
+
+ if (
+ ( sstate->type == MBG_IMS_SENSOR_PLL ) &&
+ ( ( sstate->flags & MBG_IMS_SENSOR_PLL_LOCKED ) == MBG_IMS_SENSOR_PLL_LOCKED )
+ ) return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_ims_is_pll_locked
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_supp_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx )
+{
+ const MBG_GPIO_LIMITS *limits = &gpio_info->infos[idx].info.limits;
+
+ if ( ( limits->supp_flags & MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) == MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_gpio_supp_ass_idx
+
+
+/*HDR*/
+_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_dep_on_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx )
+{
+ const MBG_GPIO_SETTINGS *settings = &gpio_info->infos[idx].info.settings;
+
+ if ( ( settings->flags & MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) == MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_gpio_dep_on_ass_idx
+
+
+/*HDR*/
+/**
+ * @brief Checks whether GPIO supports status function
+ *
+ * @param[out] info Pointer to a ::ALL_GPIO_INFO structure to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::free_all_gpio_info
+ */
+_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_has_status( const ALL_GPIO_INFO *info )
+{
+ if ( ( info->cfg_limits.flags & MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP ) == MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_dev_gpio_has_status
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_XBP_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_XBP_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xbp_info
+ */
+void free_all_xbp_info ( ALL_XBP_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->node_limits )
+ free( p->node_limits );
+
+ if ( p->node_infos )
+ free( p->node_infos );
+
+ free( p );
+ }
+
+} // free_all_xbp_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_NET_CFG_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NET_CFG_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_net_cfg_info
+ */
+void free_all_net_cfg_info ( ALL_NET_CFG_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->link_infos )
+ free( p->link_infos );
+
+ if ( p->addr_infos )
+ free( p->addr_infos );
+
+ if ( p->dns_srvrs )
+ free( p->dns_srvrs );
+
+ if ( p->dns_srch_doms )
+ free( p->dns_srch_doms );
+
+ if ( p->route_infos )
+ free( p->route_infos );
+
+ free( p );
+ }
+
+} // free_all_net_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_NET_STATUS_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NET_STATUS_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_net_status_info
+ */
+void free_all_net_status_info ( ALL_NET_STATUS_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->link_infos )
+ free( p->link_infos );
+
+ if ( p->addr_infos )
+ free( p->addr_infos );
+
+ if ( p->dns_srvrs )
+ free( p->dns_srvrs );
+
+ if ( p->dns_srch_doms )
+ free( p->dns_srch_doms );
+
+ if ( p->route_infos )
+ free( p->route_infos );
+
+ free( p );
+ }
+
+} // free_all_net_status_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_SNMP_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_SNMP_INFO structure, which will be freed
+ *
+ */
+void free_all_snmp_info ( ALL_SNMP_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->v12_infos )
+ free( p->v12_infos );
+
+ if ( p->v12_trap_infos )
+ free( p->v12_trap_infos );
+
+ if ( p->v3_infos )
+ free( p->v3_infos );
+
+ if ( p->v3_trap_infos )
+ free( p->v3_trap_infos );
+
+ free( p );
+ }
+
+} // free_all_snmp_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_MONITORING_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_MONITORING_INFO structure, which will be freed
+ *
+ */
+void free_all_monitoring_info ( ALL_MONITORING_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->all_snmp_info )
+ free_all_snmp_info( p->all_snmp_info );
+
+ if ( p->event_infos )
+ free( p->event_infos );
+
+ free ( p );
+ }
+}
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_MONITORING_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_MONITORING_STATUS structure, which will be freed
+ *
+ */
+void free_all_monitoring_status ( ALL_MONITORING_STATUS *p )
+{
+ if ( p )
+ {
+ if ( p->event_stati )
+ free( p->event_stati );
+
+ free ( p );
+ }
+}
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_XMULTI_REF_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_XMULTI_REF_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xmulti_ref_info
+ * @see ::mbg_get_all_xmulti_ref_info
+ */
+void free_all_xmulti_ref_info( ALL_XMULTI_REF_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->infos )
+ free( p->infos );
+
+ if ( p->ext_src_infos )
+ free( p->ext_src_infos );
+
+ free ( p );
+ }
+
+} // free_all_xmulti_ref_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_XMULTI_REF_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_XMULTI_REF_STATUS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xmulti_ref_status
+ * @see ::mbg_get_all_xmulti_ref_status
+ */
+void free_all_xmulti_ref_status( ALL_XMULTI_REF_STATUS *p )
+{
+ if ( p )
+ {
+ if ( p->status )
+ free( p->status );
+
+ if ( p->holdover_status )
+ free( p->holdover_status );
+
+ if ( p->stats_idx )
+ free( p->stats_idx );
+
+ if ( p->metrics_idx )
+ free( p->metrics_idx );
+
+ free( p );
+ }
+
+} // free_all_xmulti_ref_status
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_PTP_V1_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v1_common_datasets
+ *
+ * @param[in] p Pointer to the ::ALL_PTP_V1_COMMON_DATASETS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ptp_v1_common_datasets
+ */
+void free_all_ptp_v1_common_datasets( ALL_PTP_V1_COMMON_DATASETS *p )
+{
+ if ( p )
+ {
+ if ( p->port_datasets )
+ free( p->port_datasets );
+
+ free( p );
+ }
+
+} // free_all_ptp_v1_common_datasets
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_PTP_V2_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v2_common_datasets
+ *
+ * @param[in] p Pointer to the ::ALL_PTP_V2_COMMON_DATASETS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ptp_v2_common_datasets
+ */
+void free_all_ptp_v2_common_datasets( ALL_PTP_V2_COMMON_DATASETS *p )
+{
+ if ( p )
+ {
+ if ( p->port_datasets )
+ free( p->port_datasets );
+
+ free( p );
+ }
+
+} // free_all_ptp_v2_common_datasets
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_NTP_CFG_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NTP_CFG_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ntp_cfg_info
+ */
+void free_all_ntp_cfg_info( ALL_NTP_CFG_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->symm_key_limits )
+ free( p->symm_key_limits );
+
+ if ( p->symm_key_info_idx )
+ free( p->symm_key_info_idx );
+
+ if ( p->trusted_key_info_idx )
+ free( p->trusted_key_info_idx );
+
+ if ( p->clnt_info )
+ free( p->clnt_info );
+
+ if ( p->peer_settings_idx )
+ free( p->peer_settings_idx );
+
+ if ( p->srv_info )
+ free( p->srv_info );
+
+ if ( p->refclk_info_idx )
+ free( p->refclk_info_idx );
+
+ if ( p->misc_limits )
+ free( p->misc_limits );
+
+ if ( p->orphan_mode_info )
+ free( p->orphan_mode_info );
+
+ free( p );
+ }
+
+} // free_all_ntp_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_NTP_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_NTP_STATUS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ntp_status
+ */
+void free_all_ntp_status( ALL_NTP_STATUS *p )
+{
+ if ( p )
+ {
+ if ( p->refclk_states )
+ free( p->refclk_states );
+
+ if ( p->peer_states )
+ free( p->peer_states );
+
+ free( p );
+ }
+
+} // free_all_ntp_status
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ims_info
+ *
+ * @param[in] p Pointer to the ::ALL_IMS_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_dev_has_ims
+ * @see ::mbgextio_get_all_ims_info
+ * @see ::mbgextio_get_all_ims_state
+ */
+void free_all_ims_info( ALL_IMS_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->fdm_info )
+ free( p->fdm_info );
+
+ if ( p->fdm_limits )
+ free( p->fdm_limits );
+
+ if ( p->fdm_outinfo_idx )
+ free( p->fdm_outinfo_idx );
+
+ free( p );
+ }
+
+} // free_all_ims_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ims_state
+ *
+ * @param[in] p Pointer to the ::ALL_IMS_STATE structure, which will be freed
+ *
+ * @see ::mbgextio_dev_has_ims
+ * @see ::mbgextio_get_all_ims_info
+ * @see ::mbgextio_get_all_ims_state
+ */
+void free_all_ims_state( ALL_IMS_STATE *p )
+{
+ if ( p )
+ {
+ if ( p->sensor_state_idx )
+ free( p->sensor_state_idx );
+
+ if ( p->fdm_state )
+ free( p->fdm_state );
+
+ if ( p->fdm_output_state_idx )
+ free( p->fdm_output_state_idx );
+
+ free( p );
+ }
+
+} // free_all_ims_state
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_gpio_info
+ *
+ * @param[in] p Pointer to the ::ALL_GPIO_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbgextio_get_all_gpio_info
+ */
+void free_all_gpio_info( ALL_GPIO_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->infos )
+ free( p->infos );
+
+ free( p );
+ }
+
+} // free_all_gpio_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_io_port_info
+ *
+ * @param[in] p Pointer to the ::ALL_IO_PORT_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_io_ports
+ * @see ::mbgextio_get_all_io_port_info
+ * @see ::mbgextio_get_all_io_port_status
+ * @see ::free_all_io_port_status
+ */
+void free_all_io_port_info( ALL_IO_PORT_INFO *p )
+{
+ uint8_t i;
+
+ if ( p )
+ {
+ if ( p->pt_infos )
+ {
+ for ( i = 0; i < p->limits.num_ports; ++i )
+ {
+ if ( p->pt_infos[i] )
+ free( p->pt_infos[i] );
+ }
+
+ free ( p->pt_infos );
+ }
+
+ if ( p->p_infos )
+ free( p->p_infos );
+
+ free( p );
+ }
+
+} // free_all_io_port_info
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_io_port_status
+ *
+ * @param[in] p Pointer to the ::ALL_IO_PORT_STATUS structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_io_ports
+ * @see ::mbgextio_get_all_io_port_info
+ * @see ::mbgextio_get_all_io_port_status
+ * @see ::free_all_io_port_info
+ */
+void free_all_io_port_status( ALL_IO_PORT_STATUS *p )
+{
+ if ( p )
+ {
+ if ( p->status )
+ free ( p->status );
+
+ free( p );
+ }
+
+} // free_all_io_port_status
+
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_gpio_state
+ *
+ * @param[in] p Pointer to the ::ALL_GPIO_STATE structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbgextio_get_all_gpio_state
+ */
+void free_all_gpio_state( ALL_GPIO_STATE *p )
+{
+ if ( p )
+ {
+ if ( p->states )
+ free( p->states );
+
+ free( p );
+ }
+
+} // free_all_gpio_state
+
+
+
+/*HDR*/
+/**
+ * Allocates memory for a new ::UCAP_ENTRY structure
+ *
+ * @return The new allocated ::UCAP_ENTRY or NULL if the calloc call was not successful
+ */
+UCAP_ENTRY* calloc_ucap_entry( void )
+{
+ UCAP_ENTRY *entry = (UCAP_ENTRY *) calloc( 1, sizeof( *entry ) );
+ if ( entry )
+ {
+ mbg_klist_init(&entry->head);
+ }
+ return entry;
+
+} // calloc_ucap_entry
+
+
+/*HDR*/
+/**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ucap_info
+ *
+ * @param[in] p Pointer to the ::ALL_UCAP_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_ucap
+ * @see ::mbg_chk_dev_has_ucap
+ * @see ::mbgextio_get_all_ucap_info
+ * @see ::mbg_get_all_ucap_info
+ */
+void free_all_ucap_info( ALL_UCAP_INFO *p )
+{
+ if ( p )
+ {
+ UCAP_ENTRY *entry;
+
+ while ( !mbg_klist_is_empty( &p->list ) )
+ {
+ entry = mbg_klist_first_entry( &p->list, UCAP_ENTRY, head );
+ mbg_klist_delete_item( &entry->head );
+ free( entry );
+ }
+
+ free( p );
+ }
+
+} // free_all_ucap_info
+
+
+/*HDR*/
+/**
+ * @brief Frees ::ALL_UCAP_NET_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ucap_net_info
+ */
+void free_all_ucap_net_info( ALL_UCAP_NET_INFO *p )
+{
+ if ( p )
+ {
+ if ( p->recv_infos )
+ free( p->recv_infos );
+
+ free( p );
+ }
+
+} // free_all_ucap_net_info
+
+
+
+/*HDR*/
+/**
+ * @brief Set up a ::NTP_TSTAMP structure from a hex string with a time in seconds and binary fractions
+ *
+ * @param[in] s A string with a time in seconds since NTP epoch 1900-01-01,
+ * with binary fractions separated by decimal point,
+ * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
+ * @param[out] p Address of a ::NTP_TSTAMP structure to be set up
+ *
+ * @see ::str_ntp_hex_to_nano_time_64
+ */
+void str_ntp_hex_to_ntp_tstamp( const char *s, NTP_TSTAMP *p )
+{
+ char *cp = NULL;
+
+ p->seconds = strtoul( s, &cp, 16 );
+
+ if ( *cp == '.' ) // fractions may follow
+ {
+ cp++; // skip '.'
+
+ p->fractions = strtoul( cp, NULL, 16 );
+ }
+ else
+ p->fractions = 0;
+
+} // str_ntp_hex_to_ntp_tstamp
+
+
+
+#if !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+/*HDR*/
+/**
+ * @brief Convert a ::NTP_TSTAMP structure to a ::NANO_TIME_64 structure
+ *
+ * @param[in] p_nts The ::NTP_TSTAMP structure to be converted
+ * @param[out] p_nt64 The ::NANO_TIME_64 structure to be filled up
+ */
+void ntp_tstamp_to_nanotime_64( const NTP_TSTAMP *p_nts, NANO_TIME_64 *p_nt64 )
+{
+ p_nt64->secs = p_nts->seconds - NTP_SEC_BIAS;
+ p_nt64->nano_secs = bin_frac_32_to_dec_frac( p_nts->fractions, NSECS_PER_SEC );
+
+} // ntp_tstamp_to_nanotime_64
+
+
+
+/*HDR*/
+/**
+ * @brief Set up a ::NANO_TIME_64 structure from a hex string with a time in seconds and binary fractions
+ *
+ * @param[in] s A string with a time in seconds since epoch 1900-01-01,
+ * with binary fractions separated by decimal point,
+ * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ *
+ * @see ::str_ntp_hex_to_ntp_tstamp
+ */
+void str_ntp_hex_to_nano_time_64( const char *s, NANO_TIME_64 *p )
+{
+ NTP_TSTAMP nts = { 0 };
+
+ str_ntp_hex_to_ntp_tstamp( s, &nts );
+ ntp_tstamp_to_nanotime_64( &nts, p );
+
+} // str_ntp_hex_to_nano_time_64
+
+#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.h b/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.h
new file mode 100755
index 0000000..44ddbe9
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/cfg_hlp.h
@@ -0,0 +1,1217 @@
+
+/**************************************************************************
+ *
+ * $Id: cfg_hlp.h 1.4.2.1 2017/07/26 14:26:01 martin TEST $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for configuration programs.
+ *
+ * WARNING: Changing the constants defined here affects the size of
+ * the related structures and arrays, and thus would break compatibility
+ * if used in DLLs / shared object libraries.
+ *
+ * Care must be taken that the number of objects supported by
+ * any particular device (which can be only determined at runtime)
+ * does not exceed the max. number of objects specified here
+ * for the configuration programs.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: cfg_hlp.h $
+ * Revision 1.4.2.1 2017/07/26 14:26:01 martin
+ * Fixed build for NetBSD.
+ * Revision 1.4 2017/07/05 13:22:00 martin
+ * Definitions for TLV, IMS, and GPIO provided by philipp.
+ * Definitions for ALL_XPB_INFO, ALL_NET_CFG_INFO,
+ * ALL_PTP_V2_COMMON_DATASETS, ALL_PTP_V1_COMMON_DATASETS,
+ * ALL_UCAP and associated stuff provided by thomas-b.
+ * Definitions for xmulti_ref and IO PORT, SNMP and MONITORING,
+ * and associated stuff provided by philipp and thomas-b.
+ * New definitions COMP_SIG_MODES and PCPS_TIME_EXT_FLAGS.
+ * New inline functions device_id_is_serial() and
+ * device_id_is_lan().
+ * Moved inline function num_bits_set() and a lot of
+ * global configuration variables here.
+ * Older defines N_SUPP_DEV, PCPS_MAX_DDEVS, and MBG_MAX_DEVICES
+ * have been obsoleted by new defines N_SUPP_DEV_BUS, N_SUPP_DEV_EXT,
+ * and N_SUPP_DEV_TOTAL.
+ * Updated function prototypes.
+ * Revision 1.3 2013/09/25 10:02:15 martin
+ * Added ALL_PTP_CFG_INFO, ALL_GNSS_SAT_INFO_IDX and
+ * related definitions.
+ * Added doxygen comments.
+ * Revision 1.2 2012/10/02 18:16:26 martin
+ * Modified some typedefs to be more compliant with the underlying types.
+ * Revision 1.1 2011/09/21 15:59:59 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _CFG_HLP_H
+#define _CFG_HLP_H
+
+
+/* Other headers to be included */
+
+#include <gpsdefs.h>
+#include <mbgklist.h>
+
+#if !defined( MBG_TGT_KERNEL )
+ #include <stdlib.h>
+ #include <string.h>
+#endif
+
+#if defined( _PRELIMINARY_CODE )
+ #if defined( MBG_TGT_POSIX )
+ #include <sys/stat.h>
+ #include <time.h>
+ #endif // MBG_TGT_POSIX
+
+ #if defined( MBG_TGT_LINUX )
+ #include <sys/sysinfo.h>
+ #endif // MBG_TGT_LINUX
+
+#endif // _PRELIMINARY_CODE
+
+#ifdef _CFG_HLP
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if 1 // ### TODO cleanup
+
+#define N_SUPP_DEV_BUS 16
+#define N_SUPP_DEV_EXT 1
+
+#define N_SUPP_DEV_TOTAL ( N_SUPP_DEV_BUS + N_SUPP_DEV_EXT )
+
+typedef struct _DEVICE_INFO
+{
+ char *hw_id;
+ char fw_id[100];
+
+} DEVICE_INFO;
+
+_ext DEVICE_INFO device_list[N_SUPP_DEV_TOTAL];
+
+#endif
+
+
+
+/// @brief The max number of serial ports supported by configuration programs
+#define MAX_PARM_PORT 10
+
+/// @brief The max number of serial string types supported by configuration programs
+#define MAX_PARM_STR_TYPE 20
+
+/// @brief The max number of programmable pulse outputs supported by configuration programs
+#define MAX_PARM_POUT 10
+
+/// @brief The max number of GNSS settings supported by configuration programs
+#define MAX_PARM_GNSS_SAT N_GNSS_TYPES
+
+/// @brief The max number of PTP unicast masters supported by configuration programs
+#define MAX_PARM_PTP_UC_MASTER 3
+
+/// @brief The max number of external NTP server associations to be handled by configuration programs
+#define MAX_PARM_EXT_NTP_SRVR 20
+
+/// @brief The max number of GPIO ports supported by configuration programs
+#define MAX_PARM_GPIO 10
+
+/// @brief The max number of XMR sources supported by configuration programs
+#define MAX_PARM_XMR 10
+
+/// @brief The max number of external NTP servers supported by configuration programs
+#define MAX_EXT_NTP_SERVERS 20
+
+/// @brief The max. number of time monitoring modules supported by configuration programs
+/// Each module may support a different number of targets to be monitored.
+/// @see ### TODO
+#define MAX_MBG_TIME_MON_MODULES 10
+
+/// @brief The max. number of time monitoring targets supported by configuration programs
+/// This is the sum of all targets from all monitoring modules.
+/// @see ### TODO
+#define MAX_MBG_TIME_MON_TARGETS 100
+
+
+
+/// @brief An array of configuration settings for all serial ports
+typedef PORT_INFO_IDX ALL_PORT_INFO_IDX[MAX_PARM_PORT];
+
+/// @brief An array of configuration settings for all serial string types
+typedef STR_TYPE_INFO_IDX ALL_STR_TYPE_INFO_IDX[MAX_PARM_STR_TYPE];
+
+/**
+ * @brief All configuration parameters for all serial ports
+ *
+ * Used to collect all configuration parameters of a clock's serial ports
+ * that can be handled by a configuration program.
+ *
+ * @see ::RECEIVER_INFO::n_com_ports
+ * @see ::RECEIVER_INFO::n_str_type
+ */
+typedef struct
+{
+ ALL_PORT_INFO_IDX pii; ///< all serial port configuration settings
+ ALL_STR_TYPE_INFO_IDX stii; ///< all supported serial string types
+ PORT_PARM tmp_pp; ///< used internally only, for compatibility
+
+} RECEIVER_PORT_CFG;
+
+
+
+/**
+ * @brief All XBP information of a XBP supporting device
+ *
+ * This structure represents a list of connected devices
+ *
+ * @see ::GPS_HAS_XBP
+ */
+typedef struct
+{
+ XBP_LIMITS limits;
+ XBP_NODE_LIMITS* node_limits;
+ XBP_NODE_INFO_IDX* node_infos;
+} ALL_XBP_INFO;
+
+
+
+/**
+ * @brief An array of configuration settings for all programmable pulse outputs
+ *
+ * Used to collect all configuration parameters of a clock's programmable pulse outputs
+ * that can be handled by a configuration program.
+ *
+ * @see ::RECEIVER_INFO::n_prg_out
+ */
+typedef POUT_INFO_IDX ALL_POUT_INFO_IDX[MAX_PARM_POUT];
+
+
+
+/**
+ * @brief All network configuration parameters
+ *
+ * Used to collect all configuration parameters for networking
+ *
+ * @see ::GPS_HAS_NET_CFG
+ * @see ::GPS_HAS_LAN_IP4
+ */
+typedef struct
+{
+ MBG_NET_GLB_CFG_INFO glb_cfg_info;
+ MBG_NET_INTF_LINK_INFO_IDX *link_infos;
+ MBG_NET_INTF_ADDR_INFO_IDX *addr_infos;
+ MBG_IP_ADDR_IDX *dns_srvrs;
+ MBG_NET_NAME_IDX *dns_srch_doms;
+ MBG_NET_INTF_ROUTE_INFO_IDX *route_infos;
+} ALL_NET_CFG_INFO;
+
+typedef ALL_NET_CFG_INFO ALL_NET_STATUS_INFO;
+
+
+
+/**
+ * @brief All SNMP configuration information
+ *
+ * Used to collect all configuration parameters for monitoring via SNMP
+ * Can be used, if ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types
+ *
+ * @see ::MBG_XFEATURE_MONITORING
+ */
+typedef struct
+{
+ MBG_SNMP_GLB_INFO glb_info;
+ MBG_SNMP_V12_INFO_IDX *v12_infos;
+ MBG_SNMP_V12_TRAP_INFO_IDX *v12_trap_infos;
+ MBG_SNMP_V3_INFO_IDX *v3_infos;
+ MBG_SNMP_V3_TRAP_INFO_IDX *v3_trap_infos;
+
+} ALL_SNMP_INFO;
+
+
+/**
+ * @brief All monitoring information
+ *
+ * Used to collect all configuration parameters for monitoring of a device
+ * Depending on the ::MBG_MONITORING_LIMITS::supp_types,
+ * the approriate configurations can be found in the sub structures
+ *
+ * @see ::MBG_XFEATURE_MONITORING
+ */
+typedef struct
+{
+ MBG_EVENT_INFO_IDX info;
+ void *priv_data;
+
+} MBG_EVENT_INFO_IDX_DATA;
+
+typedef struct
+{
+ MBG_MONITORING_LIMITS limits;
+ ALL_SNMP_INFO *all_snmp_info;
+ MBG_EVENT_INFO_IDX_DATA *event_infos;
+
+} ALL_MONITORING_INFO;
+
+
+
+typedef struct
+{
+ MBG_EVENT_STATUS_IDX status;
+ void *priv_data;
+
+} MBG_EVENT_STATUS_IDX_DATA;
+
+
+
+/**
+ * @brief All monitoring status
+ *
+ * Used to collect all status information for monitoring a device.
+ * Depending on the ::MBG_MONITORING_LIMITS::supp_num_events,
+ * the appropriate event status for each event can be found
+ * in ::ALL_MONITORING_STATUS::event_stati.
+ */
+typedef struct
+{
+ MBG_MONITORING_STATUS status;
+ MBG_EVENT_STATUS_IDX_DATA *event_stati;
+
+} ALL_MONITORING_STATUS;
+
+
+
+/// @brief Configuration settings for all unicast master specifications
+typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO_IDX[MAX_PARM_PTP_UC_MASTER];
+
+/**
+ * @brief All PTP configuration parameters
+ *
+ * Used to collect all configuration parameters for a PTP daemon
+ * that can be handled by a configuration program.
+ *
+ * @see ::GPS_HAS_PTP
+ * @see ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master
+ */
+typedef struct
+{
+ PTP_CFG_INFO ptp_cfg_info;
+ PTP_UC_MASTER_CFG_LIMITS ptp_uc_master_cfg_limits;
+ ALL_PTP_UC_MASTER_INFO_IDX all_ptp_uc_master_info_idx;
+
+} ALL_PTP_CFG_INFO;
+
+
+
+/**
+ * @brief All PTPv1 common datasets for a PTP device
+ *
+ * Contains one of each common datasets plus one port dataset
+ * for each port of a device. The number of port datasets is defined
+ * in the ::MBG_PTP_V1_DEFAULT_DATASET::number_ports field of the
+ * ::ALL_PTP_V1_COMMON_DATASETS::default_dataset member.
+ *
+ * @see ::MBG_PTP_V1_DEFAULT_DATASET
+ * @see ::MBG_PTP_V1_CURRENT_DATASET
+ * @see ::MBG_PTP_V1_PARENT_DATASET
+ * @see ::MBG_PTP_V1_TIME_PROPERTIES_DATASET
+ * @see ::MBG_PTP_V1_PORT_DATASET_IDX
+ */
+typedef struct
+{
+ MBG_PTP_V1_DEFAULT_DATASET default_dataset;
+ MBG_PTP_V1_CURRENT_DATASET current_dataset;
+ MBG_PTP_V1_PARENT_DATASET parent_dataset;
+ MBG_PTP_V1_TIME_PROPERTIES_DATASET time_properties_dataset;
+ MBG_PTP_V1_PORT_DATASET_IDX *port_datasets;
+
+} ALL_PTP_V1_COMMON_DATASETS;
+
+
+
+/**
+ * @brief All PTPv2 common datasets for a PTP device
+ *
+ * Contains one of each common datasets plus one port dataset
+ * for each port of a device. The number of port datasets is defined
+ * in the ::MBG_PTP_V1_DEFAULT_DATASET::number_ports field of the
+ * ::ALL_PTP_V1_COMMON_DATASETS::default_dataset member.
+ *
+ * @see ::MBG_PTP_V2_DEFAULT_DATASET
+ * @see ::MBG_PTP_V2_CURRENT_DATASET
+ * @see ::MBG_PTP_V2_PARENT_DATASET
+ * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET
+ * @see ::MBG_PTP_V2_PORT_DATASET_IDX
+ */
+typedef struct
+{
+ MBG_PTP_V2_DEFAULT_DATASET default_dataset;
+ MBG_PTP_V2_CURRENT_DATASET current_dataset;
+ MBG_PTP_V2_PARENT_DATASET parent_dataset;
+ MBG_PTP_V2_TIME_PROPERTIES_DATASET time_properties_dataset;
+ MBG_PTP_V2_PORT_DATASET_IDX *port_datasets;
+
+} ALL_PTP_V2_COMMON_DATASETS;
+
+
+
+/**
+ * @brief An array of configuration settings for all programmable pulse outputs
+ *
+ * Used to collect all configuration parameters of a clock's programmable pulse outputs
+ * that can be handled by a configuration program.
+ */
+typedef GNSS_SAT_INFO_IDX ALL_GNSS_SAT_INFO_IDX[MAX_PARM_GNSS_SAT];
+
+
+
+/**
+ * @brief Summary information on all supported GNSS systems
+ *
+ * Used to collect all configuration parameters even for devices
+ * that can receive the signals from multiple satellite systems.
+ */
+typedef struct
+{
+ STAT_INFO stat_info;
+ int n_gnss_supp;
+ MBG_GNSS_MODE_INFO gnss_mode_info;
+ ALL_GNSS_SAT_INFO_IDX gnss_sat_info_idx;
+
+} ALL_GNSS_INFO;
+
+
+
+/// @brief Configuration settings for all NTP server associations
+typedef NTP_PEER_SETTINGS ALL_NTP_PEER_SETTINGS[MAX_EXT_NTP_SERVERS];
+
+/**
+ * @brief All NTP configuration parameters
+ *
+ * Used to collect all configuration parameters for an NTP daemon
+ * that can be handled by a configuration program.
+ *
+ * @see ::GPS_HAS_NTP
+ */
+typedef struct
+{
+ ALL_NTP_PEER_SETTINGS all_ntp_peer_settings;
+
+} NTP_CLIENT_CFG_PEER_SETTINGS;
+
+
+typedef struct
+{
+ NTP_GLB_INFO glb_info;
+ NTP_SYMM_KEY_LIMITS *symm_key_limits;
+ NTP_SYMM_KEY_INFO_IDX *symm_key_info_idx;
+ NTP_TRUSTED_KEY_INFO_IDX *trusted_key_info_idx;
+
+ NTP_CLNT_MODE_INFO *clnt_info;
+ NTP_PEER_SETTINGS_IDX *peer_settings_idx;
+
+ NTP_SRV_MODE_INFO *srv_info;
+ NTP_REFCLK_CFG_INFO_IDX *refclk_info_idx;
+ NTP_MISC_LIMITS *misc_limits;
+ NTP_MISC_ORPHAN_MODE_INFO *orphan_mode_info;
+
+} ALL_NTP_CFG_INFO;
+
+
+typedef struct
+{
+ NTP_SYS_STATE sys_state;
+ NTP_REFCLK_STATE_IDX *refclk_states;
+ NTP_PEER_STATE_IDX *peer_states;
+} ALL_NTP_STATUS;
+
+
+
+/// @brief Configuration settings for all GPIO ports
+typedef MBG_GPIO_INFO_IDX ALL_GPIO_INFO_IDX[MAX_PARM_GPIO];
+
+/// @brief Status information on all GPIO ports
+typedef MBG_GPIO_STATUS_IDX ALL_GPIO_STATUS_IDX[MAX_PARM_GPIO];
+
+
+
+
+/// @brief Status of all XMR inputs
+typedef XMULTI_REF_STATUS_IDX ALL_XMULTI_REF_STATUS_IDX[MAX_PARM_XMR];
+
+/// @brief Configuration settings for all XMR inputs
+typedef XMULTI_REF_INFO_IDX ALL_XMULTI_REF_INFO_IDX[MAX_PARM_XMR];
+
+
+
+typedef struct
+{
+ XMULTI_REF_INSTANCES instances;
+ XMULTI_REF_INFO_IDX *infos;
+ XMR_EXT_SRC_INFO_IDX *ext_src_infos;
+} ALL_XMULTI_REF_INFO;
+
+
+typedef struct
+{
+ XMULTI_REF_STATUS_IDX *status;
+ XMR_HOLDOVER_STATUS *holdover_status;
+ XMR_STATS_IDX *stats_idx;
+ XMR_METRICS_IDX *metrics_idx;
+ /* ALL_XMULTI_REF_STATUS related flag if at least one ref type supports stats */
+ unsigned char has_stats;
+ /* ALL_XMULTI_REF_STATUS related flag if at least one ref type supports metrics */
+ unsigned char has_metrics;
+} ALL_XMULTI_REF_STATUS;
+
+
+
+typedef struct
+{
+ MBG_IMS_STATE state;
+ MBG_IMS_FDM_INFO *fdm_info;
+ MBG_IMS_FDM_LIMITS *fdm_limits;
+ MBG_IMS_FDM_OUTPUT_INFO_IDX *fdm_outinfo_idx;
+} ALL_IMS_INFO;
+
+
+typedef struct
+{
+ MBG_IMS_SENSOR_STATE_IDX *sensor_state_idx;
+ MBG_IMS_FDM_STATE *fdm_state;
+ MBG_IMS_FDM_OUTPUT_STATE_IDX *fdm_output_state_idx;
+} ALL_IMS_STATE;
+
+
+
+typedef struct
+{
+ MBG_GPIO_CFG_LIMITS cfg_limits;
+ MBG_GPIO_INFO_IDX *infos;
+} ALL_GPIO_INFO;
+
+
+typedef struct
+{
+ MBG_GPIO_STATUS_IDX *states;
+} ALL_GPIO_STATE;
+
+
+typedef struct
+{
+ MBG_IO_PORT_LIMITS limits;
+ MBG_IO_PORT_INFO_IDX *p_infos;
+ MBG_IO_PORT_TYPE_INFO_IDX **pt_infos;
+} ALL_IO_PORT_INFO;
+
+
+typedef struct
+{
+ MBG_IO_PORT_STATUS_IDX *status;
+} ALL_IO_PORT_STATUS;
+
+
+#ifndef MAX_UCAP_ENTRIES
+/*
+ * According to Andre's GPS firmware this is the maximum
+ * number of user captures that are preserved.
+ */
+#define MAX_UCAP_ENTRIES 585
+#endif
+
+typedef struct
+{
+ struct mbg_klist_head head;
+ TTM ttm;
+} UCAP_ENTRY;
+
+typedef struct
+{
+ uint32_t num_ucaps; /// User capture counter, see ::MAX_UCAP_ENTRIES
+ struct mbg_klist_head list;
+} ALL_UCAP_INFO;
+
+// User Captures via Network configuration, see ::MBG_XFEATURE_UCAP_NET
+typedef struct
+{
+ MBG_UCAP_NET_GLB_INFO glb_info;
+ MBG_UCAP_NET_RECV_INFO_IDX *recv_infos;
+} ALL_UCAP_NET_INFO;
+
+
+
+/**
+ * @brief A mode specifying how to interpret a ::PCPS_SIG_VAL
+ *
+ * Used with ::PCPS_TIME_EXT::comp_sig_mode. Depending on this mode
+ * a signal value can be interpreted e.g. as signal strength (with
+ * long wave or IRIG time code receivers), or as indicator whether an
+ * antenna is connected (satellite receivers), or a network link is
+ * available (PTP slaves) or not, and an appropriate status message
+ * can be displayed.
+ *
+ * @see @ref PCPS_SIG_VAL_DEFS
+ */
+enum COMP_SIG_MODES
+{
+ COMP_SIG_MODE_NONE, ///< signal value not used
+ COMP_SIG_MODE_SIGNAL, ///< input signal strength
+ COMP_SIG_MODE_ANT_CONN, ///< antenna connection state
+ COMP_SIG_MODE_PORT_LINK, ///< port link state
+ N_CONN_SIG_MODES
+};
+
+
+/**
+ * @brief Flag bits indicating if some extended status is available
+ *
+ * @see ::PCPS_TIME_EXT_FLAGS
+ */
+enum PCPS_TIME_EXT_FLAG_BITS
+{
+ PCPS_TIME_EXT_FLAG_BIT_UTC_VALID, ///< ::PCPS_TIME_EXT::utc_offs field is valid
+ N_PCPS_TIME_EXT_FLAG_BITS
+};
+
+
+/**
+ * @brief Flag masks used with ::PCPS_TIME_EXT::flags
+ *
+ * @see ::PCPS_TIME_EXT_FLAG_BITS
+ */
+enum PCPS_TIME_EXT_FLAGS
+{
+ PCPS_TIME_EXT_FLAG_UTC_VALID = ( 1UL << PCPS_TIME_EXT_FLAG_BIT_UTC_VALID ) ///< see ::PCPS_TIME_EXT_FLAG_BIT_UTC_VALID
+};
+
+
+
+_ext BAUD_RATE mbg_baud_rate[N_MBG_BAUD_RATES]
+#ifdef _DO_INIT
+ = MBG_BAUD_RATES
+#endif
+;
+
+_ext const char *mbg_baud_str[N_MBG_BAUD_RATES]
+#ifdef _DO_INIT
+ = MBG_BAUD_STRS
+#endif
+;
+
+_ext const char *mbg_framing_str[N_MBG_FRAMINGS]
+#ifdef _DO_INIT
+ = MBG_FRAMING_STRS
+#endif
+;
+
+_ext const char *str_unknown
+#ifdef _DO_INIT
+ = "unknown"
+#endif
+;
+
+
+_ext const char *str_undefined
+#ifdef _DO_INIT
+ = "(undefined)"
+#endif
+;
+
+
+_ext const char *str_not_spc
+#ifdef _DO_INIT
+ = "not "
+#endif
+;
+
+
+
+//### TODO
+#define DEFAULT_MAX_STR_TYPE 2 // DEFAULT_N_STR_TYPE_GPS ?
+
+_ext STR_TYPE_INFO default_str_type_info[DEFAULT_MAX_STR_TYPE]
+#ifdef _DO_INIT
+ = {
+ { DEFAULT_STR_MODES, "Default Time String", "Time", 0 },
+ { DEFAULT_STR_MODES_UCAP, "Capture String", "Cap", 0 }
+ }
+#endif
+;
+
+
+
+_ext const char *mbg_gpio_type_names[N_MBG_GPIO_TYPES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_TYPES_SHORT_STRS
+#endif
+;
+
+#define _get_gpio_type_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_TYPES ) ? mbg_gpio_type_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_port_state_names[N_MBG_GPIO_PORT_STATES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_PORT_STATE_NAMES
+#endif
+;
+
+#define _get_gpio_port_state_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_PORT_STATES ) ? mbg_gpio_port_state_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_signal_shape_names[N_MBG_GPIO_SIGNAL_SHAPES]
+#ifdef _DO_INIT
+ = DEFAULT_GPIO_SIGNAL_SHAPE_NAMES
+#endif
+;
+
+#define _get_gpio_signal_shape_name( _i ) \
+ ( ( (_i) < N_MBG_GPIO_SIGNAL_SHAPES ) ? mbg_gpio_signal_shape_names[_i] : str_unknown )
+
+
+
+_ext const char *mbg_gpio_fixed_freq_strs[N_MBG_GPIO_FIXED_FREQ]
+#ifdef _DO_INIT
+ = MBG_GPIO_FIXED_FREQ_STRS
+#endif
+;
+
+#define _get_gpio_fixed_freq_str( _i ) \
+ ( ( (_i) < N_MBG_GPIO_FIXED_FREQ ) ? mbg_gpio_fixed_freq_strs[_i] : str_unknown )
+
+
+
+_ext const char *xmr_holdover_status_mode_names[N_XMR_HOLDOVER_STATUS_MODES]
+#ifdef _DO_INIT
+ = XMR_HOLDOVER_STATUS_MODE_NAMES
+#endif
+;
+
+#define _get_xmr_holdover_status_mode_name( _i ) \
+ ( ( (_i) < N_XMR_HOLDOVER_STATUS_MODES ) ? xmr_holdover_status_mode_names[_i] : str_unknown )
+
+
+
+/**
+ * @brief Count the number of bits which are not 0
+ *
+ * @param[in] val Value to be tested
+ *
+ * @return The number of non-zero bits in val
+ */
+static __mbg_inline
+int num_bits_set( long val )
+{
+ int bits_set = 0;
+ size_t i;
+
+ for ( i = 0; i < ( 8 * sizeof( val ) ); i++ )
+ {
+ if ( val & 1 )
+ bits_set++;
+
+ val >>= 1;
+ }
+
+ return bits_set;
+
+} // num_bits_set
+
+
+
+/**
+ * @brief Check if a device ID refers to a serial port
+ *
+ * @param[in] dev_id A string with the device name or port name
+ *
+ * @see ::DEFAULT_SERIAL_DEVICE_NAME
+ *
+ * @return true if the device id contains the name of a serial port, else false
+ */
+static __mbg_inline
+bool device_id_is_serial( const char *dev_id )
+{
+ #if defined( MBG_TGT_WIN32 )
+ //##++++ There may be also serial ports under Windows
+ // which don't have "COM" in their name.
+ return strstr( dev_id, "COM" ) != NULL;
+ #elif defined( MBG_TGT_LINUX )
+ return strstr( dev_id, "/dev/ttyS" ) != NULL // standard serial device
+ || strstr( dev_id, "/dev/ttyUSB" ) != NULL; // serial-to-USB adapter
+ #elif defined( MBG_TGT_FREEBSD )
+ return strstr( dev_id, "/dev/ttyu" ) != NULL // dial-in device (standard), FreeBSD 10 and newer
+ || strstr( dev_id, "/dev/cuau" ) != NULL // dial out device, FreeBSD 10 and newer
+ || strstr( dev_id, "/dev/ttyd" ) != NULL // dial-in device (standard), before FreeBSD 10
+ || strstr( dev_id, "/dev/cuad" ) != NULL; // dial-out device, before FreeBSD 10
+ #elif defined( MBG_TGT_NETBSD )
+ // TODO This is just an ugly hack which identifies
+ // some traditional device names as serial ports.
+ // There are quite a few other possible names.
+ // See "man 4 com" and "man 4 tty".
+ return strstr( dev_id, "/dev/tty0" ) != NULL // traditional dial-in devices
+ || strstr( dev_id, "/dev/dty0" ) != NULL; // traditional dial-out devices
+ #elif defined( MBG_TGT_QNX_NTO )
+ return strstr( dev_id, "/dev/ser" ) != NULL;
+ #elif defined( MBG_TGT_DOS )
+ return strstr( dev_id, "COM" ) != NULL;
+ #else
+ #error device_id_is_serial() needs to be implemented for this platform
+ #endif
+
+} // device_id_is_serial
+
+
+
+/**
+ * @brief Check if a device ID refers to a LAN connection
+ *
+ * @param[in] dev_id A string with the device ID
+ *
+ * @return true if the device id specifies a LAN connection, else false
+ */
+static __mbg_inline
+bool device_id_is_lan( const char *dev_id )
+{
+ return strstr( dev_id, "LAN" ) != NULL;
+
+} // device_id_is_lan
+
+
+
+#if defined( _PRELIMINARY_CODE )
+
+static __mbg_inline
+MBG_TLV_UID mbg_tlv_create_id( void )
+{
+#if defined( MBG_TGT_LINUX ) ///### FIXME for FreeBSD and Windows
+ struct sysinfo info;
+
+ // Linux specific, implement Windows equivalent
+ sysinfo( &info );
+ return ( (MBG_TLV_UID) ( ( time( NULL ) >> 16 ) | ( info.uptime << 16 ) ) );
+#else
+ return 0;
+#endif
+} // mbg_tlv_create_id
+
+#endif // defined( _PRELIMINARY_CODE )
+
+
+
+#if !defined( MBG_TGT_KERNEL )
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Check if a software revision name should be displayed
+ *
+ * The software revision name is usually empty, except if the
+ * firmware is a customized version, in which case the field
+ * contains an identifier string.
+ *
+ * There are some standard firmware versions where this string
+ * is not empty but padded with spaces, etc., so we try to
+ * clean this up and display the string properly, if appropriate.
+ *
+ * @param[in,out] p The ::SW_REV name to check
+ * @param[in] verbose The app's verbosity level
+ *
+ * @return != 0 if SW name should be displayed
+ */
+ int chk_sw_rev_name( SW_REV *p, int verbose ) ;
+
+ int get_str_idx( const char *search, const char *str_table[], int n_entries ) ;
+ int get_baud_rate_idx( BAUD_RATE baud_rate ) ;
+ int get_framing_idx( const char *framing ) ;
+ void port_settings_from_port_parm_mode( PORT_SETTINGS *p_ps, uint8_t pp_mode, int str_type_cap ) ;
+ void port_parm_mode_from_port_settings( uint8_t *pp_mode, const PORT_SETTINGS *p_ps, int str_type_cap ) ;
+ void port_settings_from_port_parm( PORT_SETTINGS *p_ps, int port_num, const PORT_PARM *p_pp, int cap_str_idx ) ;
+ void port_parm_from_port_settings( PORT_PARM *p_pp, int port_num, const PORT_SETTINGS *p_ps, int cap_str_idx ) ;
+ uint32_t check_valid_port_info( const PORT_INFO *p_pi, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ;
+ int valid_port_info( const PORT_INFO *p_pi, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ;
+ int setup_port_info_from_port_settings( PORT_INFO_IDX pii[], const PORT_PARM *p_pp, const RECEIVER_INFO *p_ri ) ;
+ int setup_default_str_type_info_idx( STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ;
+ int chk_set_n_gnss_supp( ALL_GNSS_INFO *p_agi ) ;
+ /**
+ * @brief
+ *
+ * ### Setup GNSS info from stat_info so we can use the same printing routine
+ */
+ void setup_gps_only_sat_info_idx_from_statinfo( ALL_GNSS_INFO *p_agi ) ;
+
+ /**
+ * @brief
+ *
+ * Setup GNSS info from stat_info so we can use the same printing routine
+ */
+ int setup_gps_only_gnss_info_from_statinfo( ALL_GNSS_INFO *p_agi ) ;
+
+ void chk_free_dev_hw_id( DEVICE_INFO *p ) ;
+ int alloc_dev_hw_id( DEVICE_INFO *p, size_t len ) ;
+ const char *get_fw_id_from_hw_id( const char *hw_id ) ;
+ const char *get_hw_id_from_fw_id( const char *fw_id ) ;
+ /**
+ * @brief Returns the currently used ::MBG_IO_PORT_TYPE_INFO_IDX for the appropriate ::MBG_IO_PORT_INFO_IDX
+ *
+ * @param[in] all_io_port_info Pointer to the ::ALL_IO_PORT_INFO, containing the current configuration
+ * @param[in] io_port_info_idx Pointer to the ::MBG_IO_PORT_INFO_IDX, for which the ::MBG_IO_PORT_TYPE_INFO_IDX shall be found
+ *
+ * @return Pointer to the ::MBG_IO_PORT_TYPE_INFO_IDX found, or NULL
+ */
+ MBG_IO_PORT_TYPE_INFO_IDX *get_io_port_type_info_idx( ALL_IO_PORT_INFO *all_io_port_info, MBG_IO_PORT_INFO_IDX *io_port_info_idx ) ;
+
+ /**
+ * @brief Initializes a ::MBG_TLV_ANNOUNCE structure
+ *
+ * @param[out] tlv Pointer to a ::MBG_TLV_ANNOUNCE structure
+ * @param[in] uid Unique sender ID used as identifier with all
+ * subsequent messages related to this transaction.
+ * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES
+ * @param[in] total_bytes Total number of bytes of all upcoming TLVs
+ */
+ void mbg_tlv_announce_init( MBG_TLV_ANNOUNCE *tlv, MBG_TLV_UID uid, MBG_TLV_TYPE tlv_feat_type, uint32_t total_bytes ) ;
+
+ /**
+ * @brief Initializes a ::MBG_TLV
+ *
+ * @param[out] tlv Pointer to a valid ::MBG_TLV structure
+ * @param[in] uid Unique sender ID used as identifier for each further
+ * TLV message related to this type.
+ * @param[in] tlv_type Type identifier, see ::MBG_TLV_TYPES
+ * @param[in] total_bytes Total number of bytes belonging to this
+ * TLV transaction (which is very likely split into several TLVs)
+ */
+ void mbg_tlv_init( MBG_TLV *tlv, MBG_TLV_UID uid, MBG_TLV_TYPE tlv_type, uint32_t total_bytes ) ;
+
+ /**
+ * @brief Initializes ::MBG_TLV_RCV_STATE structure
+ *
+ * @param[in,out] state Pointer to ::MBG_TLV_RCV_STATE structure
+ * @param[in] uid Unique sender ID used as identifier for each further
+ * TLV message related to this type.
+ * @param[in] total_bytes Total number of bytes belonging to this
+ * TLV transaction (which is very likely split into several TLVS)
+ */
+ void mbg_tlv_rcv_state_init( MBG_TLV_RCV_STATE *state, MBG_TLV_UID uid, uint32_t total_bytes ) ;
+
+ int mbg_snprint_revision( char *buf, size_t buflen, const char *prefix, const char *suffix, uint32_t rev) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xbp_supp_nodes( const ALL_XBP_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_net_cfg_supp_stage_2( const ALL_NET_CFG_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_client( const ALL_NTP_CFG_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_server( const ALL_NTP_CFG_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_mrf_none( const ALL_XMULTI_REF_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_src_info( const ALL_XMULTI_REF_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_holdover_status( const ALL_XMULTI_REF_INFO *info ) ;
+ /*
+ * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings,
+ * but of ::MULTI_REF_TYPES.
+ * Depends on chk_dev_supp_xmulti_ref_ext_src_info.
+ * @see chk_dev_supp_xmulti_ref_ext_src_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_stats( const ALL_XMULTI_REF_INFO *info, int type ) ;
+
+ /*
+ * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings,
+ * but of ::MULTI_REF_TYPES.
+ * Depends on chk_dev_supp_xmulti_ref_ext_src_info.
+ * @see chk_dev_supp_xmulti_ref_ext_src_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_metrics( const ALL_XMULTI_REF_INFO *info, int type ) ;
+
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_has_fdm( const ALL_IMS_INFO *info ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_enabled( const ALL_IMS_STATE *ims_state, unsigned idx ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_overload( const ALL_IMS_STATE *ims_state, unsigned idx ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_pll_locked( const ALL_IMS_STATE *ims_state, unsigned idx ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_supp_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) ;
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_dep_on_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) ;
+ /**
+ * @brief Checks whether GPIO supports status function
+ *
+ * @param[out] info Pointer to a ::ALL_GPIO_INFO structure to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::free_all_gpio_info
+ */
+ _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_has_status( const ALL_GPIO_INFO *info ) ;
+
+ /**
+ * @brief Frees ::ALL_XBP_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_XBP_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xbp_info
+ */
+ void free_all_xbp_info ( ALL_XBP_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_NET_CFG_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NET_CFG_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_net_cfg_info
+ */
+ void free_all_net_cfg_info ( ALL_NET_CFG_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_NET_STATUS_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NET_STATUS_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_net_status_info
+ */
+ void free_all_net_status_info ( ALL_NET_STATUS_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_SNMP_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_SNMP_INFO structure, which will be freed
+ *
+ */
+ void free_all_snmp_info ( ALL_SNMP_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_MONITORING_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_MONITORING_INFO structure, which will be freed
+ *
+ */
+ void free_all_monitoring_info ( ALL_MONITORING_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_MONITORING_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_MONITORING_STATUS structure, which will be freed
+ *
+ */
+ void free_all_monitoring_status ( ALL_MONITORING_STATUS *p ) ;
+
+ /**
+ * @brief Frees ::ALL_XMULTI_REF_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_XMULTI_REF_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xmulti_ref_info
+ * @see ::mbg_get_all_xmulti_ref_info
+ */
+ void free_all_xmulti_ref_info( ALL_XMULTI_REF_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_XMULTI_REF_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_XMULTI_REF_STATUS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_xmulti_ref_status
+ * @see ::mbg_get_all_xmulti_ref_status
+ */
+ void free_all_xmulti_ref_status( ALL_XMULTI_REF_STATUS *p ) ;
+
+ /**
+ * @brief Frees ::ALL_PTP_V1_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v1_common_datasets
+ *
+ * @param[in] p Pointer to the ::ALL_PTP_V1_COMMON_DATASETS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ptp_v1_common_datasets
+ */
+ void free_all_ptp_v1_common_datasets( ALL_PTP_V1_COMMON_DATASETS *p ) ;
+
+ /**
+ * @brief Frees ::ALL_PTP_V2_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v2_common_datasets
+ *
+ * @param[in] p Pointer to the ::ALL_PTP_V2_COMMON_DATASETS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ptp_v2_common_datasets
+ */
+ void free_all_ptp_v2_common_datasets( ALL_PTP_V2_COMMON_DATASETS *p ) ;
+
+ /**
+ * @brief Frees ::ALL_NTP_CFG_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_NTP_CFG_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ntp_cfg_info
+ */
+ void free_all_ntp_cfg_info( ALL_NTP_CFG_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_NTP_STATUS structure
+ *
+ * @param[in] p Pointer to the ::ALL_NTP_STATUS structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ntp_status
+ */
+ void free_all_ntp_status( ALL_NTP_STATUS *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ims_info
+ *
+ * @param[in] p Pointer to the ::ALL_IMS_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_dev_has_ims
+ * @see ::mbgextio_get_all_ims_info
+ * @see ::mbgextio_get_all_ims_state
+ */
+ void free_all_ims_info( ALL_IMS_INFO *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ims_state
+ *
+ * @param[in] p Pointer to the ::ALL_IMS_STATE structure, which will be freed
+ *
+ * @see ::mbgextio_dev_has_ims
+ * @see ::mbgextio_get_all_ims_info
+ * @see ::mbgextio_get_all_ims_state
+ */
+ void free_all_ims_state( ALL_IMS_STATE *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_gpio_info
+ *
+ * @param[in] p Pointer to the ::ALL_GPIO_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbgextio_get_all_gpio_info
+ */
+ void free_all_gpio_info( ALL_GPIO_INFO *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_io_port_info
+ *
+ * @param[in] p Pointer to the ::ALL_IO_PORT_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_io_ports
+ * @see ::mbgextio_get_all_io_port_info
+ * @see ::mbgextio_get_all_io_port_status
+ * @see ::free_all_io_port_status
+ */
+ void free_all_io_port_info( ALL_IO_PORT_INFO *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_io_port_status
+ *
+ * @param[in] p Pointer to the ::ALL_IO_PORT_STATUS structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_io_ports
+ * @see ::mbgextio_get_all_io_port_info
+ * @see ::mbgextio_get_all_io_port_status
+ * @see ::free_all_io_port_info
+ */
+ void free_all_io_port_status( ALL_IO_PORT_STATUS *p ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_gpio_state
+ *
+ * @param[in] p Pointer to the ::ALL_GPIO_STATE structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_gpio
+ * @see ::mbgextio_get_all_gpio_state
+ */
+ void free_all_gpio_state( ALL_GPIO_STATE *p ) ;
+
+ /**
+ * Allocates memory for a new ::UCAP_ENTRY structure
+ *
+ * @return The new allocated ::UCAP_ENTRY or NULL if the calloc call was not successful
+ */
+ UCAP_ENTRY* calloc_ucap_entry( void ) ;
+
+ /**
+ * @brief Frees memory allocated by ::mbgextio_get_all_ucap_info
+ *
+ * @param[in] p Pointer to the ::ALL_UCAP_INFO structure, which will be freed
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbgextio_dev_has_ucap
+ * @see ::mbg_chk_dev_has_ucap
+ * @see ::mbgextio_get_all_ucap_info
+ * @see ::mbg_get_all_ucap_info
+ */
+ void free_all_ucap_info( ALL_UCAP_INFO *p ) ;
+
+ /**
+ * @brief Frees ::ALL_UCAP_NET_INFO structure
+ *
+ * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO structure, which will be freed
+ *
+ * @see ::mbgextio_get_all_ucap_net_info
+ */
+ void free_all_ucap_net_info( ALL_UCAP_NET_INFO *p ) ;
+
+ /**
+ * @brief Set up a ::NTP_TSTAMP structure from a hex string with a time in seconds and binary fractions
+ *
+ * @param[in] s A string with a time in seconds since NTP epoch 1900-01-01,
+ * with binary fractions separated by decimal point,
+ * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
+ * @param[out] p Address of a ::NTP_TSTAMP structure to be set up
+ *
+ * @see ::str_ntp_hex_to_nano_time_64
+ */
+ void str_ntp_hex_to_ntp_tstamp( const char *s, NTP_TSTAMP *p ) ;
+
+ /**
+ * @brief Convert a ::NTP_TSTAMP structure to a ::NANO_TIME_64 structure
+ *
+ * @param[in] p_nts The ::NTP_TSTAMP structure to be converted
+ * @param[out] p_nt64 The ::NANO_TIME_64 structure to be filled up
+ */
+ void ntp_tstamp_to_nanotime_64( const NTP_TSTAMP *p_nts, NANO_TIME_64 *p_nt64 ) ;
+
+ /**
+ * @brief Set up a ::NANO_TIME_64 structure from a hex string with a time in seconds and binary fractions
+ *
+ * @param[in] s A string with a time in seconds since epoch 1900-01-01,
+ * with binary fractions separated by decimal point,
+ * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ *
+ * @see ::str_ntp_hex_to_ntp_tstamp
+ */
+ void str_ntp_hex_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#endif // !defined( MBG_TGT_KERNEL )
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _CFG_HLP_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/charcode.h b/src/external/bsd/meinberg/dist/mbglib/common/charcode.h
new file mode 100755
index 0000000..9605c95
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/charcode.h
@@ -0,0 +1,275 @@
+
+/**************************************************************************
+ *
+ * $Id: charcode.h 1.4 2016/08/10 12:25:41 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for pcpslstr.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: charcode.h $
+ * Revision 1.4 2016/08/10 12:25:41 martin
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Revision 1.3 2015/11/11 14:55:59 martin
+ * Support Unicode and UTF-8 encodings.
+ * Revision 1.2 2014/04/24 14:13:17 martin
+ * Added new codes and conversion table initializers.
+ * Revision 1.1 2012/11/20 13:41:24 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _CHARCODE_H
+#define _CHARCODE_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+
+#if MBG_TGT_HAS_WCHAR_T
+ #include <wchar.h>
+#endif
+
+#ifdef _CHARCODE
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined( MBG_TGT_LINUX )
+
+ #define MBG_UML_UTF8
+
+#elif defined( MBG_TGT_WIN32 ) \
+ || defined( MBG_TGT_POSIX ) \
+ || defined( MBG_TGT_QNX )
+
+ #define MBG_UML_ANSI
+
+#else
+
+ #define MBG_UML_DOS
+
+#endif
+
+
+
+// upper case 'A' umlaut
+#define ANSI_UC_A_UML '\xC4' // uppercase ANSI char
+#define ANSI_US_A_UML "\xC4" // uppercase ANSI string literal
+
+#define DOS_UC_A_UML '\x8E' // uppercase DOS char
+#define DOS_US_A_UML "\x8E" // uppercase DOS string literal
+
+#define UNICODE_US_A_UML "\u00C4" // uppercase Unicode string literal
+
+#define UTF8_US_A_UML "\xc3\x84" // uppercase UTF-8 string literal
+
+
+
+// upper case 'O' umlaut
+#define ANSI_UC_O_UML '\xD6' // uppercase ANSI char
+#define ANSI_US_O_UML "\xD6" // uppercase ANSI string literal
+
+#define DOS_UC_O_UML '\x99' // uppercase DOS char
+#define DOS_US_O_UML "\x99" // uppercase DOS string literal
+
+#define UNICODE_US_O_UML "\u00D6" // uppercase Unicode string literal
+
+#define UTF8_US_O_UML "\xc3\x96" // uppercase UTF-8 string literal
+
+
+
+// upper case 'U' umlaut
+#define ANSI_UC_U_UML '\xDC' // uppercase ANSI char
+#define ANSI_US_U_UML "\xDC" // uppercase ANSI string literal
+
+#define DOS_UC_U_UML '\x9A' // uppercase DOS char
+#define DOS_US_U_UML "\x9A" // uppercase DOS string literal
+
+#define UNICODE_US_U_UML "\u00DC" // uppercase Unicode string literal
+
+#define UTF8_US_U_UML "\xc3\x9c" // uppercase UTF-8 string literal
+
+
+
+// lower case 'a' umlaut
+#define ANSI_LC_A_UML '\xE4' // lowercase ANSI char
+#define ANSI_LS_A_UML "\xE4" // lowercase ANSI string literal
+
+#define DOS_LC_A_UML '\x84' // lowercase DOS char
+#define DOS_LS_A_UML "\x84" // lowercase DOS string literal
+
+#define UNICODE_LS_A_UML "\u00E4" // lowercase Unicode string literal
+
+#define UTF8_LS_A_UML "\xc3\xa4" // lowercase UTF-8 string literal
+
+
+
+// lower case 'o' umlaut
+#define ANSI_LC_O_UML '\xF6' // lowercase ANSI char
+#define ANSI_LS_O_UML "\xF6" // lowercase ANSI string literal
+
+#define DOS_LC_O_UML '\x94' // lowercase DOS char
+#define DOS_LS_O_UML "\x94" // lowercase DOS string literal
+
+#define UNICODE_LS_O_UML "\u00F6" // lowercase Unicode string literal
+
+#define UTF8_LS_O_UML "\xc3\xb6" // lowercase UTF-8 string literal
+
+
+
+// lower case 'u' umlaut
+#define ANSI_LC_U_UML '\xFC' // lowercase ANSI char
+#define ANSI_LS_U_UML "\xFC" // lowercase ANSI string literal
+
+#define DOS_LC_U_UML '\x81' // lowercase DOS char
+#define DOS_LS_U_UML "\x81" // lowercase DOS string literal
+
+#define UNICODE_LS_U_UML "\u00FC" // lowercase Unicode string literal
+
+#define UTF8_LS_U_UML "\xc3\xbc" // lowercase UTF-8 string literal
+
+
+
+// 'sz' umlaut
+#define ANSI_LC_SZ_UML '\xDF' // ANSI char
+#define ANSI_LS_SZ_UML "\xDF" // ANSI string literal
+
+#define DOS_LC_SZ_UML '\xE1' // DOS char
+#define DOS_LS_SZ_UML "\xE1" // DOS string literal
+
+#define UNICODE_LS_SZ_UML "\u00DF" // Unicode string literal
+
+#define UTF8_LS_SZ_UML "\xc3\x9f" // UTF-8 string literal
+
+
+
+// degree character
+#define ANSI_C_DEGREE '\xB0' // ANSI char
+#define ANSI_S_DEGREE "\xB0" // ANSI string literal
+
+#define DOS_C_DEGREE '\xF8' // DOS char
+#define DOS_S_DEGREE "\xF8" // DOS string literal
+
+#define UNICODE_S_DEGREE "\u00E0" // Unicode string liter
+
+#define UTF8_S_DEGREE "\xc2\xb0" // UTF-8 string literal
+
+
+
+// greek mu character (micro sign)
+#define ANSI_C_MU '\xB5' // ANSI char
+#define ANSI_S_MU "\xB5" // ANSI string literal
+
+#define DOS_C_MU '\xE6' // DOS char
+#define DOS_S_MU "\xE6" // DOS string literal
+
+#define UNICODE_S_MU "\u00B5" // Unicode string liter
+
+#define UTF8_S_MU "\xc2\xb5" // UTF-8 string literal
+
+
+
+#if defined( MBG_UML_UTF8 )
+
+ #define UCAE UTF8_US_A_UML
+ #define UCOE UTF8_US_O_UML
+ #define UCUE UTF8_US_U_UML
+
+ #define LCAE UTF8_LS_A_UML
+ #define LCOE UTF8_LS_O_UML
+ #define LCUE UTF8_LS_U_UML
+
+ #define LCSZ UTF8_LS_SZ_UML
+ #define DEG UTF8_S_DEGREE
+ #define MU UTF8_S_MU
+
+#elif defined( MBG_UML_ANSI )
+
+ #define UCAE ANSI_US_A_UML
+ #define UCOE ANSI_US_O_UML
+ #define UCUE ANSI_US_U_UML
+
+ #define LCAE ANSI_LS_A_UML
+ #define LCOE ANSI_LS_O_UML
+ #define LCUE ANSI_LS_U_UML
+
+ #define LCSZ ANSI_LS_SZ_UML
+ #define DEG ANSI_S_DEGREE
+ #define MU ANSI_S_MU
+
+#elif defined( MBG_UML_DOS )
+
+ #define UCAE DOS_US_A_UML
+ #define UCOE DOS_US_O_UML
+ #define UCUE DOS_US_U_UML
+
+ #define LCAE DOS_LS_A_UML
+ #define LCOE DOS_LS_O_UML
+ #define LCUE DOS_LS_U_UML
+
+ #define LCSZ DOS_LS_SZ_UML
+ #define DEG DOS_S_DEGREE
+ #define MU DOS_S_MU
+
+#else
+
+ #error Need to define default encoding for umlauts.
+
+#endif
+
+
+
+// A string initializer which can be used to set up a string
+// to check if all umlauts are displayed correctly.
+#define UMLAUTS_STRING UCAE UCOE UCUE LCAE LCOE LCUE LCSZ DEG MU
+
+
+#define ANSI_UMLAUTS \
+{ \
+ ANSI_UC_A_UML, ANSI_UC_O_UML, ANSI_UC_U_UML, \
+ ANSI_LC_A_UML, ANSI_LC_O_UML, ANSI_LC_U_UML, \
+ ANSI_LC_SZ_UML, ANSI_C_DEGREE, ANSI_C_MU, 0 \
+}
+
+
+#define DOS_UMLAUTS \
+{ \
+ DOS_UC_A_UML, DOS_UC_O_UML, DOS_UC_U_UML, \
+ DOS_LC_A_UML, DOS_LC_O_UML, DOS_LC_U_UML, \
+ DOS_LC_SZ_UML, DOS_C_DEGREE, DOS_S_MU, 0 \
+}
+
+
+/* ----- 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 /* _CHARCODE_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.c b/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.c
new file mode 100755
index 0000000..e1d1756
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.c
@@ -0,0 +1,163 @@
+
+/**************************************************************************
+ *
+ * $Id: chk_time_info.c 1.4 2017/07/05 09:00:14 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * System time checking support functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: chk_time_info.c $
+ * Revision 1.4 2017/07/05 09:00:14 martin
+ * Use safe string functions from str_util.c.
+ * Account for PCPS_HRT_BIN_FRAC_SCALE renamed
+ * to MBG_FRAC32_UNITS_PER_SEC.
+ * Revision 1.3 2013/07/30 12:55:33 martin
+ * Updated file description.
+ * Revision 1.2 2013/03/04 16:01:01 martin
+ * Use common function setup_hr_time_cycles_from_timestamp_cycles().
+ * Made snprint_chk_time_info() more flexible.
+ * Revision 1.1 2012/05/29 09:52:26 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _CHK_TIME_INFO
+ #include <chk_time_info.h>
+#undef _CHK_TIME_INFO
+
+#include <toolutil.h>
+#include <str_util.h>
+
+#include <stdio.h>
+
+
+//##++++++
+extern MBG_PC_CYCLES_FREQUENCY cyc_freq;
+
+
+static /*HDR*/
+MBG_PC_CYCLES do_filter( FILTER *p, MBG_PC_CYCLES cyc )
+{
+ if ( p->entries < MAX_FILTER_ENTRIES )
+ p->entries++;
+
+ if ( ++( p->index ) >= MAX_FILTER_ENTRIES )
+ p->index = 0;
+
+ // update the sum of filter entries
+ p->sum -= p->cyc[p->index]; // subtract oldest sample
+ p->cyc[p->index] = cyc; // save new sample
+ p->sum += cyc; // add new sample
+
+ return p->sum / p->entries; // return mean value
+
+} /* do_filter */
+
+
+
+/*HDR*/
+int mbg_chk_time_info( MBG_DEV_HANDLE dh, MBG_CHK_TIME_INFO *p, FILTER *p_filter, int fast_ts_only )
+{
+ MBG_PC_CYCLES tmp;
+ PCPS_TIME_STAMP *p_ref_ts;
+ MBG_PC_CYCLES *p_ref_cyc;
+ MBG_SYS_TIME_CYCLES *p_sys_tic;
+ int rc;
+
+ memset( p, 0, sizeof( *p ) );
+
+ if ( fast_ts_only )
+ {
+ MBG_TIME_INFO_TSTAMP tsi;
+
+ rc = mbg_get_time_info_tstamp( dh, &tsi );
+ setup_hr_time_cycles_from_timestamp_cycles( &p->hrti.ref_hr_time_cycles, &tsi.ref_tstamp_cycles );
+ p->hrti.sys_time_cycles = tsi.sys_time_cycles;
+ }
+ else
+ rc = mbg_get_time_info_hrt( dh, &p->hrti );
+
+ if ( rc < 0 )
+ return rc;
+
+
+ p_ref_ts = &p->hrti.ref_hr_time_cycles.t.tstamp;
+ p_ref_cyc = &p->hrti.ref_hr_time_cycles.cycles;
+ p_sys_tic = &p->hrti.sys_time_cycles;
+
+ p->d_ref = (double) p_ref_ts->sec + ( (double) p_ref_ts->frac ) / (double) MBG_FRAC32_UNITS_PER_SEC;
+ p->d_sys = (double) p_sys_tic->sys_time.secs + (double) p_sys_tic->sys_time.nano_secs / 1e9;
+
+ p->ltcy_cyc = mbg_delta_pc_cycles( p_ref_cyc, &p_sys_tic->cyc_after );
+ p->exec_cyc = mbg_delta_pc_cycles( &p_sys_tic->cyc_after, &p_sys_tic->cyc_before );
+ p->exec_cyc_limit = p_filter ? do_filter( p_filter, p->exec_cyc ) : 0;
+
+ if ( cyc_freq )
+ {
+ p->ltcy_sec = ( (double) p->ltcy_cyc ) / (double) cyc_freq;
+ p->exec_sec = ( (double) p->exec_cyc ) / (double) cyc_freq;
+ p->exec_sec_limit = ( (double) p->exec_cyc_limit ) / (double) cyc_freq;
+ }
+
+ // Compensate latencies between time stamps ->
+ // normalize ref time to system time stamp
+ p->d_ref_comp = p->d_ref - p->ltcy_sec;
+
+ // Try to set the limit to 1.7 of the mean execution cycles.
+ tmp = ( 7 * p->exec_cyc_limit ) / 10;
+
+ // If execution takes only a few cycles make sure the limit
+ // is above the mean number of cycles.
+ if ( tmp == 0 )
+ tmp++;
+
+ p->exec_cyc_limit += tmp;
+
+ return MBG_SUCCESS;
+
+} // mbg_chk_time_info
+
+
+
+/*HDR*/
+size_t snprint_chk_time_info( char *s, size_t max_len, const MBG_CHK_TIME_INFO *p, const PCPS_DEV *p_dev,
+ int frac_digits, int print_raw )
+{
+ size_t n = 0;
+
+ if ( p_dev )
+ n += snprintf_safe( &s[n], max_len - n, "%-9s: ", _pcps_type_name( p_dev ) );
+
+ n += mbg_snprint_hr_tstamp( &s[n], max_len - n, &p->hrti.ref_hr_time_cycles.t.tstamp, 0, 0 ); // raw timestamp?
+
+ n += snprintf_safe( &s[n], max_len - n, " %.*f %.*f ",
+ frac_digits, p->d_ref,
+ frac_digits, p->d_sys );
+
+ n += snprintf_safe( &s[n], max_len - n, "%+.*f, ltcy: ",
+ frac_digits, p->d_ref_comp - p->d_sys );
+
+
+ if ( cyc_freq ) // print latency and execution time in microseconds
+ {
+ n += snprintf_safe( &s[n], max_len - n, "%.2f us, exec: %.2f us, limit: %.2f us",
+ p->ltcy_sec * 1e6, p->exec_sec * 1e6, p->exec_sec_limit * 1e6 );
+ }
+ else // print latency and execution time in cycles only
+ {
+ n += snprintf_safe( &s[n], max_len - n, "%lli cyc, exec: %lli cyc, limit: %lli cyc",
+ (long long) p->ltcy_cyc, (long long) p->exec_cyc,
+ (long long) p->exec_cyc_limit );
+ }
+
+ if ( print_raw )
+ n += snprintf_safe( &s[n], max_len - n, ", raw: %+.*f",
+ frac_digits, p->d_ref - p->d_sys );
+
+ return n;
+
+} // snprint_chk_time_info
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.h b/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.h
new file mode 100755
index 0000000..1a66f6b
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/chk_time_info.h
@@ -0,0 +1,113 @@
+
+/**************************************************************************
+ *
+ * $Id: chk_time_info.h 1.3 2017/07/05 09:01:46 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for chk_time_info.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: chk_time_info.h $
+ * Revision 1.3 2017/07/05 09:01:46 martin
+ * Tiny cleanup.
+ * Updated function prototypes.
+ * Revision 1.2 2013/03/04 16:02:31 martin
+ * Updated function prototypes.
+ * Revision 1.1 2012/05/29 09:52:27 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _CHK_TIME_INFO_H
+#define _CHK_TIME_INFO_H
+
+
+/* Other headers to be included */
+
+#include <mbgdevio.h>
+
+
+#ifdef _CHK_TIME_INFO
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if 0 && defined( _USE_PACK ) // use default alignment
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !defined( MAX_FILTER_ENTRIES )
+ #define MAX_FILTER_ENTRIES 32
+#endif
+
+
+typedef struct
+{
+ MBG_PC_CYCLES cyc[MAX_FILTER_ENTRIES];
+ MBG_PC_CYCLES sum;
+ int entries;
+ int index;
+} FILTER;
+
+
+typedef struct
+{
+ MBG_TIME_INFO_HRT hrti;
+
+ MBG_PC_CYCLES ltcy_cyc;
+ MBG_PC_CYCLES exec_cyc;
+ MBG_PC_CYCLES exec_cyc_limit;
+
+ double ltcy_sec;
+ double exec_sec;
+ double exec_sec_limit;
+
+ double d_sys;
+ double d_ref;
+ double d_ref_comp;
+
+} MBG_CHK_TIME_INFO;
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ int mbg_chk_time_info( MBG_DEV_HANDLE dh, MBG_CHK_TIME_INFO *p, FILTER *p_filter, int fast_ts_only ) ;
+ size_t snprint_chk_time_info( char *s, size_t max_len, const MBG_CHK_TIME_INFO *p, const PCPS_DEV *p_dev, int frac_digits, int print_raw ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _CHK_TIME_INFO_H */
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/cnv_wday.h b/src/external/bsd/meinberg/dist/mbglib/common/cnv_wday.h
index 7736135..327d69d 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/cnv_wday.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/cnv_wday.h
@@ -1,7 +1,7 @@
/***************************************************************************/
/* */
-/* File: CNV_WDAY.H $Revision: 1.1 $ */
+/* File: CNV_WDAY.H $Revision: 1.2 $ */
/* */
/* Project: Common C Library */
/* */
@@ -24,18 +24,10 @@
/* */
/***************************************************************************/
-
#ifndef _CNV_WDAY_H
-
/* Other headers to be included */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifdef _CNV_WDAY
#define _ext
#else
@@ -45,6 +37,10 @@ extern "C" {
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* use the following macros if sure that the source value is in range */
@@ -80,11 +76,6 @@ extern "C" {
#define _wday_chk_sun17_to_sun06( d ) _inrng( (d), _wday_sun17_to_sun06( (d) ), 1, 0, 7, 6 )
#define _wday_chk_sun06_to_sun17( d ) _inrng( (d), _wday_sun06_to_sun17( (d) ), 0, 1, 6, 7 )
-
-/* function prototypes: */
-
-/* #include <CNV_WDAY.hdr> not needed yet */
-
/* End of header body */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ctry.c b/src/external/bsd/meinberg/dist/mbglib/common/ctry.c
index ef647d0..73cbe3f 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/ctry.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ctry.c
@@ -19,7 +19,6 @@
* by giving the different strings as function arguments.
* Revision 1.6 2007/03/29 12:21:51 martin
* New functions lstr_idx() and lstr_array_idx().
- * Revision 1.1 2010/06/01 07:57:03 philipp
* Revision 1.5 2004/10/26 07:39:37Z martin
* Use C99 fixed-size definitions where appropriate.
* Revision 1.4 2001/09/14 12:02:12 MARTIN
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ctry.h b/src/external/bsd/meinberg/dist/mbglib/common/ctry.h
index 08d1238..3d791ff 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/ctry.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ctry.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: ctry.h 1.12 2011/06/22 07:37:57 martin REL_M $
+ * $Id: ctry.h 1.14 2017/06/23 09:53:27 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,14 +10,19 @@
*
* -----------------------------------------------------------------------
* $Log: ctry.h $
- * Revision 1.12 2011/06/22 07:37:57 martin
+ * Revision 1.14 2017/06/23 09:53:27 martin
+ * Fixed spelling in an earlier log message.
+ * Revision 1.13 2012/11/29 12:01:09 martin
+ * Don't include mbg_tgt.h explicitly since this will anyway be
+ * included by words.h for non-firmware targets. So mbg_tgt.h
+ * must not necessarily be added to firmware projects.
+ * Revision 1.12 2011/06/22 07:37:57Z martin
* Cleaned up handling of pragma pack().
* Revision 1.11 2010/07/15 08:33:41 martin
* Added some macros implemented by Stefan.
* Updated function prototypes.
* Revision 1.10 2007/03/29 12:21:10 martin
* Updated function prototypes.
- * Revision 1.1 2010/06/01 07:57:04 philipp
* Revision 1.9 2004/10/26 07:38:50Z martin
* Redefined interface data types using C99 fixed-size definitions.
* Updated function prototypes.
@@ -33,11 +38,11 @@
* Revision 1.4 2000/11/27 14:13:27 MARTIN
* New types CLSTR, PLSTR, and PCLSTR.
* New macro _lstr() calls lstr_lng() for the current language.
- * Definitions associated with ctry_fmt_dt() and ctry_fmt_times()
+ * Definitions associated with ctry_fmt_dt() and ctry_fmt_times()
* have been moved to a new file ctry_fmt.h.
* Updated function prototypes.
* Revision 1.3 2000/08/17 15:35:02 MARTIN
- * No init function by default (previously DOS),
+ * No init function by default (previously DOS),
* Revision 1.2 2000/07/21 09:48:34 MARTIN
* Initial revision
*
@@ -49,7 +54,6 @@
/* Other headers to be included */
-#include <mbg_tgt.h>
#include <words.h>
#if defined( MBG_TGT_NETWARE )
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.c b/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.c
index 4d35644..d8ada7c 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: ctrydttm.c 1.5 2008/11/24 16:15:46 martin REL_M $
+ * $Id: ctrydttm.c 1.7 2015/11/09 11:22:12 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,11 +11,16 @@
*
* -----------------------------------------------------------------------
* $Log: ctrydttm.c $
- * Revision 1.5 2008/11/24 16:15:46 martin
+ * Revision 1.7 2015/11/09 11:22:12 martin
+ * Modified snprint_ctry_dt_short() and fixed snprint_ctry_dt().
+ * Revision 1.6 2015/08/31 10:00:46 martin
+ * Use safe string functions from str_util.c.
+ * This required renaming of functions and changing parameters.
+ * Revision 1.5 2008/11/24 16:15:46Z martin
* Don't use sprintf() without format string.
* Revision 1.4 2000/11/27 10:06:27 MARTIN
* Renamed local variable wday_str to lstrs_wday.
- * If macro USER_LSTR_WDAY is defined, lstrs_wday can be declared
+ * If macro USER_LSTR_WDAY is defined, lstrs_wday can be declared
* externally to override the defaults.
* Revision 1.3 2000/09/14 15:13:25 MARTIN
* Renamed sprint_short_ctry_dt() to sprint_ctry_dt_short() to match
@@ -30,6 +35,7 @@
#undef _CTRYDTTM
#include <ctry.h>
+#include <str_util.h>
#include <stdio.h>
@@ -53,45 +59,44 @@ extern LANGUAGE language;
/*HDR*/
-ushort sprint_02u( char *s, uchar uc )
+size_t snprint_02u( char *s, size_t max_len, uchar uc )
{
- return( sprintf( s, "%02u", uc ) );
+ return snprintf_safe( s, max_len, "%02u", uc );
-} // sprint_02u
+} // snprint_02u
/*HDR*/
-ushort sprint_04u( char *s, ushort us )
+size_t snprint_04u( char *s, size_t max_len, ushort us )
{
- return( sprintf( s, "%04u", us ) );
+ return snprintf_safe( s, max_len, "%04u", us );
-} // sprint_04u
+} // snprint_04u
/*HDR*/
-ushort sprint_ctry_wday( char *s, uchar wday, ushort language )
+size_t snprint_ctry_wday( char *s, size_t max_len, uchar wday, ushort language )
{
if ( language >= N_LNG )
language = LNG_ENGLISH;
- return( sprintf( s, "%s", ( wday < DAYS_PER_WEEK ) ?
- lstrs_wday[language][wday] : "--" ) );
+ return snprintf_safe( s, max_len, "%s", ( wday < DAYS_PER_WEEK ) ?
+ lstrs_wday[language][wday] : "--" );
-} // sprint_ctry_wday
+} // snprint_ctry_wday
/*HDR*/
-ushort sprint_ctry_dt_short( char *s, uchar mday, uchar month )
+size_t snprint_ctry_dt_short( char *s, size_t max_len, uchar mday, uchar month )
{
uchar tmp_1;
uchar tmp_2;
ushort n = 0;
-
- switch( ctry.dt_fmt )
+ switch ( ctry.dt_fmt )
{
case DT_FMT_YYYYMMDD:
case DT_FMT_MMDDYYYY:
@@ -106,79 +111,77 @@ ushort sprint_ctry_dt_short( char *s, uchar mday, uchar month )
} // switch
- n = sprint_02u( s, tmp_1 );
- s[n++] = ctry.dt_sep;
- n += sprint_02u( &s[n], tmp_2 );
- s[n++] = ctry.dt_sep;
- s[n] = 0;
+ n = snprint_02u( s, max_len, tmp_1 );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ctry.dt_sep );
+ n += snprint_02u( &s[n], max_len - n, tmp_2 );
- return( n );
+ return n;
-} // sprint_ctry_dt_short
+} // snprint_ctry_dt_short
/*HDR*/
-ushort sprint_ctry_dt( char *s, uchar mday, uchar month, ushort year )
+size_t snprint_ctry_dt( char *s, size_t max_len, uchar mday, uchar month, ushort year )
{
- ushort n = 0;
-
+ size_t n = 0;
if ( ctry.dt_fmt == DT_FMT_YYYYMMDD )
{
- n = sprint_04u( s, year );
- s[n++] = ctry.dt_sep;
+ n += snprint_04u( &s[n], max_len - n, year );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ctry.dt_sep );
}
- n += sprint_ctry_dt_short( &s[n], mday, month );
+ n += snprint_ctry_dt_short( &s[n], max_len - n, mday, month );
- if ( ctry.dt_fmt == DT_FMT_YYYYMMDD )
- s[--n] = 0;
- else
- n += sprint_04u( &s[n], year );
+ if ( ctry.dt_fmt != DT_FMT_YYYYMMDD )
+ {
+ n += sn_cpy_char_safe( &s[n], max_len - n, ctry.dt_sep );
+ n += snprint_04u( &s[n], max_len - n, year );
+ }
- return( n );
+ return n;
-} // sprint_ctry_dt
+} // snprint_ctry_dt
/*HDR*/
-ushort sprint_ctry_tm_short( char *s, uchar hour, uchar minute )
+size_t snprint_ctry_tm_short( char *s, size_t max_len, uchar hour, uchar minute )
{
- ushort n = sprint_02u( s, hour );
- s[n++] = ctry.tm_sep;
- n += sprint_02u( &s[n], minute );
+ size_t n = snprint_02u( s, max_len, hour );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ctry.tm_sep );
+ n += snprint_02u( &s[n], max_len - n, minute );
- return( n );
+ return n;
-} // sprint_ctry_tm_short
+} // snprint_ctry_tm_short
/*HDR*/
-ushort sprint_ctry_tm( char *s, uchar hour, uchar minute, uchar second )
+size_t snprint_ctry_tm( char *s, size_t max_len, uchar hour, uchar minute, uchar second )
{
- ushort n = sprint_ctry_tm_short( s, hour, minute );
- s[n++] = ctry.tm_sep;
- n += sprint_02u( &s[n], second );
+ size_t n = snprint_ctry_tm_short( s, max_len, hour, minute );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ctry.tm_sep );
+ n += snprint_02u( &s[n], max_len - n, second );
- return( n );
+ return n;
-} // sprint_ctry_tm
+} // snprint_ctry_tm
/*HDR*/
-ushort sprint_ctry_tm_long( char *s, uchar hour, uchar minute, uchar second,
- long frac, ushort frac_digits )
+size_t snprint_ctry_tm_long( char *s, size_t max_len, uchar hour, uchar minute,
+ uchar second, long frac, ushort frac_digits )
{
- ushort n = sprint_ctry_tm( s, hour, minute, second );
- s[n++] = '.';
- n += sprintf( &s[n], "%0*lu", frac_digits, frac );
+ size_t n = snprint_ctry_tm( s, max_len, hour, minute, second );
+ n += sn_cpy_char_safe( &s[n], max_len - n, '.' );
+ n += snprintf_safe( &s[n], max_len - n, "%0*lu", frac_digits, frac );
- return( n );
+ return n;
-} // sprint_ctry_tm_long
+} // snprint_ctry_tm_long
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.h b/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.h
index ce613d7..0d2807e 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ctrydttm.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: ctrydttm.h 1.3 2000/09/14 15:13:45 MARTIN REL_M $
+ * $Id: ctrydttm.h 1.5 2015/08/31 10:00:46 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: ctrydttm.h $
+ * Revision 1.5 2015/08/31 10:00:46 martin
+ * Fixed DOS build.
+ * Revision 1.4 2015/08/27 16:28:25Z martin
+ * Updated function prototypes.
* Revision 1.3 2000/09/14 15:13:45 MARTIN
* Updated function prototypes.
* Revision 1.2 2000/07/21 11:50:43 MARTIN
@@ -25,6 +29,8 @@
#include <ctry.h>
+#include <stdlib.h>
+
#ifdef __cplusplus
extern "C" {
@@ -49,14 +55,14 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
- ushort sprint_02u( char *s, uchar uc ) ;
- ushort sprint_04u( char *s, ushort us ) ;
- ushort sprint_ctry_wday( char *s, uchar wday, ushort language ) ;
- ushort sprint_ctry_dt_short( char *s, uchar mday, uchar month ) ;
- ushort sprint_ctry_dt( char *s, uchar mday, uchar month, ushort year ) ;
- ushort sprint_ctry_tm_short( char *s, uchar hour, uchar minute ) ;
- ushort sprint_ctry_tm( char *s, uchar hour, uchar minute, uchar second ) ;
- ushort sprint_ctry_tm_long( char *s, uchar hour, uchar minute, uchar second, long frac, ushort frac_digits ) ;
+ size_t snprint_02u( char *s, size_t max_len, uchar uc ) ;
+ size_t snprint_04u( char *s, size_t max_len, ushort us ) ;
+ size_t snprint_ctry_wday( char *s, size_t max_len, uchar wday, ushort language ) ;
+ size_t snprint_ctry_dt_short( char *s, size_t max_len, uchar mday, uchar month ) ;
+ size_t snprint_ctry_dt( char *s, size_t max_len, uchar mday, uchar month, ushort year ) ;
+ size_t snprint_ctry_tm_short( char *s, size_t max_len, uchar hour, uchar minute ) ;
+ size_t snprint_ctry_tm( char *s, size_t max_len, uchar hour, uchar minute, uchar second ) ;
+ size_t snprint_ctry_tm_long( char *s, size_t max_len, uchar hour, uchar minute, uchar second, long frac, ushort frac_digits ) ;
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.c b/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.c
new file mode 100755
index 0000000..b0a1180
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.c
@@ -0,0 +1,1717 @@
+
+/**************************************************************************
+ *
+ * $Id: deviohlp.c 1.3 2017/07/05 13:47:44 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Device configuration helper functions. This is an extension to
+ * mbgdevio.c providing useful functions to simplify reading/writing
+ * complex device configuration structure sets.
+ *
+ * Warning:
+ * These functions should not be implemented in a DLL / shared library
+ * since the parameter sizes might vary with different versions
+ * of the API calls, which which would make different versions of
+ * precompiled libraries incompatible to each other.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: deviohlp.c $
+ * Revision 1.3 2017/07/05 13:47:44 martin
+ * Many configuration functions provided by thomas-b,
+ * philipp, and martin.
+ * Revision 1.2 2012/10/15 13:48:35Z martin
+ * Added functions mbg_get_all_ptp_cfg_info(), mbg_save_all_ptp_cfg_info().
+ * Account for renamed structure.
+ * Updated doxygen comments.
+ * Revision 1.1 2011/08/03 15:37:00Z martin
+ * Initial revision with functions moved here from mbgdevio.
+ *
+ **************************************************************************/
+
+#define _DEVIOHLP
+ #include <deviohlp.h>
+#undef _DEVIOHLP
+
+#include <str_util.h>
+#include <lan_util.h>
+#include <stdio.h>
+
+
+#define DEFAULT_BAUD_RATES_DCF \
+( \
+ MBG_PORT_HAS_300 | \
+ MBG_PORT_HAS_600 | \
+ MBG_PORT_HAS_1200 | \
+ MBG_PORT_HAS_2400 | \
+ MBG_PORT_HAS_4800 | \
+ MBG_PORT_HAS_9600 \
+)
+
+#define DEFAULT_BAUD_RATES_DCF_HS \
+( \
+ 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 | \
+ MBG_PORT_HAS_38400 \
+)
+
+
+#define DEFAULT_FRAMINGS_DCF \
+( \
+ MBG_PORT_HAS_7E2 | \
+ MBG_PORT_HAS_8N1 | \
+ MBG_PORT_HAS_8N2 | \
+ MBG_PORT_HAS_8E1 \
+)
+
+
+/*HDR*/
+int chk_feat_supp( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, MBG_CHK_SUPP_FNC *chk_supp_fnc,
+ MBG_ERR_MSG_FNC *err_msg_fnc, const char *not_supp_msg )
+{
+ const char *cp = NULL;
+ int rc = MBG_SUCCESS; // assume option is supported
+
+ if ( chk_supp_fnc == NULL ) // no check function specified
+ goto out;
+
+
+ // A check function has been specified, so we must call it to check if
+ // the specific parameter/command is supported by this particular device.
+
+ if ( dh == MBG_INVALID_DEV_HANDLE )
+ {
+ cp = "Tried checking feature support with invalid device handle.";
+ rc = MBG_ERR_INV_HANDLE;
+ goto out;
+ }
+
+ rc = chk_supp_fnc( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ goto out; // return with success
+
+
+ if ( rc == MBG_ERR_NOT_SUPP_BY_DEV )
+ {
+ cp = not_supp_msg;
+ goto fail;
+ }
+
+
+ cp = "Failed to check if supported"; //##++++ TODO:proper error msg
+
+fail:
+ if ( err_msg_fnc && cp )
+ err_msg_fnc( p_dev, cp );
+
+out:
+ return rc;
+
+} // chk_feat_supp
+
+
+
+/*HDR*/
+/**
+ * @brief Read or setup all GNSS status information
+ *
+ * This function should be called preferably to get a summary of
+ * the GNSS status from GNSS receivers (GPS, GLONASS, ...).
+ *
+ * The function ::mbg_get_device_info must have been called before, and
+ * the returned ::PCPS_DEV structure has to be passed to this function.
+ *
+ * If the device supports this then the low level GNSS API functions
+ * are called directly to collect the status information. If the device
+ * doesn't support the GNSS API but is a pure GPS receiver then the GPS
+ * API functions are called and the GNSS data structures are filled up
+ * accordingly, so the calling application can always evaluate the
+ * GNSS data structures in ::ALL_GNSS_INFO.
+ *
+ * If neither GPS nor another GNSS system is supported then this function
+ * returns the ::MBG_ERR_NOT_SUPP_BY_DEV error.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p_agi Pointer to a ::ALL_GNSS_INFO to be filled
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_get_gps_stat_info
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ */
+int mbg_chk_get_all_gnss_info( MBG_DEV_HANDLE dh, ALL_GNSS_INFO *p_agi )
+{
+ int rc = MBG_ERR_UNSPEC;
+
+ memset( p_agi, 0, sizeof( *p_agi ) );
+
+ // First we check if the device is a GPS receiver,
+ // which includes GNSS receivers.
+ rc = mbg_chk_dev_is_gps( dh );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ // Read the STAT_INFO structure which is supported by all GPS
+ // and GNSS receivers.
+ rc = mbg_get_gps_stat_info( dh, &p_agi->stat_info );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ // Check if the device is a GNSS receiver, i.e. can track satellites
+ // from different systems (GPS, GLONASS, Beidou, ...).
+ rc = mbg_chk_dev_is_gnss( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ // The device is a GNSS receiver, i.e. it can track satellites
+ // from different systems (GPS, GLONASS, Beidou, ...).
+ // Read some specific GNSS information.
+ rc = mbg_get_gps_gnss_mode_info( dh, &p_agi->gnss_mode_info );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ rc = chk_set_n_gnss_supp( p_agi );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ // If the the device supports the current API we can simply
+ // retrieve status information for each individual GNSS system.
+ rc = mbg_get_gps_all_gnss_sat_info( dh, p_agi->gnss_sat_info_idx, &p_agi->gnss_mode_info );
+ goto out;
+ }
+
+
+ // If we get here then the device is a pure GPS receiver
+ // which neither supports additional GNSS systems nor the
+ // associated data structures, so we set up all GNSS
+ // data structures for GPS only.
+ rc = setup_gps_only_gnss_info_from_statinfo( p_agi );
+
+out:
+ return rc;
+
+} // mbg_chk_get_all_gnss_info
+
+
+
+#if !MBGDEVIO_SIMPLE
+
+/*HDR*/
+/**
+ * @brief 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 have to 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[in] dh Valid handle to a Meinberg device
+ * @param[in] *p_dev Pointer to a valid ::PCPS_DEV structure
+ * @param[out] *p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure to be filled up
+ * @param[in] *p_ri Pointer to a valid ::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
+ */
+int mbg_get_serial_settings( MBG_DEV_HANDLE dh,
+ const PCPS_DEV *p_dev,
+ RECEIVER_PORT_CFG *p_rpcfg,
+ const RECEIVER_INFO *p_ri )
+{
+ int rc;
+
+ memset( p_rpcfg, 0, sizeof( *p_rpcfg ) );
+
+ if ( _pcps_has_receiver_info( p_dev ) )
+ {
+ // The device provides a RECEIVER_INFO, so we can simply read all
+ // serial port configuration and supported string types directly.
+
+ rc = mbg_get_gps_all_port_info( dh, p_rpcfg->pii, p_ri );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ rc = mbg_get_gps_all_str_type_info( dh, p_rpcfg->stii, p_ri );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+ }
+ else
+ {
+ // The device doesn't support a RECEIVER_INFO, so this is
+ // an old GPS or non-GPS device.
+
+ if ( _pcps_is_gps( p_dev ) )
+ {
+ // Read the serial port configuration from an old GPS device using
+ // a legacy API call and set up current structures accordingly.
+
+ rc = mbg_get_gps_port_parm( dh, &p_rpcfg->tmp_pp );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ rc = setup_port_info_from_port_settings( p_rpcfg->pii, &p_rpcfg->tmp_pp, p_ri );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ // Also set up default string type information.
+ rc = setup_default_str_type_info_idx( p_rpcfg->stii, p_ri );
+ }
+ else
+ {
+ // Not all legacy non-GPS clocks have a serial port.
+ if ( _pcps_has_serial( p_dev ) )
+ {
+ // Read the serial port configuration from an old non-GPS device using
+ // a legacy API call and set up current structures accordingly.
+
+ PCPS_SERIAL ser_code;
+
+ rc = mbg_get_serial( dh, &ser_code );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ port_info_from_pcps_serial( p_rpcfg->pii, ser_code,
+ _pcps_has_serial_hs( p_dev ) ?
+ DEFAULT_BAUD_RATES_DCF_HS :
+ DEFAULT_BAUD_RATES_DCF
+ );
+ // Also set up default string type information.
+ rc = setup_default_str_type_info_idx( p_rpcfg->stii, p_ri );
+ }
+ }
+
+ }
+
+ rc = MBG_SUCCESS;
+
+out:
+ return rc;
+
+} // mbg_get_serial_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Write the configuration settings for a single serial port to a device
+ *
+ * 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
+ * vave to be passed to this function.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] *p_dev Pointer to a valid ::PCPS_DEV structure
+ * @param[in] *p_rpcfg Pointer to a valid ::RECEIVER_PORT_CFG structure
+ * @param[in] 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
+ */
+int mbg_save_serial_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev,
+ RECEIVER_PORT_CFG *p_rpcfg, int port_num )
+{
+ int rc;
+
+ if ( _pcps_has_receiver_info( p_dev ) )
+ {
+ rc = mbg_set_gps_port_settings( dh, &p_rpcfg->pii[port_num].port_info.port_settings, port_num );
+ }
+ else
+ {
+ if ( _pcps_is_gps( p_dev ) )
+ {
+ port_parm_from_port_settings( &p_rpcfg->tmp_pp, port_num,
+ &p_rpcfg->pii[port_num].port_info.port_settings, 1 );
+
+ rc = mbg_set_gps_port_parm( dh, &p_rpcfg->tmp_pp );
+ }
+ else
+ {
+ PCPS_SERIAL ser_code;
+
+ pcps_serial_from_port_info( &ser_code, p_rpcfg->pii );
+
+ rc = mbg_set_serial( dh, &ser_code );
+ }
+ }
+
+ return rc;
+
+} // mbg_save_serial_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read all network configuration into an ::ALL_NET_CFG_INFO structure
+ *
+ * Reads the network configuration of a device via the LAN_IP4 API and
+ * translates the structures into NET_CFG structures.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * A ::ALL_NET_CFG_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX,
+ * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and
+ * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later
+ * by calling ::free_all_net_cfg_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_NET_CFG_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ * @see ::free_all_net_cfg_info
+ */
+int mbg_get_all_net_cfg_info( MBG_DEV_HANDLE dh, ALL_NET_CFG_INFO **p )
+{
+ ALL_NET_CFG_INFO *net_cfg_info = *p;
+ int rc;
+
+ if ( net_cfg_info == NULL )
+ {
+ net_cfg_info = ( ALL_NET_CFG_INFO * )calloc( 1, sizeof( *net_cfg_info ) );
+ if ( net_cfg_info == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ // TODO Use NET_CFG API as soon as its available for PCI/PCIe devices
+ rc = mbg_chk_dev_has_lan_intf( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ LAN_IF_INFO lan_if_info;
+ IP4_SETTINGS ip4_settings;
+
+ if ( net_cfg_info->glb_cfg_info.n_supp_intf_link != 0 )
+ goto out;
+
+ rc = mbg_get_lan_if_info( dh, &lan_if_info );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if ( net_cfg_info->link_infos == NULL )
+ {
+ net_cfg_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )calloc( 1, sizeof( *net_cfg_info->link_infos ) );
+ if ( net_cfg_info->link_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_cfg_info->glb_cfg_info.glb_settings.num_intf_link = 1;
+
+ memset( &net_cfg_info->link_infos[0], 0, sizeof( net_cfg_info->link_infos[0] ) );
+
+ net_cfg_info->link_infos[0].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_cfg_info->link_infos[0].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_PHYS | MBG_NET_INTF_LINK_TYPE_MASK_VLAN;
+ net_cfg_info->link_infos[0].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL;
+ net_cfg_info->link_infos[0].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP;
+
+ snprintf_safe( net_cfg_info->link_infos[0].info.link_settings.name, sizeof( net_cfg_info->link_infos[0].info.link_settings.name ), "lan0" );
+ net_cfg_info->link_infos[0].info.link_settings.mac_addr = lan_if_info.mac_addr;
+ net_cfg_info->link_infos[0].info.link_settings.if_index = 0;
+ net_cfg_info->link_infos[0].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_PHYS;
+ net_cfg_info->link_infos[0].info.link_settings.port_type = MBG_NET_INTF_LINK_PORT_TYPE_TP;
+
+ if ( net_cfg_info->glb_cfg_info.n_supp_intf_addr != 0 )
+ goto out;
+
+ rc = mbg_get_ip4_settings( dh, &ip4_settings );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if( ip4_settings.flags & IP4_MSK_LINK )
+ {
+ net_cfg_info->link_infos->info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_cfg_info->link_infos->info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP;
+ }
+
+ if ( net_cfg_info->addr_infos == NULL )
+ {
+ net_cfg_info->addr_infos = ( MBG_NET_INTF_ADDR_INFO_IDX * )calloc( 1, sizeof( *net_cfg_info->addr_infos ) );
+ if ( net_cfg_info->addr_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_cfg_info->glb_cfg_info.glb_settings.num_intf_addr = 1;
+
+ memset( &net_cfg_info->addr_infos[0], 0, sizeof( net_cfg_info->addr_infos[0] ) );
+
+ net_cfg_info->addr_infos[0].info.supp_flags = MBG_NET_INTF_ADDR_MASK_DHCP4;
+
+ snprintf_safe( net_cfg_info->addr_infos[0].info.addr_settings.label, sizeof( net_cfg_info->addr_infos[0].info.addr_settings.label ), "lan0:0" );
+
+ if ( ip4_settings.flags & IP4_MSK_VLAN )
+ {
+ net_cfg_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_cfg_info->link_infos, 2 * sizeof( *net_cfg_info->link_infos ) );
+ if ( net_cfg_info->link_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+
+ net_cfg_info->glb_cfg_info.glb_settings.num_intf_link = 2;
+
+ memset(&net_cfg_info->link_infos[1], 0, sizeof(net_cfg_info->link_infos[1]));
+
+ net_cfg_info->link_infos[1].idx = 1;
+ net_cfg_info->link_infos[1].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_cfg_info->link_infos[1].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_VLAN;
+ net_cfg_info->link_infos[1].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL;
+ net_cfg_info->link_infos[1].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP;
+
+ snprintf_safe( net_cfg_info->link_infos[1].info.link_settings.name, sizeof( net_cfg_info->link_infos[1].info.link_settings.name ), "vlan0" );
+ net_cfg_info->link_infos[1].info.link_settings.mac_addr = net_cfg_info->link_infos[0].info.link_settings.mac_addr;
+ net_cfg_info->link_infos[1].info.link_settings.if_index = 1;
+ net_cfg_info->link_infos[1].info.link_settings.ass_if_index = 0;
+ net_cfg_info->link_infos[1].info.link_settings.states = net_cfg_info->link_infos[0].info.link_settings.states;
+ net_cfg_info->link_infos[1].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_VLAN;
+ net_cfg_info->link_infos[1].info.link_settings.vlan_cfg = ip4_settings.vlan_cfg;
+
+ net_cfg_info->addr_infos[0].info.addr_settings.ass_if_index = 1;
+ }
+
+ if ( ip4_settings.flags & IP4_MSK_DHCP )
+ net_cfg_info->addr_infos[0].info.addr_settings.flags |= MBG_NET_INTF_ADDR_MASK_DHCP4;
+
+ net_cfg_info->addr_infos[0].info.addr_settings.ip.type = MBG_IP_ADDR_TYPE_IP4;
+ net_cfg_info->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr = ip4_settings.ip_addr;
+
+ net_cfg_info->addr_infos[0].info.addr_settings.broadcast.type = MBG_IP_ADDR_TYPE_IP4;
+ net_cfg_info->addr_infos[0].info.addr_settings.broadcast.u_addr.ip4_addr = ip4_settings.broad_addr;
+
+ net_cfg_info->addr_infos[0].info.addr_settings.prefix_bits = get_ip4_net_mask_bits(&ip4_settings.netmask);
+
+ if ( net_cfg_info->glb_cfg_info.n_supp_intf_route == 0 )
+ {
+ if ( net_cfg_info->route_infos == NULL )
+ {
+ net_cfg_info->route_infos = ( MBG_NET_INTF_ROUTE_INFO_IDX * )calloc( 1, sizeof( *net_cfg_info->route_infos ) );
+ if ( net_cfg_info->route_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_cfg_info->glb_cfg_info.glb_settings.num_intf_route = 1;
+
+ memset( &net_cfg_info->route_infos[0], 0, sizeof( net_cfg_info->route_infos[0] ) );
+
+ net_cfg_info->route_infos[0].info.route_settings.type = MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY;
+ net_cfg_info->route_infos[0].info.route_settings.gateway.type = MBG_IP_ADDR_TYPE_IP4;
+ net_cfg_info->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr = ip4_settings.gateway;
+ if ( ip4_settings.gateway != 0 )
+ {
+ if(net_cfg_info->glb_cfg_info.glb_settings.num_intf_link == 2)
+ net_cfg_info->route_infos[0].info.route_settings.ass_if_index = 1;
+ }
+ else net_cfg_info->route_infos[0].info.route_settings.ass_if_index = (uint32_t)-1;
+
+ }
+
+ }
+
+out:
+ if ( mbg_rc_is_error( rc ) )
+ {
+ free_all_net_cfg_info( net_cfg_info );
+ net_cfg_info = NULL;
+ }
+
+ *p = net_cfg_info;
+
+ return rc;
+
+} // mbg_get_all_net_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Write all network settings to a device
+ *
+ * The complementary function ::mbg_get_all_net_cfg_info should
+ * have been used to read the original network settings and
+ * supported configuration parameters.
+ *
+ * The appropriate settings are translated into LAN_IP4 structures
+ * and send to the device using the appropriate API functions.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] p Pointer to a pointer of ::ALL_NET_CFG_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_set_ip4_settings
+ */
+int mbg_save_all_net_cfg_info( MBG_DEV_HANDLE dh, ALL_NET_CFG_INFO *p )
+{
+ // TODO: Use NET_CFG API as soon as its available for PCI/PCIe devices
+ int rc = mbg_chk_dev_has_lan_intf( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ IP4_SETTINGS ip4_settings;
+ memset( &ip4_settings, 0, sizeof( ip4_settings ) );
+
+ if ( p->addr_infos[0].info.addr_settings.ip.type == MBG_IP_ADDR_TYPE_IP4 )
+ ip4_settings.ip_addr = p->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr;
+
+ ip4_settings.netmask = ip4_net_mask_from_cidr( p->addr_infos[0].info.addr_settings.prefix_bits );
+ ip4_settings.broad_addr = ip4_broad_addr_from_addr( &ip4_settings.ip_addr, &ip4_settings.netmask );
+
+ if ( p->route_infos[0].info.route_settings.gateway.type == MBG_IP_ADDR_TYPE_IP4 )
+ ip4_settings.gateway = p->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr;
+
+ if ( ( p->glb_cfg_info.glb_settings.num_intf_link > 1 ) && ( p->addr_infos[0].info.addr_settings.ass_if_index == 1 ) )
+ {
+ ip4_settings.flags |= IP4_MSK_VLAN;
+ ip4_settings.vlan_cfg = p->link_infos[1].info.link_settings.vlan_cfg;
+ }
+
+ if ( ( p->addr_infos[0].info.addr_settings.flags & MBG_NET_INTF_ADDR_MASK_DHCP4 ) == MBG_NET_INTF_ADDR_MASK_DHCP4 )
+ ip4_settings.flags |= IP4_MSK_DHCP;
+
+ rc = mbg_set_ip4_settings( dh, &ip4_settings );
+ }
+
+ return rc;
+
+} // mbg_save_all_net_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Read current network status into an ::ALL_NET_STATUS_INFO structure
+ *
+ * Reads the network status of a device via the LAN_IP4 API and
+ * translates the structures into NET_CFG structures.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * A ::ALL_NET_STATUS_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX,
+ * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and
+ * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later
+ * by calling ::free_all_net_status_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_NET_STATUS_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::free_all_net_status_info
+ */
+int mbg_get_all_net_status_info( MBG_DEV_HANDLE dh, ALL_NET_STATUS_INFO **p )
+{
+ ALL_NET_STATUS_INFO *net_status_info = *p;
+ int rc;
+
+ if ( net_status_info == NULL )
+ {
+ net_status_info = ( ALL_NET_STATUS_INFO * )calloc( 1, sizeof( *net_status_info ) );
+ if ( net_status_info == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ // TODO Use NET_CFG API as soon as its available for PCI/PCIe devices
+ rc = mbg_chk_dev_has_lan_intf( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ LAN_IF_INFO lan_if_info;
+ IP4_SETTINGS ip4_state;
+
+ if ( net_status_info->glb_cfg_info.n_supp_intf_link != 0 )
+ goto out;
+
+ rc = mbg_get_lan_if_info( dh, &lan_if_info );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if ( net_status_info->link_infos == NULL )
+ {
+ net_status_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )calloc( 1, sizeof( *net_status_info->link_infos ) );
+ if ( net_status_info->link_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_status_info->glb_cfg_info.glb_settings.num_intf_addr = 1;
+
+ memset( &net_status_info->link_infos[0], 0, sizeof( net_status_info->link_infos[0] ) );
+
+ net_status_info->link_infos[0].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_status_info->link_infos[0].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_PHYS | MBG_NET_INTF_LINK_TYPE_MASK_VLAN;
+ net_status_info->link_infos[0].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL;
+ net_status_info->link_infos[0].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP;
+
+ snprintf_safe( net_status_info->link_infos[0].info.link_settings.name, sizeof( net_status_info->link_infos[0].info.link_settings.name ), "lan0" );
+ net_status_info->link_infos[0].info.link_settings.mac_addr = lan_if_info.mac_addr;
+ net_status_info->link_infos[0].info.link_settings.if_index = 0;
+ net_status_info->link_infos[0].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_PHYS;
+ net_status_info->link_infos[0].info.link_settings.port_type = MBG_NET_INTF_LINK_PORT_TYPE_TP;
+
+ if ( net_status_info->glb_cfg_info.n_supp_intf_addr != 0 )
+ goto out;
+
+ rc = mbg_get_ip4_state( dh, &ip4_state );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if( ip4_state.flags & IP4_MSK_LINK )
+ {
+ net_status_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_status_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP;
+ }
+
+ if ( net_status_info->addr_infos == NULL )
+ {
+ net_status_info->addr_infos = ( MBG_NET_INTF_ADDR_INFO_IDX * )realloc( net_status_info->addr_infos, sizeof( *net_status_info->addr_infos ) );
+ if ( net_status_info->addr_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_status_info->glb_cfg_info.glb_settings.num_intf_addr = 1;
+
+ memset( &net_status_info->addr_infos[0], 0, sizeof( net_status_info->addr_infos[0] ) );
+
+ net_status_info->addr_infos[0].info.supp_flags = MBG_NET_INTF_ADDR_MASK_DHCP4;
+
+ snprintf_safe( net_status_info->addr_infos[0].info.addr_settings.label, sizeof( net_status_info->addr_infos[0].info.addr_settings.label ), "lan0:0" );
+
+ if ( ip4_state.flags & IP4_MSK_VLAN )
+ {
+ net_status_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_status_info->link_infos, 2 * sizeof( *net_status_info->link_infos ) );
+ if ( net_status_info->link_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+
+ net_status_info->glb_cfg_info.glb_settings.num_intf_link = 2;
+
+ memset(&net_status_info->link_infos[1], 0, sizeof(net_status_info->link_infos[1]));
+
+ net_status_info->link_infos[1].idx = 1;
+ net_status_info->link_infos[1].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP;
+ net_status_info->link_infos[1].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_VLAN;
+ net_status_info->link_infos[1].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL;
+ net_status_info->link_infos[1].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP;
+
+ snprintf_safe( net_status_info->link_infos[1].info.link_settings.name, sizeof( net_status_info->link_infos[1].info.link_settings.name ), "vlan0" );
+ net_status_info->link_infos[1].info.link_settings.mac_addr = net_status_info->link_infos[0].info.link_settings.mac_addr;
+ net_status_info->link_infos[1].info.link_settings.if_index = 1;
+ net_status_info->link_infos[1].info.link_settings.ass_if_index = 0;
+ net_status_info->link_infos[1].info.link_settings.states = net_status_info->link_infos[0].info.link_settings.states;
+ net_status_info->link_infos[1].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_VLAN;
+ net_status_info->link_infos[1].info.link_settings.vlan_cfg = ip4_state.vlan_cfg;
+
+ net_status_info->addr_infos[0].info.addr_settings.ass_if_index = 1;
+ }
+
+ if ( ip4_state.flags & IP4_MSK_DHCP )
+ net_status_info->addr_infos[0].info.addr_settings.flags |= MBG_NET_INTF_ADDR_MASK_DHCP4;
+
+ net_status_info->addr_infos[0].info.addr_settings.ip.type = MBG_IP_ADDR_TYPE_IP4;
+ net_status_info->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr = ip4_state.ip_addr;
+
+ net_status_info->addr_infos[0].info.addr_settings.broadcast.type = MBG_IP_ADDR_TYPE_IP4;
+ net_status_info->addr_infos[0].info.addr_settings.broadcast.u_addr.ip4_addr = ip4_state.broad_addr;
+
+ net_status_info->addr_infos[0].info.addr_settings.prefix_bits = get_ip4_net_mask_bits(&ip4_state.netmask);
+
+ if ( net_status_info->glb_cfg_info.n_supp_intf_route == 0 )
+ {
+ if ( net_status_info->route_infos == NULL )
+ {
+ net_status_info->route_infos = ( MBG_NET_INTF_ROUTE_INFO_IDX * )calloc( 1, sizeof( *net_status_info->route_infos ) );
+ if ( net_status_info->route_infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ net_status_info->glb_cfg_info.glb_settings.num_intf_route = 1;
+
+ memset( &net_status_info->route_infos[0], 0, sizeof( net_status_info->route_infos[0] ) );
+
+ net_status_info->route_infos[0].info.route_settings.type = MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY;
+ net_status_info->route_infos[0].info.route_settings.gateway.type = MBG_IP_ADDR_TYPE_IP4;
+ net_status_info->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr = ip4_state.gateway;
+ if ( ip4_state.gateway != 0 )
+ {
+ if(net_status_info->glb_cfg_info.glb_settings.num_intf_link == 2)
+ net_status_info->route_infos[0].info.route_settings.ass_if_index = 1;
+ }
+ else net_status_info->route_infos[0].info.route_settings.ass_if_index = (uint32_t)-1;
+
+ }
+
+ }
+
+out:
+ if ( mbg_rc_is_error( rc ) )
+ {
+ free_all_net_status_info( net_status_info );
+ net_status_info = NULL;
+ }
+
+ *p = net_status_info;
+
+ return rc;
+
+} // mbg_get_all_net_status_info
+
+
+
+/*HDR*/
+/**
+ * @brief Read all PTP settings and supported configuration parameters
+ *
+ * The complementary function ::mbg_save_all_ptp_cfg_info should
+ * be used to write the modified configuration back to the device.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] *p Pointer to a ::ALL_PTP_CFG_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ *
+ * @see ::mbg_save_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+int mbg_get_all_ptp_cfg_info( MBG_DEV_HANDLE dh, ALL_PTP_CFG_INFO *p )
+{
+ int rc = MBG_SUCCESS;
+
+ memset( p, 0, sizeof( *p ) );
+
+ rc = mbg_get_ptp_cfg_info( dh, &p->ptp_cfg_info );
+
+ if ( rc < 0 )
+ return rc;
+
+ if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST )
+ {
+ rc = mbg_get_ptp_uc_master_cfg_limits( dh, &p->ptp_uc_master_cfg_limits );
+
+ if ( rc < 0 )
+ return rc;
+
+ if ( p->ptp_uc_master_cfg_limits.n_supp_master > MAX_PARM_PTP_UC_MASTER )
+ {
+ // The number of PTP unicast masters supported by this device
+ // exceeds the number of unicast masters supporterd by this driver.
+ return MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP;
+ }
+
+ rc = mbg_get_all_ptp_uc_master_info( dh, p->all_ptp_uc_master_info_idx,
+ &p->ptp_uc_master_cfg_limits );
+ if ( rc < 0 )
+ return rc;
+ }
+
+ return MBG_SUCCESS;
+
+} // mbg_get_all_ptp_cfg_info
+
+
+
+/*HDR*/
+/**
+ * @brief Write all PTP settings to a device
+ *
+ * The complementary function ::mbg_get_all_ptp_cfg_info should
+ * have been used to read the original PTP settings and supported
+ * configuration parameters.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] *p Pointer to a valid ::ALL_PTP_CFG_INFO structure
+ *
+ * @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ *
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+int mbg_save_all_ptp_cfg_info( MBG_DEV_HANDLE dh, const ALL_PTP_CFG_INFO *p )
+{
+ int rc = MBG_SUCCESS;
+
+ rc = mbg_set_ptp_cfg_settings( dh, &p->ptp_cfg_info.settings );
+
+ if ( rc < 0 )
+ return rc;
+
+
+ if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST )
+ {
+ int i;
+
+ for ( i = 0; i < p->ptp_uc_master_cfg_limits.n_supp_master; i++ )
+ {
+ PTP_UC_MASTER_SETTINGS_IDX s;
+
+ memset( &s, 0, sizeof( s ) );
+
+ s.idx = i;
+ s.settings = p->all_ptp_uc_master_info_idx[i].info.settings;
+
+ rc = mbg_set_ptp_uc_master_settings_idx( dh, &s );
+
+ if ( rc < 0 )
+ return rc;
+ }
+ }
+
+ return MBG_SUCCESS;
+
+} // mbg_save_all_ptp_cfg_info
+
+#endif // !MBGDEVIO_SIMPLE
+
+
+/*HDR*/
+/**
+ * @brief Read all XMR info into a newly or re-allocated ::ALL_XMULTI_REF_INFO
+ *
+ * @note ::mbg_chk_dev_has_xmr should be called before using this function
+ *
+ * A ::ALL_XMULTI_REF_INFO and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings
+ * of ::XMULTI_REF_INFO_IDX and ::XMR_EXT_SRC_INFO_IDX will be allocated and needs
+ * to be freed by calling ::free_all_xmulti_ref_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::free_all_xmulti_ref_info
+ */
+int mbg_get_all_xmulti_ref_info( MBG_DEV_HANDLE dh, ALL_XMULTI_REF_INFO **p )
+{
+ ALL_XMULTI_REF_INFO *xmr_info = *p;
+ int rc;
+
+ if ( xmr_info == NULL )
+ {
+ xmr_info = ( ALL_XMULTI_REF_INFO * )calloc( 1, sizeof( *xmr_info ) );
+ if ( xmr_info == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ // First, get the XMULTI_REF_INSTANCES to check how many sources are supported
+ rc = mbg_get_xmr_instances( dh, &xmr_info->instances );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if ( xmr_info->infos == NULL )
+ {
+ xmr_info->infos = ( XMULTI_REF_INFO_IDX * )calloc( xmr_info->instances.n_xmr_settings, sizeof( *xmr_info->infos ) );
+ if ( xmr_info->infos == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ rc = mbg_get_gps_all_xmr_info( dh, xmr_info->infos, &xmr_info->instances );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_src_info( xmr_info ) ) )
+ {
+ // TODO!!!
+ // XMR_EXT_SRC_INFO_IDX can not be read out from bus devices, yet
+ // Therefore, remove the feature bit from this card
+ // Has to be changed as soon as low level functions are ready
+ // TODO!!!
+ xmr_info->instances.flags &= ~XMRIF_MSK_EXT_SRC_INFO_SUPP;
+ }
+
+out:
+ if ( mbg_rc_is_error( rc ) )
+ {
+ free_all_xmulti_ref_info( xmr_info );
+ xmr_info = NULL;
+ }
+
+ *p = xmr_info;
+
+ return rc;
+
+} // mbg_get_all_xmulti_ref_info
+
+
+/*HDR*/
+/**
+ * @brief Set all extended multi ref settings to a device
+ *
+ * The complementary function ::mbg_get_all_xmulti_ref_info should
+ * have been used to read the original extended multi ref info.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a ::ALL_XMULTI_REF_INFO structure with all settings
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_set_gps_xmr_settings_idx
+ */
+_NO_MBG_API_ATTR int _MBG_API mbg_save_all_xmulti_ref_info( MBG_DEV_HANDLE dh, ALL_XMULTI_REF_INFO *p )
+{
+ int rc = MBG_SUCCESS, i;
+ XMULTI_REF_SETTINGS_IDX settings;
+
+ for (i = 0; ( i < p->instances.n_xmr_settings ) && mbg_rc_is_success( rc ); i++ )
+ {
+ settings.idx = i;
+ memcpy( &settings.settings, &p->infos[i].info.settings, sizeof( settings.settings ) );
+ rc = mbg_set_gps_xmr_settings_idx( dh, &settings );
+ }
+
+ // if all settings have been successully set, send dummy structure with index -1 to apply settings
+ if( mbg_rc_is_success( rc ) )
+ {
+ memset( &settings, 0, sizeof( settings ) );
+ settings.idx = -1;
+ settings.settings.id.type = MULTI_REF_NONE;
+ rc = mbg_set_gps_xmr_settings_idx( dh, &settings );
+ }
+
+ return rc;
+
+} // mbg_save_all_xmulti_ref_info
+
+
+/*HDR*/
+/**
+ * @brief Read all XMR status info into a newly or re-allocated ::ALL_XMULTI_REF_STATUS
+ *
+ * @note ::mbg_chk_dev_has_xmr should be called before using this function
+ *
+ * A ::ALL_XMULTI_REF_STATUS and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings
+ * of ::XMULTI_REF_STATUS_IDX will be allocated and needs to be freed by calling
+ * ::free_all_xmulti_ref_status
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] info Pointer to the appropriate info structure
+ * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_STATUS
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::free_all_xmulti_ref_status
+ */
+int mbg_get_all_xmulti_ref_status( MBG_DEV_HANDLE dh, const ALL_XMULTI_REF_INFO *info, ALL_XMULTI_REF_STATUS **p )
+{
+ ALL_XMULTI_REF_STATUS *xmr_status = *p;
+ int rc;
+
+ if ( info == NULL )
+ return MBG_ERR_INV_PARM;
+
+ if ( xmr_status == NULL )
+ {
+ xmr_status = ( ALL_XMULTI_REF_STATUS * )calloc( 1, sizeof( *xmr_status ) );
+ if ( xmr_status == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ if ( xmr_status->status == NULL )
+ {
+ xmr_status->status = ( XMULTI_REF_STATUS_IDX* )calloc( info->instances.n_xmr_settings, sizeof( *xmr_status->status ) );
+
+ if ( xmr_status->status == NULL )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto out;
+ }
+ }
+
+ rc = mbg_get_gps_all_xmr_status( dh, xmr_status->status, &info->instances );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+ if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_src_info( info ) ) )
+ {
+ // TODO
+ // XMR_EXT_SRC_INFO_IDX can not be read out from bus devices, yet
+ }
+
+out:
+ if ( mbg_rc_is_error( rc ) )
+ {
+ free_all_xmulti_ref_status( xmr_status );
+ xmr_status = NULL;
+ }
+
+ *p = xmr_status;
+
+ return rc;
+
+} // mbg_get_all_xmulti_ref_status
+
+
+
+/*HDR*/
+/**
+ * @brief Read all user capture information and store it into a newly allocated or reused ::ALL_UCAP_INFO
+ *
+ * @note ::mbg_chk_dev_has_ucap should be called to check if this API is supported.
+ *
+ * The appropriate number of ::TTM structures will be allocated and needs to be freed
+ * by calling ::free_all_ucap_info. Existing user captures will not be removed, so the
+ * number of user captures can never decrease.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer to ::ALL_UCAP_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_ucap
+ * @see ::free_all_ucap_info
+ */
+int mbg_get_all_ucap_info( MBG_DEV_HANDLE dh, ALL_UCAP_INFO **p )
+{
+ int rc;
+ ALL_UCAP_INFO *ucap_info = *p;
+ UCAP_ENTRY *new_entry, *old_entry;
+
+ // if this function is called for the first time, allocate a new ::ALL_UCAP_INFO structure
+ if ( ucap_info == NULL )
+ {
+ ucap_info = ( ALL_UCAP_INFO* )calloc( 1, sizeof( *ucap_info ) );
+ if ( ucap_info == NULL )
+ {
+ *p = NULL;
+ return MBG_ERR_NO_MEM;
+ }
+ mbg_klist_init(&ucap_info->list);
+ }
+
+ do
+ {
+ new_entry = calloc_ucap_entry();
+ if ( !new_entry )
+ {
+ rc = MBG_ERR_NO_MEM;
+ goto err_out;
+ }
+
+ rc = mbg_get_gps_ucap( dh, &new_entry->ttm );
+ if ( mbg_rc_is_error( rc ) )
+ goto err_out;
+
+ if ( ( (uint8_t)new_entry->ttm.tm.sec == (uint8_t) 0xFF ) )
+ {
+ free ( new_entry );
+ new_entry = NULL;
+ break;
+ }
+
+ if ( ucap_info->num_ucaps < MAX_UCAP_ENTRIES )
+ {
+ mbg_klist_append_item(&ucap_info->list, &new_entry->head);
+ ++ucap_info->num_ucaps;
+ }
+ else
+ {
+ old_entry = mbg_klist_first_entry(&ucap_info->list, UCAP_ENTRY, head);
+ mbg_klist_delete_item(&old_entry->head);
+ free(old_entry);
+ mbg_klist_append_item(&ucap_info->list, &new_entry->head);
+ }
+
+ } while (1);
+
+ rc = MBG_SUCCESS;
+
+ goto success_out;
+
+err_out:
+ free_all_ucap_info( ucap_info );
+ ucap_info = NULL;
+ if ( new_entry )
+ free( new_entry );
+
+success_out:
+ *p = ucap_info;
+
+ return rc;
+
+} // mbg_get_all_ucap_info
+
+
+
+#if 0 && defined( DEBUG ) // ### TODO
+
+/*HDR*/
+void test_gpio( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, int verbose )
+{
+ int b;
+ int rc;
+ unsigned int i;
+ MBG_GPIO_CFG_LIMITS gpio_cfg_limits = { 0 };
+ ALL_GPIO_INFO_IDX all_gpio_info_idx = { { 0 } };
+ ALL_GPIO_STATUS_IDX all_gpio_status_idx = { { 0 } };
+
+ rc = mbg_chk_dev_has_gpio( dh );
+
+ printf( "\nGPIO chk supp: %i\n", rc );
+
+ rc = mbg_dev_has_gpio( dh, &b );
+
+ if ( rc != MBG_SUCCESS || !b )
+ {
+ printf( "GPIO not supported, rc: %i, b: %i\n", rc, b );
+ return;
+ }
+
+ printf( "GPIO supported, rc: %i, b: %i\n", rc, b );
+
+ printf( "\nChecking GPIO:\n" );
+
+ rc = mbg_get_gpio_cfg_limits( dh, &gpio_cfg_limits );
+
+ if ( rc != MBG_SUCCESS )
+ {
+ printf( "Failed to read GPIO limits, rc: %i\n", rc );
+ return;
+ }
+
+ printf( "Number of GPIO ports: %i\n", gpio_cfg_limits.num_io );
+
+ rc = mbg_get_gps_all_gpio_info( dh, all_gpio_info_idx, &gpio_cfg_limits );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "Failed to read all GPIO info, rc: %i\n", rc );
+
+ if ( !( gpio_cfg_limits.flags & MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP ) )
+ printf( "GPIO status not supported (flag not set).\n" );
+ else
+ {
+ rc = mbg_get_gps_all_gpio_status( dh, all_gpio_status_idx, &gpio_cfg_limits );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "Failed to read all GPIO status, rc: %i\n", rc );
+ }
+
+
+ for ( i = 0; i < gpio_cfg_limits.num_io; i++ )
+ {
+ MBG_GPIO_INFO *p_i = &all_gpio_info_idx[i].info;
+ MBG_GPIO_STATUS *p_st = &all_gpio_status_idx[i].status;
+ int gpio_type = p_i->settings.type;
+
+ printf( "GPIO %i: type 0x%02X (%s)", i,
+ gpio_type, _get_gpio_type_name( gpio_type ) );
+
+ switch ( gpio_type )
+ {
+ case MBG_GPIO_TYPE_FREQ_IN: // variable frequency input, freq == 0 if input not used
+ {
+ MBG_GPIO_FREQ_IN_SETTINGS *p = &p_i->settings.u.freq_in;
+#if 0
+ MBG_GPIO_FREQ freq; ///< frequency in range ::MBG_GPIO_FREQ_IN_SUPP::freq_min..::MBG_GPIO_FREQ_IN_SUPP::freq_max, or 0 if input is not used
+ uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units], see ::MBG_GPIO_FREQ_IN_SUPP::csc_limit_max
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+#endif
+
+ } break;
+
+ case MBG_GPIO_TYPE_FREQ_OUT: // variable frequency output
+ {
+ MBG_GPIO_FREQ_OUT_SETTINGS *p = &p_i->settings.u.freq_out;
+
+ printf( " %lu.%lu Hz %s, phase %li.%03li deg",
+ (ulong) p->freq.hz, (ulong) p->freq.frac,
+ _get_gpio_signal_shape_name( p->shape ),
+ (long) p->milli_phase / 1000,
+ labs( (long) p->milli_phase % 1000 ) );
+
+ } break;
+
+ case MBG_GPIO_TYPE_FIXED_FREQ_OUT: // fixed frequency output
+ {
+ MBG_GPIO_FIXED_FREQ_OUT_SETTINGS *p = &p_i->settings.u.ff_out;
+
+#if 0
+typedef struct
+{
+ uint32_t freq_idx; ///< fixed frequency index, see ::MBG_GPIO_FIXED_FREQS
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FIXED_FREQ_OUT_SETTINGS;
+#endif
+
+ printf( " %s %s", _get_gpio_fixed_freq_str( p->freq_idx ),
+ _get_gpio_signal_shape_name( p->shape ) );
+
+ } break;
+
+ case MBG_GPIO_TYPE_BITS_IN: // framed data stream input
+ break;
+
+ case MBG_GPIO_TYPE_BITS_OUT: // framed data stream output
+ break;
+ }
+
+ printf( ", status 0x%02X (%s)",
+ p_st->port_state, _get_gpio_port_state_name( p_st->port_state ) );
+
+ printf( "\n" );
+ }
+
+#if 0
+ rc = mbg_set_gps_gpio_settings_idx( dh, MBG_GPIO_SETTINGS_IDX *p )
+#endif
+
+} // test_gpio
+
+
+
+/*HDR*/
+void test_xmr( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, int verbose )
+{
+ static const char *multi_ref_names[N_MULTI_REF] = DEFAULT_MULTI_REF_NAMES;
+
+ XMULTI_REF_INSTANCES xmr_instances = { 0 };
+ ALL_XMULTI_REF_INFO_IDX all_xmulti_ref_info_idx = { { 0 } };
+ ALL_XMULTI_REF_STATUS_IDX all_xmulti_ref_status_idx = { { 0 } };
+ XMR_HOLDOVER_STATUS xmr_holdover_status;
+
+ int b;
+ int rc;
+ int i;
+
+ rc = mbg_chk_dev_has_xmr( dh );
+
+ printf( "\nXMR chk supp: %i\n", rc );
+
+ rc = mbg_dev_has_xmr( dh, &b );
+
+ if ( rc != MBG_SUCCESS || !b )
+ {
+ printf( "XMR not supported, rc: %i, b: %i\n", rc, b );
+ return;
+ }
+
+ printf( "XMR supported, rc: %i, b: %i\n", rc, b );
+
+ printf( "\nChecking XMR:\n" );
+
+ rc = mbg_get_xmr_instances( dh, &xmr_instances );
+
+ if ( rc != MBG_SUCCESS )
+ {
+ printf( "*** Failed to read XMR instances, rc: %i\n", rc );
+ return;
+ }
+
+ printf( "Slot %u, supp. XMR instances/priority levels: %u, flags: 0x%08lX\n",
+ xmr_instances.slot_id, xmr_instances.n_xmr_settings,
+ (ulong) xmr_instances.flags );
+
+ if ( verbose )
+ {
+// XMRIF_MSK_MRF_NONE_SUPP = ( 1UL << XMRIF_BIT_MRF_NONE_SUPP ), ///< see ::XMRIF_BIT_MRF_NONE_SUPP
+//##++++++++++++++++++++ XMRIF_MSK_HOLDOVER_STATUS_SUPP = ( 1UL << XMRIF_BIT_HOLDOVER_STATUS_SUPP ) ///< see ::XMRIF_BIT_HOLDOVER_STATUS_SUPP
+ }
+
+
+ for ( i = 0; i < MAX_N_MULTI_REF_TYPES; i++ )
+ {
+ int n_inst = xmr_instances.n_inst[i];
+
+ if ( i < N_MULTI_REF ) // a known signal type
+ {
+ if ( verbose )
+ {
+ if ( n_inst )
+ printf( "%u %s input%s supported\n", n_inst,
+ multi_ref_names[i], ( n_inst == 1 ) ? "" : "s" );
+ else
+ if ( verbose > 1 )
+ printf( "No %s input supported\n", multi_ref_names[i] );
+ }
+
+ continue;
+ }
+
+ // If execution gets here then the signal type is unknown.
+ // Print a warning if the device supports instances of this signal type.
+ if ( n_inst )
+ printf( "*** Warning: %u instances of unknown signal type idx %u supported!\n",
+ n_inst, i );
+ }
+
+ rc = mbg_get_gps_all_xmr_info( dh, all_xmulti_ref_info_idx, &xmr_instances );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "*** Failed to read all XMR info, rc: %i\n", rc );
+
+ rc = mbg_get_gps_all_xmr_status( dh, all_xmulti_ref_status_idx, &xmr_instances );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "*** Failed to read all XMR status, rc: %i\n", rc );
+
+ for ( i = 0; i < xmr_instances.n_xmr_settings; i++ )
+ {
+ XMULTI_REF_INFO *p = &all_xmulti_ref_info_idx[i].info;
+
+ printf( "XMR %i: %li\n", i,
+ (long) p->settings.bias.secs );
+
+#if 0
+ XMULTI_REF_SETTINGS_IDX xmrsi;
+ xmrsi.settings = p->settings;
+ xmrsi.settings.precision.nano_secs = i + 40;
+ xmrsi.settings.bias.secs = 0xA55ACDEF;
+ xmrsi.settings.bias.nano_secs = 0x12345678;
+ xmrsi.idx = i;
+
+ rc = mbg_set_gps_xmr_settings_idx( dh, &xmrsi );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "Failed to write XMR settings %i, rc: %i\n", i, rc );
+#endif
+ }
+
+ if ( !( xmr_instances.flags & XMRIF_MSK_HOLDOVER_STATUS_SUPP ) )
+ printf( "*** Warning: XMR holdover status not supported!\n" );
+ else
+ {
+ rc = mbg_get_xmr_holdover_status( dh, &xmr_holdover_status, &xmr_instances );
+
+ if ( rc != MBG_SUCCESS )
+ printf( "*** Failed to read XMR holdover status, rc: %i\n", rc );
+ else
+ {
+ printf( "XMR mode: %s, %s%s, %s%s, %s%s\n",
+ _get_xmr_holdover_status_mode_name( xmr_holdover_status.mode ),
+ ( xmr_holdover_status.flags & XMR_HLDOVR_MSK_IN_HOLDOVER ) ? "" : str_not_spc, "in holdover",
+ ( xmr_holdover_status.flags & XMR_HLDOVR_MSK_TRANSITION_ENBD ) ? "" : str_not_spc, "transition enabled",
+ ( xmr_holdover_status.flags & XMR_HLDOVR_MSK_IN_TRANSITION ) ? "" : str_not_spc, "in transition"
+ );
+
+//##+++++ print_xmr_prio( xmr_holdover_status.curr_prio, "Current",
+#if 0
+typedef struct
+{
+ uint8_t mode; ///< XMR/holdover mode, see ::XMR_HOLDOVER_STATUS_MODES
+ int8_t curr_prio; ///< current priority level, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ int8_t nxt_prio; ///< next priority level after holdover, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ uint8_t remote_watchdog; ///< counts down in ::XMR_HLDOVR_PRE_AUTONOMOUS mode
+ uint32_t reserved; ///< reserved, don't use, currently 0
+ XMR_HOLDOVER_INTV elapsed; ///< elapsed time in holdover mode, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ XMR_HOLDOVER_INTV interval; ///< current holdover interval, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ uint32_t flags; ///< holdover status flags, see ::XMR_HOLDOVER_STATUS_FLAG_MASKS
+
+} XMR_HOLDOVER_STATUS;
+#endif
+
+ }
+ }
+
+} // test_xmr
+
+#endif // defined DEBUG
+
+
+
+static const int pcps_to_mbg_framing_tbl[N_PCPS_FR_DCF] =
+{
+ MBG_FRAMING_8N1,
+ MBG_FRAMING_7E2,
+ MBG_FRAMING_8N2,
+ MBG_FRAMING_8E1
+};
+
+
+
+/*HDR*/
+void port_info_from_pcps_serial(
+ PORT_INFO_IDX *p_pii,
+ PCPS_SERIAL pcps_serial,
+ uint32_t supp_baud_rates
+)
+{
+ PCPS_SER_PACK ser_pack;
+ PORT_INFO *p_pi;
+ PORT_SETTINGS *p_ps;
+
+ ser_pack.pack = pcps_serial;
+ pcps_unpack_serial( &ser_pack );
+
+ p_pi = &p_pii[0].port_info;
+ p_ps = &p_pi->port_settings;
+
+ p_ps->parm.baud_rate = mbg_baud_rate[ser_pack.baud];
+
+ strncpy_safe( p_ps->parm.framing, //### TODO
+ mbg_framing_str[pcps_to_mbg_framing_tbl[ser_pack.frame]],
+ sizeof( p_ps->parm.framing ) );
+
+ p_ps->parm.handshake = HS_NONE;
+
+ p_ps->str_type = 0;
+ p_ps->mode = ser_pack.mode;
+
+ p_pi->supp_baud_rates = supp_baud_rates;
+ p_pi->supp_framings = DEFAULT_FRAMINGS_DCF;
+ p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_DCF;
+
+} // port_info_from_pcps_serial
+
+
+/*HDR*/
+void pcps_serial_from_port_info(
+ PCPS_SERIAL *p,
+ const PORT_INFO_IDX *p_pii
+)
+{
+ PCPS_SER_PACK ser_pack;
+ const PORT_INFO *p_pi = &p_pii[0].port_info;
+ const PORT_SETTINGS *p_ps = &p_pi->port_settings;
+ int framing_idx = get_framing_idx( p_ps->parm.framing );
+ int i;
+
+
+ ser_pack.baud = get_baud_rate_idx( p_ps->parm.baud_rate );
+
+ // Translate the common framing index to the corresponding
+ // number used with the old PCPS_SERIAL parameter.
+ // This should always return a valid result since the
+ // framing index is expected to be selected from
+ // supported framings.
+ for ( i = 0; i < N_PCPS_FR_DCF; i++ )
+ if ( pcps_to_mbg_framing_tbl[i] == framing_idx )
+ break;
+
+ ser_pack.frame = i;
+
+ ser_pack.mode = p_ps->mode;
+
+ pcps_pack_serial( &ser_pack );
+
+ *p = ser_pack.pack;
+
+} // pcps_serial_from_port_info
+
+
+
+/*--------------------------------------------------------------
+ * Name: pcps_unpack_serial()
+ *
+ * Purpose: Unpack a structure with serial port parameters
+ *
+ * Input/Output: p address of a structure holding both the
+ * packed and unpacked information
+ *
+ * Ret value: --
+ *-------------------------------------------------------------*/
+
+/*HDR*/
+void pcps_unpack_serial( PCPS_SER_PACK *p )
+{
+ uint8_t pack = p->pack;
+
+ p->baud = (uint8_t) ( pack & BITMASK( PCPS_BD_BITS ) );
+ p->frame = (uint8_t) ( ( pack >> PCPS_FR_SHIFT ) & BITMASK( PCPS_FR_BITS ) );
+ p->mode = (uint8_t) ( ( pack >> PCPS_MOD_SHIFT ) & BITMASK( PCPS_MOD_BITS ) );
+
+} // pcps_unpack_serial
+
+
+
+/*--------------------------------------------------------------
+ * Name: pcps_pack_serial()
+ *
+ * Purpose: Pack a structure with serial port parameters
+ *
+ * Input/Output: p address of a structure holding both the
+ * packed and unpacked information
+ *
+ * Ret value: --
+ *-------------------------------------------------------------*/
+
+/*HDR*/
+void pcps_pack_serial( PCPS_SER_PACK *p )
+{
+ p->pack = (uint8_t) ( ( p->baud & BITMASK( PCPS_BD_BITS ) )
+ | ( ( p->frame & BITMASK( PCPS_FR_BITS ) ) << PCPS_FR_SHIFT )
+ | ( ( p->mode & BITMASK( PCPS_MOD_BITS ) ) << PCPS_MOD_SHIFT ) );
+
+} /* pcps_pack_serial */
+
+
+
+/*--------------------------------------------------------------
+ * Name: pcps_str_to_port()
+ *
+ * Purpose: Try to convert a string to a valid port
+ * address.
+ *
+ * Input: s the string
+ *
+ * Output: --
+ *
+ * Ret value: a valid port number or 0
+ *+-------------------------------------------------------------*/
+
+/*HDR*/
+void pcps_setup_isa_ports( char *s,
+ int *port_vals,
+ int n_vals )
+{
+ ushort i;
+
+
+ for ( i = 0; i < n_vals; i++ )
+ {
+ if ( *s == 0 )
+ break;
+
+ *port_vals++ = (uint16_t) strtoul( s, &s, 16 );
+
+ if ( *s == ',' )
+ s++;
+ }
+
+} // pcps_setup_isa_ports
+
+
+
+/*HDR*/
+const char *setup_device_type_name( char *s, size_t max_len, MBG_DEV_HANDLE dh,
+ const RECEIVER_INFO *p_ri )
+{
+ size_t n = sn_cpy_str_safe( s, max_len, p_ri->model_name );
+
+ if ( mbg_rc_is_success( mbg_chk_dev_has_asic_version( dh ) ) )
+ {
+ PCI_ASIC_VERSION asic_version;
+
+ if ( mbg_rc_is_success( mbg_get_asic_version( dh, &asic_version ) ) )
+ n += snprintf_safe( &s[n], max_len - n, " (PCI ASIC v%i.%02i)",
+ _convert_asic_version_number( asic_version ) >> 8,
+ _convert_asic_version_number( asic_version ) & 0xFF );
+ }
+
+ return s;
+
+} // setup_device_type_name
+
+
+
+/*HDR*/
+const char *setup_asic_features( char *s, size_t max_len, MBG_DEV_HANDLE dh )
+{
+ size_t n = 0;
+
+ if ( mbg_rc_is_success( mbg_chk_dev_has_asic_features( dh ) ) )
+ {
+ PCI_ASIC_FEATURES asic_features;
+
+ if ( mbg_rc_is_success( mbg_get_asic_features( dh, &asic_features ) ) )
+ {
+ if ( asic_features & PCI_ASIC_HAS_MM_IO )
+ n += sn_cpy_str_safe( &s[n], max_len - n, "Memory Mapped I/O" );
+
+ //### if ( asic_features & PCI_ASIC_HAS_PGMB_IRQ )
+ // (implement this as loop)
+ }
+ }
+
+ if ( n == 0 ) // nothing else printed
+ sn_cpy_str_safe( s, max_len, str_not_avail );
+
+ return s;
+
+} // setup_asic_features
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.h b/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.h
new file mode 100755
index 0000000..f06b72a
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/deviohlp.h
@@ -0,0 +1,415 @@
+
+/**************************************************************************
+ *
+ * $Id: deviohlp.h 1.4 2017/07/05 13:50:18 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for deviohlp.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: deviohlp.h $
+ * Revision 1.4 2017/07/05 13:50:18 martin
+ * Moved definition of PCPS_SER_PACK here.
+ * Defined function type MBG_ERR_MSG_FNC.
+ * New structure PCPS_TIME_EXT.
+ * New inline function pcps_time_is_valid().
+ * Updated function prototypes.
+ * Revision 1.3 2013/09/26 08:25:18Z martin
+ * Moved ALL_PTP_CFG_INFO definition to cfg_hlp.h.
+ * Updated doxygen comments.
+ * Revision 1.2 2012/10/15 13:51:18Z martin
+ * Include cfg_hlp.h.
+ * Added structure ALL_PTP_CFG_INFO.
+ * Updated function prototypes.
+ * Revision 1.1 2011/08/03 15:36:44Z martin
+ * Initial revision with functions moved here from mbgdevio.
+ *
+ **************************************************************************/
+
+#ifndef _DEVIOHLP_H
+#define _DEVIOHLP_H
+
+
+/* Other headers to be included */
+
+#include <mbgdevio.h>
+#include <cfg_hlp.h>
+
+
+#ifdef _DEVIOHLP
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief A helper structure used with configuration of old DCF77 clocks
+ *
+ * @deprecated This structure has been used with some very
+ * old DCF77 clocks to configure the serial interface.
+ * It has been deprecated by ::PORT_SETTINGS and ::PORT_INFO.
+ */
+typedef struct
+{
+ PCPS_SERIAL pack; ///< This packed byte is read from or written to the board
+
+ uint8_t baud; ///< The unpacked baud rate code, see ::PCPS_BD_CODES
+ uint8_t frame; ///< The unpacked framing code, see ::PCPS_FR_CODES
+ uint8_t mode; ///< The unpacked mode code, see ::PCPS_MOD_CODES
+
+} PCPS_SER_PACK;
+
+
+
+typedef int MBG_ERR_MSG_FNC( const PCPS_DEV *p_dev, const char *s );
+
+
+/**
+ * @brief An extended time and status structure
+ *
+ * This structure provides monitoring and configuration tools
+ * with a unified structure containing the current time and
+ * extended status. The structure needs to be set up depending
+ * on the capabilities of a particular device and the API calls
+ * which could be used to retrieve the information.
+ */
+typedef struct
+{
+ PCPS_TIME t; ///< current date, time, and limited status
+ uint8_t comp_sig_mode; ///< 0..::N_CONN_SIG_MODES-1, see ::COMP_SIG_MODES
+ int16_t comp_sig_val; ///< compensated signal value, see @ref PCPS_SIG_VAL_DEFS
+ int32_t utc_offs; ///< %UTC offset, always expanded to [seconds]
+ PCPS_TIME_STATUS_X status_x; ///< extended status, see @see @ref PCPS_TIME_STATUS_FLAGS
+ uint16_t year; ///< full year number
+ uint32_t flags; ///< see ::PCPS_TIME_EXT_FLAGS
+
+} PCPS_TIME_EXT;
+
+
+
+/**
+ * @brief Check if a ::PCPS_TIME structure contains valid date and time
+ *
+ * @param[in] p The structure to be checked
+ *
+ * @return != 0 if date and time valid, else 0
+ */
+static __mbg_inline
+int pcps_time_is_valid( const PCPS_TIME *p )
+{
+ return ( p->sec100 <= 99 )
+ && ( p->sec <= 60 ) // allow for leap second
+ && ( p->min <= 59 )
+ && ( p->hour <= 23 )
+ && ( p->mday >= 1 ) && ( p->mday <= 31 )
+ && ( p->wday >= 1 ) && ( p->wday <= 7 )
+ && ( p->month >= 1 ) && ( p->month <= 12 )
+ && ( p->year <= 99 );
+
+} // pcps_time_is_valid
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ int chk_feat_supp( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, MBG_CHK_SUPP_FNC *chk_supp_fnc, MBG_ERR_MSG_FNC *err_msg_fnc, const char *not_supp_msg ) ;
+ /**
+ * @brief Read or setup all GNSS status information
+ *
+ * This function should be called preferably to get a summary of
+ * the GNSS status from GNSS receivers (GPS, GLONASS, ...).
+ *
+ * The function ::mbg_get_device_info must have been called before, and
+ * the returned ::PCPS_DEV structure has to be passed to this function.
+ *
+ * If the device supports this then the low level GNSS API functions
+ * are called directly to collect the status information. If the device
+ * doesn't support the GNSS API but is a pure GPS receiver then the GPS
+ * API functions are called and the GNSS data structures are filled up
+ * accordingly, so the calling application can always evaluate the
+ * GNSS data structures in ::ALL_GNSS_INFO.
+ *
+ * If neither GPS nor another GNSS system is supported then this function
+ * returns the ::MBG_ERR_NOT_SUPP_BY_DEV error.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p_agi Pointer to a ::ALL_GNSS_INFO to be filled
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_get_gps_stat_info
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ */
+ int mbg_chk_get_all_gnss_info( MBG_DEV_HANDLE dh, ALL_GNSS_INFO *p_agi ) ;
+
+ /**
+ * @brief 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 have to 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[in] dh Valid handle to a Meinberg device
+ * @param[in] *p_dev Pointer to a valid ::PCPS_DEV structure
+ * @param[out] *p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure to be filled up
+ * @param[in] *p_ri Pointer to a valid ::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
+ */
+ int mbg_get_serial_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, RECEIVER_PORT_CFG *p_rpcfg, const RECEIVER_INFO *p_ri ) ;
+
+ /**
+ * @brief Write the configuration settings for a single serial port to a device
+ *
+ * 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
+ * vave to be passed to this function.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] *p_dev Pointer to a valid ::PCPS_DEV structure
+ * @param[in] *p_rpcfg Pointer to a valid ::RECEIVER_PORT_CFG structure
+ * @param[in] 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
+ */
+ int mbg_save_serial_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, RECEIVER_PORT_CFG *p_rpcfg, int port_num ) ;
+
+ /**
+ * @brief Read all network configuration into an ::ALL_NET_CFG_INFO structure
+ *
+ * Reads the network configuration of a device via the LAN_IP4 API and
+ * translates the structures into NET_CFG structures.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * A ::ALL_NET_CFG_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX,
+ * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and
+ * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later
+ * by calling ::free_all_net_cfg_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_NET_CFG_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ * @see ::free_all_net_cfg_info
+ */
+ int mbg_get_all_net_cfg_info( MBG_DEV_HANDLE dh, ALL_NET_CFG_INFO **p ) ;
+
+ /**
+ * @brief Write all network settings to a device
+ *
+ * The complementary function ::mbg_get_all_net_cfg_info should
+ * have been used to read the original network settings and
+ * supported configuration parameters.
+ *
+ * The appropriate settings are translated into LAN_IP4 structures
+ * and send to the device using the appropriate API functions.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] p Pointer to a pointer of ::ALL_NET_CFG_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_set_ip4_settings
+ */
+ int mbg_save_all_net_cfg_info( MBG_DEV_HANDLE dh, ALL_NET_CFG_INFO *p ) ;
+
+ /**
+ * @brief Read current network status into an ::ALL_NET_STATUS_INFO structure
+ *
+ * Reads the network status of a device via the LAN_IP4 API and
+ * translates the structures into NET_CFG structures.
+ *
+ * As soon as available, this function should make use of the NET_CFG API.
+ *
+ * A ::ALL_NET_STATUS_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX,
+ * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and
+ * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later
+ * by calling ::free_all_net_status_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_NET_STATUS_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::free_all_net_status_info
+ */
+ int mbg_get_all_net_status_info( MBG_DEV_HANDLE dh, ALL_NET_STATUS_INFO **p ) ;
+
+ /**
+ * @brief Read all PTP settings and supported configuration parameters
+ *
+ * The complementary function ::mbg_save_all_ptp_cfg_info should
+ * be used to write the modified configuration back to the device.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] *p Pointer to a ::ALL_PTP_CFG_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ *
+ * @see ::mbg_save_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+ int mbg_get_all_ptp_cfg_info( MBG_DEV_HANDLE dh, ALL_PTP_CFG_INFO *p ) ;
+
+ /**
+ * @brief Write all PTP settings to a device
+ *
+ * The complementary function ::mbg_get_all_ptp_cfg_info should
+ * have been used to read the original PTP settings and supported
+ * configuration parameters.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] *p Pointer to a valid ::ALL_PTP_CFG_INFO structure
+ *
+ * @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ *
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+ int mbg_save_all_ptp_cfg_info( MBG_DEV_HANDLE dh, const ALL_PTP_CFG_INFO *p ) ;
+
+ /**
+ * @brief Read all XMR info into a newly or re-allocated ::ALL_XMULTI_REF_INFO
+ *
+ * @note ::mbg_chk_dev_has_xmr should be called before using this function
+ *
+ * A ::ALL_XMULTI_REF_INFO and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings
+ * of ::XMULTI_REF_INFO_IDX and ::XMR_EXT_SRC_INFO_IDX will be allocated and needs
+ * to be freed by calling ::free_all_xmulti_ref_info
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::free_all_xmulti_ref_info
+ */
+ int mbg_get_all_xmulti_ref_info( MBG_DEV_HANDLE dh, ALL_XMULTI_REF_INFO **p ) ;
+
+ /**
+ * @brief Set all extended multi ref settings to a device
+ *
+ * The complementary function ::mbg_get_all_xmulti_ref_info should
+ * have been used to read the original extended multi ref info.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a ::ALL_XMULTI_REF_INFO structure with all settings
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_set_gps_xmr_settings_idx
+ */
+ _NO_MBG_API_ATTR int _MBG_API mbg_save_all_xmulti_ref_info( MBG_DEV_HANDLE dh, ALL_XMULTI_REF_INFO *p ) ;
+
+ /**
+ * @brief Read all XMR status info into a newly or re-allocated ::ALL_XMULTI_REF_STATUS
+ *
+ * @note ::mbg_chk_dev_has_xmr should be called before using this function
+ *
+ * A ::ALL_XMULTI_REF_STATUS and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings
+ * of ::XMULTI_REF_STATUS_IDX will be allocated and needs to be freed by calling
+ * ::free_all_xmulti_ref_status
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[in] info Pointer to the appropriate info structure
+ * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_STATUS
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::free_all_xmulti_ref_status
+ */
+ int mbg_get_all_xmulti_ref_status( MBG_DEV_HANDLE dh, const ALL_XMULTI_REF_INFO *info, ALL_XMULTI_REF_STATUS **p ) ;
+
+ /**
+ * @brief Read all user capture information and store it into a newly allocated or reused ::ALL_UCAP_INFO
+ *
+ * @note ::mbg_chk_dev_has_ucap should be called to check if this API is supported.
+ *
+ * The appropriate number of ::TTM structures will be allocated and needs to be freed
+ * by calling ::free_all_ucap_info. Existing user captures will not be removed, so the
+ * number of user captures can never decrease.
+ *
+ * @param[in] dh Valid handle to a Meinberg device
+ * @param[out] p Pointer to a pointer to ::ALL_UCAP_INFO
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_chk_dev_has_ucap
+ * @see ::free_all_ucap_info
+ */
+ int mbg_get_all_ucap_info( MBG_DEV_HANDLE dh, ALL_UCAP_INFO **p ) ;
+
+ void test_gpio( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, int verbose ) ;
+ void test_xmr( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, int verbose ) ;
+ void port_info_from_pcps_serial( PORT_INFO_IDX *p_pii, PCPS_SERIAL pcps_serial, uint32_t supp_baud_rates ) ;
+ void pcps_serial_from_port_info( PCPS_SERIAL *p, const PORT_INFO_IDX *p_pii ) ;
+ void pcps_unpack_serial( PCPS_SER_PACK *p ) ;
+ void pcps_pack_serial( PCPS_SER_PACK *p ) ;
+ void pcps_setup_isa_ports( char *s, int *port_vals, int n_vals ) ;
+ const char *setup_device_type_name( char *s, size_t max_len, MBG_DEV_HANDLE dh, const RECEIVER_INFO *p_ri ) ;
+ const char *setup_asic_features( char *s, size_t max_len, MBG_DEV_HANDLE dh ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _DEVIOHLP_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/gpsdefs.h b/src/external/bsd/meinberg/dist/mbglib/common/gpsdefs.h
index b638657..32194a6 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/gpsdefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/gpsdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsdefs.h 1.91.1.24 2011/07/08 09:04:05 martin TRASH $
+ * $Id: gpsdefs.h 1.125 2017/07/05 18:18:27 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -13,57 +13,255 @@
*
* -----------------------------------------------------------------------
* $Log: gpsdefs.h $
- * Revision 1.91.1.24 2011/07/08 09:04:05 martin
- * Renamed some PTP stuff.
- * Added some definitions for PTP.
- * Revision 1.91.1.23 2011/06/29 10:49:47 martin
+ * Revision 1.125 2017/07/05 18:18:27 martin
+ * New models GPS_MODEL_CTC100, GPS_MODEL_TCR180,
+ * GPS_MODEL_LUE180, GPS_MODEL_CPC_01, GPS_MODEL_TSU_01,
+ * GPS_MODEL_CMC_01, GPS_MODEL_SCU_01, GPS_MODEL_FCU_01,
+ * GPS_MODEL_CSM100, GPS_MODEL_LNE180SFP, GPS_MODEL_GTS180,
+ * GPS_MODEL_GPS180CSM, GPS_MODEL_GRC181, GPS_MODEL_N2X180,
+ * GPS_MODEL_GNS181PEX, GPS_MODEL_MDU180, GPS_MODEL_MDU312,
+ * GPS_MODEL_GPS165, GPS_MODEL_GNS181_UC, GPS_MODEL_PSX_4GE,
+ * GPS_MODEL_RSC180RDU, GPS_MODEL_USYNCPWR, GPS_MODEL_FDM180M,
+ * GPS_MODEL_LSG180, GPS_MODEL_GPS190, GPS_MODEL_GNS181 and
+ * associated definitions.
+ * New GPS_BUILTIN_FEATURE_BITS and associated definitions.
+ * New macros _setup_default_receiver_info_dcf() and
+ * _setup_default_receiver_info_gps() as well as associated
+ * definitions which can be used to set up a RECEIVER_INFO
+ * structure for legacy devices which don't provide it.
+ * New Receiver_INO feature bit GPS_FEAT_XFEATURE which
+ * indicates that a new, extended feature set is supported.
+ * Defined a new st of extended features (MBG_XFEATURE_BITS)
+ * and associated definitions.
+ * Moved definitions for NANO_TIME and NANO_TIME_64 to words.h.
+ * New IRIG TX codes ICODE_TX_A006_A136, ICODE_TX_A007_A137,
+ * and associated definitions.
+ * Renamed ICODE_RX_G142_G146 to ICODE_RX_G142, and
+ * ICODE_RX_G002_G006 to ICODE_RX_G002.
+ * New IRIG RX codes ICODE_RX_A136_A137, ICODE_RX_A006_A007,
+ * ICODE_RX_G146, ICODE_RX_G006, and associated definitions.
+ * New union POUT_DATA union used for varying configuration
+ * data in POUT_SETTINGS, depending on the output mode.
+ * New POUT_MODES POUT_PTTI_PPS, POUT_HAVEQUICK, and
+ * associated definitions.
+ * Definitions to support a configurable pulse shift
+ * of some programmable output signals.
+ * New multiref source MULTI_REF_SYNCE and associated
+ * definitions.
+ * Added a number of swab..() macros that were still missing.
+ * XMR statistics, XMR_QL and some other XMR stuff by andre.
+ * New GPIO types including video modes, and associated stuff.
+ * Renamed some structure fields and added some definitions
+ * related to FDM.
+ * Added some SCU_STAT_MASKS.
+ * New GNSS_TYPE_QZSS, and modified MBG_GNSS_MODE_INFO.
+ * New flag MBG_GNSS_FLAG_HAS_SV_STATUS, structure
+ * GNSS_SV_STATUS and associated definitions.
+ * A bunch of new structures and definitions for network
+ * configuration.
+ * Many new structures and definitions for NTP configuration.
+ * New structures and associated definitions used to send
+ * user capture events over the network (ext_ucap).
+ * New PTP_ROLES and associated stuff.
+ * Changed one of PTP_STATE's reserved fields to tsu_secs.
+ * Changed PTP_ANN_RCPT_TIMEOUT_MAX from 255 to 8.
+ * New PTP_CFG_FLAGS, PTP_OPT_EXTS flags, PTP_PRESETS_MASKS
+ * and associated definitions.
+ * Definitions for PTPv1 and v2 data sets, and PTP statistics.
+ * Preliminary definitions to support SMPTE and SDH.
+ * Definition for XBP addressing of devices.
+ * Definitions to support TLVs.
+ * Added LED and LNE API definitions.
+ * MBG_EXT_SYS_INFO_BITS and associated definitions for an
+ * extended sysinfo API.
+ * MBG_CLK_RES_INFO and associated stuff for clock resolution
+ * info.
+ * Definitions for configuration transaction handling.
+ * Definitions for a higher level I/O port API.
+ * Definitions for monitoring / notification.
+ * Definitions for USB locking.
+ * Preliminary licensing stuff.
+ * Defined macros in a safer way.
+ * Revision 1.124 2015/07/14 14:22:46 martin
+ * Doxygen fix.
+ * Revision 1.123 2015/07/06 13:00:10 martin
+ * Added definitions for VSG180, MSF180, WWVB180, and CPC180.
+ * Added definitions for PZF180.
+ * Definitions for SDI and MDU300 added by stephan.
+ * Definitions for HPS100 added by daniel.
+ * FDM180 and associated definitions added by paul.
+ * Started to support eXtended Binary Protocol (XBP).
+ * Merged daniel and gregoire's changes from the 1.120.2.x branch.
+ * Defines for IPv6 multicast scopes added by gregoire.
+ * XMR_EXT_SRC_INFO and associated XMR_SETTINGS_FLAG_MSKS flags
+ * defined by andre.
+ * Support XMULTI_REF_INFO::n_prio field again.
+ * Fixed _mbg_swab_gpio_cfg_limits() macro.
+ * Added MBG_NET_LINK_OPT_MASK_CAN_SYNCE to MBG_NET_LINK_OPT_MASKS.
+ * New PTP_ROLE_MASKS PTP_ROLE_NTP_SERVER and PTP_ROLE_NTP_CLIENT.
+ * Some PTP profile extensions added by daniel.
+ * Added missing defines for SPT.
+ * Added definitions for REL1000.
+ * Moved structure NANO_TIME_64 here.
+ * Revision 1.122 2014/07/29 08:57:44Z martin
+ * Updated doxygen comments.
+ * Revision 1.121 2014/07/17 09:41:50 martin
+ * Introduced XMR_HOLDOVER_STATUS, MBG_GPIO_STATUS,
+ * and associated definitions.
+ * Huge update and cleanup on doxygen comments.
+ * Revision 1.120 2014/05/27 08:34:40 martin
+ * Fixed braces in some _mbg_rcvr_is_..() macros.
+ * Definitions used with extended network cfg, VST, and SHS.
+ * Introduced XMR_HOLDOVER_STATUS.
+ * Introduced programmable output mode POUT_GPIO.
+ * Introduced oscillator type OCXO_SQ.
+ * Defined some new baud rates.
+ * Defines for IEEE C37.118.1-2011 CTQ.
+ * Support for new model SCG by paul.
+ * Support new model PPG180.
+ * New SCU control masks.
+ * New GNSS flag MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER.
+ * DEFAULT_MULTI_REF_NAMES_SHORT added by udo.
+ * Definitions used for NTP configuration by thomas-b and marvin.
+ * MBG_NET_ADDR structures changed to MBG_IP_ADDR, and
+ * associated symbols defined by marvin.
+ * Huge rework of comments in doxygen format.
+ * Revision 1.119 2013/12/05 10:13:13 daniel
+ * Support new PTP_CFG_FLAGS for 1-step-L2 and 1-step-P2P support
+ * Revision 1.118 2013/11/19 13:38:35 martin
+ * Added LAN_IF_TYPE_RSC.
+ * Revision 1.117 2013/11/18 14:13:39 martin
+ * Support model LNE_GB.
+ * Revision 1.116 2013/11/11 09:46:11 martin
+ * New PTP configuration flags PTP_CFG_SUPP_MCAST_SLAVE_FLAG and
+ * PTP_CFG_CAN_BE_MULTICAST_SLAVE, plus associated bit masks.
+ * New XMR_INST_FLAGS and XMR_INST_FLAG_MASKS defined by andre.
+ * Fixes for big-endian targets.
+ * Updated doxygen comments.
+ * Revision 1.115 2013/10/02 15:19:28 martin
+ * Changed PTP_CFG_SETTINGS::vlan_cfg back to a reserved field,
+ * and removed associated flag and flag mask.
+ * Revision 1.114 2013/09/25 11:02:10 martin
+ * Support models MRI, BPE, GLN180PEX, N2X, RSC180.
+ * Added feature bit GPS_FEAT_NTP.
+ * Enhanced VLAN configuration structures.
+ * Started to support IPv6.
+ * Renamed PTP_CFG_SETTINGS field "profile" to "selected_presets".
+ * Renamed PTP_CFG_INFO field "supp_profiles" to "supp_opt_ext".
+ * New PTP role PTP_ROLE_BOTH_MASTER.
+ * New PTP flag PTP_FLAG_ONE_STEP.
+ * Added some new PTP_CFG_FLAGS flags.
+ * Added PTP_OPT_EXTS and associated definitions.
+ * Added PTP_PRESETS and associated definitions.
+ * Added "tzdl" field to PTP_POWER_PROFILE_CFG.
+ * Made reserved PTP_CFG_SETTINGS field to "opt_ext" field.
+ * Made reserved PTP_CFG_SETTINGS field to "vlan_cfg" field.
+ * Made reserved PTP_STATE field to "parent_clock_class" and "parent_clock_accuracy".
+ * Definitions for MULTI_REF_EXT_OSC added by Andre.
+ * String initializers for supported HaveQuick formats added by Gregoire.
+ * Lots of doxygen changes.
+ * Revision 1.113 2013/04/04 09:02:01Z martin
+ * Added definitions to support HaveQuick.
+ * Fixed a typo.
+ * Revision 1.112 2013/02/19 15:39:13 martin
+ * New PTP settings field ann_rcpt_timeout and associated
+ * values PTP_ANN_RCPT_TIMEOUT_LIMITS.
+ * Changed many defines to named enums to simplify references
+ * with doxygen.
+ * Updated doxygen comments.
+ * Revision 1.111 2013/02/01 15:37:36 martin
+ * Added and modified a huge number of doxygen comments.
+ * Revision 1.110 2013/01/16 15:23:25 martin
+ * Fixed 2 comments which were interchanged.
+ * Revision 1.109 2013/01/11 10:39:34 martin
+ * Added definitions for IMS.
+ * Support XMR_HOLDOVER_INTV.
+ * New XMRS status bit XMRS_BIT_LOW_JITTER / XMRS_MSK_LOW_JITTER.
+ * Added framing type 8E2, though most UARTs don't support this.
+ * Added enum names and updated comments for doxygen.
+ * Revision 1.108 2012/10/30 11:31:16 martin
+ * Defined PTP_UC_MSG_DURATION_MIN and PTP_UC_MSG_DURATION_MAX.
+ * Fixed some doxygen comments.
+ * Changes by andre: changed reserved field to ssm and boc in BITS_OUT settings.
+ * Revision 1.107 2012/10/12 07:40:12 martin
+ * New PTP state flags PTP_FLAG_MSK_UTC_VALID and
+ * PTP_CFG_MSK_SUPP_UTC_VALID.
+ * Revision 1.106 2012/10/02 18:22:10 martin
+ * Added default baud rate and framing for binary protocol.
+ * Added definitions for IRIG codes E002/E112 and NASA36.
+ * Reworked GPIO structures.
+ * Added definitions for GRC, LIU, DCF600RS, and DCF600HS.
+ * New flag POUT_FIXED_PULSE_LEN.
+ * New flag POUT_NOT_INVERTIBLE.
+ * Unified capitalization in MBG_XMRS_STATUS_STRS.
+ * Revision 1.105 2012/06/01 16:31:16 martin
+ * Some TIME_SLOT definitions added by marvin.
+ * Moved some PTP configuration defaults and limits to ptpdflts.h.
+ * Revision 1.104 2012/04/11 16:02:55Z martin
+ * Fixed some doxygen comments.
+ * Revision 1.103 2012/04/02 11:08:57Z martin
+ * Extended description of GPS UTC/leap second data.
+ * Revision 1.102 2012/03/16 11:43:31 martin
+ * Fixed a potential compiler warning.
+ * Revision 1.101 2012/03/06 16:56:01Z martin
+ * Added support for PTP multicast auto role.
+ * Merged Daniel's definitions for PTP profile support.
+ * Support time slot mode for programmable pulse outputs.
+ * Support LNO180.
+ * Moved definition of MBG_MAC_ADDR here.
+ * Use MBG_MAC_ADDR in definition of LAN_IF_INFO.
+ * Revision 1.100 2012/01/17 13:33:55 martin
+ * Added new IRIG RX delay compensation code groups for G0xx and G1xx codes.
+ * As a consequence the value of N_IRIG_RX_COMP has changed.
+ * Added definition of IRIG_RX_COMP_MAX.
+ * Updated IRIG code classification macros.
+ * Removed obsolete/unused definition of CAL_REC_INFO.
+ * Added some comments.
+ * Revision 1.99 2011/12/09 09:22:03 martin
+ * Fixed a typo.
+ * Revision 1.98 2011/11/25 14:58:34 martin
+ * Renamed some evt_log definitions.
+ * Revision 1.97 2011/11/25 10:11:17 martin
+ * Initializers for XMRS status bit strings added by gregoire.
+ * New feature GPS_FEAT_EVT_LOG.
+ * Added definitions used with event logs.
+ * Moved cal_reg and gen_io stuff here.
+ * Added macro _mbg_swab_debug_status().
* Updated some comments.
- * Revision 1.91.1.22 2011/06/29 09:07:50 martin
- * Renamed PZF600PEX to PZF180PEX.
- * Added MGR180, MSF600, WWVB600, and JJY600.
- * Revision 1.91.1.21 2011/06/22 08:23:58 andre
- * Revision 1.91.1.20 2011/06/21 14:11:31Z martin
+ * Revision 1.96 2011/10/11 13:40:46Z andre
+ * changed reserved field into slot_id in XMULTI_REF_INSTANCES
+ * Revision 1.95.1.1 2011/10/07 09:31:58Z andre
+ * Revision 1.95 2011/10/04 09:35:41Z martin
+ * Added support for ESI180.
+ * Changed RECEIVER_INFO::flags bit GPS_10MHZ_DISBD to a RECEIVER_INFO::features bit.
+ * Support MULTI_REF_INTERNAL, MULTI_REF_LWR and MULTI_REF_PZF.
+ * Added MBG_GPIO_BITS structure and associated definitions.
+ * Revision 1.94 2011/08/25 07:42:43Z martin
+ * Fixed a bug in macro _mbg_swab_pout_settings() where the 16 bit timeout
+ * field was swapped using a macro for 32 bit types.
+ * Use shorter names for some PTP unicast master default values.
+ * Revision 1.93 2011/08/10 08:19:38Z martin
+ * New PORT_INFO and PORT_SETTINGS flag PORT_FLAG_PORT_INVISIBLE.
+ * Revision 1.92 2011/07/29 09:49:35 martin
+ * Support PZF180PEX, MGR180, MSF600, WWVB600, JJY600,
+ * GPS180HS, and GPS180AMC.
+ * Added receiver info features GPS_FEAT_PTP_UNICAST
+ * and GPS_FEAT_XMRS_MULT_INSTC.
+ * Added receiver info flag bit GPS_10MHZ_DISBD.
+ * Added initializers for PTP timescale names.
+ * New PTP_STATE flags bit PTP_FLAG_MSK_IS_UNICAST.
+ * Made unused PTP_STATE fields num_clients and num_masters reserved.
+ * Account for different PTP roles.
+ * Added / renamed some definitions for PTP.
+ * Modified default string for PTP layer 2 protocol.
* Support PTP unicast configuration.
* Support GPIO configuration.
- * Support PZF600PEX.
- * Cleaned up handling of pragma pack().
- * Fixed a typo.
- * Revision 1.91.1.19 2011/04/18 13:43:57 martin
- * Doxygen changes.
- * Revision 1.91.1.18 2011/04/18 13:00:33 martin
- * Merged some modified comments from an older branch.
- * Revision 1.91.1.17 2011/04/13 15:34:07 martin
- * Added lots of comments in doxygen style.
- * Revision 1.91.1.16 2011/04/11 09:15:00 andre
- * Revision 1.91.1.15 2011/04/08 08:29:18Z andre
- * Revision 1.91.1.14 2011/04/08 08:10:31Z martin
- * Renamed .._INST_.. to .._INSTC_..
+ * Introduced XMULTI_REF_INSTANCES.
* Moved flags XMRS_..._IS_EXTERNAL and XMRS_..._INSTC_EXCEEDED
* to definitions for XMULTI_REF_STATUS::status.
- * Revision 1.91.1.13 2011/04/07 15:50:16 martin
- * Introduced XMULTI_REF_INSTANCES:
- * Converted some comments to Doxygen style.
- * Revision 1.91.1.12 2011/04/07 13:52:04 martin
- * Revision 1.91.1.11 2011/04/07 13:23:41 martin
- * Started to add GPIO support and configuration stuff.
- * Revision 1.91.1.10 2011/04/07 10:38:43 martin
- * Modified default string for PTP layer 2 protocol.
- * Revision 1.91.1.9 2011/04/07 10:29:36 martin
- * Added initializers for PTP timescale names.
- * Revision 1.91.1.8 2011/02/23 15:11:23 martin
- * New PTP_STATE flags bit PTP_FLAG_MSK_IS_UNICAST.
- * Revision 1.91.1.7 2011/02/23 15:05:54 martin
- * Made unused PTP_STATE fields num_clients and num_masters reserved.
- * Revision 1.91.1.6 2011/02/23 14:47:22 martin
+ * Some comments added, updated, and converted to doxygen style.
+ * Cleaned up handling of pragma pack().
* Removed trailing whitespace and hard tabs.
- * Revision 1.91.1.5 2011/02/23 13:17:06 daniel
- * Revision 1.91.1.4 2011/02/17 14:39:13Z daniel
- * Account for different PTP roles.
- * Revision 1.91.1.3 2011/02/15 14:24:53 martin
- * Revision 1.91.1.2 2011/02/15 11:30:56 martin
- * New feature GPS_FEAT_PTP_UNICAST.
- * Revision 1.91.1.1 2011/02/15 10:54:28 daniel
- * Started to support configuration for PTP unicast.
* Revision 1.91 2011/01/31 11:23:56Z martin
* Added model type name definitions for GPS180PEX and TCR180PEX.
* Introduced synthesizer mode for programmable outputs.
@@ -89,7 +287,7 @@
* Added support for new model GLN170.
* Revision 1.87 2010/03/10 11:29:37Z martin
* Added definitions for GPS180.
- * Added multiref source 1 PPS plus associated string.
+ * Added multi ref source 1 PPS plus associated string.
* Revision 1.86 2010/02/17 14:16:42 martin
* Added definitions for PZF600 and TCR600.
* Revision 1.85 2010/02/15 11:34:36 martin
@@ -159,7 +357,7 @@
* Added definitions for PTP270PEX and FRC511PEX.
* Revision 1.67 2008/07/17 08:54:52Z martin
* Added macros to convert the endianess of structures.
- * Added multiref fixed frequency source.
+ * Added multi ref fixed frequency source.
* Revision 1.66 2008/05/19 14:49:07 daniel
* Renamed s_addr to start_addr in FPGA_INFO.
* Revision 1.65 2008/05/19 09:00:01Z martin
@@ -181,7 +379,7 @@
* Added definitions to support GPS170PEX.
* Revision 1.60 2007/09/13 12:37:35Z martin
* Modified and added initializers for TZDL.
- * Added multiref source PTP over E1.
+ * Added multi ref source PTP over E1.
* Added codes for MSF511 and GRC170 devices.
* Modified XMULTI_REF_SETTINGS and XMULTI_REF_STATUS structures.
* Avoid inclusion of other Meinberg headers in non-Meinberg projects.
@@ -234,7 +432,7 @@
* Added ROM_CSUM, RCV_TIMEOUT, and IGNORE_LOCK types.
* Revision 1.44 2006/05/18 09:34:41Z martin
* Added definitions for POUT max. pulse_len and max timeout.
- * Changed comment for POUT_SETTINGS::timeout:
+ * Changed comment for POUT_SETTINGS::timeout.
* Units are minutes, not seconds.
* Added definition for MAX_POUT_TIME_STR_PORTS.
* Added definitions for POUT mode 10MHz.
@@ -307,7 +505,7 @@
* Revision 1.20 2003/04/03 11:03:44Z martin
* Extended definitions for IRIG support.
* Revision 1.19 2003/01/31 13:38:20 MARTIN
- * Modified type of RECEIVER_INFO.fixed_freq field.
+ * Modified type of RECEIVER_INFO::fixed_freq field.
* Revision 1.18 2002/10/28 09:24:07 MARTIN
* Added/renamed some POUT related symbols.
* Revision 1.17 2002/09/05 10:58:39 MARTIN
@@ -379,6 +577,7 @@
#endif
+
/* Start of header body */
#if defined( _USE_PACK )
@@ -387,12 +586,36 @@
#endif
+
/* "magic" number */
#define MEINBERG_MAGIC 0x6AAC
-#define MIN_SVNO 1 /* min. SV number */
-#define MAX_SVNO 32 /* max. SV number */
-#define N_SVNO ( MAX_SVNO - MIN_SVNO + 1) /* number of possibly active SVs */
+/**
+ * @brief GNSS satellite numbers
+ *
+ * @todo: Check if MAX_SVNO_GLN is 94 instead of 95, and thus
+ * N_SVNO_GLN is 30 instead of 31, as reported by Wikipedia.
+ */
+enum GNSS_SVNOS
+{
+ MIN_SVNO_GPS = 1, ///< min. GPS satellite PRN number
+ MAX_SVNO_GPS = 32, ///< max. GPS satellite PRN number
+ N_SVNO_GPS = 32, ///< max. number of active GPS satellites
+
+ MIN_SVNO_WAAS = 33, ///< min. WAAS satellite number
+ MAX_SVNO_WAAS = 64, ///< max. WAAS satellite number
+ N_SVNO_WAAS = 32, ///< max. number of active WAAS satellites
+
+ MIN_SVNO_GLONASS = 65, ///< min. Glonass satellite number (64 + sat slot ID)
+ MAX_SVNO_GLONASS = 95, ///< max. Glonass satellite number (64 + sat slot ID)
+ N_SVNO_GLONASS = 31 ///< max. number of active Glonass satellites
+};
+
+// for compatibility with GPS-only software:
+#define MIN_SVNO MIN_SVNO_GPS ///< min. SV number
+#define MAX_SVNO MAX_SVNO_GPS ///< max. SV number
+#define N_SVNO N_SVNO_GPS ///< number of possibly active SVs
+
#define GPS_ID_STR_LEN 16
@@ -402,41 +625,42 @@
#define GPS_EPLD_STR_SIZE ( GPS_EPLD_STR_LEN + 1 )
-#define DEFAULT_GPS_TICKS_PER_SEC 10000000L /* system time base */
+#define DEFAULT_GPS_TICKS_PER_SEC 10000000L ///< system time base, see ::GPS_TICKS_PER_SEC
#if !defined( GPS_TICKS_PER_SEC )
/*
* The actual ticks per seconds may vary for different
* GPS receiver models. If this is the case, the receiver
- * model support the RECEIVER_INFO structure which contains
+ * model support the ::RECEIVER_INFO structure which contains
* the actual value.
*/
- #define GPS_TICKS_PER_SEC DEFAULT_GPS_TICKS_PER_SEC
+ #define GPS_TICKS_PER_SEC DEFAULT_GPS_TICKS_PER_SEC ///< see ::DEFAULT_GPS_TICKS_PER_SEC
+
#endif
-typedef uint16_t SVNO; /* the number of a SV */
-typedef uint16_t HEALTH; /* a SV's health code */
-typedef uint16_t CFG; /* a SV's configuration code */
-typedef uint16_t IOD; /* Issue-Of-Data code */
+typedef uint16_t SVNO; ///< the number of an SV (Space Vehicle, i.e. satellite)
+typedef uint16_t HEALTH; ///< an SV's 6 bit health code
+typedef uint16_t CFG; ///< an SV's 4 bit configuration code
+typedef uint16_t IOD; ///< Issue-Of-Data code
/* the type of various checksums */
#ifndef _CSUM_DEFINED
- typedef uint16_t CSUM;
+ typedef uint16_t CSUM; ///< checksum used by some structures stored in non-volatile memory
#define _CSUM_DEFINED
-
- #define _mbg_swab_csum( _p ) _mbg_swab16( _p )
#endif
+#define _mbg_swab_csum( _p ) _mbg_swab16( _p )
+
+
/**
* @brief The type of a GPS command code
*
- * These command codes can be passed via
- * @ref gps_cmds_serial "serial port" (see @file gpsserio.h), or
- * @ref gps_cmds_bus "system bus" (see @file pcpsdefs.h).
+ * @see ::GPS_CMD_CODES
+ * @see ::PC_GPS_CMD_CODES
*/
typedef uint16_t GPS_CMD;
@@ -448,23 +672,27 @@ typedef uint16_t GPS_CMD;
*
* Contains a software revision code, plus an optional
* identifier for a customized version.
+ *
+ * @see @ref group_ext_sys_info
*/
typedef struct
{
- uint16_t code; /**< Version number, e.g. 0x0120 means v1.20 */
- char name[GPS_ID_STR_SIZE]; /**< Optional string identifying a customized version */
- uint8_t reserved; /**< Reserved field to yield even structure size */
+ uint16_t code; ///< Version number, e.g. 0x0120 means v1.20
+ char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized firmware version, should be empty in standard versions
+ uint8_t reserved; ///< Reserved field to yield even structure size
+
} SW_REV;
#define _mbg_swab_sw_rev( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->code ); \
-}
+} while ( 0 )
/**
- * @defgroup group_bvar_stat BVAR_STAT status of buffered GPS data
+ * @defgroup group_bvar_stat Status of buffered (non-volatile) data
*
* Status word, associated bit numbers and bit masks indicating
* whether certain data from the GPS satellites are
@@ -476,93 +704,141 @@ typedef struct
* @{ */
/**
- * @brief Status flags of battery buffered data received
- * from GPS satellites.
+ * @brief Status flags of battery buffered data
+ *
+ * Related to data received from the satellites, or data derived thereof.
*
* All '0' means OK, single bits set to '1' indicate
* the associated type of GPS data is not available.
+ *
+ * @see ::BVAR_FLAGS
*/
typedef uint16_t BVAR_STAT;
#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) )
-/** @brief Enumeration of bits used with BVAR_STAT */
-enum
+/**
+ * @brief Enumeration of flag bits used to define ::BVAR_FLAGS
+ *
+ * For each bit which is set this means the associated data set in
+ * non-volatile memory is not available, or incomplete.
+ * Most data sets will just be re-collected from the data streams sent
+ * by the satellites. However, the receiver position has usually been
+ * computed earlier during normal operation, and will be re-computed
+ * when a sufficient number of satellites can be received.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAGS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAG_BITS
{
- BVAR_BIT_CFGH_INVALID,
- BVAR_BIT_ALM_NOT_COMPLETE,
- BVAR_BIT_UTC_INVALID,
- BVAR_BIT_IONO_INVALID,
- BVAR_BIT_RCVR_POS_INVALID,
- N_BVAR_BIT /**< @brief number of defined ::BVAR_STAT bits */
+ BVAR_BIT_CFGH_INVALID, ///< Satellite configuration and health parameters incomplete
+ BVAR_BIT_ALM_NOT_COMPLETE, ///< Almanac parameters incomplete
+ BVAR_BIT_UTC_INVALID, ///< %UTC offset parameters incomplete
+ BVAR_BIT_IONO_INVALID, ///< Ionospheric correction parameters incomplete
+ BVAR_BIT_RCVR_POS_INVALID, ///< No valid receiver position available
+ N_BVAR_BIT ///< number of defined ::BVAR_STAT bits
};
-#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID ) /**< @brief Configuration and health data (::CFGH) not valid */
-#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ) /**< @brief Almanach data (::ALM) not complete */
-#define BVAR_UTC_INVALID ( 1UL << BVAR_BIT_UTC_INVALID ) /**< @brief UTC data not valid */
-#define BVAR_IONO_INVALID ( 1UL << BVAR_BIT_IONO_INVALID ) /**< @brief Ionospheric correction data (::IONO) not valid */
-#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID ) /**< @brief Receiver position (::POS) not valid */
-
-#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) /**< @brief Bit mask for all defined bits */
-/** @} group_bvar_stat */
+/**
+ * @brief Bit masks associated with ::BVAR_FLAG_BITS
+ *
+ * Used with ::BVAR_STAT.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAG_BITS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAGS
+{
+ BVAR_CFGH_INVALID = ( 1UL << BVAR_BIT_CFGH_INVALID ), ///< see ::BVAR_BIT_CFGH_INVALID
+ BVAR_ALM_NOT_COMPLETE = ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ), ///< see ::BVAR_BIT_ALM_NOT_COMPLETE
+ BVAR_UTC_INVALID = ( 1UL << BVAR_BIT_UTC_INVALID ), ///< see ::BVAR_BIT_UTC_INVALID
+ BVAR_IONO_INVALID = ( 1UL << BVAR_BIT_IONO_INVALID ), ///< see ::BVAR_BIT_IONO_INVALID
+ BVAR_RCVR_POS_INVALID = ( 1UL << BVAR_BIT_RCVR_POS_INVALID ), ///< see ::BVAR_BIT_RCVR_POS_INVALID
+};
+#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) ///< Bit mask for all defined bits
/**
- A structure used to hold a fixed frequency value.
- frequ[kHz] = khz_val * 10^range
-*/
+ * @brief String initializer for ::BVAR_STAT flag names
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAG_BITS
+ * @see ::BVAR_FLAGS
+ */
+#define BVAR_FLAG_NAMES \
+{ \
+ "Sat. config and health", \
+ "Almanac", \
+ "UTC offset", \
+ "Ionospheric correction", \
+ "Receiver position" \
+}
+/** @} defgroup group_bvar_stat */
+
+
+
+/**
+ * @brief A structure used to hold a fixed frequency value
+ *
+ * @note frequ[kHz] = khz_val * 10^range
+ */
typedef struct
{
- uint16_t khz_val; /* the base frequency in [kHz] */
- int16_t range; /* an optional base 10 exponent */
+ uint16_t khz_val; ///< the base frequency in [kHz]
+ int16_t range; ///< an optional base 10 exponent
+
} FIXED_FREQ_INFO;
#define _mbg_swab_fixed_freq_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->khz_val ); \
_mbg_swab16( &(_p)->range ); \
-}
+} while ( 0 )
+
+/**
+ * @brief A data type to specify feature flags within ::RECEIVER_INFO
+ */
+typedef uint32_t RI_FEATURES; ///< see @ref GPS_FEATURE_MASKS
-typedef uint32_t RI_FEATURES; // type of RECEIVER_INFO::features field
-/*
- * The following code defines features and properties
- * of the various GPS receivers. Older GPS receivers
- * may require a recent firmvare version to support
- * this, or may not support this at all.
- */
-
-/**
- * The structure is ordered in a way that all fields
- * except chars or arrays of chars are word-aligned.
- */
-typedef struct
-{
- uint16_t model_code; /**< identifier for receiver model */
- SW_REV sw_rev; /**< software revision and ID */
- char model_name[GPS_ID_STR_SIZE]; /**< ASCIIZ, name of receiver model */
- char sernum[GPS_ID_STR_SIZE]; /**< ASCIIZ, serial number */
- char epld_name[GPS_EPLD_STR_SIZE]; /**< ASCIIZ, file name of EPLD image */
- uint8_t n_channels; /**< number of sats to be tracked simultaneously */
- uint32_t ticks_per_sec; /**< resolution of fractions of seconds */
- RI_FEATURES features; /**< optional features, see below */
- FIXED_FREQ_INFO fixed_freq; /**< optional non-standard fixed frequency */
- uint8_t osc_type; /**< type of installed oscillator, see below */
- uint8_t osc_flags; /**< oscillator flags, see below */
- uint8_t n_ucaps; /**< number of user time capture inputs */
- uint8_t n_com_ports; /**< number of on-board serial ports */
- uint8_t n_str_type; /**< max num of string types supported by any port */
- uint8_t n_prg_out; /**< number of programmable pulse outputs */
- uint16_t flags; /**< additional information, see below */
+/**
+ * @brief A structure used to identify a device type and supported features
+ *
+ * @note This may not be supported by some very old devices.
+ */
+typedef struct
+{
+ uint16_t model_code; ///< identifier for receiver model, see ::GPS_MODEL_CODES
+ SW_REV sw_rev; ///< software revision and ID
+ char model_name[GPS_ID_STR_SIZE]; ///< ASCIIZ, name of receiver model
+ char sernum[GPS_ID_STR_SIZE]; ///< ASCIIZ, serial number
+ char epld_name[GPS_EPLD_STR_SIZE]; ///< ASCIIZ, file name of EPLD image (optional)
+ uint8_t n_channels; ///< number of satellites which can be tracked simultaneously
+ uint32_t ticks_per_sec; ///< resolution of fractions of seconds, see ::GPS_TICKS_PER_SEC
+ RI_FEATURES features; ///< optional features, see @ref GPS_FEATURE_MASKS
+ FIXED_FREQ_INFO fixed_freq; ///< optional non-standard fixed frequency, may be 0 if not supported
+ uint8_t osc_type; ///< type of installed oscillator, see ::GPS_OSC_TYPES
+ uint8_t osc_flags; ///< oscillator flags, actually not used and always 0
+ uint8_t n_ucaps; ///< number of user time capture inputs
+ uint8_t n_com_ports; ///< number of on-board serial ports
+ uint8_t n_str_type; ///< max num of string types supported by any port
+ uint8_t n_prg_out; ///< number of programmable pulse outputs
+ uint16_t flags; ///< additional information, see ::RECEIVER_INFO_FLAG_MASKS
+
} RECEIVER_INFO;
#define _mbg_swab_receiver_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->model_code ); \
_mbg_swab_sw_rev( &(_p)->sw_rev ); \
@@ -570,13 +846,16 @@ typedef struct
_mbg_swab32( &(_p)->features ); \
_mbg_swab_fixed_freq_info( &(_p)->fixed_freq ); \
_mbg_swab16( &(_p)->flags ); \
-}
+} while ( 0 )
/**
- * Valid codes for RECEIVER_INFO.model_code:
+ * @brief Known device ID codes for ::RECEIVER_INFO::model_code
+ *
+ * @see @ref GPS_MODEL_NAMES
+ * @see ::DEFAULT_GPS_MODEL_NAMES
*/
-enum
+enum GPS_MODEL_CODES
{
GPS_MODEL_UNKNOWN,
GPS_MODEL_GPS166,
@@ -617,21 +896,82 @@ enum
GPS_MODEL_MSF600,
GPS_MODEL_WWVB600,
GPS_MODEL_JJY600,
+ GPS_MODEL_GPS180HS,
+ GPS_MODEL_GPS180AMC,
+ GPS_MODEL_ESI180,
+ GPS_MODEL_CPE180,
+ GPS_MODEL_LNO180,
+ GPS_MODEL_GRC180,
+ GPS_MODEL_LIU,
+ GPS_MODEL_DCF600HS,
+ GPS_MODEL_DCF600RS,
+ GPS_MODEL_MRI,
+ GPS_MODEL_BPE,
+ GPS_MODEL_GLN180PEX,
+ GPS_MODEL_N2X,
+ GPS_MODEL_RSC180,
+ GPS_MODEL_LNE_GB,
+ GPS_MODEL_PPG180,
+ GPS_MODEL_SCG,
+ GPS_MODEL_MDU300,
+ GPS_MODEL_SDI,
+ GPS_MODEL_FDM180,
+ GPS_MODEL_SPT,
+ GPS_MODEL_PZF180,
+ GPS_MODEL_REL1000,
+ GPS_MODEL_HPS100,
+ GPS_MODEL_VSG180,
+ GPS_MODEL_MSF180,
+ GPS_MODEL_WWVB180,
+ GPS_MODEL_CPC180,
+ GPS_MODEL_CTC100,
+ GPS_MODEL_TCR180,
+ GPS_MODEL_LUE180,
+ GPS_MODEL_CPC_01,
+ GPS_MODEL_TSU_01,
+ GPS_MODEL_CMC_01,
+ GPS_MODEL_SCU_01,
+ GPS_MODEL_FCU_01,
+ GPS_MODEL_CSM100,
+ GPS_MODEL_LNE180SFP,
+ GPS_MODEL_GTS180,
+ GPS_MODEL_GPS180CSM,
+ GPS_MODEL_GRC181,
+ GPS_MODEL_N2X180,
+ GPS_MODEL_GNS181PEX,
+ GPS_MODEL_MDU180,
+ GPS_MODEL_MDU312,
+ GPS_MODEL_GPS165,
+ GPS_MODEL_GNS181_UC,
+ GPS_MODEL_PSX_4GE,
+ GPS_MODEL_RSC180RDU,
+ GPS_MODEL_USYNCPWR,
+ GPS_MODEL_FDM180M,
+ GPS_MODEL_LSG180, // Line Signal Generator
+ GPS_MODEL_GPS190,
+ GPS_MODEL_GNS181,
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. */
+ * to update the associated string initializers GPS_MODEL_NAMES
+ * and GPS_MODEL_NAME_TABLE accordingly, and to check whether
+ * the classification macros also cover the new model names.
+ */
};
+/**
+ * @brief Model name strings used with Meinberg devices
+ *
+ * String initializers for each of the device models
+ * enumerated in ::GPS_MODEL_CODES.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::DEFAULT_GPS_MODEL_NAMES
+ *
+ * @anchor GPS_MODEL_NAMES @{ */
-/*
- * String initializers for each of the GPS
- * receiver models enum'ed above:
- */
-#define GPS_MODEL_NAME_UNKNOWN "(unknown)"
+#define GPS_MODEL_NAME_UNKNOWN "Unknown"
#define GPS_MODEL_NAME_GPS166 "GPS166"
#define GPS_MODEL_NAME_GPS167 "GPS167"
#define GPS_MODEL_NAME_GPS167SV "GPS167SV"
@@ -670,13 +1010,76 @@ enum
#define GPS_MODEL_NAME_MSF600 "MSF600"
#define GPS_MODEL_NAME_WWVB600 "WWVB600"
#define GPS_MODEL_NAME_JJY600 "JJY600"
+#define GPS_MODEL_NAME_GPS180HS "GPS180HS"
+#define GPS_MODEL_NAME_GPS180AMC "GPS180AMC"
+#define GPS_MODEL_NAME_ESI180 "ESI180"
+#define GPS_MODEL_NAME_CPE180 "CPE180"
+#define GPS_MODEL_NAME_LNO180 "LNO180"
+#define GPS_MODEL_NAME_GRC180 "GRC180"
+#define GPS_MODEL_NAME_LIU "LIU"
+#define GPS_MODEL_NAME_DCF600HS "DCF600HS"
+#define GPS_MODEL_NAME_DCF600RS "DCF600RS"
+#define GPS_MODEL_NAME_MRI "MRI"
+#define GPS_MODEL_NAME_BPE "BPE"
+#define GPS_MODEL_NAME_GLN180PEX "GLN180PEX"
+#define GPS_MODEL_NAME_N2X "N2X"
+#define GPS_MODEL_NAME_RSC180 "RSC180"
+#define GPS_MODEL_NAME_LNE_GB "LNE_GB"
+#define GPS_MODEL_NAME_PPG180 "PPG180"
+#define GPS_MODEL_NAME_SCG "SCG"
+#define GPS_MODEL_NAME_MDU300 "MDU300"
+#define GPS_MODEL_NAME_SDI "SDI"
+#define GPS_MODEL_NAME_FDM180 "FDM180"
+#define GPS_MODEL_NAME_SPT "SPT"
+#define GPS_MODEL_NAME_PZF180 "PZF180"
+#define GPS_MODEL_NAME_REL1000 "REL1000"
+#define GPS_MODEL_NAME_HPS100 "HPS100"
+#define GPS_MODEL_NAME_VSG180 "VSG180"
+#define GPS_MODEL_NAME_MSF180 "MSF180"
+#define GPS_MODEL_NAME_WWVB180 "WWVB180"
+#define GPS_MODEL_NAME_CPC180 "CPC180"
+#define GPS_MODEL_NAME_CTC100 "CTC100"
+#define GPS_MODEL_NAME_TCR180 "TCR180"
+#define GPS_MODEL_NAME_LUE180 "LUE180"
+#define GPS_MODEL_NAME_CPC_01 "CPC_01"
+#define GPS_MODEL_NAME_TSU_01 "TSU_01"
+#define GPS_MODEL_NAME_CMC_01 "CMC_01"
+#define GPS_MODEL_NAME_SCU_01 "SCU_01"
+#define GPS_MODEL_NAME_FCU_01 "FCU_01"
+#define GPS_MODEL_NAME_CSM100 "CSM100"
+#define GPS_MODEL_NAME_LNE180SFP "LNE180SFP"
+#define GPS_MODEL_NAME_GTS180 "GTS180"
+#define GPS_MODEL_NAME_GPS180CSM "GPS180CSM"
+#define GPS_MODEL_NAME_GRC181 "GRC181"
+#define GPS_MODEL_NAME_N2X180 "N2X180"
+#define GPS_MODEL_NAME_GNS181PEX "GNS181PEX"
+#define GPS_MODEL_NAME_MDU180 "MDU180"
+#define GPS_MODEL_NAME_MDU312 "MDU312"
+#define GPS_MODEL_NAME_GPS165 "GPS165"
+#define GPS_MODEL_NAME_GNS181_UC "GNS181_UC"
+#define GPS_MODEL_NAME_PSX_4GE "PSX_4GE"
+#define GPS_MODEL_NAME_RSC180RDU "RSC180RDU"
+#define GPS_MODEL_NAME_USYNCPWR "MICROSYNC-PWR"
+#define GPS_MODEL_NAME_FDM180M "FDM180M"
+#define GPS_MODEL_NAME_LSG180 "LSG180"
+#define GPS_MODEL_NAME_GPS190 "GPS190"
+#define GPS_MODEL_NAME_GNS181 "GNS181"
+
+/** @} anchor GPS_MODEL_NAMES */
-/*
- * The definition below can be used to initialize
- * an array of N_GPS_MODEL type name strings.
- * Including the trailing 0, each name must not
- * exceed GPS_ID_STR_SIZE chars.
+
+/**
+ * @brief An initializer for a table of device names
+ *
+ * Can be used to initialize an array of ::N_GPS_MODEL
+ * type name strings.
+ *
+ * @note Including the trailing 0, each name must not
+ * exceed ::GPS_ID_STR_SIZE chars.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_NAMES
*/
#define DEFAULT_GPS_MODEL_NAMES \
{ \
@@ -718,9 +1121,778 @@ enum
GPS_MODEL_NAME_MGR180, \
GPS_MODEL_NAME_MSF600, \
GPS_MODEL_NAME_WWVB600, \
- GPS_MODEL_NAME_JJY600 \
+ GPS_MODEL_NAME_JJY600, \
+ GPS_MODEL_NAME_GPS180HS, \
+ GPS_MODEL_NAME_GPS180AMC, \
+ GPS_MODEL_NAME_ESI180, \
+ GPS_MODEL_NAME_CPE180, \
+ GPS_MODEL_NAME_LNO180, \
+ GPS_MODEL_NAME_GRC180, \
+ GPS_MODEL_NAME_LIU, \
+ GPS_MODEL_NAME_DCF600HS, \
+ GPS_MODEL_NAME_DCF600RS, \
+ GPS_MODEL_NAME_MRI, \
+ GPS_MODEL_NAME_BPE, \
+ GPS_MODEL_NAME_GLN180PEX, \
+ GPS_MODEL_NAME_N2X, \
+ GPS_MODEL_NAME_RSC180, \
+ GPS_MODEL_NAME_LNE_GB, \
+ GPS_MODEL_NAME_PPG180, \
+ GPS_MODEL_NAME_SCG, \
+ GPS_MODEL_NAME_MDU300, \
+ GPS_MODEL_NAME_SDI, \
+ GPS_MODEL_NAME_FDM180, \
+ GPS_MODEL_NAME_SPT, \
+ GPS_MODEL_NAME_PZF180, \
+ GPS_MODEL_NAME_REL1000, \
+ GPS_MODEL_NAME_HPS100, \
+ GPS_MODEL_NAME_VSG180, \
+ GPS_MODEL_NAME_MSF180, \
+ GPS_MODEL_NAME_WWVB180, \
+ GPS_MODEL_NAME_CPC180, \
+ GPS_MODEL_NAME_CTC100, \
+ GPS_MODEL_NAME_TCR180, \
+ GPS_MODEL_NAME_LUE180, \
+ GPS_MODEL_NAME_CPC_01, \
+ GPS_MODEL_NAME_TSU_01, \
+ GPS_MODEL_NAME_CMC_01, \
+ GPS_MODEL_NAME_SCU_01, \
+ GPS_MODEL_NAME_FCU_01, \
+ GPS_MODEL_NAME_CSM100, \
+ GPS_MODEL_NAME_LNE180SFP, \
+ GPS_MODEL_NAME_GTS180, \
+ GPS_MODEL_NAME_GPS180CSM, \
+ GPS_MODEL_NAME_GRC181, \
+ GPS_MODEL_NAME_N2X180, \
+ GPS_MODEL_NAME_GNS181PEX, \
+ GPS_MODEL_NAME_MDU180, \
+ GPS_MODEL_NAME_MDU312, \
+ GPS_MODEL_NAME_GPS165, \
+ GPS_MODEL_NAME_GNS181_UC, \
+ GPS_MODEL_NAME_PSX_4GE, \
+ GPS_MODEL_NAME_RSC180RDU, \
+ GPS_MODEL_NAME_USYNCPWR, \
+ GPS_MODEL_NAME_FDM180M, \
+ GPS_MODEL_NAME_LSG180, \
+ GPS_MODEL_NAME_GPS190, \
+ GPS_MODEL_NAME_GNS181 \
+}
+
+
+
+
+/**
+ * @brief Definitions used to classify devices and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::GPS_BUILTIN_FEATURE_BITS
+ * @see @ref GPS_BUILTIN_FEATURE_MASKS
+ *
+ * @anchor GPS_BUILTIN_FEATURE_DEFS @{ */
+
+
+/**
+ * @brief A data type to hold a mask of @ref GPS_BUILTIN_FEATURE_MASKS
+ *
+ * @see @ref GPS_BUILTIN_FEATURE_MASKS
+ */
+typedef uint32_t BUILTIN_FEATURE_MASK;
+
+
+/**
+ * @brief Enumeration of classifiers and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_BUILTIN_FEATURE_MASKS
+ */
+enum GPS_BUILTIN_FEATURE_BITS
+{
+ GPS_BIT_MODEL_IS_GPS,
+ GPS_BIT_MODEL_IS_GNSS,
+ GPS_BIT_MODEL_IS_TCR,
+ GPS_BIT_MODEL_IS_DCF_AM,
+ GPS_BIT_MODEL_IS_DCF_PZF,
+ GPS_BIT_MODEL_IS_MSF,
+ GPS_BIT_MODEL_IS_JJY,
+ GPS_BIT_MODEL_IS_WWVB,
+
+ GPS_BIT_MODEL_IS_BUS_LVL_DEV,
+ GPS_BIT_MODEL_HAS_BVAR_STAT,
+ GPS_BIT_MODEL_HAS_POS_XYZ,
+ GPS_BIT_MODEL_HAS_POS_LLA,
+ GPS_BIT_MODEL_HAS_TIME_TTM,
+ GPS_BIT_MODEL_HAS_TZDL,
+ GPS_BIT_MODEL_HAS_TZCODE,
+ GPS_BIT_MODEL_HAS_ANT_INFO,
+
+ GPS_BIT_MODEL_HAS_ENABLE_FLAGS,
+ GPS_BIT_MODEL_HAS_STAT_INFO,
+ GPS_BIT_MODEL_HAS_ANT_CABLE_LEN,
+ GPS_BIT_MODEL_HAS_SCU_STAT,
+ GPS_BIT_MODEL_HAS_SV_INFO,
+
+ GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV,
+
+#if 0 //### TODO This has to be discussed
+ GPS_BIT_MODEL_IS_LNO,
+ GPS_BIT_MODEL_IS_SCU,
+#endif
+
+ N_GPS_BUILTIN_FEATURE_BITS
+};
+
+
+
+/**
+ * @brief Bit masks associated with classifiers and built-in features
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see ::GPS_BUILTIN_FEATURE_BITS
+ *
+ * @anchor GPS_BUILTIN_FEATURE_MASKS @{ */
+
+#define GPS_MODEL_IS_GPS ( 1UL << GPS_BIT_MODEL_IS_GPS ) ///< see ::GPS_BIT_MODEL_IS_GPS
+#define GPS_MODEL_IS_GNSS ( 1UL << GPS_BIT_MODEL_IS_GNSS ) ///< see ::GPS_BIT_MODEL_IS_GNSS
+#define GPS_MODEL_IS_TCR ( 1UL << GPS_BIT_MODEL_IS_TCR ) ///< see ::GPS_BIT_MODEL_IS_TCR
+#define GPS_MODEL_IS_DCF_AM ( 1UL << GPS_BIT_MODEL_IS_DCF_AM ) ///< see ::GPS_BIT_MODEL_IS_DCF_AM
+#define GPS_MODEL_IS_DCF_PZF ( 1UL << GPS_BIT_MODEL_IS_DCF_PZF ) ///< see ::GPS_BIT_MODEL_IS_DCF_PZF
+#define GPS_MODEL_IS_MSF ( 1UL << GPS_BIT_MODEL_IS_MSF ) ///< see ::GPS_BIT_MODEL_IS_MSF
+#define GPS_MODEL_IS_JJY ( 1UL << GPS_BIT_MODEL_IS_JJY ) ///< see ::GPS_BIT_MODEL_IS_JJY
+#define GPS_MODEL_IS_WWVB ( 1UL << GPS_BIT_MODEL_IS_WWVB ) ///< see ::GPS_BIT_MODEL_IS_WWVB
+
+#define GPS_MODEL_IS_BUS_LVL_DEV ( 1UL << GPS_BIT_MODEL_IS_BUS_LVL_DEV ) ///< see ::GPS_BIT_MODEL_IS_BUS_LVL_DEV
+#define GPS_MODEL_HAS_BVAR_STAT ( 1UL << GPS_BIT_MODEL_HAS_BVAR_STAT ) ///< see ::GPS_BIT_MODEL_HAS_BVAR_STAT
+#define GPS_MODEL_HAS_POS_XYZ ( 1UL << GPS_BIT_MODEL_HAS_POS_XYZ ) ///< see ::GPS_BIT_MODEL_HAS_POS_XYZ
+#define GPS_MODEL_HAS_POS_LLA ( 1UL << GPS_BIT_MODEL_HAS_POS_LLA ) ///< see ::GPS_BIT_MODEL_HAS_POS_LLA
+#define GPS_MODEL_HAS_TIME_TTM ( 1UL << GPS_BIT_MODEL_HAS_TIME_TTM ) ///< see ::GPS_BIT_MODEL_HAS_TIME_TTM
+#define GPS_MODEL_HAS_TZDL ( 1UL << GPS_BIT_MODEL_HAS_TZDL ) ///< see ::GPS_BIT_MODEL_HAS_TZDL
+#define GPS_MODEL_HAS_TZCODE ( 1UL << GPS_BIT_MODEL_HAS_TZCODE ) ///< see ::GPS_BIT_MODEL_HAS_TZCODE
+#define GPS_MODEL_HAS_ANT_INFO ( 1UL << GPS_BIT_MODEL_HAS_ANT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_ANT_INFO
+
+#define GPS_MODEL_HAS_ENABLE_FLAGS ( 1UL << GPS_BIT_MODEL_HAS_ENABLE_FLAGS ) ///< see ::GPS_BIT_MODEL_HAS_ENABLE_FLAGS
+#define GPS_MODEL_HAS_STAT_INFO ( 1UL << GPS_BIT_MODEL_HAS_STAT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_STAT_INFO
+#define GPS_MODEL_HAS_ANT_CABLE_LEN ( 1UL << GPS_BIT_MODEL_HAS_ANT_CABLE_LEN ) ///< see ::GPS_BIT_MODEL_HAS_ANT_CABLE_LEN
+#define GPS_MODEL_HAS_SCU_STAT ( 1UL << GPS_BIT_MODEL_HAS_SCU_STAT ) ///< see ::GPS_BIT_MODEL_HAS_SCU_STAT
+#define GPS_MODEL_HAS_SV_INFO ( 1UL << GPS_BIT_MODEL_HAS_SV_INFO ) ///< see ::GPS_BIT_MODEL_HAS_SV_INFO
+
+#if 0 // ### TODO This has to be discussed
+ #define GPS_MODEL_IS_LNO ( 1UL << GPS_BIT_MODEL_IS_LNO ) ///< see ::GPS_BIT_MODEL_IS_LNO
+ #define GPS_MODEL_IS_SCU ( 1UL << GPS_BIT_MODEL_IS_SCU ) ///< see ::GPS_BIT_MODEL_IS_SCU
+#endif
+
+// ### TODO do we need the next one?
+#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV ( 1UL << GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV ) ///< see ::GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV
+
+//### TODO: should we use an extra flag?
+#define GPS_MODEL_HAS_POS ( GPS_MODEL_HAS_POS_XYZ | GPS_MODEL_HAS_POS_LLA )
+
+/** @} anchor GPS_BUILTIN_FEATURE_MASKS */
+
+
+#if 0 //##++ more potential builtin features and classifiers
+
+ GPS_MODEL_HAS_CFGH | \
+ GPS_MODEL_HAS_ALM | \
+ GPS_MODEL_HAS_EPH | \
+ GPS_MODEL_HAS_UTC | \
+ GPS_MODEL_HAS_IONO \
+
+#define GPS_MODEL_HAS_AUTO_ON // --
+#define GPS_MODEL_HAS_AUTO_OFF // --
+#define GPS_MODEL_HAS_SW_REV // deprecated, use only if ri not supported
+#define GPS_MODEL_HAS_BVAR_STAT // req
+#define GPS_MODEL_HAS_POS_XYZ // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_XYZ ?
+#define GPS_MODEL_HAS_POS_LLA // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_LLA ?
+#define GPS_MODEL_HAS_TZDL // req
+#define GPS_MODEL_HAS_PORT_PARM // deprecated, use only if ri not supported
+#define GPS_MODEL_HAS_SYNTH // ri GPS_HAS_SYNTH
+#define GPS_MODEL_HAS_ANT_INFO // GPS_MODEL_IS_GPS, also GNSS, or req?
+#define GPS_MODEL_HAS_UCAP // ri n_ucap
+#define GPS_MODEL_HAS_ENABLE_FLAGS // req
+#define GPS_MODEL_HAS_STAT_INFO // req
+#define GPS_MODEL_HAS_SWITCH_PARMS // deprecated, use ...
+#define GPS_MODEL_HAS_STRING_PARMS // deprecated, use ...
+#define GPS_MODEL_HAS_ANT_CABLE_LEN // GPS_MODEL_IS_GPS, also GNSS, or req?
+#define GPS_MODEL_HAS_SYNC_OUTAGE_DELAY // custom
+#define GPS_MODEL_HAS_PULSE_INFO // custom
+#define GPS_MODEL_HAS_OPT_FEATURES // deprecated, use ri
+#define GPS_MODEL_HAS_IRIG_TX_SETTINGS // ri GPS_HAS_IRIG_TX
+#define GPS_MODEL_HAS_RECEIVER_INFO // --
+#define GPS_MODEL_HAS_STR_TYPE_INFO_IDX // ri n_str_type
+#define GPS_MODEL_HAS_PORT_INFO_IDX // ri n_com
+#define GPS_MODEL_HAS_PORT_SETTINGS_IDX // ri n_com
+#define GPS_MODEL_HAS_POUT_INFO_IDX // ri n_pout
+#define GPS_MODEL_HAS_POUT_SETTINGS_IDX // ri n_pout
+#define GPS_MODEL_HAS_IRIG_TX_INFO // ri GPS_HAS_IRIG_TX
+#define GPS_MODEL_HAS_MULTI_REF_SETTINGS // ri GPS_HAS_MULTI_REF
+#define GPS_MODEL_HAS_MULTI_REF_INFO // ri GPS_HAS_MULTI_REF
+#define GPS_MODEL_HAS_ROM_CSUM // ?
+#define GPS_MODEL_HAS_MULTI_REF_STATUS // ri ...
+#define GPS_MODEL_HAS_RCV_TIMEOUT // ri ...
+#define GPS_MODEL_HAS_IRIG_RX_SETTINGS // ri ...
+#define GPS_MODEL_HAS_IRIG_RX_INFO // ri ...
+#define GPS_MODEL_HAS_REF_OFFS // ri ...
+#define GPS_MODEL_HAS_DEBUG_STATUS //
+#define GPS_MODEL_HAS_XMR_SETTINGS_IDX //
+#define GPS_MODEL_HAS_XMR_INFO_IDX //
+#define GPS_MODEL_HAS_XMR_STATUS_IDX //
+#define GPS_MODEL_HAS_OPT_SETTINGS //
+#define GPS_MODEL_HAS_OPT_INFO //
+#define GPS_MODEL_HAS_CLR_UCAP_BUFF //
+#define GPS_MODEL_HAS_TIME_SCALE //
+#define GPS_MODEL_HAS_NAV_ENG_SETTINGS //
+#define GPS_MODEL_HAS_RAW_IRIG_DATA //
+#define GPS_MODEL_HAS_GPIO_CFG_LIMITS //
+#define GPS_MODEL_HAS_GPIO_INFO_IDX //
+#define GPS_MODEL_HAS_GPIO_SETTINGS_IDX //
+#define GPS_MODEL_HAS_XMR_INSTANCES //
+#define GPS_MODEL_HAS_CLR_EVT_LOG //
+#define GPS_MODEL_HAS_NUM_EVT_LOG_ENTRIES //
+#define GPS_MODEL_HAS_FIRST_EVT_LOG_ENTRY //
+#define GPS_MODEL_HAS_NEXT_EVT_LOG_ENTRY //
+#define GPS_MODEL_HAS_LNO_STATUS //
+#define GPS_MODEL_HAS_IMS_STATE //
+#define GPS_MODEL_HAS_IMS_SENSOR_STATE_IDX //
+#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV //
+#define GPS_MODEL_HAS_HAVEQUICK_RX_SETTINGS //
+#define GPS_MODEL_HAS_HAVEQUICK_RX_INFO //
+#define GPS_MODEL_HAS_HAVEQUICK_TX_SETTINGS //
+#define GPS_MODEL_HAS_HAVEQUICK_TX_INFO //
+#define GPS_MODEL_HAS_PTP_CFG //
+#define GPS_MODEL_HAS_PTP_STATE //
+#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG_LIMITS //
+#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG //
+#define GPS_MODEL_HAS_NTP_GLB_CFG //
+#define GPS_MODEL_HAS_NTP_CLNT_MODE_CFG //
+#define GPS_MODEL_HAS_NTP_SRV_MODE_CFG //
+#define GPS_MODEL_HAS_NTP_PEER_SETTINGS_IDX //
+#define GPS_MODEL_HAS_NTP_SYS_STATE //
+#define GPS_MODEL_HAS_NTP_PEER_STATE_IDX //
+#define GPS_MODEL_HAS_SHS //
+#define GPS_MODEL_HAS_SHS_STATUS //
+#define GPS_MODEL_HAS_NET_GLB_CFG //
+#define GPS_MODEL_HAS_NET_DNS_SRVR //
+#define GPS_MODEL_HAS_NET_DNS_SRCH_DOM //
+#define GPS_MODEL_HAS_NET_STAT_DNS_SRVR //
+#define GPS_MODEL_HAS_NET_STAT_DNS_SRCH_DOM //
+#define GPS_MODEL_HAS_GNSS_SAT_INFO_IDX //
+
+#define GPS_MODEL_HAS_CFGH //
+#define GPS_MODEL_HAS_ALM //
+#define GPS_MODEL_HAS_EPH //
+#define GPS_MODEL_HAS_UTC //
+#define GPS_MODEL_HAS_IONO //
+#define GPS_MODEL_HAS_ASCII_MSG //
+
+#define GPS_MODEL_HAS_GLNS_ALM //
+#define GPS_MODEL_HAS_GNSS_SAT_INFO //
+//#define GPS_MODEL_HAS_GNSS_MODE //
+
+#define GPS_MODEL_HAS_IP4_SETTINGS //
+#define GPS_MODEL_HAS_LAN_IF_INFO //
+#define GPS_MODEL_HAS_IP4_STATE //
+
+#define GPS_MODEL_HAS_CRYPTED_PACKET //
+#define GPS_MODEL_HAS_CRYPTED_RAW_PACKET //
+
+#define GPS_MODEL_HAS_SECU_INFO //
+#define GPS_MODEL_HAS_SECU_SETTINGS //
+#define GPS_MODEL_HAS_SECU_PUBLIC_KEY //
+
+#endif //##++ more potential builtin features and classifiers
+
+
+
+/**
+ * @brief Common builtin features of all GPS receivers
+ *
+ * @see ::BUILTIN_FEAT_GPS_BUS_LVL
+ * @see ::BUILTIN_FEAT_GNSS
+ */
+#define BUILTIN_FEAT_GPS \
+( \
+ GPS_MODEL_IS_GPS | \
+ GPS_MODEL_HAS_BVAR_STAT | \
+ GPS_MODEL_HAS_POS_XYZ | \
+ GPS_MODEL_HAS_POS_LLA | \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS | \
+ GPS_MODEL_HAS_STAT_INFO | \
+ GPS_MODEL_HAS_ANT_CABLE_LEN | \
+ GPS_MODEL_HAS_SV_INFO \
+)
+
+
+/**
+ * @brief Common builtin features of all GNSS receivers
+ *
+ * GNSS includes GPS but optionally other satellite systems,
+ * and the associated API.
+ *
+ * @see ::BUILTIN_FEAT_GNSS_BUS_LVL
+ * @see ::BUILTIN_FEAT_GPS
+ */
+#define BUILTIN_FEAT_GNSS \
+( \
+ BUILTIN_FEAT_GPS | \
+ GPS_MODEL_IS_GNSS \
+)
+
+
+
+/**
+ * @brief Common builtin features of all simple TCR devices
+ */
+#define BUILTIN_FEAT_TCR_1 \
+( \
+ GPS_MODEL_IS_TCR \
+)
+
+
+/**
+ * @brief Common builtin features of all enhanced TCR devices
+ */
+#define BUILTIN_FEAT_TCR_2 \
+( \
+ GPS_MODEL_IS_TCR | \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS \
+)
+
+
+
+/**
+ * @brief Common builtin features of all simple DCF77 AM receivers
+ */
+#define BUILTIN_FEAT_DCF_1 \
+( \
+ GPS_MODEL_IS_DCF_AM | \
+ GPS_MODEL_HAS_TZCODE \
+)
+
+
+/**
+ * @brief Common builtin features of all enhanced DCF77 AM receivers
+ */
+#define BUILTIN_FEAT_DCF_2 \
+( \
+ GPS_MODEL_IS_DCF_AM | \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS \
+)
+
+
+/**
+ * @brief Common builtin features of all simple DCF77 PZF receivers
+ */
+#define BUILTIN_FEAT_DCF_PZF_1 \
+( \
+ GPS_MODEL_IS_DCF_PZF | \
+ GPS_MODEL_HAS_TZCODE \
+)
+
+
+/**
+ * @brief Common builtin features of all enhanced DCF77 PZF receivers
+ */
+#define BUILTIN_FEAT_DCF_PZF_2 \
+( \
+ GPS_MODEL_IS_DCF_PZF | \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS \
+)
+
+
+
+/**
+ * @brief Common builtin features of all simple MSF receivers
+ */
+#define BUILTIN_FEAT_MSF_1 \
+( \
+ GPS_MODEL_IS_MSF | \
+ GPS_MODEL_HAS_TZCODE \
+)
+
+
+/**
+ * @brief Common builtin features of all enhanced MSF receivers
+ */
+#define BUILTIN_FEAT_MSF_2 \
+( \
+ GPS_MODEL_IS_MSF | \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ANT_INFO | \
+ GPS_MODEL_HAS_ENABLE_FLAGS \
+)
+
+
+
+/**
+ * @brief Common builtin features of all simple WWVB receivers
+ */
+#define BUILTIN_FEAT_WVB_1 \
+( \
+ GPS_MODEL_IS_WWVB | \
+ GPS_MODEL_HAS_TZCODE \
+)
+
+
+/**
+ * @brief Common builtin features of all enhanced WWVB receivers
+ */
+#define BUILTIN_FEAT_WVB_2 \
+( \
+ GPS_MODEL_IS_WWVB | \
+ GPS_MODEL_HAS_TZDL \
+)
+
+
+
+/**
+ * @brief Common builtin features of all simple JJY receivers
+ */
+#define BUILTIN_FEAT_JJY_1 \
+( \
+ GPS_MODEL_IS_JJY | \
+ GPS_MODEL_HAS_TZCODE \
+)
+
+
+
+/**
+ * @brief Common builtin features of all N2X devices
+ */
+#define BUILTIN_FEAT_COMM_N2X \
+( \
+ GPS_MODEL_HAS_TIME_TTM | \
+ GPS_MODEL_HAS_TZDL | \
+ GPS_MODEL_HAS_ENABLE_FLAGS \
+)
+
+
+
+/**
+ * @brief Common builtin features of all bus-level GPS receivers
+ */
+#define BUILTIN_FEAT_GPS_BUS_LVL ( BUILTIN_FEAT_GPS | GPS_MODEL_IS_BUS_LVL_DEV )
+
+
+/**
+ * @brief Common builtin features of all bus-level GNSS receivers
+ */
+#define BUILTIN_FEAT_GNSS_BUS_LVL ( BUILTIN_FEAT_GNSS | GPS_MODEL_IS_BUS_LVL_DEV )
+
+
+/**
+ * @brief Common builtin features of all simple, bus-level TCR devices
+ */
+#define BUILTIN_FEAT_TCR_1_BUS_LVL ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_IS_BUS_LVL_DEV )
+
+/**
+ * @brief Common builtin features of all enhanced, bus-level TCR devices
+ */
+#define BUILTIN_FEAT_TCR_2_BUS_LVL ( BUILTIN_FEAT_TCR_2 | GPS_MODEL_IS_BUS_LVL_DEV )
+
+
+/**
+ * @brief Common builtin features of all simple, bus-level DCF77 AM receivers
+ */
+#define BUILTIN_FEAT_DCF_1_BUS_LVL ( BUILTIN_FEAT_DCF_1 | GPS_MODEL_IS_BUS_LVL_DEV )
+
+/**
+ * @brief Common builtin features of all enhanced, bus-level DCF77 AM receivers
+ */
+#define BUILTIN_FEAT_DCF_2_BUS_LVL ( BUILTIN_FEAT_DCF_2 | GPS_MODEL_IS_BUS_LVL_DEV )
+
+/**
+ * @brief Common builtin features of all enhanced, bus-level DCF77 PZF receivers
+ */
+#define BUILTIN_FEAT_DCF_PZF_2_BUS_LVL ( BUILTIN_FEAT_DCF_PZF_2 | GPS_MODEL_IS_BUS_LVL_DEV )
+
+
+
+/**
+ * @brief Definitions of builtin features per device type
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_BUILTIN_FEATURES
+ *
+ * @anchor GPS_MODEL_BUILTIN_FEATURE_MASKS @{ */
+
+#define BUILTIN_FEAT_GPS166 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167SV ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS167PC ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_GPS167PCI ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_GPS163 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS168PCI ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_GPS161 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS169PCI ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_TCR167PCI ( BUILTIN_FEAT_TCR_2_BUS_LVL )
+#define BUILTIN_FEAT_GPS164 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS170PCI ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_PZF511 ( BUILTIN_FEAT_DCF_PZF_1 )
+#define BUILTIN_FEAT_GPS170 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_TCR511 ( BUILTIN_FEAT_TCR_1_BUS_LVL | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2?
+#define BUILTIN_FEAT_AM511 ( BUILTIN_FEAT_DCF_1 )
+#define BUILTIN_FEAT_MSF511 ( BUILTIN_FEAT_MSF_1 )
+#define BUILTIN_FEAT_GRC170 ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_GPS170PEX ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_GPS162 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_PTP270PEX ( GPS_MODEL_IS_BUS_LVL_DEV )
+#define BUILTIN_FEAT_FRC511PEX ( GPS_MODEL_IS_BUS_LVL_DEV )
+#define BUILTIN_FEAT_GEN170 ( 0 )
+#define BUILTIN_FEAT_TCR170PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL )
+#define BUILTIN_FEAT_WWVB511 ( BUILTIN_FEAT_WVB_1 )
+#define BUILTIN_FEAT_MGR170 ( 0 )
+#define BUILTIN_FEAT_JJY511 ( BUILTIN_FEAT_JJY_1 )
+#define BUILTIN_FEAT_PZF600 ( BUILTIN_FEAT_DCF_PZF_1 ) //### TODO Or full PZF_2?
+#define BUILTIN_FEAT_TCR600 ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2?
+#define BUILTIN_FEAT_GPS180 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GLN170 ( BUILTIN_FEAT_GNSS)
+#define BUILTIN_FEAT_GPS180PEX ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_TCR180PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL )
+#define BUILTIN_FEAT_PZF180PEX ( BUILTIN_FEAT_DCF_PZF_2_BUS_LVL )
+#define BUILTIN_FEAT_MGR180 ( 0 )
+#define BUILTIN_FEAT_MSF600 ( BUILTIN_FEAT_MSF_1 ) //### TODO Or full MSF_2?
+#define BUILTIN_FEAT_WWVB600 ( BUILTIN_FEAT_WVB_1 ) //### TODO Or full WVB_2?
+#define BUILTIN_FEAT_JJY600 ( BUILTIN_FEAT_JJY_1 ) //### TODO Or full JJY_2?
+#define BUILTIN_FEAT_GPS180HS ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GPS180AMC ( BUILTIN_FEAT_GPS_BUS_LVL )
+#define BUILTIN_FEAT_ESI180 ( 0 )
+#define BUILTIN_FEAT_CPE180 ( 0 )
+#define BUILTIN_FEAT_LNO180 ( 0 )
+#define BUILTIN_FEAT_GRC180 ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_LIU ( 0 )
+#define BUILTIN_FEAT_DCF600HS ( BUILTIN_FEAT_DCF_2 ) //### TODO
+#define BUILTIN_FEAT_DCF600RS ( BUILTIN_FEAT_DCF_2 ) //### TODO
+#define BUILTIN_FEAT_MRI ( 0 )
+#define BUILTIN_FEAT_BPE ( 0 )
+#define BUILTIN_FEAT_GLN180PEX ( BUILTIN_FEAT_GNSS_BUS_LVL )
+#define BUILTIN_FEAT_N2X ( BUILTIN_FEAT_COMM_N2X )
+#define BUILTIN_FEAT_RSC180 ( GPS_MODEL_HAS_SCU_STAT )
+#define BUILTIN_FEAT_LNE_GB ( 0 )
+#define BUILTIN_FEAT_PPG180 ( 0 )
+#define BUILTIN_FEAT_SCG ( 0 )
+#define BUILTIN_FEAT_MDU300 ( 0 )
+#define BUILTIN_FEAT_SDI ( 0 )
+#define BUILTIN_FEAT_FDM180 ( GPS_MODEL_HAS_TZDL | GPS_MODEL_HAS_ENABLE_FLAGS )
+#define BUILTIN_FEAT_SPT ( 0 )
+#define BUILTIN_FEAT_PZF180 ( BUILTIN_FEAT_DCF_PZF_2 )
+#define BUILTIN_FEAT_REL1000 ( 0 )
+#define BUILTIN_FEAT_HPS100 ( 0 )
+#define BUILTIN_FEAT_VSG180 ( 0 )
+#define BUILTIN_FEAT_MSF180 ( BUILTIN_FEAT_MSF_2 )
+#define BUILTIN_FEAT_WWVB180 ( BUILTIN_FEAT_WVB_2 )
+#define BUILTIN_FEAT_CPC180 ( 0 )
+#define BUILTIN_FEAT_CTC100 ( 0 )
+#define BUILTIN_FEAT_TCR180 ( BUILTIN_FEAT_TCR_2 )
+#define BUILTIN_FEAT_LUE180 ( 0 )
+#define BUILTIN_FEAT_CPC_01 ( 0 )
+#define BUILTIN_FEAT_TSU_01 ( 0 )
+#define BUILTIN_FEAT_CMC_01 ( 0 )
+#define BUILTIN_FEAT_SCU_01 ( 0 )
+#define BUILTIN_FEAT_FCU_01 ( 0 )
+#define BUILTIN_FEAT_CSM100 ( 0 )
+#define BUILTIN_FEAT_LNE180SFP ( 0 )
+#define BUILTIN_FEAT_GTS180 ( 0 )
+#define BUILTIN_FEAT_GPS180CSM ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GRC181 ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_N2X180 ( BUILTIN_FEAT_COMM_N2X )
+#define BUILTIN_FEAT_GNS181PEX ( BUILTIN_FEAT_GNSS_BUS_LVL )
+#define BUILTIN_FEAT_MDU180 ( GPS_MODEL_HAS_SCU_STAT )
+#define BUILTIN_FEAT_MDU312 ( 0 )
+#define BUILTIN_FEAT_GPS165 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GNS181_UC ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_PSX_4GE ( 0 )
+#define BUILTIN_FEAT_RSC180RDU ( GPS_MODEL_HAS_SCU_STAT )
+#define BUILTIN_FEAT_USYNCPWR ( 0 )
+#define BUILTIN_FEAT_FDM180M ( GPS_MODEL_HAS_TZDL | GPS_MODEL_HAS_ENABLE_FLAGS )
+#define BUILTIN_FEAT_LSG180 ( 0 )
+#define BUILTIN_FEAT_GPS190 ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_GNS181 ( BUILTIN_FEAT_GNSS )
+
+/**
+ * @brief Feature mask used for legacy devices
+ *
+ * This code is used to set builtin feature flags
+ * legacy devices not listed here, so we can simply
+ * search for ::BUILTIN_FEAT_UNDEFINED to identify
+ * such devices. The numeric value is just 0, though.
+ */
+#define BUILTIN_FEAT_UNDEFINED ( 0 )
+
+/** @} anchor GPS_MODEL_BUILTIN_FEATURE_MASKS */
+
+
+
+/**
+ * @brief Initializer for a table of built-in features per device
+ *
+ * Last entry is all zero to indicated end of table.
+ *
+ * @see ::GPS_MODEL_CODES
+ * @see @ref GPS_MODEL_BUILTIN_FEATURE_MASKS
+ */
+#define GPS_MODEL_BUILTIN_FEATURES \
+{ \
+ { GPS_MODEL_GPS166, BUILTIN_FEAT_GPS166 }, \
+ { GPS_MODEL_GPS167, BUILTIN_FEAT_GPS167 }, \
+ { GPS_MODEL_GPS167SV, BUILTIN_FEAT_GPS167SV }, \
+ { GPS_MODEL_GPS167PC, BUILTIN_FEAT_GPS167PC }, \
+ { GPS_MODEL_GPS167PCI, BUILTIN_FEAT_GPS167PCI }, \
+ { GPS_MODEL_GPS163, BUILTIN_FEAT_GPS163 }, \
+ { GPS_MODEL_GPS168PCI, BUILTIN_FEAT_GPS168PCI }, \
+ { GPS_MODEL_GPS161, BUILTIN_FEAT_GPS161 }, \
+ { GPS_MODEL_GPS169PCI, BUILTIN_FEAT_GPS169PCI }, \
+ { GPS_MODEL_TCR167PCI, BUILTIN_FEAT_TCR167PCI }, \
+ { GPS_MODEL_GPS164, BUILTIN_FEAT_GPS164 }, \
+ { GPS_MODEL_GPS170PCI, BUILTIN_FEAT_GPS170PCI }, \
+ { GPS_MODEL_PZF511, BUILTIN_FEAT_PZF511 }, \
+ { GPS_MODEL_GPS170, BUILTIN_FEAT_GPS170 }, \
+ { GPS_MODEL_TCR511, BUILTIN_FEAT_TCR511 }, \
+ { GPS_MODEL_AM511, BUILTIN_FEAT_AM511 }, \
+ { GPS_MODEL_MSF511, BUILTIN_FEAT_MSF511 }, \
+ { GPS_MODEL_GRC170, BUILTIN_FEAT_GRC170 }, \
+ { GPS_MODEL_GPS170PEX, BUILTIN_FEAT_GPS170PEX }, \
+ { GPS_MODEL_GPS162, BUILTIN_FEAT_GPS162 }, \
+ { GPS_MODEL_PTP270PEX, BUILTIN_FEAT_PTP270PEX }, \
+ { GPS_MODEL_FRC511PEX, BUILTIN_FEAT_FRC511PEX }, \
+ { GPS_MODEL_GEN170, BUILTIN_FEAT_GEN170 }, \
+ { GPS_MODEL_TCR170PEX, BUILTIN_FEAT_TCR170PEX }, \
+ { GPS_MODEL_WWVB511, BUILTIN_FEAT_WWVB511 }, \
+ { GPS_MODEL_MGR170, BUILTIN_FEAT_MGR170 }, \
+ { GPS_MODEL_JJY511, BUILTIN_FEAT_JJY511 }, \
+ { GPS_MODEL_PZF600, BUILTIN_FEAT_PZF600 }, \
+ { GPS_MODEL_TCR600, BUILTIN_FEAT_TCR600 }, \
+ { GPS_MODEL_GPS180, BUILTIN_FEAT_GPS180 }, \
+ { GPS_MODEL_GLN170, BUILTIN_FEAT_GLN170 }, \
+ { GPS_MODEL_GPS180PEX, BUILTIN_FEAT_GPS180PEX }, \
+ { GPS_MODEL_TCR180PEX, BUILTIN_FEAT_TCR180PEX }, \
+ { GPS_MODEL_PZF180PEX, BUILTIN_FEAT_PZF180PEX }, \
+ { GPS_MODEL_MGR180, BUILTIN_FEAT_MGR180 }, \
+ { GPS_MODEL_MSF600, BUILTIN_FEAT_MSF600 }, \
+ { GPS_MODEL_WWVB600, BUILTIN_FEAT_WWVB600 }, \
+ { GPS_MODEL_JJY600, BUILTIN_FEAT_JJY600 }, \
+ { GPS_MODEL_GPS180HS, BUILTIN_FEAT_GPS180HS }, \
+ { GPS_MODEL_GPS180AMC, BUILTIN_FEAT_GPS180AMC }, \
+ { GPS_MODEL_ESI180, BUILTIN_FEAT_ESI180 }, \
+ { GPS_MODEL_CPE180, BUILTIN_FEAT_CPE180 }, \
+ { GPS_MODEL_LNO180, BUILTIN_FEAT_LNO180 }, \
+ { GPS_MODEL_GRC180, BUILTIN_FEAT_GRC180 }, \
+ { GPS_MODEL_LIU, BUILTIN_FEAT_LIU }, \
+ { GPS_MODEL_DCF600HS, BUILTIN_FEAT_DCF600HS }, \
+ { GPS_MODEL_DCF600RS, BUILTIN_FEAT_DCF600RS }, \
+ { GPS_MODEL_MRI, BUILTIN_FEAT_MRI }, \
+ { GPS_MODEL_BPE, BUILTIN_FEAT_BPE }, \
+ { GPS_MODEL_GLN180PEX, BUILTIN_FEAT_GLN180PEX }, \
+ { GPS_MODEL_N2X, BUILTIN_FEAT_N2X }, \
+ { GPS_MODEL_RSC180, BUILTIN_FEAT_RSC180 }, \
+ { GPS_MODEL_LNE_GB, BUILTIN_FEAT_LNE_GB }, \
+ { GPS_MODEL_PPG180, BUILTIN_FEAT_PPG180 }, \
+ { GPS_MODEL_SCG, BUILTIN_FEAT_SCG }, \
+ { GPS_MODEL_MDU300, BUILTIN_FEAT_MDU300 }, \
+ { GPS_MODEL_SDI, BUILTIN_FEAT_SDI }, \
+ { GPS_MODEL_FDM180, BUILTIN_FEAT_FDM180 }, \
+ { GPS_MODEL_SPT, BUILTIN_FEAT_SPT }, \
+ { GPS_MODEL_PZF180, BUILTIN_FEAT_PZF180 }, \
+ { GPS_MODEL_REL1000, BUILTIN_FEAT_REL1000 }, \
+ { GPS_MODEL_HPS100, BUILTIN_FEAT_HPS100 }, \
+ { GPS_MODEL_VSG180, BUILTIN_FEAT_VSG180 }, \
+ { GPS_MODEL_MSF180, BUILTIN_FEAT_MSF180 }, \
+ { GPS_MODEL_WWVB180, BUILTIN_FEAT_WWVB180 }, \
+ { GPS_MODEL_CPC180, BUILTIN_FEAT_CPC180 }, \
+ { GPS_MODEL_CTC100, BUILTIN_FEAT_CTC100 }, \
+ { GPS_MODEL_TCR180, BUILTIN_FEAT_TCR180 }, \
+ { GPS_MODEL_LUE180, BUILTIN_FEAT_LUE180 }, \
+ { GPS_MODEL_CPC_01, BUILTIN_FEAT_CPC_01 }, \
+ { GPS_MODEL_TSU_01, BUILTIN_FEAT_TSU_01 }, \
+ { GPS_MODEL_CMC_01, BUILTIN_FEAT_CMC_01 }, \
+ { GPS_MODEL_SCU_01, BUILTIN_FEAT_SCU_01 }, \
+ { GPS_MODEL_FCU_01, BUILTIN_FEAT_FCU_01 }, \
+ { GPS_MODEL_CSM100, BUILTIN_FEAT_CSM100 }, \
+ { GPS_MODEL_LNE180SFP, BUILTIN_FEAT_LNE180SFP }, \
+ { GPS_MODEL_GTS180, BUILTIN_FEAT_GTS180 }, \
+ { GPS_MODEL_GPS180CSM, BUILTIN_FEAT_GPS180CSM }, \
+ { GPS_MODEL_GRC181, BUILTIN_FEAT_GRC181 }, \
+ { GPS_MODEL_N2X180, BUILTIN_FEAT_N2X180 }, \
+ { GPS_MODEL_GNS181PEX, BUILTIN_FEAT_GNS181PEX }, \
+ { GPS_MODEL_MDU180, BUILTIN_FEAT_MDU180 }, \
+ { GPS_MODEL_MDU312, BUILTIN_FEAT_MDU312 }, \
+ { GPS_MODEL_GPS165, BUILTIN_FEAT_GPS165 }, \
+ { GPS_MODEL_GNS181_UC, BUILTIN_FEAT_GNS181_UC }, \
+ { GPS_MODEL_PSX_4GE, BUILTIN_FEAT_PSX_4GE }, \
+ { GPS_MODEL_RSC180RDU, BUILTIN_FEAT_RSC180RDU }, \
+ { GPS_MODEL_USYNCPWR, BUILTIN_FEAT_USYNCPWR }, \
+ { GPS_MODEL_FDM180M, BUILTIN_FEAT_FDM180M }, \
+ { GPS_MODEL_LSG180, BUILTIN_FEAT_LSG180 }, \
+ { GPS_MODEL_GPS190, BUILTIN_FEAT_GPS190 }, \
+ { GPS_MODEL_GNS181, BUILTIN_FEAT_GNS181 }, \
+ { 0, 0 } \
}
+/** @} anchor GPS_BUILTIN_FEATURE_DEFS */
+
+
+
+/**
+ * @brief Initialize a ::RECEIVER_INFO structure for legacy DCF77 receivers
+ *
+ * Legacy DCF77 receivers may not provide a ::RECEIVER_INFO structure,
+ * but have well-known properties which can be used to set up a
+ * default ::RECEIVER_INFO.
+ *
+ * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up
+ * @param[in] _pdev Pointer to a ::PCPS_DEV structure read before
+ *
+ * @see ::_setup_default_receiver_info_gps
+ */
+#define _setup_default_receiver_info_dcf( _p, _pdev ) \
+do \
+{ \
+ memset( (_p), 0, sizeof( *(_p) ) ); \
+ \
+ (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \
+ (_p)->n_ucaps = 0; \
+ (_p)->n_com_ports = _pcps_has_serial( _pdev ) ? 1 : 0; \
+ (_p)->n_str_type = ( (_p)->n_com_ports != 0 ) ? \
+ DEFAULT_N_STR_TYPE_DCF : 0; \
+} while ( 0 )
+
+
+
+/**
+ * @brief Initialize a ::RECEIVER_INFO structure for legacy GPS receivers
+ *
+ * Legacy GPS receivers may not provide a ::RECEIVER_INFO structure,
+ * but have well-known properties which can be used to set up a
+ * default ::RECEIVER_INFO.
+ *
+ * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up
+ *
+ * @see ::_setup_default_receiver_info_dcf
+ */
+#define _setup_default_receiver_info_gps( _p ) \
+do \
+{ \
+ memset( (_p), 0, sizeof( *(_p) ) ); \
+ \
+ (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \
+ (_p)->n_ucaps = 2; \
+ (_p)->n_com_ports = DEFAULT_N_COM; \
+ (_p)->n_str_type = DEFAULT_N_STR_TYPE_GPS; \
+} while ( 0 )
+
+
/*
* The macros below can be used to classify a receiver,
@@ -730,11 +1902,11 @@ enum
#define _mbg_rcvr_is_plug_in( _p_ri ) \
( strstr( (_p_ri)->model_name, "PC" ) || \
- ( strstr( (_p_ri)->model_name, "PEX" ) )
+ strstr( (_p_ri)->model_name, "PEX" ) )
#define _mbg_rcvr_is_gps( _p_ri ) \
( strstr( (_p_ri)->model_name, "GPS" ) || \
- ( strstr( (_p_ri)->model_name, "MGR" ) )
+ strstr( (_p_ri)->model_name, "MGR" ) )
#define _mbg_rcvr_is_mobile_gps( _p_ri ) \
( strstr( (_p_ri)->model_name, "MGR" ) )
@@ -784,7 +1956,7 @@ enum
#define _mbg_rcvr_is_glonass( _p_ri ) \
( strstr( (_p_ri)->model_name, "GRC" ) || \
- ( strstr( (_p_ri)->model_name, "GLN" ) )
+ strstr( (_p_ri)->model_name, "GLN" ) )
#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \
( _mbg_rcvr_is_glonass( _p_ri ) && \
@@ -798,13 +1970,17 @@ enum
_mbg_rcvr_is_plug_in( _p_ri ) )
+
/**
- * The classification codes for oscillators below
- * are used with RECEIVER_INFO.osc_type. New codes
- * must be appended to the enumeration, so the sequence
- * of codes does NOT reflect the order of quality:
+ * @brief Known oscillator types used with ::RECEIVER_INFO::osc_type
+ *
+ * The sequence of codes does NOT reflect the order of quality.
+ * New oscillator type codes will just be appended to the enumeration.
+ *
+ * @see ::DEFAULT_GPS_OSC_NAMES
+ * @see ::DEFAULT_GPS_OSC_QUALITY_IDX
*/
-enum
+enum GPS_OSC_TYPES
{
GPS_OSC_UNKNOWN,
GPS_OSC_TCXO_LQ,
@@ -816,14 +1992,19 @@ enum
GPS_OSC_RUBIDIUM,
GPS_OSC_TCXO_MQ,
GPS_OSC_OCXO_DHQ,
+ GPS_OSC_OCXO_SQ,
N_GPS_OSC
};
-/*
- * The sequence and number of oscillator names
- * listed below must correspond to the enumeration
- * above:
+/**
+ * @brief Oscillator type name string initializer
+ *
+ * The sequence and number of oscillator names has to
+ * correspond to the enumeration in ::GPS_OSC_TYPES
+ *
+ * @see ::GPS_OSC_TYPES
+ * @see ::DEFAULT_GPS_OSC_QUALITY_IDX
*/
#define DEFAULT_GPS_OSC_NAMES \
{ \
@@ -836,15 +2017,21 @@ enum
"OCXO XHQ", \
"RUBIDIUM", \
"TCXO MQ", \
- "OCXO DHQ" \
+ "OCXO DHQ", \
+ "OCXO SQ" \
}
-/*
- * The initializer below can be used to initialize
- * an array (e.g. "int osc_quality_idx[N_GPS_OSC]")
- * which allows to display the oscillator types
- * ordered by quality:
+/**
+ * @brief Oscillator quality index
+ *
+ * Can be used to initialize a index array
+ * (e.g. "int osc_quality_idx[N_GPS_OSC];")
+ * allowing to display the oscillator types
+ * ordered by quality
+ *
+ * @see ::GPS_OSC_TYPES
+ * @see ::DEFAULT_GPS_OSC_NAMES
*/
#define DEFAULT_GPS_OSC_QUALITY_IDX \
{ \
@@ -853,6 +2040,7 @@ enum
GPS_OSC_TCXO_MQ, \
GPS_OSC_TCXO_HQ, \
GPS_OSC_OCXO_LQ, \
+ GPS_OSC_OCXO_SQ, \
GPS_OSC_OCXO_MQ, \
GPS_OSC_OCXO_HQ, \
GPS_OSC_OCXO_DHQ, \
@@ -862,45 +2050,71 @@ enum
-/*
- * Codes to be used with RECEIVER_INFO.osc_flags
- * are not yet used/required, so they are reserved
- * for future use.
- */
-
-
/**
- * The codes below enumerate some features which may be
- * supported by a given clock, or not.
+ * @brief Enumeration of device features flags reported in ::RI_FEATURES
+ *
+ * Used with ::RECEIVER_INFO::features. Each flags indicates if a device
+ * supports the associated feature, but due to the limited bit size of
+ * the ::RI_FEATURES type the number of these features is limited to 32.
+ *
+ * To extend the number of possible features the ::MBG_XFEATURE_BITS, the
+ * ::MBG_XFEATURE_BUFFER structure and associated definitions have been
+ * introduced, which are supported by devices which have ::GPS_HAS_XFEATURE
+ * set in ::RI_FEATURES.
+ *
+ * @see ::RI_FEATURES
+ * @see ::MBG_XFEATURE_BITS
+ * @see ::MBG_XFEATURE_BUFFER
*/
-enum
+enum GPS_FEATURE_BITS
{
- GPS_FEAT_PPS, /**< has pulse per second output */
- GPS_FEAT_PPM, /**< has pulse per minute output */
- GPS_FEAT_SYNTH, /**< has programmable synthesizer output */
- GPS_FEAT_DCFMARKS, /**< has DCF77 compatible time mark output */
- GPS_FEAT_IRIG_TX, /**< has on-board IRIG output */
- GPS_FEAT_IRIG_RX, /**< has on-board IRIG input */
- GPS_FEAT_LAN_IP4, /**< has LAN IPv4 interface */
- GPS_FEAT_MULTI_REF, /**< has multiple input sources with priorities */
- GPS_FEAT_RCV_TIMEOUT, /**< timeout after GPS reception has stopped */
- GPS_FEAT_IGNORE_LOCK, /**< supports "ignore lock", alternatively */
- /**< MBG_OPT_BIT_EMU_SYNC may be supported */
- GPS_FEAT_5_MHZ, /**< output 5 MHz rather than 100 kHz */
- GPS_FEAT_XMULTI_REF, /**< has extended multiple input source configuration */
- GPS_FEAT_OPT_SETTINGS, /**< supports MBG_OPT_SETTINGS */
- GPS_FEAT_TIME_SCALE, /**< supports configurable time scale (UTC, TAI, GPS, ...) */
- GPS_FEAT_IRIG_CTRL_BITS, /**< supports IRIG control bits */
- GPS_FEAT_PTP, /**< has PTP support */
- GPS_FEAT_NAV_ENGINE_SETTINGS, /**< supports navigation engine configuration */
- GPS_FEAT_RAW_IRIG_DATA, /**< supports reading raw IRIG input data */
- GPS_FEAT_RAW_IRIG_TIME, /**< supports reading decoded IRIG time */
- GPS_FEAT_PTP_UNICAST, /**< has PTP Unicast support */
- GPS_FEAT_GPIO, /**< has general purpose in/outputs */
- N_GPS_FEATURE /**< the number of valid features */
+ GPS_FEAT_PPS, ///< has pulse per second output
+ GPS_FEAT_PPM, ///< has pulse per minute output
+ GPS_FEAT_SYNTH, ///< has programmable synthesizer output
+ GPS_FEAT_DCFMARKS, ///< has DCF77 compatible time mark output
+ GPS_FEAT_IRIG_TX, ///< has on-board IRIG output
+ GPS_FEAT_IRIG_RX, ///< has on-board IRIG input
+ GPS_FEAT_LAN_IP4, ///< has simple LAN IPv4 interface, superseded by ::GPS_FEAT_NET_CFG
+ GPS_FEAT_MULTI_REF, ///< has multiple input sources with priorities, superseded by ::GPS_FEAT_XMULTI_REF
+
+ GPS_FEAT_RCV_TIMEOUT, ///< timeout after GPS reception has stopped
+ GPS_FEAT_IGNORE_LOCK, ///< supports "ignore lock", ::MBG_OPT_BIT_EMU_SYNC can be set alternatively
+ GPS_FEAT_5_MHZ, ///< output 5 MHz rather than 100 kHz
+ GPS_FEAT_XMULTI_REF, ///< has extended multiple input source configuration, supersedes ::GPS_FEAT_MULTI_REF
+ GPS_FEAT_OPT_SETTINGS, ///< supports ::MBG_OPT_SETTINGS
+ GPS_FEAT_TIME_SCALE, ///< supports configurable time scale (%UTC, TAI, GPS, ...)
+ GPS_FEAT_IRIG_CTRL_BITS, ///< supports IRIG control bits (::MBG_IRIG_CTRL_BITS)
+ GPS_FEAT_PTP, ///< has PTP support
+
+ GPS_FEAT_NAV_ENGINE_SETTINGS, ///< supports navigation engine configuration
+ GPS_FEAT_RAW_IRIG_DATA, ///< supports reading raw IRIG input data (::MBG_RAW_IRIG_DATA)
+ GPS_FEAT_RAW_IRIG_TIME, ///< supports reading decoded IRIG time (::PCPS_IRIG_TIME)
+ GPS_FEAT_PTP_UNICAST, ///< has PTP Unicast support
+ GPS_FEAT_GPIO, ///< has general purpose inputs/outputs
+ GPS_FEAT_XMRS_MULT_INSTC, ///< multiple XMRS instances of the same ref type supported (::XMULTI_REF_INSTANCES)
+ GPS_FEAT_10MHZ_DISBD, ///< 10 MHz output is always disabled
+ GPS_FEAT_EVT_LOG, ///< Event logging supported
+
+ GPS_FEAT_IMS, ///< supports IMS data structures
+ GPS_FEAT_HAVEQUICK, ///< supports HaveQuick structures
+ GPS_FEAT_NTP, ///< supports NTP structures
+ GPS_FEAT_NET_CFG, ///< supports extended network interface configuration, supersedes ::GPS_FEAT_LAN_IP4
+ GPS_FEAT_VST, ///< supports VST (Versatile Storage) API and structures
+ GPS_FEAT_SHS, ///< supports SHS (Secure Hybrid System) API and structures
+ GPS_FEAT_XBP, ///< supports XBP (eXtended Binary Protocol) API and structures, see @ref group_xbp
+ GPS_FEAT_XFEATURE, ///< support eXtended features, see @ref group_xfeature
+ N_GPS_FEATURE ///< the number of known ::GPS_FEATURE_BITS, should now be at its limit, i.e. 32.
+
+ // WARNING: There are no more unassigned feature bits available here.
+ // New features have to be defined using the ::MBG_XFEATURE_BITS
};
+/**
+ * @brief Names of device features
+ *
+ * @see ::GPS_FEATURE_BITS
+ */
#define DEFAULT_GPS_FEATURE_NAMES \
{ \
"Pulse Per Second", \
@@ -923,37 +2137,197 @@ enum
"Raw IRIG Data", \
"Raw IRIG Time", \
"PTP/IEEE1588 Unicast", \
- "General Purpose I/O" \
+ "General Purpose I/O", \
+ "Multiple XMRS Instances", \
+ "10 MHz Output Disabled", \
+ "Event Logging", \
+ "IMS data", \
+ "HaveQuick", \
+ "NTP", \
+ "Ext. Network Config", \
+ "Versatile Storage", \
+ "SHS", \
+ "Extended Binary Protocol", \
+ "Extended Features" \
}
-/*
- * Bit masks used with RECEIVER_INFO.features
- * (others are reserved):
- */
-#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS )
-#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM )
-#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH )
-#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS )
-#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX )
-#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX )
-#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 )
-#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF )
-#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT )
-#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK )
-#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ )
-#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF )
-#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS )
-#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE )
-#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS )
-#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP )
-#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS )
-#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA )
-#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME )
-#define GPS_HAS_PTP_UNICAST ( 1UL << GPS_FEAT_PTP_UNICAST )
-#define GPS_HAS_GPIO ( 1UL << GPS_FEAT_GPIO )
-
-#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX
+/**
+ * @brief Bit masks used with ::RECEIVER_INFO::features
+ *
+ * @see ::GPS_FEATURE_BITS
+ *
+ * @anchor GPS_FEATURE_MASKS @{ */
+
+#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS ) ///< see ::GPS_FEAT_PPS
+#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM ) ///< see ::GPS_FEAT_PPM
+#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH ) ///< see ::GPS_FEAT_SYNTH
+#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS ) ///< see ::GPS_FEAT_DCFMARKS
+#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX ) ///< see ::GPS_FEAT_IRIG_TX
+#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX ) ///< see ::GPS_FEAT_IRIG_RX
+#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 ) ///< see ::GPS_FEAT_LAN_IP4
+#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF ) ///< see ::GPS_FEAT_MULTI_REF
+
+#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT ) ///< see ::GPS_FEAT_RCV_TIMEOUT
+#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK ) ///< see ::GPS_FEAT_IGNORE_LOCK
+#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ ) ///< see ::GPS_FEAT_5_MHZ
+#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF ) ///< see ::GPS_FEAT_XMULTI_REF
+#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS ) ///< see ::GPS_FEAT_OPT_SETTINGS
+#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE ) ///< see ::GPS_FEAT_TIME_SCALE
+#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS ) ///< see ::GPS_FEAT_IRIG_CTRL_BITS
+#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP ) ///< see ::GPS_FEAT_PTP
+
+#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS ) ///< see ::GPS_FEAT_NAV_ENGINE_SETTINGS
+#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA ) ///< see ::GPS_FEAT_RAW_IRIG_DATA
+#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME ) ///< see ::GPS_FEAT_RAW_IRIG_TIME
+#define GPS_HAS_PTP_UNICAST ( 1UL << GPS_FEAT_PTP_UNICAST ) ///< see ::GPS_FEAT_PTP_UNICAST
+#define GPS_HAS_GPIO ( 1UL << GPS_FEAT_GPIO ) ///< see ::GPS_FEAT_GPIO
+#define GPS_HAS_XMRS_MULT_INSTC ( 1UL << GPS_FEAT_XMRS_MULT_INSTC ) ///< see ::GPS_FEAT_XMRS_MULT_INSTC
+#define GPS_HAS_10MHZ_DISBD ( 1UL << GPS_FEAT_10MHZ_DISBD ) ///< see ::GPS_FEAT_10MHZ_DISBD
+#define GPS_HAS_EVT_LOG ( 1UL << GPS_FEAT_EVT_LOG ) ///< see ::GPS_FEAT_EVT_LOG
+
+#define GPS_HAS_IMS ( 1UL << GPS_FEAT_IMS ) ///< see ::GPS_FEAT_IMS
+#define GPS_HAS_HAVEQUICK ( 1UL << GPS_FEAT_HAVEQUICK ) ///< see ::GPS_FEAT_HAVEQUICK
+#define GPS_HAS_NTP ( 1UL << GPS_FEAT_NTP ) ///< see ::GPS_FEAT_NTP
+#define GPS_HAS_NET_CFG ( 1UL << GPS_FEAT_NET_CFG ) ///< see ::GPS_FEAT_NET_CFG
+#define GPS_HAS_VST ( 1UL << GPS_FEAT_VST ) ///< see ::GPS_FEAT_VST
+#define GPS_HAS_SHS ( 1UL << GPS_FEAT_SHS ) ///< see ::GPS_FEAT_SHS
+#define GPS_HAS_XBP ( 1UL << GPS_FEAT_XBP ) ///< see ::GPS_FEAT_XBP
+#define GPS_HAS_XFEATURE ( 1UL << GPS_FEAT_XFEATURE ) ///< see ::GPS_FEAT_XFEATURE
+
+// the next ones are special since they just shadow another flag:
+#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX
+#define GPS_HAS_DEBUG_STATUS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX
+
+/** @} anchor GPS_FEATURE_MASKS */
+
+
+/**
+ * @defgroup group_xfeature Extended feature definitions
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::GPS_HAS_XFEATURE is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+
+/**
+ * @brief The maximum number of feature bits supported by the MBG_XFEATURE API.
+ *
+ * Warning: Changing this number breaks API compatibility!
+ *
+ * @see ::MBG_XFEATURE_BITS
+ */
+#define MAX_XFEATURE_BITS 1024
+
+
+
+/**
+ * @brief Enumeration of defined extended features.
+ *
+ * @see ::MBG_XFEATURE_NAMES
+ * @see ::MBG_XFEATURE_BUFFER
+ */
+enum MBG_XFEATURE_BITS
+{
+ MBG_XFEATURE_TLV_API, ///< Supports generic TLV API, see @ref group_tlv_api
+ MBG_XFEATURE_SAVE_CFG, ///< Supports the ::GPS_SAVE_CFG command
+ MBG_XFEATURE_LED_API, ///< Supports programmable LED API, see @ref group_led_api
+ MBG_XFEATURE_LNE_API, ///< Supports specific LNE API, see @ref group_lne_api
+ MBG_XFEATURE_PWR_CTL_API, ///< Supports power control, see @ref group_pwr_ctl_api
+ MBG_XFEATURE_EXT_SYS_INFO, ///< Supports extended revision information, see @ref group_ext_sys_info
+ MBG_XFEATURE_TRANSACTIONS, ///< Supports the ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION commands, see also ::MBG_TRANSACTION_TYPES
+ MBG_XFEATURE_REBOOT, ///< Supports the ::GPS_REBOOT command
+ MBG_XFEATURE_CLK_RES_INFO, ///< Supports the ::GPS_CLK_RES_INFO command, see @ref group_clk_res_info
+ MBG_XFEATURE_UCAP_NET, ///< Supports the ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX commands, see @ref group_ucap_net
+ MBG_XFEATURE_REQ_TTM, ///< Supports TTM requests via GPS_TIME command
+ MBG_XFEATURE_IO_PORTS, ///< Supports I/O port structures, see @ref group_io_ports
+ MBG_XFEATURE_MONITORING, ///< Supports monitoring / notifications, see @ref group_monitoring
+ MBG_XFEATURE_XHE, ///< Supports XHE external rubidium unit I/O commands
+ MBG_XFEATURE_USB_LOCK, ///< Supports USB interrupt structures, see @ref group_usb_lock
+ N_MBG_XFEATURE ///< Number of defined extended features
+ // NOTE If new features are appended here then an appropriate feature
+ // name string has to be appended to ::MBG_XFEATURE_NAMES, and care must
+ // be taken that ::N_MBG_XFEATURE doesn't exceed ::MAX_XFEATURE_BITS.
+};
+
+
+
+/**
+ * @brief Names of extended device features
+ *
+ * Can be used to initialize a string array of ::N_MBG_XFEATURE entries,
+ * so the number of strings must correspond to ::N_MBG_XFEATURE.
+ *
+ * @see ::MBG_XFEATURE_BITS
+ */
+#define MBG_XFEATURE_NAMES \
+{ \
+ "Generic TLV API", \
+ "Save Config On Card", \
+ "Programmable LED API", \
+ "LNE API", \
+ "Power Control API", \
+ "Extended Revision Info", \
+ "Transaction commands", \
+ "Reboot command", \
+ "Clock Resolution Info", \
+ "Extended User Captures", \
+ "Request TTM", \
+ "I/O Ports", \
+ "Monitoring", \
+ "XHE unit", \
+ "USB lock" \
+}
+
+
+
+/**
+ * @brief Array size required to store all extended features
+ *
+ * The number of bytes required to store up to ::MAX_XFEATURE_BITS
+ * feature bits in a byte array.
+ */
+#define MAX_XFEATURE_BYTES ( MAX_XFEATURE_BITS / 8 )
+
+
+
+/**
+ * @brief A structure used to store extended device features.
+ *
+ * Up to ::MAX_XFEATURE_BITS totally can be stored, but only
+ * ::N_MBG_XFEATURE extended features are currently defined.
+ * The ::_set_xfeature_bit macro should be used by the firmware
+ * to set a feature bit in the buffer, and the ::check_xfeature
+ * function should be used to implement API calls which test if an
+ * extended feature is supported.
+ *
+ * @see ::_set_xfeature_bit
+ * @see ::check_xfeature
+ */
+typedef struct
+{
+ uint8_t b[MAX_XFEATURE_BYTES];
+
+} MBG_XFEATURE_BUFFER;
+
+
+
+/**
+ * @brief Set an extended feature bit in a ::MBG_XFEATURE_BUFFER
+ *
+ * Should be used by the firmware only to set one of the ::MBG_XFEATURE_BITS
+ * in an ::MBG_XFEATURE_BUFFER after power-up.
+ *
+ * @param[in] _xf_bit One of the ::MBG_XFEATURE_BITS
+ * @param[in] _xf_buffp Pointer to an ::MBG_XFEATURE_BUFFER
+ */
+#define _set_xfeature_bit( _xf_bit, _xf_buffp ) \
+ _set_array_bit( _xf_bit, (_xf_buffp)->b, MAX_XFEATURE_BYTES )
+
+
+/** @} defgroup group_xfeature */
+
/*
@@ -969,16 +2343,32 @@ enum
}
-/*
- * Codes to be used with RECEIVER_INFO::flags:
+/**
+ * @brief Bits used to define ::RECEIVER_INFO_FLAG_MASKS
*/
-#define GPS_OSC_CFG_SUPP 0x0001 // GPS_OSC_CFG supported
-#define GPS_IRIG_FO_IN 0x0002 // IRIG input via fiber optics
-#define GPS_HAS_FPGA 0x0004 // device provides on-board FPGA
+enum RECEIVER_INFO_FLAG_BITS
+{
+ GPS_BIT_OSC_CFG_SUPP, ///< oscillator cfg is supported, see ::RECEIVER_INFO::osc_type
+ GPS_BIT_IRIG_FO_IN, ///< IRIG input via fiber optics
+ GPS_BIT_HAS_FPGA, ///< device provides on-board FPGA
+ N_RECEIVER_INFO_FLAG_BITS ///< number of known bits
+};
+
+
+/**
+ * @brief Bit masks to be used with ::RECEIVER_INFO::flags
+ */
+enum RECEIVER_INFO_FLAG_MASKS
+{
+ GPS_OSC_CFG_SUPP = ( 1UL << GPS_BIT_OSC_CFG_SUPP ), ///< see ::GPS_BIT_OSC_CFG_SUPP
+ GPS_IRIG_FO_IN = ( 1UL << GPS_BIT_IRIG_FO_IN ), ///< see ::GPS_BIT_IRIG_FO_IN
+ GPS_HAS_FPGA = ( 1UL << GPS_BIT_HAS_FPGA ) ///< see ::GPS_BIT_HAS_FPGA
+};
+
/*
- * If the GPS_HAS_FPGA flag is set in RECEIVER_INFO::flags then the card
+ * If the ::GPS_HAS_FPGA flag is set in ::RECEIVER_INFO::flags then the card
* provides an FPGA and the following information about the FPGA is available:
*/
#define FPGA_NAME_LEN 31 // max name length
@@ -992,11 +2382,7 @@ typedef union
{
CSUM csum;
uint32_t fsize;
- #if _IS_MBG_FIRMWARE
- uint32_t start_addr;
- #else
- uint8_t *start_addr;
- #endif
+ uint32_t start_addr;
char name[FPGA_NAME_SIZE];
} hdr;
@@ -1014,6 +2400,7 @@ typedef struct
{
CSUM csum;
uint16_t fpga_start_seg; // Number of the 4k block where an FPGA image is located
+
} FPGA_START_INFO;
#define DEFAULT_FPGA_START_SEG 0x60
@@ -1027,172 +2414,202 @@ typedef struct
/**
- Date and time referred to the linear time scale defined by GPS.
- GPS time is defined by the number of weeks since midnight from
- January 5, 1980 to January 6, 1980 plus the number of seconds of
- the current week plus fractions of a second. GPS time differs from
- UTC because UTC is corrected with leap seconds while GPS time scale
- is continuous.
-*/
+ * @brief A structure used to hold time in GPS format
+ *
+ * Date and time refer to the linear time scale defined by GPS, with
+ * the epoch starting at %UTC midnight at the beginning of January 6, 1980.
+ *
+ * GPS time is counted by the week numbers since the epoch, plus second
+ * of the week, plus fraction of the second. The week number transmitted
+ * by the satellites rolls over from 1023 to 0, but Meinberg devices
+ * just continue to count the weeks beyond the 1024 week limit to keep
+ * the receiver's internal time.
+ *
+ * %UTC time differs from GPS time since a number of leap seconds have
+ * been inserted in the %UTC time scale after the GPS epoch. The number
+ * of leap seconds is disseminated by the satellites using the ::UTC
+ * parameter set, which also provides info on pending leap seconds.
+ */
typedef struct
{
- uint16_t wn; /**< the week number since GPS has been installed */
- uint32_t sec; /**< the second of that week */
- uint32_t tick; /**< fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
+ uint16_t wn; ///< the week number since the GPS system has been put into operation
+ uint32_t sec; ///< the second of that week
+ uint32_t tick; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
+
} T_GPS;
#define _mbg_swab_t_gps( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->wn ); \
_mbg_swab32( &(_p)->sec ); \
_mbg_swab32( &(_p)->tick ); \
-}
+} while ( 0 )
/**
- Local date and time computed from GPS time. The current number
- of leap seconds have to be added to get UTC from GPS time.
- Additional corrections could have been made according to the
- time zone/daylight saving parameters (TZDL, see below) defined
- by the user. The status field can be checked to see which corrections
- have been applied.
-*/
+ * @brief Local date and time computed from GPS time
+ *
+ * The current number of leap seconds have to be added to get %UTC
+ * from GPS time. Additional corrections could have been made according
+ * to the time zone/daylight saving parameters ::TZDL defined by the user.
+ * The status field can be checked to see which corrections
+ * have actually been applied.
+ *
+ * @note Conversion from GPS time to %UTC and/or local time can only be
+ * done if some valid ::UTC correction parameters are available in the
+ * receiver's non-volatile memory.
+ */
typedef struct
{
- int16_t year; /**< year number, 0..9999 */
- int8_t month; /**< month, 1..12 */
- int8_t mday; /**< day of month, 1..31 */
- int16_t yday; /**< day of year, 1..366 */
- int8_t wday; /**< day of week, 0..6 == Sun..Sat */
- int8_t hour; /**< hours, 0..23 */
- int8_t min; /**< minutes, 0..59 */
- int8_t sec; /**< seconds, 0..59 */
- int32_t frac; /**< fractions of a second; scale: 1/GPS_TICKS_PER_SEC */
- int32_t offs_from_utc; /**< local time's offset from UTC */
- uint16_t status; /**< status flags */
+ int16_t year; ///< year number, 0..9999
+ int8_t month; ///< month, 1..12
+ int8_t mday; ///< day of month, 1..31
+ int16_t yday; ///< day of year, 1..365, or 366 in case of leap year
+ int8_t wday; ///< day of week, 0..6 == Sun..Sat
+ int8_t hour; ///< hours, 0..23
+ int8_t min; ///< minutes, 0..59
+ int8_t sec; ///< seconds, 0..59, or 60 in case of inserted leap second
+ int32_t frac; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
+ int32_t offs_from_utc; ///< local time offset from %UTC [sec]
+ uint16_t status; ///< status flags, see ::TM_GPS_STATUS_BIT_MASKS
+
} TM_GPS;
#define _mbg_swab_tm_gps( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->year ); \
_mbg_swab16( &(_p)->yday ); \
_mbg_swab32( &(_p)->frac ); \
_mbg_swab32( &(_p)->offs_from_utc ); \
_mbg_swab16( &(_p)->status ); \
-}
-
+} while ( 0 )
-/* status flag bits used with conversion from GPS time to local time */
-enum
+/**
+ * @brief Status flag bits used to define ::TM_GPS_STATUS_BIT_MASKS
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BIT_MASKS
+ */
+enum TM_GPS_STATUS_BITS
{
- TM_BIT_UTC, /* UTC correction has been made */
- TM_BIT_LOCAL, /* UTC has been converted to local time */
- TM_BIT_DL_ANN, /* state of daylight saving is going to change */
- TM_BIT_DL_ENB, /* daylight saving is enabled */
- TM_BIT_LS_ANN, /* leap second will be inserted */
- TM_BIT_LS_ENB, /* current second is leap second */
- TM_BIT_LS_ANN_NEG, /* set in addition to TM_LS_ANN if leap sec negative */
- TM_BIT_INVT, /* invalid time, e.g. if RTC battery empty */
-
- TM_BIT_EXT_SYNC, /* sync'd externally */
- TM_BIT_HOLDOVER, /* holdover mode after previous sync. */
- TM_BIT_ANT_SHORT, /* antenna cable short circuited */
- TM_BIT_NO_WARM, /* OCXO has not warmed up */
- TM_BIT_ANT_DISCONN, /* antenna currently disconnected */
- TM_BIT_SYN_FLAG, /* TIME_SYN output is low */
- TM_BIT_NO_SYNC, /* time sync actually not verified */
- TM_BIT_NO_POS /* position actually not verified, LOCK LED off */
-};
-
-// Type of an extended TM status which is mainly used by the firmware.
-typedef uint32_t TM_STATUS_EXT; // extended status, mainly used by the firmware
-
-// The lower 16 bits of the TM_STATUS_X type correspond to those defined above,
-// and the upper bits are defined below:
-enum
+ TM_BIT_UTC, ///< %UTC correction has been made
+ TM_BIT_LOCAL, ///< %UTC has been converted to local time according to ::TZDL settings
+ TM_BIT_DL_ANN, ///< state of daylight saving is going to change
+ TM_BIT_DL_ENB, ///< daylight saving is in effect
+ TM_BIT_LS_ANN, ///< leap second pending
+ TM_BIT_LS_ENB, ///< current second is leap second
+ TM_BIT_LS_ANN_NEG, ///< set in addition to ::TM_BIT_LS_ANN if leap sec is negative
+ TM_BIT_INVT, ///< invalid time, e.g. if RTC battery bas been empty
+
+ TM_BIT_EXT_SYNC, ///< synchronized externally
+ TM_BIT_HOLDOVER, ///< in holdover mode after previous synchronization
+ TM_BIT_ANT_SHORT, ///< antenna cable short circuited
+ TM_BIT_NO_WARM, ///< oscillator control loop not settled
+ TM_BIT_ANT_DISCONN, ///< antenna currently disconnected
+ TM_BIT_SYN_FLAG, ///< clock not synchronized, reflects the state of the "time sync error" output pin
+ TM_BIT_NO_SYNC, ///< time sync actually not verified
+ TM_BIT_NO_POS ///< position actually not verified, LOCK LED off
+};
+
+
+/**
+ * @brief Status flag masks used with ::TM_GPS::status
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BITS
+ */
+enum TM_GPS_STATUS_BIT_MASKS
{
- TM_BIT_SCALE_GPS = 16,
- TM_BIT_SCALE_TAI
- // the remaining bits are reserved
+ TM_UTC = ( 1UL << TM_BIT_UTC ), ///< see ::TM_BIT_UTC
+ TM_LOCAL = ( 1UL << TM_BIT_LOCAL ), ///< see ::TM_BIT_LOCAL
+ TM_DL_ANN = ( 1UL << TM_BIT_DL_ANN ), ///< see ::TM_BIT_DL_ANN
+ TM_DL_ENB = ( 1UL << TM_BIT_DL_ENB ), ///< see ::TM_BIT_DL_ENB
+ TM_LS_ANN = ( 1UL << TM_BIT_LS_ANN ), ///< see ::TM_BIT_LS_ANN
+ TM_LS_ENB = ( 1UL << TM_BIT_LS_ENB ), ///< see ::TM_BIT_LS_ENB
+ TM_LS_ANN_NEG = ( 1UL << TM_BIT_LS_ANN_NEG ), ///< see ::TM_BIT_LS_ANN_NEG
+ TM_INVT = ( 1UL << TM_BIT_INVT ), ///< see ::TM_BIT_INVT
+
+ TM_EXT_SYNC = ( 1UL << TM_BIT_EXT_SYNC ), ///< see ::TM_BIT_EXT_SYNC
+ TM_HOLDOVER = ( 1UL << TM_BIT_HOLDOVER ), ///< see ::TM_BIT_HOLDOVER
+ TM_ANT_SHORT = ( 1UL << TM_BIT_ANT_SHORT ), ///< see ::TM_BIT_ANT_SHORT
+ TM_NO_WARM = ( 1UL << TM_BIT_NO_WARM ), ///< see ::TM_BIT_NO_WARM
+ TM_ANT_DISCONN = ( 1UL << TM_BIT_ANT_DISCONN ), ///< see ::TM_BIT_ANT_DISCONN
+ TM_SYN_FLAG = ( 1UL << TM_BIT_SYN_FLAG ), ///< see ::TM_BIT_SYN_FLAG
+ TM_NO_SYNC = ( 1UL << TM_BIT_NO_SYNC ), ///< see ::TM_BIT_NO_SYNC
+ TM_NO_POS = ( 1UL << TM_BIT_NO_POS ) ///< see ::TM_BIT_NO_POS
};
-/* bit masks corresponding to the flag bits above */
-#define TM_UTC ( 1UL << TM_BIT_UTC )
-#define TM_LOCAL ( 1UL << TM_BIT_LOCAL )
-#define TM_DL_ANN ( 1UL << TM_BIT_DL_ANN )
-#define TM_DL_ENB ( 1UL << TM_BIT_DL_ENB )
-#define TM_LS_ANN ( 1UL << TM_BIT_LS_ANN )
-#define TM_LS_ENB ( 1UL << TM_BIT_LS_ENB )
-#define TM_LS_ANN_NEG ( 1UL << TM_BIT_LS_ANN_NEG )
-#define TM_INVT ( 1UL << TM_BIT_INVT )
+/**
+ * @brief Type of an extended TM status which is mainly used inside the firmware
+ */
+typedef uint32_t TM_STATUS_EXT;
-#define TM_EXT_SYNC ( 1UL << TM_BIT_EXT_SYNC )
-#define TM_HOLDOVER ( 1UL << TM_BIT_HOLDOVER )
-#define TM_ANT_SHORT ( 1UL << TM_BIT_ANT_SHORT )
-#define TM_NO_WARM ( 1UL << TM_BIT_NO_WARM )
-#define TM_ANT_DISCONN ( 1UL << TM_BIT_ANT_DISCONN )
-#define TM_SYN_FLAG ( 1UL << TM_BIT_SYN_FLAG )
-#define TM_NO_SYNC ( 1UL << TM_BIT_NO_SYNC )
-#define TM_NO_POS ( 1UL << TM_BIT_NO_POS )
+/**
+ * @brief Enumeration of extended status bits used with ::TM_STATUS_EXT
+ *
+ * @note The lower 16 bits correspond to ::TM_GPS_STATUS_BITS
+ */
+enum TM_GPS_STATUS_BITS_EX
+{
+ TM_BIT_SCALE_GPS = 16, ///< time scale configured to return GPS time
+ TM_BIT_SCALE_TAI ///< time scale configured to return TAI
+ // the remaining bits are reserved
+};
-// The following bits are only used with the TM_STATUS_X type:
+// The following bits are only used with the ::TM_STATUS_X type:
#define TM_SCALE_GPS ( 1UL << TM_BIT_SCALE_GPS )
#define TM_SCALE_TAI ( 1UL << TM_BIT_SCALE_TAI )
#define TM_MSK_TIME_VALID ( TM_UTC | TM_SCALE_GPS | TM_SCALE_TAI )
+
/**
* @brief A structure used to transmit information on date and time
+ *
+ * This structure can be used to transfer the current time, in which
+ * case the channel field has to be set to -1, or an event capture time
+ * retrieved from the on-board FIFO, in which case the channel field
+ * contains the index of the time capture input, e.g. 0 or 1.
*/
typedef struct
{
- int16_t channel; /**< -1: the current time; 0, 1: capture 0, 1 */
- T_GPS t; /**< time in GPS format */
- TM_GPS tm; /**< that time converted to local time */
+ int16_t channel; ///< -1: the current on-board time; >= 0 the capture channel number
+ T_GPS t; ///< time in GPS scale and format
+ TM_GPS tm; ///< time converted to %UTC and/or local time according to ::TZDL settings
+
} TTM;
#define _mbg_swab_ttm( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->channel ); \
_mbg_swab_t_gps( &(_p)->t ); \
_mbg_swab_tm_gps( &(_p)->tm ); \
-}
-
+} while ( 0 )
-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 ); \
-}
-
-// The macro below checks if a NANO_TIME value is negative.
-#define _nano_time_negative( _nt ) \
- ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) )
-
-
-
-/* Two types of variables used to store a position. Type XYZ is */
-/* used with a position in earth centered, earth fixed (ECEF) */
-/* coordinates whereas type LLA holds such a position converted */
-/* to geographic coordinates as defined by WGS84 (World Geodetic */
-/* System from 1984). */
#ifndef _XYZ_DEFINED
- /* sequence and number of components of a cartesian position */
- enum { XP, YP, ZP, N_XYZ };
+ /**
+ * @brief Sequence and number of components of a cartesian position
+ */
+ enum XYZ_FIELDS { XP, YP, ZP, N_XYZ }; // x, y, z
- /** @brief An array holding a cartesian position */
- typedef double XYZ[N_XYZ]; /**< values are in [m] */
+ /**
+ * @brief A position in cartesian coordinates
+ *
+ * Usually earth centered, earth fixed (ECEF) coordinates.
+ */
+ typedef double XYZ[N_XYZ]; ///< values are in [m], see ::XYZ_FIELDS
#define _XYZ_DEFINED
#endif
@@ -1201,11 +2618,20 @@ typedef struct
#ifndef _LLA_DEFINED
- /* sequence and number of components of a geographic position */
- enum { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
-
- /** @brief An array holding a geographic position */
- typedef double LLA[N_LLA]; /**< lon, lat in [rad], alt in [m] */
+ /**
+ * @brief Sequence and number of components of a geographic position
+ */
+ enum LLA_FIELDS { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
+
+ /**
+ * @brief A geographic position based on latitude, longitude, and altitude
+ *
+ * The geographic position associated to specific cartesian coordinates
+ * depends on the characteristics of the ellipsoid used for the computation,
+ * the so-called geographic datum. GPS uses the WGS84 (World Geodetic System
+ * from 1984) ellipsoid by default.
+ */
+ typedef double LLA[N_LLA]; ///< lon, lat in [rad], alt in [m], see ::LLA_FIELDS
#define _LLA_DEFINED
#endif
@@ -1214,65 +2640,74 @@ typedef struct
/**
- @defgroup group_synth Synthesizer parameters
-
- Synthesizer frequency is expressed as a
- four digit decimal number (freq) to be multiplied by 0.1 Hz and an
- base 10 exponent (range). If the effective frequency is less than
- 10 kHz its phase is synchronized corresponding to the variable phase.
- Phase may be in a range from -360 deg to +360 deg with a resolution
- of 0.1 deg, so the resulting numbers to be stored are in a range of
- -3600 to +3600.
-
- Example:<br>
- Assume the value of freq is 2345 (decimal) and the value of phase is 900.
- If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg.
- If range == 1 the synthesizer will generate a 2345 Hz output frequency
- and so on.
-
- Limitations:<br>
- If freq == 0 the synthesizer is disabled. If range == 0 the least
- significant digit of freq is limited to 0, 3, 5 or 6. The resulting
- frequency is shown in the examples below:
- - freq == 1230 --> 123.0 Hz
- - freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz)
- - freq == 1235 --> 123.5 Hz
- - freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz)
-
- If range == MAX_RANGE the value of freq must not exceed 1000, so the
- output frequency is limited to 10 MHz.
- @{
-*/
+ * @defgroup group_synth Synthesizer parameters
+ *
+ * Synthesizer frequency is expressed as a
+ * four digit decimal number (freq) to be multiplied by 0.1 Hz and an
+ * base 10 exponent (range). If the effective frequency is less than
+ * 10 kHz its phase is synchronized corresponding to the variable phase.
+ * Phase may be in a range from -360 deg to +360 deg with a resolution
+ * of 0.1 deg, so the resulting numbers to be stored are in a range of
+ * -3600 to +3600.
+ *
+ * Example:<br>
+ * Assume the value of freq is 2345 (decimal) and the value of phase is 900.
+ * If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg.
+ * If range == 1 the synthesizer will generate a 2345 Hz output frequency
+ * and so on.
+ *
+ * Limitations:<br>
+ * If freq == 0 the synthesizer is disabled. If range == 0 the least
+ * significant digit of freq is limited to 0, 3, 5 or 6. The resulting
+ * frequency is shown in the examples below:
+ * - freq == 1230 --> 123.0 Hz
+ * - freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz)
+ * - freq == 1235 --> 123.5 Hz
+ * - freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz)
+ *
+ * If range == ::MAX_SYNTH_RANGE the value of freq must not exceed 1000, so
+ * the output frequency is limited to 10 MHz (see ::MAX_SYNTH_FREQ_VAL).
+ *
+ * @{ */
-#define N_SYNTH_FREQ_DIGIT 4 /**< number of digits to edit */
-#define MAX_SYNTH_FREQ 1000 /**< if range == MAX_SYNTH_RANGE */
+#define N_SYNTH_FREQ_DIGIT 4 ///< number of digits to edit
+#define MAX_SYNTH_FREQ 1000 ///< if range == ::MAX_SYNTH_RANGE
#define MIN_SYNTH_RANGE 0
#define MAX_SYNTH_RANGE 5
#define N_SYNTH_RANGE ( MAX_SYNTH_RANGE - MIN_SYNTH_RANGE + 1 )
-#define N_SYNTH_PHASE_DIGIT 4
-#define MAX_SYNTH_PHASE 3600
+#define N_SYNTH_PHASE_DIGIT 4
+#define MAX_SYNTH_PHASE 3600
+
+#define MAX_SYNTH_FREQ_EDIT 9999 ///< max sequence of digits when editing
-#define MAX_SYNTH_FREQ_EDIT 9999 /**< max sequence of digits when editing */
-/** @brief The maximum frequency that can be configured for the synthesizer */
-#define MAX_SYNTH_FREQ_VAL 10000000UL /**< 10 MHz */
+/**
+ * @brief The maximum frequency that can be configured for the synthesizer
+ */
+#define MAX_SYNTH_FREQ_VAL 10000000UL ///< 10 MHz
/* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */
-/** @brief The synthesizer's phase is only be synchronized if the frequency is below this limit */
-#define SYNTH_PHASE_SYNC_LIMIT 10000UL /**< 10 kHz */
+/**
+ * @brief The synthesizer's phase is only be synchronized if the frequency is below this limit
+ */
+#define SYNTH_PHASE_SYNC_LIMIT 10000UL ///< 10 kHz
/**
- the position of the decimal point if the frequency is
- printed as 4 digit value */
+ * A Macro used to determine the position of the decimal point
+ * when printing the synthesizer frequency as 4 digit value
+ */
#define _synth_dp_pos_from_range( _r ) \
( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 )
/**
- An initializer for commonly displayed synthesizer frequency units
- (N_SYNTH_RANGE strings) */
+ * @brief Synthesizer frequency units
+ *
+ * An initializer for commonly displayed synthesizer frequency units
+ * (::N_SYNTH_RANGE strings)
+ */
#define DEFAULT_FREQ_RANGES \
{ \
"Hz", \
@@ -1285,86 +2720,118 @@ typedef struct
+/**
+ * @brief Synthesizer configuration parameters
+ */
typedef struct
{
- int16_t freq; /**< four digits used; scale: 0.1; e.g. 1234 -> 123.4 Hz */
- int16_t range; /**< scale factor for freq; 0..MAX_SYNTH_RANGE */
- int16_t phase; /**< -MAX_SYNTH_PHASE..+MAX_SYNTH_PHASE; >0 -> pulses later */
+ int16_t freq; ///< four digits used; scale: 0.1 Hz; e.g. 1234 -> 123.4 Hz
+ int16_t range; ///< scale factor for freq; 0..::MAX_SYNTH_RANGE
+ int16_t phase; ///< -::MAX_SYNTH_PHASE..+::MAX_SYNTH_PHASE; >0 -> pulses later
+
} SYNTH;
#define _mbg_swab_synth( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->freq ); \
_mbg_swab16( &(_p)->range ); \
_mbg_swab16( &(_p)->phase ); \
-}
+} while ( 0 )
/**
- The definitions below can be used to query the
- current synthesizer state.
+ * @brief Enumeration of synthesizer states
*/
-enum
+enum SYNTH_STATES
{
- SYNTH_DISABLED, /**< disbled by cfg, i.e. freq == 0.0 */
- SYNTH_OFF, /**< not enabled after power-up */
- SYNTH_FREE, /**< enabled, but not synchronized */
- SYNTH_DRIFTING, /**< has initially been sync'd, but now running free */
- SYNTH_SYNC, /**< fully synchronized */
- N_SYNTH_STATE /**< the number of known states */
+ SYNTH_DISABLED, ///< disbled by cfg, i.e. freq == 0.0
+ SYNTH_OFF, ///< not enabled after power-up
+ SYNTH_FREE, ///< enabled, but not synchronized
+ SYNTH_DRIFTING, ///< has initially been sync'd, but now running free
+ SYNTH_SYNC, ///< fully synchronized
+ N_SYNTH_STATE ///< the number of known states
};
+
+/**
+ * @brief A structure used to report the synthesizer state
+ */
typedef struct
{
- uint8_t state; /**< state code as enumerated above */
- uint8_t flags; /**< reserved, currently always 0 */
+ uint8_t state; ///< state code as enumerated in ::SYNTH_STATES
+ uint8_t flags; ///< reserved, currently always 0
+
} SYNTH_STATE;
#define _mbg_swab_synth_state( _p ) _nop_macro_fnc()
#define SYNTH_FLAG_PHASE_IGNORED 0x01
-/** @} group_synth */
+/** @} defgroup group_synth */
-/**
- @defgroup group_tzdl Time zone/daylight saving parameters
- Example: <br>
- For automatic daylight saving enable/disable in Central Europe,
- the variables are to be set as shown below: <br>
- - offs = 3600L one hour from UTC
- - offs_dl = 3600L one additional hour if daylight saving enabled
- - tm_on = first Sunday from March 25, 02:00:00h ( year |= DL_AUTO_FLAG )
- - tm_off = first Sunday from October 25, 03:00:00h ( year |= DL_AUTO_FLAG )
- - name[0] == "CET " name if daylight saving not enabled
- - name[1] == "CEST " name if daylight saving is enabled
- @{
-*/
-/** the name of a time zone, 5 characters plus trailing zero */
+/**
+ * @defgroup group_tzdl Time zone / daylight saving parameters
+ *
+ * Example: <br>
+ * For automatic daylight saving enable/disable in Central Europe,
+ * the variables are to be set as shown below: <br>
+ * - offs = 3600L one hour from %UTC
+ * - offs_dl = 3600L one additional hour if daylight saving enabled
+ * - tm_on = first Sunday from March 25, 02:00:00h ( year |= ::DL_AUTO_FLAG )
+ * - tm_off = first Sunday from October 25, 03:00:00h ( year |= ::DL_AUTO_FLAG )
+ * - name[0] == "CET " name if daylight saving not enabled
+ * - name[1] == "CEST " name if daylight saving is enabled
+ *
+ * @{ */
+
+/**
+ * @brief The name of a time zone
+ *
+ * @note Up to 5 printable characters, plus trailing zero
+ */
typedef char TZ_NAME[6];
+/**
+ * @brief Time zone / daylight saving parameters
+ *
+ * This structure is used to specify how a device converts on-board %UTC
+ * to local time, including computation of beginning and end of daylight
+ * saving time (DST), if required.
+ *
+ * @note The ::TZDL structure contains members of type ::TM_GPS to specify
+ * the times for beginning and end of DST. However, the ::TM_GPS::frac,
+ * ::TM_GPS::offs_from_utc, and ::TM_GPS::status fields of these ::TZDL::tm_on
+ * and ::TZDL::tm_off members are ignored for the conversion to local time,
+ * and thus should be 0.
+ */
typedef struct
{
- int32_t offs; /**< offset from UTC to local time [sec] */
- int32_t offs_dl; /**< additional offset if daylight saving enabled [sec] */
- TM_GPS tm_on; /**< date/time when daylight saving starts */
- TM_GPS tm_off; /**< date/time when daylight saving ends */
- TZ_NAME name[2]; /**< names without and with daylight saving enabled */
+ int32_t offs; ///< standard offset from %UTC to local time [sec]
+ int32_t offs_dl; ///< additional offset if daylight saving enabled [sec]
+ TM_GPS tm_on; ///< date/time when daylight saving starts
+ TM_GPS tm_off; ///< date/time when daylight saving ends
+ TZ_NAME name[2]; ///< names without and with daylight saving enabled
+
} TZDL;
#define _mbg_swab_tzdl( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->offs ); \
_mbg_swab32( &(_p)->offs_dl ); \
_mbg_swab_tm_gps( &(_p)->tm_on ); \
_mbg_swab_tm_gps( &(_p)->tm_off ); \
-}
+} while ( 0 )
/**
- If the year in tzdl.tm_on and tzdl.tm_off is or'ed with that constant,
- the receiver automatically generates daylight saving year by year.
+ * @brief A flag indicating automatic computation of DST
+ *
+ * If this flag is or'ed to the year numbers in ::TZDL::tm_on and ::TZDL::tm_off
+ * then daylight saving is computed automatically year by year.
*/
#define DL_AUTO_FLAG 0x8000
@@ -1372,20 +2839,20 @@ typedef struct
// Below there are some initializers for commonly used TZDL configurations:
-#define DEFAULT_TZDL_AUTO_YEAR ( 2007 | DL_AUTO_FLAG )
+#define DEFAULT_TZDL_AUTO_YEAR ( (int16_t) ( 2007L | DL_AUTO_FLAG ) )
-#define DEFAULt_TZDL_OFFS_DL 3600L /**< usually DST is +1 hour */
+#define DEFAULt_TZDL_OFFS_DL 3600L ///< usually DST is +1 hour
/**
- The symbol below can be used to initialize both the tm_on
- and tm_off fields for time zones which do not switch to DST:
+ * An initializer for ::TZDL::tm_on and ::TZDL::tm_off for time zones
+ * which do not observe DST.
*/
#define DEFAULT_TZDL_TM_ON_OFF_NO_DST \
{ DEFAULT_TZDL_AUTO_YEAR, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }
-// Settings used with UTC:
+// Settings used with %UTC:
#define TZ_INFO_UTC "UTC (Universal Time, Coordinated)"
@@ -1393,22 +2860,23 @@ typedef struct
#define DEFAULT_TZDL_UTC \
{ \
- 0L, /**< offs */ \
- 0L, /**< offs_dl */ \
- DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_on */ \
- DEFAULT_TZDL_TM_ON_OFF_NO_DST, /**< tm_off */ \
- DEFAULT_TZDL_NAMES_UTC /**< name[] */ \
+ 0L, /* offs */ \
+ 0L, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /* tm_on */ \
+ DEFAULT_TZDL_TM_ON_OFF_NO_DST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_UTC /* name */ \
}
/**
- The symbols below specify beginning and end of DST for
- Central Europe, as constituted by the European Parliament:
- */
-
+ * @brief An initializer for ::TZDL::tm_on according to the rules for Central Europe
+ */
#define DEFAULT_TZDL_TM_ON_CET_CEST \
{ DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 }
+/**
+ * @brief An initializer for ::TZDL::tm_off according to the rules for Central Europe
+ */
#define DEFAULT_TZDL_TM_OFF_CET_CEST \
{ DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 }
@@ -1425,20 +2893,20 @@ typedef struct
#define DEFAULT_TZDL_CET_CEST_EN \
{ \
- DEFAULT_TZDL_OFFS_CET, /**< offs */ \
- DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
- DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
- DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
- DEFAULT_TZDL_NAMES_CET_CEST_EN /**< name[] */ \
+ DEFAULT_TZDL_OFFS_CET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_EN /* name */ \
}
#define DEFAULT_TZDL_CET_CEST_DE \
{ \
- DEFAULT_TZDL_OFFS_CET, /**< offs */ \
- DEFAULt_TZDL_OFFS_DL, /**< offs_dl */ \
- DEFAULT_TZDL_TM_ON_CET_CEST, /**< tm_on */ \
- DEFAULT_TZDL_TM_OFF_CET_CEST, /**< tm_off */ \
- DEFAULT_TZDL_NAMES_CET_CEST_DE /**< name[] */ \
+ DEFAULT_TZDL_OFFS_CET, /* offs */ \
+ DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
+ DEFAULT_TZDL_TM_ON_CET_CEST, /* tm_on */ \
+ DEFAULT_TZDL_TM_OFF_CET_CEST, /* tm_off */ \
+ DEFAULT_TZDL_NAMES_CET_CEST_DE /* name */ \
}
@@ -1468,7 +2936,7 @@ typedef struct
DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
- DEFAULT_TZDL_NAMES_EET_EEST_EN /* name[] */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_EN /* name */ \
}
#define DEFAULT_TZDL_EET_EEST_DE \
@@ -1477,96 +2945,136 @@ typedef struct
DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \
DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \
DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \
- DEFAULT_TZDL_NAMES_EET_EEST_DE /* name[] */ \
+ DEFAULT_TZDL_NAMES_EET_EEST_DE /* name */ \
}
-/** @} group_tzdl */
+/** @} defgroup group_tzdl */
+
+
/**
+ * @brief Antenna status and error at reconnect information
+ *
* The structure below reflects the status of the antenna,
* the times of last disconnect/reconnect, and the board's
- * clock offset after the disconnection interval.
+ * clock offset when it has synchronized again after the
+ * disconnection interval.
+ *
+ * @note ::ANT_INFO::status changes back to ::ANT_RECONN only
+ * after the antenna has been reconnected <b>and</b> the
+ * receiver has re-synchronized to the satellite signal.
+ * In this case ::ANT_INFO::delta_t reports the time offset
+ * before resynchronization, i.e. how much the internal
+ * time has drifted while the antenna was disconnected.
*/
typedef struct
{
- int16_t status; /**< current status of antenna */
- TM_GPS tm_disconn; /**< time of antenna disconnect */
- TM_GPS tm_reconn; /**< time of antenna reconnect */
- int32_t delta_t; /**< clock offs. at reconn. time in #GPS_TICKS_PER_SEC */
+ int16_t status; ///< current status of antenna, see ::ANT_STATUS_CODES
+ TM_GPS tm_disconn; ///< time of antenna disconnect
+ TM_GPS tm_reconn; ///< time of antenna reconnect
+ int32_t delta_t; ///< clock offs at reconn. time in 1/::RECEIVER_INFO::ticks_per_sec units
+
} ANT_INFO;
#define _mbg_swab_ant_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->status ); \
_mbg_swab_tm_gps( &(_p)->tm_disconn ); \
_mbg_swab_tm_gps( &(_p)->tm_reconn ); \
_mbg_swab32( &(_p)->delta_t ); \
-}
+} while ( 0 )
/**
- The status field may be set to one of the values below:
-*/
-enum
+ * @brief Status code used with ::ANT_INFO::status
+ */
+enum ANT_STATUS_CODES
{
- ANT_INVALID, /**< struct not set yet because ant. has not been disconn. */
- ANT_DISCONN, /**< ant. now disconn., tm_reconn and delta_t not set */
- ANT_RECONN /**< ant. has been disconn. and reconn., all fields valid */
+ ANT_INVALID, ///< No other fields valid since antenna has not yet been disconnected
+ ANT_DISCONN, ///< Antenna is disconnected, tm_reconn and delta_t not yet set
+ ANT_RECONN, ///< Antenna has been disconnect, and receiver sync. after reconnect, so all fields valid
+ N_ANT_STATUS_CODES ///< the number of known status codes
};
-/* Defines used with ENABLE_FLAGS */
-
-#define EF_OFF 0x00 /**< outputs off until sync'd */
-#define EF_SERIAL_BOTH 0x03 /**< both serial ports on */
-#define EF_PULSES_BOTH 0x03 /**< both pulses P_SEC and P_MIN on */
-#define EF_FREQ_ALL 0x07 /**< all fixed freq. outputs on */
-#define EF_SYNTH 0x01 /**< synth. on */
/**
- The structure holds some flags which let
- the corresponding outputs be disabled after power-up until
- the receiver has synchronized (flag == 0x00, the default) or force
- the outputs to be enabled immediately after power-up. The fixed
- frequency output is hard-wired to be enabled immediately after
- power-up, so the code for freq must always be 0x03.
-*/
+ * @brief A structure controlling when output signals are enabled
+ *
+ * The structure holds some flags which let the corresponding outputs
+ * be disabled after power-up until the receiver has synchronized
+ * (flags == ::EF_OFF, the default) or force the outputs to be enabled
+ * immediately after power-up. The fixed frequency output is hard-wired
+ * to be enabled immediately after power-up, so ::ENABLE_FLAGS::freq must
+ * always be set to ::EF_FREQ_ALL.
+ */
typedef struct
{
- uint16_t serial; /**< #EF_OFF or #EF_SERIAL_BOTH */
- uint16_t pulses; /**< #EF_OFF or #EF_PULSES_BOTH */
- uint16_t freq; /**< always #EF_FREQ_ALL */
- uint16_t synth; /**< #EF_OFF or #EF_SYNTH */
+ uint16_t serial; ///< ::EF_OFF or ::EF_SERIAL_BOTH
+ uint16_t pulses; ///< ::EF_OFF or ::EF_PULSES_BOTH
+ uint16_t freq; ///< always ::EF_FREQ_ALL
+ uint16_t synth; ///< ::EF_OFF or ::EF_SYNTH
+
} ENABLE_FLAGS;
#define _mbg_swab_enable_flags( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->serial ); \
_mbg_swab16( &(_p)->pulses ); \
_mbg_swab16( &(_p)->freq ); \
_mbg_swab16( &(_p)->synth ); \
-}
+} while ( 0 )
+
+
+/**
+ * @brief Codes used with ::ENABLE_FLAGS
+ **/
+enum ENABLE_FLAGS_CODES
+{
+ EF_OFF = 0x00, ///< associated outputs off until synchronized
+
+ EF_SERIAL_BOTH = 0x03, ///< both serial ports on, use with ::ENABLE_FLAGS::serial
+ EF_PULSES_BOTH = 0x03, ///< both pulses P_SEC and P_MIN on, use with ::ENABLE_FLAGS::pulses
+ EF_FREQ_ALL = 0x07, ///< all fixed freq. outputs on, use with ::ENABLE_FLAGS::freq
+ EF_SYNTH = 0x01 ///< synthesizer on, use with ::ENABLE_FLAGS::synth
+};
-/* 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 };
+ /**
+ * @brief Enumeration of handshake modes
+ */
+ enum COM_HANSHAKE_MODES { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
#define _COM_HS_DEFINED
#endif
#ifndef _COM_PARM_DEFINED
+ /**
+ * @brief A data type to configure a serial port's baud rate
+ *
+ * @see ::MBG_BAUD_RATES
+ */
typedef int32_t BAUD_RATE;
- /* indices used to identify a parameter in the framing string */
- enum { F_DBITS, F_PRTY, F_STBITS };
+ /**
+ * @brief Indices used to identify a parameter in the framing string
+ *
+ * @see ::MBG_FRAMING_STRS
+ */
+ enum MBG_FRAMING_STR_IDXS { F_DBITS, F_PRTY, F_STBITS };
+ /**
+ * @brief A structure to store the configuration of a serial port
+ */
typedef struct
{
- BAUD_RATE baud_rate; /* e.g. 19200L */
- char framing[4]; /* e.g. "8N1" */
- int16_t handshake; /* a numeric value, only HS_NONE supported yet */
+ BAUD_RATE baud_rate; ///< transmission speed, e.g. 19200L, see ::MBG_BAUD_RATES
+ char framing[4]; ///< ASCIIZ framing string, e.g. "8N1" or "7E2", see ::MBG_FRAMING_STRS
+ int16_t handshake; ///< handshake mode, yet only ::HS_NONE supported
+
} COM_PARM;
#define _COM_PARM_DEFINED
@@ -1575,18 +3083,22 @@ typedef struct
#define _mbg_swab_baud_rate( _p ) _mbg_swab32( _p )
#define _mbg_swab_com_parm( _p ) \
+do \
{ \
_mbg_swab_baud_rate( &(_p)->baud_rate ); \
_mbg_swab16( &(_p)->handshake ); \
-}
+} while ( 0 )
-/*
- * Indices of any supported baud rates.
- * Note that not each baud rate must be supported by
- * any clock model and/or port:
+/**
+ * @brief Enumeration of serial port baud rates
+ *
+ * @note Most clock models and/or serial ports don't support all defined baud rates.
+ *
+ * @see ::MBG_BAUD_RATES
+ * @see ::MBG_BAUD_RATE_MASKS
*/
-enum
+enum MBG_BAUD_RATE_CODES
{
MBG_BAUD_RATE_300,
MBG_BAUD_RATE_600,
@@ -1596,12 +3108,23 @@ enum
MBG_BAUD_RATE_9600,
MBG_BAUD_RATE_19200,
MBG_BAUD_RATE_38400,
- N_MBG_BAUD_RATES /* the number of supported baud rates */
+ MBG_BAUD_RATE_57600,
+ MBG_BAUD_RATE_115200,
+ MBG_BAUD_RATE_230400,
+ MBG_BAUD_RATE_460800,
+ MBG_BAUD_RATE_921600,
+ N_MBG_BAUD_RATES ///< the number of known baud rates
};
-/*
- * An initializer for a table of baud rate values.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of baud rate values
+ *
+ * These values can be used with ::COM_PARM::baud_rate, if the device
+ * supports the particular baud rate.
+ *
+ * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES
+ *
+ * @see ::MBG_BAUD_RATE_CODES
*/
#define MBG_BAUD_RATES \
{ \
@@ -1612,12 +3135,20 @@ enum
4800L, \
9600L, \
19200L, \
- 38400L \
+ 38400L, \
+ 57600L, \
+ 115200L, \
+ 230400L, \
+ 460800L, \
+ 921600L \
}
-/*
- * An initializer for a table of baud rate strings.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of baud rate strings
+ *
+ * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES
+ *
+ * @see ::MBG_BAUD_RATE_CODES
*/
#define MBG_BAUD_STRS \
{ \
@@ -1628,32 +3159,49 @@ enum
"4800", \
"9600", \
"19200", \
- "38400" \
+ "38400", \
+ "57600", \
+ "115200", \
+ "230400", \
+ "460800", \
+ "921600" \
}
-/*
- * The bit masks below can be used to determine which baud rates
- * are supported by a serial port. This may vary between
- * different ports of the same device since different
- * types of UART are used which must not necessarily support
- * each baud rate:
- */
-#define MBG_PORT_HAS_300 ( 1UL << MBG_BAUD_RATE_300 )
-#define MBG_PORT_HAS_600 ( 1UL << MBG_BAUD_RATE_600 )
-#define MBG_PORT_HAS_1200 ( 1UL << MBG_BAUD_RATE_1200 )
-#define MBG_PORT_HAS_2400 ( 1UL << MBG_BAUD_RATE_2400 )
-#define MBG_PORT_HAS_4800 ( 1UL << MBG_BAUD_RATE_4800 )
-#define MBG_PORT_HAS_9600 ( 1UL << MBG_BAUD_RATE_9600 )
-#define MBG_PORT_HAS_19200 ( 1UL << MBG_BAUD_RATE_19200 )
-#define MBG_PORT_HAS_38400 ( 1UL << MBG_BAUD_RATE_38400 )
+/**
+ * @brief Bit masks associated with baud rates enumerated in ::MBG_BAUD_RATE_CODES
+ *
+ * These bit masks are used e.g. with ::PORT_INFO::supp_baud_rates to
+ * determine which baud rates are supported by a particular serial port.
+ *
+ * @see ::MBG_BAUD_RATE_CODES
+ * @see ::MBG_FRAMING_MASKS
+ */
+enum MBG_BAUD_RATE_MASKS
+{
+ MBG_PORT_HAS_300 = ( 1UL << MBG_BAUD_RATE_300 ), ///< see ::MBG_BAUD_RATE_300
+ MBG_PORT_HAS_600 = ( 1UL << MBG_BAUD_RATE_600 ), ///< see ::MBG_BAUD_RATE_600
+ MBG_PORT_HAS_1200 = ( 1UL << MBG_BAUD_RATE_1200 ), ///< see ::MBG_BAUD_RATE_1200
+ MBG_PORT_HAS_2400 = ( 1UL << MBG_BAUD_RATE_2400 ), ///< see ::MBG_BAUD_RATE_2400
+ MBG_PORT_HAS_4800 = ( 1UL << MBG_BAUD_RATE_4800 ), ///< see ::MBG_BAUD_RATE_4800
+ MBG_PORT_HAS_9600 = ( 1UL << MBG_BAUD_RATE_9600 ), ///< see ::MBG_BAUD_RATE_9600
+ MBG_PORT_HAS_19200 = ( 1UL << MBG_BAUD_RATE_19200 ), ///< see ::MBG_BAUD_RATE_19200
+ MBG_PORT_HAS_38400 = ( 1UL << MBG_BAUD_RATE_38400 ), ///< see ::MBG_BAUD_RATE_38400
+ MBG_PORT_HAS_57600 = ( 1UL << MBG_BAUD_RATE_57600 ), ///< see ::MBG_BAUD_RATE_57600
+ MBG_PORT_HAS_115200 = ( 1UL << MBG_BAUD_RATE_115200 ), ///< see ::MBG_BAUD_RATE_115200
+ MBG_PORT_HAS_230400 = ( 1UL << MBG_BAUD_RATE_230400 ), ///< see ::MBG_BAUD_RATE_230400
+ MBG_PORT_HAS_460800 = ( 1UL << MBG_BAUD_RATE_460800 ), ///< see ::MBG_BAUD_RATE_460800
+ MBG_PORT_HAS_921600 = ( 1UL << MBG_BAUD_RATE_921600 ) ///< see ::MBG_BAUD_RATE_921600
+};
-/*
- * Indices of any supported framings.
- * Note that not each framing must be supported by
- * any clock model and/or port:
+/**
+ * @brief Enumeration of all known serial port framings
+ *
+ * @note Most clock models and/or serial ports don't support all defined framing types.
+ *
+ * @see ::MBG_FRAMING_STRS
*/
-enum
+enum MBG_FRAMING_CODES
{
MBG_FRAMING_7N2,
MBG_FRAMING_7E1,
@@ -1664,12 +3212,21 @@ enum
MBG_FRAMING_7O1,
MBG_FRAMING_7O2,
MBG_FRAMING_8O1,
- N_MBG_FRAMINGS /* the number of supported framings */
+ MBG_FRAMING_8E2, ///< Note: most serial ports don't support this!
+ N_MBG_FRAMINGS ///< the number of known framings
};
-/*
- * An initializer for a table of framing strings.
- * The values must correspond to the enumeration above.
+/**
+ * @brief An initializer for a table of known framing strings
+ *
+ * These values can be used with ::COM_PARM::framing, if the device
+ * supports the particular framing.
+ *
+ * The values must correspond to the enumeration ::MBG_FRAMING_CODES
+ *
+ * @see ::MBG_FRAMING_CODES
+ * @see ::MBG_FRAMING_MASKS
+ * @see ::MBG_FRAMING_STR_IDXS
*/
#define MBG_FRAMING_STRS \
{ \
@@ -1681,25 +3238,80 @@ enum
"8E1", \
"7O1", \
"7O2", \
- "8O1" \
+ "8O1", \
+ "8E2" \
}
-/*
- * The bit masks below can be used to determine which framings
- * are supported by a serial port. This may vary between
- * different ports of the same device since different
- * types of UART are used which must not necessarily support
- * each framing type:
+/**
+ * @brief Bit masks associated with framings enumerated in ::MBG_FRAMING_CODES
+ *
+ * These bit masks are used e.g. with ::PORT_INFO::supp_framings to
+ * determine which framings are supported by a particular serial port.
+ *
+ * @see ::MBG_FRAMING_CODES
+ * @see ::MBG_FRAMING_STRS
+ */
+enum MBG_FRAMING_MASKS
+{
+ MBG_PORT_HAS_7N2 = ( 1UL << MBG_FRAMING_7N2 ), ///< see ::MBG_FRAMING_7N2
+ MBG_PORT_HAS_7E1 = ( 1UL << MBG_FRAMING_7E1 ), ///< see ::MBG_FRAMING_7E1
+ MBG_PORT_HAS_7E2 = ( 1UL << MBG_FRAMING_7E2 ), ///< see ::MBG_FRAMING_7E2
+ MBG_PORT_HAS_8N1 = ( 1UL << MBG_FRAMING_8N1 ), ///< see ::MBG_FRAMING_8N1
+ MBG_PORT_HAS_8N2 = ( 1UL << MBG_FRAMING_8N2 ), ///< see ::MBG_FRAMING_8N2
+ MBG_PORT_HAS_8E1 = ( 1UL << MBG_FRAMING_8E1 ), ///< see ::MBG_FRAMING_8E1
+ MBG_PORT_HAS_7O1 = ( 1UL << MBG_FRAMING_7O1 ), ///< see ::MBG_FRAMING_7O1
+ MBG_PORT_HAS_7O2 = ( 1UL << MBG_FRAMING_7O2 ), ///< see ::MBG_FRAMING_7O2
+ MBG_PORT_HAS_8O1 = ( 1UL << MBG_FRAMING_8O1 ), ///< see ::MBG_FRAMING_8O1
+ MBG_PORT_HAS_8E2 = ( 1UL << MBG_FRAMING_8E2 ) ///< see ::MBG_FRAMING_8E2
+};
+
+
+
+/**
+ * @brief Definitions used with the Meinberg binary protocol
+ *
+ * @anchor GPS_BIN_PROT_DEFS @{ */
+
+/**
+ * @brief Framing used with the binary protocol
+ *
+ * Different data length, or parity settings would corrupt
+ * the binary data.
+ */
+#define MBG_DEFAULT_FRAMING "8N1"
+
+/**
+ * @brief The standard baud rate used for the binary protocol
+ *
+ * This is supported by most devices. Some new devices may also
+ * support ::MBG_DEFAULT_BAUDRATE_HS
+ */
+#define MBG_DEFAULT_BAUDRATE 19200L
+
+/**
+ * @brief The high speed baud rate used for the binary protocol
+ *
+ * This is not supported by older devices which work
+ * with ::MBG_DEFAULT_BAUDRATE only.
*/
-#define MBG_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 )
+#define MBG_DEFAULT_BAUDRATE_HS 115200L
+
+
+/**
+ * @brief Strings used to force connection settings for the binary protocol
+ *
+ * If a device supports this and receives one of these ASCII strings
+ * then it temporarily switches the serial port to some well-known
+ * baud rate and framing appropriate for the binary protocol.
+ *
+ * @anchor GPS_BIN_PROT_CMD_STRS @{ */
+
+#define MBG_FORCE_CONN_CMD_STR "\nDFC\n" ///< switch to ::MBG_DEFAULT_BAUDRATE
+#define MBG_FORCE_CONN_HS_CMD_STR "\nDFCHS\n" ///< switch to ::MBG_DEFAULT_BAUDRATE_HS
+
+/** @} anchor GPS_BIN_PROT_CMD_STRS */
+
+/** @} anchor GPS_BIN_PROT_DEFS */
@@ -1756,106 +3368,136 @@ enum
)
-/*
- * The structure below is more flexible if different receiver
- * models have different numbers of serial ports, so the old
- * structure PORT_PARM will become obsolete.
+/**
+ * @brief Configuration settings of a serial port
+ *
+ * @note This should be used preferably instead of
+ * ::PORT_PARM, which is deprecated.
*/
typedef struct
{
- COM_PARM parm; /* speed, framing, etc. */
- uint8_t mode; /* per second, per minute, etc. */
- uint8_t str_type; /* type of the output string */
- uint32_t flags; /* reserved for future use, currently 0 */
+ COM_PARM parm; ///< transmission speed, framing, etc.
+ uint8_t mode; ///< string mode, see ::STR_MODES
+ uint8_t str_type; ///< index of the supported time string formats, see ::STR_TYPE_INFO_IDX
+ uint32_t flags; ///< reserved, don't use, currently 0
+
} PORT_SETTINGS;
#define _mbg_swab_port_settings( _p ) \
+do \
{ \
_mbg_swab_com_parm( &(_p)->parm ); \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
-/*
- * The definitions below can be used to mark specific fields of a
- * PORT_SETTINGS structure, e.g. when editing build a mask indicating
- * which of the fields have changed or which are not valid.
+/**
+ * @brief Flag bits used to mark individual ::PORT_SETTINGS fields
+ *
+ * These definitions can be used to mark specific fields of a
+ * ::PORT_SETTINGS structure, e.g. which fields have changed when
+ * editing, or which fields have settings which are not valid.
*/
-enum
+enum MBG_COM_CFG_STATUS_BITS
{
- MBG_PS_BIT_BAUD_RATE_OVR_SW, /* Baud rate index exceeds num supp by driver SW */
- MBG_PS_BIT_BAUD_RATE_OVR_DEV, /* Baud rate index exceeds num supp by device */
- MBG_PS_BIT_BAUD_RATE, /* Baud rate not supp by given port */
- MBG_PS_BIT_FRAMING_OVR_SW, /* Framing index exceeds num supp by driver SW */
- MBG_PS_BIT_FRAMING_OVR_DEV, /* Framing index exceeds num supp by device */
- MBG_PS_BIT_FRAMING, /* Framing not supp by given port */
- MBG_PS_BIT_HS_OVR_SW, /* Handshake index exceeds num supp by driver SW */
- MBG_PS_BIT_HS, /* Handshake mode not supp by given port */
- MBG_PS_BIT_STR_TYPE_OVR_SW, /* String type index exceeds num supp by driver SW */
- MBG_PS_BIT_STR_TYPE_OVR_DEV, /* String type index exceeds num supp by device */
- MBG_PS_BIT_STR_TYPE, /* String type not supp by given port */
- MBG_PS_BIT_STR_MODE_OVR_SW, /* String mode index exceeds num supp by driver SW */
- MBG_PS_BIT_STR_MODE_OVR_DEV, /* String mode index exceeds num supp by device */
- MBG_PS_BIT_STR_MODE, /* String mode not supp by given port and string type */
- MBG_PS_BIT_FLAGS_OVR_SW, /* Flags not supp by driver SW */
- MBG_PS_BIT_FLAGS, /* Flags not supp by device */
+ MBG_PS_BIT_BAUD_RATE_OVR_SW, ///< Baud rate index exceeds num supp by driver SW
+ MBG_PS_BIT_BAUD_RATE_OVR_DEV, ///< Baud rate index exceeds num supp by device
+ MBG_PS_BIT_BAUD_RATE, ///< Baud rate not supp by given port
+ MBG_PS_BIT_FRAMING_OVR_SW, ///< Framing index exceeds num supp by driver SW
+ MBG_PS_BIT_FRAMING_OVR_DEV, ///< Framing index exceeds num supp by device
+ MBG_PS_BIT_FRAMING, ///< Framing not supp by given port
+ MBG_PS_BIT_HS_OVR_SW, ///< Handshake index exceeds num supp by driver SW
+ MBG_PS_BIT_HS, ///< Handshake mode not supp by given port
+ MBG_PS_BIT_STR_TYPE_OVR_SW, ///< String type index exceeds num supp by driver SW
+ MBG_PS_BIT_STR_TYPE_OVR_DEV, ///< String type index exceeds num supp by device
+ MBG_PS_BIT_STR_TYPE, ///< String type not supp by given port
+ MBG_PS_BIT_STR_MODE_OVR_SW, ///< String mode index exceeds num supp by driver SW
+ MBG_PS_BIT_STR_MODE_OVR_DEV, ///< String mode index exceeds num supp by device
+ MBG_PS_BIT_STR_MODE, ///< String mode not supp by given port and string type
+ MBG_PS_BIT_FLAGS_OVR_SW, ///< Flags not supp by driver SW
+ MBG_PS_BIT_FLAGS, ///< Flags not supp by device
N_MBG_PS_BIT
};
-#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW )
-#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV )
-#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE )
-#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW )
-#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV )
-#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING )
-#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW )
-#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS )
-#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW )
-#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV )
-#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE )
-#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW )
-#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV )
-#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE )
-#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW )
-#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS )
+/**
+ * @brief Flag bit masks associated with ::MBG_COM_CFG_STATUS_BITS
+ *
+ * These definitions can be used to mark specific fields of a
+ * ::PORT_SETTINGS structure, e.g. which fields have changed when
+ * editing, or which fields have settings which are not valid.
+ *
+ * @anchor MBG_COM_CFG_STATUS_MASKS @{ */
+#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW ) ///< see ::MBG_PS_BIT_BAUD_RATE_OVR_SW
+#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV ) ///< see ::MBG_PS_BIT_BAUD_RATE_OVR_DEV
+#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE ) ///< see ::MBG_PS_BIT_BAUD_RATE
+#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW ) ///< see ::MBG_PS_BIT_FRAMING_OVR_SW
+#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV ) ///< see ::MBG_PS_BIT_FRAMING_OVR_DEV
+#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING ) ///< see ::MBG_PS_BIT_FRAMING
+#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW ) ///< see ::MBG_PS_BIT_HS_OVR_SW
+#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS ) ///< see ::MBG_PS_BIT_HS
+#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW ) ///< see ::MBG_PS_BIT_STR_TYPE_OVR_SW
+#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV ) ///< see ::MBG_PS_BIT_STR_TYPE_OVR_DEV
+#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE ) ///< see ::MBG_PS_BIT_STR_TYPE
+#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW ) ///< see ::MBG_PS_BIT_STR_MODE_OVR_SW
+#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV ) ///< see ::MBG_PS_BIT_STR_MODE_OVR_DEV
+#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE ) ///< see ::MBG_PS_BIT_STR_MODE
+#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW ) ///< see ::MBG_PS_BIT_FLAGS_OVR_SW
+#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS ) ///< see ::MBG_PS_BIT_FLAGS
+/** @} anchor MBG_COM_CFG_STATUS_MASKS */
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+
+
+/**
+ * @brief Configuration settings of a specific serial port
+ *
+ * This structure should be sent to a device to configure
+ * a specific serial port. The number of supported ports
+ * is ::RECEIVER_INFO::n_com_ports.
+ *
+ * @note The ::PORT_INFO_IDX structure should be read from
+ * a device to retrieve the current settings and capabilities.
+ *
+ * @see ::STR_TYPE_INFO
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ uint16_t idx; ///< port index, 0..::RECEIVER_INFO::n_com_ports-1
PORT_SETTINGS port_settings;
+
} PORT_SETTINGS_IDX;
#define _mbg_swab_port_settings_idx( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->idx ); \
_mbg_swab_port_settings( &(_p)->port_settings ); \
-}
+} while ( 0 )
-/*
- * The structure below holds the current settings
- * for a port, plus additional informaton on the
- * port's capabilities. This can be read by setup
- * programs to allow setup of supported features
- * only.
+/**
+ * @brief Current settings and general capabilities of a serial port
+ *
+ * @note This structure should be read from a device to retrieve
+ * the current settings of a serial port plus its capabilities,
+ * e.g. supported baud rates, supported string formats, etc.
+ *
+ * @see ::STR_TYPE_INFO
*/
typedef struct
{
- PORT_SETTINGS port_settings; /* COM port settings as defined above */
- uint32_t supp_baud_rates; /* bit mask of baud rates supp. by this port */
- uint32_t supp_framings; /* bit mask of framings supp. by this port */
- uint32_t supp_str_types; /* bit mask, bit 0 set if str_type[0] supp. */
- uint32_t reserved; /* reserved for future use, currently 0 */
- uint32_t flags; /* reserved for future use, currently 0 */
+ PORT_SETTINGS port_settings; ///< current configuration of the port
+ uint32_t supp_baud_rates; ///< bit mask of baud rates supp. by this port, see ::MBG_BAUD_RATE_MASKS
+ uint32_t supp_framings; ///< bit mask of framings supp. by this port, see ::MBG_FRAMING_MASKS
+ uint32_t supp_str_types; ///< bit mask of string types supp. by this port, i.e. bit 0 set if str_type[0] is supp.
+ uint32_t reserved; ///< reserved for future use, currently always 0
+ uint32_t flags; ///< see ::PORT_INFO_FLAGS
+
} PORT_INFO;
#define _mbg_swab_port_info( _p ) \
+do \
{ \
_mbg_swab_port_settings( &(_p)->port_settings ); \
_mbg_swab32( &(_p)->supp_baud_rates ); \
@@ -1863,80 +3505,159 @@ typedef struct
_mbg_swab32( &(_p)->supp_str_types ); \
_mbg_swab32( &(_p)->reserved ); \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+/**
+ * @brief Flags bits used to define ::PORT_INFO_FLAGS
+ *
+ * @see ::PORT_INFO_FLAGS
+ */
+enum PORT_INFO_FLAG_BITS
+{
+ PORT_INFO_FLAG_BIT_PORT_INVISIBLE, ///< port is used internally and should not be displayed by config apps
+ PORT_INFO_FLAG_BIT_BIN_PROT_HS, ///< port supports binary protocol at high speed, see ::MBG_DEFAULT_BAUDRATE_HS
+ N_PORT_INFO_FLAG_BITS ///< the number of defined bits
+};
+
+
+/**
+ * @brief Bit masks used with ::PORT_INFO::flags
+ *
+ * @see ::PORT_INFO_FLAG_BITS
+ */
+enum PORT_INFO_FLAGS
+{
+ PORT_INFO_FLAG_PORT_INVISIBLE = ( 1UL << PORT_INFO_FLAG_BIT_PORT_INVISIBLE ), ///< see ::PORT_INFO_FLAG_BIT_PORT_INVISIBLE
+ PORT_INFO_FLAG_BIN_PROT_HS = ( 1UL << PORT_INFO_FLAG_BIT_BIN_PROT_HS ) ///< see ::PORT_INFO_FLAG_BIT_BIN_PROT_HS
+};
+
+
+/**
+ * @brief Current settings and general capabilities of a specific serial port
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a specific serial port plus its capabilities,
+ * e.g. supported baud rates, supported string formats, etc.
+ * The number of supported ports is ::RECEIVER_INFO::n_com_ports.
+ *
+ * @note The ::PORT_SETTINGS_IDX structure should be send back to
+ * the device to configure the specified serial port.
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_com_port-1 */
+ uint16_t idx; ///< port index, 0..::RECEIVER_INFO::n_com_ports-1
PORT_INFO port_info;
+
} PORT_INFO_IDX;
#define _mbg_swab_port_info_idx( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->idx ); \
_mbg_swab_port_info( &(_p)->port_info ); \
-}
+} while ( 0 )
-/*
- * The structure below keeps information for a given
- * string type, e.g. which modes can be used with that
- * string type:
+/**
+ * @brief Information on a supported string format
+ *
+ * Information includes the name of the string format, which
+ * transmission modes are supported, etc.
+ *
+ * The number of string types, and which string types are supported
+ * depends on the device type and firmware version.
+ *
+ * @note Multiple structures ::STR_TYPE_INFO_IDX should be read
+ * to retrieve all supported string types.
*/
typedef struct
{
- uint32_t supp_modes; /* bit mask of modes supp. with this string type */
- char long_name[23]; /* long name of the string format */
- char short_name[11]; /* short name of the string format */
- uint16_t flags; /* reserved, currently always 0 */
+ uint32_t supp_modes; ///< bit mask of modes supp. for this string type, see ::STR_MODE_MASKS
+ char long_name[23]; ///< long name of the string format
+ char short_name[11]; ///< short name of the string format
+ uint16_t flags; ///< reserved, currently always 0
+
} STR_TYPE_INFO;
#define _mbg_swab_str_type_info( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->supp_modes ); \
_mbg_swab16( &(_p)->flags ); \
-}
+} while ( 0 )
-/*
- * The structure below adds an index number to the structure
- * above to allow addressing of several instances:
+/**
+ * @brief Information on a specific supported string format
+ *
+ * This structure should be read from a device to retrieve information
+ * on a specific supported time string type from an array of supported
+ * string types. The number of supported string types is returned
+ * in ::RECEIVER_INFO::n_str_type.
+ *
+ * A selected index number can be saved in ::PORT_SETTINGS::str_type to
+ * configure the selected string type for the specific serial port.
*/
typedef struct
{
- uint16_t idx; /* 0..RECEIVER_INFO.n_str_type-1 */
+ uint16_t idx; ///< string type index, 0..::RECEIVER_INFO::n_str_type-1
STR_TYPE_INFO str_type_info;
+
} STR_TYPE_INFO_IDX;
#define _mbg_swab_str_type_info_idx( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->idx ); \
_mbg_swab_str_type_info( &(_p)->str_type_info ); \
-}
+} while ( 0 )
-/*
- * The codes below define valid modes for time strings,
- * i.e. the condition when a string is being sent
- * via the serial port:
+/**
+ * @brief Enumeration of modes supported for time string transmission
+ *
+ * This determines e.g. at which point in time a string starts
+ * to be transmitted via the serial port.
+ * Used with ::PORT_SETTINGS::mode.
+ *
+ * @see ::STR_MODE_MASKS
*/
-enum
+enum STR_MODES
+{
+ STR_ON_REQ, ///< transmission on request by received '?' character only
+ STR_PER_SEC, ///< transmission automatically if second changes
+ STR_PER_MIN, ///< transmission automatically if minute changes
+ STR_AUTO, ///< transmission automatically if required, e.g. on capture event
+ STR_ON_REQ_SEC, ///< transmission if second changes and a request has been received before
+ N_STR_MODE ///< the number of known modes
+};
+
+
+/**
+ * @brief Bit masks associated with ::STR_MODES
+ *
+ * Used with ::STR_TYPE_INFO::supp_modes to indicate which
+ * transmission modes are supported by the particular string type.
+ *
+ * @see ::STR_MODES
+ */
+enum STR_MODE_MASKS
{
- STR_ON_REQ, /* on request only */
- STR_PER_SEC, /* automatically if second changes */
- STR_PER_MIN, /* automatically if minute changes */
- STR_AUTO, /* automatically if required, e.g. on capture event */
- STR_ON_REQ_SEC, /* if second changes and a request has been received */
- N_STR_MODE /* the number of valid modes */
+ MSK_STR_ON_REQ = ( 1UL << STR_ON_REQ ), ///< see ::STR_ON_REQ
+ MSK_STR_PER_SEC = ( 1UL << STR_PER_SEC ), ///< see ::STR_PER_SEC
+ MSK_STR_PER_MIN = ( 1UL << STR_PER_MIN ), ///< see ::STR_PER_MIN
+ MSK_STR_AUTO = ( 1UL << STR_AUTO ), ///< see ::STR_AUTO
+ MSK_STR_ON_REQ_SEC = ( 1UL << STR_ON_REQ_SEC ) ///< see ::STR_ON_REQ_SEC
};
+/**
+ * @brief Initializer for short name strings associated with ::STR_MODES
+ *
+ * @see ::STR_MODES
+ */
#define DEFAULT_SHORT_MODE_NAMES \
{ \
"'?'", \
@@ -1947,9 +3668,12 @@ enum
}
-/*
- * Default initializers for English mode string names. Initializers
- * for multi-language strings can be found in pcpslstr.h.
+/**
+ * @brief Default initializers for English mode name strings
+ *
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::STR_MODES
*/
#define ENG_MODE_NAME_STR_ON_REQ "on request '?' only"
#define ENG_MODE_NAME_STR_PER_SEC "per second"
@@ -1957,6 +3681,14 @@ enum
#define ENG_MODE_NAME_STR_AUTO "automatically"
#define ENG_MODE_NAME_STR_ON_REQ_SEC "sec after request"
+
+/**
+ * @brief Initializer for an English mode name string table
+ *
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::STR_MODES
+ */
#define DEFAULT_ENG_MODE_NAMES \
{ \
ENG_MODE_NAME_STR_ON_REQ, \
@@ -1966,17 +3698,6 @@ enum
ENG_MODE_NAME_STR_ON_REQ_SEC \
}
-/*
- * The definitions below are used to set up bit masks
- * which restrict the modes which can be used with
- * a given string type:
- */
-#define MSK_STR_ON_REQ ( 1UL << STR_ON_REQ )
-#define MSK_STR_PER_SEC ( 1UL << STR_PER_SEC )
-#define MSK_STR_PER_MIN ( 1UL << STR_PER_MIN )
-#define MSK_STR_AUTO ( 1UL << STR_AUTO )
-#define MSK_STR_ON_REQ_SEC ( 1UL << STR_ON_REQ_SEC )
-
/*
* The modes below are supported by most string types:
@@ -2001,8 +3722,56 @@ enum
/**
- * The number of serial ports which were available
- * with all GPS receiver models:
+ * @brief The number of string types supported by legacy DCF77 receivers
+ *
+ * For receivers supporting a ::RECEIVER_INFO this should be determined
+ * from ::RECEIVER_INFO::n_str_type.
+ *
+ * @see ::DEFAULT_SUPP_STR_TYPES_DCF
+ */
+#define DEFAULT_N_STR_TYPE_DCF 1
+
+/**
+ * @brief Bit mask of string types supported by legacy DCF77 receivers
+ *
+ * For receivers supporting a ::RECEIVER_INFO this should be determined
+ * from ::PORT_INFO::supp_str_types.
+ *
+ * @see ::DEFAULT_N_STR_TYPE_DCF
+ */
+#define DEFAULT_SUPP_STR_TYPES_DCF \
+ ( ( 1UL << DEFAULT_N_STR_TYPE_DCF ) - 1 )
+
+
+
+/**
+ * @brief The number of string types supported by legacy GPS receivers
+ *
+ * For receivers supporting a ::RECEIVER_INFO this should be determined
+ * from ::RECEIVER_INFO::n_str_type.
+ *
+ * @see ::DEFAULT_SUPP_STR_TYPES_GPS
+ */
+#define DEFAULT_N_STR_TYPE_GPS 2
+
+/**
+ * @brief Bit mask of string types supported by legacy GPS receivers
+ *
+ * For receivers supporting a ::RECEIVER_INFO this should be determined
+ * from ::PORT_INFO::supp_str_types.
+ *
+ * @see ::DEFAULT_N_STR_TYPE_GPS
+ */
+#define DEFAULT_SUPP_STR_TYPES_GPS \
+ ( ( 1UL << DEFAULT_N_STR_TYPE_GPS ) - 1 )
+
+
+
+/*
+ * The number of serial ports which are at least available
+ * even with very old GPS receiver models. For devices providing
+ * a ::RECEIVER_INFO structure the number of provided COM ports
+ * is available in ::RECEIVER_INFO::n_com_ports.
*/
#define DEFAULT_N_COM 2
@@ -2015,16 +3784,20 @@ enum
#endif
/**
- * The structure used to store the modes of both serial ports:<br>
- * <b>(now obsolete)</b>
+ * @brief A The structure used to store the configuration of two serial ports
+ *
+ * @deprecated This structure is deprecated, ::PORT_SETTINGS and related structures
+ * should be used instead, if supported by the device.
*/
typedef struct
{
- COM_PARM com[DEFAULT_N_COM]; /**< COM0 and COM1 settings */
- uint8_t mode[DEFAULT_N_COM]; /**< COM0 and COM1 output mode */
+ COM_PARM com[DEFAULT_N_COM]; ///< COM0 and COM1 settings
+ uint8_t mode[DEFAULT_N_COM]; ///< COM0 and COM1 output mode
+
} PORT_PARM;
#define _mbg_swab_port_parm( _p ) \
+do \
{ \
int i; \
for ( i = 0; i < DEFAULT_N_COM; i++ ) \
@@ -2032,13 +3805,17 @@ typedef struct
_mbg_swab_com_parm( &(_p)->com[i] ); \
/* no need to swap mode byte */ \
} \
-}
+} while ( 0 )
-/*
- * The codes below were used with the obsolete
- * PORT_PARM.mode above. They are defined for
- * compatibility with older devices only:
+/**
+ * @brief Deprecated codes for mode of operation
+ *
+ * @deprecated These codes have been used with the
+ * deprecated ::PORT_PARM::mode. They are only still
+ * defined for compatibility with older devices.
+ *
+ * @see ::STR_MODES
*/
enum
{
@@ -2054,75 +3831,135 @@ enum
/**
- @defgroup group_icode IRIG codes
-
- The following definitions are used to configure an optional
- on-board IRIG input or output. Which frame types are supported
- by a device depends on the device type, and may eventually
- depend on the device's firmware version.
-
- All IRIG frames transport the day-of-year number plus the time-of-day,
- and include a control field segment which can transport user defined
- information.
-
- Some newer IRIG frames are compatible with older frame types but support
- well defined extensions like the year number, local time offset, DST status,
- etc., in the control fields:
-
- - Supported IRIG signal code types:
- - \b A002: 1000 bps, DCLS, time-of-year
- - \b A003: 1000 bps, DCLS, time-of-year, SBS
- - \b A132: 1000 bps, 10 kHz carrier, time-of-year
- - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
- - \b B002: 100 bps, DCLS, time-of-year
- - \b B003: 100 bps, DCLS, time-of-year, SBS
- - \b B122: 100 bps, 1 kHz carrier, time-of-year
- - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
- - \b B006: 100 bps, DCLS, complete date
- - \b B007: 100 bps, DCLS, complete date, SBS
- - \b B126: 100 bps, 1 kHz carrier, complete date
- - \b B127: 100 bps, 1 kHz carrier, complete date, SBS
- - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions
- - \b B222: 100 bps, DCLS, manchester encoded, time-of-year
- - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS
- - \b G002: 10 kbps, DCLS, time-of-year
- - \b G142: 10 kbps, 100 kHz carrier, time-of-year
- - \b G006: 10 kbps, DCLS, complete date
- - \b G146: 10 kbps, 100 kHz carrier, complete date
- - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
- - <b> AFNOR DC:</b> 100 bps, DCLS, SBS, complete date
- - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE1344 extensions (B120)
- - <b> IEEE1344 DC:</b> 100 bps, DCLS, time-of-year, SBS, IEEE1344 extensions (B000)
- - \b C37.118: like IEEE1344, but UTC offset with reversed sign
- - \b C37.118 DC: like IEEE1344 DC, but UTC offset with reversed sign
-
- - time-of-year: day-of-year, hours, minutes, seconds
- - complete date: time-of-year plus year number
- - SBS: straight binary seconds, second-of-day
-
- AFNOR codes are based on the french standard AFNOR NF S87-500
-
- IEEE1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible
- with B002/B122 but provides some well defined extensions in the control field which
- include a quality indicator (time figure of merit, TFOM), year number, DST and leap
- second status, and local time offset from UTC.
-
- C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version
- of the IEEE 1344 standard from 1995. These codes provide the same extensions as IEEE 1344
- but unfortunately define the UTC offset with reversed sign.
-
- @note There are 3rd party IRIG devices out there which apply the UTC offset as specified
- in C37.118, but claim to be compatible with IEEE 1344. So if local time is transmitted
- by the IRIG signal then care must be taken that the UTC offset is evaluated by the IRIG
- receiver in the same way as computed by the IRIG generator. Otherwise the UTC
- time computed by the receiver may be <b>wrong</b>.
- @{
- */
-
-/**
- * Definitions used with IRIG transmitters which usually output both
- * the unmodulated and the modulated IRIG signals at the same time: */
-enum
+ * @defgroup group_icode IRIG time codes
+ *
+ * The following definitions are used to configure an optional
+ * on-board IRIG input or output. Which frame types are supported
+ * by a device depends on the device type, and may eventually
+ * depend on the device's firmware version.
+ *
+ * All IRIG frames transport the day-of-year number plus the time-of-day,
+ * and include a control field segment which can transport user defined
+ * information.
+ *
+ * Some newer IRIG frames are compatible with older frame types but support
+ * well defined extensions like the year number, local time offset, DST status,
+ * etc., in the control fields:
+ *
+ * The following specification can be found in IRIG Standard 200-04 (September 2004):
+ *
+ * Format A: 1k pps
+ * Format B: 100 pps
+ * Format D: 1 ppm
+ * Format E: 10 pps
+ * Format G: 10k pps
+ * Format H: 1 pps
+ *
+ * 1st digit: Modulation Frequency
+ * 0 Pulse width code
+ * 1 Sine wave, amplitude modulated
+ * 2 Manchester modulated
+ *
+ * 2nd digit: Frequency / Resolution
+ * 0: No carrier / index count interval
+ * 1: 100 Hz / 10 ms
+ * 2: 1 kHz / 1 ms
+ * 3: 10 kHz / 0.1 ms
+ * 4: 100 kHz / 10 ms
+ * 5: 1 MHz / 1 ms
+ *
+ * 3rd digit: Coded expressions
+ * 0: DOY+TOD, CF, SBS
+ * 1: DOY+TOD, CF
+ * 2: DOY+TOD
+ * 3: DOY+TOD, SBS
+ * 4: DOY+TOD, Year, CF, SBS
+ * 5: DOY+TOD, Year, CF
+ * 6: DOY+TOD, Year
+ * 7: DOY+TOD, Year, SBS
+ *
+ *
+ * Table of Permissible Code Formats
+ *
+ * Letter 1st digit 2nd digit 3rd digit
+ * ----------------------------------------------
+ * A 0,1,2 0,3,4,5 0,1,2,3,4,5,6,7
+ * B 0,1,2 0,2,3,4,5 0,1,2,3,4,5,6,7
+ * D 0,1 0,1,2 1,2
+ * E 0,1 0,1,2 1,2,5,6
+ * G 0,1,2 0,4,5 1,2,5,6
+ * H 0,1 0,1,2 1,2
+ *
+ * - Known IRIG signal code types:
+ * - \b A002: 1000 bps, DCLS, time-of-year
+ * - \b A003: 1000 bps, DCLS, time-of-year, SBS
+ * - \b A132: 1000 bps, 10 kHz carrier, time-of-year
+ * - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS
+ * - \b B002: 100 bps, DCLS, time-of-year
+ * - \b B003: 100 bps, DCLS, time-of-year, SBS
+ * - \b B122: 100 bps, 1 kHz carrier, time-of-year
+ * - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS
+ * - \b B006: 100 bps, DCLS, complete date
+ * - \b B007: 100 bps, DCLS, complete date, SBS
+ * - \b B126: 100 bps, 1 kHz carrier, complete date
+ * - \b B127: 100 bps, 1 kHz carrier, complete date, SBS
+ * - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions
+ * - \b B222: 100 bps, DCLS, manchester encoded, time-of-year
+ * - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS
+ * - \b G002: 10 kbps, DCLS, time-of-year
+ * - \b G142: 10 kbps, 100 kHz carrier, time-of-year
+ * - \b G006: 10 kbps, DCLS, complete date
+ * - \b G146: 10 kbps, 100 kHz carrier, complete date
+ * - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date
+ * - \b AFNOR DC: 100 bps, DCLS, SBS, complete date
+ * - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE 1344 extensions (B120)
+ * - \b IEEE1344 DC: 100 bps, DCLS, time-of-year, SBS, IEEE 1344 extensions (B000)
+ * - \b C37.118: like IEEE 1344, but %UTC offset applied with reversed sign
+ * - \b C37.118 DC: like IEEE 1344 DC, but %UTC offset applied with reversed sign
+ *
+ * - time-of-year: day-of-year, hours, minutes, seconds
+ * - complete date: time-of-year plus year number
+ * - SBS: straight binary seconds, second-of-day
+ *
+ * AFNOR codes are based on the french standard AFNOR NF S87-500
+ *
+ * IEEE 1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible
+ * with B002/B122 but provides some well defined extensions in the control field which
+ * include a quality indicator (time figure of merit, TFOM), year number, DST and leap
+ * second status, and local time offset from %UTC.
+ *
+ * IEEE C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version
+ * of the IEEE 1344 standard from 1995. These codes provide the same extensions as IEEE 1344
+ * but unfortunately determine that the %UTC offset has to be applied with reversed sign.
+ *
+ * For example, if a -6 hours UTC offset is transmitted in the time code:<br>
+ * IEEE 1344: (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)<br>
+ * IEEE C37.118: (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)<br>
+ *
+ * @see @ref MSK_ICODE_RX_UTC_OFFS_ADD and @ref MSK_ICODE_RX_UTC_OFFS_SUB
+ *
+ * @note There are 3rd party IRIG devices out there which apply the %UTC offset as specified
+ * in IEEE C37.118-2005, but claim to be compatible with IEEE 1344. So if local time is transmitted
+ * by the timecode then care must be taken that the %UTC offset is evaluated by the timecode
+ * receiver in the same way as computed by the timecode generator. Otherwise the %UTC
+ * time computed by the receiver may be <b>wrong</b>.
+ *
+ * @{ */
+
+/**
+ * @brief Known IRIG TX code formats
+ *
+ * Used with ::IRIG_SETTINGS::icode for IRIG transmitters.
+ * For IRIG receivers see ::ICODE_RX_CODES.
+ *
+ * Meinberg timecode transmitters always generate the unmodulated (DCLS)
+ * and usually the modulated timecode signals internally at the same time,
+ * so the code definitions always refer to both.
+ *
+ * @note Not all device may provide both the modulated and unmodulated
+ * signal externally.
+ */
+enum ICODE_TX_CODES
{
ICODE_TX_B002_B122,
ICODE_TX_B003_B123,
@@ -2130,88 +3967,122 @@ enum
ICODE_TX_A003_A133,
ICODE_TX_AFNOR,
ICODE_TX_IEEE1344,
- ICODE_TX_B2201344, // DCLS only
- ICODE_TX_B222, // DCLS only
- ICODE_TX_B223, // DCLS only
+ ICODE_TX_B2201344, ///< DCLS only
+ ICODE_TX_B222, ///< DCLS only
+ ICODE_TX_B223, ///< DCLS only
ICODE_TX_B006_B126,
ICODE_TX_B007_B127,
ICODE_TX_G002_G142,
ICODE_TX_G006_G146,
ICODE_TX_C37118,
- N_ICODE_TX /**< number of code types */
+ ICODE_TX_TXC101,
+ ICODE_TX_E002_E112,
+ ICODE_TX_NASA36,
+ ICODE_TX_A006_A136,
+ ICODE_TX_A007_A137,
+ N_ICODE_TX ///< number of known codes
};
/**
- * Initializers for format name strings.
+ * @brief Initializers for TX timecode format name strings
+ *
+ * @see ::ICODE_TX_CODES
*/
-#define DEFAULT_ICODE_TX_NAMES \
-{ \
- "B002+B122", \
- "B003+B123", \
- "A002+A132", \
- "A003+A133", \
- "AFNOR NF S87-500", \
- "IEEE1344", \
- "B220(1344) DCLS", \
- "B222 DCLS", \
- "B223 DCLS", \
- "B006+B126", \
- "B007+B127", \
- "G002+G142", \
- "G006+G146", \
- "C37.118" \
-}
-
-/**
- * Initializers for short name strings which must not
- * be longer than 10 printable characters.
+#define DEFAULT_ICODE_TX_NAMES \
+{ \
+ /* B002_B122 */ "B002+B122", \
+ /* B003_B123 */ "B003+B123", \
+ /* A002_A132 */ "A002+A132", \
+ /* A003_A133 */ "A003+A133", \
+ /* AFNOR */ "AFNOR NF S87-500", \
+ /* IEEE1344 */ "IEEE 1344", \
+ /* B2201344 */ "B220(1344) DCLS", \
+ /* B222 */ "B222 DCLS", \
+ /* B223 */ "B223 DCLS", \
+ /* B006_B126 */ "B006+B126", \
+ /* B007_B127 */ "B007+B127", \
+ /* G002_G142 */ "G002+G142", \
+ /* G006_G146 */ "G006+G146", \
+ /* C37118 */ "IEEE C37.118", \
+ /* TXC101 */ "TXC-101 DTR-6", \
+ /* E002_E112 */ "E002+E112", \
+ /* NASA36 */ "NASA 36", \
+ /* A006_A136 */ "A006+A136", \
+ /* A007_A137 */ "A007+A137" \
+}
+
+/**
+ * @brief Initializers for short TX timecode format name strings
+ *
+ * @note Must not be longer than 10 printable characters
+ *
+ * @see ::ICODE_TX_CODES
*/
#define DEFAULT_ICODE_TX_NAMES_SHORT \
{ \
- "B002+B122", \
- "B003+B123", \
- "A002+A132", \
- "A003+A133", \
- "AFNOR NF-S", \
- "IEEE1344", \
- "B220/1344", \
- "B222 DC", \
- "B223 DC", \
- "B006+B126", \
- "B007+B127", \
- "G002+G142", \
- "G006+G146", \
- "C37.118" \
+ /* B002_B122 */ "B002+B122", \
+ /* B003_B123 */ "B003+B123", \
+ /* A002_A132 */ "A002+A132", \
+ /* A003_A133 */ "A003+A133", \
+ /* AFNOR */ "AFNOR NF S", \
+ /* IEEE1344 */ "IEEE 1344", \
+ /* B2201344 */ "B220/1344", \
+ /* B222 */ "B222 DC", \
+ /* B223 */ "B223 DC", \
+ /* B006_B126 */ "B006+B126", \
+ /* B007_B127 */ "B007+B127", \
+ /* G002_G142 */ "G002+G142", \
+ /* G006_G146 */ "G006+G146", \
+ /* C37118 */ "C37.118", \
+ /* TXC101 */ "TXC-101", \
+ /* E002_E112 */ "E002+E112", \
+ /* NASA36 */ "NASA 36", \
+ /* A006_A136 */ "A006+A136", \
+ /* A007_A137 */ "A007+A137" \
}
/**
- * Initializers for English format description strings.
+ * @brief Initializers for English TX format description strings
+ *
+ * @see ::ICODE_TX_CODES
*/
-#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \
-{ \
- "100 bps, DCLS or 1 kHz carrier", \
- "100 bps, DCLS or 1 kHz carrier, SBS", \
- "1000 bps, DCLS or 10 kHz carrier", \
- "1000 bps, DCLS or 10 kHz carrier, SBS", \
- "100 bps, DCLS or 1 kHz carrier, SBS, complete date", \
- "100 bps, DCLS or 1 kHz carrier, SBS, complete date, time zone info", \
- "100 bps, Manchester enc., DCLS only, SBS, complete date, time zone info", \
- "100 bps, Manchester enc., DCLS only", \
- "100 bps, Manchester enc., DCLS only, SBS", \
- "100 bps, DCLS or 1 kHz carrier, complete date", \
- "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \
- "10 kbps, DCLS or 100 kHz carrier", \
- "10 kbps, DCLS or 100 kHz carrier, complete date", \
- "like IEEE1344, but UTC offset with reversed sign" \
+#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \
+{ \
+ /* B002_B122 */ "100 bps, DCLS or 1 kHz carrier", \
+ /* B003_B123 */ "100 bps, DCLS or 1 kHz carrier, SBS", \
+ /* A002_A132 */ "1000 bps, DCLS or 10 kHz carrier", \
+ /* A003_A133 */ "1000 bps, DCLS or 10 kHz carrier, SBS", \
+ /* AFNOR */ "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \
+ /* IEEE1344 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \
+ /* B2201344 */ "100 bps, Manchester enc., DCLS only, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \
+ /* B222 */ "100 bps, Manchester enc., DCLS only", \
+ /* B223 */ "100 bps, Manchester enc., DCLS only, SBS", \
+ /* B006_B126 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number", \
+ /* B007_B127 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS", \
+ /* G002_G142 */ "10 kbps, DCLS or 100 kHz carrier", \
+ /* G006_G146 */ "10 kbps, DCLS or 100 kHz carrier, 2 digit year number", \
+ /* C37118 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offs. reverse to 1344, DST/Leap sec status", \
+ /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \
+ /* E002_E112 */ "10 bps, DCLS or 100 Hz carrier", \
+ /* NASA36 */ "100 bps, DCLS or 1 kHz carrier", \
+ /* A006_A136 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number", \
+ /* A007_A137 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number, 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:
- */
+
+/**
+ * @brief Bit masks used with ::IRIG_INFO::supp_codes for TX
+ *
+ * These bit masks are used with timecode receivers only
+ *
+ * @see @ref ICODE_TX_CODES
+ * @see @ref ICODE_RX_CODES
+ * @see @ref ICODE_RX_MASKS
+ *
+ * @anchor ICODE_TX_MASKS @{ */
+
#define MSK_ICODE_TX_B002_B122 ( 1UL << ICODE_TX_B002_B122 )
#define MSK_ICODE_TX_B003_B123 ( 1UL << ICODE_TX_B003_B123 )
#define MSK_ICODE_TX_A002_A132 ( 1UL << ICODE_TX_A002_A132 )
@@ -2226,19 +4097,35 @@ enum
#define MSK_ICODE_TX_G002_G142 ( 1UL << ICODE_TX_G002_G142 )
#define MSK_ICODE_TX_G006_G146 ( 1UL << ICODE_TX_G006_G146 )
#define MSK_ICODE_TX_C37118 ( 1UL << ICODE_TX_C37118 )
+#define MSK_ICODE_TX_TXC101 ( 1UL << ICODE_TX_TXC101 )
+#define MSK_ICODE_TX_E002_E112 ( 1UL << ICODE_TX_E002_E112 )
+#define MSK_ICODE_TX_NASA36 ( 1UL << ICODE_TX_NASA36 )
+#define MSK_ICODE_TX_A006_A136 ( 1UL << ICODE_TX_A006_A136 )
+#define MSK_ICODE_TX_A007_A137 ( 1UL << ICODE_TX_A007_A137 )
+
+/** @} anchor ICODE_TX_MASKS */
+
/**
- * A mask of IRIG formats with manchester encoded DC output:
+ * @brief A mask of IRIG TX formats with manchester encoded DC output
*/
#define MSK_ICODE_TX_DC_MANCH \
( \
- MSK_ICODE_TX_B2201344 | \
- MSK_ICODE_TX_B222 | \
+ MSK_ICODE_TX_B2201344 | \
+ MSK_ICODE_TX_B222 | \
MSK_ICODE_TX_B223 \
)
/**
- * A mask of IRIG formats with 1 kHz carrier:
+ * @brief A mask of IRIG TX formats with 100 Hz carrier
+ */
+#define MSK_ICODE_TX_100HZ \
+( \
+ MSK_ICODE_TX_E002_E112 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats with 1 kHz carrier
*/
#define MSK_ICODE_TX_1KHZ \
( \
@@ -2251,80 +4138,224 @@ enum
MSK_ICODE_TX_B223 | \
MSK_ICODE_TX_B006_B126 | \
MSK_ICODE_TX_B007_B127 | \
- MSK_ICODE_TX_C37118 \
+ MSK_ICODE_TX_C37118 | \
+ MSK_ICODE_TX_NASA36 \
)
/**
- * A mask of IRIG formats with 10 kHz carrier:
+ * @brief A mask of IRIG TX formats with 10 kHz carrier
*/
#define MSK_ICODE_TX_10KHZ \
( \
MSK_ICODE_TX_A002_A132 | \
- MSK_ICODE_TX_A003_A133 \
+ MSK_ICODE_TX_A003_A133 | \
+ MSK_ICODE_TX_A006_A136 | \
+ MSK_ICODE_TX_A007_A137 \
)
/**
- * A mask of IRIG formats with 100 kHz carrier:
+ * @brief A mask of IRIG TX formats with 100 kHz carrier
*/
#define MSK_ICODE_TX_100KHZ \
( \
- MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G002_G142 | \
MSK_ICODE_TX_G006_G146 \
)
/**
- * A mask of IRIG formats with 100 bps data rate:
+ * @brief A mask of IRIG TX formats with 10 bps data rate
+ */
+#define MSK_ICODE_TX_10BPS \
+( \
+ MSK_ICODE_TX_E002_E112 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats with 100 bps data rate
*/
#define MSK_ICODE_TX_100BPS \
( \
- MSK_ICODE_TX_B002_B122 | \
- MSK_ICODE_TX_B003_B123 | \
- MSK_ICODE_TX_AFNOR | \
- MSK_ICODE_TX_IEEE1344 | \
- MSK_ICODE_TX_B006_B126 | \
- MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_B002_B122 | \
+ MSK_ICODE_TX_B003_B123 | \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_B006_B126 | \
+ MSK_ICODE_TX_B007_B127 | \
MSK_ICODE_TX_C37118 \
)
/**
- * A mask of IRIG formats with 1000 bps data rate:
+ * @brief A mask of IRIG TX formats with 1000 bps data rate
*/
#define MSK_ICODE_TX_1000BPS \
( \
- MSK_ICODE_TX_A002_A132 | \
- MSK_ICODE_TX_A003_A133 \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 | \
+ MSK_ICODE_TX_A006_A136 | \
+ MSK_ICODE_TX_A007_A137 \
)
/**
- * A mask of IRIG formats with 10 kbps data rate:
+ * @brief A mask of IRIG TX formats with 10 kbps data rate
*/
#define MSK_ICODE_TX_10000BPS \
( \
- MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G002_G142 | \
MSK_ICODE_TX_G006_G146 \
)
/**
- * A mask of IRIG formats which support TFOM:
+ * @brief A mask of IRIG TX formats supporting 10ths of seconds
+ */
+#define MSK_ICODE_TX_HAS_SEC10THS \
+( \
+ MSK_ICODE_TX_A002_A132 | \
+ MSK_ICODE_TX_A003_A133 | \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 | \
+ MSK_ICODE_TX_A006_A136 | \
+ MSK_ICODE_TX_A007_A137 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats supporting 100ths of seconds
+ */
+#define MSK_ICODE_TX_HAS_SEC100THS \
+( \
+ MSK_ICODE_TX_G002_G142 | \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats providing a short year number after P5
+ *
+ * The IEEE codes, the AFNOR codes, and some IRIG codes provide a
+ * 2 digit year number after position identifier P5. However, some
+ * IRIG G codes provide a 100ths-of-seconds field after P5,and
+ * eventually provide a year number after P6.
+ *
+ * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6
+ * @see @ref MSK_ICODE_TX_HAS_ANY_SHORT_YEAR
+ */
+#define MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_B2201344 | \
+ MSK_ICODE_TX_B006_B126 | \
+ MSK_ICODE_TX_B007_B127 | \
+ MSK_ICODE_TX_C37118 | \
+ MSK_ICODE_TX_A006_A136 | \
+ MSK_ICODE_TX_A007_A137 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats providing a short year number after P6
+ *
+ * While most time codes that provide a year number do this after P5,
+ * there are some IRIG codes which provide a 100ths-of-seconds field
+ * at that position, and eventually provide a year number after P6.
+ *
+ * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5
+ * @see @ref MSK_ICODE_TX_HAS_ANY_SHORT_YEAR
+ */
+ #define MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 \
+( \
+ MSK_ICODE_TX_G006_G146 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats providing a short year number in general
+ *
+ * Depending on the code format, the year number can be transmitted
+ * either after position identifier P5, or after P6.
+ *
+ * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5
+ * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6
+ */
+#define MSK_ICODE_TX_HAS_ANY_SHORT_YEAR \
+( \
+ MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 | \
+ MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats supporting TFOM
*/
#define MSK_ICODE_TX_HAS_TFOM \
( \
- MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_C37118 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats supporting CTQ continuous time quality
+ *
+ * This has been introduced in IEEE C37.118.1-2011
+ */
+#define MSK_ICODE_TX_HAS_CTQ \
+( \
+ MSK_ICODE_TX_IEEE1344 | \
MSK_ICODE_TX_C37118 \
)
/**
- * A mask of IRIG formats which support time zone information:
+ * @brief A mask of IRIG TX formats supporting time zone information
*/
#define MSK_ICODE_TX_HAS_TZI \
( \
- MSK_ICODE_TX_IEEE1344 | \
+ MSK_ICODE_TX_IEEE1344 | \
MSK_ICODE_TX_C37118 \
)
/**
- * The default mask of IRIG formats supported by
- * IRIG transmitters:
+ * @brief IRIG TX formats where UTC offset must be subtracted to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)
+ */
+#define MSK_ICODE_TX_UTC_OFFS_SUB \
+( \
+ MSK_ICODE_TX_IEEE1344 \
+)
+
+/**
+ * @brief IRIG TX formats where UTC offset must be added to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)
+ */
+#define MSK_ICODE_TX_UTC_OFFS_ADD \
+( \
+ MSK_ICODE_TX_C37118 \
+)
+
+/**
+ * @brief A mask of IRIG TX formats supporting a day of week number
+ */
+#define MSK_ICODE_TX_HAS_AFNOR_WDAY \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_AFNOR_DC \
+)
+
+/**
+ * @brief A mask of IRIG TX formats supporting a date (day-of-month, month)
+ */
+#define MSK_ICODE_TX_HAS_AFNOR_DATE \
+( \
+ MSK_ICODE_TX_AFNOR | \
+ MSK_ICODE_TX_AFNOR_DC \
+)
+
+
+/**
+ * @brief The default mask of IRIG TX formats supported by IRIG transmitters
+ *
+ * @note The formats which are actually supported should be retrieved
+ * from the device
*/
#if !defined( SUPP_MSK_ICODE_TX )
#define SUPP_MSK_ICODE_TX \
@@ -2340,105 +4371,159 @@ enum
/**
- * Definitions used with IRIG receivers which decode
- * two similar IRIG codes (with or without SBS)
- * at the same time.
+ * @brief Known IRIG RX code formats
+ *
+ * Used with ::IRIG_SETTINGS::icode for IRIG receivers.
+ * For IRIG transmitters see ::ICODE_TX_CODES.
+ *
+ * The SBS value is redundant and can easily by computed
+ * from the time-of-day, so Meinberg time code receivers
+ * usually don't evaluate the SBS field anyway, and thus
+ * it makes no difference if a code with or withour SBS
+ * is supplied.
*/
-enum
+enum ICODE_RX_CODES
{
- ICODE_RX_B122_B123, // modulated
- ICODE_RX_A132_A133, // modulated
- ICODE_RX_B002_B003, // DCLS
- ICODE_RX_A002_A003, // DCLS
- ICODE_RX_AFNOR, // modulated
- ICODE_RX_AFNOR_DC, // DCLS
- ICODE_RX_IEEE1344, // modulated
- ICODE_RX_IEEE1344_DC, // DCLS
- ICODE_RX_B126_B127, // modulated
- ICODE_RX_B006_B007, // DCLS
- ICODE_RX_G142_G146, // modulated
- ICODE_RX_G002_G006, // DCLS
- ICODE_RX_C37118, // modulated
- ICODE_RX_C37118_DC, // DCLS
- ICODE_RX_TXC_101, // modulated
- ICODE_RX_TXC_101_DC, // DCLS
- N_ICODE_RX /* the number of valid signal code types */
+ ICODE_RX_B122_B123, ///< modulated
+ ICODE_RX_A132_A133, ///< modulated
+ ICODE_RX_B002_B003, ///< DCLS
+ ICODE_RX_A002_A003, ///< DCLS
+ ICODE_RX_AFNOR, ///< modulated
+ ICODE_RX_AFNOR_DC, ///< DCLS
+ ICODE_RX_IEEE1344, ///< modulated
+ ICODE_RX_IEEE1344_DC, ///< DCLS
+ ICODE_RX_B126_B127, ///< modulated
+ ICODE_RX_B006_B007, ///< DCLS
+ ICODE_RX_G142, ///< modulated (G143 is undefined, SBS not supported with Gxxx)
+ ICODE_RX_G002, ///< DCLS (G003 is undefined, SBS not supported with Gxxx)
+ ICODE_RX_C37118, ///< modulated
+ ICODE_RX_C37118_DC, ///< DCLS
+ ICODE_RX_TXC101, ///< modulated
+ ICODE_RX_TXC101_DC, ///< DCLS
+ ICODE_RX_E112, ///< modulated
+ ICODE_RX_E002, ///< DCLS
+ ICODE_RX_NASA36, ///< modulated
+ ICODE_RX_NASA36_DC, ///< DCLS
+ ICODE_RX_A136_A137, ///< modulated
+ ICODE_RX_A006_A007, ///< DCLS
+ ICODE_RX_G146, ///< modulated (G147 is undefined, SBS not supported with Gxxx)
+ ICODE_RX_G006, ///< DCLS (G007 is undefined, SBS not supported with Gxxx)
+ N_ICODE_RX ///< the number of known codes
};
/**
- * Initializers for format name strings.
+ * @brief Initializers for RX timecode format name strings
+ *
+ * @see ::ICODE_RX_CODES
*/
#define DEFAULT_ICODE_RX_NAMES \
{ \
- "B122/B123", \
- "A132/A133", \
- "B002/B003 (DCLS)", \
- "A002/A003 (DCLS)", \
- "AFNOR NF S87-500", \
- "AFNOR NF S87-500 (DCLS)", \
- "IEEE1344", \
- "IEEE1344 (DCLS)", \
- "B126/B127", \
- "B006/B007 (DCLS)", \
- "G142/G146", \
- "G002/G006 (DCLS)", \
- "C37.118", \
- "C37.118 (DCLS)", \
- "TXC-101 DTR-6", \
- "TXC-101 DTR-6 (DCLS)" \
-}
-
-/**
- * Initializers for short name strings which must not
- * be longer than 11 printable characters.
- */
-#define DEFAULT_ICODE_RX_NAMES_SHORT \
-{ \
- "B122/B123", \
- "A132/A133", \
- "B002/B003", \
- "A002/A003", \
- "AFNOR NF-S", \
- "AFNOR DC", \
- "IEEE1344", \
- "IEEE1344 DC", \
- "B126/B127", \
- "B006/B007", \
- "G142/G146", \
- "G002/G006", \
- "C37.118", \
- "C37.118 DC", \
- "TXC-101", \
- "TXC-101 DC" \
+ /* B122_B123 */ "B122/B123", \
+ /* A132_A133 */ "A132/A133", \
+ /* B002_B003 */ "B002/B003 (DCLS)", \
+ /* A002_A003 */ "A002/A003 (DCLS)", \
+ /* AFNOR */ "AFNOR NF S87-500", \
+ /* AFNOR_DC */ "AFNOR NF S87-500 (DCLS)", \
+ /* IEEE1344 */ "IEEE1344", \
+ /* IEEE1344_DC */ "IEEE1344 (DCLS)", \
+ /* B126_B127 */ "B126/B127", \
+ /* B006_B007 */ "B006/B007 (DCLS)", \
+ /* G142 */ "G142", \
+ /* G002 */ "G002 (DCLS)", \
+ /* C37118 */ "C37.118", \
+ /* C37118_DC */ "C37.118 (DCLS)", \
+ /* TXC101 */ "TXC-101 DTR-6", \
+ /* TXC101_DC */ "TXC-101 DTR-6 (DCLS)", \
+ /* E112 */ "E112", \
+ /* E002 */ "E002 (DCLS)", \
+ /* NASA36 */ "NASA-36", \
+ /* NASA36_DC */ "NASA-36 (DCLS)", \
+ /* A136_A137 */ "A136/A137", \
+ /* A006_A007 */ "A006/A007 (DCLS)", \
+ /* G146 */ "G146", \
+ /* G006 */ "G006 (DCLS)" \
}
-
/**
- * Initializers for English format description strings.
+ * @brief Initializers for short RX timecode format name strings
+ *
+ * @note Must not be longer than 11 printable characters
+ *
+ * @see ::ICODE_RX_CODES
*/
-#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
-{ \
- "100 bps, 1 kHz carrier, SBS optionally", \
- "1000 bps, 10 kHz carrier, SBS optionally", \
- "100 bps, DCLS, SBS optionally", \
- "1000 bps, DCLS, SBS optionally", \
- "100 bps, 1 kHz carrier, SBS, complete date", \
- "100 bps, DCLS, SBS, complete date", \
- "100 bps, 1 kHz carrier, SBS, time zone info", \
- "100 bps, DCLS, SBS, time zone info", \
- "100 bps, 1 kHz carrier, complete date, SBS optionally", \
- "100 bps, DCLS, complete date, SBS optionally", \
- "10 kbps, 100 kHz carrier, complete date optionally", \
- "10 kbps, DCLS, complete date optionally", \
- "like IEEE1344, but UTC offset with reversed sign", \
- "like IEEE1344 DC, but UTC offset with reversed sign", \
- "code from TV time sync device TXC-101 DTR-6", \
- "DC code from TV time sync device TXC-101 DTR-6" \
+#define DEFAULT_ICODE_RX_NAMES_SHORT \
+{ \
+ /* B122_B123 */ "B122/B123", \
+ /* A132_A133 */ "A132/A133", \
+ /* B002_B003 */ "B002/B003", \
+ /* A002_A003 */ "A002/A003", \
+ /* AFNOR */ "AFNOR NF S", \
+ /* AFNOR_DC */ "AFNOR DC", \
+ /* IEEE1344 */ "IEEE1344", \
+ /* IEEE1344_DC */ "IEEE1344 DC", \
+ /* B126_B127 */ "B126/B127", \
+ /* B006_B007 */ "B006/B007", \
+ /* G142 */ "G142", \
+ /* G002 */ "G002 DC", \
+ /* C37118 */ "C37.118", \
+ /* C37118_DC */ "C37.118 DC", \
+ /* TXC101 */ "TXC-101", \
+ /* TXC101_DC */ "TXC-101 DC", \
+ /* E112 */ "E112", \
+ /* E002 */ "E002 DC", \
+ /* NASA36 */ "NASA-36", \
+ /* NASA36_DC */ "NASA-36 DC", \
+ /* A136_A137 */ "A136/A137", \
+ /* A006_A007 */ "A006/A007", \
+ /* G146 */ "G146", \
+ /* G006 */ "G006 DC" \
}
-/*
- * Bit masks corresponding to the enumeration above:
+
+/**
+ * @brief Initializers for English RX format description strings
+ *
+ * @see ::ICODE_RX_CODES
*/
+#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \
+{ \
+ /* B122_B123 */ "100 bps, 1 kHz carrier, SBS optionally", \
+ /* A132_A133 */ "1000 bps, 10 kHz carrier, SBS optionally", \
+ /* B002_B003 */ "100 bps, DCLS, SBS optionally", \
+ /* A002_A003 */ "1000 bps, DCLS, SBS optionally", \
+ /* AFNOR */ "100 bps, 1 kHz carrier, complete date, SBS", \
+ /* AFNOR_DC */ "100 bps, DCLS, complete date, SBS", \
+ /* IEEE1344 */ "100 bps, 1 kHz carrier, SBS, time zone info", \
+ /* IEEE1344_DC */ "100 bps, DCLS, SBS, time zone info", \
+ /* B126_B127 */ "100 bps, 1 kHz carrier, 2 digit year number, SBS optionally", \
+ /* B006_B007 */ "100 bps, DCLS, 2 digit year number, SBS optionally", \
+ /* G142 */ "10 kbps, 100 kHz carrier", \
+ /* G002 */ "10 kbps, DCLS", \
+ /* C37118 */ "like IEEE1344, but UTC offset with reversed sign", \
+ /* C37118_DC */ "like IEEE1344 DC, but UTC offset with reversed sign", \
+ /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \
+ /* TXC101_DC */ "DC code from TV time sync device TXC-101 DTR-6", \
+ /* E112 */ "10 bps, 100 Hz carrier", \
+ /* E002 */ "10 bps, DCLS", \
+ /* NASA36 */ "100 bps, 1 kHz carrier", \
+ /* NASA36_DC */ "100 bps, DCLS", \
+ /* A136_A137 */ "1000 bps, 10 kHz carrier, 2 digit year number, SBS optionally", \
+ /* A006_A007 */ "1000 bps, DCLS, 2 digit year number, SBS optionally", \
+ /* G146 */ "10 kbps, 100 kHz carrier, 2 digit year number", \
+ /* G006 */ "10 kbps, DCLS, 2 digit year number" \
+}
+
+/**
+ * @brief Bit masks used with ::IRIG_INFO::supp_codes for RX
+ *
+ * These bit masks are used with timecode receivers only
+ *
+ * @see @ref ICODE_RX_CODES
+ * @see @ref ICODE_TX_CODES
+ * @see @ref ICODE_TX_MASKS
+ *
+ * @anchor ICODE_RX_MASKS @{ */
+
#define MSK_ICODE_RX_B122_B123 ( 1UL << ICODE_RX_B122_B123 )
#define MSK_ICODE_RX_A132_A133 ( 1UL << ICODE_RX_A132_A133 )
#define MSK_ICODE_RX_B002_B003 ( 1UL << ICODE_RX_B002_B003 )
@@ -2449,15 +4534,26 @@ enum
#define MSK_ICODE_RX_IEEE1344_DC ( 1UL << ICODE_RX_IEEE1344_DC )
#define MSK_ICODE_RX_B126_B127 ( 1UL << ICODE_RX_B126_B127 )
#define MSK_ICODE_RX_B006_B007 ( 1UL << ICODE_RX_B006_B007 )
-#define MSK_ICODE_RX_G142_G146 ( 1UL << ICODE_RX_G142_G146 )
-#define MSK_ICODE_RX_G002_G006 ( 1UL << ICODE_RX_G002_G006 )
+#define MSK_ICODE_RX_G142 ( 1UL << ICODE_RX_G142 )
+#define MSK_ICODE_RX_G002 ( 1UL << ICODE_RX_G002 )
#define MSK_ICODE_RX_C37118 ( 1UL << ICODE_RX_C37118 )
#define MSK_ICODE_RX_C37118_DC ( 1UL << ICODE_RX_C37118_DC )
-#define MSK_ICODE_RX_TXC_101 ( 1UL << ICODE_RX_TXC_101 )
-#define MSK_ICODE_RX_TXC_101_DC ( 1UL << ICODE_RX_TXC_101_DC )
+#define MSK_ICODE_RX_TXC101 ( 1UL << ICODE_RX_TXC101 )
+#define MSK_ICODE_RX_TXC101_DC ( 1UL << ICODE_RX_TXC101_DC )
+#define MSK_ICODE_RX_E112 ( 1UL << ICODE_RX_E112 )
+#define MSK_ICODE_RX_E002 ( 1UL << ICODE_RX_E002 )
+#define MSK_ICODE_RX_NASA36 ( 1UL << ICODE_RX_NASA36 )
+#define MSK_ICODE_RX_NASA36_DC ( 1UL << ICODE_RX_NASA36_DC )
+#define MSK_ICODE_RX_A136_A137 ( 1UL << ICODE_RX_A136_A137 )
+#define MSK_ICODE_RX_A006_A007 ( 1UL << ICODE_RX_A006_A007 )
+#define MSK_ICODE_RX_G146 ( 1UL << ICODE_RX_G146 )
+#define MSK_ICODE_RX_G006 ( 1UL << ICODE_RX_G006 )
+
+/** @} anchor ICODE_RX_MASKS */
+
/**
- * A mask of IRIG DCLS formats:
+ * @brief A mask of IRIG RX DCLS formats
*/
#define MSK_ICODE_RX_DC \
( \
@@ -2466,12 +4562,25 @@ enum
MSK_ICODE_RX_AFNOR_DC | \
MSK_ICODE_RX_IEEE1344_DC | \
MSK_ICODE_RX_B006_B007 | \
- MSK_ICODE_RX_G002_G006 | \
- MSK_ICODE_RX_C37118_DC \
+ MSK_ICODE_RX_G002 | \
+ MSK_ICODE_RX_C37118_DC | \
+ MSK_ICODE_RX_TXC101_DC | \
+ MSK_ICODE_RX_E002 | \
+ MSK_ICODE_RX_NASA36_DC | \
+ MSK_ICODE_RX_A006_A007 | \
+ MSK_ICODE_RX_G006 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats with 100 Hz carrier
+ */
+#define MSK_ICODE_RX_100HZ \
+( \
+ MSK_ICODE_RX_E112 \
)
/**
- * A mask of IRIG formats with 1 kHz carrier:
+ * @brief A mask of IRIG RX formats with 1 kHz carrier
*/
#define MSK_ICODE_RX_1KHZ \
( \
@@ -2479,27 +4588,40 @@ enum
MSK_ICODE_RX_AFNOR | \
MSK_ICODE_RX_IEEE1344 | \
MSK_ICODE_RX_B126_B127 | \
- MSK_ICODE_RX_C37118 \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_TXC101 | \
+ MSK_ICODE_RX_NASA36 \
)
/**
- * A mask of IRIG formats with 10 kHz carrier:
+ * @brief A mask of IRIG RX formats with 10 kHz carrier
*/
#define MSK_ICODE_RX_10KHZ \
( \
- MSK_ICODE_RX_A132_A133 \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A136_A137 \
)
/**
- * A mask of IRIG formats with 100 kHz carrier:
+ * @brief A mask of IRIG RX formats with 100 kHz carrier
*/
#define MSK_ICODE_RX_100KHZ \
( \
- MSK_ICODE_RX_G142_G146 \
+ MSK_ICODE_RX_G142 | \
+ MSK_ICODE_RX_G146 \
)
/**
- * A mask of IRIG formats with 100 bps data rate:
+ * @brief A mask of IRIG RX formats with 10 bps data rate
+ */
+#define MSK_ICODE_RX_10BPS \
+( \
+ MSK_ICODE_RX_E002_E112 | \
+ MSK_ICODE_RX_E002_E002 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats with 100 bps data rate
*/
#define MSK_ICODE_RX_100BPS \
( \
@@ -2512,28 +4634,118 @@ enum
MSK_ICODE_RX_B126_B127 | \
MSK_ICODE_RX_B006_B007 | \
MSK_ICODE_RX_C37118 | \
- MSK_ICODE_RX_C37118_DC \
+ MSK_ICODE_RX_C37118_DC | \
+ MSK_ICODE_RX_TXC101 | \
+ MSK_ICODE_RX_TXC101_DC | \
+ MSK_ICODE_RX_NASA36 | \
+ MSK_ICODE_RX_NASA36_DC \
)
/**
- * A mask of IRIG formats with 1000 bps data rate:
+ * @brief A mask of IRIG RX formats with 1000 bps data rate
*/
#define MSK_ICODE_RX_1000BPS \
( \
- MSK_ICODE_RX_A132_A133 | \
- MSK_ICODE_RX_A002_A003 \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_A136_A137 | \
+ MSK_ICODE_RX_A006_A007 \
)
/**
- * A mask of IRIG formats with 10 kbps data rate:
+ * @brief A mask of IRIG RX formats with 10 kbps data rate
*/
#define MSK_ICODE_RX_10000BPS \
( \
- MSK_ICODE_RX_G142_G146 \
+ MSK_ICODE_RX_G142 | \
+ MSK_ICODE_RX_G002 | \
+ MSK_ICODE_RX_G146 | \
+ MSK_ICODE_RX_G006 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting 10ths of seconds
+ */
+#define MSK_ICODE_RX_HAS_SEC10THS \
+( \
+ MSK_ICODE_RX_A132_A133 | \
+ MSK_ICODE_RX_A002_A003 | \
+ MSK_ICODE_RX_G142 | \
+ MSK_ICODE_RX_G002 | \
+ MSK_ICODE_RX_A136_A137 | \
+ MSK_ICODE_RX_A006_A007 | \
+ MSK_ICODE_RX_G146 | \
+ MSK_ICODE_RX_G006 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats which support 100ths of seconds
+ */
+#define MSK_ICODE_RX_HAS_SEC100THS \
+( \
+ MSK_ICODE_RX_G142 | \
+ MSK_ICODE_RX_G002 | \
+ MSK_ICODE_RX_G146 | \
+ MSK_ICODE_RX_G006 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting a 2 digit year number after P5
+ *
+ * Note: This macro specifies ONLY the codes where the year number
+ * is transmitted after position identifier P5.
+ *
+ * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6
+ * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR
+ */
+#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC | \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_B126_B127 | \
+ MSK_ICODE_RX_B006_B007 | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC | \
+ MSK_ICODE_RX_A136_A137 | \
+ MSK_ICODE_RX_A006_A007 \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting a 2 digit year number after P6
+ *
+ * Note: This macro specifies ONLY the codes where the year number
+ * is transmitted after position identifier P6.
+ *
+ * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5
+ * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR
+ */
+#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \
+( \
+ MSK_ICODE_RX_G146 | \
+ MSK_ICODE_RX_G006 \
)
/**
- * A mask of IRIG formats which support TFOM:
+ * @brief A mask of IRIG RX formats providing any 2 digit year number
+ *
+ * Note: Different sets of code frames may provide a year number
+ * in different locations of the transmitted code.
+ *
+ * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5
+ * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6
+ */
+#define MSK_ICODE_RX_HAS_ANY_SHORT_YEAR \
+( \
+ MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 | \
+ MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \
+)
+
+
+
+/**
+ * @brief A mask of IRIG RX formats supporting TFOM time quality indicator
*/
#define MSK_ICODE_RX_HAS_TFOM \
( \
@@ -2544,7 +4756,20 @@ enum
)
/**
- * A mask of IRIG formats which support time zone information:
+ * @brief A mask of IRIG RX formats supporting CTQ continuous time quality
+ *
+ * This has been introduced in IEEE C37.118.1-2011
+ */
+#define MSK_ICODE_RX_HAS_CTQ \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC | \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting time zone information
*/
#define MSK_ICODE_RX_HAS_TZI \
( \
@@ -2555,8 +4780,55 @@ enum
)
/**
- * The default mask of IRIG formats supported by
- * IRIG receivers:
+ * @brief IRIG RX formats where UTC offset must be subtracted to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) - (offs -6 h) = (UTC 20:43:27)
+ */
+#define MSK_ICODE_RX_UTC_OFFS_SUB \
+( \
+ MSK_ICODE_RX_IEEE1344 | \
+ MSK_ICODE_RX_IEEE1344_DC \
+)
+
+/**
+ * @brief IRIG RX formats where UTC offset must be added to yield UTC
+ *
+ * A mask of IRIG formats where the decoded UTC offset must be
+ * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br>
+ * (IRIG time 14:43:27 h) + (offs -6 h) = (UTC 08:43:27)
+ */
+#define MSK_ICODE_RX_UTC_OFFS_ADD \
+( \
+ MSK_ICODE_RX_C37118 | \
+ MSK_ICODE_RX_C37118_DC \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting a day of week number
+ */
+#define MSK_ICODE_RX_HAS_AFNOR_WDAY \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC \
+)
+
+/**
+ * @brief A mask of IRIG RX formats supporting a date (day-of-month, month)
+ */
+#define MSK_ICODE_RX_HAS_AFNOR_DATE \
+( \
+ MSK_ICODE_RX_AFNOR | \
+ MSK_ICODE_RX_AFNOR_DC \
+)
+
+
+/**
+ * @brief The default mask of IRIG RX formats supported by IRIG receivers
+ *
+ * @note The formats which are actually supported should be retrieved
+ * from the device
*/
#if !defined( SUPP_MSK_ICODE_RX )
#define SUPP_MSK_ICODE_RX \
@@ -2570,91 +4842,255 @@ enum
)
#endif
-/** @} group_icode */
+/** @} defgroup group_icode */
/**
- * The structure below is used to configure an optional
- * on-board IRIG output:
+ * @brief Configuration settings of an IRIG input or output
+ *
+ * @see @ref group_icode
*/
typedef struct
{
- uint16_t icode; /**< IRIG signal code, see \ref group_icode */
- uint16_t flags; /**< see \ref group_irig_flags */
+ uint16_t icode; ///< IRIG signal code, see ::ICODE_RX_CODES and ::ICODE_TX_CODES
+ uint16_t flags; ///< see ::IFLAGS_BIT_MASKS
+
} IRIG_SETTINGS;
#define _mbg_swab_irig_settings( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->icode ); \
_mbg_swab16( &(_p)->flags ); \
-}
+} while ( 0 )
+
/**
- * @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS::flags
+ * @brief Flag bits used to define ::IFLAGS_BIT_MASKS
*
- * (others are reserved)
- * @{
+ * @see ::IFLAGS_BIT_MASKS
*/
-#define IFLAGS_DISABLE_TFOM 0x0001 /**< RX ignore/TX don't gen TFOM */
-#define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /**< gen local time, not UTC */
+enum IFLAGS_BITS
+{
+ IFLAGS_BIT_DISABLE_TFOM, ///< for RX ignore, for TX don't generate TFOM flag
+ IFLAGS_BIT_TX_GEN_LOCAL_TIME, ///< TX output local time instead of %UTC
+ N_IFLAGS_BITS ///< number of known bits
+};
+
-#define IFLAGS_MASK 0x0003 /**< flags above or'ed */
+/**
+ * @brief Bit masks used with ::IRIG_SETTINGS::flags
+ *
+ * @note The presence or absence of the ::IFLAGS_DISABLE_TFOM flag for the IRIG RX
+ * settings of some PCI cards may not be evaluated correctly by some firmware
+ * versions for those cards, even if an IRIG code has been configured which supports
+ * this flag. See the comments near the declaration of the ::_pcps_incoming_tfom_ignored
+ * macro in pcpsdev.h for details.
+ *
+ * @see ::IFLAGS_BITS
+ */
+enum IFLAGS_BIT_MASKS
+{
+ IFLAGS_DISABLE_TFOM = ( 1UL << IFLAGS_BIT_DISABLE_TFOM ), ///< see ::IFLAGS_BIT_DISABLE_TFOM
+ IFLAGS_TX_GEN_LOCAL_TIME = ( 1UL << IFLAGS_BIT_TX_GEN_LOCAL_TIME ), ///< see ::IFLAGS_BIT_TX_GEN_LOCAL_TIME
-// Note: the presence or absence of the IFLAGS_DISABLE_TFOM flag for the IRIG RX
-// settings of some PCI cards may not be evaluated correctly by some firmware
-// versions for those cards, even if an IRIG code has been configured which supports
-// this flag. See the comments near the declaration of the _pcps_incoming_tfom_ignored()
-// macro in pcpsdev.h for details.
+ IFLAGS_MASK = ( ( 1UL << N_IFLAGS_BITS ) - 1 ) ///< mask of all known flags
+};
-/** @} group_irig_flags */
/**
* @brief Current IRIG settings and supported codes
*
- * Used to query the IRIG current IRIG settings
+ * Used to query the current IRIG settings
* plus a mask of supported codes.
*/
typedef struct
{
- IRIG_SETTINGS settings;
- uint32_t supp_codes; /**< bit mask of supported codes */
+ IRIG_SETTINGS settings; ///< current settings
+ uint32_t supp_codes; ///< see @ref ICODE_TX_MASKS and @ref ICODE_RX_MASKS
+
} IRIG_INFO;
#define _mbg_swab_irig_info( _p ) \
+do \
{ \
_mbg_swab_irig_settings( &(_p)->settings ); \
_mbg_swab32( &(_p)->supp_codes ); \
+} while ( 0 )
+
+
+/**
+ * @defgroup group_irig_comp IRIG input delay compensation
+ *
+ * These definitions are used with IRIG RX delay compensation
+ * which is supported by some IRIG receivers. Delay compensation
+ * depends on the basic frame type, so there are different records
+ * required for the different frame type groups.
+ *
+ * @{ */
+
+/**
+ * The number of coefficients of a compensation record
+ * for a single frame type group, and the structure
+ * which contains those coefficients.
+ */
+#define N_IRIG_RX_COMP_VAL 4
+
+/**
+ * @brief A structure used to store compensation values
+ */
+typedef struct
+{
+ /**
+ * @brief Delay compensation values [100 ns units]
+ *
+ * @note Only the first value is actually used to compensate
+ * a delay, so the remaining values should be 0.
+ */
+ int16_t c[N_IRIG_RX_COMP_VAL];
+
+} IRIG_RX_COMP;
+
+#define _mbg_swab_irig_rx_comp( _p ) \
+do \
+{ \
+ int i; \
+ for ( i = 0; i < N_IRIG_RX_COMP_VAL; i++ ) \
+ _mbg_swab16( &(_p)->c[i] ); \
+} while ( 0 )
+
+
+/** The absolute value of the maximum compensation value accepted by a device */
+#define IRIG_RX_COMP_MAX 999 // [100 ns units], i.e. valid range is +/-99.9 us
+
+
+
+/**
+ * @brief Structure used to retrieve the number of records for a given type
+ */
+typedef struct
+{
+ uint16_t type; ///< record type, see ::CAL_REC_TYPES
+ uint16_t idx; ///< index if several records of same type are supported, see ::IRIG_RX_COMP_GROUPS
+
+} CAL_REC_HDR;
+
+#define _mbg_swab_cal_rec_hdr( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->type ); \
+ _mbg_swab16( &(_p)->idx ); \
+} while ( 0 )
+
+
+/**
+ * @brief Types to be used with ::CAL_REC_HDR::type
+ */
+enum CAL_REC_TYPES
+{
+ CAL_REC_TYPE_UNDEF, ///< undefined type
+ CAL_REC_TYPE_IRIG_RX_COMP, ///< IRIG receiver delay compensation
+ N_CAL_REC_TYPE ///< number of known types
+};
+
+
+/**
+ * @brief Types to be used with ::CAL_REC_HDR::idx
+ *
+ * IRIG frame type groups to be distinguished for delay compensation.
+ */
+enum IRIG_RX_COMP_GROUPS
+{
+ IRIG_RX_COMP_B1, ///< codes B1xx, AFNOR, IEEE1344
+ IRIG_RX_COMP_A1, ///< code A1xx
+ IRIG_RX_COMP_B0, ///< codes B0xx, AFNOR DC, IEEE1344 DC
+ IRIG_RX_COMP_A0, ///< code A0xx
+ IRIG_RX_COMP_G1, ///< code G14x
+ IRIG_RX_COMP_G0, ///< code G00x
+ N_IRIG_RX_COMP ///< number of compensation values
+};
+
+
+/**
+ * @brief Initializers for format name strings
+ */
+#define DEFAULT_IRIG_RX_COMP_NAMES \
+{ \
+ "B1xx/AFNOR/IEEE1344", \
+ "A1xx", \
+ "B0xx/AFNOR DC/IEEE1344 DC", \
+ "A0xx", \
+ "G14X", \
+ "G00X", \
}
-// 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
+/**
+ * @brief Structure used to transfer calibration records
+ */
+typedef struct
{
- MBG_IRIG_BIT_WARMED_UP, /**< Osc has warmed up */
- MBG_IRIG_BIT_PPS_ACTIVE, /**< PPS output is active */
- MBG_IRIG_BIT_INV_CONFIG, /**< Invalid config, e.g. data csum error */
- MBG_IRIG_BIT_MSG_DECODED, /**< IRIG msg could be decoded */
- MBG_IRIG_BIT_MSG_INCONSISTENT, /**< IRIG msg contains inconsistent data */
- MBG_IRIG_BIT_LOOP_LOCKED, /**< Decoder control loop is locked */
- MBG_IRIG_BIT_JITTER_TOO_LARGE, /**< Phase jitter too large */
- MBG_IRIG_BIT_INV_REF_OFFS, /**< UTC ref offset not configured */
+ CAL_REC_HDR hdr; ///< data header
+ IRIG_RX_COMP comp_data; ///< IRIG receiver delay compensation
+
+} CAL_REC_IRIG_RX_COMP;
+
+#define _mbg_swab_cal_rec_irig_rx_comp( _p ) \
+do \
+{ \
+ _mbg_swab_cal_rec_hdr( &(_p)->hdr ); \
+ _mbg_swab_irig_rx_comp( &(_p)->comp_data ); \
+} while ( 0 )
+
+/** @} defgroup group_irig_comp */
+
+
+
+/**
+ * @brief A data type used to read the board's debug status
+ *
+ * @note This also includes IRIG decoder status.
+ *
+ * @see @ref MBG_DEBUG_STATUS_BIT_MASKS
+ */
+typedef uint32_t MBG_DEBUG_STATUS;
+
+#define _mbg_swab_debug_status( _p ) \
+ _mbg_swab32( _p )
- MBG_SYS_BIT_INV_TIME, /**< Internal time not valid/set */
- MBG_SYS_BIT_TIME_SET_VIA_API, /**< On board time set externally */
- MBG_SYS_BIT_INV_RTC, /**< On board RTC invalid */
- MBG_SYS_BIT_CPU_PLL_FAILED, /**< The CPU's PLL watchdog */
- N_MBG_DEBUG_BIT
+
+/**
+ * @brief Enumeration of flag bits used for debug status
+ *
+ * @see @ref MBG_DEBUG_STATUS_BIT_MASKS
+ */
+enum MBG_DEBUG_STATUS_BITS
+{
+ MBG_IRIG_BIT_WARMED_UP, ///< Osc has warmed up
+ MBG_IRIG_BIT_PPS_ACTIVE, ///< PPS output is active
+ MBG_IRIG_BIT_INV_CONFIG, ///< Invalid config, e.g. data csum error
+ MBG_IRIG_BIT_MSG_DECODED, ///< IRIG msg could be decoded
+ MBG_IRIG_BIT_MSG_INCONSISTENT, ///< IRIG msg contains inconsistent data
+ MBG_IRIG_BIT_LOOP_LOCKED, ///< Decoder control loop is locked
+ MBG_IRIG_BIT_JITTER_TOO_LARGE, ///< Phase jitter too large
+ MBG_IRIG_BIT_INV_REF_OFFS, ///< %UTC ref offset not configured
+
+ MBG_SYS_BIT_INV_TIME, ///< Internal time not valid/set
+ MBG_SYS_BIT_TIME_SET_VIA_API, ///< On board time set externally
+ MBG_SYS_BIT_INV_RTC, ///< On board RTC invalid
+ MBG_SYS_BIT_CPU_PLL_FAILED, ///< The CPU's PLL watchdog
+
+ N_MBG_DEBUG_BIT ///< The number of known bits
};
-/*
- * Initializers for IRIG status bit strings.
+/**
+ * @brief Initializers for debug status bit strings
+ *
+ * @see ::MBG_DEBUG_STATUS_BITS
*/
#define MBG_DEBUG_STATUS_STRS \
{ \
@@ -2674,6 +5110,12 @@ enum
}
+/**
+ * @brief Bit masks used with ::MBG_DEBUG_STATUS
+ *
+ * @see ::MBG_DEBUG_STATUS_BITS
+ *
+ * @anchor MBG_DEBUG_STATUS_BIT_MASKS @{ */
#define MBG_IRIG_MSK_WARMED_UP ( 1UL << MBG_IRIG_BIT_WARMED_UP )
#define MBG_IRIG_MSK_PPS_ACTIVE ( 1UL << MBG_IRIG_BIT_PPS_ACTIVE )
@@ -2689,73 +5131,133 @@ enum
#define MBG_SYS_MSK_INV_RTC ( 1UL << MBG_SYS_BIT_INV_RTC )
#define MBG_SYS_MSK_CPU_PLL_FAILED ( 1UL << MBG_SYS_BIT_CPU_PLL_FAILED )
+/** @} anchor MBG_DEBUG_STATUS_BIT_MASKS */
-typedef int16_t MBG_REF_OFFS; /**< -MBG_REF_OFFS_MAX..MBG_REF_OFFS_MAX */
+/**
+ * @brief A data type used to configure the ref offset
+ *
+ * The ref offset if the offset of the incoming reference time from %UTC.
+ * For some types of signal (e.g. most IRIG frame formats) this can't be
+ * determined automatically.
+ *
+ * Valid range: -::MBG_REF_OFFS_MAX..::MBG_REF_OFFS_MAX, or ::MBG_REF_OFFS_NOT_CFGD
+ *
+ * @note There's a special flag ::MBG_REF_OFFS_NOT_CFGD indicating that
+ * this parameter is unconfigured, in which case a Meinberg time code
+ * receiver refuses to synchronize to the time code signal unless a time
+ * code frame has been configured which provides the UTC offset (namely
+ * IEEE 1344 or IEEE C37.118).
+ */
+typedef int16_t MBG_REF_OFFS;
#define _mbg_swab_mbg_ref_offs( _p ) _mbg_swab16( (_p) )
-/** the maximum allowed positive / negative offset */
+/**
+ * @brief The maximum allowed positive / negative ref offset
+ */
#define MBG_REF_OFFS_MAX ( ( 12L * 60 ) + 30 ) // [minutes]
/**
- * the following value is used to indicate that the ref offset
- * value has not yet been configured
+ * @brief A flag indicating that the ref offset has not yet been configured
+ *
+ * If this flag is set in ::MBG_REF_OFFS this means the ref offset
+ * (time offset from %UTC) has not yet been configured. This is usually
+ * the case for IRIG receiver devices right after they have been shipped.
*/
-#define MBG_REF_OFFS_NOT_CFGD 0x8000
+#define MBG_REF_OFFS_NOT_CFGD ( (MBG_REF_OFFS) 0x8000 )
+
+/**
+ * @brief A structure used to configure optional settings
+ *
+ * Optional settings are a generic way to configure some extended settings.
+ */
typedef struct
{
- uint32_t flags;
+ uint32_t flags; ///< @see ::MBG_OPT_FLAGS
+
} MBG_OPT_SETTINGS;
#define _mbg_swab_mbg_opt_settings( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
+/**
+ * @brief A structure used to configure optional settings
+ *
+ * This structure includes the current settings, and a bit mask
+ * indicating which flags are supported.
+ */
typedef struct
{
- MBG_OPT_SETTINGS settings;
- uint32_t supp_flags;
+ MBG_OPT_SETTINGS settings; ///< current settings
+ uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_OPT_FLAGS
+
} MBG_OPT_INFO;
#define _mbg_swab_mbg_opt_info( _p ) \
+do \
{ \
_mbg_swab_mbg_opt_settings( &(_p)->settings ); \
_mbg_swab32( &(_p)->supp_flags ); \
-}
+} while ( 0 )
-enum
+/**
+ * @brief Enumeration of flag bits used to define ::MBG_OPT_FLAGS
+ */
+enum MBG_OPT_BITS
{
- MBG_OPT_BIT_STR_UTC, /**< serial string contains UTC time */
- MBG_OPT_BIT_EMU_SYNC, /**< emulate/pretend to be synchronized, */
- /**< alternatively GPS_FEAT_IGNORE_LOCK may be supported */
+ MBG_OPT_BIT_STR_UTC, ///< serial time string contains %UTC time
+ MBG_OPT_BIT_EMU_SYNC, ///< always pretend to be synchronized, alternatively ::GPS_FEAT_IGNORE_LOCK may be supported
N_MBG_OPT_BIT
};
-/*
- * Bit masks corresponding to the enumeration above:
+
+/**
+ * @brief Bit masks according to ::MBG_OPT_BITS
+ *
+ * Used with ::MBG_OPT_SETTINGS::flags and ::MBG_OPT_INFO::supp_flags.
*/
-#define MBG_OPT_FLAG_STR_UTC ( 1UL << MBG_OPT_BIT_STR_UTC )
-#define MBG_OPT_FLAG_EMU_SYNC ( 1UL << MBG_OPT_BIT_EMU_SYNC )
+enum MBG_OPT_FLAGS
+{
+ MBG_OPT_FLAG_STR_UTC = ( 1UL << MBG_OPT_BIT_STR_UTC ), ///< see ::MBG_OPT_BIT_STR_UTC
+ MBG_OPT_FLAG_EMU_SYNC = ( 1UL << MBG_OPT_BIT_EMU_SYNC ) ///< see ::MBG_OPT_BIT_EMU_SYNC
+};
-// bit coded return type for PCPS_GET_IRIG_CTRL_BITS
-typedef uint32_t MBG_IRIG_CTRL_BITS;
+/**
+ * @brief Bit coded return type for ::PCPS_GET_IRIG_CTRL_BITS
+ *
+ * The control bits a time code receiver has decoded from
+ * the incoming time code signal.
+ *
+ * @note ::MBG_RAW_IRIG_DATA is more versatile and should
+ * be used preferably, if supported.
+ *
+ * @see ::MBG_RAW_IRIG_DATA
+ */
+typedef uint32_t MBG_IRIG_CTRL_BITS;
#define _mbg_swab_irig_ctrl_bits( _p ) _mbg_swab32( _p )
-// The following macro extracts the 4 bit TFOM code from the
-// IRIG control bits read from a card. This only works if the received
-// IRIG code is a code which supports TFOM, this is currently
-// only IEEE1344.
+/**
+ * @brief Extract the TFOM code from ::MBG_IRIG_CTRL_BITS
+ *
+ * The resulting code is only valid if the configured IRIG code frame format
+ * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM
+ *
+ * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is
+ * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable).
+ */
#define _pcps_tfom_from_irig_ctrl_bits( _p ) \
( ( ( *(_p) ) >> 24 ) & 0x0F )
@@ -2764,24 +5266,33 @@ typedef uint32_t MBG_IRIG_CTRL_BITS;
#define RAW_IRIG_SIZE 16
/**
- The buffer below can be used to get the raw data bits
- from the IRIG decoder. A maximum number of RAW_IRIG_SIZE
- bytes can be filled. If less bytes are used then the rest
- of the bytes are filled with zeros.
-
- The first IRIG bit received from the transmitter is saved
- in the MSB (bit 7) of data_bytes[0], etc.
-*/
+ * @brief A buffer used to read raw IRIG data bits from an IRIG receiver
+ *
+ * Used to get the raw data bits from the IRIG decoder. A maximum number
+ * of ::RAW_IRIG_SIZE bytes can be filled up, depending on the IRIG code.
+ * If less bytes are used then the rest of the bytes are filled with zeros.
+ *
+ * @note The first IRIG bit received from the transmitter is saved
+ * in the MSB (bit 7) of data_bytes[0], etc.
+ */
typedef struct
{
uint8_t data_bytes[RAW_IRIG_SIZE];
+
} MBG_RAW_IRIG_DATA;
-// The following macro extracts the 4 bit TFOM code from the raw
-// data bits read from a card. This only works if the received
-// IRIG code is a code which supports TFOM, this is currently
-// only IEEE1344.
-#define _pcps_tfom_from_raw_irig_data( _p ) \
+#define _mbg_swab_mbg_raw_irig_data( _p ) _nop_macro_fnc()
+
+/**
+ * @brief Extract the TFOM code from ::MBG_RAW_IRIG_DATA
+ *
+ * The resulting code is only valid if the configured IRIG code frame format
+ * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM
+ *
+ * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is
+ * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable).
+ */
+#define _pcps_tfom_from_raw_irig_data( _p ) \
( ( ( (_p)->data_bytes[9] >> 2 ) & 0x08 ) \
| ( ( (_p)->data_bytes[9] >> 4 ) & 0x04 ) \
| ( ( (_p)->data_bytes[9] >> 6 ) & 0x02 ) \
@@ -2790,32 +5301,43 @@ typedef struct
/**
- @defgroup group_time_scale Time Scale Configuration
-
- The structures and defines can be used to configure the GPS receiver's
- basic time scale. By default this is UTC which can optionally
- be converted to some local time. However, some applications
- prefer TAI or pure GPS time. This can be configured using the
- structures below if the GPS_HAS_TIME_SCALE flag is set in
- RECEIVER_INFO::features.
- @{
-*/
+ * @defgroup group_time_scale Time Scale Configuration
+ *
+ * Used to configure the GPS receiver's basic time scale.
+ * By default this is %UTC which can optionally be converted
+ * to some local time. However, some applications prefer
+ * TAI or pure GPS time. This can be configured using the
+ * structures below if the ::GPS_HAS_TIME_SCALE flag is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @{ */
-enum
+/**
+ * @brief Known time scales
+ *
+ * @see ::MBG_TIME_SCALE_MASKS
+ * @see ::TM_SCALE_GPS
+ * @see ::TM_SCALE_TAI
+ */
+enum MBG_TIME_SCALES
{
- MBG_TIME_SCALE_DEFAULT, /**< UTC or local time, t_gps - deltat_ls */
- MBG_TIME_SCALE_GPS, /**< GPS time, monotonical */
- MBG_TIME_SCALE_TAI, /**< TAI, t_gps + GPS_TAI_OFFSET seconds */
+ MBG_TIME_SCALE_DEFAULT, ///< %UTC or local time according to ::UTC parameters and ::TZDL configuration
+ MBG_TIME_SCALE_GPS, ///< GPS time as sent by the satellites, monotonical
+ MBG_TIME_SCALE_TAI, ///< TAI, i.e. GPS time plus constant offset (see ::GPS_TAI_OFFSET)
N_MBG_TIME_SCALE
};
-#define MBG_TIME_SCALE_MSK_DEFAULT ( 1UL << MBG_TIME_SCALE_DEFAULT )
-#define MBG_TIME_SCALE_MSK_GPS ( 1UL << MBG_TIME_SCALE_GPS )
-#define MBG_TIME_SCALE_MSK_TAI ( 1UL << MBG_TIME_SCALE_TAI )
-
-// See also the extended status bits TM_SCALE_GPS and TM_SCALE_TAI
-// indicating the active time scale setting.
-
+/**
+ * @brief Bit masks for known time scales
+ *
+ * @see ::MBG_TIME_SCALES
+ */
+enum MBG_TIME_SCALE_MASKS
+{
+ MBG_TIME_SCALE_MSK_DEFAULT = ( 1UL << MBG_TIME_SCALE_DEFAULT ), ///< see ::MBG_TIME_SCALE_DEFAULT
+ MBG_TIME_SCALE_MSK_GPS = ( 1UL << MBG_TIME_SCALE_GPS ), ///< see ::MBG_TIME_SCALE_GPS
+ MBG_TIME_SCALE_MSK_TAI = ( 1UL << MBG_TIME_SCALE_TAI ) ///< see ::MBG_TIME_SCALE_TAI
+};
#define MBG_TIME_SCALE_STRS \
{ \
@@ -2827,70 +5349,87 @@ enum
/**
- The fixed time offset between the GPS and TAI time scales, in seconds
-*/
-#define GPS_TAI_OFFSET 19 /**< [s], TAI = GPS + GPS_TAI_OFFSET */
+ * @brief The constant time offset between the GPS and TAI time scales, in seconds
+ */
+#define GPS_TAI_OFFSET 19 ///< [s], TAI = GPS + GPS_TAI_OFFSET
+/**
+ * @brief Time scale configuration settings
+ */
typedef struct
{
- uint8_t scale; /**< current time scale code from the enum above */
- uint8_t flags; /**< reserved, currently always 0 */
+ uint8_t scale; ///< current time scale code, see ::MBG_TIME_SCALES
+ uint8_t flags; ///< reserved, don't use, currently always 0
+
} MBG_TIME_SCALE_SETTINGS;
#define _mbg_swab_mbg_time_scale_settings( _p ) \
_nop_macro_fnc()
+/**
+ * @brief Time scale configuration settings plus capabilities
+ */
typedef struct
{
- MBG_TIME_SCALE_SETTINGS settings; /**< current settings */
- MBG_TIME_SCALE_SETTINGS max_settings; /**< numb. of scales, all supported flags */
- uint32_t supp_scales; /**< bit masks of supported scales */
+ MBG_TIME_SCALE_SETTINGS settings; ///< current settings
+ MBG_TIME_SCALE_SETTINGS max_settings; ///< number of scales, all supported flags
+ uint32_t supp_scales; ///< bit masks of supported scales, see ::MBG_TIME_SCALE_MASKS
+
} MBG_TIME_SCALE_INFO;
#define _mbg_swab_mbg_time_scale_info( _p ) \
+do \
{ \
_mbg_swab_mbg_time_scale_settings( &(_p)->settings ); \
_mbg_swab_mbg_time_scale_settings( &(_p)->max_settings ); \
_mbg_swab32( &(_p)->supp_scales ); \
-}
+} while ( 0 )
-/** @} group_time_scale */
+/** @} defgroup group_time_scale */
-/*
- * The structures below are required to setup the programmable
+
+/**
+ * @defgroup group_pout_api Programmable Output API
+ *
+ * These structures below are used to configure the programmable
* pulse outputs which are provided by some GPS receivers.
* The number of programmable pulse outputs supported by a GPS
- * receiver is reported in the RECEIVER_INFO.n_str_type field.
- */
+ * receiver is reported in the RECEIVER_INFO::n_prg_out field.
+ *
+ * @{ */
+
/**
- * The structure is used to define a date of year:
+ * @brief A calendar date including full year number
*/
typedef struct
{
- uint8_t mday; /* 1..28,29,30,31 */
- uint8_t month; /* 1..12 */
- uint16_t year; /* including century */
+ uint8_t mday; ///< 1..28,29,30,31
+ uint8_t month; ///< 1..12
+ uint16_t year; ///< including century
+
} MBG_DATE;
#define _mbg_swab_mbg_date( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->year ); \
-}
+} while ( 0 )
/**
- * The structure is used to define a time of day:
+ * @brief The time of day including hundredths of seconds
*/
typedef struct
{
- uint8_t hour; /**< 0..23 */
- uint8_t min; /**< 0..59 */
- uint8_t sec; /**< 0..59,60 */
- uint8_t sec100; /**< reserved, currently always 0 */
+ uint8_t hour; ///< 0..23
+ uint8_t min; ///< 0..59
+ uint8_t sec; ///< 0..59,60
+ uint8_t sec100; ///< 100ths of seconds
+
} MBG_TIME;
#define _mbg_swab_mbg_time( _p ) \
@@ -2898,107 +5437,490 @@ typedef struct
/**
- * The structure defines a single date and time
- * for switching operations:
+ * @brief Date and time specification for switching operations
*/
typedef struct
{
- MBG_DATE d; /* date to switch */
- MBG_TIME t; /* time to switch */
- uint8_t wday; /* reserved, currently always 0 */
- uint8_t flags; /* reserved, currently 0 */
+ MBG_DATE d; ///< date to switch
+ MBG_TIME t; ///< time to switch
+ uint8_t wday; ///< reserved, currently always 0
+ uint8_t flags; ///< reserved, currently 0
+
} MBG_DATE_TIME;
#define _mbg_swab_mbg_date_time( _p ) \
+do \
{ \
_mbg_swab_mbg_date( &(_p)->d ); \
_mbg_swab_mbg_time( &(_p)->t ); \
-}
+} while ( 0 )
/**
- * The structure defines times and dates
- * for an on/off cycle:
+ * @brief A structure to define on/off cycle times
+ *
+ * @note The ::MBG_TIME::sec100 field in ::POUT_TIME:on and
+ * ::POUT_TIME:off is not evaluated by the firmware and thus
+ * should always be set to 0.
*/
typedef struct
{
- MBG_DATE_TIME on; /* time and date to switch on */
- MBG_DATE_TIME off; /* time and date to switch off */
+ MBG_DATE_TIME on; ///< date and time to switch on
+ MBG_DATE_TIME off; ///< date and time to switch off
+
} POUT_TIME;
#define _mbg_swab_pout_time( _p ) \
+do \
{ \
_mbg_swab_mbg_date_time( &(_p)->on ); \
_mbg_swab_mbg_date_time( &(_p)->off ); \
-}
+} while ( 0 )
+
+
+
+/**
+ * @brief The number of ::POUT_TIME settings for each programmable pulse output
+ *
+ * @note This can't be changed without breaking compatibility of the API
+ */
+#define N_POUT_TIMES 3
+
+/**
+ * @brief A Generic data field for programmable output settings
+ */
+typedef union
+{
+ /// Switching times. See ::POUT_MODES_DATA_TM, ::POUT_MODES_DATA_TM_0
+ POUT_TIME tm[N_POUT_TIMES];
+
+ uint8_t b[N_POUT_TIMES * sizeof( POUT_TIME )];
+
+ /// Only if ::POUT_SUPP_PULSE_SHIFT is set, this field can be used to
+ /// configure the time interval in [ns] by which output pulse slopes are
+ /// to be shifted. The configured pulse shift must be in the range
+ /// ::DEFAULT_POUT_PULSE_SHIFT_MIN through ::DEFAULT_POUT_PULSE_SHIFT_MAX.
+ /// The resolution / steps at which the pulse shift interval can be configured
+ /// is returned in ::POUT_INFO::pulse_shift_res.
+ /// @see ::POUT_MODES_DATA_PULSE_SHIFT
+ int32_t pulse_shift;
+
+} POUT_DATA;
+
+#define DEFAULT_POUT_PULSE_SHIFT_MIN -500000000L ///< Default minimum value for ::POUT_DATA::pulse_shift, in [ns]
+#define DEFAULT_POUT_PULSE_SHIFT_MAX 499000000L ///< Default maximum value for ::POUT_DATA::pulse_shift, in [ns]
/**
- * The number of POUT_TIMEs for each programmable pulse output
+ * @brief Convert ::POUT_DATA endianess depending on the mode
+ *
+ * Assuming the mode is passed to the macro with correct endianess.
*/
-#define N_POUT_TIMES 3
+#define _mbg_swab_pout_data( _p, _mode ) \
+do \
+{ \
+ uint32_t mode_mask = 1UL << _mode; \
+ \
+ if ( mode_mask & POUT_MODES_DATA_TM ) \
+ { \
+ int i; \
+ \
+ for ( i = 0; i < N_POUT_TIMES; i++ ) \
+ _mbg_swab_pout_time( &(_p)->tm[i] ); \
+ } \
+ else \
+ { \
+ if ( mode_mask & POUT_MODES_DATA_TM_0 ) \
+ _mbg_swab_pout_time( &(_p)->tm[0] ); \
+ else \
+ if ( mode_mask & POUT_MODES_DATA_PULSE_SHIFT ) \
+ _mbg_swab32( &(_p)->pulse_shift ); \
+ } \
+ \
+} while ( 0 )
+
+
/**
- * The structure is used to configure a single programmable
- * pulse output.
+ * @brief Configuration settings for a single programmable pulse output
*/
typedef struct
{
- uint16_t mode; /**< mode of operation, codes defined below */
- uint16_t pulse_len; /**< 10 msec units, or COM port number */
- uint16_t timeout; /**< [min], for dcf_mode */
- uint16_t flags; /**< see below */
- POUT_TIME tm[N_POUT_TIMES]; /**< switching times */
+ uint16_t mode; ///< Mode of operation, see ::POUT_MODES
+ uint16_t mode_param; ///< Optional parameter depending on the mode, see @ref POUT_MODES_PARAM_MASKS
+
+ /// Timeout [min] which can be specified for some modes, see ::POUT_MODES_TIMEOUT, ::MAX_POUT_DCF_TIMOUT.
+ ///
+ /// If the clock looses synchronization then the output
+ /// - is disabled **immediately** if ::POUT_IF_SYNC_ONLY is set in ::POUT_SETTINGS::flags
+ /// - is disabled after ::POUT_SETTINGS::timeout, if timeout is not 0 (see ::MAX_POUT_DCF_TIMOUT)
+ /// - stays enabled if timeout is 0 **and** ::POUT_IF_SYNC_ONLY is **not** set
+ uint16_t timeout;
+
+ uint16_t flags; ///< @see ::POUT_SETTINGS_FLAGS
+ POUT_DATA pout_data; ///< Additional configuration data, see ::POUT_DATA
+
} POUT_SETTINGS;
-#define _mbg_swab_pout_settings( _p ) \
-{ \
- int i; \
- _mbg_swab16( &(_p)->mode ); \
- _mbg_swab16( &(_p)->pulse_len ); \
- _mbg_swab32( &(_p)->timeout ); \
- _mbg_swab16( &(_p)->flags ); \
- \
- for ( i = 0; i < N_POUT_TIMES; i++ ) \
- _mbg_swab_pout_time( &(_p)->tm[i] ); \
-}
+/**
+ * @brief Convert ::POUT_SETTINGS endianess after reading from a device
+ */
+#define _mbg_swab_pout_settings_on_get( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->mode_param ); \
+ _mbg_swab16( &(_p)->timeout ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \
+} while ( 0 )
+
+/**
+ * @brief Convert ::POUT_SETTINGS endianess before writing to a device
+ */
+#define _mbg_swab_pout_settings_on_set( _p ) \
+do \
+{ \
+ _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \
+ _mbg_swab16( &(_p)->mode ); \
+ _mbg_swab16( &(_p)->mode_param ); \
+ _mbg_swab16( &(_p)->timeout ); \
+ _mbg_swab16( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Definitions used with ::POUT_TIME_SLOTS mode
+ *
+ * If ::POUT_SETTINGS::mode is set to ::POUT_TIME_SLOTS then the number
+ * of time slots per minute is stored in ::POUT_SETTINGS::mode_param.
+ * Valid numbers are all numbers n in the range ::MIN_TIME_SLOTS_PER_MINUTE
+ * to ::MAX_TIME_SLOTS_PER_MINUTE for which the remainder of 60 / n is 0.
+ * @see ::POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN
+ *
+ * @anchor POUT_TIME_SLOTS_MODE_DEFS @{ */
+
+#define MIN_TIME_SLOTS_PER_MINUTE 1
+#define MAX_TIME_SLOTS_PER_MINUTE 60
+#define TIME_SLOT_REGISTER_IN_SEC 60
+
+#define TIMEOUT_DIVIDED_BY 10
+#define TIME_SLOT_SWITCH_OFF_BUFFER_MIN 50 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_MAX 500 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_STD 500 / TIMEOUT_DIVIDED_BY
+#define TIME_SLOT_SWITCH_OFF_BUFFER_STEP_SIZE 50 / TIMEOUT_DIVIDED_BY
+
+#define _valid_time_slots_per_minute( _n ) \
+ ( ( (_n) >= MIN_TIME_SLOTS_PER_MINUTE ) && \
+ ( (_n) <= MAX_TIME_SLOTS_PER_MINUTE ) && \
+ ( ( 60 % (_n) ) == 0 ) \
+ )
+
+/** @} anchor POUT_TIME_SLOTS_MODE_DEFS */
+
-#define MAX_POUT_PULSE_LEN 1000 /**< 10 secs, in 10 msec units */
-#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) /**< 48 hours, in minutes */
+#define MAX_POUT_PULSE_LEN 1000 ///< 10 secs, in 10 msec units
+#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) ///< 48 hours, in minutes
+
/**
- * These codes are defined for POUT_SETTINGS.mode to setup
- * the basic mode of operation for a single programmable pulse
- * output:
+ * @brief Enumeration of known operation modes for programmable pulse outputs
+ *
+ * These codes are used with ::POUT_SETTINGS::mode. One or more of
+ * the remaining fields in ::POUT_SETTINGS are evaluated depending
+ * on the selected mode. Unused fields should be set to 0.
+ *
+ * Unless ::POUT_NOT_INVERTIBLE is set in ::POUT_INFO::flags
+ * the output signal level can be inverted if ::POUT_INVERTED
+ * is set in ::POUT_SETTINGS::flags.
+ *
+ * @note Not every programmable pulse output supports all modes.
+ *
+ * @see @ref POUT_MODE_MASKS
+ * @see @ref POUT_MODES_PARAM_MASKS
+ * @see @ref ENG_POUT_NAMES
+ * @see @ref ENG_POUT_HINTS
*/
-enum
+enum POUT_MODES
{
- POUT_IDLE, /**< always off, or on if POUT_INVERTED */
- POUT_TIMER, /**< switch on/off at configured times */
- POUT_SINGLE_SHOT, /**< pulse at time POUT_SETTINGS.tm[0].on */
- POUT_CYCLIC_PULSE, /**< pulse every POUT_SETTINGS.tm[0].on.t interval */
- POUT_PER_SEC, /**< pulse if second changes */
- POUT_PER_MIN, /**< pulse if minute changes */
- POUT_PER_HOUR, /**< pulse if hour changes */
- POUT_DCF77, /**< emulate DCF77 signal */
- POUT_POS_OK, /**< on if pos. OK (nav_solved) */
- POUT_TIME_SYNC, /**< on if time sync (time_syn) */
- POUT_ALL_SYNC, /**< on if pos. OK and time sync */
- POUT_TIMECODE, /**< IRIG/AFNOR DCLS output */
- POUT_TIMESTR, /**< COM port number in pulse_len field */
- POUT_10MHZ, /**< 10 MHz fixed frequency */
- POUT_DCF77_M59, /**< DCF77-like signal with 500 ms pulse in 59th second */
- POUT_SYNTH, /**< programmable synthesizer frequency */
- N_POUT_MODES
+ /// Output is normally always 'off', or always 'on', if flag ::POUT_INVERTED is set.
+ POUT_IDLE,
+
+ /// Switch 'on' or 'off' at the times specified in ::POUT_DATA::tm.
+ POUT_TIMER,
+
+ /// Generate a pulse at the time specified in ::POUT_SETTINGS::pout_data::tm[0]::on.
+ /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
+ /// See ::MAX_POUT_PULSE_LEN.
+ POUT_SINGLE_SHOT,
+
+ /// Generate a cyclic pulse at the interval specified in ::POUT_SETTINGS::pout_data::tm[0]:on::t.
+ /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
+ /// See ::MAX_POUT_PULSE_LEN.
+ POUT_CYCLIC_PULSE,
+
+ /// Generate a pulse whenever the second changes.
+ /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
+ /// See ::MAX_POUT_PULSE_LEN.
+ POUT_PER_SEC,
+
+ /// Generate a pulse whenever the minute changes.
+ /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
+ /// See ::MAX_POUT_PULSE_LEN.
+ POUT_PER_MIN,
+
+ /// Generate a pulse whenever the hour changes.
+ /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
+ /// See ::MAX_POUT_PULSE_LEN.
+ POUT_PER_HOUR,
+
+ /// Generate DCF77-compatible second marks.
+ /// See ::POUT_DCF77_M59, ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT.
+ POUT_DCF77,
+
+ /// Output switched on if receiver position verified (condition nav_solved).
+ POUT_POS_OK,
+
+ /// Output switched on if time synchronized (condition time_syn).
+ POUT_TIME_SYNC,
+
+ /// Output switched on if both position verified and time synchronized.
+ POUT_ALL_SYNC,
+
+ /// IRIG/AFNOR DCLS time code signal mapped to this output.
+ POUT_TIMECODE,
+
+ /// Serial time string of one one of the serial ports mapped to this output.
+ /// ::POUT_SETTINGS::mode_param contains the number of the COM port.
+ /// See ::MAX_POUT_TIMESTR_PORTS.
+ POUT_TIMESTR,
+
+ /// 10 MHz fixed frequency output.
+ POUT_10MHZ,
+
+ /// DCF77-like signal with extra 500 ms pulse in the 59th second
+ /// (the original DCF77 signal has no such pulse). See ::POUT_DCF77,
+ /// ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT.
+ POUT_DCF77_M59,
+
+ /// Output signal generated by the programmable frequency synthesizer.
+ POUT_SYNTH,
+
+ /// Programmable time slots during each minute.
+ /// ::POUT_SETTINGS::mode_param specifies the time slots per minute.
+ /// Uses ::POUT_DATA. ::TODO
+ POUT_TIME_SLOTS,
+
+ /// A GPIO input or output signal is reflected at this pulse output.
+ /// ::POUT_SETTINGS::mode_param specifies the GPIO number which must
+ /// be in the range 0..::MBG_GPIO_CFG_LIMITS::num_io.
+ POUT_GPIO,
+
+ /// A 1 PPS signal with a fixed 20 us pulse length
+ POUT_PTTI_PPS,
+
+ /// A HaveQuick signal as configured in ::HAVEQUICK_SETTINGS::format
+ POUT_HAVEQUICK,
+
+ // New modes have to be added here at the end of the enumeration, and the
+ // POUT_MODE_MASKS, the POUT_MODES_PARAM_MASKS as well as string initializers
+ // (also in pcpslstr.h) have to be updated accordingly.
+ N_POUT_MODES ///< the number of known modes
};
-/*
- * Default initializers for English pulse mode names. Initializers
- * for multi-language strings can be found in pcpslstr.h.
+/**
+ * @brief Bit masks associated with ::POUT_MODES
+ *
+ * Used with ::POUT_INFO::supp_modes to specify which ::POUT_MODES
+ * are supported for a particular programmable output.
+ *
+ * @see ::POUT_MODES
+ *
+ * @anchor POUT_MODE_MASKS @{ */
+
+#define MSK_POUT_IDLE ( 1UL << POUT_IDLE ) ///< see ::POUT_IDLE
+#define MSK_POUT_TIMER ( 1UL << POUT_TIMER ) ///< see ::POUT_TIMER
+#define MSK_POUT_SINGLE_SHOT ( 1UL << POUT_SINGLE_SHOT ) ///< see ::POUT_SINGLE_SHOT
+#define MSK_POUT_CYCLIC_PULSE ( 1UL << POUT_CYCLIC_PULSE ) ///< see ::POUT_CYCLIC_PULSE
+#define MSK_POUT_PER_SEC ( 1UL << POUT_PER_SEC ) ///< see ::POUT_PER_SEC
+#define MSK_POUT_PER_MIN ( 1UL << POUT_PER_MIN ) ///< see ::POUT_PER_MIN
+#define MSK_POUT_PER_HOUR ( 1UL << POUT_PER_HOUR ) ///< see ::POUT_PER_HOUR
+#define MSK_POUT_DCF77 ( 1UL << POUT_DCF77 ) ///< see ::POUT_DCF77
+#define MSK_POUT_POS_OK ( 1UL << POUT_POS_OK ) ///< see ::POUT_POS_OK
+#define MSK_POUT_TIME_SYNC ( 1UL << POUT_TIME_SYNC ) ///< see ::POUT_TIME_SYNC
+#define MSK_POUT_ALL_SYNC ( 1UL << POUT_ALL_SYNC ) ///< see ::POUT_ALL_SYNC
+#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE ) ///< see ::POUT_TIMECODE
+#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR ) ///< see ::POUT_TIMESTR
+#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ ) ///< see ::POUT_10MHZ
+#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 ) ///< see ::POUT_DCF77_M59
+#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH ) ///< see ::POUT_SYNTH
+#define MSK_POUT_TIME_SLOTS ( 1UL << POUT_TIME_SLOTS ) ///< see ::POUT_TIME_SLOTS
+#define MSK_POUT_GPIO ( 1UL << POUT_GPIO ) ///< see ::POUT_GPIO
+#define MSK_POUT_PTTI_PPS ( 1UL << POUT_PTTI_PPS ) ///< see ::POUT_PTTI_PPS
+#define MSK_POUT_HAVEQUICK ( 1UL << POUT_HAVEQUICK ) ///< see ::POUT_HAVEQUICK
+
+/** @} anchor POUT_MODE_MASKS */
+
+
+
+/**
+ * @brief Bit masks indicating which parameters relevant for which ::POUT_MODES
+ *
+ * @see ::POUT_MODES
+ * @see @ref POUT_MODE_MASKS
+ *
+ * @anchor POUT_MODES_PARAM_MASKS @{ */
+
+
+/**
+ * @brief POUT modes which use the full ::POUT_DATA::tm array as parameter
+ */
+#define POUT_MODES_DATA_TM \
+( \
+ MSK_POUT_TIMER \
+)
+
+
+/**
+ * @brief POUT modes which use only ::POUT_DATA::tm[0] as parameter
+ */
+#define POUT_MODES_DATA_TM_0 \
+( \
+ MSK_POUT_SINGLE_SHOT | \
+ MSK_POUT_CYCLIC_PULSE \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_SETTINGS::mode_param as pulse length
+ *
+ * @see ::MAX_POUT_PULSE_LEN
+ */
+#define POUT_MODES_MODE_PARAM_AS_PULSE_LEN \
+( \
+ MSK_POUT_SINGLE_SHOT | \
+ MSK_POUT_CYCLIC_PULSE | \
+ MSK_POUT_PER_SEC | \
+ MSK_POUT_PER_MIN | \
+ MSK_POUT_PER_HOUR \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_SETTINGS::mode_param as COM port index number
+ */
+#define POUT_MODES_MODE_PARAM_AS_COM_IDX \
+( \
+ MSK_POUT_TIMESTR \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_SETTINGS::mode_param as time slots per minute
+ *
+ * @see @ref POUT_TIME_SLOTS_MODE_DEFS
+ */
+#define POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN \
+( \
+ MSK_POUT_TIME_SLOTS \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_SETTINGS::mode_param as GPIO index number
+ */
+#define POUT_MODES_MODE_PARAM_AS_GPIO_IDX \
+( \
+ MSK_POUT_GPIO \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_SETTINGS::timeout
+ */
+#define POUT_MODES_TIMEOUT \
+( \
+ MSK_POUT_DCF77 | \
+ MSK_POUT_DCF77_M59 \
+)
+
+
+/**
+ * @brief POUT modes which which support ::POUT_TIMEBASE_UTC
+ */
+#define POUT_MODES_SUPP_TIMEBASE_UTC \
+( \
+ MSK_POUT_DCF77 | \
+ MSK_POUT_DCF77_M59 \
+)
+
+
+/**
+ * @brief POUT modes which use ::POUT_DATA::pulse_shift
+ *
+ * @note: Supported only if ::POUT_SUPP_PULSE_SHIFT is set
+ */
+#define POUT_MODES_DATA_PULSE_SHIFT \
+( \
+ MSK_POUT_PER_SEC | \
+ MSK_POUT_PER_MIN | \
+ MSK_POUT_PER_HOUR \
+)
+
+
+/**
+ * @brief POUT modes which support ::POUT_SUPP_IF_SYNC_ONLY
+ *
+ * Even if ::POUT_SUPP_IF_SYNC_ONLY is set in ::POUT_INFO::flags
+ * the associated flag ::POUT_IF_SYNC_ONLY in ::POUT_SETTINGS::flags
+ * may be evaluated depending on the mode.
+ *
+ * Modes ::POUT_POS_OK, ::POUT_TIME_SYNC, and ::MSK_POUT_ALL_SYNC
+ * are explicitly excluded.
+ *
+ * For modes ::MSK_POUT_DCF77 and ::MSK_POUT_DCF77_M59 see also
+ * ::POUT_SETTINGS::timeout.
*/
+#define POUT_MODES_SUPP_IF_SYNC_ONLY \
+( \
+ MSK_POUT_IDLE | \
+ MSK_POUT_TIMER | \
+ MSK_POUT_SINGLE_SHOT | \
+ MSK_POUT_CYCLIC_PULSE | \
+ MSK_POUT_PER_SEC | \
+ MSK_POUT_PER_MIN | \
+ MSK_POUT_PER_HOUR | \
+ MSK_POUT_DCF77 | \
+ MSK_POUT_TIMECODE | \
+ MSK_POUT_TIMESTR | \
+ MSK_POUT_10MHZ | \
+ MSK_POUT_DCF77_M59 | \
+ MSK_POUT_SYNTH | \
+ MSK_POUT_TIME_SLOTS | \
+ MSK_POUT_GPIO | \
+ MSK_POUT_PTTI_PPS | \
+ MSK_POUT_HAVEQUICK \
+)
+
+/** @} anchor POUT_MODES_PARAM_MASKS */
+
+
+
+/**
+ * @brief Name strings associated with ::POUT_MODES
+ *
+ * Default initializers for English programmable output mode names.
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::POUT_MODES
+ * @see ::DEFAULT_ENG_POUT_NAMES
+ *
+ * @anchor ENG_POUT_NAMES @{ */
+
#define ENG_POUT_NAME_IDLE "Idle"
#define ENG_POUT_NAME_TIMER "Timer"
#define ENG_POUT_NAME_SINGLE_SHOT "Single Shot"
@@ -3011,11 +5933,24 @@ enum
#define ENG_POUT_NAME_TIME_SYNC "Time Sync"
#define ENG_POUT_NAME_ALL_SYNC "All Sync"
#define ENG_POUT_NAME_TIMECODE "DCLS Time Code"
-#define ENG_POUT_NAME_TIMESTR "COM Time String"
+#define ENG_POUT_NAME_TIMESTR "Serial Time String"
#define ENG_POUT_NAME_10MHZ "10 MHz Frequency"
#define ENG_POUT_NAME_DCF77_M59 "DCF77-like M59"
#define ENG_POUT_NAME_SYNTH "Synthesizer Frequency"
+#define ENG_POUT_NAME_TIME_SLOTS "Time Slots per Minute"
+#define ENG_POUT_NAME_GPIO "GPIO Signal"
+#define ENG_POUT_PTTI_PPS "PTTI 1 PPS"
+#define ENG_POUT_HAVEQUICK "HaveQuick"
+
+/** @} anchor ENG_POUT_NAMES */
+
+
+/**
+ * @brief An initializer for a table of English POUT name strings
+ *
+ * @see @ref ENG_POUT_NAMES
+ */
#define DEFAULT_ENG_POUT_NAMES \
{ \
ENG_POUT_NAME_IDLE, \
@@ -3033,10 +5968,25 @@ enum
ENG_POUT_NAME_TIMESTR, \
ENG_POUT_NAME_10MHZ, \
ENG_POUT_NAME_DCF77_M59, \
- ENG_POUT_NAME_SYNTH \
+ ENG_POUT_NAME_SYNTH, \
+ ENG_POUT_NAME_TIME_SLOTS, \
+ ENG_POUT_NAME_GPIO, \
+ ENG_POUT_PTTI_PPS, \
+ ENG_POUT_HAVEQUICK \
}
+/**
+ * @brief Hint strings associated with ::POUT_MODES
+ *
+ * Default initializers for English programmable output mode hints.
+ * Initializers for multi-language strings can be found in pcpslstr.h.
+ *
+ * @see ::POUT_MODES
+ * @see ::DEFAULT_ENG_POUT_HINTS
+ *
+ * @anchor ENG_POUT_HINTS @{ */
+
#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"
@@ -3053,7 +6003,19 @@ enum
#define ENG_POUT_HINT_10MHZ "10 MHz fixed output frequency"
#define ENG_POUT_HINT_DCF77_M59 "DCF77 time marks with 500 ms pulse in 59th second"
#define ENG_POUT_HINT_SYNTH "Frequency generated by programmable synthesizer"
+#define ENG_POUT_HINT_TIME_SLOTS "Output enabled during specified time slots per minute"
+#define ENG_POUT_HINT_GPIO "Duplicated signal of the specified GPIO input or output"
+#define ENG_POUT_HINT_PTTI_PPS "Generate 20us Pulse at beginning of the second"
+#define ENG_POUT_HINT_HAVEQUICK "Duplicated HaveQuick Signal"
+/** @} anchor ENG_POUT_HINTS */
+
+
+/**
+ * @brief An initializer for a table of English POUT hint strings
+ *
+ * @see @ref ENG_POUT_HINTS
+ */
#define DEFAULT_ENG_POUT_HINTS \
{ \
ENG_POUT_HINT_IDLE, \
@@ -3071,145 +6033,278 @@ enum
ENG_POUT_HINT_TIMESTR, \
ENG_POUT_HINT_10MHZ, \
ENG_POUT_HINT_DCF77_M59, \
- ENG_POUT_HINT_SYNTH \
+ ENG_POUT_HINT_SYNTH, \
+ ENG_POUT_HINT_TIME_SLOTS, \
+ ENG_POUT_HINT_GPIO, \
+ ENG_POUT_HINT_PTTI_PPS, \
+ ENG_POUT_HINT_HAVEQUICK \
}
-/*
- * The definitions below are used to set up bit masks
- * which restrict the modes which can be used with
- * a given programmable output:
- */
-#define MSK_POUT_IDLE ( 1UL << POUT_IDLE )
-#define MSK_POUT_TIMER ( 1UL << POUT_TIMER )
-#define MSK_POUT_SINGLE_SHOT ( 1UL << POUT_SINGLE_SHOT )
-#define MSK_POUT_CYCLIC_PULSE ( 1UL << POUT_CYCLIC_PULSE )
-#define MSK_POUT_PER_SEC ( 1UL << POUT_PER_SEC )
-#define MSK_POUT_PER_MIN ( 1UL << POUT_PER_MIN )
-#define MSK_POUT_PER_HOUR ( 1UL << POUT_PER_HOUR )
-#define MSK_POUT_DCF77 ( 1UL << POUT_DCF77 )
-#define MSK_POUT_POS_OK ( 1UL << POUT_POS_OK )
-#define MSK_POUT_TIME_SYNC ( 1UL << POUT_TIME_SYNC )
-#define MSK_POUT_ALL_SYNC ( 1UL << POUT_ALL_SYNC )
-#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE )
-#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR )
-#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ )
-#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 )
-#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH )
+/**
+ * @brief Flag bits used to define ::POUT_SETTINGS_FLAGS
+ *
+ * @see ::POUT_SETTINGS_FLAGS
+ */
+enum POUT_SETTINGS_FLAG_BITS
+{
+ /// Output level is to be inverted. Can only be used
+ /// if ::POUT_NOT_INVERTIBLE is **not** set, but is
+ /// supported by all ::POUT_MODES.
+ POUT_BIT_INVERTED,
+
+ /// Enable output **only** while synchronized. This even overrides
+ /// the settings in ::ENABLE_FLAGS::pulses, so if this flag is set
+ /// the output is only enabled if the clock is synchronized, and is
+ /// disabled when synchronization is lost, i.e. the device enters
+ /// holdover mode.
+ /// This flag can only be used with outputs that have ::POUT_SUPP_IF_SYNC_ONLY
+ /// set, and is only supported for the ::POUT_MODES specified in
+ /// ::POUT_MODES_SUPP_IF_SYNC_ONLY.
+ POUT_BIT_IF_SYNC_ONLY,
+
+ /// Output %UTC time instead of local time for DCF77 emulation.
+ /// This flag can only be used with outputs that have ::POUT_SUPP_DCF77_UTC
+ /// set, and is only supported for the ::POUT_MODES specified in
+ /// ::POUT_MODES_SUPP_TIMEBASE_UTC (e.g. ::POUT_DCF77 or ::POUT_DCF77_M59).
+ POUT_BIT_TIMEBASE_UTC,
+
+ N_POUT_SETTINGS_FLAG_BITS ///< Number of known flag bits
+};
-/*
- * The codes below are used with POUT_SETTINGS::flags:
+
+/**
+ * @brief Flag bit masks used with ::POUT_SETTINGS::flags
+ *
+ * @see ::POUT_SETTINGS_FLAG_BITS
*/
-#define POUT_INVERTED 0x0001 // invert output level
-#define POUT_IF_SYNC_ONLY 0x0002 // disable in holdover mode
-#define POUT_TIMEBASE_UTC 0x0004 // use UTC, only applicable for DCF77 output
+enum POUT_SETTINGS_FLAGS
+{
+ POUT_INVERTED = ( 1UL << POUT_BIT_INVERTED ), ///< see ::POUT_BIT_INVERTED, ::POUT_NOT_INVERTIBLE
+ POUT_IF_SYNC_ONLY = ( 1UL << POUT_BIT_IF_SYNC_ONLY ), ///< see ::POUT_BIT_IF_SYNC_ONLY, ::POUT_SUPP_IF_SYNC_ONLY
+ POUT_TIMEBASE_UTC = ( 1UL << POUT_BIT_TIMEBASE_UTC ) ///< see ::POUT_BIT_TIMEBASE_UTC, ::POUT_SUPP_DCF77_UTC
+};
+
/**
- Since a clock may support more than one programmable
- pulse output, setup tools must use the structure below
- to read/set pulse output configuration.
- The number of outputs supported by a receiver model
- can be queried using the RECEIVER_INFO structure.
+ * @brief Configuration settings for a specific programmable pulse output
+ *
+ * This structure can be used to send configuration settings for a specific
+ * programmable output to a device.
+ * The number of supported outputs is RECEIVER_INFO::n_prg_out.
+ *
+ * @note The ::POUT_INFO_IDX structure should be read from
+ * a device to retrieve the current settings and capabilities.
*/
typedef struct
{
- uint16_t idx; /**< 0..RECEIVER_INFO.n_prg_out-1 */
+ uint16_t idx; ///< 0..::RECEIVER_INFO::n_prg_out-1
POUT_SETTINGS pout_settings;
+
} POUT_SETTINGS_IDX;
-#define _mbg_swab_pout_settings_idx( _p ) \
-{ \
- _mbg_swab16( &(_p)->idx ); \
- _mbg_swab_pout_settings( &(_p)->pout_settings ); \
-}
+#define _mbg_swab_pout_settings_idx_on_set( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \
+} while ( 0 )
+
+#define _mbg_swab_pout_settings_idx_on_get( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \
+} while ( 0 )
/**
- The structure below holds the current settings
- for a programmable pulse output, plus additional
- informaton on the output's capabilities.
- This can be read by setup programs to allow setup
- of supported features only.
+ * @brief Current settings and general capabilities of a programmable pulse output
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a programmable pulse output plus its capabilities,
+ * e.g. the supported output modes, etc.
+ *
+ * @note The ::POUT_INFO_IDX structure should be used to read
+ * current settings and capabilities of a specific output.
*/
typedef struct
{
POUT_SETTINGS pout_settings;
- uint32_t supp_modes; /**< bit mask of modes supp. by this output */
- uint8_t timestr_ports; /**< bit mask of COM ports supported for POUT_TIMESTR */
- uint8_t reserved_0; /**< reserved for future use, currently 0 */
- uint16_t reserved_1; /**< reserved for future use, currently 0 */
- uint32_t flags; /**< see below */
+ uint32_t supp_modes; ///< bit mask of modes supp. by this output, see @ref POUT_MODE_MASKS
+ uint8_t timestr_ports; ///< bit mask of COM ports supported for mode ::POUT_TIMESTR, see ::MAX_POUT_TIMESTR_PORTS
+ uint8_t pulse_shift_res; ///< pulse shift resolution, in [ns], only if ::POUT_SUPP_PULSE_SHIFT, see ::POUT_DATA::pulse_shift
+ uint16_t reserved_1; ///< reserved for future use, currently unused and always 0
+ uint32_t flags; ///< @see ::POUT_INFO_FLAG_MASKS
+
} POUT_INFO;
-#define _mbg_swab_pout_info( _p ) \
-{ \
- _mbg_swab_pout_settings( &(_p)->pout_settings ); \
- _mbg_swab32( &(_p)->supp_modes ); \
- _mbg_swab16( &(_p)->reserved_1 ); \
- _mbg_swab32( &(_p)->flags ); \
-}
+#define _mbg_swab_pout_info_on_get( _p ) \
+do \
+{ \
+ _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab8( &(_p)->timestr_ports ); \
+ _mbg_swab8( &(_p)->pulse_shift_res ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
-/** The max number of COM ports that can be handled by POUT_INFO::timestr_ports */
-#define MAX_POUT_TIMESTR_PORTS 8
+#define MAX_POUT_TIMESTR_PORTS 8 ///< The max number of COM ports that can be handled by ::POUT_INFO::timestr_ports
-/*
- * The codes below are used with POUT_INFO::flags:
+
+/**
+ * @brief Flag bits used to define ::POUT_INFO_FLAG_MASKS
+ *
+ * @see ::POUT_INFO_FLAG_MASKS
+ */
+enum POUT_INFO_FLAG_BITS
+{
+ POUT_BIT_SUPP_IF_SYNC_ONLY, ///< ::POUT_IF_SYNC_ONLY is supported for this output
+ POUT_BIT_SUPP_DCF77_UTC, ///< ::POUT_SUPP_DCF77_UTC is supported for this output
+ POUT_BIT_FIXED_PULSE_LEN, ///< pulse length is limited to the value ::POUT_SETTINGS::mode_param
+ POUT_BIT_NOT_INVERTIBLE, ///< output level can't be inverted, thus ::POUT_INVERTED is not supported for this output
+ POUT_BIT_SUPP_PULSE_SHIFT, ///< output slopes can be shifted, see ::POUT_DATA::pulse_shift
+ N_POUT_INFO_FLAG_BITS ///< number of known flag bits
+};
+
+
+/**
+ * @brief Flag bit masks used with ::POUT_INFO::flags
+ *
+ * @see ::POUT_INFO_FLAG_BITS
*/
-#define POUT_SUPP_IF_SYNC_ONLY 0x0001 // supports disabling outputs in holdover mode
-#define POUT_SUPP_DCF77_UTC 0x0002 // supports UTC output in DCF77 mode
+enum POUT_INFO_FLAG_MASKS
+{
+ POUT_SUPP_IF_SYNC_ONLY = ( 1UL << POUT_BIT_SUPP_IF_SYNC_ONLY ), ///< see ::POUT_BIT_SUPP_IF_SYNC_ONLY, ::POUT_IF_SYNC_ONLY
+ POUT_SUPP_DCF77_UTC = ( 1UL << POUT_BIT_SUPP_DCF77_UTC ), ///< see ::POUT_BIT_SUPP_DCF77_UTC, ::POUT_SUPP_DCF77_UTC
+ POUT_FIXED_PULSE_LEN = ( 1UL << POUT_BIT_FIXED_PULSE_LEN ), ///< see ::POUT_BIT_FIXED_PULSE_LEN
+ POUT_NOT_INVERTIBLE = ( 1UL << POUT_BIT_NOT_INVERTIBLE ), ///< see ::POUT_BIT_NOT_INVERTIBLE, ::POUT_INVERTED
+ POUT_SUPP_PULSE_SHIFT = ( 1UL << POUT_BIT_SUPP_PULSE_SHIFT ) ///< see ::POUT_BIT_SUPP_PULSE_SHIFT, ::POUT_DATA::pulse_shift
+};
+
/**
- The structure below adds an index number to the structure
- above to allow addressing of several instances:
+ * @brief Current settings and general capabilities of a specific programmable pulse output
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of a specific programmable output plus its capabilities,
+ * e.g. supported modes of operation, etc.
+ * The number of supported ports is RECEIVER_INFO::n_prg_out.
+ *
+ * @note The ::POUT_SETTINGS_IDX structure should be send back to
+ * the device to configure the specified programmable pulse output.
*/
typedef struct
{
- uint16_t idx; /**< 0..RECEIVER_INFO.n_prg_out-1 */
+ uint16_t idx; ///< 0..::RECEIVER_INFO::n_prg_out-1
POUT_INFO pout_info;
+
} POUT_INFO_IDX;
-#define _mbg_swab_pout_info_idx( _p ) \
-{ \
- _mbg_swab16( &(_p)->idx ); \
- _mbg_swab_pout_info( &(_p)->pout_info ); \
-}
+#define _mbg_swab_pout_info_idx_on_get( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \
+} while ( 0 )
+/** @} defgroup group_pout_api */
-/*
- * 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.
- */
/**
- * @brief All possibly supported ref time sources
+ * @defgroup group_multi_ref_all Support for multiple reference time sources
+ *
+ * Some devices can evaluate and synchronize to several different types
+ * of input signal, and eventually even several signals of the same type,
+ * e.g. several 1 PPS input signals.
+ *
+ * There are two different ways to configure multi ref devices.
+ *
+ * Newer devices which have the ::GPS_HAS_XMULTI_REF flag set in
+ * ::RECEIVER_INFO::features support the newer XMULTI_REF_... structures
+ * which provide a more flexible API, see @ref group_multi_ref_ext
+ *
+ * Older devices may have the ::GPS_FEAT_MULTI_REF flag set in which
+ * case an older API is supported, see @ref group_multi_ref_old
+ *
+ * Symbols defined in @ref group_multi_ref_common can be used
+ * with both APIs.
+ *
+ * @see @ref group_multi_ref_common
+ * @see @ref group_multi_ref_old
+ * @see @ref group_multi_ref_ext
+ * @{ */
+
+/**
+ * @defgroup group_multi_ref_common Common multi ref definitions
+ *
+ * Common definitions used with both the old and the extended
+ * multi ref API.
+ *
+ * @{ */
+
+/**
+ * @brief Enumeration of all known types of reference time source
+ *
+ * All known types of input signal which may possibly be supported
+ * by devices which support several different input signals, i.e.
+ * have the ::GPS_HAS_MULTI_REF or ::GPS_HAS_XMULTI_REF bit set
+ * in ::RECEIVER_INFO::features. Not all devices support each known
+ * type of input signal.
+ *
+ * @see @ref group_multi_ref_all
+ * @see ::DEFAULT_MULTI_REF_NAMES
+ * @see ::DEFAULT_MULTI_REF_NAMES_SHORT
+ * @see @ref MULTI_REF_TYPE_MASKS
*/
-enum
+enum MULTI_REF_TYPES
{
- MULTI_REF_NONE = -1, /**< nothing, undefined */
- MULTI_REF_GPS = 0, /**< standard GPS */
- MULTI_REF_10MHZ, /**< 10 MHz input frequency */
- MULTI_REF_PPS, /**< 1 PPS input signal */
- MULTI_REF_10MHZ_PPS, /**< combined 10 MHz plus PPS */
- MULTI_REF_IRIG, /**< IRIG input */
- MULTI_REF_NTP, /**< Network Time Protocol (NTP) */
- MULTI_REF_PTP, /**< Precision Time Protocol (PTP, IEEE1588) */
- MULTI_REF_PTP_E1, /**< PTP over E1 */
- MULTI_REF_FREQ, /**< fixed frequency */
- MULTI_REF_PPS_STRING, /**< PPS in addition to string */
- MULTI_REF_GPIO, /**< variable input signal via GPIO */
- N_MULTI_REF /**< the number of defined sources, can not exceed bit number of uint32_t - 1 */
+ /// This ref type must not be used as index, but marks particular
+ /// ::XMULTI_REF_SETTINGS structures as "unused". It is only
+ /// supported if bit ::XMRIF_BIT_MRF_NONE_SUPP is set.
+ MULTI_REF_NONE = -1,
+
+ MULTI_REF_GPS = 0, ///< standard GPS
+ MULTI_REF_10MHZ, ///< 10 MHz input frequency
+ MULTI_REF_PPS, ///< 1 PPS input signal
+ MULTI_REF_10MHZ_PPS, ///< combined 10 MHz plus PPS
+ MULTI_REF_IRIG, ///< IRIG input
+ MULTI_REF_NTP, ///< Network Time Protocol (NTP)
+ MULTI_REF_PTP, ///< Precision Time Protocol (PTP/IEEE1588)
+ MULTI_REF_PTP_E1, ///< PTP over E1
+ MULTI_REF_FREQ, ///< fixed frequency
+ MULTI_REF_PPS_STRING, ///< 1 PPS in addition to time string
+ MULTI_REF_GPIO, ///< variable input signal via GPIO
+ MULTI_REF_INTERNAL, ///< reserved, used internally by firmware only
+ MULTI_REF_PZF, ///< DCF77 PZF providing much more accuracy than a standard LWR
+ MULTI_REF_LWR, ///< long wave receiver. e.g. DCF77 AM, WWVB, MSF, JJY
+ MULTI_REF_GRC, ///< Glonass / GPS receiver
+ MULTI_REF_HAVEQUICK, ///< HaveQuick input
+ MULTI_REF_EXT_OSC, ///< external oscillator disciplined and looped back via 1 PPS I/O
+ MULTI_REF_SYNCE, ///< Synchronous Ethernet, needs (external) ethernet interface
+ N_MULTI_REF ///< the number of defined sources, must not exceed ::MAX_N_MULTI_REF_TYPES
};
+/**
+ * @brief Theoretical maximum number of multi ref input signal types
+ *
+ * Actually only ::N_MULTI_REF types have been defined, but ::N_MULTI_REF
+ * must not exceed the number of bits which can be hold by a uint32_t type.
+ */
+#define MAX_N_MULTI_REF_TYPES 32
-/*
- * Names of supported ref time sources
+
+/**
+ * @brief Names of known ref time sources
+ *
+ * @see ::MULTI_REF_TYPES
*/
#define DEFAULT_MULTI_REF_NAMES \
{ \
@@ -3223,137 +6318,252 @@ enum
"PTP over E1", \
"Fixed Freq. in", \
"PPS plus string", \
- "Var. freq. via GPIO" \
+ "Var. freq. via GPIO", \
+ "(reserved)", \
+ "DCF77 PZF Receiver", \
+ "Long Wave Receiver", \
+ "GLONASS/GPS Receiver", \
+ "HaveQuick Input", \
+ "ext. Osc.", \
+ "Synchronous Ethernet" \
}
-
-/*
- * Bit masks used to indicate supported reference sources
+/**
+ * @brief Short names of supported ref time sources
+ *
+ * Used e.g. to configure a particular input signal type
+ *
+ * @see ::MULTI_REF_TYPES
*/
-#define HAS_MULTI_REF_GPS ( 1UL << MULTI_REF_GPS )
-#define HAS_MULTI_REF_10MHZ ( 1UL << MULTI_REF_10MHZ )
-#define HAS_MULTI_REF_PPS ( 1UL << MULTI_REF_PPS )
-#define HAS_MULTI_REF_10MHZ_PPS ( 1UL << MULTI_REF_10MHZ_PPS )
-#define HAS_MULTI_REF_IRIG ( 1UL << MULTI_REF_IRIG )
-#define HAS_MULTI_REF_NTP ( 1UL << MULTI_REF_NTP )
-#define HAS_MULTI_REF_PTP ( 1UL << MULTI_REF_PTP )
-#define HAS_MULTI_REF_PTP_E1 ( 1UL << MULTI_REF_PTP_E1 )
-#define HAS_MULTI_REF_FREQ ( 1UL << MULTI_REF_FREQ )
-#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING )
-#define HAS_MULTI_REF_GPIO ( 1UL << MULTI_REF_GPIO )
+#define DEFAULT_MULTI_REF_NAMES_SHORT \
+{ \
+ "GPS", \
+ "FRQ", \
+ "PPS", \
+ "10MHZ+PPS", \
+ "TCR", \
+ "NTP", \
+ "PTP", \
+ "PTP_E1", \
+ "FIXED_FREQ", \
+ "STRING+PPS", \
+ "GPIO", \
+ "(reserved)", \
+ "PZF", \
+ "LWR", \
+ "GGR", \
+ "HQI", \
+ "EXT", \
+ "SYNCE" \
+}
-/*
- * There are 2 different ways to configure multi ref support
- * provided by some devices.
+/**
+ * @brief Bit masks associated with multi ref types
*
- * Newer devices which have the GPS_FEAT_XMULTI_REF flag set
- * in RECEIVER_INFO::features support the newer XMULTI_REF_...
- * structures which provide a more flexible interface.
+ * Used to indicate which multi ref types are supported, e.g.
+ * in ::XMULTI_REF_INFO::supp_ref or ::MULTI_REF_INFO::supp_ref.
*
- * Older devices which have the GPS_FEAT_MULTI_REF flag set
- * support these MULTI_REF_... structures below where
- * the number of supported input sources and priorities
- * is limited to N_MULTI_REF_PRIO.
- */
+ * @see ::MULTI_REF_TYPES
+ *
+ * @anchor MULTI_REF_TYPE_MASKS @{ */
+
+#define HAS_MULTI_REF_GPS ( 1UL << MULTI_REF_GPS ) ///< see ::MULTI_REF_GPS
+#define HAS_MULTI_REF_10MHZ ( 1UL << MULTI_REF_10MHZ ) ///< see ::MULTI_REF_10MHZ
+#define HAS_MULTI_REF_PPS ( 1UL << MULTI_REF_PPS ) ///< see ::MULTI_REF_PPS
+#define HAS_MULTI_REF_10MHZ_PPS ( 1UL << MULTI_REF_10MHZ_PPS ) ///< see ::MULTI_REF_10MHZ_PPS
+#define HAS_MULTI_REF_IRIG ( 1UL << MULTI_REF_IRIG ) ///< see ::MULTI_REF_IRIG
+#define HAS_MULTI_REF_NTP ( 1UL << MULTI_REF_NTP ) ///< see ::MULTI_REF_NTP
+#define HAS_MULTI_REF_PTP ( 1UL << MULTI_REF_PTP ) ///< see ::MULTI_REF_PTP
+#define HAS_MULTI_REF_PTP_E1 ( 1UL << MULTI_REF_PTP_E1 ) ///< see ::MULTI_REF_PTP_E1
+
+#define HAS_MULTI_REF_FREQ ( 1UL << MULTI_REF_FREQ ) ///< see ::MULTI_REF_FREQ
+#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING ) ///< see ::MULTI_REF_PPS_STRING
+#define HAS_MULTI_REF_GPIO ( 1UL << MULTI_REF_GPIO ) ///< see ::MULTI_REF_GPIO
+#define HAS_MULTI_REF_INTERNAL ( 1UL << MULTI_REF_INTERNAL ) ///< see ::MULTI_REF_INTERNAL
+#define HAS_MULTI_REF_PZF ( 1UL << MULTI_REF_PZF ) ///< see ::MULTI_REF_PZF
+#define HAS_MULTI_REF_LWR ( 1UL << MULTI_REF_LWR ) ///< see ::MULTI_REF_LWR
+#define HAS_MULTI_REF_GRC ( 1UL << MULTI_REF_GRC ) ///< see ::MULTI_REF_GRC
+#define HAS_MULTI_REF_HAVEQUICK ( 1UL << MULTI_REF_HAVEQUICK ) ///< see ::MULTI_REF_HAVEQUICK
+
+#define HAS_MULTI_REF_EXT_OSC ( 1UL << MULTI_REF_EXT_OSC ) ///< see ::MULTI_REF_EXT_OSC
+#define HAS_MULTI_REF_SYNCE ( 1UL << MULTI_REF_SYNCE ) ///< see ::MULTI_REF_SYNCE
+
+/** @} anchor MULTI_REF_TYPE_MASKS */
+
+/** @} defgroup group_multi_ref_common */
-#define N_MULTI_REF_PRIO 4
/**
- The structure below is used to configure the priority of
- the supported ref sources.
+ * @defgroup group_multi_ref_old Definitions used with the old multi ref API
+ *
+ * This API has been deprecated by a newer one which should be used preferably.
+ *
+ * @see @ref group_multi_ref_ext
+ *
+ * @{ */
+
+/**
+ * @brief Maximum number of input sources
+ *
+ * The number of supported input sources and priorities is
+ * limited to this value if the old API is used, i.e. if only
+ * the ::GPS_FEAT_MULTI_REF flag is set.
+ */
+#define N_MULTI_REF_PRIO 4
- The number stored in prio[0] of the array indicates the ref time
- source with highest priority. If that source fails, the device
- falls back to the source indicated by prio[1]. Each field of
- the prio[] array must be set to one of the values 0..N_MULTI_REF-1,
- or to -1 (0xFF) if the value is not assigned.
+
+/**
+ * @brief A structure used to configure the priority of the supported ref sources
+ *
+ * The number stored in prio[0] of the array indicates the ref time
+ * source with highest priority. If that source fails, the device
+ * falls back to the source indicated by prio[1]. Each field of
+ * the prio[] array has to be set to one of the values 0..::N_MULTI_REF-1,
+ * or to ::MULTI_REF_NONE if no time source is specified.
*/
typedef struct
{
uint8_t prio[N_MULTI_REF_PRIO];
+
} MULTI_REF_SETTINGS;
/**
- The structure below is used to query the MULTI_REF configuration,
- plus the supported ref sources.
+ * @brief A structure used to query MULTI_REF configuration parameters
+ *
+ * This also includes a bit mask of supported ref sources.
*/
typedef struct
{
- MULTI_REF_SETTINGS settings; /* current settings */
- uint32_t supp_ref; /* supp. HAS_MULTI_REF_... codes or'ed */
- uint16_t n_levels; /* supp. levels, 0..N_MULTI_REF_PRIO */
- uint16_t flags; /* reserved, currently 0 */
+ MULTI_REF_SETTINGS settings; ///< current settings
+ uint32_t supp_ref; ///< bit mask of supported sources, see @ref MULTI_REF_TYPE_MASKS
+ uint16_t n_levels; ///< supported priority levels, 0..::N_MULTI_REF_PRIO-1
+ uint16_t flags; ///< reserved, currently always 0
+
} MULTI_REF_INFO;
-/*
- * The type below is used to query the MULTI_REF status information,
+/**
+ * @brief A data type used to query MULTI_REF status information
+ *
+ * @see ::MULTI_REF_STATUS_BIT_MASKS
*/
-typedef uint16_t MULTI_REF_STATUS; /* flag bits as defined below */
+typedef uint16_t MULTI_REF_STATUS;
-/*
- * The bits and associated bit masks below are used with the
- * MULTI_REF_STATUS type. Each bit is set if the associated
- * condition is true and is reset if the condition is not true:
+/**
+ * @brief Enumeration of multi ref status bits
+ *
+ * @see ::MULTI_REF_STATUS_BIT_MASKS
*/
-enum
+enum MULTI_REF_STATUS_BITS
{
- WRN_MODULE_MODE, /* selected input mode was invalid, set to default */
- WRN_COLD_BOOT, /* GPS is in cold boot mode */
- WRN_WARM_BOOT, /* GPS is in warm boot mode */
- WRN_ANT_DISCONN, /* antenna is disconnected */
- WRN_10MHZ_UNLOCK, /* impossible to lock to external 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
+ WRN_MODULE_MODE, ///< selected input mode was invalid, set to default
+ WRN_COLD_BOOT, ///< GPS is in cold boot mode
+ WRN_WARM_BOOT, ///< GPS is in warm boot mode
+ WRN_ANT_DISCONN, ///< antenna is disconnected
+ WRN_10MHZ_UNLOCK, ///< impossible to lock to external 10 MHz reference
+ WRN_1PPS_UNLOCK, ///< impossible to lock to external 1 PPS reference
+ WRN_GPS_UNLOCK, ///< impossible to lock to GPS
+ WRN_10MHZ_MISSING, ///< external 10 MHz signal not available
+ WRN_1PPS_MISSING, ///< external 1 PPS signal not available
+ N_MULTI_REF_STATUS_BITS ///< the number of known bits
};
-#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 )
+
+/**
+ * @brief Bit masks associated with ::MULTI_REF_STATUS_BITS
+ *
+ * Used with ::MULTI_REF_STATUS.
+ *
+ * @see ::MULTI_REF_STATUS_BITS
+ */
+enum MULTI_REF_STATUS_BIT_MASKS
+{
+ MSK_WRN_COLD_BOOT = ( 1UL << WRN_COLD_BOOT ), ///< see ::WRN_COLD_BOOT
+ MSK_WRN_WARM_BOOT = ( 1UL << WRN_WARM_BOOT ), ///< see ::WRN_WARM_BOOT
+ MSK_WRN_ANT_DISCONN = ( 1UL << WRN_ANT_DISCONN ), ///< see ::WRN_ANT_DISCONN
+ MSK_WRN_10MHZ_UNLOCK = ( 1UL << WRN_10MHZ_UNLOCK ), ///< see ::WRN_10MHZ_UNLOCK
+ MSK_WRN_1PPS_UNLOCK = ( 1UL << WRN_1PPS_UNLOCK ), ///< see ::WRN_1PPS_UNLOCK
+ MSK_WRN_GPS_UNLOCK = ( 1UL << WRN_GPS_UNLOCK ), ///< see ::WRN_GPS_UNLOCK
+ MSK_WRN_10MHZ_MISSING = ( 1UL << WRN_10MHZ_MISSING ), ///< see ::WRN_10MHZ_MISSING
+ MSK_WRN_1PPS_MISSING = ( 1UL << WRN_1PPS_MISSING ), ///< see ::WRN_1PPS_MISSING
+ MSK_WRN_MODULE_MODE = ( 1UL << WRN_MODULE_MODE ) ///< see ::WRN_MODULE_MODE
+};
+
+/** @} defgroup group_multi_ref_old */
/**
- * @defgroup group_xmr_cfg Extended multiref configuration stuff
+ * @defgroup group_multi_ref_ext Extended multi ref definitions
+ *
+ * If the ::GPS_HAS_XMULTI_REF feature is set in ::RECEIVER_INFO::features then
+ * the XMULTI_REF (extended multi ref, XMR) feature and API are supported and
+ * have to be used in favor of the older multi ref API (see @ref group_multi_ref_old).
+ *
+ * Devices supporting the XMULTI_REF feature provide a number of
+ * priority levels addressed by the priority index, starting at 0
+ * for highest priority. A single reference time source from the set
+ * of supported sources can be assigned to each priority level.
+ *
+ * These structures are used to configure the individual time source for each
+ * priority level, and retrieve the status of the time source at each priority level.
*
- * If 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.
+ * If ::GPS_HAS_XMRS_MULT_INSTC is also set in ::RECEIVER_INFO::features then
+ * ::XMULTI_REF_INSTANCES can be used to find out which types of input source
+ * are supported (::XMULTI_REF_INSTANCES::n_inst array entries != 0), and
+ * how many priority levels are supported to which an input source can be
+ * assigned (::XMULTI_REF_INSTANCES::n_xmr_settings).
*
- * 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.
+ * If ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags
+ * then ::XMR_HOLDOVER_STATUS can be used to monitor the switching between
+ * different time sources when they become available or unavailable.
*
- * These structures are used to configure the individual
- * time source for each priority level, and retrieve the status
- * of the time source at each priority level.
+ * If an XMR time source at a high priority level becomes unavailable the
+ * XMR control function tries to find and switch to a different time source
+ * at a lower level of the priority list, which is still available.
+ *
+ * On the other hand, if a time source at a higher priority level becomes
+ * available again, the XMR control function switches over to the time source
+ * at the higher priority even if the current time source is still available.
+ *
+ * If the accuracy of the time source at the next priority level is better than
+ * the accuracy of the time source at the current priority level then switching
+ * can be done immediately. However, if the next time source is worse than
+ * the current one it makes more sense to switch only after a certain holdover
+ * interval.
+ *
+ * The holdover interval is computed so that the time error due to the expected
+ * drift of the previously disciplined time base grows until it reaches the
+ * accuracy level of the next available reference time source.
+ *
+ * Only if the time source at the current priority level is still unavailable
+ * when the holdover interval expires the reference time source is switched
+ * to the time source at the next available priority level.
*
* @{ */
+
/**
* @brief Identifier for a reference source
*/
typedef struct
{
- uint8_t type; /**< 0..N_MULTI_REF-1 from the enum above */
- uint8_t instance; /**< instance number, if multiple instances are supported, else 0 */
+ uint8_t type; ///< see ::MULTI_REF_TYPES, and note for ::XMRIF_BIT_MRF_NONE_SUPP
+ uint8_t instance; ///< instance number, if multiple instances are supported, else 0
} XMULTI_REF_ID;
+#define _mbg_swab_xmulti_ref_id( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->type ); \
+ _mbg_swab8( &(_p)->instance ); \
+} while ( 0 )
+
/**
@@ -3361,56 +6571,129 @@ typedef struct
*/
typedef struct
{
- XMULTI_REF_ID id; /**< time source identifier */
- uint16_t flags; /**< reserved, currently always 0 */
- NANO_TIME bias; /**< time bias, e.g. path delay */
- NANO_TIME precision; /**< precision of the time source */
- uint32_t fine_limit; /**< smooth control if below this limit */
+ XMULTI_REF_ID id; ///< reference time source identifier
+ uint16_t flags; ///< see ::XMR_SETTINGS_FLAG_MSKS and ::XMR_EXT_SRC_INFO::supp_flags
+ NANO_TIME bias; ///< time bias, e.g. path delay @todo specify sign vs. earlier/later
+ NANO_TIME precision; ///< precision of the time source
+ uint32_t reserved; ///< reserved, currently always 0
} XMULTI_REF_SETTINGS;
+#define _mbg_swab_xmulti_ref_settings( _p ) \
+do \
+{ \
+ _mbg_swab_xmulti_ref_id( &(_p)->id ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab_nano_time( &(_p)->bias ); \
+ _mbg_swab_nano_time( &(_p)->precision ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
/**
- * @brief Reference source configuration settings for a specific priority level
+ * @brief Reference source configuration for a specific priority level
*
- * @note After configuring, a structure with idx == 0xFFFF (-1) must be sent
- * to let the changes become effective.
+ * @note After all other ::XMULTI_REF_SETTINGS_IDX configuration structures
+ * have been sent to a device, an additional structure with idx == -1 (0xFFFF)
+ * has to be sent to let the new settings come into effect.
*/
typedef struct
{
- uint16_t idx; /* the priority level index, highest == 0 */
- XMULTI_REF_SETTINGS settings; /* the settings configured for this level */
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMULTI_REF_SETTINGS settings; ///< the settings configured for this level
} XMULTI_REF_SETTINGS_IDX;
+#define _mbg_swab_xmulti_ref_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Bit masks used to define ::XMR_SETTINGS_FLAG_MSKS
+ */
+enum XMR_SETTINGS_FLAG_BITS
+{
+ XMRSF_BIT_AUTO_BIAS_MASTER, ///< src is allowed to operate as zero asymmetry master
+ XMRSF_BIT_AUTO_BIAS_SLAVE, ///< accept static bias correction from zero asymmetry master
+ XMRSF_BIT_ASYMMETRY_STEP_DETECTION, ///< static bias auto correction in case of step
+ N_XMRSF_BITS ///< number of known flag bits
+};
+
+
+/**
+ * @brief Bit masks used with ::XMULTI_REF_SETTINGS::flags and ::XMR_EXT_SRC_INFO::supp_flags
+ */
+enum XMR_SETTINGS_FLAG_MSKS
+{
+ XMRSF_MSK_AUTO_BIAS_MASTER = ( 1UL << XMRSF_BIT_AUTO_BIAS_MASTER ), ///< see ::XMRSF_BIT_AUTO_BIAS_MASTER
+ XMRSF_MSK_AUTO_BIAS_SLAVE = ( 1UL << XMRSF_BIT_AUTO_BIAS_SLAVE ), ///< see ::XMRSF_BIT_AUTO_BIAS_SLAVE
+ XMRSF_MSK_ASYMMETRY_STEP_DETECTION = ( 1UL << XMRSF_BIT_ASYMMETRY_STEP_DETECTION ) ///< see ::XMRSF_BIT_ASYMMETRY_STEP_DETECTION
+};
+
/**
- * @brief Reference source configuration settings and capabilities
+ * @brief Reference source capabilities and current configuration
*/
typedef struct
{
- XMULTI_REF_SETTINGS settings; /**< current settings */
- uint32_t supp_ref; /**< bit mask of or'ed HAS_MULTI_REF_... codes */
- uint8_t n_supp_ref; /**< number of supported ref time sources */
- uint8_t n_prio; /**< number of supported priority levels */
- uint16_t flags; /**< currently always 0 */
+ XMULTI_REF_SETTINGS settings; ///< current settings
+
+ /**
+ * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_inst.
+ * If ::GPS_HAS_XMRS_MULT_INSTC is *not* set then this field provides
+ * a bit mask of supported sources (see @ref MULTI_REF_TYPE_MASKS),
+ * and only a single instance of each source signal type is supported.
+ */
+ uint32_t supp_ref;
+
+ /**
+ * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_xmr_settings.
+ * If ::GPS_HAS_XMRS_MULT_INSTC is *not* set then this field
+ * reports the number of priority levels supported by the device.
+ */
+ uint8_t n_supp_ref;
+
+ uint8_t n_prio; ///< reserved, don't use, currently always 0 //##++++ TODO: check which devices support/use this field
+ uint16_t flags; ///< reserved, don't use, currently always 0
} XMULTI_REF_INFO;
+#define _mbg_swab_xmulti_ref_info( _p ) \
+do \
+{ \
+ _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_ref ); \
+ _mbg_swab8( &(_p)->n_supp_ref ); \
+ _mbg_swab8( &(_p)->n_prio ); \
+ _mbg_swab16( &(_p)->flags ); \
+} while ( 0 )
+
/**
- * @brief Reference source configuration settings and capabilities for a specific priority level
+ * @brief Reference source capabilities and current configuration for a specific priority level
*/
typedef struct
{
- uint16_t idx; /**< the priority level index, highest == 0 */
- XMULTI_REF_INFO info; /**< ref source cfg and capabilities */
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMULTI_REF_INFO info; ///< ref source configuration and capabilities
} XMULTI_REF_INFO_IDX;
+#define _mbg_swab_xmulti_ref_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmulti_ref_info( &(_p)->info ); \
+} while ( 0 )
+
/**
@@ -3418,82 +6701,160 @@ typedef struct
*/
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 flags; /**< see flags specified below */
+ XMULTI_REF_ID id; ///< time source identifier
+ uint16_t status; ///< status bits, see @ref XMR_REF_STATUS_BIT_MASKS
+ NANO_TIME offset; ///< time offset from main time base @todo specify sign vs. earlier/later
+ uint16_t flags; ///< flags, see ::XMR_QL // TODO ###
+ uint8_t ssm; ///< synchronization status message, if supported by signal source
+ uint8_t soc; ///< signal outage counter, incremented on loss of signal
} XMULTI_REF_STATUS;
+#define _mbg_swab_xmulti_ref_status( _p ) \
+do \
+{ \
+ _mbg_swab_xmulti_ref_id( &(_p)->id ); \
+ _mbg_swab16( &(_p)->status ); \
+ _mbg_swab_nano_time( &(_p)->offset ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->ssm ); \
+ _mbg_swab8( &(_p)->soc ); \
+} while ( 0 )
+
/**
- * @brief Bits and masks used with XMULTI_REF_STATUS::flags
- *
- * @note If XMRS_FLAG_MULT_INSTC_SUPP is set then the API calls to read
- * XMULTI_REF_INSTANCES is supported, otherwise it is not.
+ * @brief Status information on a ref time source at a specific priority level
*/
-enum
+typedef struct
{
- XMRSF_BIT_MULT_INSTC_SUPP, /**< multiple instances of the same ref type supported */
- XMRSF_BIT_IS_EXTERNAL, /**< this ref source is on extension card */
- N_XMRS_FLAGS
-};
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMULTI_REF_STATUS status; ///< status information
+
+} XMULTI_REF_STATUS_IDX;
-#define XMRSF_MSK_MULT_INSTC_SUPP ( 1UL << XMRSF_BIT_MULT_INSTC_SUPP )
-#define XMRSF_MSK_IS_EXTERNAL ( 1UL << XMRSF_BIT_IS_EXTERNAL )
+#define _mbg_swab_xmulti_ref_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmulti_ref_status( &(_p)->status ); \
+} while ( 0 )
/**
- * @brief Status information on a ref time source at a specific priority level
+ * @brief ::TODO
+ *
+ * Used with the ::... field of ::XMULTI_REF_STATUS::flags
+ *
+ * @see ::XMULTI_REF_STATUS::flags
+ * @see ::XMR_QL_TDEV_MASK
+ * @see ::_GET_XMR_QL_TDEV
+ * @see ::_PUT_XMR_QL_TDEV
+ * @see ::XMR_QL_MTIE_MASK
+ * @see ::_GET_XMR_QL_MTIE
+ * @see ::_PUT_XMR_QL_MTIE
*/
-typedef struct
+enum XMR_QL
{
- uint16_t idx; /**< the priority level index, highest == 0 */
- XMULTI_REF_STATUS status; /**< status information */
+ XMR_QL_UNKNOWN,
+ XMR_QL_GREEN,
+ XMR_QL_YELLOW,
+ XMR_QL_RED,
+ N_XMR_QL
+};
-} XMULTI_REF_STATUS_IDX;
+#define XMR_QL_TDEV_MASK ( 0x03 << 0 )
+#define XMR_QL_MTIE_MASK ( 0x03 << 2 )
+
+#define _GET_XMR_QL_TDEV( _x ) ( ( ( _x ) & XMR_QL_TDEV_MASK ) >> 0 )
+#define _PUT_XMR_QL_TDEV( _x, _ql ) \
+do { \
+ ( _x ) = ( ( _x ) & ~XMR_QL_TDEV_MASK ) | ( ( ( _ql ) << 0 ) & XMR_QL_TDEV_MASK ); \
+} while ( 0 )
+
+
+#define _GET_XMR_QL_MTIE( _x ) ( ( ( _x ) & XMR_QL_MTIE_MASK ) >> 2 )
+#define _PUT_XMR_QL_MTIE( _x, _ql ) \
+do { \
+ ( _x ) = ( ( _x ) & ~XMR_QL_MTIE_MASK ) | ( ( ( _ql ) << 2 ) & XMR_QL_MTIE_MASK ); \
+} while ( 0 )
/**
- * @brief Bits and bit masks used with XMULTI_REF_STATUS::status
- *
- * @note Flags XMRS_BIT_MULT_INSTC_SUPP and XMRS_BIT_NUM_SRC_EXC
- * are set in the status flags for every priority if the associated
- * condition is met.
+ * @brief XMULTI_REF status bits
*/
-enum
+enum XMR_REF_STATUS_BITS
{
- XMRS_BIT_NOT_SUPP, /**< ref type cfg'd for this level is not supported */
- XMRS_BIT_NO_CONN, /**< input signal is disconnected */
- XMRS_BIT_NO_SIGNAL, /**< no input signal */
- XMRS_BIT_IS_MASTER, /**< reference is master source */
- XMRS_BIT_IS_LOCKED, /**< locked to input signal */
- XMRS_BIT_IS_ACCURATE, /**< oscillator control has reached full accuracy */
- XMRS_BIT_NOT_SETTLED, /**< reference time signal not settled */
- XMRS_BIT_NOT_PHASE_LOCKED, /**< oscillator not phase locked to PPS */
- XMRS_BIT_NUM_SRC_EXC, /**< number of available sources exceeds what can be handled */
- XMRS_BIT_IS_EXTERNAL, /**< this ref source is on extension card */
- N_XMRS_BITS /**< number of know status bits */
+ XMRS_BIT_NOT_SUPP, ///< ref type cfg'd for this level is not supported
+ XMRS_BIT_NO_CONN, ///< input signal is disconnected
+ XMRS_BIT_NO_SIGNAL, ///< no input signal
+ XMRS_BIT_IS_MASTER, ///< reference is master source
+ XMRS_BIT_IS_LOCKED, ///< locked to input signal
+ XMRS_BIT_IS_ACCURATE, ///< oscillator control has reached full accuracy
+ XMRS_BIT_NOT_SETTLED, ///< reference time signal not settled
+ XMRS_BIT_NOT_PHASE_LOCKED, ///< oscillator not phase locked to PPS
+ XMRS_BIT_NUM_SRC_EXC, ///< number of available sources exceeds what can be handled
+ XMRS_BIT_IS_EXTERNAL, ///< this ref source is on extension card
+ XMRS_BIT_LOW_JITTER, ///< this ref source has low jitter
+ XMRS_BIT_ITU_LIMIT_VIOLATED, ///< ITU limits violated (valid if device has ::XMR_METRICS)
+ N_XMRS_BITS ///< number of know status bits
};
-#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP )
-#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN )
-#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL )
-#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER )
-#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED )
-#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE )
-#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED )
-#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED )
-#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC )
-#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL )
+
+
+/**
+ * @brief Bit masks associated with ::XMR_REF_STATUS_BITS
+ *
+ * Used with ::XMULTI_REF_STATUS::status.
+ *
+ * @see ::XMR_REF_STATUS_BITS
+ *
+ * @anchor XMR_REF_STATUS_BIT_MASKS @{ */
+
+#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) ///< see ::XMRS_BIT_NOT_SUPP
+#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) ///< see ::XMRS_BIT_NO_CONN
+#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) ///< see ::XMRS_BIT_NO_SIGNAL
+#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER ) ///< see ::XMRS_BIT_IS_MASTER
+#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED ) ///< see ::XMRS_BIT_IS_LOCKED
+#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE ) ///< see ::XMRS_BIT_IS_ACCURATE
+#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED ) ///< see ::XMRS_BIT_NOT_SETTLED
+#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED ) ///< see ::XMRS_BIT_NOT_PHASE_LOCKED
+#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC ) ///< see ::XMRS_BIT_NUM_SRC_EXC
+#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL ) ///< see ::XMRS_BIT_IS_EXTERNAL
+#define XMRS_MSK_LOW_JITTER ( 1UL << XMRS_BIT_LOW_JITTER ) ///< see ::XMRS_BIT_LOW_JITTER
+#define XMRS_MSK_ITU_LIMIT_VIOLATED ( 1UL << XMRS_BIT_ITU_LIMIT_VIOLATED ) ///< see ::XMRS_BIT_ITU_LIMIT_VIOLATED
+
+/** @} anchor XMR_REF_STATUS_BIT_MASKS */
+
+
+
+/**
+ * @brief XMRS status bit name strings
+ *
+ * @see ::XMR_REF_STATUS_BITS
+ */
+#define MBG_XMRS_STATUS_STRS \
+{ \
+ "Ref type not supported", \
+ "No connection", \
+ "No signal", \
+ "Is master", \
+ "Is locked", \
+ "Is accurate", \
+ "Not settled", \
+ "Phase not locked", \
+ "Number sources exceeds limit", \
+ "Is external", \
+ "Low jitter", \
+ "ITU Limit violated" \
+}
/*
- * An initializer for a XMULTI_REF_STATUS variable
+ * An initializer for a ::XMULTI_REF_STATUS variable
* with status invalid / not used
*/
#define XMULTI_REF_STATUS_INVALID \
@@ -3505,236 +6866,3313 @@ enum
}
+
/**
- * @brief The number of supported instances of each ref source type
+ * @brief General info on supported XMR sources and instances
+ *
+ * @note This structure is only supported if ::GPS_HAS_XMRS_MULT_INSTC
+ * is set in ::RECEIVER_INFO::features.
*
- * @note This structure is only supported if bit XMRS_FLAG_MULT_INSTC_SUPP
- * is set in XMULTI_REF_STATUS::flags.
+ * The field ::XMULTI_REF_INSTANCES::n_xmr_settings reports the maximum number
+ * of entries that can be held by the input source table provided by this device.
+ * The input source table entry with the lowest index has the highest priority,
+ * and values 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 can be used as index
+ * when reading ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX from the device,
+ * or when writing ::XMULTI_REF_SETTINGS_IDX to the device to configure
+ * the priority/order of input sources.
+ *
+ * An input source table entry is empty if ::XMULTI_REF_ID::type is set to
+ * ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id, and accordingly
+ * in ::XMULTI_REF_STATUS::id.
+ *
+ * The array ::XMULTI_REF_INSTANCES::n_inst reports how many instances are supported
+ * for every known reference type. For example, if 2 PPS input signals were supported
+ * then ::XMULTI_REF_INSTANCES::n_inst[::MULTI_REF_PPS] was set to 2. Even though
+ * this array can hold up to ::MAX_N_MULTI_REF_TYPES entries, the number entries
+ * which are actually used is ::N_MULTI_REF, according to the number of known
+ * reference signal types, which is less or equal than ::MAX_N_MULTI_REF_TYPES.
*/
typedef struct
{
- uint32_t flags; /**< currently always 0 */
- uint16_t n_xmr_settings; /**< number of configurable multi ref settings */
- uint16_t reserved; /**< number of configurable multi ref settings */
- uint8_t n_inst[32]; /**< N_MULTI_REF entries used, but can not exceed bit number of uint32_t - 1 */
+ uint32_t flags; ///< see ::XMR_INST_FLAG_BIT_MASKS
+ uint16_t n_xmr_settings; ///< number of ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX which can be retrieved
+ uint8_t slot_id; ///< ID of the slot in which this device is installed, 0 or up to 15, if multiple slots not supported
+ uint8_t reserved; ///< reserved, don't use, currently always 0
+ uint8_t n_inst[MAX_N_MULTI_REF_TYPES]; ///< the number of supported instances of each input signal type
+
} XMULTI_REF_INSTANCES;
-/** @} group_xmr_cfg */
+#define _mbg_swab_xmulti_ref_instances( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->n_xmr_settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of flag bits used with XMULTI_REF instances
+ *
+ * @see ::XMR_INST_FLAG_BIT_MASKS
+ */
+enum XMR_INST_FLAGS
+{
+ /// This flag indicates that configuration programs may set
+ /// ::XMULTI_REF_ID::type to ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id
+ /// for unused priority levels, and that this will be reflected in
+ /// ::XMULTI_REF_STATUS::id accordingly. With some older firmware versions
+ /// this was not supported.
+ XMRIF_BIT_MRF_NONE_SUPP,
+
+ XMRIF_BIT_HOLDOVER_STATUS_SUPP, ///< ::XMR_HOLDOVER_STATUS and associated types supported
+
+ XMRIF_BIT_EXT_SRC_INFO_SUPP, ///< ::XMR_EXT_SRC_INFO structure supported
+
+ N_XMRIF_BITS ///< number of known flag bits
+};
+
+
+/**
+ * @brief Bit masks associated with ::XMR_INST_FLAGS
+ *
+ * Used with ::XMULTI_REF_INSTANCES::flags.
+ *
+ * @see ::XMR_INST_FLAGS
+ */
+enum XMR_INST_FLAG_BIT_MASKS
+{
+ XMRIF_MSK_MRF_NONE_SUPP = ( 1UL << XMRIF_BIT_MRF_NONE_SUPP ), ///< see ::XMRIF_BIT_MRF_NONE_SUPP
+ XMRIF_MSK_HOLDOVER_STATUS_SUPP = ( 1UL << XMRIF_BIT_HOLDOVER_STATUS_SUPP ), ///< see ::XMRIF_BIT_HOLDOVER_STATUS_SUPP
+ XMRIF_MSK_EXT_SRC_INFO_SUPP = ( 1UL << XMRIF_BIT_EXT_SRC_INFO_SUPP ) ///< see ::XMRIF_BIT_EXT_SRC_INFO_SUPP
+};
+
+
+
+/**
+ * @brief XMR holdover interval, or elapsed holdover time, in [s]
+ */
+typedef uint32_t XMR_HOLDOVER_INTV;
+
+#define _mbg_swab_xmr_holdover_intv( _p ) \
+ _mbg_swab32( _p )
+
+
+
+/**
+ * @brief A code used to indicate that a input source table index is unspecified
+ */
+#define XMR_PRIO_LVL_UNSPEC -1
+
+
+/**
+ * @brief XMR holdover status
+ *
+ * Only supported if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags
+ *
+ * Reports the current holdover status including the elapsed holdover time
+ * and the currently active holdover interval, as well as the indices of the
+ * current and next XMR time source.
+ *
+ * The flag ::XMR_HLDOVR_MSK_IN_HOLDOVER is set if holdover mode is currently active.
+ *
+ * The fields ::XMR_HOLDOVER_STATUS::curr_prio and ::XMR_HOLDOVER_STATUS::nxt_prio
+ * specify the current or next priority level which can be in the range
+ * 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, or ::XMR_PRIO_LVL_UNSPEC if the
+ * index is undefined, e.g. because no input source is available to which can
+ * be switched after the holdover interval.
+ *
+ * The ::XMR_HOLDOVER_STATUS::mode field indicates the current XMR/holdover mode
+ * which is usually ::XMR_HLDOVR_AUTONOMOUS. However, in certain applications
+ * XMR switching is controlled remotely, in which case ::XMR_HOLDOVER_STATUS::mode
+ * is set to ::XMR_HLDOVR_REMOTE.
+ *
+ * If the device is in remote mode and needs to switch XMR sources then mode changes
+ * to ::XMR_HLDOVR_PRE_AUTONOMOUS, and the ::XMR_HOLDOVER_STATUS::remote_watchdog
+ * starts to count down. If the watchdog expires before a remote switch command
+ * has been received the device switches to ::XMR_HLDOVR_AUTONOMOUS.
+ */
+typedef struct
+{
+ uint8_t mode; ///< XMR/holdover mode, see ::XMR_HOLDOVER_STATUS_MODES
+ int8_t curr_prio; ///< current priority level, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ int8_t nxt_prio; ///< next priority level after holdover, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC
+ uint8_t remote_watchdog; ///< counts down in ::XMR_HLDOVR_PRE_AUTONOMOUS mode
+ uint32_t time_offset_ns; ///< estimated time offset in holdover operation
+ XMR_HOLDOVER_INTV elapsed; ///< elapsed time in holdover mode, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ XMR_HOLDOVER_INTV interval; ///< current holdover interval, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set
+ uint32_t flags; ///< holdover status flags, see ::XMR_HOLDOVER_STATUS_FLAG_MASKS
+
+} XMR_HOLDOVER_STATUS;
+
+#define _mbg_swab_xmr_holdover_status( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->mode ); \
+ _mbg_swab8( &(_p)->curr_prio ); \
+ _mbg_swab8( &(_p)->nxt_prio ); \
+ _mbg_swab8( &(_p)->remote_watchdog ); \
+ _mbg_swab32( &(_p)->time_offset_ns ); \
+ _mbg_swab_xmr_holdover_intv( &(_p)->elapsed ); \
+ _mbg_swab_xmr_holdover_intv( &(_p)->interval ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+
+/**
+ * @brief XMR holdover status modes
+ *
+ * Used with ::XMR_HOLDOVER_STATUS::mode.
+ *
+ * @see ::XMR_HOLDOVER_STATUS_MODE_NAMES
+ */
+enum XMR_HOLDOVER_STATUS_MODES
+{
+ XMR_HLDOVR_AUTONOMOUS, ///< autonomous mode, XMR sources are selected automatically by the device
+ XMR_HLDOVR_PRE_AUTONOMOUS, ///< going to switch to autonomous mode when ::XMR_HOLDOVER_STATUS::remote_watchdog reaches 0
+ XMR_HLDOVR_REMOTE, ///< remote mode, XMR switching done by external command/control
+ N_XMR_HOLDOVER_STATUS_MODES ///< the number of known modes
+};
+
+
+/**
+ * @brief String initializers for XMR holdover status mode
+ *
+ * @see ::XMR_HOLDOVER_STATUS_MODES
+ */
+#define XMR_HOLDOVER_STATUS_MODE_NAMES \
+{ \
+ "Autonomous", \
+ "Pre-Autonomous", \
+ "Remote" \
+}
+
+
+
+/**
+ * @brief XMR holdover status flag bits
+ *
+ * Used to define ::XMR_HOLDOVER_STATUS_FLAG_MASKS.
+ */
+enum XMR_HOLDOVER_STATUS_FLAG_BITS
+{
+ XMR_HLDOVR_BIT_IN_HOLDOVER, ///< the device is currently in holdover mode
+ XMR_HLDOVR_BIT_TRANSITION_ENBD, ///< timebase is in transition (being slewed) after sources have been switched
+ XMR_HLDOVR_BIT_IN_TRANSITION, ///< transition is currently active, slewing in progress
+ XMR_HLDOVR_BIT_TIME_OFFS_VALID, ///< values in field ::XMR_HOLDOVER_STATUS::time_offset_ns are valid
+ N_XMR_HOLDOVER_STATUS_FLAG_BITS ///< the number of known status flags
+};
+
+
+/**
+ * @brief XMR holdover status flag masks
+ *
+ * Used with ::XMR_HOLDOVER_STATUS::flags.
+ */
+enum XMR_HOLDOVER_STATUS_FLAG_MASKS
+{
+ XMR_HLDOVR_MSK_IN_HOLDOVER = ( 1UL << XMR_HLDOVR_BIT_IN_HOLDOVER ), ///< see ::XMR_HLDOVR_BIT_IN_HOLDOVER
+ XMR_HLDOVR_MSK_TRANSITION_ENBD = ( 1UL << XMR_HLDOVR_BIT_TRANSITION_ENBD ), ///< see ::XMR_HLDOVR_BIT_TRANSITION_ENBD
+ XMR_HLDOVR_MSK_IN_TRANSITION = ( 1UL << XMR_HLDOVR_BIT_IN_TRANSITION ), ///< see ::XMR_HLDOVR_BIT_IN_TRANSITION
+ XMR_HLDOVR_MSK_TIME_OFFS_VALID = ( 1UL << XMR_HLDOVR_BIT_TIME_OFFS_VALID ) ///< see ::XMR_HLDOVR_BIT_TIME_OFFS_VALID
+};
+
+
+
+/**
+ * @brief XMR source feature flag bits
+ *
+ * Used to define ::XMR_EXT_SRC_FEAT_FLAG_MSKS
+ */
+enum XMR_EXT_SRC_FEAT_FLAG_BITS
+{
+ XMR_EXT_SRC_FEAT_FLAG_BIT_STATS, ///< XMR source provides ::XMR_STATS
+ XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS, ///< XMR source provides ::XMR_METRICS
+ N_XMR_EXT_SRC_FEAT_FLAG_BITS
+};
+
+
+
+/**
+ * @brief XMR source feature flag bit masks
+ *
+ * Used with ::XMR_EXT_SRC_INFO::feat_flags.
+ *
+ * @see ::XMR_EXT_SRC_FEAT_FLAG_BITS
+ */
+enum XMR_EXT_SRC_FEAT_FLAG_MSKS
+{
+ XMR_EXT_SRC_FEAT_FLAG_MSK_STATS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_STATS ), ///< see ::XMR_EXT_SRC_FEAT_FLAG_BIT_STATS
+ XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS ) ///< see ::XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS
+};
+
+
+
+typedef struct
+{
+ uint16_t supp_flags; ///< indicates which flags are supported by ::XMULTI_REF_SETTINGS::flags, see ::XMR_SETTINGS_FLAG_MSKS
+ uint16_t feat_flags; ///< see ::XMR_EXT_SRC_FEAT_FLAG_MSKS
+ uint32_t reserved_0;
+
+} XMR_EXT_SRC_INFO;
+
+#define _mbg_swab_xmr_ext_src_info( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->supp_flags ); \
+ _mbg_swab16( &(_p)->feat_flags ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint16_t idx; //
+ XMR_EXT_SRC_INFO info; //
+
+} XMR_EXT_SRC_INFO_IDX; //
+
+#define _mbg_swab_xmr_ext_src_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmr_ext_src_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief XMR statistics for a particular source
+ *
+ * This structure is only provided by an XMR source which has
+ * ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS set in ::XMR_EXT_SRC_INFO::feat_flags.
+ *
+ * @see ::XMR_STATS_IDX
+ * @see ::XMR_EXT_SRC_INFO::feat_flags
+ * @see ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS
+ */
+typedef struct
+{
+ uint32_t timestamp; ///< time stamp when the record was taken, UTC, seconds since 1970
+ NANO_TIME last_mue; ///< mean value (mue) of prev. interval
+ NANO_TIME last_sigma; ///< standard deviation (sigma) of prev. interval
+ NANO_TIME last_max; ///< maximum value within interval
+ NANO_TIME last_min; ///< minimum value within interval
+ NANO_TIME reserved_0; ///< currently reserved, unused, always 0
+ NANO_TIME step_comp_val; ///< current step compensation value
+ NANO_TIME auto_bias; ///< current time automatic bias compensation
+ uint32_t reserved_1; ///< currently reserved, unused, always 0
+ uint32_t reserved_2; ///< currently reserved, unused, always 0
+ uint32_t flags; ///< see ::XMR_STATS_FLAGS_MSKS
+
+} XMR_STATS;
+
+#define _mbg_swab_xmr_stats( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->timestamp ); \
+ _mbg_swab_nano_time( &(_p)->last_mue ); \
+ _mbg_swab_nano_time( &(_p)->last_sigma ); \
+ _mbg_swab_nano_time( &(_p)->last_max ); \
+ _mbg_swab_nano_time( &(_p)->last_min ); \
+ _mbg_swab_nano_time( &(_p)->reserved_0 ); \
+ _mbg_swab_nano_time( &(_p)->step_comp_val ); \
+ _mbg_swab_nano_time( &(_p)->auto_bias ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of bits used to define ::XMR_STATS_FLAGS_MSKS
+ *
+ * @see ::XMR_STATS_FLAGS_MSKS
+ */
+enum XMR_STATS_FLAGS_BITS
+{
+ XMR_STATS_FLAG_BIT_STEP_DETECTED, ///< A time step was detected at the input source
+ XMR_STATS_FLAG_BIT_STEP_COMPENSATED, ///< A time step was compensated at the input source
+ XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID, ///< The value in ::XMR_STATS::auto_bias is valid
+ N_XMR_STATS_FLAGS_BITS
+};
+
+
+
+/**
+ * @brief Flag bit masks used with ::XMR_STATS::flags
+ *
+ * @see ::XMR_STATS_FLAGS_BITS
+ */
+enum XMR_STATS_FLAGS_MSKS
+{
+ XMR_STATS_FLAG_MSK_STEP_DETECTED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_DETECTED ), ///< see ::XMR_STATS_FLAG_BIT_STEP_DETECTED
+ XMR_STATS_FLAG_MSK_STEP_COMPENSATED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_COMPENSATED ), ///< see ::XMR_STATS_FLAG_BIT_STEP_COMPENSATED
+ XMR_STATS_FLAG_MSK_AUTO_BIAS_VALID = ( 1UL << XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID ) ///< see ::XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID
+};
+
+
+
+/**
+ * @brief String initializers for XMR Stats Flags
+ *
+ * @see ::XMR_STATS_FLAGS_MSKS
+ */
+#define DEFAULT_XMR_STATS_FLAG_NAMES \
+{ \
+ "Step Detected", \
+ "Step Compensated", \
+ "Auto BIAS valid" \
+}
+
+
+
+/**
+ * @brief XMR statistics for a particular source, with index
+ *
+ * @see ::XMR_STATS
+ */
+typedef struct
+{
+ uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1
+ XMR_STATS stats; ///< XMR statistics of the particular source
+
+} XMR_STATS_IDX;
+
+#define _mbg_swab_xmr_stats_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmr_stats( &(_p)->stats ); \
+} while ( 0 )
+
+
+
+#define MAX_XMR_METRICS 20
+
+typedef struct
+{
+ uint32_t timestamp;
+ uint32_t flags; ///< idx bit set if mtie[idx] is valid
+ uint8_t mtie_scale; ///< scale factors of MTIE
+ uint8_t tdev_scale; ///< scale factors of TDEV
+ uint16_t reserved_0; ///< currently unused
+ uint32_t reserved_1; ///< currently unused
+ uint32_t reserved_2; ///< currently unused
+ uint32_t mtie[MAX_XMR_METRICS]; ///< mtie scaled 32 bit fixed point unsigned
+ uint32_t tdev[MAX_XMR_METRICS]; ///< tdev scaled 32 bit fixed point unsigned
+
+} XMR_METRICS;
+
+#define _mbg_swab_xmr_metrics( _p ) \
+do \
+{ \
+ int i; \
+ \
+ _mbg_swab32( &(_p)->timestamp ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->mtie_scale ); \
+ _mbg_swab8( &(_p)->tdev_scale ); \
+ _mbg_swab16( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ \
+ for ( i = 0; i < MAX_XMR_METRICS; i++ ) \
+ _mbg_swab32( &(_p)->mtie[i] ); \
+ \
+ for ( i = 0; i < MAX_XMR_METRICS; i++ ) \
+ _mbg_swab32( &(_p)->tdev[i] ); \
+ \
+} while ( 0 )
+
+
+
+// conversion factor scaled FPU32 to double
+#define _fpu32_to_double_fac( _x ) ( 1.0 / ( 4294967296.0 * ( _x ) ) )
+
+
+
+/**
+ * @brief XMR timing metrics for a particular source, with index
+ *
+ * @see ::XMR_METRICS
+ */
+typedef struct
+{
+ uint16_t idx;
+ XMR_METRICS metrics;
+
+} XMR_METRICS_IDX;
+
+#define _mbg_swab_xmr_metrics_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_xmr_metrics( &(_p)->metrics ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of ITU limit masks
+ *
+ * Used for detection of ::XMR_METRICS mask violation.
+ *
+ * @see ::ITU_LIMIT_MASKS
+ * @see ::XMR_METRICS
+ */
+enum ITU_LIMITS
+{
+ ITU_LIMIT_G811_PRC,
+ ITU_LIMIT_G823_SSU,
+ ITU_LIMIT_G823_SEC,
+ ITU_LIMIT_G8272_PRTC,
+ ITU_LIMIT_G82721_EPRTC,
+ N_ITU_LIMITS
+} ;
+
+
+
+/**
+ * @brief Enumeration of ITU limit masks
+ *
+ * Used for detection of ::XMR_METRICS mask violation.
+ *
+ * @see ::ITU_LIMITS
+ * @see ::XMR_METRICS
+ */
+enum ITU_LIMIT_MASKS
+{
+ MSK_ITU_LIMIT_G811_PRC = ( 1UL << ITU_LIMIT_G811_PRC ),
+ MSK_ITU_LIMIT_G823_SSU = ( 1UL << ITU_LIMIT_G823_SSU ),
+ MSK_ITU_LIMIT_G823_SEC = ( 1UL << ITU_LIMIT_G823_SEC ),
+ MSK_ITU_LIMIT_G8272_PRTC = ( 1UL << ITU_LIMIT_G8272_PRTC ),
+ MSK_ITU_LIMIT_G82721_EPRTC = ( 1UL << ITU_LIMIT_G82721_EPRTC )
+};
+
+
+
+/**
+ * @brief String initializers for ITU limit masks
+ *
+ * Used for detection of ::XMR_METRICS mask violation.
+ *
+ * @see ::ITU_LIMITS
+ * @see ::XMR_METRICS
+ */
+#define ITU_LIMIT_SHORT_STRS \
+{ \
+ "G811 (PRC)", \
+ "G823 (SSU)", \
+ "G823 (SEC)", \
+ "G8272 (PRTC)", \
+ "G82721 (ePRTC)" \
+}
+
+
+
+/**
+ * @brief supported limits for qualtity metrics
+ *
+ * @see ::XMR_METRICS
+ */
+typedef struct
+{
+ uint8_t ql_mask; ///< see :ITU_LIMIT_MASKS
+ uint8_t hysteresis; ///< hysteresis (percent) between yellow and red alarm
+ uint16_t reserved_0;
+ uint32_t reserved_1;
+
+} XMR_QL_SETTINGS;
+
+
+
+typedef struct
+{
+ uint32_t supp_ql_masks; ///< see :ITU_LIMIT_MASKS
+ uint32_t reserved_0;
+ uint32_t reserved_1;
+ XMR_QL_SETTINGS settings;
+
+} XMR_QL_INFO;
+
+
+
+typedef struct
+{
+ uint16_t idx;
+ XMR_QL_SETTINGS settings;
+
+} XMR_QL_SETTINGS_IDX;
+
+
+
+typedef struct
+{
+ uint16_t idx;
+ XMR_QL_INFO info;
+
+} XMR_QL_INFO_IDX;
+
+
+/** @} defgroup group_multi_ref_ext */
+
+/** @} defgroup group_multi_ref_all */
/**
* @defgroup group_gpio GPIO port configuration stuff
*
+ * @note This is only supported if ::GPS_HAS_GPIO is set
+ * in the ::RECEIVER_INFO::features mask.
+ *
* @{ */
+
/**
* @brief General GPIO config info to be read from a device
+ *
+ * Used to query from a device how many GPIO ports are supported
+ * by the device, then index 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ * configuration or status records can be read from or written to
+ * the device.
*/
typedef struct
{
- uint32_t num_io; /**< number of supported GPIO ports */
- uint32_t reserved; /**< currently always 0 */
- uint32_t flags; /**< currently always 0 */
+ uint32_t num_io; ///< number of supported GPIO ports
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
} MBG_GPIO_CFG_LIMITS;
+#define _mbg_swab_mbg_gpio_cfg_limits( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->num_io ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief GPIO limits flag bits used to define ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+ *
+ * @see ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+ */
+enum MBG_GPIO_CFG_LIMIT_FLAG_BITS
+{
+ MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP, ///< indicates that ::MBG_GPIO_STATUS is supported
+ N_MBG_GPIO_CFG_LIMIT_FLAG_BITS
+};
+
+
+
+/**
+ * @brief GPIO limits flag masks associated with ::MBG_GPIO_CFG_LIMIT_FLAG_BITS
+ *
+ * Used with ::MBG_GPIO_CFG_LIMITS::flags
+ *
+ * @see ::MBG_GPIO_CFG_LIMIT_FLAG_BITS
+ */
+enum MBG_GPIO_CFG_LIMIT_FLAG_MASKS
+{
+ MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP = ( 1UL << MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP ), ///< see ::MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP
+};
+
+
+
+/**
+ * @brief Enumeration of GPIO types
+ *
+ * Usually a specific GPIO port can only be either an input
+ * or an output, and supports only a single signal type.
+ * This is due to hardware limitations, i.e. input or output
+ * circuitry required for the given signal.
+ *
+ * @see ::DEFAULT_GPIO_TYPES_SHORT_STRS
+ */
+enum MBG_GPIO_TYPES
+{
+ MBG_GPIO_TYPE_FREQ_IN, ///< Variable frequency input, freq == 0 if input not used
+ MBG_GPIO_TYPE_FREQ_OUT, ///< Variable frequency output
+ MBG_GPIO_TYPE_FIXED_FREQ_OUT, ///< Fixed frequency output
+ MBG_GPIO_TYPE_BITS_IN, ///< Framed data stream input
+ MBG_GPIO_TYPE_BITS_OUT, ///< Framed data stream output
+ MBG_GPIO_TYPE_VIDEO_OUT, ///< Video signal output (PAL, NTSC, ...)
+ MBG_GPIO_TYPE_VIDEO_SYNC_OUT, ///< Video sync signal output (H-Sync, V-Sync, ...)
+ MBG_GPIO_TYPE_STUDIO_CLOCK_OUT, ///< Studio clock output
+ MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT, ///< Digital Audio output (DARS, ...)
+ N_MBG_GPIO_TYPES ///< Number of known types
+};
+
+
+
+#define DEFAULT_GPIO_TYPES_SHORT_STRS \
+{ \
+ "Freq. In", \
+ "Freq. Out", \
+ "Fixed Freq Out", \
+ "BITS In", \
+ "BITS Out", \
+ "Video Out", \
+ "Video Sync Out", \
+ "Studio Clock Out", \
+ "Digital Audio Out" \
+}
+
+
+
+/**
+ * @brief Enumeration of known signal shapes
+ *
+ * Used to specify the signal shape of an input or output
+ * frequency signal.
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ * @see ::DEFAULT_GPIO_SIGNAL_SHAPE_NAMES
+ */
+enum MBG_GPIO_SIGNAL_SHAPES
+{
+ MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED, ///< unknown or unspecified signal shape
+ MBG_GPIO_SIGNAL_SHAPE_SINE, ///< sine wave
+ MBG_GPIO_SIGNAL_SHAPE_SQUARE, ///< square wave
+ N_MBG_GPIO_SIGNAL_SHAPES ///< number of known signal shapes
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_SIGNAL_SHAPES
+ *
+ * Used e.g. with ::MBG_GPIO_FREQ_IN_SUPP::supp_shapes,
+ * ::MBG_GPIO_FREQ_OUT_SUPP::supp_shapes,
+ * and ::MBG_GPIO_FIXED_FREQ_OUT_SUPP::supp_shapes.
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPES
+ */
+enum MBG_GPIO_SIGNAL_SHAPE_MASKS
+{
+ MBG_GPIO_SIGNAL_SHAPE_MSK_UNSPECIFIED = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED ), ///< see ::MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED
+ MBG_GPIO_SIGNAL_SHAPE_MSK_SINE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SINE ), ///< see ::MBG_GPIO_SIGNAL_SHAPE_SINE
+ MBG_GPIO_SIGNAL_SHAPE_MSK_SQUARE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SQUARE ) ///< see ::MBG_GPIO_SIGNAL_SHAPE_SQUARE
+};
+
+
+
+/**
+ * @brief String initializers for GPIO signal shapes
+ *
+ * @see ::MBG_GPIO_SIGNAL_SHAPES
+ */
+#define DEFAULT_GPIO_SIGNAL_SHAPE_NAMES \
+{ \
+ "(unspec. shape)", \
+ "Sine wave", \
+ "Rectangle Pulse" \
+}
+
/**
* @brief A structure used to specify a variable frequency
+ *
+ * Used to specify a variable frequency for GPIO input or output
*/
typedef struct
{
- uint32_t hz; /**< integral number, Hz */
- uint32_t frac; /**< fractional part, binary */
+ uint32_t hz; ///< integral number [Hz]
+ uint32_t frac; ///< fractional part, binary (0x80000000 --> 0.5, 0xFFFFFFFF --> 0.9999999...)
} MBG_GPIO_FREQ;
+#define _mbg_swab_mbg_gpio_freq( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->hz ); \
+ _mbg_swab32( &(_p)->frac); \
+} while ( 0 )
+
+
/**
- * @brief A structure used to specify a fixed frequency
+ * @brief Configuration of a GPIO variable frequency input
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_IN
+ * @see ::MBG_GPIO_SETTINGS
*/
typedef struct
{
- uint32_t frq_bit; /**< fixed freq. bit mask ( see enum ) */
- uint32_t reserved; /**< reserved */
+ MBG_GPIO_FREQ freq; ///< frequency in range ::MBG_GPIO_FREQ_IN_SUPP::freq_min..::MBG_GPIO_FREQ_IN_SUPP::freq_max, or 0 if input is not used
+ uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units], see ::MBG_GPIO_FREQ_IN_SUPP::csc_limit_max
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_IN_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_freq_in_settings( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \
+ _mbg_swab32( &(_p)->csc_limit ); \
+ _mbg_swab32( &(_p)->shape ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
-} MBG_GPIO_FIXED_FREQ;
/**
- * @brief A structure used to configure a GPIO as frequency output
+ * @brief Supported options for a variable frequency GPIO input
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_IN
+ * @see ::MBG_GPIO_LIMITS
*/
typedef struct
{
- MBG_GPIO_FREQ freq; /**< frequency */
- int32_t milli_phase; /**< phase [1/1000 degree units] */
- uint32_t type; /**< sine, rectangle, etc. */ //##++++++++++++++
- uint32_t reserved; /**< currently always 0 */
- uint32_t flags; /**< currently always 0 */
+ uint32_t freq_min; ///< minimum output frequency [Hz]
+ uint32_t freq_max; ///< maximum output frequency [Hz]
+ uint32_t csc_limit_max; ///< 1/1000 units of the signal period, limited due to 10 ns sampling interval, see ::MBG_GPIO_FREQ_IN_SETTINGS::csc_limit //##++++++++++++++++
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t supp_limits; ///< supported ITU limit masks for BITS signal see ::ITU_LIMIT_MASKS
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_IN_SUPP;
+
+#define _mbg_swab_mbg_gpio_freq_in_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->freq_min ); \
+ _mbg_swab32( &(_p)->freq_max ); \
+ _mbg_swab32( &(_p)->csc_limit_max ); \
+ _mbg_swab32( &(_p)->supp_shapes ); \
+ _mbg_swab32( &(_p)->supp_limits ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
-} MBG_GPIO_FREQ_OUT_SETTINGS;
/**
- * @brief A structure used to configure a GPIO as frequency output
+ * @brief Configuration of a GPIO variable frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_OUT
+ * @see ::MBG_GPIO_SETTINGS
*/
+typedef struct
+{
+ MBG_GPIO_FREQ freq; ///< frequency, see ::MBG_GPIO_FREQ_OUT_SUPP::freq_min and ::MBG_GPIO_FREQ_OUT_SUPP::freq_max
+ int32_t milli_phase; ///< phase [1/1000 degree units], see ::MBG_GPIO_FREQ_OUT_SUPP::milli_phase_max
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_freq_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \
+ _mbg_swab32( &(_p)->milli_phase ); \
+ _mbg_swab32( &(_p)->shape ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Supported options for a variable frequency GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FREQ_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
typedef struct
{
- MBG_GPIO_FREQ freq; /**< frequency */
- uint32_t csc_limit; /**< max. cycle slip [1/1000 cycle units] */
- uint32_t type; /**< sine, rectangle, etc. */ //##++++++++++++++
- uint32_t reserved; /**< currently always 0 */
- uint32_t flags; /**< currently always 0 */
+ uint32_t freq_min; ///< minimum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq
+ uint32_t freq_max; ///< maximum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq
+ uint32_t freq_resolution; ///< frequency resolution [Hz], unspecified if 0
+ uint32_t milli_phase_max; ///< max. abs. milli_phase, see ::MBG_GPIO_FREQ_OUT_SETTINGS::milli_phase
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FREQ_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_freq_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->freq_min ); \
+ _mbg_swab32( &(_p)->freq_max ); \
+ _mbg_swab32( &(_p)->freq_resolution ); \
+ _mbg_swab32( &(_p)->milli_phase_max ); \
+ _mbg_swab32( &(_p)->supp_shapes ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
-} MBG_GPIO_FREQ_IN_SETTINGS;
+
+
+/**
+ * @brief Enumeration of predefined fixed frequencies
+ *
+ * @see ::MBG_GPIO_FIXED_FREQ_MASKS
+ * @see ::MBG_GPIO_FIXED_FREQ_STRS
+ */
+enum MBG_GPIO_FIXED_FREQS
+{
+ MBG_GPIO_FIXED_FREQ_8kHz, ///< 8 kHz
+ MBG_GPIO_FIXED_FREQ_48kHz, ///< 48 kHz
+ MBG_GPIO_FIXED_FREQ_1MHz, ///< 1 MHz
+ MBG_GPIO_FIXED_FREQ_1544kHz, ///< 1.544 MHz
+ MBG_GPIO_FIXED_FREQ_2048kHz, ///< 2.048 MHz
+ MBG_GPIO_FIXED_FREQ_5MHz, ///< 5 MHz
+ MBG_GPIO_FIXED_FREQ_10MHz, ///< 10 MHz
+ MBG_GPIO_FIXED_FREQ_19440kHz, ///< 19.44 MHz
+ N_MBG_GPIO_FIXED_FREQ ///< number of predefined fixed frequencies
+};
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_FIXED_FREQS
+ *
+ * @see ::MBG_GPIO_FIXED_FREQS
+ * @see ::MBG_GPIO_FIXED_FREQ_STRS
+ */
+enum MBG_GPIO_FIXED_FREQ_MASKS
+{
+ MSK_MBG_GPIO_FIXED_FREQ_8kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_8kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_8kHz
+ MSK_MBG_GPIO_FIXED_FREQ_48kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_48kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_48kHz
+ MSK_MBG_GPIO_FIXED_FREQ_1MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_1MHz
+ MSK_MBG_GPIO_FIXED_FREQ_1544kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1544kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_1544kHz
+ MSK_MBG_GPIO_FIXED_FREQ_2048kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_2048kHz ), ///< see ::MBG_GPIO_FIXED_FREQ_2048kHz
+ MSK_MBG_GPIO_FIXED_FREQ_5MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_5MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_5MHz
+ MSK_MBG_GPIO_FIXED_FREQ_10MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_10MHz ), ///< see ::MBG_GPIO_FIXED_FREQ_10MHz
+ MSK_MBG_GPIO_FIXED_FREQ_19440kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_19440kHz ) ///< see ::MBG_GPIO_FIXED_FREQ_19440kHz
+};
+
+
+/**
+ * @brief Initializers for an array of GPIO fixed frequency name strings
+ *
+ * @see ::MBG_GPIO_FIXED_FREQS
+ * @see ::MBG_GPIO_FIXED_FREQ_MASKS
+ */
+#define MBG_GPIO_FIXED_FREQ_STRS \
+{ \
+ "8 kHz", \
+ "48 kHz", \
+ "1 MHz", \
+ "1544 kHz", \
+ "2048 kHz", \
+ "5 MHz", \
+ "10 MHz", \
+ "19440 kHz" \
+}
/**
- * @brief A structure used to configure a GPIO as fixed frequency output
+ * @brief Configuration of a GPIO fixed frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ * @see ::MBG_GPIO_SETTINGS
*/
typedef struct
{
- MBG_GPIO_FIXED_FREQ freq; /**< frequency */
- uint32_t reserved_0; /**< supported frequencies bit mask, see enum */
- uint32_t type; /**< sine, rectangle, etc. */ //##++++++++++++++
- uint32_t reserved_1; /**< currently always 0 */
- uint32_t flags; /**< currently always 0 */
+ uint32_t freq_idx; ///< fixed frequency index, see ::MBG_GPIO_FIXED_FREQS
+ uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
} MBG_GPIO_FIXED_FREQ_OUT_SETTINGS;
+#define _mbg_swab_mbg_gpio_fixed_freq_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->freq_idx ); \
+ _mbg_swab32( &(_p)->shape ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Supported options for a fixed frequency output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_freq; ///< bit mask of supported fixed frequencies, see ::MBG_GPIO_FIXED_FREQ_MASKS
+ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< reserved, currently always 0
+
+} MBG_GPIO_FIXED_FREQ_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_fixed_freq_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_freq ); \
+ _mbg_swab32( &(_p)->supp_shapes ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of BITS signal formats
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::format and ::MBG_GPIO_BITS_OUT_SETTINGS::format
+ *
+ * @see ::MBG_GPIO_BITS_FORMAT_MASKS
+ */
+enum MBG_GPIO_BITS_FORMATS
+{
+ MBG_GPIO_BITS_E1_FRAMED, ///< 2.048 MBit
+ MBG_GPIO_BITS_T1_FRAMED, ///< 1.544 MBit
+ MBG_GPIO_BITS_E1_TIMING, ///< 2.048 MHz
+ MBG_GPIO_BITS_T1_TIMING, ///< 2.048 MHz
+ N_MBG_GPIO_BITS_FORMATS ///< number of defined formats
+};
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_BITS_FORMATS
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SUPP::supp_fmts and ::MBG_GPIO_BITS_OUT_SUPP::supp_fmts.
+ *
+ * @see ::MBG_GPIO_BITS_FORMATS
+ */
+enum MBG_GPIO_BITS_FORMAT_MASKS
+{
+ MSK_MBG_GPIO_BITS_E1_FRAMED = ( 1UL << MBG_GPIO_BITS_E1_FRAMED ), ///< see ::MBG_GPIO_BITS_E1_FRAMED
+ MSK_MBG_GPIO_BITS_T1_FRAMED = ( 1UL << MBG_GPIO_BITS_T1_FRAMED ), ///< see ::MBG_GPIO_BITS_T1_FRAMED
+ MSK_MBG_GPIO_BITS_E1_TIMING = ( 1UL << MBG_GPIO_BITS_E1_TIMING ), ///< see ::MBG_GPIO_BITS_E1_TIMING
+ MSK_MBG_GPIO_BITS_T1_TIMING = ( 1UL << MBG_GPIO_BITS_T1_TIMING ) ///< see ::MBG_GPIO_BITS_T1_TIMING
+};
+
+
+/**
+ * @brief Initializers for an array of GPIO bit format strings
+ *
+ * @see ::MBG_GPIO_BITS_FORMATS
+ * @see ::MBG_GPIO_BITS_FORMAT_MASKS
+ */
+#define MBG_GPIO_BITS_FORMAT_STRS \
+{ \
+ "E1 Framed", \
+ "T1 Framed", \
+ "E1 Timing", \
+ "T1 Timing" \
+}
+
+
+
+/**
+ * @brief Minimum and maximum known SSM values
+ *
+ * Values according to ITU G.704-1998
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1.ssm
+ * and ::MBG_GPIO_BITS_OUT_SETTINGS::ssm.
+ */
+enum GPIO_SSM_VALS
+{
+ GPIO_SSM_UNKNOWN, ///< Quality unknown, existing synchronization network
+ GPIO_SSM_RSVD_1, ///< (reserved)
+ GPIO_SSM_G_811, ///< Rec. G.811
+ GPIO_SSM_RSVD_3, ///< (reserved)
+ GPIO_SSM_SSU_A, ///< SSU-A
+ GPIO_SSM_RSVD_5, ///< (reserved)
+ GPIO_SSM_RSVD_6, ///< (reserved)
+ GPIO_SSM_RSVD_7, ///< (reserved)
+ GPIO_SSM_SSU_B, ///< SSU-B
+ GPIO_SSM_RSVD_9, ///< (reserved)
+ GPIO_SSM_RSVD_10, ///< (reserved)
+ GPIO_SSM_RSVD_SETS, ///< Synchronous Equipment Timing Source (SETS)
+ GPIO_SSM_RSVD_12, ///< (reserved)
+ GPIO_SSM_RSVD_13, ///< (reserved)
+ GPIO_SSM_RSVD_14, ///< (reserved)
+ GPIO_SSM_DONT_USE, ///< don't use
+ N_GPIO_SSM_VALS
+};
+
+
+
+/**
+ * @brief Minimum and maximum SA BITS groups
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1::sa_bits
+ * and ::MBG_GPIO_BITS_OUT_SETTINGS::sa_bits.
+ */
+enum GPIO_SA_BITS_GROUPS
+{
+ MIN_SA_BITS_GROUP = 4,
+ MAX_SA_BITS_GROUP = 8
+};
+
+
+
+/**
+ * @brief Configuration of a GPIO as BITS input module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_IN
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units]
+
+ union quality
+ {
+ struct e1
+ {
+ uint8_t ssm; ///< minimum E1 SSM for acceptance, 0..::N_GPIO_SSM_VALS-1
+ uint8_t sa_bits; ///< sa bits group carrying SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP
+ uint16_t reserved; ///< reserved, currently always 0
+ } e1; ///< used with E1 formats
+
+ struct t1
+ {
+ uint8_t min_boc;
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint16_t reserved_1; ///< reserved, currently always 0
+ } t1; ///< used with T1 formats
+
+ uint32_t u32; ///< dummy to force at least 32 bit alignment
+
+ } quality;
+
+ uint32_t err_msk; ///< controls which types of error can be ignored, see ::MBG_GPIO_BITS_ERR_MASKS
+ uint32_t flags; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_IN_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_bits_in_settings( _p, _recv ) \
+do \
+{ \
+ uint32_t f = (_p)->format; \
+ if ( (_recv) ) \
+ _mbg_swab32( &f); \
+ _mbg_swab32( &(_p)->format ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->csc_limit ); \
+ switch( f ) \
+ { \
+ case MBG_GPIO_BITS_E1_FRAMED : \
+ case MBG_GPIO_BITS_E1_TIMING : \
+ _mbg_swab8( &(_p)->quality.e1.ssm ); \
+ _mbg_swab8( &(_p)->quality.e1.sa_bits ); \
+ _mbg_swab16( &(_p)->quality.e1.reserved ); \
+ break; \
+ \
+ case MBG_GPIO_BITS_T1_FRAMED : \
+ case MBG_GPIO_BITS_T1_TIMING : \
+ _mbg_swab8( &(_p)->quality.t1.min_boc ); \
+ _mbg_swab8( &(_p)->quality.t1.reserved_0 ); \
+ _mbg_swab16( &(_p)->quality.t1.reserved_1 ); \
+ break; \
+ \
+ default: \
+ break; \
+ } \
+ _mbg_swab32( &(_p)->err_msk ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of BITS input error conditions
+ */
+enum MBG_GPIO_BITS_ERRS
+{
+ MBG_GPIO_BITS_ERR_LOS, ///< loss of signal
+ MBG_GPIO_BITS_ERR_LOF, ///< loss of frame
+ N_MBG_GPIO_BITS_ERRS ///< number of known errors
+};
+
+
+/**
+ * @brief Bit masks associated with BITS input error conditions
+ *
+ * Used with ::MBG_GPIO_BITS_IN_SETTINGS::err_msk
+ *
+ * @see ::MBG_GPIO_BITS_ERRS
+ */
+enum MBG_GPIO_BITS_ERR_MASKS
+{
+ MSK_MBG_GPIO_BITS_ERR_LOS = ( 1UL << MBG_GPIO_BITS_ERR_LOS ), ///< see ::MBG_GPIO_BITS_ERR_LOS
+ MSK_MBG_GPIO_BITS_ERR_LOF = ( 1UL << MBG_GPIO_BITS_ERR_LOF ) ///< see ::MBG_GPIO_BITS_ERR_LOF
+};
+
+
+
+/**
+ * @brief Supported options of a BITS GPIO input
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_IN
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_IN_SUPP;
+
+#define _mbg_swab_mbg_gpio_bits_in_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_fmts ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Configuration of a GPIO as BITS output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS
+ uint32_t flags; ///< flags for encoder control etc., see ::MBG_GPIO_BITS_OUT_FLAG_MASKS
+ uint8_t sa_bits; ///< number of SA bit group for E1 SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP
+ uint8_t ssm; ///< ssm for E1 mode, 0..::N_GPIO_SSM_VALS-1
+ uint8_t boc; ///< boc for T1 mode, 0..0x1F //##++++++++++++++
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+ uint32_t reserved_2; ///< reserved, currently always 0
+ uint32_t reserved_3; ///< reserved, currently always 0
+
+} MBG_GPIO_BITS_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_bits_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->format ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->sa_bits ); \
+ _mbg_swab8( &(_p)->ssm ); \
+ _mbg_swab8( &(_p)->boc ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of flags used with BITS type GPIO outputs
+ *
+ * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS
+ * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS
+ */
+enum MBG_GPIO_BITS_OUT_FLAGS
+{
+ MBG_GPIO_BITS_OUT_FLAG_HDB3, ///< enable HDB3 encoding (E1 mode only)
+ MBG_GPIO_BITS_OUT_FLAG_B8ZS, ///< enable B8ZS encoding (T1 mode only)
+ N_MBG_GPIO_BITS_OUT_FLAGS ///< number of known flags
+};
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_BITS_OUT_FLAGS
+ *
+ * Used with ::MBG_GPIO_BITS_OUT_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_BITS_OUT_FLAGS
+ * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS
+ */
+enum MBG_GPIO_BITS_OUT_FLAG_MASKS
+{
+ MSK_MBG_GPIO_BITS_OUT_FLAG_HDB3 = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_HDB3 ), ///< see ::MBG_GPIO_BITS_OUT_FLAG_HDB3
+ MSK_MBG_GPIO_BITS_OUT_FLAG_B8ZS = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_B8ZS ) ///< see ::MBG_GPIO_BITS_OUT_FLAG_B8ZS
+};
+
+
+/**
+ * @brief String initializers for an array of GPIO BITS out flags
+ *
+ * @see ::MBG_GPIO_BITS_OUT_FLAGS
+ * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS
+ */
+#define MBG_GPIO_BITS_OUT_FLAG_STRS \
+{ \
+ "HDB3", \
+ "B8ZS" \
+}
+
+
+/**
+ * @brief Supported options of a BITS type GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_BITS_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS
+ uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_GPIO_BITS_OUT_FLAG_MASKS
+
+} MBG_GPIO_BITS_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_bits_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_fmts ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of Video signal formats
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::format
+ *
+ * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS
+ */
+enum MBG_GPIO_VIDEO_FORMATS
+{
+ MBG_GPIO_VIDEO_FORMAT_OFF, ///< OFF
+ MBG_GPIO_VIDEO_SD_FORMAT_NTSC, ///< NTSC 525i
+ MBG_GPIO_VIDEO_SD_FORMAT_PAL, ///< PAL standard (Germany) 625i
+ MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz, ///< SMPTE296M-3 720p at 50 Hz
+ MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz, ///< SMPTE274M-6 1080i at 50 Hz
+ MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz, ///< SMPTE296M-1 720p at 59.94 Hz
+ MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz, ///< SMPTE274M-7 1080i at 59.94 Hz
+ MBG_GPIO_VIDEO_SD_FORMAT_PAL_M, ///< PAL M (Brazil) 525i
+ N_MBG_GPIO_VIDEO_FORMATS ///< number of defined video formats
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_VIDEO_FORMATS
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SUPP::supp_formats
+ *
+ * @see ::MBG_GPIO_VIDEO_FORMATS
+ */
+enum MBG_GPIO_VIDEO_FORMAT_MASKS
+{
+ MSK_MBG_GPIO_VIDEO_FORMAT_OFF = ( 1UL << MBG_GPIO_VIDEO_FORMAT_OFF ), ///< see ::MBG_GPIO_VIDEO_FORMAT_OFF
+ MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_NTSC ), ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_NTSC
+ MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL ), ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_PAL
+ MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz
+ MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz
+ MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz
+ MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz
+ MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL_M ) ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_PAL_M
+};
+
+
+/**
+ * @brief A combination of bit masks for SD video formats
+ * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS
+ */
+#define MBG_GPIO_VIDEO_SD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC | MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL | \
+ MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M )
+
+/**
+ * @brief A combination of bit masks for HD video formats
+ * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS
+ */
+#define MBG_GPIO_VIDEO_HD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz | \
+ MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz )
+
+
+
+/**
+ * @brief Initializers for an array of video output name strings
+ *
+ * @see ::MBG_GPIO_VIDEO_FORMATS
+ * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS
+ */
+#define MBG_GPIO_VIDEO_OUT_STRS \
+{ \
+ "OFF", \
+ "NTSC (525i)", \
+ "PAL (625i)", \
+ "720p 50 Hz", \
+ "1080i 50 Hz", \
+ "720p 59.94 Hz", \
+ "1080i 59.94 Hz", \
+ "PAL M (525i)" \
+}
+
+
+
+/**
+ * @brief Enumeration of flags used with video type GPIO outputs
+ */
+enum MBG_GPIO_VIDEO_OUT_FLAGS
+{
+ MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF, ///< if set, Out1: HD, Out2: SD
+ MBG_GPIO_VIDEO_OUT_HAS_TC_SD, ///< supports Time Code for SD Black Bursts
+ N_MBG_GPIO_VIDEO_OUT_FLAGS ///< number of known flags
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_VIDEO_OUT_FLAGS
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_VIDEO_OUT_FLAGS
+ */
+enum MBG_GPIO_VIDEO_OUT_FLAG_MASKS
+{
+ MSK_MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF ), ///< see ::MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF
+ MSK_MBG_GPIO_VIDEO_OUT_HAS_TC_SD = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_TC_SD ) ///< see ::MBG_GPIO_VIDEO_OUT_HAS_TC_SD
+};
+
+
+
+/**
+ * @brief Enumeration of epochs used with video type GPIO outputs
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::epoch, and used to
+ * define ::MBG_GPIO_VIDEO_EPOCH_MASKS
+ *
+ * @see ::MBG_GPIO_VIDEO_EPOCH_MASKS
+ * @see ::MBG_GPIO_VIDEO_EPOCH_STRS
+ */
+enum MBG_GPIO_VIDEO_EPOCHS
+{
+ SMPTE_TAI_EPOCH_1970, ///< 1970-01-01 00:00:00
+ SMPTE_TAI_EPOCH_1958, ///< 1958-01-01 00:00:00
+ SMPTE_UTC_EPOCH_1972, ///< 1972-01-01 00:00:00
+ SMPTE_GPS_EPOCH_1980, ///< 1980-01-06 00:00:00
+ N_MBG_GPIO_VIDEO_EPOCHS ///< number of known epochs
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_VIDEO_EPOCHS
+ *
+ * Used with :: MBG_GPIO_VIDEO_OUT_SUPP::supp_epochs
+ *
+ * @see ::MBG_GPIO_VIDEO_EPOCHS
+ */
+enum MBG_GPIO_VIDEO_EPOCH_MASKS
+{
+ MSK_SMPTE_TAI_EPOCH_1970 = ( 1UL << SMPTE_TAI_EPOCH_1970 ), ///< see ::SMPTE_TAI_EPOCH_1970
+ MSK_SMPTE_TAI_EPOCH_1958 = ( 1UL << SMPTE_TAI_EPOCH_1958 ), ///< see ::SMPTE_TAI_EPOCH_1958
+ MSK_SMPTE_UTC_EPOCH_1972 = ( 1UL << SMPTE_UTC_EPOCH_1972 ), ///< see ::SMPTE_UTC_EPOCH_1972
+ MSK_SMPTE_GPS_EPOCH_1980 = ( 1UL << SMPTE_GPS_EPOCH_1980 ) ///< see ::SMPTE_GPS_EPOCH_1980
+};
+
+
+
+/**
+ * @brief Initializers for an array of video epoch strings
+ *
+ * @see ::MBG_GPIO_VIDEO_EPOCHS
+ */
+#define MBG_GPIO_VIDEO_EPOCH_STRS \
+{ \
+ "TAI D1970-01-01 T00:00:00", \
+ "TAI D1958-01-01 T00:00:00", \
+ "UTC D1972-01-01 T00:00:00", \
+ "GPS D1980-01-06 T00:00:00" \
+}
+
+
+
+/**
+ * @brief Enumeration of time code modes used with video type GPIO outputs
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode
+ *
+ */
+enum MBG_GPIO_VIDEO_TC_MODES
+{
+ MBG_GPIO_VIDEO_TC_MODE_NONE, ///< None
+ MBG_GPIO_VIDEO_TC_MODE_VITC, ///< Vertical Interval Time Code
+ N_MBG_GPIO_VIDEO_TC_MODES
+};
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_VIDEO_TC_MODES
+ *
+ * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode
+ *
+ */
+enum MBG_GPIO_VIDEO_TC_MODE_MASKS
+{
+ MSK_MBG_GPIO_VIDEO_TC_MODE_NONE = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_NONE ), ///< see ::MBG_GPIO_VIDEO_TC_MODE_NONE
+ MSK_MBG_GPIO_VIDEO_TC_MODE_VITC = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_VITC ) ///< see ::MBG_GPIO_VIDEO_TC_MODE_VITC
+};
+
+
+/**
+ * @brief Initializers for an array of video time code modes
+ *
+ * @see ::MBG_GPIO_VIDEO_TC_MODES
+ */
+#define MBG_GPIO_VIDEO_TC_MODE_STRS \
+{ \
+ "None", \
+ "VITC" \
+}
+
+
+
+/**
+ * @brief Configuration of a GPIO as video output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_VIDEO_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t format; ///< video format, see ::MBG_GPIO_VIDEO_FORMATS
+ uint32_t flags; ///< flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS
+ int32_t phase_offset; ///< Phase offset in [ns]
+ uint8_t epoch; ///< epoch, see ::MBG_GPIO_VIDEO_EPOCHS
+
+ uint8_t tc_mode; ///< time code mode, see ::MBG_GPIO_VIDEO_TC_MODES
+ uint8_t tc_line0; ///< first time code line location, valid lines: 6-22
+ uint8_t tc_line1; ///< second time code line location, valid lines: 6-22
+
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+
+} MBG_GPIO_VIDEO_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_video_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->format ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->phase_offset ); \
+ _mbg_swab8( &(_p)->epoch ); \
+ _mbg_swab8( &(_p)->tc_mode ); \
+ _mbg_swab8( &(_p)->tc_line0 ); \
+ _mbg_swab8( &(_p)->tc_line1 ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Supported options of a video type GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_VIDEO_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_formats; ///< supported video formats, see ::MBG_GPIO_VIDEO_FORMAT_MASKS
+ uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS
+ uint32_t supp_epochs; ///< supported epochs, see ::MBG_GPIO_VIDEO_EPOCH_MASKS
+
+ uint8_t supp_tc_modes; ///< supported tc_modes, see ::MBG_GPIO_VIDEO_TC_MODE_MASKS
+
+ uint8_t reserved0; ///< reserved, currently always 0
+ uint8_t reserved2; ///< reserved, currently always 0
+ uint16_t reserved3; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+
+} MBG_GPIO_VIDEO_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_video_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_formats ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_epochs ); \
+ _mbg_swab8( &(_p)->supp_tc_modes ); \
+ _mbg_swab8( &(_p)->reserved0 ); \
+ _mbg_swab16( &(_p)->reserved2 ); \
+ _mbg_swab16( &(_p)->reserved3 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of types used with video sync GPIO outputs
+ * Depends on configured video output
+ */
+enum MBG_GPIO_VIDEO_SYNC_TYPES
+{
+ MBG_GPIO_VIDEO_SYNC_TYPE_OFF, ///< Output Off
+ MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC, ///< SD horizontal sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC, ///< SD vertical sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME, ///< SD frame/field sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK, ///< SD blanking interval
+ MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC, ///< HD horizontal sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC, ///< HD vertical sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME, ///< HD frame/field sync
+ MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK, ///< HD blanking interval
+ N_MBG_GPIO_VIDEO_SYNC_TYPES ///< number of known types
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_VIDEO_SYNC_TYPES
+ *
+ * Used with ::MBG_GPIO_VIDEO_SYNC_OUT_SUPP::supp_types
+ *
+ * @see ::MBG_GPIO_VIDEO_SYNC_TYPES
+ */
+enum MBG_GPIO_VIDEO_SYNC_TYPE_MASKS
+{
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_OFF ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME ),
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK )
+};
+
+
+
+/**
+ * @brief Initializers for an array of video sync output name strings
+ *
+ * @see ::MBG_GPIO_VIDEO_SYNC_TYPES
+ * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS
+ */
+#define MBG_GPIO_VIDEO_SYNC_OUT_STRS \
+{ \
+ "OFF", \
+ "SD H-Sync", \
+ "SD V-Sync", \
+ "SD Frame", \
+ "SD Blank", \
+ "HD H-Sync", \
+ "HD V-Sync", \
+ "HD Frame", \
+ "HD Blank" \
+}
+
+
+
+/**
+ * @brief A combination of bit masks for SD video sync types
+ * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS
+ */
+#define MBG_GPIO_VIDEO_SYNC_SD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC | \
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK )
+
+/**
+ * @brief A combination of bit masks for HD video sync types
+ * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS
+ */
+#define MBG_GPIO_VIDEO_SYNC_HD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC | \
+ MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK )
+
+
+
+/**
+ * @brief Configuration of a GPIO as sync output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t type; ///< sync type, see :: MBG_GPIO_SYNC_TYPES
+ uint32_t flags; ///< flags, currently always 0
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+ uint32_t reserved2; ///< reserved, currently always 0
+ uint32_t reserved3; ///< reserved, currently always 0
+
+} MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_video_sync_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->type ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+ _mbg_swab32( &(_p)->reserved2 ); \
+ _mbg_swab32( &(_p)->reserved3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Supported options of a sync type GPIO output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_types; ///< supported types, see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS
+ uint32_t supp_flags; ///< supported flags, currently always 0
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+
+} MBG_GPIO_VIDEO_SYNC_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_video_sync_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_types ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of studio clock base frequencies
+ *
+ * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::base_freq
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS
+ */
+enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQS
+{
+ MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ, ///< 32 kHz base frequency
+ MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ, ///< 44.1 kHz base frequency
+ MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ, ///< 48 kHz base frequency
+ N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS ///< number of defined base frequencies
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS
+ *
+ * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_base_freqs
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS
+ */
+enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS
+{
+ MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ ), ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ
+ MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ ), ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ
+ MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ ) ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ
+};
+
+
+
+/**
+ * @brief Initializers for an array of base frequencies of studio clock output name strings
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS
+ * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS
+ */
+#define MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_STRS \
+{ \
+ "32 kHz", \
+ "44.1 kHz", \
+ "48 kHz" \
+}
+
+
+
+/**
+ * @brief Enumeration of studio clock scales
+ *
+ * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::scale
+ * Multiply scale with base frequency
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS
+ */
+enum MBG_GPIO_STUDIO_CLOCK_SCALES
+{
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_1,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_2,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_4,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_8,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_16,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_32,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_64,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_128,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_256,
+ MBG_GPIO_STUDIO_CLOCK_SCALE_512,
+ N_MBG_GPIO_STUDIO_CLOCK_SCALES ///< number of defined scales
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_SCALES
+ *
+ * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_scales[N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS]
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES
+ */
+enum MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS
+{
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_2 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_2
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_4 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_4
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_8 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_8
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_16 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_16
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_32 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_32
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_64 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_64 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_64
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_128 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_128 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_128
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_256 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_256 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_256
+ MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_512 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_512 ) ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_512
+};
+
+
+
+/**
+ * @brief Initializers for an array of scales of studio clock output name strings
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES
+ * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS
+ */
+#define MBG_GPIO_STUDIO_CLOCK_SCALE_STRS \
+{ \
+ "1/32", \
+ "1/16", \
+ "1/8", \
+ "1/4", \
+ "1/2", \
+ "1", \
+ "2", \
+ "4", \
+ "8", \
+ "16", \
+ "32", \
+ "64", \
+ "128", \
+ "256", \
+ "512" \
+}
+
+
+
+/**
+ * @brief Enumeration of flags used with studio clock type GPIO outputs
+ */
+enum MBG_GPIO_STUDIO_CLOCK_FLAGS
+{
+ MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED, ///< if set, enables output
+ N_MBG_GPIO_STUDIO_CLOCK_FLAGS ///< number of known flags
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_FLAGS
+ *
+ * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_STUDIO_CLOCK_FLAGS
+ */
+enum MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS
+{
+ MSK_MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED = ( 1UL << MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED ) ///< see ::MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED
+};
+
+
+
+/**
+ * @brief Configuration of a GPIO as studio clock output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t base_freq; ///< base frequency, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS
+ uint32_t scale; ///< scale, see ::MBG_GPIO_STUDIO_CLOCK_SCALES
+ uint32_t flags; ///< flags, see ::MBG_GPIO_STUDIO_CLOCK_FLAGS
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+
+} MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_studio_clock_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->base_freq ); \
+ _mbg_swab32( &(_p)->scale ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+} while ( 0 )
+
+
+
+#define MAX_SUPP_BASE_FREQUENCIES 8 ///< max. supported base frequencies for studio clock outputs
+
+/**
+ * @brief Configuration of a GPIO as studio clock output module
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint8_t supp_base_freqs; ///< supported base frequencies, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS
+ uint8_t reserved0; ///< reserved, currently always 0
+ uint16_t reserved1; ///< reserved, currently always 0
+ uint16_t supp_scales[MAX_SUPP_BASE_FREQUENCIES]; ///< supported scales for each base frequency, see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS
+ uint32_t supp_flags; ///< supported flags, see::MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS
+ uint32_t reserved2; ///< reserved, currently always 0
+
+} MBG_GPIO_STUDIO_CLOCK_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_studio_clock_out_supp( _p ) \
+do \
+{ \
+ uint8_t idx; \
+ _mbg_swab8( &(_p)->supp_base_freqs ); \
+ _mbg_swab8( &(_p)->reserved0 ); \
+ _mbg_swab16( &(_p)->reserved1 ); \
+ for( idx = 0; idx < MAX_SUPP_BASE_FREQUENCIES; idx++ ) \
+ _mbg_swab16( &(_p)->supp_scales[idx] ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of types used with GPIO type digital audio outputs
+ *
+ * Used with ::MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS::type, and to
+ * define ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS
+ *
+ * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS
+ * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS
+ */
+enum MBG_GPIO_DIGITAL_AUDIO_TYPES
+{
+ MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF,
+ MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS, ///< DARS
+ N_MBG_GPIO_DIGITAL_AUDIO_TYPES ///< number of known types
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_TYPES
+ *
+ * Used with :: MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT_SUPP::supp_types
+ *
+ * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPES
+ */
+enum MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS
+{
+ MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF ), ///< see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF
+ MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS ) ///< see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS
+};
+
+
+
+/**
+ * @brief Initializers for an array of video epoch strings
+ *
+ * @see ::MBG_GPIO_VIDEO_EPOCHS
+ */
+#define MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS \
+{ \
+ "OFF", \
+ "DARS" \
+}
+
+
+
+/**
+ * @brief Enumeration of flags used with GPIO type digital audio outputs
+ */
+enum MBG_GPIO_DIGITAL_AUDIO_FLAGS
+{
+ MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG, ///< reserved
+ N_MBG_GPIO_DIGITAL_AUDIO_FLAGS ///< number of known flags
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_FLAGS
+ *
+ * Used with ::MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_DIGITAL_AUDIO_FLAGS
+ */
+enum MBG_GPIO_DIGITAL_AUDIO_FLAG_MASKS
+{
+ MSK_MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG ) ///< see ::MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG
+};
+
+
+
+/**
+ * @brief Configuration of a GPIO digital audio output
+ *
+ * Used as sub-structure of ::MBG_GPIO_SETTINGS.
+ *
+ * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT
+ * @see ::MBG_GPIO_SETTINGS
+ */
+typedef struct
+{
+ uint32_t type; ///< digital audio type, see ::MBG_GPIO_DIGITAL_AUDIO_TYPES
+ uint32_t flags; ///< reserved, currently always 0
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+ uint32_t reserved2; ///< reserved, currently always 0
+
+} MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS;
+
+#define _mbg_swab_mbg_gpio_digital_audio_out_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->type ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+ _mbg_swab32( &(_p)->reserved2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Supported options for digital audio output
+ *
+ * Used as sub-structure of ::MBG_GPIO_LIMITS.
+ *
+ * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT
+ * @see ::MBG_GPIO_LIMITS
+ */
+typedef struct
+{
+ uint32_t supp_types; ///< supported digital audio types, see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS
+ uint32_t supp_flags; ///< reserved, currently always 0
+ uint32_t reserved0; ///< reserved, currently always 0
+ uint32_t reserved1; ///< reserved, currently always 0
+ uint32_t reserved2; ///< reserved, currently always 0
+
+} MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP;
+
+#define _mbg_swab_mbg_gpio_digital_audio_out_supp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_types ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved0 ); \
+ _mbg_swab32( &(_p)->reserved1 ); \
+ _mbg_swab32( &(_p)->reserved2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of general flags used with a GPIO
+ *
+ * @see ::MBG_GPIO_FLAG_MASKS
+ */
+enum MBG_GPIO_FLAGS
+{
+ MBG_GPIO_DEPENDS_ON_ASS_IO_IDX, ///< indicates that this output depends on GPIO with ::MBG_GPIO_SETTINGS::ass_io_idx and may not be configured independently
+ N_MBG_GPIO_FLAGS ///< number of known flags
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::MBG_GPIO_FLAGS
+ *
+ * Used with ::MBG_GPIO_LIMITS::supp_flags and ::MBG_GPIO_SETTINGS::flags
+ *
+ * @see ::MBG_GPIO_FLAGS
+ */
+enum MBG_GPIO_FLAG_MASKS
+{
+ MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX = ( 1UL << MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) ///< see ::MBG_GPIO_DEPENDS_ON_ASS_IO_IDX
+};
+
+
/**
- * @brief A structure used to configure a GPIO port
+ * @brief A generic structure used to hold a GPIO port's settings
*/
typedef struct
{
- uint32_t mode; /** frequency out, frequency in, pulse out, etc. */
- uint32_t reserved; /**< currently always 0 */
- uint32_t flags; /**< currently always 0 */
+ uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES
+ uint16_t reserved_1; ///< reserved, currently always 0
+ uint8_t reserved_2; ///< reserved, currently always 0
+ uint8_t ass_io_idx; ///< associated GPIO index, only valid if ::MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX is set in flags field
+
+ uint32_t flags; ///< flags, see ::MBG_GPIO_FLAG_MASKS
+
+ /// settings depending on the GPIO type, see ::MBG_GPIO_TYPES
union
{
- MBG_GPIO_FREQ_OUT_SETTINGS freq_out; /** if type is frequency output */
- MBG_GPIO_FREQ_IN_SETTINGS freq_in; /** if type is frequency input */
- MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; /** if type is fixed frequency output */
+ MBG_GPIO_FREQ_IN_SETTINGS freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN
+ MBG_GPIO_FREQ_OUT_SETTINGS freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT
+ MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ MBG_GPIO_BITS_IN_SETTINGS bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN
+ MBG_GPIO_BITS_OUT_SETTINGS bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT
+ MBG_GPIO_VIDEO_OUT_SETTINGS video_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT
+ MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS video_sync_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT
+ MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS studio_clk_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT
+ MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS digital_audio_out; ///< if ::MBG_GPIO_SETTINGS::type is ::;MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT
} u;
} MBG_GPIO_SETTINGS;
+#define _mbg_swab_mbg_gpio_settings( _p, _recv ) \
+do \
+{ \
+ uint32_t t = (_p)->type; \
+ if ( (_recv) ) \
+ _mbg_swab32( &t ); \
+ _mbg_swab32( &(_p)->type ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab8( &(_p)->reserved_2 ); \
+ _mbg_swab8( &(_p)->ass_io_idx ); \
+ _mbg_swab32( &(_p)->flags ); \
+ switch( t ) \
+ { \
+ case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_settings( &(_p)->u.freq_in ); break; \
+ case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_settings( &(_p)->u.freq_out ); break; \
+ case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_settings( &(_p)->u.ff_out ); break; \
+ case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_settings( &(_p)->u.bits_in, (_recv) ); break; \
+ case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_settings( &(_p)->u.bits_out ); break; \
+ case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_settings( &(_p)->u.video_out ); break; \
+ case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_settings( &(_p)->u.video_sync_out ); break; \
+ case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_settings( &(_p)->u.studio_clk_out ); break; \
+ case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_settings( &(_p)->u.digital_audio_out ); break; \
+ default : break; \
+ } \
+} while ( 0 )
+
+
+
+/**
+ * @brief A GPIO port's current settings, plus port index
+ */
+typedef struct
+{
+ uint32_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_SETTINGS settings; ///< current settings
+
+} MBG_GPIO_SETTINGS_IDX;
+
+#define _mbg_swab_mbg_gpio_settings_idx( _p, _recv ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv ) ); \
+} while ( 0 )
+
+
/**
- * @brief A structure used to describe a GPIO ports limiting values
+ * @brief A generic structure used to specify a GPIO port's limits
*/
typedef struct
{
- uint32_t supp_modes; /**< supported modes */
- uint32_t reserved;
- uint32_t supp_flags; /**< supported flags */
+ uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_FLAG_MASKS
+ /// limits depending on the GPIO type, see ::MBG_GPIO_TYPES
union
{
- MBG_GPIO_FREQ_OUT_SETTINGS freq_out; /** max. freq. values for output */
- MBG_GPIO_FREQ_IN_SETTINGS freq_in; /** max. freq. values for input */
- MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; /** max. ff values for output */
+ MBG_GPIO_FREQ_IN_SUPP freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN
+ MBG_GPIO_FREQ_OUT_SUPP freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT
+ MBG_GPIO_FIXED_FREQ_OUT_SUPP ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT
+ MBG_GPIO_BITS_IN_SUPP bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN
+ MBG_GPIO_BITS_OUT_SUPP bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT
+ MBG_GPIO_VIDEO_OUT_SUPP video_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT
+ MBG_GPIO_VIDEO_SYNC_OUT_SUPP video_sync_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT
+ MBG_GPIO_STUDIO_CLOCK_OUT_SUPP studio_clk_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT
+ MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP digital_audio_out; ///< if ::MBG_GPIO_SETTINGS::type is ::;MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT
} u;
} MBG_GPIO_LIMITS;
+#define _mbg_swab_mbg_gpio_limits( _p, _recv ) \
+do \
+{ \
+ uint32_t t = (_p)->type; \
+ if ( (_recv) ) \
+ _mbg_swab32( &t ); \
+ _mbg_swab32( &(_p)->type ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ switch( t ) \
+ { \
+ case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_supp( &(_p)->u.freq_in ); break; \
+ case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_supp( &(_p)->u.freq_out ); break; \
+ case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_supp( &(_p)->u.ff_out ); break; \
+ case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_supp( &(_p)->u.bits_in ); break; \
+ case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_supp( &(_p)->u.bits_out ); break; \
+ case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_supp( &(_p)->u.video_out ); break; \
+ case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_supp( &(_p)->u.video_sync_out ); break; \
+ case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_supp( &(_p)->u.studio_clk_out ); break; \
+ case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_supp( &(_p)->u.digital_audio_out ); break; \
+ default : break; \
+ } \
+} while ( 0 )
+/**
+ * @brief A GPIO port's current settings and limits
+ */
+typedef struct
+{
+ MBG_GPIO_SETTINGS settings; ///< current settings
+ MBG_GPIO_LIMITS limits; ///< limits of this GPIO port
+
+} MBG_GPIO_INFO;
+
+
+#define _mbg_swab_mbg_gpio_info( _p, _recv ) \
+do \
+{ \
+ _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv) ); \
+ _mbg_swab_mbg_gpio_limits( &(_p)->limits, (_recv) ); \
+} while ( 0 )
+
/**
- * @brief A structure used to configure a specific GPIO port
+ * @brief A GPIO port's current settings and limits, plus port index
*/
typedef struct
{
- uint32_t idx; /**< port number, 0..(MBG_GPIO_CFG_LIMITS::num_io - 1) */
- MBG_GPIO_SETTINGS settings; /**< configuration settings */
+ uint32_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_INFO info; ///< limits and current settings of this GPIO port
-} MBG_GPIO_SETTINGS_IDX;
+} MBG_GPIO_INFO_IDX;
+
+#define _mbg_swab_mbg_gpio_info_idx( _p, _recv ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_gpio_info( &(_p)->info, (_recv) ); \
+} while ( 0 )
/**
- * @brief A structure used query the current GPIO port settings and capabilities
+ * @brief Status information on a single GPIO port
*/
typedef struct
{
- MBG_GPIO_SETTINGS settings; /**< current configuration */
- MBG_GPIO_LIMITS limits; /**< supp. and max. values */
-} MBG_GPIO_INFO;
+ uint8_t port_state; ///< see ::MBG_GPIO_PORT_STATES
+ uint8_t reserved_0; ///< reserved, currently unused and always 0
+ uint16_t reserved_1; ///< reserved, currently unused and always 0
+ uint32_t reserved_2; ///< reserved, currently unused and always 0
+ uint32_t reserved_3; ///< reserved, currently unused and always 0
+
+} MBG_GPIO_STATUS;
+
+#define _mbg_swab_mbg_gpio_status( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->port_state ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
/**
- * @brief A structure used to query configuration and capabilities of a specific GPIO port
+ * @brief Status information on a specific GPIO port
*/
typedef struct
{
- uint32_t idx; /**< port number, 0..(MBG_GPIO_CFG_LIMITS::num_io - 1) */
- MBG_GPIO_INFO info; /**< current settings and capabilities of this GPIO port */
-} MBG_GPIO_INFO_IDX;
+ uint16_t idx; ///< port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1
+ MBG_GPIO_STATUS status; ///< status information
+
+} MBG_GPIO_STATUS_IDX;
+
+#define _mbg_swab_mbg_gpio_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_mbg_gpio_status( &(_p)->status ); \
+} while ( 0 )
/**
- * @brief Definitions for MBG_GPIO_SETTINGS::mode
+ * @brief GPIO port states
+ *
+ * Used with ::MBG_GPIO_STATUS::port_state
+ *
+ * @see ::DEFAULT_GPIO_PORT_STATE_NAMES
*/
-enum
+enum MBG_GPIO_PORT_STATES
{
- MBG_GPIO_SIGNAL_TYPE_FREQ_OUT, /**< variable frequency output */
- MBG_GPIO_SIGNAL_TYPE_FREQ_IN, /**< variable frequency inputs */
- MBG_GPIO_SIGNAL_TYPE_FIXED_FREQ_OUT, /**< fixed frequency outputs */
- N_MBG_GPIO_SIGNAL_TYPES /**< number of known modes */
+ MBG_GPIO_PORT_UNUSED, ///< configured as unused input
+ MBG_GPIO_PORT_OUTPUT_ENBD, ///< configured output signal enabled
+ MBG_GPIO_INPUT_SIG_AVAIL, ///< input signal is available
+ N_MBG_GPIO_PORT_STATES ///< number of known port states
};
/**
- * @brief Definitions for MBG_GPIO_FF_OUT_SETTINGS::frq_bit
+ * @brief String initializers for GPIO port state names
+ *
+ * @see ::MBG_GPIO_PORT_STATES
*/
-enum
+#define DEFAULT_GPIO_PORT_STATE_NAMES \
+{ \
+ "unused", \
+ "output enabled", \
+ "input signal available" \
+}
+
+
+/** @} defgroup group_gpio */
+
+
+
+/**
+ * @defgroup group_havequick HaveQuick definitions
+ *
+ * @note This is only supported if the ::GPS_HAS_HAVEQUICK bit is set
+ * in the ::RECEIVER_INFO::features mask.
+ *
+ * @{ */
+
+
+/**
+ * @brief Enumeration of HaveQuick formats
+ *
+ * @see ::HAVEQUICK_SETTINGS::format
+ * @see ::HAVEQUICK_FORMAT_MASKS
+ */
+enum HAVEQUICK_FORMATS
{
- MBG_GPIO_FIXED_FREQ_8kHz, /**< 8kHz */
- MBG_GPIO_FIXED_FREQ_48kHz, /**< 48kHz */
- MBG_GPIO_FIXED_FREQ_1MHz, /**< 1MHz */
- MBG_GPIO_FIXED_FREQ_1544kHz, /**< 1.544MHz */
- MBG_GPIO_FIXED_FREQ_2048kHz, /**< 2.048MHz */
- MBG_GPIO_FIXED_FREQ_5MHz, /**< 5MHz */
- MBG_GPIO_FIXED_FREQ_10MHz, /**< 10MHz */
- MBG_GPIO_FIXED_FREQ_19440kHz, /**< 19.44MHz */
- N_MBG_GPIO_FIXED_FREQ /**< number of known frequencies */
+ HQ_FMT_STANAG4246_1,
+ HQ_FMT_STANAG4246_2,
+ HQ_FMT_STANAG4246_PTTI,
+ HQ_FMT_STANAG4372_SATURN_1,
+ HQ_FMT_STANAG4372_SATURN_2,
+ HQ_FMT_STANAG4430_EXTD,
+ N_HQ_FMT ///< number of known formats
};
-/**< Bit Masks to be used with MBG_GPIO_FF_OUT_SETTINGS::frq_bit */
-#define MSK_MBG_GPIO_FIXED_FREQ_8kHz ( 1UL << MBG_GPIO_FIXED_FREQ_8kHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_48kHz ( 1UL << MBG_GPIO_FIXED_FREQ_48kHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_1MHz ( 1UL << MBG_GPIO_FIXED_FREQ_1MHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_1544kHz ( 1UL << MBG_GPIO_FIXED_FREQ_1544kHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_2048kHz ( 1UL << MBG_GPIO_FIXED_FREQ_2048kHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_5MHz ( 1UL << MBG_GPIO_FIXED_FREQ_5MHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_10MHz ( 1UL << MBG_GPIO_FIXED_FREQ_10MHz )
-#define MSK_MBG_GPIO_FIXED_FREQ_19440kHz ( 1UL << MBG_GPIO_FIXED_FREQ_19440kHz )
-
-/** @} group_gpio */
+/**
+ * @brief Bit masks associated with the enumerated HaveQuick formats
+ *
+ * @see ::HAVEQUICK_INFO::supp_formats
+ * @see ::HAVEQUICK_FORMATS
+ */
+enum HAVEQUICK_FORMAT_MASKS
+{
+ HQ_MSK_STANAG4246_1 = ( 1UL << HQ_FMT_STANAG4246_1 ), ///< see ::HQ_FMT_STANAG4246_1
+ HQ_MSK_STANAG4246_2 = ( 1UL << HQ_FMT_STANAG4246_2 ), ///< see ::HQ_FMT_STANAG4246_2
+ HQ_MSK_STANAG4246_PTTI = ( 1UL << HQ_FMT_STANAG4246_PTTI ), ///< see ::HQ_FMT_STANAG4246_PTTI
+ HQ_MSK_STANAG4372_SATURN_1 = ( 1UL << HQ_FMT_STANAG4372_SATURN_1 ), ///< see ::HQ_FMT_STANAG4372_SATURN_1
+ HQ_MSK_STANAG4372_SATURN_2 = ( 1UL << HQ_FMT_STANAG4372_SATURN_2 ), ///< see ::HQ_FMT_STANAG4372_SATURN_2
+ HQ_MSK_STANAG4430_EXTD = ( 1UL << HQ_FMT_STANAG4430_EXTD ) ///< see ::HQ_FMT_STANAG4430_EXTD
+};
-/*------------------------------------------------------------------------*/
+/*
+ * String initializers for each Havequick format
+ */
+#define HQ_FMT_NAME_STANAG4246_1 "STANAG4246 1"
+#define HQ_FMT_NAME_STANAG4246_2 "STANAG4246 2"
+#define HQ_FMT_NAME_STANAG4246_PTTI "STANAG4246 PTTI"
+#define HQ_FMT_NAME_STANAG4372_SATURN_1 "STANAG4372 SATURN 1"
+#define HQ_FMT_NAME_STANAG4372_SATURN_2 "STANAG4372 SATURN 2"
+#define HQ_FMT_NAME_STANAG4430_EXTD "STANAG4430 EXTD"
+
+#define HQ_FMT_SHRT_NAME_STANAG4246_1 "STG4246 1"
+#define HQ_FMT_SHRT_NAME_STANAG4246_2 "STG4246 2"
+#define HQ_FMT_SHRT_NAME_STANAG4246_PTTI "STG4246 PTTI"
+#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1 "STG4372 SATURN1"
+#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2 "STG4372 SATURN2"
+#define HQ_FMT_SHRT_NAME_STANAG4430_EXTD "STG4430 EXTD"
/*
- * The types below are not used with all devices:
+ * The definition below can be used to initialize
+ * an array of ::N_HQ_FMT name strings.
+ */
+#define DEFAULT_HQ_FMT_NAMES \
+{ \
+ HQ_FMT_NAME_STANAG4246_1, \
+ HQ_FMT_NAME_STANAG4246_2, \
+ HQ_FMT_NAME_STANAG4246_PTTI, \
+ HQ_FMT_NAME_STANAG4372_SATURN_1, \
+ HQ_FMT_NAME_STANAG4372_SATURN_2, \
+ HQ_FMT_NAME_STANAG4430_EXTD \
+}
+
+#define DEFAULT_HQ_SHRT_FMT_NAMES \
+{ \
+ HQ_FMT_SHRT_NAME_STANAG4246_1, \
+ HQ_FMT_SHRT_NAME_STANAG4246_2, \
+ HQ_FMT_SHRT_NAME_STANAG4246_PTTI, \
+ HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1, \
+ HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2, \
+ HQ_FMT_SHRT_NAME_STANAG4430_EXTD \
+}
+
+
+
+/**
+ * @brief Configuration settings for a HaveQuick input or output
+ */
+typedef struct
+{
+ uint16_t format; ///< see ::HAVEQUICK_FORMATS
+ uint16_t flags; ///< see ::HAVEQUICK_FLAG_MASKS
+ int32_t offset; ///< Tx: unused, Rx: offset of incoming time in [s]
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} HAVEQUICK_SETTINGS;
+
+#define _mbg_swab_havequick_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->format ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->offset ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+/**
+ * @brief Current settings and capabilities of a HaveQuick input or output
+ */
+typedef struct
+{
+ HAVEQUICK_SETTINGS settings; ///< current settings
+ uint32_t supp_formats; ///< see ::HAVEQUICK_FORMAT_MASKS
+ uint16_t supp_flags; ///< mask of flags supported in settings, see ::HAVEQUICK_FLAG_MASKS
+ uint16_t reserved; ///< reserved, currently always 0
+
+} HAVEQUICK_INFO;
+
+#define _mbg_swab_havequick_info( _p ) \
+do \
+{ \
+ _mbg_swab_havequick_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_formats ); \
+ _mbg_swab16( &(_p)->supp_flags ); \
+ _mbg_swab16( &(_p)->reserved ); \
+} while ( 0 )
+
+
+/**
+ * @brief Known HaveQuick control flags
+ *
+ * @see ::HAVEQUICK_FLAG_MASKS
+ */
+enum HAVEQUICK_FLAG_BITS
+{
+ HQ_FLAG_TX_GEN_LOCAL_TIME,
+ HQ_FLAG_SIGNAL_INVERTED,
+ HQ_FLAG_USE_EXT_PPS,
+ N_HQ_FLAG_BITS
+};
+
+
+/**
+ * @brief Bit masks associated with HaveQuick control flags
+ *
+ * @see ::HAVEQUICK_SETTINGS::flags
+ * @see ::HAVEQUICK_INFO::supp_flags
+ * @see ::HAVEQUICK_FLAG_BITS
+ */
+enum HAVEQUICK_FLAG_MASKS
+{
+ HQ_MSK_TX_GEN_LOCAL_TIME = ( 1UL << HQ_FLAG_TX_GEN_LOCAL_TIME ), ///< see ::HQ_FLAG_TX_GEN_LOCAL_TIME
+ HQ_MSK_SIGNAL_INVERTED = ( 1UL << HQ_FLAG_SIGNAL_INVERTED ), ///< see ::HQ_FLAG_SIGNAL_INVERTED
+ HQ_MSK_USE_EXT_PPS = ( 1UL << HQ_FLAG_USE_EXT_PPS ) ///< see ::HQ_FLAG_USE_EXT_PPS
+};
+
+/** @} defgroup group_havequick */
+
+
+
+/**
+ * @defgroup group_evt_log Event logging support
+ *
+ * @note This is only available if ::GPS_HAS_EVT_LOG is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Number of event log entries that can be stored and yet have been saved
+ */
+typedef struct
+{
+ uint32_t used; ///< current number of saved log entries
+ uint32_t max; ///< max number of log entries which can be saved
+
+} MBG_NUM_EVT_LOG_ENTRIES;
+
+#define _mbg_swab_mbg_num_evt_log_entries( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->used ); \
+ _mbg_swab32( &(_p)->max ); \
+} while ( 0 )
+
+
+typedef uint16_t MBG_EVT_CODE;
+#define _mbg_swab_evt_code( _p ) _mbg_swab16( _p )
+
+typedef uint16_t MBG_EVT_INFO;
+#define _mbg_swab_evt_info( _p ) _mbg_swab16( _p )
+
+/**
+ * @brief An event log entry
+ */
+typedef struct
+{
+ uint32_t time; ///< like time_t, seconds since 1970
+ MBG_EVT_CODE code; ///< event ID or'ed with severity level, see @ref MBG_EVENT_CODES
+ MBG_EVT_INFO info; ///< optional event info, depending on event ID
+
+} MBG_EVT_LOG_ENTRY;
+
+#define _mbg_swab_mbg_evt_log_entry( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->time ); \
+ _mbg_swab_evt_code( &(_p)->code ); \
+ _mbg_swab_evt_info( &(_p)->info ); \
+} while ( 0 )
+
+
+// ::MBG_EVT_LOG_ENTRY::code is a combination of some bits used for the ID,
+// plus some bits used for the severity/level. The sum of bits must not
+// exceed (8 * sizeof ::MBG_EVT_LOG_ENTRY::code):
+
+#define MBG_EVT_ID_BITS 13
+#define MBG_EVT_LVL_BITS 3
+
+#define MBG_EVT_ID_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_ID_BITS ) - 1 )
+#define MBG_EVT_LVL_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_LVL_BITS ) - 1 )
+
+
+// Combine an ID and Level to a code which can be stored
+// in the code field:
+#define _mbg_mk_evt_code( _id, _lvl ) \
+ ( (MBG_EVT_CODE) ( (MBG_EVT_CODE)(_id) | ( (MBG_EVT_CODE)(_lvl) << MBG_EVT_ID_BITS ) ) )
+
+// Extract the event ID from the code field:
+#define _mbg_get_evt_id( _code ) \
+ ( (_code) & MBG_EVT_ID_MASK )
+
+// Extract the severity level from the code field:
+#define _mbg_get_evt_lvl( _code ) \
+ ( ( (_code) >> MBG_EVT_ID_BITS ) & MBG_EVT_LVL_MASK )
+
+
+/**
+ * @brief Enumeration of event IDs
+ *
+ * @see @ref MBG_EVENT_CODES
+ * @see @ref MBG_EVT_ID_BITS
+ * @see @ref MBG_EVT_LVL_BITS
+ */
+enum MBG_EVT_IDS
+{
+ MBG_EVT_ID_NONE, ///< no event (empty entry)
+ MBG_EVT_ID_POW_UP_RES, ///< power up reset
+ MBG_EVT_ID_WDOG_RES, ///< watchdog reset
+ MBG_EVT_ID_COLD_BOOT, ///< entering cold boot mode
+ MBG_EVT_ID_WARM_BOOT, ///< entering warm boot mode
+ MBG_EVT_ID_NORMAL_OP, ///< entering normal operation
+ MBG_EVT_ID_ANT_DISCONN, ///< antenna disconnect detected
+ MBG_EVT_ID_ANT_SHORT, ///< antenna short circuit detected
+ MBG_EVT_ID_ANT_OK, ///< antenna OK after failure
+ MBG_EVT_ID_LOW_SATS, ///< no satellites can be received though antenna not failing
+ N_MBG_EVT_ID
+};
+
+
+#define ENG_EVT_ID_NAME_NONE "No event"
+#define ENG_EVT_ID_NAME_POW_UP_RES "Power Up Reset"
+#define ENG_EVT_ID_NAME_WDOG_RES "Watchdog Reset"
+#define ENG_EVT_ID_NAME_COLD_BOOT "Cold Boot"
+#define ENG_EVT_ID_NAME_WARM_BOOT "Warm Boot"
+#define ENG_EVT_ID_NAME_NORMAL_OP "Normal Operation"
+#define ENG_EVT_ID_NAME_ANT_DISCONN "Antenna Disconn."
+#define ENG_EVT_ID_NAME_ANT_SHORT "Ant. Short-Circ."
+#define ENG_EVT_ID_NAME_ANT_OK "Antenna OK"
+#define ENG_EVT_ID_NAME_LOW_SATS "Few Sats Only"
+
+
+#define MBG_EVT_ID_NAMES_ENG \
+{ \
+ ENG_EVT_ID_NAME_NONE, \
+ ENG_EVT_ID_NAME_POW_UP_RES, \
+ ENG_EVT_ID_NAME_WDOG_RES, \
+ ENG_EVT_ID_NAME_COLD_BOOT, \
+ ENG_EVT_ID_NAME_WARM_BOOT, \
+ ENG_EVT_ID_NAME_NORMAL_OP, \
+ ENG_EVT_ID_NAME_ANT_DISCONN, \
+ ENG_EVT_ID_NAME_ANT_SHORT, \
+ ENG_EVT_ID_NAME_ANT_OK, \
+ ENG_EVT_ID_NAME_LOW_SATS \
+}
+
+
+
+/**
+ * @brief Enumeration of event severity levels
+ *
+ * @see @ref MBG_EVENT_CODES
+ * @see @ref MBG_EVT_ID_BITS
+ * @see @ref MBG_EVT_LVL_BITS
+ */
+enum MBG_EVT_LVLS
+{
+ MBG_EVT_LVL_NONE,
+ MBG_EVT_LVL_DEBUG,
+ MBG_EVT_LVL_INFO,
+ MBG_EVT_LVL_WARN,
+ MBG_EVT_LVL_ERR,
+ MBG_EVT_LVL_CRIT,
+ N_MBG_EVT_LVL
+};
+
+
+#define ENG_EVT_LVL_NAME_NONE "None"
+#define ENG_EVT_LVL_NAME_DEBUG "Debug"
+#define ENG_EVT_LVL_NAME_INFO "Info"
+#define ENG_EVT_LVL_NAME_WARN "Warn"
+#define ENG_EVT_LVL_NAME_ERR "Err"
+#define ENG_EVT_LVL_NAME_CRIT "Crit."
+
+
+#define MBG_EVT_LVL_NAMES_ENG \
+{ \
+ ENG_EVT_LVL_NAME_NONE, \
+ ENG_EVT_LVL_NAME_DEBUG, \
+ ENG_EVT_LVL_NAME_INFO, \
+ ENG_EVT_LVL_NAME_WARN, \
+ ENG_EVT_LVL_NAME_ERR, \
+ ENG_EVT_LVL_NAME_CRIT \
+}
+
+
+/**
+ * @brief Predefined event codes with associated severity levels
+ *
+ * @see ::MBG_EVT_IDS
+ * @see ::MBG_EVT_LVLS
+ *
+ * @anchor MBG_EVENT_CODES @{ */
+
+#define MBG_EVT_NONE _mbg_mk_evt_code( MBG_EVT_ID_NONE, MBG_EVT_LVL_NONE )
+#define MBG_EVT_POW_UP_RES _mbg_mk_evt_code( MBG_EVT_ID_POW_UP_RES, MBG_EVT_LVL_WARN )
+#define MBG_EVT_WDOG_RES _mbg_mk_evt_code( MBG_EVT_ID_WDOG_RES, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_COLD_BOOT _mbg_mk_evt_code( MBG_EVT_ID_COLD_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_WARM_BOOT _mbg_mk_evt_code( MBG_EVT_ID_WARM_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_NORMAL_OP _mbg_mk_evt_code( MBG_EVT_ID_NORMAL_OP, MBG_EVT_LVL_INFO )
+#define MBG_EVT_ANT_DISCONN _mbg_mk_evt_code( MBG_EVT_ID_ANT_DISCONN, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_SHORT _mbg_mk_evt_code( MBG_EVT_ID_ANT_SHORT, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_OK _mbg_mk_evt_code( MBG_EVT_ID_ANT_OK, MBG_EVT_LVL_INFO )
+#define MBG_EVT_LOW_SATS _mbg_mk_evt_code( MBG_EVT_ID_LOW_SATS, MBG_EVT_LVL_WARN )
+
+/** @} anchor MBG_EVENT_CODES */
+
+/** @} defgroup group_evt_log */
+
+
+
+/**
+ * @defgroup group_ims IMS support
+ *
+ * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Generic state of an IMS device
+ */
+typedef struct
+{
+ uint8_t chassis_id; ///< chassis ID, 0 if installed on the backplane
+ uint8_t slot_id; ///< slot number on the chassis
+ uint16_t num_sensors; ///< number of sensors provided by the device
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::MBG_IMS_STATE_FLAG_MASKS
+
+} MBG_IMS_STATE;
+
+#define _mbg_swab_mbg_ims_state( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->num_sensors ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of bits used to define ::MBG_IMS_STATE_FLAG_MASKS
+ *
+ * @see ::MBG_IMS_STATE_FLAG_MASKS
+ */
+enum MBG_IMS_STATE_FLAG_BITS
+{
+ MBG_IMS_STATE_FLAG_BIT_HAS_FDM, ///< device supports FDM API
+ N_MBG_IMS_STATE_FLAG_BITS
+};
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_STATE::flags
+ *
+ * @see ::MBG_IMS_STATE_FLAG_BITS
+ */
+enum MBG_IMS_STATE_FLAG_MASKS
+{
+ MBG_IMS_STATE_FLAG_MSK_HAS_FDM = ( 1UL << MBG_IMS_STATE_FLAG_BIT_HAS_FDM ) ///< see ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM
+};
+
+
+
+/**
+ * @brief Generic state of an IMS sensor
+ */
+typedef struct
+{
+ uint16_t type; ///< sensor type, see ::MBG_IMS_SENSORS
+ uint16_t idx; ///< index of the sensor of this type
+ int32_t val; ///< sensor value, in units according to the type
+ int16_t exp; ///< 10s exponent of the sensor value
+ uint16_t reserved; ///< currently unused, always 0
+ uint32_t flags; ///< currently unused, always 0
+
+} MBG_IMS_SENSOR_STATE;
+
+#define _mbg_swab_mbg_ims_sensor_state( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->type ); \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab32( &(_p)->val ); \
+ _mbg_swab16( &(_p)->exp ); \
+ _mbg_swab16( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Generic state of an IMS sensor, with sensor index
+ */
+typedef struct
+{
+ uint32_t idx; ///< sensor index, 0..::MBG_IMS_STATE::num_sensors-1
+ MBG_IMS_SENSOR_STATE state; ///< sensor state
+
+} MBG_IMS_SENSOR_STATE_IDX;
+
+#define _mbg_swab_mbg_ims_sensor_state_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_sensor_state( &(_p)->state ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief IMS sensor types
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::type
+ */
+enum MBG_IMS_SENSORS
+{
+ MBG_IMS_SENSOR_TEMP_C, ///< temperature in degrees Celsius
+ MBG_IMS_SENSOR_VOLTAGE, ///< voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_PLL, ///< control voltage in val/exp, lock state in flags
+ N_MBG_IMS_SENSORS ///< number of supported sensor types
+};
+
+
+
+/**
+ * @brief IMS sensor state flags for voltage
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type
+ * is ::MBG_IMS_SENSOR_VOLTAGE.
+ */
+enum MBG_IMS_SENSOR_STATE_FLAG_MASK_VOLTAGE
+{
+ MBG_IMS_SENSOR_VOLTAGE_OUT_ENB = 0x01, ///< output is enabled
+ MBG_IMS_SENSOR_VOLTAGE_OUT_OVR = 0x02 ///< output overload
+};
+
+
+/**
+ * @brief IMS sensor state flags for PLL
+ *
+ * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type
+ * is ::MBG_IMS_SENSOR_PLL.
+ */
+enum MBG_IMS_SENSOR_STATE_FLAG_MASK_PLL
+{
+ MBG_IMS_SENSOR_PLL_LOCKED = 0x01 ///< PLL is locked
+};
+
+
+
+/**
+ * @brief DAC limit specs
+ */
+typedef struct
+{
+ int32_t dac_val_min; ///< min. possible DAC Value, positive or negative
+ int32_t dac_val_max; ///< max. possible DAC Value, positive or negative
+
+ int32_t u_min; ///< min. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_min
+ int32_t u_max; ///< max. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_max
+
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} MBG_DAC_SPECS;
+
+#define _mbg_swab_mbg_dac_specs( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->dac_val_min ); \
+ _mbg_swab32( &(_p)->dac_val_max ); \
+ _mbg_swab32( &(_p)->u_min ); \
+ _mbg_swab32( &(_p)->u_max ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Output state of FDM device.
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ */
+typedef struct
+{
+ int32_t dac_val; ///< current DAC value, positive or negative
+ uint32_t mode; ///< current output mode, see ::MBG_IMS_FDM_OUTPUT_MODES
+
+ MBG_DAC_SPECS dac_specs; ///< DAC specific limits
+
+ uint32_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_OUTPUT_STATE;
+
+#define _mbg_swab_mbg_ims_fdm_output_state( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->dac_val ); \
+ _mbg_swab32( &(_p)->mode ); \
+ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Output state of FDM device plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_STATE state;
+
+} MBG_IMS_FDM_OUTPUT_STATE_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_state_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_state( &(_p)->state ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Output settings of FDM device
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags
+ */
+typedef struct
+{
+ uint32_t mode; ///< mode, see ::MBG_IMS_FDM_OUTPUT_MODES
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_OUTPUT_SETTINGS;
+
+#define _mbg_swab_mbg_ims_fdm_output_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->mode ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+/**
+ * @brief Output settings for FDM devices plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_SETTINGS settings;
+
+} MBG_IMS_FDM_OUTPUT_SETTINGS_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Specific output settings and limits.
+ */
+typedef struct
+{
+ MBG_IMS_FDM_OUTPUT_SETTINGS settings; ///< current settings
+ uint32_t supp_modes; ///< supported modes, see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS
+ MBG_DAC_SPECS dac_specs; ///< DAC specific limits
+
+} MBG_IMS_FDM_OUTPUT_INFO;
+
+#define _mbg_swab_mbg_ims_fdm_output_info( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Specific output settings and limits, plus index.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IMS_FDM_OUTPUT_INFO info;
+
+} MBG_IMS_FDM_OUTPUT_INFO_IDX;
+
+#define _mbg_swab_mbg_ims_fdm_output_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_mbg_ims_fdm_output_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of known output modes
+ *
+ * Used with ::MBG_IMS_FDM_OUTPUT_STATE::mode
+ *
+ * @see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS
+ */
+enum MBG_IMS_FDM_OUTPUT_MODES
+{
+ MBG_IMS_FDM_OUTPUT_MODE_FD, ///< Analog output reflects frequency deviation
+ MBG_IMS_FDM_OUTPUT_MODE_TD, ///< Analog output reflects time deviation
+ N_MBG_IMS_FDM_OUTPUT_MODES ///< Number of known output modes
+};
+
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_FDM_OUTPUT_STATE::mode
+ *
+ * @see ::MBG_IMS_FDM_OUTPUT_MODES
+ */
+enum MBG_IMS_FDM_OUTPUT_MODE_MASKS
+{
+ MBG_IMS_FDM_OUTPUT_MODE_MSK_FD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_FD ), ///< see ::MBG_IMS_FDM_OUTPUT_MODE_FD
+ MBG_IMS_FDM_OUTPUT_MODE_MSK_TD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_TD ) ///< see ::MBG_IMS_FDM_OUTPUT_MODE_TD
+};
+
+
+
+/**
+ * @brief A generic structure used to specify FDM limits
+ */
+typedef struct
+{
+ uint8_t n_outputs; ///< number of outputs per module
+ uint8_t reserved_0; ///< reserved, currently always 0
+ uint16_t reserved_1; ///< reserved, currently always 0
+
+ uint32_t fd_neg_limit; ///< min. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units
+ uint32_t fd_pos_limit; ///< max. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units
+ uint32_t fd_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::fd_neg_limit and ::MBG_IMS_FDM_LIMITS::fd_pos_limit
+
+ uint32_t td_neg_limit; ///< min. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units
+ uint32_t td_pos_limit; ///< max. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units
+ uint32_t td_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::td_neg_limit and ::MBG_IMS_FDM_LIMITS::td_pos_limit
+
+ uint32_t reserved_2; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_LIMITS;
+
+#define _mbg_swab_mbg_ims_fdm_limits( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->n_outputs ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ \
+ _mbg_swab32( &(_p)->fd_neg_limit ); \
+ _mbg_swab32( &(_p)->fd_pos_limit ); \
+ _mbg_swab32( &(_p)->fd_scale ); \
+ \
+ _mbg_swab32( &(_p)->td_neg_limit ); \
+ _mbg_swab32( &(_p)->td_pos_limit ); \
+ _mbg_swab32( &(_p)->td_scale ); \
+ \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief State of FDM device
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags.
+ *
+ */
+typedef struct
+{
+ MBG_GPIO_FREQ freq; ///< Current frequency
+
+ NANO_TIME_64 t_ref; ///< Current reference time
+ NANO_TIME_64 t_plt; ///< Current power line time
+ NANO_TIME_64 t_sync; ///< Last sync Time (reference time)
+
+ uint32_t line_freq; ///< Nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS
+ uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_STATE_FLAG_MASKS
+ uint32_t reserved; ///< Reserved, currently always 0
+
+} MBG_IMS_FDM_STATE;
+
+#define _mbg_swab_mbg_ims_fdm_state( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \
+ _mbg_swab_nano_time_64( &(_p)->t_ref ); \
+ _mbg_swab_nano_time_64( &(_p)->t_plt ); \
+ _mbg_swab_nano_time_64( &(_p)->t_sync ); \
+ _mbg_swab32( &(_p)->line_freq ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration known line frequencies
+ *
+ * Used with ::MBG_IMS_FDM_STATE::line_freq
+ *
+ * @see ::MBG_IMS_FDM_LINE_FREQ_MASKS
+ */
+enum MBG_IMS_FDM_LINE_FREQS
+{
+ MBG_IMS_FDM_LINE_FREQ_AUTO, ///< Auto detect line frequency
+ MBG_IMS_FDM_LINE_FREQ_50HZ, ///< 50Hz line frequency
+ MBG_IMS_FDM_LINE_FREQ_60HZ, ///< 60Hz line frequency
+ N_MBG_IMS_FDM_LINE_FREQS ///< number of known line frequencies
+};
+
+
+/**
+ * @brief Bit masks corresponding to defined line frequencies
+ *
+ * @see ::MBG_IMS_FDM_LINE_FREQS
+ */
+enum MBG_IMS_FDM_LINE_FREQ_MASKS
+{
+ MBG_IMS_FDM_LINE_FREQ_MSK_AUTO = ( 1UL << MBG_IMS_FDM_LINE_FREQ_AUTO ), ///< see ::MBG_IMS_FDM_LINE_FREQ_AUTO
+ MBG_IMS_FDM_LINE_FREQ_MSK_50HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_50HZ ), ///< see ::MBG_IMS_FDM_LINE_FREQ_50HZ
+ MBG_IMS_FDM_LINE_FREQ_MSK_60HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_60HZ ) ///< see ::MBG_IMS_FDM_LINE_FREQ_60HZ
+};
+
+
+/**
+ * @brief Initializers for an array of line freq. name strings
+ *
+ * @see ::MBG_IMS_FDM_LINE_FREQS
+ */
+#define MBG_IMS_FDM_LINE_FREQ_STRS \
+{ \
+ "Auto", \
+ "50 Hz", \
+ "60 Hz", \
+}
+
+
+/**
+ * @brief Enumeration of flag bits used to define ::MBG_IMS_FDM_STATE_FLAG_MASKS
+ */
+enum MBG_IMS_FDM_STATE_FLAG_BITS
+{
+ MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET, ///< if sync'ed after reset
+ MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED, ///< Power Line Time is locked
+ MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW, ///< Frequency deviation overflow occurred
+ MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW, ///< Time deviation overflow occurred
+ N_MBG_IMS_FDM_STATE_FLAG_BITS ///< number of known state flag bits
+};
+
+
+/**
+ * @brief Bit masks used with ::MBG_IMS_FDM_STATE::flags
+ *
+ * @see ::MBG_IMS_FDM_STATE_FLAG_BITS
+ */
+enum MBG_IMS_FDM_STATE_FLAG_MASKS
+{
+ MBG_IMS_FDM_STATE_FLAG_MSK_SYNC_AFTER_RESET = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET
+ MBG_IMS_FDM_STATE_FLAG_MSK_PLT_IS_LOCKED = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED
+ MBG_IMS_FDM_STATE_FLAG_MSK_FD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW ), ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW
+ MBG_IMS_FDM_STATE_FLAG_MSK_TD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW ) ///< see ::MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW
+};
+
+
+
+/**
+ * @brief FDM device settings
+ *
+ * @note This is only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags.
+ *
+ */
+typedef struct
+{
+ uint32_t fd_neg_limit; ///< min. frequency deviation limit in 1 mHz steps
+ uint32_t fd_pos_limit; ///< max. frequency deviation limit in 1 mHz steps
+
+ uint32_t td_neg_limit; ///< min. time deviation limit in 1 ms steps
+ uint32_t td_pos_limit; ///< max. time deviation limit in 1 ms steps
+
+ uint32_t line_freq; ///< nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS
+ uint32_t reserved; ///< reserved, currently always 0
+
+} MBG_IMS_FDM_SETTINGS;
+
+#define _mbg_swab_mbg_ims_fdm_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->fd_neg_limit ); \
+ _mbg_swab32( &(_p)->fd_pos_limit ); \
+ _mbg_swab32( &(_p)->td_neg_limit ); \
+ _mbg_swab32( &(_p)->td_pos_limit ); \
+ _mbg_swab32( &(_p)->line_freq ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief IMS FDM flags
+ *
+ * @see ::MBG_IMS_FDM_FLAG_MASKS
+ */
+enum MBG_IMS_FDM_FLAGS
+{
+ MBG_IMS_FDM_FLAG_CAN_SET_TDEV, ///< Device supports command GPS_FDM_SET_TD
+ N_MBG_IMS_FDM_FLAGS ///< Number of known FDM flags
+};
+
+
+
+/**
+ * @brief IMS FDM flag masks
+ *
+ * @see ::MBG_IMS_FDM_FLAGS
+ */
+enum MBG_IMS_FDM_FLAG_MASKS
+{
+ MBG_IMS_FDM_FLAG_MASK_CAN_SET_TDEV = ( 1UL << MBG_IMS_FDM_FLAG_CAN_SET_TDEV ) ///< see ::MBG_IMS_FDM_FLAG_CAN_SET_TDEV
+};
+
+
+
+/**
+ * @brief Specific FDM settings and limits.
*/
+typedef struct
+{
+ MBG_IMS_FDM_SETTINGS settings;
+ uint32_t supp_line_freqs; ///< Bit mask of supported line frequencies, see ::MBG_IMS_FDM_LINE_FREQ_MASKS
+ uint32_t reserved; ///< Reserved, currently always 0
+ uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_FLAG_MASKS
+
+} MBG_IMS_FDM_INFO;
+
+#define _mbg_swab_mbg_ims_fdm_info( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_ims_fdm_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_line_freqs ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+/** @} defgroup group_ims */
+
+
+
+/**
+ * @defgroup group_generic_io Generic I/O support.
+ *
+ * The definitions below are used with the GENERIC_IO API.
+ *
+ * This API is <b>NOT</b> supported by all devices, it depends on
+ * the type of the device, and the firmware version. The macro
+ * _pcps_has_generic_io() or the corresponding function
+ * mbg_dev_has_generic_io() should be used by applications to
+ * check whether a particular bus-level device supports this.
+ *
+ * @{ */
+
+typedef uint16_t GEN_IO_INFO_TYPE;
+
+#define _mbg_swab_gen_io_info_type( _p ) \
+ _mbg_swab16( _p )
+
+
+
+/**
+ * @brief The data structure used with the ::PCPS_GEN_IO_GET_INFO command
+ *
+ * Used to determine how many data sets of a specific type are supported
+ * by the device.
+ */
+typedef struct
+{
+ GEN_IO_INFO_TYPE type; // see ::PCPS_GEN_IO_TYPES
+ uint16_t num; // supported number of data sets of the specified type
+
+} GEN_IO_INFO;
+
+#define _mbg_swab_gen_io_info( _p ) \
+do \
+{ \
+ _mbg_swab_gen_io_info_type( &(_p)->type ); \
+ _mbg_swab16( &(_p)->num ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Data types used with ::GEN_IO_INFO::type
+ *
+ * The first type specifier, ::PCPS_GEN_IO_GET_INFO, can
+ * be used to find out which of the other data types are
+ * supported, and how many data sets of the specified type
+ * are supported by a device.
+ */
+enum PCPS_GEN_IO_TYPES
+{
+ PCPS_GEN_IO_GET_INFO, ///< ::GEN_IO_INFO (read only)
+ PCPS_GEN_IO_CAL_REC_IRIG_RX_COMP, ///< ::CAL_REC_IRIG_RX_COMP (read/write)
+ N_PCPS_GEN_IO_TYPE ///< number of known types
+};
+
+/** @} defgroup group_generic_io */
+
+
typedef uint16_t ROM_CSUM; /* The ROM checksum */
-typedef uint16_t RCV_TIMEOUT; /* [min] (only if HAS_RCV_TIMEOUT) */
-typedef uint16_t IGNORE_LOCK; /* (only if GPS_HAS_IGNORE_LOCK) */
+typedef uint16_t RCV_TIMEOUT; /* [min] (only if ::HAS_RCV_TIMEOUT) */
+typedef uint16_t IGNORE_LOCK; /* (only if ::GPS_HAS_IGNORE_LOCK) */
/*
- * Originally IGNORE_LOG above has been a boolean value (equal or
+ * Originally ::IGNORE_LOG above has been a boolean value (equal or
* not equal 0) which was evaluated the same way for all ports.
*
* Due to special firmware requirements it has been changed to a
@@ -3763,93 +10201,158 @@ typedef uint16_t IGNORE_LOCK; /* (only if GPS_HAS_IGNORE_LOCK) */
( (_il) & ( _ignore_lock_for_port(_n) | IGNORE_LOCK_FOR_ALL_PORTS ) )
-/*------------------------------------------------------------------------*/
-/*
+/**
+ * @defgroup group_scu Definitions used with SCU devices
+ *
* The structures below are used with the SCU multiplexer board
- * in a redundant system:
- */
+ * in a redundant system.
+ *
+ * @see ::GPS_MODEL_IS_SCU
+ *
+ * @{ */
typedef struct
{
- uint32_t hw_id; // hardware identification
- uint32_t fw_id; // firmware identification
- uint16_t flags; // reserved currently 0
- uint8_t clk0_info; // reference clock 0 type
- uint8_t clk1_info; // reference clock 1 type
- uint16_t epld_status; // epld status word, see defintions below
- uint16_t epld_control; // epld control word, see defintions below
+ uint32_t hw_id; ///< hardware identification
+ uint32_t fw_id; ///< firmware identification
+ uint16_t flags; ///< reserved currently 0
+ uint8_t clk0_info; ///< reference clock 0 type
+ uint8_t clk1_info; ///< reference clock 1 type
+ uint16_t epld_status; ///< EPLD status word, see ::SCU_STAT_MASKS
+ uint16_t epld_control; ///< EPLD control word, see ::SCU_CTRL_MASKS
+
} SCU_STAT_INFO;
+#define _mbg_swab_scu_stat_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->hw_id ); \
+ _mbg_swab32( &(_p)->fw_id ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->clk0_info ); \
+ _mbg_swab8( &(_p)->clk1_info ); \
+ _mbg_swab16( &(_p)->epld_status ); \
+ _mbg_swab16( &(_p)->epld_control ); \
+} while ( 0 )
+
+
+
typedef struct
{
- uint16_t epld_control_mask; // control mask, determines which bit is to be changed
- uint16_t epld_control_value; // control value, determines value of bits to be changed
- uint32_t flags; // reserved, currently 0
+ uint16_t epld_control_mask; ///< control mask, determines which bit is to be changed, see ::SCU_CTRL_MASKS
+ uint16_t epld_control_value; ///< control value, determines value of bits to be changed, see ::SCU_CTRL_MASKS
+ uint32_t flags; ///< reserved, currently 0
+
} SCU_STAT_SETTINGS;
-// definitions for status word bit masks
-#define MSK_EPLD_STAT_TS1 0x0001 // state of time sync signal clk_1
-#define MSK_EPLD_STAT_TS2 0x0002 // state of time sync signal clk_2
-#define MSK_EPLD_STAT_TL_ERROR 0x0004 // state of time limit error input
-#define MSK_EPLD_STAT_PSU1_OK 0x0008 // state of power supply 1 monitoring input
-#define MSK_EPLD_STAT_PSU2_OK 0x0010 // state of power supply 2 monitoring input
-#define MSK_EPLD_STAT_AUTO 0x0020 // AUTOMATIC/REMOTE or MANUAL Mode
-#define MSK_EPLD_STAT_SEL 0x0040 // select bit for output MUX, ( clk_1 = 0 )
-#define MSK_EPLD_STAT_ENA 0x0080 // enable Bit for output MUX, set if enabled
-#define MSK_EPLD_STAT_ACO 0x4000 // Access control override bit
-#define MSK_EPLD_STAT_WDOG_OK 0x8000 // WDT_OK set to zero if watchdog expired
+#define _mbg_swab_scu_stat_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->epld_control_mask ); \
+ _mbg_swab16( &(_p)->epld_control_value ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
-#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 )
+/**
+ * @brief Bit masks used to check the SCU EPLD status
+ *
+ * Used with ::SCU_STAT_INFO::epld_status
+ */
+enum SCU_STAT_MASKS
+{
+ MSK_EPLD_STAT_TS1 = 0x0001, ///< state of time sync signal clk_1
+ MSK_EPLD_STAT_TS2 = 0x0002, ///< state of time sync signal clk_2
+ MSK_EPLD_STAT_TL_ERROR = 0x0004, ///< state of time limit error input
+ MSK_EPLD_STAT_PSU1_OK = 0x0008, ///< state of power supply 1 monitoring input
+ MSK_EPLD_STAT_PSU2_OK = 0x0010, ///< state of power supply 2 monitoring input
+ MSK_EPLD_STAT_AUTO = 0x0020, ///< AUTOMATIC/REMOTE or MANUAL Mode
+ MSK_EPLD_STAT_SEL = 0x0040, ///< select bit for output MUX, ( clk_1 = 0 )
+ MSK_EPLD_STAT_ENA = 0x0080, ///< enable Bit for output MUX, set if enabled
+ MSK_EPLD_STAT_HAS_LAN = 0x0100, ///< indicates that the device has a network interface
+ MSK_EPLD_STAT_RESERVED0 = 0x0200, ///< reserved, DO NOT USE!
+ MSK_EPLD_STAT_RESERVED1 = 0x0400, ///< reserved, DO NOT USE!
+ MSK_EPLD_STAT_HAS_4_PSUS = 0x0800, ///< indicates 4 power supplies instead of 2
+ MSK_EPLD_STAT_PSU3_OK = 0x1000, ///< state of power supply 3 monitoring input
+ MSK_EPLD_STAT_PSU4_OK = 0x2000, ///< state of power supply 4 monitoring input
+ MSK_EPLD_STAT_ACO = 0x4000, ///< Access control override bit
+ MSK_EPLD_STAT_WDOG_OK = 0x8000 ///< WDT_OK set to zero if watchdog expired
+};
-/*
- * Definitions for clk0_info and clk1_info, can be used to determine
- * the reference clock type connected to SCU input channel 0 and 1:
+
+/**
+ * @brief Bit masks used to control the SCU EPLD
+ *
+ * Used with ::SCU_STAT_INFO::epld_control, ::SCU_STAT_SETTINGS::epld_control_mask,
+ * and ::SCU_STAT_SETTINGS::epld_control_value.
*/
-enum
+enum SCU_CTRL_MASKS
+{
+ MSK_EPLD_CTL_DISB_SERIAL = 0x0001, ///< disable serial output on error
+ MSK_EPLD_CTL_DISB_PPS = 0x0002, ///< disable PPS output on error
+ MSK_EPLD_CTL_DISB_10MHZ = 0x0004, ///< disable 10 MHz output on error
+
+ MSK_EPLD_CNTL_SEL_REM = 0x0800, ///< remote select for output MUX (clk_1 = 0)
+ MSK_EPLD_CNTL_DIS_REM = 0x1000, ///< remote disable for output MUX
+ MSK_EPLD_CNTL_REMOTE = 0x2000, ///< must be set to enable remote operation
+ MSK_EPLD_CNTL_SEL_SNMP = 0x4000, ///< select clk for comm. (clk1 = 0)
+ MSK_EPLD_CNTL_ENA_SNMP = 0x8000, ///< connect COM0 channels to XPORT
+};
+
+
+
+/**
+ * @brief Definitions for ::SCU_STAT_INFO::clk0_info and ::SCU_STAT_INFO::clk1_info
+ *
+ * Can be used to determine the reference clock type connected to the SCU input channels.
+ */
+enum SCU_CLK_INFO_TYPES
{
- SCU_CLK_INFO_GPS, // ref. clock is GPS receiver
- SCU_CLK_INFO_DCF_PZF, // ref. clock is DCF77 PZF receiver
- SCU_CLK_INFO_DCF_AM, // ref. clock is DCF77 AM receiver
- SCU_CLK_INFO_TCR // ref. clock is IRIG time code receiver
+ SCU_CLK_INFO_GPS, ///< ref. clock is GPS receiver
+ SCU_CLK_INFO_DCF_PZF, ///< ref. clock is DCF77 PZF receiver
+ SCU_CLK_INFO_DCF_AM, ///< ref. clock is DCF77 AM receiver
+ SCU_CLK_INFO_TCR, ///< ref. clock is IRIG time code receiver
+ N_SCU_CLK_INFO ///< number of known types
};
+/** @} defgroup group_scu */
+
/*------------------------------------------------------------------------*/
+#define REMOTE 0x10
+#define BOOT 0x20
+
/**
* @brief Satellite receiver modes of operation.
*
- * @note Some of the code combinations are obsolete with recent
+ * @note Some of the code combinations are deprecated with recent
* satellite receivers. However, this doesn't matter since the mode
* is just read from the receiver.
*/
-#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 )
+enum RECEIVER_MODES
+{
+ TRACK = ( 0x01 ),
+ AUTO_166 = ( 0x02 ),
+ WARM_166 = ( 0x03 | BOOT ),
+ COLD_166 = ( 0x04 | BOOT ),
+ AUTO_BC = ( 0x05 | REMOTE ),
+ WARM_BC = ( 0x06 | REMOTE | BOOT ),
+ COLD_BC = ( 0x07 | REMOTE | BOOT ),
+ UPDA_166 = ( 0x08 | BOOT ),
+ UPDA_BC = ( 0x09 | REMOTE | BOOT )
+};
typedef int16_t DAC_VAL;
#define _mbg_swab_dac_val( _p ) \
- _mbg_swab16( _p );
+ _mbg_swab16( _p )
@@ -3858,21 +10361,23 @@ typedef int16_t DAC_VAL;
*/
typedef struct
{
- uint16_t mode; /**< Mode of operation, see predefined codes */
- uint16_t good_svs; /**< Numb. of satellites that can currently be received and used */
- uint16_t svs_in_view; /**< Numb. of satellites that should be in view according to the almanac data */
- DAC_VAL dac_val; /**< Oscillator fine DAC value */
- DAC_VAL dac_cal; /**< Oscillator calibration DAC value ( see #OSC_DAC_RANGE, #OSC_DAC_BIAS ) */
+ uint16_t mode; ///< Mode of operation, see ::RECEIVER_MODES
+ uint16_t good_svs; ///< Numb. of satellites that can currently be received and used
+ uint16_t svs_in_view; ///< Numb. of satellites that should be visible above the horizon
+ DAC_VAL dac_val; ///< Oscillator fine DAC value
+ DAC_VAL dac_cal; ///< Oscillator calibration DAC value ( see ::OSC_DAC_RANGE, ::OSC_DAC_BIAS )
+
} STAT_INFO;
#define _mbg_swab_stat_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->mode ); \
_mbg_swab16( &(_p)->good_svs ); \
_mbg_swab16( &(_p)->svs_in_view ); \
_mbg_swab_dac_val( &(_p)->dac_val ); \
_mbg_swab_dac_val( &(_p)->dac_cal ); \
-}
+} while ( 0 )
#define OSC_DAC_RANGE 4096UL
@@ -3882,96 +10387,372 @@ typedef struct
/**
* @brief An enumeration of known satellite navigation systems
+ *
+ * @see ::MBG_GNSS_TYPE_MASKS
+ * @see ::GNSS_TYPE_STRS
*/
-enum
+enum MBG_GNSS_TYPES
{
- GNSS_TYPE_GPS, /**< GPS, United States */
- GNSS_TYPE_GLONASS, /**< GLONASS, Russia */
- GNSS_TYPE_BEIDOU, /**< BEIDOU, China */
- GNSS_TYPE_GALILEO, /**< GALILEO, Europe */
- N_GNSS_TYPES /**< Number of defined codes */
+ GNSS_TYPE_GPS, ///< GPS, United States
+ GNSS_TYPE_GLONASS, ///< GLONASS, Russia
+ GNSS_TYPE_BEIDOU, ///< BEIDOU, China
+ GNSS_TYPE_GALILEO, ///< GALILEO, Europe
+ GNSS_TYPE_WAAS, ///< WAAS, Wide Area Augmentation System
+ GNSS_TYPE_EGNOS, ///< EGNOS, European Geostationary Navigation Overlay Service
+ GNSS_TYPE_QZSS, ///< QZSS, Quasi Zenit Satellite System
+ N_GNSS_TYPES ///< Number of defined codes
};
+
+/**
+ * @brief Bit masks associated with ::MBG_GNSS_TYPES
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
+enum MBG_GNSS_TYPE_MASKS
+{
+ MBG_GNSS_TYPE_MSK_GPS = ( 1UL << GNSS_TYPE_GPS ), ///< see ::GNSS_TYPE_GPS
+ MBG_GNSS_TYPE_MSK_GLONASS = ( 1UL << GNSS_TYPE_GLONASS ), ///< see ::GNSS_TYPE_GLONASS
+ MBG_GNSS_TYPE_MSK_BEIDOU = ( 1UL << GNSS_TYPE_BEIDOU ), ///< see ::GNSS_TYPE_BEIDOU
+ MBG_GNSS_TYPE_MSK_GALILEO = ( 1UL << GNSS_TYPE_GALILEO ), ///< see ::GNSS_TYPE_GALILEO
+ MBG_GNSS_TYPE_MSK_WAAS = ( 1UL << GNSS_TYPE_WAAS ), ///< see ::GNSS_TYPE_WAAS
+ MBG_GNSS_TYPE_MSK_EGNOS = ( 1UL << GNSS_TYPE_EGNOS ), ///< see ::GNSS_TYPE_EGNOS
+ MBG_GNSS_TYPE_MSK_QZSS = ( 1UL << GNSS_TYPE_QZSS ) ///< see ::GNSS_TYPE_QZSS
+};
+
+
+/**
+ * @brief Name strings for the the known satellite navigation systems
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
#define GNSS_TYPE_STRS \
{ \
"GPS", \
"GLONASS", \
- "BEIDOU" , \
- "GALILEO" \
+ "BEIDOU", \
+ "GALILEO", \
+ "WAAS", \
+ "EGNOS", \
+ "QZSS" \
}
-#define MBG_GNSS_TYPE_MSK_GPS ( 1UL << GNSS_TYPE_GPS )
-#define MBG_GNSS_TYPE_MSK_GLONASS ( 1UL << GNSS_TYPE_GLONASS )
-#define MBG_GNSS_TYPE_MSK_BEIDOU ( 1UL << GNSS_TYPE_BEIDOU )
-#define MBG_GNSS_TYPE_MSK_GALILEO ( 1UL << GNSS_TYPE_GALILEO )
-
#define N_GNSS_MODE_PRIO 8
+/**
+ * @brief GNSS mode settings
+ *
+ * @see ::MBG_GNSS_TYPES
+ */
typedef struct
{
- uint32_t gnss_set; /**< current set of GNSS types */
- uint8_t prio[N_GNSS_MODE_PRIO]; /**< index 0 for highest priority, use GNSS enumeration above, init with 0xFF if not supported */
- uint32_t flags; /**< see below */
+ uint32_t gnss_set; ///< bit mask of currently used GNSS systems, see ::MBG_GNSS_TYPE_MASKS
+ uint8_t prio[N_GNSS_MODE_PRIO]; ///< see ::MBG_GNSS_TYPES, unused fields set to 0xFF, idx 0 is highest prio
+ uint32_t flags; ///< unused, currently always 0 (should be named MBG_GNSS_MODE_SETTINGS_FLAG_MASKS)
+
} MBG_GNSS_MODE_SETTINGS;
#define _mbg_swab_mbg_gnss_mode_settings( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->gnss_set ); \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
typedef struct
{
- MBG_GNSS_MODE_SETTINGS settings; /**< current GNSS mode settings */
- uint32_t supp_gnss_types; /**< bit masks of supported GNSS types */
- uint32_t flags; /**< indicates which of the defined flags are supported by the device */
+ MBG_GNSS_MODE_SETTINGS settings; ///< Current GNSS mode settings
+ uint32_t supp_gnss_types; ///< Bit masks of supported GNSS types, see ::MBG_GNSS_TYPE_MASKS
+ uint16_t flags; ///< See ::MBG_GNSS_MODE_INFO_FLAG_MASKS
+ uint16_t n_sv_status; ///< Number of ::GNSS_SV_STATUS_IDX structures that can be read (only if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS)
+
} MBG_GNSS_MODE_INFO;
#define _mbg_swab_mbg_gnss_mode_info( _p ) \
+do \
{ \
_mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \
_mbg_swab32( &(_p)->supp_gnss_types ); \
- _mbg_swab32( &(_p)->flags ); \
-}
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->n_sv_status ); \
+} while ( 0 )
+
/**
- * @brief Flags used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags
+ * @brief Flag bits used to define ::MBG_GNSS_MODE_INFO_FLAG_MASKS
+ *
+ * @see ::MBG_GNSS_MODE_INFO_FLAG_MASKS
*/
-enum
+enum MBG_GNSS_MODE_INFO_FLAG_BITS
{
- MBG_GNSS_FLAG_EXCLUSIVE, /**< (read only) only one of the supported GNSS systems can be used at the same time */
- MBG_GNSS_FLAG_HAS_PRIORITY, /**< (read only) priority can be configured using the MBG_GNSS_MODE_SETTINGS::prio field */
+ MBG_GNSS_FLAG_EXCLUSIVE, ///< Only one of the supported GNSS systems can be used at the same time
+ MBG_GNSS_FLAG_HAS_PRIORITY, ///< Priority can be configured using the ::MBG_GNSS_MODE_SETTINGS::prio field
+ MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, ///< The ::GNSS_SAT_INFO_IDX structure is supported by the device
+ MBG_GNSS_FLAG_HAS_SV_STATUS, ///< The ::GNSS_SV_STATUS_IDX structure is supported by the device
N_MBG_GNSS_FLAGS
};
-#define MBG_GNSS_FLAG_MSK_EXCLUSIVE ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE )
-#define MBG_GNSS_FLAG_MSK_HAS_PRIORITY ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY )
+/**
+ * @brief Flag masks used with ::MBG_GNSS_MODE_INFO::flags
+ *
+ * @see ::MBG_GNSS_MODE_INFO_FLAG_BITS
+ */
+enum MBG_GNSS_MODE_INFO_FLAG_MASKS
+{
+ MBG_GNSS_FLAG_MSK_EXCLUSIVE = ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE ), ///< see ::MBG_GNSS_FLAG_EXCLUSIVE
+ MBG_GNSS_FLAG_MSK_HAS_PRIORITY = ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY ), ///< see ::MBG_GNSS_FLAG_HAS_PRIORITY
+ MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER = ( 1UL << MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER ), ///< see ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER
+ MBG_GNSS_FLAG_MSK_HAS_SV_STATUS = ( 1UL << MBG_GNSS_FLAG_HAS_SV_STATUS ) ///< see ::MBG_GNSS_FLAG_HAS_SV_STATUS
+};
-#define MAX_USED_SATS 32
+
+#define MAX_USED_SATS 32
/**
- * @brief SV information from a certain GNSS type.
+ * @brief Satellite information for a particular GNSS type.
*/
typedef struct
{
- uint8_t gnss_type; /**< GNSS type from the enumeration above */
- uint8_t reserved;
- uint16_t good_svs;
- uint16_t svs_in_view;
- uint8_t svs[MAX_USED_SATS];
+ uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES
+ uint8_t reserved; ///< Reserved, currently always 0
+ uint16_t good_svs; ///< Num. of satellites that can currently be received and used
+ uint16_t svs_in_view; ///< Num. of satellites that should be visible above the horizon
+ uint8_t svs[MAX_USED_SATS]; ///< IDs of the satellites actually used for navigation, 0 == not used
+
} GNSS_SAT_INFO;
#define _mbg_swab_gnss_sat_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->good_svs ); \
_mbg_swab16( &(_p)->svs_in_view ); \
-}
+} while ( 0 )
+
+
+
+/**
+ * @brief One of several sets of satellite information for a particular GNSS type.
+ *
+ *
+ */
+typedef struct
+{
+ /// GNSS system type index according to ::MBG_GNSS_MODE_INFO::supp_gnss_types.
+ /// I.e., idx 0 corresponds to the GNSS system for which the least significant
+ /// bit is set in ::MBG_GNSS_MODE_INFO::supp_gnss_types, idx 1 corresponds to
+ /// GNSS system for which the next higher bit is set, etc. This must *not*
+ /// necessarily match the sequence of the ::MBG_GNSS_TYPES enumeration.
+ uint16_t idx;
+
+ GNSS_SAT_INFO gnss_sat_info; ///< see ::GNSS_SAT_INFO
+
+} GNSS_SAT_INFO_IDX;
+
+#define _mbg_swab_gnss_sat_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_gnss_sat_info( &(_p)->gnss_sat_info ); \
+} while ( 0 )
+
+
+
+/**
+ * @defgroup group_gnss_sv_status GNSS Satellite Status
+ *
+ * @note These structures and associated types are only supported by a device
+ * if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS is set // ::FIXME
+ *
+ * @{ */
+
+/**
+ * @brief Detailed GNSS satellite status
+ *
+ * @see ::GNSS_SV_STATUS_IDX
+ * @see @ref group_gnss_sv_stat_flags
+ */
+typedef struct
+{
+ uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES
+ uint8_t svno; ///< Satellite number, see ::TODO
+ uint8_t cn_ratio; ///< Carrier-to-noise ratio [dbHz]
+ int8_t elev; ///< Elevation [deg], range: -90..90 deg
+
+ int16_t azim; ///< Azimuth [deg], range: 0..360 deg
+ int16_t pr_residual; ///< Pseudo range residual [m]
+
+ uint32_t stat_flags; ///< see @ref group_gnss_sv_stat_flags
+
+} GNSS_SV_STATUS;
+
+#define _mbg_swab_gnss_sv_status( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->gnss_type ); \
+ _mbg_swab8( &(_p)->svno ); \
+ _mbg_swab8( &(_p)->cn_ratio ); \
+ _mbg_swab8( &(_p)->elev ); \
+ _mbg_swab16( &(_p)->azim ); \
+ _mbg_swab16( &(_p)->pr_residual ); \
+ _mbg_swab32( &(_p)->stat_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @defgroup group_gnss_sv_stat_flags GNSS status flags encoding
+ *
+ * Used with ::GNSS_SV_STATUS::stat_flags.
+ *
+ * @{ */
+
+/// Bits 0 to 2 are a 3 bit quality indicator, see ::GNSS_SV_STAT_QUALITY_INDS
+#define _gnss_sv_stat_quality_ind( __stat_flags ) \
+ ( (uint8_t) ( (__stat_flags) & 0x00000007UL ) )
+
+/// Bit 3 is set if the SV is actually used for navigation
+#define _gnss_sv_stat_sv_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00000008UL ) != 0 )
+
+/// Bits 4 and 5 are a 2 bit health code, see ::GNSS_SV_STAT_HEALTH_CODES
+#define _gnss_sv_stat_health_code( __stat_flags ) \
+ ( (uint8_t) ( ( (__stat_flags) & 0x00000030UL ) >> 4 ) )
+
+/// Bit 6 is set if differential correction is available for this SV
+#define _gnss_sv_stat_diff_corr( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00000040UL ) != 0 )
+
+/// Bit 7 is set if carrier smoothed pseudorange is used for this SV
+#define _gnss_sv_stat_smoothed( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00000080UL ) != 0 )
+
+/// Bits 8 to 10 are a 3 bit code indicating the orbit source, see ::GNSS_SV_STAT_ORBIT_SOURCES
+#define _gnss_sv_stat_orbit_src( __stat_flags ) \
+ ( (uint8_t) ( ( (__stat_flags) & 0x00000700UL ) >> 8 ) )
+
+/// Bit 11 is set if ephemeris parameters are available for this SV
+#define _gnss_sv_stat_eph_avail( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00000800UL ) != 0 )
+
+/// Bit 12 is set if almanac parameters are available for this SV
+#define _gnss_sv_stat_alm_avail( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00001000UL ) != 0 )
+
+/// Bit 13 is set if AssistNow Offline data is available for this SV
+#define _gnss_sv_stat_ano_avail( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00002000UL ) != 0 )
+
+/// Bit 14 is set if AssistNow Autonomous data is available for this SV
+#define _gnss_sv_stat_aop_avail( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00004000UL ) != 0 )
+
+/// Bit 15 is reserved.
+
+/// Bit 16 is set if SBAS corrections have been used for this SV
+#define _gnss_sv_stat_sbas_corr_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00010000UL ) != 0 )
+
+/// Bit 17 is set if RTCM corrections have been used for this SV
+#define _gnss_sv_stat_rtcm_corr_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00020000UL ) != 0 )
+
+/// Bits 18 and 19 are reserved.
+
+/// Bit 20 is set if pseudorange corrections have been used for this SV
+#define _gnss_sv_stat_pr_corr_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00100000UL ) != 0 )
+
+/// Bit 21 is set if carrier range corrections have been used for this SV
+#define _gnss_sv_stat_cr_corr_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00200000UL ) != 0 )
+
+/// Bit 22 is set if range rate (doppler) corrections have been used for this SV
+#define _gnss_sv_stat_do_corr_used( __stat_flags ) \
+ ( ( (__stat_flags) & 0x00400000UL ) != 0 )
+
+/// Bits 23 to 31 are reserved.
+
+/** @} defgroup group_gnss_sv_stat_flags */
+
+
+/**
+ * @brief Quality indicators used with ::GNSS_SV_STATUS::stat_flags
+ *
+ * @see ::_gnss_sv_stat_quality_ind
+ */
+enum GNSS_SV_STAT_QUALITY_INDS
+{
+ GNSS_SV_STAT_NO_SIGNAL, ///< No signal
+ GNSS_SV_STAT_SEARCHING, ///< Searching signal
+ GNSS_SV_STAT_ACQUIRED, ///< Signal acquired
+ GNSS_SV_STAT_UNUSABLE, ///< Signal detected but unusable
+ GNSS_SV_STAT_CODE_LOCKED, ///< Code locked and time synchronized
+ GNSS_SV_STAT_CODE_CARRIER_LOCKED, ///< Code and carrier locked, and time synchronized
+ GNSS_SV_STAT_CODE_CARRIER_LOCKED_2, ///< Code and carrier locked, and time synchronized
+ GNSS_SV_STAT_CODE_CARRIER_LOCKED_3 ///< Code and carrier locked, and time synchronized
+};
+
+
+/**
+ * @brief Health indicators used with ::GNSS_SV_STATUS::stat_flags
+ *
+ * @see ::_gnss_sv_stat_health_code
+ */
+enum GNSS_SV_STAT_HEALTH_CODES
+{
+ GNSS_SV_STAT_HEALTH_UNKNOWN, ///< Health status unknown
+ GNSS_SV_STAT_HEALTH_OK, ///< Healthy
+ GNSS_SV_STAT_HEALTH_NOT_OK ///< Unhealthy
+};
+
+
+/**
+ * @brief Orbit source codes used with ::GNSS_SV_STATUS::stat_flags
+ *
+ * @see ::_gnss_sv_stat_orbit_src
+ */
+enum GNSS_SV_STAT_ORBIT_SOURCES
+{
+ GNSS_SV_STAT_ORBIT_SRC_UNKNOWN, ///< Orbit source unknown
+ GNSS_SV_STAT_ORBIT_SRC_EPH, ///< Ephemeris data used for orbit
+ GNSS_SV_STAT_ORBIT_SRC_ALM, ///< Almanac data used for orbit
+ GNSS_SV_STAT_ORBIT_SRC_ASSN_OFFL, ///< AssistNow Offline orbit is used
+ GNSS_SV_STAT_ORBIT_SRC_ASSN_AUTO, ///< AssistNow Autonomous orbit is used
+ GNSS_SV_STAT_ORBIT_OTHER_1, ///< Other orbit information is used
+ GNSS_SV_STAT_ORBIT_OTHER_2, ///< Other orbit information is used
+ GNSS_SV_STAT_ORBIT_OTHER_3 ///< Other orbit information is used
+};
+
+
+
+/**
+ * @brief Detailed GNSS satellite status, plus index
+ *
+ * @see ::GNSS_SV_STATUS
+ */
+typedef struct
+{
+ uint32_t idx; ///< Range 0..::MBG_GNSS_MODE_INFO::n_sv_status-1
+ GNSS_SV_STATUS gnss_sv_status;
+
+} GNSS_SV_STATUS_IDX;
+
+#define _mbg_swab_gnss_sv_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_gnss_sv_status( &(_p)->gnss_sv_status ); \
+} while ( 0 )
+
+
+/** @} defgroup group_gnss_sv_status */
+
#ifndef _IDENT_DEFINED
@@ -3987,11 +10768,14 @@ typedef struct
#endif
#define _mbg_swab_ident( _p ) \
+do \
{ \
int i; \
for ( i = 0; i < 4; i++ ) \
_mbg_swab32( &(_p)->lw[i] ); \
-}
+} while ( 0 )
+
+
/**
* @brief A data type used to configure the length of an antenna cable [m]
@@ -4003,14 +10787,28 @@ typedef uint16_t ANT_CABLE_LEN;
/**
- * @defgroup group_ip4_cfg Simple configuration and status
- * of an optional LAN interface.
+ * @defgroup group_net_cfg Network configuration stuff
*
- * @note This is only supported if the flag GPS_HAS_LAN_IP4 is set
- * in RECEIVER_INFO::features.
+ * @{ */
+
+/**
+ * @defgroup group_net_basic_types Basic network parameter types
*
* @{ */
+/**
+ * @brief The MAC address of a network interface
+ */
+typedef struct
+{
+ uint8_t b[6];
+
+} MBG_MAC_ADDR;
+
+#define _mbg_swab_mbg_mac_addr( _p ) \
+ _nop_macro_fnc()
+
+
/**
* @brief An IPv4 address
@@ -4018,57 +10816,172 @@ typedef uint16_t ANT_CABLE_LEN;
typedef uint32_t IP4_ADDR;
#define _mbg_swab_ip4_addr( _p ) \
- _mbg_swab32( _p );
+ _mbg_swab32( _p )
+
+/** @brief The number of bits used for an IPv6 address */
+#define IP6_ADDR_BITS 128
+
+/** @brief The number of bytes used for an IPv6 address */
+#define IP6_ADDR_BYTES ( IP6_ADDR_BITS / 8 ) // == 16
+
/**
- * @brief Settings of an IPv4 network interface
+ * @brief An IPv6 address
*/
typedef struct
{
- IP4_ADDR ip_addr; /**< the IP address */
- IP4_ADDR netmask; /**< the network mask */
- IP4_ADDR broad_addr; /**< the broadcast address */
- IP4_ADDR gateway; /**< the default gateway */
- uint16_t flags; /**< flags as specified below */
- uint16_t vlan_cfg; /**< VLAN configuration, see below */
+ uint8_t b[IP6_ADDR_BYTES]; ///< bytes holding the address bits (not the string notation), b[0] == LSBs
-} IP4_SETTINGS;
+} IP6_ADDR;
-#define _mbg_swab_ip4_settings( _p ) \
-{ \
- _mbg_swab_ip4_addr( &(_p)->ip_addr ); \
- _mbg_swab_ip4_addr( &(_p)->netmask ); \
- _mbg_swab_ip4_addr( &(_p)->broad_addr ); \
- _mbg_swab_ip4_addr( &(_p)->gateway ); \
- _mbg_swab16( &(_p)->flags ); \
- _mbg_swab16( &(_p)->vlan_cfg ); \
+#define _mbg_swab_ip6_addr( _p ) _nop_macro_fnc()
+
+
+
+/**
+ * @brief An IPv6 address plus number of netmask bits
+ */
+typedef struct
+{
+ IP6_ADDR addr; ///< bit mask of the bytes holding the address bits, b[0] == LSBs
+ uint8_t prefix; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24
+ uint8_t reserved[3]; ///< Reserved, alignment, currently 0
+
+} IP6_ADDR_CIDR;
+
+
+
+/** @brief The max number of chars required for an IPv6 address string */
+#define MAX_IP6_ADDR_STR_LEN 43 ///< e.g. 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/128
+
+/** @brief Buffer size required to store an IPv6 address string */
+#define IP6_ADDR_STR_SIZE ( MAX_IP6_ADDR_STR_LEN + 1 ) ///< ::MAX_IP6_ADDR_STR_LEN + terminating 0
+
+/** @brief A buffer for an IPv6 address string */
+typedef char IP6_ADDR_STR[IP6_ADDR_STR_SIZE];
+
+
+
+/**
+ * @brief Possible IPv6 Multicast Scopes
+ *
+ * If the first (most significant) byte of an IPv6 address is 0xFF this
+ * indicates that the address is a multicast address, and in this case
+ * the second byte determines the scope for which the specified address
+ * is valid. These scope ID numbers are assigned in RFC 7346 which
+ * supersedes RFC 4291.
+ *
+ * @see ::IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES
+ */
+enum IPV6_MULTICAST_SCOPES
+{
+ IPV6_MULTICAST_SCOPE_INTF_LOCAL = 0x01, ///< Interface-Local scope
+ IPV6_MULTICAST_SCOPE_LINK_LOCAL, ///< Link-Local scope
+ IPV6_MULTICAST_SCOPE_REALM_LOCAL, ///< Realm-Local scope
+ IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, ///< Admin-Local scope
+ IPV6_MULTICAST_SCOPE_SITE_LOCAL, ///< Site-Local scope
+ IPV6_MULTICAST_SCOPE_ORGA_LOCAL = 0x08, ///< Organization-Local scope
+ IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE = 0x0E ///< Global scope
+};
+
+
+/**
+ * @brief Name strings for IPv6 multicast scopes
+ *
+ * This can e.g. be used to initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements.
+ *
+ * @see ::IPV6_MULTICAST_SCOPES
+ */
+#define IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES \
+{ \
+ { IPV6_MULTICAST_SCOPE_INTF_LOCAL, "FF01 - Interface-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_LINK_LOCAL, "FF02 - Link-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_REALM_LOCAL, "FF03 - Realm-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, "FF04 - Admin-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_SITE_LOCAL, "FF05 - Site-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_ORGA_LOCAL, "FF08 - Organization-Local Scope" }, \
+ { IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE, "FF0E - Global Scope" }, \
+ { 0, NULL } \
}
+
+/**
+ * @brief The maximum length of a fully qualified host/domain domain name (FQDN)
+ *
+ * In theory each single component (host name, domain name, top level domain name)
+ * of a FQDN can have up to 63 characters, but the overall length is limited to
+ * 255 characters (see RFC-1123). We specify one more character for the trailing 0.
+ */
+#define MBG_MAX_HOSTNAME_LEN 256
+
+
+/**
+ * @brief A buffer for a fully qualified domain name (FQDN) or a numeric IP address string
+ */
+typedef char MBG_HOSTNAME[MBG_MAX_HOSTNAME_LEN]; ///< ASCIIZ format
+
+#define _mbg_swab_mbg_host_name( _p ) _nop_macro_fnc()
+
+
+/** @} defgroup group_net_basic_types */
+
+
+
+/**
+ * @brief The maximum length of an interface name
+ *
+ * We use an extra name here for the Meinberg-specific structures
+ * to avoid a name clash with system definitions, e.g. Linux systems
+ * define IFNAMSIZ usually as 16 in linux/if.h.
+ */
+#define MBG_IFNAMSIZ 16
+
+
+/**
+ * @brief Hardware type for identification of physical interfaces
+ *
+ */
+enum MBG_NET_HW_TYPES
+{
+ MBG_NET_HW_TYPE_UNKNOWN,
+ MBG_ARPHRD_ETHER,
+ N_MBG_NET_HW_TYPES
+};
+
+
+/**
+ * @defgroup group_vlan_cfg Definitions used with VLAN configuration
+ *
+ * @{ */
+
/**
- * @brief Definitions used with IP4_SETTINGS::vlan_cfg
+ * @brief VLAN configuration
*
- * @note IP4_SETTINGS::vlan_cfg contains a combination of
- * a VLAN ID number plus a VLAN priority code.
+ * @note This is a combination of a VLAN ID number plus a VLAN priority code.
*/
-#define VLAN_ID_BITS 12 //< number of bits to hold the ID
-#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) //< number of ID values
-#define MIN_VLAN_ID 0 //< minimum ID value
-#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) //< maximum ID value
+typedef uint16_t MBG_VLAN_CFG;
+
+#define _mbg_swab_mbg_vlan_cfg( _p ) _mbg_swab16( _p )
+
+#define VLAN_ID_BITS 12 ///< number of bits to hold the ID
+#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) ///< number of ID values
+#define MIN_VLAN_ID 0 ///< minimum ID value
+#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) ///< maximum ID value
// vlan_id = ( vlan_cfg >> VLAN_ID_SHIFT ) & VLAN_ID_MSK
#define VLAN_ID_SHIFT 0
#define VLAN_ID_MSK ( ( 1 << VLAN_ID_BITS ) - 1 )
-#define VLAN_PRIORITY_BITS 3 //< number of bits to hold priority
-#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) //< number of priority values
-#define MIN_VLAN_PRIORITY 0 //< minimum priority
-#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) //< maximum priority
+#define VLAN_PRIORITY_BITS 3 ///< number of bits to hold priority
+#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) ///< number of priority values
+#define MIN_VLAN_PRIORITY 0 ///< minimum priority
+#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) ///< maximum priority
// vlan_priority = ( vlan_cfg >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK
-#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( uint16_t ) ) - VLAN_PRIORITY_BITS )
+#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( MBG_VLAN_CFG ) ) - VLAN_PRIORITY_BITS )
#define VLAN_PRIORITY_MSK ( ( 1 << VLAN_PRIORITY_BITS ) - 1 )
/**
@@ -4078,92 +10991,1406 @@ typedef struct
#define _decode_vlan_priority( _cfg ) ( ( (_cfg) >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK )
#define _encode_vlan_cfg( _id, _prty ) ( ( (_id) << VLAN_ID_SHIFT ) | ( (_prty) << VLAN_PRIORITY_SHIFT ) )
+/** @} defgroup group_vlan_cfg */
-#if 0 //##++ currently not used
-
-/* Misc configuration */
-
-typedef struct
-{
- uint16_t id; /* service ID, see below */
- uint16_t index; /* used if several same svcs must be cfg'd, e.g. DNS */
- char host[50]; /* see below */
-
-} IP_CFG;
+/**
+ * @defgroup group_ip4_cfg Simple IPv4-only configuration or status
+ *
+ * This is only supported if the flag ::GPS_HAS_LAN_IP4 is set
+ * in ::RECEIVER_INFO::features.
+ * @see @ref group_ext_net_cfg Extended network configuration and status
+ *
+ * @{ */
-/* Description of a service running on a device */
-
+/**
+ * @brief Settings of an IPv4-only network interface
+ */
typedef struct
{
- uint16_t id; /* service ID, see below */
- uint16_t socket; /* the socket on which the service is listening */
- uint32_t flags; /* see below */
+ IP4_ADDR ip_addr; ///< the IP address
+ IP4_ADDR netmask; ///< the network mask
+ IP4_ADDR broad_addr; ///< the broadcast address
+ IP4_ADDR gateway; ///< the default gateway
+ uint16_t flags; ///< see ::MBG_IP4_FLAG_MASKS
+ MBG_VLAN_CFG vlan_cfg; ///< VLAN configuration
-} IP_SERVICE;
+} IP4_SETTINGS;
-#endif // 0
+#define _mbg_swab_ip4_settings( _p ) \
+do \
+{ \
+ _mbg_swab_ip4_addr( &(_p)->ip_addr ); \
+ _mbg_swab_ip4_addr( &(_p)->netmask ); \
+ _mbg_swab_ip4_addr( &(_p)->broad_addr ); \
+ _mbg_swab_ip4_addr( &(_p)->gateway ); \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab_mbg_vlan_cfg( &(_p)->vlan_cfg ); \
+} while ( 0 )
/**
- * @brief LAN interface information
+ * @brief Simple LAN interface information
*
* This structure can be retrieved from a device
* to check the device's capabilities.
+ *
+ * It is only supported if the flag ::GPS_HAS_LAN_IP4 is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @see @ref group_ext_net_cfg Extended network configuration and status
*/
typedef struct
{
- uint16_t type; //< type of LAN interface, see below
- uint8_t mac_addr[6]; //< MAC address
- uint16_t ver_code; //< version number, high byte.low byte, in hex
- char ver_str[GPS_ID_STR_SIZE]; //< version string
- char sernum[GPS_ID_STR_SIZE]; //< serial number
- uint32_t rsvd_0; //< reserved, currently always 0
- uint16_t flags; //< flags as specified below
- uint16_t rsvd_1; //< reserved, currently always 0
+ uint16_t type; ///< type of LAN interface, see ::LAN_IF_TYPES
+ MBG_MAC_ADDR mac_addr; ///< MAC address
+ uint16_t ver_code; ///< version number (hex)
+ char ver_str[GPS_ID_STR_SIZE]; ///< version string
+ char sernum[GPS_ID_STR_SIZE]; ///< serial number
+ uint32_t rsvd_0; ///< reserved, currently always 0
+ uint16_t flags; ///< see ::MBG_IP4_FLAG_MASKS
+ uint16_t rsvd_1; ///< reserved, currently always 0
} LAN_IF_INFO;
#define _mbg_swab_lan_if_info( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->type ); \
_mbg_swab16( &(_p)->ver_code ); \
_mbg_swab32( &(_p)->rsvd_0 ); \
_mbg_swab16( &(_p)->flags ); \
_mbg_swab16( &(_p)->rsvd_1 ); \
+} while ( 0 )
+
+
+/**
+ * @brief Codes used with ::LAN_IF_INFO::type
+ */
+enum LAN_IF_TYPES
+{
+ LAN_IF_TYPE_XPORT, ///< LAN interface on an XPORT, superseded by RSC devices
+ LAN_IF_TYPE_PTP, ///< LAN interface is a special PTP interface
+ LAN_IF_TYPE_RSC, ///< RSC device, supersedes XPORT
+ N_LAN_IF_TYPE ///< number of defined LAN interface types
+};
+
+
+/**
+ * @brief Enumeration of flag bits used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags
+ *
+ * @see ::MBG_IP4_FLAG_MASKS
+ */
+enum MBG_IP4_FLAG_BITS
+{
+ /// In ::LAN_IF_INFO::flags this reports if DHCP is supported by the device.
+ /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable
+ /// or disable DHCP for the network interface.
+ IP4_BIT_DHCP,
+
+ /// Only used with ::IP4_SETTINGS::flags. Set if port link has been established.
+ IP4_BIT_LINK,
+
+ /// In ::LAN_IF_INFO::flags this reports if VLAN is supported by the device.
+ /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable
+ /// or disable VLAN for the network interface.
+ IP4_BIT_VLAN,
+
+ N_IP4_BIT ///< number of defined flag bits
+};
+
+
+/**
+ * @brief Bit masks used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags
+ *
+ * @see ::MBG_IP4_FLAG_BITS
+ */
+enum MBG_IP4_FLAG_MASKS
+{
+ IP4_MSK_DHCP = ( 1UL << IP4_BIT_DHCP ), ///< see ::IP4_BIT_DHCP
+ IP4_MSK_LINK = ( 1UL << IP4_BIT_LINK ), ///< see ::IP4_BIT_LINK
+ IP4_MSK_VLAN = ( 1UL << IP4_BIT_VLAN ), ///< see ::IP4_BIT_VLAN
+};
+
+/** @} defgroup group_ip4_cfg */
+
+
+
+/**
+ * @defgroup group_ext_net_cfg_types Types used for extended network configuration and status
+ *
+ * @{ */
+
+/**
+ * @brief Enumeration of types used with ::MBG_IP_ADDR::type
+ */
+enum MBG_IP_ADDR_TYPES
+{
+ MBG_IP_ADDR_TYPE_UNKNOWN,
+ MBG_IP_ADDR_TYPE_IP4,
+ MBG_IP_ADDR_TYPE_IP6,
+ N_MBG_IP_ADDR_TYPES
+};
+
+/*
+ * Default initializers for English mode string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN "unknown"
+#define MBG_IP_ADDR_TYPE_STR_ENG_IP4 "IPv4"
+#define MBG_IP_ADDR_TYPE_STR_ENG_IP6 "IPv6"
+
+#define MBG_IP_ADDR_TYPE_NAMES_ENG \
+{ \
+ MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN, \
+ MBG_IP_ADDR_TYPE_STR_ENG_IP4, \
+ MBG_IP_ADDR_TYPE_STR_ENG_IP6 \
}
+/**
+ * @brief Feature flag bits used to define ::MBG_NET_GLB_CFG_INFO_MASKS
+ *
+ * @see ::MBG_NET_GLB_CFG_INFO_MASKS
+ */
+enum MBG_NET_GLB_CFG_INFO_FLAGS
+{
+ MBG_NET_GLB_SUPP_STAGE_2, ///< Supports commands which have been added in stage 2
+ MBG_NET_GLB_SUPP_BONDING, ///< Supports bonding
+ N_MBG_NET_GLB_INFO_FLAGS
+};
+
/**
- * @brief Codes used with LAN_IF_INFO::type
+ * @brief Flag masks used with ::MBG_NET_GLB_CFG_INFO::feat_flags
+ *
+ * @see ::MBG_NET_GLB_CFG_INFO_FLAGS
*/
-enum
+enum MBG_NET_GLB_CFG_INFO_MASKS
{
- LAN_IF_TYPE_XPORT, //< LAN interface on an XPORT
- LAN_IF_TYPE_PTP, //< LAN interface is a special PTP interface
- N_LAN_IF_TYPE //< number of defined LAN interface types
+ MBG_NET_GLB_SUPP_STAGE_2_MASK = (1UL << MBG_NET_GLB_SUPP_STAGE_2), ///< see ::MBG_NET_GLB_SUPP_STAGE_2
+ MBG_NET_GLB_SUPP_BONDING_MASK = (1UL << MBG_NET_GLB_SUPP_BONDING) ///< see ::MBG_NET_GLB_SUPP_BONDING
};
+
/**
- * @brief Flags used with IP4_SETTINGS::flags and LAN_IF_INFO::flags
+ * @brief Network interface link speed mode enumeration
+ *
+ * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS
*/
-enum
+enum MBG_NET_INTF_LINK_SPEED_MODES
+{
+ MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN, ///< Unknown speed mode
+ MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF, ///< 10baseT Half Duplex (10 MBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL, ///< 10baseT Full Duplex (10 MBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF, ///< 100baseT Half Duplex (100 MBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL, ///< 100baseT Full Duplex (100 MBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF, ///< 1000baseT Half Duplex (1 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL, ///< 1000baseT Full Duplex (1 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL, ///< 1000baseKX Full Duplex (1 GBit/s)
+
+ MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL, ///< 2500baseX Full Duplex (2.5 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL, ///< 10000baseT Full Duplex (10 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL, ///< 10000baseKX4 Full Duplex (10 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL, ///< 10000baseKR Full Duplex (10 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC, ///< 10000baseR FEC (forward error correction) (10 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL, ///< 20000baseMLD2 Full Duplex (20 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL, ///< 20000baseKR2 Full Duplex (20 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL, ///< 40000baseKR4 Full Duplex (40 GBit/s)
+
+ MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL, ///< 40000baseCR4 Full Duplex (40 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL, ///< 40000baseSR4 Full Duplex (40 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL, ///< 40000baseLR4 Full Duplex (40 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL, ///< 56000baseKR4 Full Duplex (56 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL, ///< 56000baseCR4 Full Duplex (56 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL, ///< 56000baseSR4 Full Duplex (56 GBit/s)
+ MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL, ///< 56000baseLR4 Full Duplex (56 GBit/s)
+
+ N_MBG_NET_INTF_LINK_SPEED_MODES
+};
+
+
+
+/**
+ * @brief Network interface link speed mode masks
+ *
+ * @see ::MBG_NET_INTF_LINK_SPEED_MODES
+ *
+ * @anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS @{ */
+
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_UNKNOWN ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_KX_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL
+
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_2500_X_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KX4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KR_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_R_FEC ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_MLD2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_KR2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL
+
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL
+#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL
+
+/** @} anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS */
+
+
+
+/**
+ * @brief Network interface link speeds [Mb/s]
+ *
+ * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS
+ */
+enum MBG_NET_INTF_LINK_SPEEDS
+{
+ MBG_NET_INTF_LINK_SPEED_UNKNOWN = 0UL,
+ MBG_NET_INTF_LINK_SPEED_10 = 10UL,
+ MBG_NET_INTF_LINK_SPEED_100 = 100UL,
+ MBG_NET_INTF_LINK_SPEED_1000 = 1000UL,
+ MBG_NET_INTF_LINK_SPEED_2500 = 2500UL,
+ MBG_NET_INTF_LINK_SPEED_10000 = 10000UL,
+ MBG_NET_INTF_LINK_SPEED_20000 = 20000UL,
+ MBG_NET_INTF_LINK_SPEED_40000 = 40000UL,
+ MBG_NET_INTF_LINK_SPEED_56000 = 56000UL
+};
+
+
+
+/**
+ * @brief Network interface link port types
+ *
+ * @see ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS
+ */
+enum MBG_NET_INTF_LINK_PORT_TYPES
+{
+ MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN, ///< Unknown port type
+ MBG_NET_INTF_LINK_PORT_TYPE_TP, ///< Twisted Pair (TP) copper cable
+ MBG_NET_INTF_LINK_PORT_TYPE_FIBRE, ///< Fibre Optic (FO) cable
+ MBG_NET_INTF_LINK_PORT_TYPE_BNC, ///< Coaxial BNC cable
+ MBG_NET_INTF_LINK_PORT_TYPE_AUI, ///< Attachment Unit Interface (AUI), externel transceiver
+ MBG_NET_INTF_LINK_PORT_TYPE_MII, ///< Media Independent Interface (MII), external receiver
+ MBG_NET_INTF_LINK_PORT_TYPE_DA, ///< Direct attach SFP+ connection
+ N_MBG_NET_INTF_LINK_PORT_TYPES
+};
+
+
+
+/**
+ * @brief Network interface link port masks
+ *
+ * @see ::MBG_NET_INTF_LINK_PORT_TYPES
+ */
+enum MBG_NET_INTF_LINK_PORT_TYPE_MASKS
+{
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_UNKNOWN = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_TP ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_TP
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_FIBRE = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_FIBRE ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_FIBRE
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_BNC = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_BNC ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_BNC
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_AUI = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_AUI ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_AUI
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_MII = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_MII ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_MII
+ MBG_NET_INTF_LINK_PORT_TYPE_MASK_DA = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_DA ) ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_DA
+};
+
+
+
+/**
+ * @brief Initializers for network interface link port type long strings
+ *
+ * @see ::MBG_NET_INTF_LINK_PORT_TYPES
+ */
+#define MBG_NET_INTF_LINK_PORT_TYPE_LONG_STRS \
+{ \
+ "Unknown", \
+ "Twisted Pair", \
+ "Fibre Optic", \
+ "Coaxial BNC", \
+ "Attachment Unit Interface", \
+ "Media Independent Interface", \
+ "Direct Attach SFP+" \
+}
+
+
+/**
+ * @brief Initializers for network interface link port type short strings
+ *
+ * @see ::MBG_NET_INTF_LINK_PORT_TYPES
+ */
+#define MBG_NET_INTF_LINK_PORT_TYPE_SHORT_STRS \
+{ \
+ "Unknown", \
+ "TP", \
+ "FO", \
+ "BNC", \
+ "AUI", \
+ "MII", \
+ "DA" \
+}
+
+
+
+/**
+ * @brief Network interface link state bits
+ *
+ * @see @ref MBG_NET_INTF_LINK_STATE_MASKS
+ *
+ * @note See official Linux kernel documentation
+ * https://www.kernel.org/doc/Documentation/networking/operstates.txt
+ * for states below and explanations. Windows supports this in nearly the same way
+ * using similar names struct IP_ADAPTER_ADDRESSES which is explained at
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx
+ */
+enum MBG_NET_INTF_LINK_STATE_BITS
+{
+ MBG_NET_INTF_LINK_STATE_BIT_UP,
+ MBG_NET_INTF_LINK_STATE_BIT_RUNNING,
+ MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP,
+ MBG_NET_INTF_LINK_STATE_BIT_DORMANT,
+ MBG_NET_INTF_LINK_STATE_BIT_BROADCAST,
+ MBG_NET_INTF_LINK_STATE_BIT_MULTICAST,
+ MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI,
+ MBG_NET_INTF_LINK_STATE_BIT_DEBUG,
+
+ MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK,
+ MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT,
+ MBG_NET_INTF_LINK_STATE_BIT_NO_ARP,
+ MBG_NET_INTF_LINK_STATE_BIT_PROMISC,
+ MBG_NET_INTF_LINK_STATE_BIT_MASTER,
+ MBG_NET_INTF_LINK_STATE_BIT_SLAVE,
+ MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL,
+ MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA,
+
+ MBG_NET_INTF_LINK_STATE_BIT_ECHO,
+ MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC,
+ MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS,
+
+ N_MBG_NET_INTF_LINK_STATE_BITS
+};
+
+
+
+/**
+ * @brief Network interface link state masks
+ *
+ * @see ::MBG_NET_INTF_LINK_STATE_BITS (reclined to Linux' if.h, Windows is similiar)
+ *
+ * @anchor MBG_NET_INTF_LINK_STATE_MASKS @{ */
+
+#define MBG_NET_INTF_LINK_STATE_MASK_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_UP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_UP
+#define MBG_NET_INTF_LINK_STATE_MASK_RUNNING ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_RUNNING ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_RUNNING
+#define MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP
+#define MBG_NET_INTF_LINK_STATE_MASK_DORMANT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DORMANT ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DORMANT
+#define MBG_NET_INTF_LINK_STATE_MASK_BROADCAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_BROADCAST ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_BROADCAST
+#define MBG_NET_INTF_LINK_STATE_MASK_MULTICAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MULTICAST ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_MULTICAST
+#define MBG_NET_INTF_LINK_STATE_MASK_ALL_MULTI ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI
+#define MBG_NET_INTF_LINK_STATE_MASK_DEBUG ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DEBUG ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DEBUG
+
+#define MBG_NET_INTF_LINK_STATE_MASK_LOOPBACK ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK
+#define MBG_NET_INTF_LINK_STATE_MASK_POINT_TO_POINT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT
+#define MBG_NET_INTF_LINK_STATE_MASK_NO_ARP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_ARP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_NO_ARP
+#define MBG_NET_INTF_LINK_STATE_MASK_PROMISC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PROMISC ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_PROMISC
+#define MBG_NET_INTF_LINK_STATE_MASK_MASTER ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MASTER ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_MASTER
+#define MBG_NET_INTF_LINK_STATE_MASK_SLAVE ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_SLAVE ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_SLAVE
+#define MBG_NET_INTF_LINK_STATE_MASK_PORT_SEL ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL
+#define MBG_NET_INTF_LINK_STATE_MASK_AUTO_MEDIA ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA
+
+#define MBG_NET_INTF_LINK_STATE_MASK_ECHO ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ECHO ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_ECHO
+#define MBG_NET_INTF_LINK_STATE_MASK_DYNAMIC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC
+#define MBG_NET_INTF_LINK_STATE_MASK_NO_TRAILERS ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS
+
+/** @} anchor MBG_NET_INTF_LINK_STATE_MASKS */
+
+
+
+/**
+ * @brief Network interface link option bits
+ *
+ * @see ::MBG_NET_INTF_LINK_OPT_MASKS
+ */
+enum MBG_NET_INTF_LINK_OPTS
+{
+ MBG_NET_INTF_LINK_OPT_CAN_SET_MAC,
+ MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN,
+ MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT,
+ MBG_NET_INTF_LINK_OPT_CAN_AUTONEG,
+ MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS,
+ MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS,
+ N_MBG_NET_INTF_LINK_OPTS
+};
+
+
+
+/**
+ * @brief Network interface link option masks
+ *
+ * @see ::MBG_NET_INTF_LINK_OPTS
+ */
+enum MBG_NET_INTF_LINK_OPT_MASKS
+{
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_SET_MAC = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SET_MAC ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SET_MAC
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_IN = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_OUT = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_AUTONEG = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_AUTONEG ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_AUTONEG
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_NTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS
+ MBG_NET_INTF_LINK_OPT_MASK_CAN_PTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS ) ///< see ::MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS
+};
+
+
+
+/**
+ * @brief Network interface link bonding mode
+ *
+ * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_mode
+ *
+ * @note if_bonding.h contains bonding modes under Linux, found no hint under Windows.
+ * BUT: Something similiar (concerning naming) can be configured under Windows
+ * via GUI in device manager, if supported.
+ */
+enum MBG_NET_INTF_LINK_BOND_MODES
+{
+ MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN,
+ MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP,
+ MBG_NET_INTF_LINK_BOND_MODE_XOR,
+ MBG_NET_INTF_LINK_BOND_MODE_BROADCAST,
+ MBG_NET_INTF_LINK_BOND_MODE_8023AD,
+ MBG_NET_INTF_LINK_BOND_MODE_TLB,
+ MBG_NET_INTF_LINK_BOND_MODE_ALB,
+ N_MBG_NET_INTF_LINK_BOND_MODES
+};
+
+
+
+/**
+ * @brief Network interface link bonding mode masks
+ *
+ * @see ::MBG_NET_INTF_LINK_BOND_MODES
+ */
+enum MBG_NET_INTF_LINK_BOND_MODE_MASKS
+{
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_ROUNDROBIN = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_ACTIVEBACKUP = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_XOR = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_XOR ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_XOR
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_BROADCAST = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_BROADCAST ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_BROADCAST
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_8023AD = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_8023AD ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_8023AD
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_TLB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_TLB ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_TLB
+ MBG_NET_INTF_LINK_BOND_MODE_MASK_ALB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ALB ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ALB
+};
+
+
+
+/**
+ * @brief Network interface link bonding mode name strings
+ *
+ * @see ::MBG_NET_INTF_LINK_BOND_MODES
+ */
+#define MBG_NET_INTF_LINK_BOND_MODE_STRS \
+{ \
+ "Round Robin", \
+ "Active Backup", \
+ "XOR", \
+ "Broadcast", \
+ "802.3ad (LACP)", \
+ "TLB", \
+ "ALB" \
+}
+
+
+
+/**
+ * @brief Network interface link bonding states
+ *
+ * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_state
+ */
+enum MBG_NET_INTF_LINK_BOND_STATES
+{
+ MBG_NET_INTF_LINK_BOND_STATE_ACTIVE,
+ MBG_NET_INTF_LINK_BOND_STATE_BACKUP,
+ N_MBG_NET_INTF_LINK_BOND_STATES
+};
+
+
+/**
+ * @brief Network interface link type bits
+ *
+ * Used with ::MBG_NET_INTF_LINK_SETTINGS::type
+ *
+ * @see ::MBG_NET_INTF_LINK_TYPE_MASKS
+ */
+enum MBG_NET_INTF_LINK_TYPES
+{
+ MBG_NET_INTF_LINK_TYPE_PHYS, ///< Real physical network interface
+ MBG_NET_INTF_LINK_TYPE_VLAN, ///< VLAN interface, assigned to physical interface
+ MBG_NET_INTF_LINK_TYPE_BOND, ///< Bonding interface, which acts as bonding master
+ N_MBG_NET_INTF_LINK_TYPE_BITS
+};
+
+
+/**
+ * @brief Network interface link type masks
+ *
+ * Used with ::MBG_NET_INTF_LINK_INFO::supp_types
+ *
+ * @see ::MBG_NET_INTF_LINK_TYPES
+ */
+enum MBG_NET_INTF_LINK_TYPE_MASKS
+{
+ MBG_NET_INTF_LINK_TYPE_MASK_PHYS = ( 1UL << MBG_NET_INTF_LINK_TYPE_PHYS ), ///< see ::MBG_NET_INTF_LINK_TYPE_PHYS
+ MBG_NET_INTF_LINK_TYPE_MASK_VLAN = ( 1UL << MBG_NET_INTF_LINK_TYPE_VLAN ), ///< see ::MBG_NET_INTF_LINK_TYPE_VLAN
+ MBG_NET_INTF_LINK_TYPE_MASK_BOND = ( 1UL << MBG_NET_INTF_LINK_TYPE_BOND ) ///< see ::MBG_NET_INTF_LINK_TYPE_BOND
+};
+
+
+/**
+ * @brief Network interface address bits
+ *
+ * @see ::MBG_NET_INTF_ADDR_MASKS
+ *
+ * Used with ::MBG_NET_INTF_ADDR_INFO::supp_flags and ::MBG_NET_INTF_ADDR_SETTINGS::flags
+ */
+enum MBG_NET_INTF_ADDR_BITS
+{
+ MBG_NET_INTF_ADDR_BIT_DHCP4, ///< Address has been automatically assigned by DHCP via IPv4
+ MBG_NET_INTF_ADDR_BIT_DHCP6, ///< Address has been automatically assigned by DHCP via IPv6
+ N_MBG_NET_INTF_ADDR_FLAGS
+};
+
+
+
+/**
+ * @brief Network interface address masks
+ *
+ * @see ::MBG_NET_INTF_ADDR_BITS
+ */
+enum MBG_NET_INTF_ADDR_MASKS
+{
+ MBG_NET_INTF_ADDR_MASK_DHCP4 = ( 1UL << MBG_NET_INTF_ADDR_BIT_DHCP4 ), ///< see ::MBG_NET_INTF_ADDR_BIT_DHCP4
+ MBG_NET_INTF_ADDR_MASK_DHCP6 = ( 1UL << MBG_NET_INTF_ADDR_BIT_DHCP6 ) ///< see ::MBG_NET_INTF_ADDR_BIT_DHCP6
+};
+
+
+enum MBG_NET_INTF_ROUTE_TYPES
+{
+ MBG_NET_INTF_ROUTE_TYPE_UNKNOWN,
+ MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY,
+ MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY,
+ MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR,
+ N_MBG_NET_INTF_ROUTE_TYPES
+};
+
+/** @} defgroup group_ext_net_cfg_types */
+
+
+
+/**
+ * @defgroup group_ext_net_cfg Extended network configuration and status
+ *
+ * This is only supported if the flag ::GPS_HAS_NET_CFG is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Global network configuration settings
+ */
+typedef struct
+{
+ MBG_HOSTNAME hostname; ///< hostname, eventually FQDN including domain name
+
+ uint8_t num_intf_link; ///< number of detected/configured physical network interfaces (links), see ::MBG_NET_INTF_LINK_INFO_IDX
+ uint8_t num_intf_addr; ///< number of configured interface addresses, see ::MBG_NET_INTF_ADDR_INFO_IDX
+ uint8_t num_dns_srvr; ///< number of configured DNS servers, see ::MBG_IP_ADDR_IDX
+ uint8_t num_dns_srch_dom; ///< number of configured DNS search domains, see ::MBG_NET_NAME_IDX
+ uint8_t num_intf_route; ///< number of configured interface routes, see ::MBG_NET_INTF_ROUTE_INFO_IDX
+
+ uint8_t reserved; ///< currently reserved, always 0
+ uint16_t flags; ///< currently reserved, always 0
+
+} MBG_NET_GLB_CFG_SETTINGS;
+
+#define _mbg_swab_net_glb_cfg_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Global current network settings and supported features
+ */
+typedef struct
+{
+ MBG_NET_GLB_CFG_SETTINGS glb_settings;
+ uint16_t n_supp_intf_link; ///< max. number of supported physical network interfaces (links), see ::MBG_NET_INTF_LINK_SETTINGS_IDX, ::MBG_NET_INTF_LINK_INFO_IDX
+ uint16_t n_supp_intf_addr; ///< max. number of supported interface addresses, see ::MBG_NET_INTF_ADDR_SETTINGS_IDX, ::MBG_NET_INTF_ADDR_INFO_IDX
+ uint16_t n_supp_dns_srvr; ///< max. number of supported DNS server addresses, using ::MBG_IP_ADDR_IDX records
+ uint16_t n_supp_dns_srch_dom; ///< max. number of supported DNS search domain records, using ::MBG_NET_NAME_IDX records
+ uint16_t n_supp_intf_route; ///< max. number of supported interface routes, see ::MBG_NET_INTF_ROUTE_SETTINGS_IDX, ::MBG_NET_INTF_ROUTE_INFO_IDX
+ uint16_t max_hostname_len; ///< max. length of hostname including trailing 0; if set to 0, max. length is 256 (see rfc1123)
+ uint32_t reserved_1; ///< currently reserved, always 0
+ uint32_t reserved_2; ///< currently reserved, always 0
+ uint32_t feat_flags; ///< Feature flags, see ::MBG_NET_GLB_CFG_INFO_MASKS
+ uint32_t flags_2; ///< currently reserved, always 0
+
+} MBG_NET_GLB_CFG_INFO;
+
+#define _mbg_swab_net_glb_cfg_info( _p ) \
+do \
+{ \
+ _mbg_swab_net_glb_cfg_settings( &(_p)->glb_settings ); \
+ _mbg_swab16( &(_p)->n_supp_intf_link ); \
+ _mbg_swab16( &(_p)->n_supp_intf_addr ); \
+ _mbg_swab16( &(_p)->n_supp_dns_srvr ); \
+ _mbg_swab16( &(_p)->n_supp_dns_srch_dom ); \
+ _mbg_swab16( &(_p)->n_supp_intf_route ); \
+ _mbg_swab16( &(_p)->max_hostname_len ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->feat_flags ); \
+ _mbg_swab32( &(_p)->flags_2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief An IPv4 or IPv6 network address
+ */
+typedef struct
+{
+ uint8_t type; ///< see ::MBG_IP_ADDR_TYPES
+ uint8_t reserved_1; ///< reserved, currently always 0 @todo Do we need this as scope indicator?
+ uint16_t reserved_2; ///< reserved, currently always 0
+
+ union u_addr
+ {
+ IP4_ADDR ip4_addr; ///< IPv4 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP4
+ IP6_ADDR ip6_addr; ///< IPv6 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP6
+ } u_addr;
+
+} MBG_IP_ADDR;
+
+#define _mbg_swab_ip_addr( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->type ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ \
+ switch ( (_p)->type ) \
+ { \
+ case MBG_IP_ADDR_TYPE_IP4: \
+ _mbg_swab_ip4_addr( &(_p)->u_addr.ip4_addr ); \
+ break; \
+ \
+ case MBG_IP_ADDR_TYPE_IP6: \
+ _mbg_swab_ip6_addr( &(_p)->u_addr.ip6_addr ); \
+ break; \
+ } \
+ \
+} while ( 0 )
+
+
+
+/**
+ * @brief An IPv4 or IPv6 network address, plus index
+ */
+typedef struct
+{
+ uint16_t idx;
+ MBG_IP_ADDR addr; ///< network address
+
+} MBG_IP_ADDR_IDX;
+
+#define _mbg_swab_ip_addr_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_ip_addr( &(_p)->addr ); \
+} while ( 0 )
+
+
+/**
+ * @brief An IPv4 or IPv6 network address plus UDP or TCP port number
+ */
+typedef struct
+{
+ MBG_IP_ADDR addr; ///< see ::MBG_IP_ADDR
+
+ uint16_t port; ///< UDP or TCP port
+ uint16_t flags; ///< currently always 0
+ //##+++++ TODO should the flags field indicate if the port is UDP and/or TCP?
+
+} MBG_IP_ADDR_PORT;
+
+#define _mbg_swab_ip_addr_port( _p ) \
+do \
+{ \
+ _mbg_swab_ip_addr( &(_p)->addr ); \
+ _mbg_swab16( &(_p)->port ); \
+ _mbg_swab16( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Network host or domain name
+ */
+typedef struct
+{
+ MBG_HOSTNAME name;
+
+} MBG_NET_NAME;
+
+#define _mbg_swab_net_name( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_host_name( &(_p)->name ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Network host or domain name, plus index
+ */
+typedef struct
+{
+ uint16_t idx;
+ MBG_NET_NAME net_name;
+
+} MBG_NET_NAME_IDX;
+
+#define _mbg_swab_net_name_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_name( &(_p)->net_name ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Physical network interface link specific settings
+ */
+typedef struct
+{
+ char name[MBG_IFNAMSIZ]; ///< Interface name
+ MBG_MAC_ADDR mac_addr; ///< Physical hardware address
+ MBG_MAC_ADDR broadcast; ///< Physical broadcast address
+
+ uint32_t if_index; ///< Interface index assigned by the kernel
+ uint32_t common_if_index; ///< Common interface index assigned by the lib (associated with the MAC address),
+ ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_PHYS
+ uint32_t ass_if_index; ///< Interface index of the associated physical interface link,
+ ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN
+
+ uint32_t flags; ///< Reserved, currently 0
+ uint32_t states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS
+
+ uint32_t hw_type; ///< Hardware type of interface (see ::MBG_NET_HW_TYPES)
+ uint32_t mtu; ///< Max. packet size in bytes
+ uint32_t txqlen; ///< Transmission queue length (number of packets)
+ uint32_t speed; ///< Link speed in MBit/s
+
+ uint8_t type; ///< see ::MBG_NET_INTF_LINK_TYPES
+ uint8_t duplex; ///< Duplex mode, half (0) or full (1)
+ uint8_t autoneg; ///< Indicates, whether autonegotiation is enabled or disabled
+ uint8_t port_type; ///< see ::MBG_NET_INTF_LINK_PORT_TYPES
+
+ uint8_t bond_mode; ///< Bonding mode, see ::MBG_NET_INTF_LINK_BOND_MODES
+ ///< Valid if ::MBG_NET_INTF_LINK_STATE_MASK_MASTER is set in ::MBG_NET_INTF_LINK_SETTINGS::states
+ uint8_t bond_state; ///< Status of this interface in the bonding group, see ::MBG_NET_INTF_LINK_BOND_STATES
+ ///< Valid if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states
+ uint16_t bond_idx; ///< Interface index of the bonding master link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index
+ ///< Valid, if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states
+
+ uint16_t vlan_cfg; ///< VLAN configuration options, see ::MBG_VLAN_CFG
+ ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN
+ uint16_t reserved_1; ///< Reserved, currently 0
+
+ uint32_t reserved_2; ///< Reserved, currently 0
+ uint32_t reserved_3; ///< Reserved, currently 0
+
+} MBG_NET_INTF_LINK_SETTINGS;
+
+#define _mbg_swab_net_intf_link_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->if_index ); \
+ _mbg_swab32( &(_p)->common_if_index ); \
+ _mbg_swab32( &(_p)->ass_if_index ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->states ); \
+ _mbg_swab32( &(_p)->hw_type ); \
+ _mbg_swab32( &(_p)->mtu ); \
+ _mbg_swab32( &(_p)->txqlen ); \
+ _mbg_swab32( &(_p)->speed ); \
+ _mbg_swab16( &(_p)->bond_idx ); \
+ _mbg_swab16( &(_p)->vlan_cfg ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Link (physical interface) specific settings, plus index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::n_supp_intf_link-1
+ MBG_NET_INTF_LINK_SETTINGS settings;
+
+} MBG_NET_INTF_LINK_SETTINGS_IDX;
+
+#define _mbg_swab_net_intf_link_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_link_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Link (physical interface) specific settings, flags and supported features
+ */
+typedef struct
+{
+ MBG_NET_INTF_LINK_SETTINGS link_settings; ///< see ::MBG_NET_INTF_LINK_SETTINGS
+ uint32_t supp_flags; ///< Reserved, currently 0
+ uint32_t supp_states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS
+ uint32_t supp_types; ///< see ::MBG_NET_INTF_LINK_TYPE_MASKS
+ uint32_t supp_speed_modes; ///< see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS
+ uint32_t supp_port_types; ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS
+ uint32_t supp_opts; ///< see ::MBG_NET_INTF_LINK_OPT_MASKS
+ uint32_t supp_bond_modes; ///< see ::MBG_NET_INTF_LINK_BOND_MODE_MASKS
+ uint32_t reserved_1;
+ uint32_t reserved_2;
+ uint32_t reserved_3;
+ uint32_t reserved_4;
+} MBG_NET_INTF_LINK_INFO;
+
+#define _mbg_swab_net_intf_link_info( _p ) \
+do \
+{ \
+ _mbg_swab_net_intf_link_settings( &(_p)->link_settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_states ); \
+ _mbg_swab32( &(_p)->supp_types ); \
+ _mbg_swab32( &(_p)->supp_speed_modes ); \
+ _mbg_swab32( &(_p)->supp_port_types ); \
+ _mbg_swab32( &(_p)->supp_opts ); \
+ _mbg_swab32( &(_p)->supp_bond_modes ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Query MBG_NET_INTF_LINK_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_link-1
+ MBG_NET_INTF_LINK_INFO info; ///< see ::MBG_NET_INTF_LINK_INFO
+
+} MBG_NET_INTF_LINK_INFO_IDX;
+
+#define _mbg_swab_net_intf_link_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_link_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief Network interface address specific settings, flags and supported features
+ *
+ * @note Use if_index to identify uniquely its associated network link.
+ */
+typedef struct
+{
+ char label[MBG_IFNAMSIZ]; ///< Interface label
+
+ uint32_t addr_index; ///< Index of the address on the physical interface it is assigned to
+ uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index
+
+ uint32_t flags; ///< see ::MBG_NET_INTF_ADDR_MASKS
+
+ MBG_IP_ADDR ip; ///< IP address associated with this interface
+ MBG_IP_ADDR broadcast; ///< Broadcast address associated with this interface
+
+ uint8_t prefix_bits; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24
+ uint8_t reserved_1; ///< Reserved, currently 0
+ uint16_t reserved_2; ///< Reserved, currently 0
+
+ uint32_t reserved_3; ///< Reserved, currently 0
+ uint32_t reserved_4; ///< Reserved, currently 0
+ uint32_t reserved_5; ///< Reserved, currently 0
+
+} MBG_NET_INTF_ADDR_SETTINGS;
+
+#define _mbg_swab_net_intf_addr_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->addr_index ); \
+ _mbg_swab32( &(_p)->ass_if_index ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab_ip_addr( &(_p)->ip ); \
+ _mbg_swab_ip_addr( &(_p)->broadcast ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->reserved_5 ); \
+} while ( 0 )
+
+
+/**
+ * @brief Query MBG_NET_INTF_ADDR_SETTINGS by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1
+ MBG_NET_INTF_ADDR_SETTINGS settings; ///< see ::MBG_NET_INTF_ADDR_SETTINGS
+
+} MBG_NET_INTF_ADDR_SETTINGS_IDX;
+
+#define _mbg_swab_net_intf_addr_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_addr_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief Network interface address specific settings, flags and supported features
+ */
+typedef struct
+{
+ MBG_NET_INTF_ADDR_SETTINGS addr_settings; ///< see ::MBG_NET_INTF_ADDR_SETTINGS
+ uint32_t supp_flags; ///< see ::MBG_NET_INTF_ADDR_MASKS
+ uint32_t reserved_1; ///< Reserved, currently 0
+ uint32_t reserved_2; ///< Reserved, currently 0
+
+} MBG_NET_INTF_ADDR_INFO;
+
+#define _mbg_swab_net_intf_addr_info( _p ) \
+do \
+{ \
+ _mbg_swab_net_intf_addr_settings( &(_p)->addr_settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+/**
+ * @brief Query MBG_NET_INTF_ADDR_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1
+ MBG_NET_INTF_ADDR_INFO info; ///< see ::MBG_NET_INTF_ADDR_INFO
+
+} MBG_NET_INTF_ADDR_INFO_IDX;
+
+#define _mbg_swab_net_intf_addr_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_addr_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief Network interface route specific settings
+ *
+ * @note Use link_mac and ass_addr_idx to identify the associated network address and network link (via address)
+ */
+typedef struct
+{
+ uint8_t type; ///< Type of the route entry, see ::MBG_NET_INTF_ROUTE_TYPES
+ uint8_t reserved_1; ///< Reserved, currently 0
+ uint16_t reserved_2; ///< Reserved, currently 0
+
+ MBG_IP_ADDR gateway; ///< Gateway IP address, only used if type is
+ ///< ::MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY
+ MBG_IP_ADDR dst; ///< Destination IP address, only used if ::MBG_NET_INTF_ROUTE_SETTINGS::type is
+ ///< ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR
+ uint8_t dst_prefix_bits; ///< Prefix Bits for the destination address
+
+ uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index
+ uint32_t ass_addr_index; ///< Index of the associated interface address, see ::MBG_NET_INTF_ADDR_SETTINGS::addr_index,
+ ///< Valid if ::MBG_NET_INTF_ROUTE_SETTINGS::type is ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR
+
+ uint32_t reserved_3; ///< Reserved, currently 0
+ uint32_t reserved_4; ///< Reserved, currently 0
+ uint32_t reserved_5; ///< Reserved, currently 0
+
+} MBG_NET_INTF_ROUTE_SETTINGS;
+
+#define _mbg_swab_net_intf_route_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab_ip_addr( &(_p)->gateway ); \
+ _mbg_swab_ip_addr( &(_p)->dst ); \
+ _mbg_swab32( &(_p)->ass_if_index ); \
+ _mbg_swab32( &(_p)->ass_addr_index ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->reserved_5 ); \
+} while ( 0 )
+
+
+/**
+ * @brief Query MBG_NET_INTF_ROUTE_SETTINGS by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1
+ MBG_NET_INTF_ROUTE_SETTINGS settings; ///< see ::MBG_NET_INTF_ROUTE_SETTINGS
+
+} MBG_NET_INTF_ROUTE_SETTINGS_IDX;
+
+#define _mbg_swab_net_intf_route_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_route_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief Network interface address specific settings
+ */
+typedef struct
+{
+ MBG_NET_INTF_ROUTE_SETTINGS route_settings; ///< see ::MBG_NET_INTF_ROUTE_SETTINGS
+ uint32_t reserved_1; ///< Reserved, currently 0
+ uint32_t reserved_2; ///< Reserved, currently 0
+ uint32_t reserved_3; ///< Reserved, currently 0
+ uint32_t reserved_4; ///< Reserved, currently 0
+} MBG_NET_INTF_ROUTE_INFO;
+
+#define _mbg_swab_net_intf_route_info( _p ) \
+do \
+{ \
+ _mbg_swab_net_intf_route_settings( &(_p)->route_settings ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+} while ( 0 )
+
+
+/**
+ * @brief Query MBG_NET_INTF_ROUTE_INFO by its index
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1
+ MBG_NET_INTF_ROUTE_INFO info; ///< see ::MBG_NET_INTF_ROUTE_INFO
+
+} MBG_NET_INTF_ROUTE_INFO_IDX;
+
+#define _mbg_swab_net_intf_route_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_net_intf_route_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/** @} defgroup group_ext_net_cfg */
+
+/** @} defgroup group_net_cfg */
+
+
+
+
+
+/**
+ * @defgroup group_ucap_net User Captures via Network
+ *
+ * @note Group for the user capture via network feature
+ * Only supported if ::MBG_XFEATURE_UCAP_NET is set in extended features
+ * Corresponding GPS commands are ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX
+ *
+ * @{ */
+
+
+#define MBG_UCAP_NET_DEFAULT_UDP_PORT 50815
+
+/**
+ * @brief Transfer mode for user captures via network
+ *
+ * @see ::MBG_UCAP_NET_TRANSF_MODE_MASKS
+ *
+ * Used with ::MBG_UCAP_NET_RECV_SETTINGS::mode
+ */
+enum MBG_UCAP_NET_TRANSF_MODE
+{
+ MBG_UCAP_NET_TRANSF_MODE_UNKNOWN, ///< Unknown transfer mode
+ MBG_UCAP_NET_TRANSF_MODE_ON_REQ, ///< User captures will be transferred on request only
+ MBG_UCAP_NET_TRANSF_MODE_AUTO, ///< User captures are being transferred automatically
+ N_MBG_UCAP_NET_TRANSF_MODES
+};
+
+
+/**
+ * @brief Masks for transfer mode used with ::MBG_UCAP_NET_GLB_INFO::supp_modes
+ *
+ * @see ::MBG_UCAP_NET_TRANSF_MODE
+ */
+enum MBG_UCAP_NET_TRANSF_MODE_MASKS
+{
+ MBG_UCAP_NET_TRANSF_MODE_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_UNKNOWN ), ///< see ::MBG_UCAP_NET_TRANSF_MODE_UNKNOWN
+ MBG_UCAP_NET_TRANSF_MODE_MASK_ON_REQ = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_ON_REQ ), ///< see ::MBG_UCAP_NET_TRANSF_MODE_ON_REQ
+ MBG_UCAP_NET_TRANSF_MODE_MASK_AUTO = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_AUTO ) ///< see ::MBG_UCAP_NET_TRANSF_MODE_AUTO
+};
+
+
+
+/**
+ * @brief Transfer protocol for user captures via network
+ *
+ * @see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS
+ *
+ * Used with ::MBG_UCAP_NET_RECV_SETTINGS::proto
+ */
+enum MBG_UCAP_NET_TRANSF_PROTO
+{
+ MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN, ///< Unknown transfer mode
+ MBG_UCAP_NET_TRANSF_PROTO_UDP, ///< User captures are transferred via UDP
+ N_MBG_UCAP_NET_TRANSF_PROTOS
+};
+
+
+/**
+ * @brief Masks for transfer protocol used with ::MBG_UCAP_NET_GLB_INFO::supp_protos
+ *
+ * @see ::MBG_UCAP_NET_TRANSF_PROTO
+ */
+enum MBG_UCAP_NET_TRANSF_PROTO_MASKS
+{
+ MBG_UCAP_NET_TRANSF_PROTO_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN ), ///< see ::MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN
+ MBG_UCAP_NET_TRANSF_PROTO_MASK_UDP = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UDP ) ///< see ::MBG_UCAP_NET_TRANSF_PROTO_UDP
+};
+
+
+
+/**
+ * @brief Supported flags for user captures via network
+ *
+ * @see ::MBG_UCAP_NET_SUPP_FLAG_MASKS
+ */
+enum MBG_UCAP_NET_SUPP_FLAGS
+{
+ MBG_UCAP_NET_SUPP_FLAG_IPV6,
+ N_MBG_UCAP_NET_SUPP_FLAGS
+};
+
+
+/**
+ * @brief Masks for supported flags used with ::MBG_UCAP_NET_GLB_INFO::supp_flags
+ *
+ * @see ::MBG_UCAP_NET_TRANSF_PROTO
+ */
+enum MBG_UCAP_NET_SUPP_FLAG_MASKS
{
- IP4_BIT_DHCP, //< DHCP supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
- IP4_BIT_LINK, //< used only in IP4_SETTINGS to report link state
- IP4_BIT_VLAN, //< VLAN supported (LAN_IF_INFO) / enabled (IP4_SETTINGS)
- N_IP4_BIT //< number of defined flag bits
+ MBG_UCAP_NET_SUPP_FLAG_MASK_IPV6 = ( 1UL << MBG_UCAP_NET_SUPP_FLAG_IPV6 ) ///< see ::MBG_UCAP_NET_SUPP_FLAG_IPV6
};
-#define IP4_MSK_DHCP ( 1UL << IP4_BIT_DHCP )
-#define IP4_MSK_LINK ( 1UL << IP4_BIT_LINK )
-#define IP4_MSK_VLAN ( 1UL << IP4_BIT_VLAN )
-/** @} group_ip4_cfg */
+/**
+ * @brief Global settings for user captures via network
+ *
+ * @note This structure shall be used to set the current global settings of a device
+ * with GPS command ::GPS_UCAP_NET_GLB_INFO.
+ */
+typedef struct
+{
+ uint32_t num_recvs; ///< Number of configured network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX
+ uint32_t reserved_0; ///< Reserved, currently always 0
+ uint32_t reserved_1; ///< Reserved, currently always 0
+ uint32_t reserved_2; ///< Reserved, currently always 0
+
+} MBG_UCAP_NET_GLB_SETTINGS;
+
+
+#define _mbg_swab_ucap_net_glb_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->num_recvs ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Global settings, features and flags for user captures via network
+ *
+ * @note This structure shall be used to read the current global settings from a device
+ * with GPS command ::GPS_UCAP_NET_GLB_INFO.
+ */
+typedef struct
+{
+ MBG_UCAP_NET_GLB_SETTINGS settings; ///< see ::MBG_UCAP_NET_GLB_SETTINGS
+
+ uint32_t n_supp_recvs; ///< Number of supported network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX
+ uint32_t supp_modes; ///< Supported transfer modes, see ::MBG_UCAP_NET_TRANSF_MODE_MASKS
+ uint32_t supp_protos; ///< Supported transfer protocols, see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS
+ uint32_t reserved_0; ///< Reserved, currently always 0
+ uint32_t reserved_1; ///< Reserved, currently always 0
+ uint32_t supp_flags; ///< Supported flags, see ::MBG_UCAP_NET_SUPP_FLAG_MASKS
+
+} MBG_UCAP_NET_GLB_INFO;
+
+
+#define _mbg_swab_ucap_net_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab_ucap_net_glb_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->n_supp_recvs ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab32( &(_p)->supp_protos ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Settings for receivers of user captures via network
+ */
+typedef struct
+{
+ uint8_t mode; ///< Transfer mode, see ::MBG_UCAP_NET_TRANSF_MODE
+ uint8_t proto; ///< Transfer protocol, see ::MBG_UCAP_NET_TRANSF_PROTO
+ uint16_t reserved_1; ///< Reserved, currently always 0
+
+ uint32_t reserved_2; ///< Reserved, currently always 0
+ uint32_t reserved_3; ///< Reserved, currently always 0
+ uint32_t ucaps; ///< Bit mask for active user captures
+
+ MBG_IP_ADDR_PORT addr; ///< Destination IP and port address of the network receiver, see ::MBG_IP_ADDR_PORT
+
+} MBG_UCAP_NET_RECV_SETTINGS;
+
+
+#define _mbg_swab_ucap_net_recv_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->ucaps ); \
+ _mbg_swab_ip_addr_port( &(_p)->addr ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Settings for receivers of user captures via network
+ *
+ * @note This structure shall be used to write the settings to the device
+ * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX.
+ * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1.
+ *
+ * @see ::MBG_UCAP_NET_RECV_SETTINGS
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1
+ MBG_UCAP_NET_RECV_SETTINGS settings; ///< see ::MBG_UCAP_NET_RECV_SETTINGS
+
+} MBG_UCAP_NET_RECV_SETTINGS_IDX;
+
+
+#define _mbg_swab_ucap_net_recv_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Settings, features and flags for receivers of user captures via network
+ */
+typedef struct
+{
+ MBG_UCAP_NET_RECV_SETTINGS settings; ///< see ::MBG_UCAP_NET_RECV_SETTINGS
+
+ uint32_t reserved_0; ///< Reserved, currently always 0
+ uint32_t reserved_1; ///< Reserved, currently always 0
+ uint32_t reserved_2; ///< Reserved, currently always 0
+ uint32_t reserved_3; ///< Reserved, currently always 0
+
+} MBG_UCAP_NET_RECV_INFO;
+
+
+#define _mbg_swab_ucap_net_recv_info( _p ) \
+do \
+{ \
+ _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Settings, features and flags for receivers of user captures via network
+ *
+ * @note This structure shall be used to read the current settings from the device
+ * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX.
+ * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1.
+ *
+ * @see ::MBG_UCAP_NET_RECV_INFO
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_UCAP_NET_GLB_INFO::n_supp_recvs-1
+ MBG_UCAP_NET_RECV_INFO info; ///< see ::MBG_UCAP_NET_RECV_INFO
+
+} MBG_UCAP_NET_RECV_INFO_IDX;
+
+
+#define _mbg_swab_ucap_net_recv_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_ucap_net_recv_info( &(_p)->info ); \
+} while ( 0 )
+
+/** @} defgroup ext_ucap */
@@ -4174,33 +12401,44 @@ enum
/**
* @brief Enumeration of protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROT_MASKS
*/
-enum
+enum PTP_NW_PROTS
{
- PTP_NW_PROT_BIT_RESERVED, //< reserved
- PTP_NW_PROT_BIT_UDP_IPV4, //< IPv4
- PTP_NW_PROT_BIT_UDP_IPV6, //< IPv6
- PTP_NW_PROT_BIT_IEEE_802_3, //< Ethernet (raw layer 2)
- PTP_NW_PROT_BIT_DEVICE_NET, //< DeviceNet
- PTP_NW_PROT_BIT_CONTROL_NET, //< ControlNet
- PTP_NW_PROT_BIT_PROFINET, //< ProfiNet
- N_PTP_NW_PROT //< number of defined protocols
-};
-
-#define PTP_NW_PROT_MSK_RESERVED ( 1UL << PTP_NW_PROT_BIT_RESERVED )
-#define PTP_NW_PROT_MSK_UDP_IPV4 ( 1UL << PTP_NW_PROT_BIT_UDP_IPV4 )
-#define PTP_NW_PROT_MSK_UDP_IPV6 ( 1UL << PTP_NW_PROT_BIT_UDP_IPV6 )
-#define PTP_NW_PROT_MSK_IEEE_802_3 ( 1UL << PTP_NW_PROT_BIT_IEEE_802_3 )
-#define PTP_NW_PROT_MSK_DEVICE_NET ( 1UL << PTP_NW_PROT_BIT_DEVICE_NET )
-#define PTP_NW_PROT_MSK_CONTROL_NET ( 1UL << PTP_NW_PROT_BIT_CONTROL_NET )
-#define PTP_NW_PROT_MSK_PROFINET ( 1UL << PTP_NW_PROT_BIT_PROFINET )
-
-#if !defined( DEFAULT_PTP_NW_PROT_MASK )
- #define DEFAULT_PTP_NW_PROT_MASK ( PTP_NW_PROT_MSK_UDP_IPV4 | PTP_NW_PROT_MSK_IEEE_802_3 )
-#endif
+ PTP_NW_PROT_RESERVED, ///< reserved
+ PTP_NW_PROT_UDP_IPV4, ///< IPv4
+ PTP_NW_PROT_UDP_IPV6, ///< IPv6
+ PTP_NW_PROT_IEEE_802_3, ///< Ethernet (raw layer 2)
+ PTP_NW_PROT_DEVICE_NET, ///< DeviceNet
+ PTP_NW_PROT_CONTROL_NET, ///< ControlNet
+ PTP_NW_PROT_PROFINET, ///< ProfiNet
+ N_PTP_NW_PROT ///< number of defined protocols
+};
+
+
+/**
+ * @brief Bit masks for enumerated protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
+ */
+enum PTP_NW_PROT_MASKS
+{
+ PTP_NW_PROT_MSK_RESERVED = ( 1UL << PTP_NW_PROT_RESERVED ), ///< see ::PTP_NW_PROT_RESERVED
+ PTP_NW_PROT_MSK_UDP_IPV4 = ( 1UL << PTP_NW_PROT_UDP_IPV4 ), ///< see ::PTP_NW_PROT_UDP_IPV4
+ PTP_NW_PROT_MSK_UDP_IPV6 = ( 1UL << PTP_NW_PROT_UDP_IPV6 ), ///< see ::PTP_NW_PROT_UDP_IPV6
+ PTP_NW_PROT_MSK_IEEE_802_3 = ( 1UL << PTP_NW_PROT_IEEE_802_3 ), ///< see ::PTP_NW_PROT_IEEE_802_3
+ PTP_NW_PROT_MSK_DEVICE_NET = ( 1UL << PTP_NW_PROT_DEVICE_NET ), ///< see ::PTP_NW_PROT_DEVICE_NET
+ PTP_NW_PROT_MSK_CONTROL_NET = ( 1UL << PTP_NW_PROT_CONTROL_NET ), ///< see ::PTP_NW_PROT_CONTROL_NET
+ PTP_NW_PROT_MSK_PROFINET = ( 1UL << PTP_NW_PROT_PROFINET ) ///< see ::PTP_NW_PROT_PROFINET
+};
+
+
/**
* @brief Name strings for the protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
*/
#define PTP_NW_PROT_STRS \
{ \
@@ -4216,10 +12454,12 @@ enum
/**
* @brief Short name strings for the protocols possibly used with PTP
+ *
+ * @see ::PTP_NW_PROTS
*/
#define PTP_NW_PROT_STRS_SHORT \
{ \
- "RES", \
+ "RSV", \
"IP4", \
"IP6", \
"ETH", \
@@ -4232,19 +12472,19 @@ enum
/**
* @brief Possible states of a PTP port
*/
-enum
+enum PTP_PORT_STATES
{
- PTP_PORT_STATE_UNINITIALIZED, //< uninitialized
- PTP_PORT_STATE_INITIALIZING, //< currently initializing
- PTP_PORT_STATE_FAULTY, //< faulty
- PTP_PORT_STATE_DISABLED, //< disabled
- PTP_PORT_STATE_LISTENING, //< listening for PTP packets
- PTP_PORT_STATE_PRE_MASTER, //< going to become master
- PTP_PORT_STATE_MASTER, //< master
- PTP_PORT_STATE_PASSIVE, //< passive
- PTP_PORT_STATE_UNCALIBRATED, //< uncalibrated
- PTP_PORT_STATE_SLAVE, //< slave
- N_PTP_PORT_STATE //< number of defined port states
+ PTP_PORT_STATE_UNINITIALIZED, ///< uninitialized
+ PTP_PORT_STATE_INITIALIZING, ///< currently initializing
+ PTP_PORT_STATE_FAULTY, ///< faulty
+ PTP_PORT_STATE_DISABLED, ///< disabled
+ PTP_PORT_STATE_LISTENING, ///< listening for PTP packets
+ PTP_PORT_STATE_PRE_MASTER, ///< going to become master
+ PTP_PORT_STATE_MASTER, ///< master
+ PTP_PORT_STATE_PASSIVE, ///< passive
+ PTP_PORT_STATE_UNCALIBRATED, ///< uncalibrated
+ PTP_PORT_STATE_SLAVE, ///< slave
+ N_PTP_PORT_STATE ///< number of defined port states
};
@@ -4271,53 +12511,70 @@ enum
*/
typedef struct
{
- uint8_t value; //< the parameter value
- const char *name; //< the parameter name
+ uint8_t value; ///< the parameter value
+ const char *name; ///< the parameter name
+
} PTP_TABLE;
+
/**
* @brief An enumeration of PTP delay mechanisms
*
* @note This is different than the numeric values specified
* in the published specs for IEEE1588. In addition, the specs
- * define 0x14 for "disabled".
+ * define code 0x14 for "disabled".
+ *
+ * @see ::PTP_DELAY_MECH_MASKS
+ * @see ::PTP_DELAY_MECH_NAMES
*/
-enum
+enum PTP_DELAY_MECHS
{
- PTP_DELAY_MECH_BIT_E2E, //< End-to-End (in PTP2 specs: 0x01)
- PTP_DELAY_MECH_BIT_P2P, //< Peer-to-Peer (in PTP2 specs: 0x02)
- N_PTP_DELAY_MECH //< number of defined delay mechanisms
+ PTP_DELAY_MECH_E2E, ///< End-to-End (in PTP2 specs: 0x01)
+ PTP_DELAY_MECH_P2P, ///< Peer-to-Peer (in PTP2 specs: 0x02)
+ N_PTP_DELAY_MECH ///< number of defined delay mechanisms
};
-#define PTP_DELAY_MECH_MSK_E2E ( 1UL << PTP_DELAY_MECH_BIT_E2E )
-#define PTP_DELAY_MECH_MSK_P2P ( 1UL << PTP_DELAY_MECH_BIT_P2P )
-#if !defined( DEFAULT_PTP_DELAY_MECH_MASK )
- #define DEFAULT_PTP_DELAY_MECH_MASK ( PTP_DELAY_MECH_MSK_E2E | PTP_DELAY_MECH_MSK_P2P )
-#endif
+/**
+ * @brief Bit masks associated with enumerated PTP delay mechanisms
+ *
+ * @see ::PTP_DELAY_MECH_MASKS
+ */
+enum PTP_DELAY_MECH_MASKS
+{
+ PTP_DELAY_MECH_MSK_E2E = ( 1UL << PTP_DELAY_MECH_E2E ), ///< see ::PTP_DELAY_MECH_E2E
+ PTP_DELAY_MECH_MSK_P2P = ( 1UL << PTP_DELAY_MECH_P2P ) ///< see ::PTP_DELAY_MECH_P2P
+};
+
+
+#define PTP_DELAY_MECH_NAME_E2E "E2E"
+#define PTP_DELAY_MECH_NAME_P2P "P2P"
/**
* @brief Name strings for the PTP delay mechanisms
+ *
+ * @see ::PTP_DELAY_MECHS
*/
#define PTP_DELAY_MECH_NAMES \
{ \
- "E2E", \
- "P2P" \
+ PTP_DELAY_MECH_NAME_E2E, \
+ PTP_DELAY_MECH_NAME_P2P \
}
-#define PTP_CLOCK_ACCURACY_NUM_BIAS 0x20
-
/**
* @brief An enumeration of accuracy classes used with PTP
*
* @note This enumeration does not start at 0 but with a bias
- * specified by PTP_CLOCK_ACCURACY_NUM_BIAS.
+ * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS.
+ *
+ * @see ::PTP_CLOCK_ACCURACY_STRS
*/
-enum
+enum PTP_CLOCK_ACCURACIES
{
+ PTP_CLOCK_ACCURACY_NUM_BIAS = 0x20,
PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_NUM_BIAS,
PTP_CLOCK_ACCURACY_100ns,
PTP_CLOCK_ACCURACY_250ns,
@@ -4341,6 +12598,8 @@ enum
PTP_CLOCK_ACCURACY_RESERVED_3,
PTP_CLOCK_ACCURACY_RESERVED_4,
N_PTP_CLOCK_ACCURACY
+ //##++++ TODO: Add a code for 0xFE (unknown), or eventually
+ // redesign the lookup of associated strings completely.
};
@@ -4348,8 +12607,10 @@ enum
* @brief Name strings for PTP accuracy classes
*
* @note The enumeration does not start at 0 but with a bias
- * specified by PTP_CLOCK_ACCURACY_NUM_BIAS, so this bias needs
+ * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS, so this bias needs
* to be accounted for when accessing a string table.
+ *
+ * @see ::PTP_CLOCK_ACCURACIES
*/
#define PTP_CLOCK_ACCURACY_STRS \
{ \
@@ -4381,20 +12642,27 @@ enum
/**
* @brief Codes to specify the type of a time source used with PTP
+ *
+ * @see ::PTP_TIME_SOURCE_TABLE
*/
-#define PTP_TIME_SOURCE_ATOMIC_CLOCK 0x10
-#define PTP_TIME_SOURCE_GPS 0x20
-#define PTP_TIME_SOURCE_TERRESTRIAL_RADIO 0x30
-#define PTP_TIME_SOURCE_PTP 0x40
-#define PTP_TIME_SOURCE_NTP 0x50
-#define PTP_TIME_SOURCE_HAND_SET 0x60
-#define PTP_TIME_SOURCE_OTHER 0x90
-#define PTP_TIME_SOURCE_INTERNAL_OSCILLATOR 0xA0
+enum PTP_TIME_SOURCES
+{
+ PTP_TIME_SOURCE_ATOMIC_CLOCK = 0x10,
+ PTP_TIME_SOURCE_GPS = 0x20,
+ PTP_TIME_SOURCE_TERRESTRIAL_RADIO = 0x30,
+ PTP_TIME_SOURCE_PTP = 0x40,
+ PTP_TIME_SOURCE_NTP = 0x50,
+ PTP_TIME_SOURCE_HAND_SET = 0x60,
+ PTP_TIME_SOURCE_OTHER = 0x90,
+ PTP_TIME_SOURCE_INTERNAL_OSCILLATOR = 0xA0
+};
/**
* @brief A table of PTP time source codes plus associated name strings
+ *
+ * @see ::PTP_TIME_SOURCES
*/
#define PTP_TIME_SOURCE_TABLE \
{ \
@@ -4413,41 +12681,116 @@ enum
/**
* @brief An enumeration of roles which can be taken by a PTP node
*
- * @note A role in this context specifies a certain mode of operation.
+ * A role in this context specifies a certain mode of operation.
+ * Depending on its specification a devices may not be able to take
+ * each of the specified roles.
+ *
+ * @note: A device in MULTICAST_AUTO role can be either master or slave,
+ * so the port state needs to be checked to determine the current
+ * mode of operation.
+ *
+ * @see ::PTP_ROLE_MASKS
+ * @see ::PTP_ROLE_STRS
+ * @see ::PTP_ROLE_STRS_SHORT
+ */
+enum PTP_ROLES
+{
+ PTP_ROLE_MULTICAST_SLAVE, ///< slave in multicast mode
+ PTP_ROLE_UNICAST_SLAVE, ///< slave in unicast mode
+ PTP_ROLE_MULTICAST_MASTER, ///< multicast master
+ PTP_ROLE_UNICAST_MASTER, ///< unicast master
+ PTP_ROLE_MULTICAST_AUTO, ///< multicast master or slave (auto selection)
+ PTP_ROLE_BOTH_MASTER, ///< simultanous multicast and unicast master
+ PTP_ROLE_NTP_SERVER, ///< NTP Unicast Server
+ PTP_ROLE_NTP_CLIENT, ///< NTP Unicast Client
+ PTP_ROLE_TIME_MONITOR, ///< Time Monitor for external PTP or NTP devices
+ PTP_ROLE_V1_MASTER, ///< PTPv1 Master in Multicast mode
+ PTP_ROLE_V1_SLAVE, ///< PTPv1 Slave in Multicast mode
+ N_PTP_ROLES ///< number of defined roles
+};
+
+
+/**
+ * @brief Bit mask associated with ::PTP_ROLES
+ *
+ * A role in this context specifies a certain mode of operation.
* Depending on its specification a devices may not be able to take
* each of the specified roles.
+ *
+ * @note: A device in MULTICAST_AUTO role can be either master or slave,
+ * so the port state needs to be checked to determine the current
+ * mode of operation.
+ *
+ * @see ::PTP_ROLES
+ * @see ::get_supp_ptp_role_mask
*/
-enum
+enum PTP_ROLE_MASKS
{
- PTP_ROLE_MULTICAST_SLAVE, //< slave in multicast mode
- PTP_ROLE_UNICAST_SLAVE, //< slave in unicast mode
- PTP_ROLE_MULTICAST_MASTER, //< multicast master
- PTP_ROLE_UNICAST_MASTER, //< unicast master
- N_PTP_ROLES //< number of defined roles
+ PTP_ROLE_MSK_MULTICAST_SLAVE = ( 1UL << PTP_ROLE_MULTICAST_SLAVE ), ///< see ::PTP_ROLE_MULTICAST_SLAVE
+ PTP_ROLE_MSK_UNICAST_SLAVE = ( 1UL << PTP_ROLE_UNICAST_SLAVE ), ///< see ::PTP_ROLE_UNICAST_SLAVE
+ PTP_ROLE_MSK_MULTICAST_MASTER = ( 1UL << PTP_ROLE_MULTICAST_MASTER ), ///< see ::PTP_ROLE_MULTICAST_MASTER
+ PTP_ROLE_MSK_UNICAST_MASTER = ( 1UL << PTP_ROLE_UNICAST_MASTER ), ///< see ::PTP_ROLE_UNICAST_MASTER
+ PTP_ROLE_MSK_MULTICAST_AUTO = ( 1UL << PTP_ROLE_MULTICAST_AUTO ), ///< see ::PTP_ROLE_MULTICAST_AUTO
+ PTP_ROLE_MSK_BOTH_MASTER = ( 1UL << PTP_ROLE_BOTH_MASTER ), ///< see ::PTP_ROLE_BOTH_MASTER
+ PTP_ROLE_MSK_NTP_SERVER = ( 1UL << PTP_ROLE_NTP_SERVER ), ///< see ::PTP_ROLE_NTP_SERVER
+ PTP_ROLE_MSK_NTP_CLIENT = ( 1UL << PTP_ROLE_NTP_CLIENT ), ///< see ::PTP_ROLE_NTP_CLIENT
+ PTP_ROLE_MSK_TIME_MONITOR = ( 1UL << PTP_ROLE_TIME_MONITOR ), ///< see ::PTP_ROLE_TIME_MONITOR
+ PTP_ROLE_MSK_V1_MASTER = ( 1UL << PTP_ROLE_V1_MASTER ), ///< see ::PTP_ROLE_MULTICAST_MASTER
+ PTP_ROLE_MSK_V1_SLAVE = ( 1UL << PTP_ROLE_V1_SLAVE ) ///< see ::PTP_ROLE_UNICAST_SLAVE
};
+#define PTP_ROLE_MSK_SLAVES ( PTP_ROLE_MSK_MULTICAST_SLAVE \
+ | PTP_ROLE_MSK_UNICAST_SLAVE \
+ | PTP_ROLE_MSK_MULTICAST_AUTO )
+
+#define PTP_ROLE_MSK_MASTERS ( PTP_ROLE_MSK_MULTICAST_MASTER \
+ | PTP_ROLE_MSK_UNICAST_MASTER \
+ | PTP_ROLE_MSK_MULTICAST_AUTO \
+ | PTP_ROLE_BOTH_MASTER )
+
+
/**
* @brief Name strings for defined PTP roles
+ *
+ * @see ::PTP_ROLES
+ * @see ::PTP_ROLE_STRS_SHORT
*/
#define PTP_ROLE_STRS \
{ \
"Multicast Slave", \
"Unicast Slave", \
"Multicast Master", \
- "Unicast Master" \
+ "Unicast Master", \
+ "Multicast (Auto)", \
+ "UC+MC Master", \
+ "NTP Server", \
+ "NTP Client", \
+ "Time Monitor", \
+ "V1 Master", \
+ "V1 Slave" \
}
/**
* @brief Short name strings for defined PTP roles
+ *
+ * @see ::PTP_ROLES
+ * @see ::PTP_ROLE_STRS
*/
#define PTP_ROLE_STRS_SHORT \
{ \
"MCS", \
"UCS", \
"MCM", \
- "UCM" \
+ "UCM", \
+ "MCA", \
+ "UMM", \
+ "NSV", \
+ "NCL", \
+ "MON", \
+ "V1M", \
+ "V1S" \
}
@@ -4460,6 +12803,7 @@ enum
typedef struct
{
uint8_t b[8];
+
} PTP_CLOCK_ID;
#define _mbg_swab_ptp_clock_id( _p ) _nop_macro_fnc() // nothing to swap
@@ -4469,9 +12813,6 @@ typedef struct
/**
* @brief A PTP port ID
- *
- * @note This usually consists of a 6 byte MAC address with
- * 2 fixed bytes inserted, or all ones as wildcard.
*/
typedef uint16_t PTP_PORT_ID;
@@ -4481,16 +12822,84 @@ typedef uint16_t PTP_PORT_ID;
/**
+ * @brief A PTP port identity
+ *
+ * @note For further information, see IEEE 1588-2008, chapter 5.3.5
+ *
+ * @see ::PTP_CLOCK_ID
+ * @see ::PTP_PORT_ID
+ */
+typedef struct
+{
+ PTP_CLOCK_ID clock_identity;
+ PTP_PORT_ID port_number;
+
+} PTP_PORT_IDENTITY;
+
+
+#define _mbg_swab_ptp_port_identity( _p ) \
+{ \
+ _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \
+ _mbg_swab_ptp_port_id( &(_p)->port_number ); \
+}
+
+
+/**
+ * @brief PTP clock quality
+ *
+ * @note For further information, see IEEE 1588-2008, chapter 5.3.7
+ */
+typedef struct
+{
+ uint8_t clock_class; ///< PTP clock class representing the current sync status
+ int8_t clock_accuracy; ///< see ::PTP_CLOCK_ACCURACIES
+ uint16_t log_variance; ///< PTP offset scaled log variance representing the time stability
+
+} PTP_CLOCK_QUALITY;
+
+
+#define _mbg_swab_ptp_clock_quality( _p ) \
+{ \
+ _mbg_swab8( &(_p)->clock_class ); \
+ _mbg_swab8( &(_p)->clock_accuracy ); \
+ _mbg_swab16( &(_p)->log_variance ); \
+}
+
+
+/**
+ * @brief PTP time interval
+ *
+ * @note For further information, see IEEE 1588-2008, chapter 5.3.2
+ *
+ */
+typedef struct
+{
+ int64_t scaled_nanoseconds;
+
+} PTP_TIME_INTERVAL;
+
+
+#define _mbg_swab_ptp_time_interval( _p ) \
+{ \
+ _mbg_swab64( &(_p)->scaled_nanoseconds ); \
+}
+
+
+/**
* @brief An enumeration of time scales used with PTP
*
* @note The standard time scale used by PTP is TAI, which is a linear time scale.
- * The protocol provides a UTC offset to be able to convert TAI to compute UTC, which
- * can observe leap seconds. For the arbitrary time scale the UTC offset is unspecified.
+ * The protocol provides a %UTC offset to be able to convert TAI to compute %UTC, which
+ * can observe leap seconds. For the arbitrary time scale the %UTC offset is unspecified,
+ * so arbitrary time can be %UTC, or something else.
+ *
+ * @see ::PTP_TIMESCALE_NAMES
+ * @see ::PTP_TIMESCALE_NAMES_SHORT
*/
-enum
+enum PTP_TIME_SCALES
{
- PTP_TIMESCALE_PTP, /* default */
- PTP_TIMESCALE_ARB,
+ PTP_TIMESCALE_PTP, ///< PTP default, TAI
+ PTP_TIMESCALE_ARB, ///< arbitrary time scale, maybe %UTC
N_PTP_TIMESCALE
};
@@ -4510,6 +12919,9 @@ enum
/**
* @brief A table of name strings for the PTP time scales
+ *
+ * @see ::PTP_TIME_SCALES
+ * @see ::PTP_TIMESCALE_NAMES_SHORT
*/
#define PTP_TIMESCALE_NAMES \
{ \
@@ -4519,6 +12931,9 @@ enum
/**
* @brief A table of short name strings for the PTP time scales
+ *
+ * @see ::PTP_TIME_SCALES
+ * @see ::PTP_TIMESCALE_NAMES
*/
#define PTP_TIMESCALE_NAMES_SHORT \
{ \
@@ -4533,38 +12948,41 @@ enum
*/
typedef struct
{
- //##++++ Do we need a port identifier ??
- uint16_t nw_prot; /**< one of the enumerated protocols (@see N_PTP_NW_PROT) */
- uint8_t ptp_prot_version; /**< PTP protocol version, 1, or 2, usually 2 for v2 */
- uint8_t port_state; /**< one of the enumerated port states (@see N_PTP_PORT_STATE ) */
- uint32_t flags; /**< bit masks as defined below */
- NANO_TIME offset; /**< estimated time offset from the upstream time source */
+ uint16_t nw_prot; ///< one of the enumerated protocols, see ::PTP_NW_PROTS
+ uint8_t ptp_prot_version; ///< PTP protocol version, 1, or 2, usually 2 for v2
+ uint8_t port_state; ///< one of the enumerated port states, see ::PTP_PORT_STATES
+ uint32_t flags; ///< see ::PTP_STATE_FLAGS
+ NANO_TIME offset; ///< estimated time offset from the upstream time source
NANO_TIME path_delay;
NANO_TIME mean_path_delay;
NANO_TIME delay_asymmetry;
- PTP_CLOCK_ID gm_id; /**< identifier ot the upstream time source */
+ PTP_CLOCK_ID gm_id; ///< identifier ot the upstream time source
uint16_t clock_offset_scaled_log_variance;
uint8_t clock_class;
- uint8_t clock_accuracy; /**< one of the enumerated accuracy class codes (@see N_PTP_CLOCK_ACCURACY) */
+ uint8_t clock_accuracy; ///< see ::PTP_CLOCK_ACCURACIES
- uint32_t reserved_1; /**< reserved, currently always 0 */
- uint32_t reserved_2; /**< reserved, currently always 0 */
+ uint32_t tsu_secs; ///< current seconds value of time stamp unit
+ uint32_t reserved_2; ///< reserved, currently always 0
- uint8_t domain_number; /**< the PTP clock domain number, 0:3 */
- uint8_t time_source; /**< one of the defined codes PTP_TIME_SOURCE_... */
- uint8_t delay_mech; /**< PTP_DELAY_MECH_BIT_E2E or PTP_DELAY_MECH_BIT_P2P */
+ uint8_t domain_number; ///< the PTP clock domain number, 0:3
+ uint8_t time_source; ///< see ::PTP_TIME_SOURCES
+ uint8_t delay_mech; ///< see ::PTP_DELAY_MECHS
int8_t log_delay_req_intv;
- int16_t utc_offset; /**< UTC offset observed against TAI */
- DAC_VAL osc_dac_cal; /**< disiplination value of the oscillator */
+ int16_t utc_offset; ///< %UTC offset observed against TAI
+ DAC_VAL osc_dac_cal; ///< disciplination value of the oscillator
- uint32_t reserved_3; /**< reserved, currently always 0 */
+ uint8_t parent_clock_class; ///< clock class of the parent node
+ uint8_t parent_clock_accuracy; ///< clock accuracy of the parent node, see ::PTP_CLOCK_ACCURACIES
+
+ uint16_t reserved_3; ///< reserved, currently always 0
} PTP_STATE;
#define _mbg_swab_ptp_state( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->nw_prot ); \
_mbg_swab32( &(_p)->flags ); \
@@ -4574,65 +12992,48 @@ typedef struct
_mbg_swab_nano_time( &(_p)->delay_asymmetry ); \
_mbg_swab_ptp_clock_id( &(_p)->gm_id ); \
_mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \
- _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->tsu_secs ); \
_mbg_swab32( &(_p)->reserved_2 ); \
_mbg_swab16( &(_p)->utc_offset ); \
_mbg_swab_dac_val( &(_p)->osc_dac_cal ); \
- _mbg_swab32( &(_p)->reserved_3 ); \
-}
+ _mbg_swab16( &(_p)->reserved_3 ); \
+} while ( 0 )
/**
- * @brief Flag bits used with PTP_STATE::flags
+ * @brief Flags bits used with PTP_STATE::flags
+ *
+ * @see ::PTP_STATE_FLAG_MASKS
*/
-enum
+enum PTP_STATE_FLAGS
{
- PTP_FLAG_BIT_SLAVE_ONLY, /**< the port can only be slave */
- PTP_FLAG_BIT_IS_SLAVE, /**< the port is currently slave */
- PTP_FLAG_BIT_TIMESCALE_IS_PTP, /**< the timescale is PTP standard, not arbitrary */
- PTP_FLAG_BIT_LS_ANN, /**< a leap second is being announced */
- PTP_FLAG_BIT_LS_ANN_NEG, /**< the announced leap second is negative */
- PTP_FLAG_BIT_IS_UNICAST, /**< the port currently operates in unicast mode */
- N_PTP_FLAG_BIT /**< the number of defined flag bits */
+ PTP_FLAG_SLAVE_ONLY, ///< the port can only be slave
+ PTP_FLAG_IS_SLAVE, ///< the port is currently slave
+ PTP_FLAG_TIMESCALE_IS_PTP, ///< the timescale is PTP standard, not arbitrary
+ PTP_FLAG_LS_ANN, ///< a leap second is being announced
+ PTP_FLAG_LS_ANN_NEG, ///< the announced leap second is negative
+ PTP_FLAG_IS_UNICAST, ///< the port currently operates in unicast mode
+ PTP_FLAG_UTC_VALID, ///< %UTC parameters are valid
+ PTP_FLAG_ONE_STEP, ///< One-Step Clock active
+ N_PTP_STATE_FLAGS ///< the number of defined flag bits
};
-#define PTP_FLAG_MSK_SLAVE_ONLY ( 1UL << PTP_FLAG_BIT_SLAVE_ONLY )
-#define PTP_FLAG_MSK_IS_SLAVE ( 1UL << PTP_FLAG_BIT_IS_SLAVE )
-#define PTP_FLAG_MSK_TIMESCALE_IS_PTP ( 1UL << PTP_FLAG_BIT_TIMESCALE_IS_PTP )
-#define PTP_FLAG_MSK_LS_ANN ( 1UL << PTP_FLAG_BIT_LS_ANN )
-#define PTP_FLAG_MSK_LS_ANN_NEG ( 1UL << PTP_FLAG_BIT_LS_ANN_NEG )
-#define PTP_FLAG_MSK_IS_UNICAST ( 1UL << PTP_FLAG_BIT_IS_UNICAST )
-
-
-
-#define PTP_SYNC_INTERVAL_MIN -6
-#define PTP_SYNC_INTERVAL_MAX 6
-
-#define PTP_DELAY_REQ_INTERVAL_MIN -6
-#define PTP_DELAY_REQ_INTERVAL_MAX 6
-
-#define PTP_DEFAULT_UNICAST_SYNC_INTERVAL_MIN -4
-#define PTP_DEFAULT_UNICAST_SYNC_INTERVAL_MAX 4
-
-#define PTP_DEFAULT_UNICAST_DELAY_REQ_INTERVAL_MIN -4
-#define PTP_DEFAULT_UNICAST_DELAY_REQ_INTERVAL_MAX 4
-
-#define PTP_DEFAULT_UNICAST_ANNOUNCE_INTERVAL_MIN -4
-#define PTP_DEFAULT_UNICAST_ANNOUNCE_INTERVAL_MAX 4
-
/**
- * @defgroup group_ptp_uc_msg_duration_limits Unicast PTP masters send messages
- * to a unicast slave only for a given interval as requested by the particular
- * slave, which is called message duration. These symbols define the minimum and
- * maximum message duration configured on a slave for a specific unicast master,
- * i.e. for PTP_UC_MASTER_SETTINGS::message_duration.
- * @{ */
-
-#define PTP_UC_MSG_DURATION_MIN 10 //< minimum message duration [s]
-#define PTP_UC_MSG_DURATION_MAX 1000 //< maximum message duration [s]
-#define PTP_UC_MSG_DURATION_DEFAULT 60 //< default, though the specs say 300 s
-
-/** @} group_ptp_uc_msg_duration_limits */
+ * @brief Flags masks used with PTP_STATE::flags
+ *
+ * @see ::PTP_STATE_FLAGS
+ */
+enum PTP_STATE_FLAG_MASKS
+{
+ PTP_FLAG_MSK_SLAVE_ONLY = ( 1UL << PTP_FLAG_SLAVE_ONLY ), ///< see ::PTP_FLAG_SLAVE_ONLY
+ PTP_FLAG_MSK_IS_SLAVE = ( 1UL << PTP_FLAG_IS_SLAVE ), ///< see ::PTP_FLAG_IS_SLAVE
+ PTP_FLAG_MSK_TIMESCALE_IS_PTP = ( 1UL << PTP_FLAG_TIMESCALE_IS_PTP ), ///< see ::PTP_FLAG_TIMESCALE_IS_PTP
+ PTP_FLAG_MSK_LS_ANN = ( 1UL << PTP_FLAG_LS_ANN ), ///< see ::PTP_FLAG_LS_ANN
+ PTP_FLAG_MSK_LS_ANN_NEG = ( 1UL << PTP_FLAG_LS_ANN_NEG ), ///< see ::PTP_FLAG_LS_ANN_NEG
+ PTP_FLAG_MSK_IS_UNICAST = ( 1UL << PTP_FLAG_IS_UNICAST ), ///< see ::PTP_FLAG_IS_UNICAST
+ PTP_FLAG_MSK_UTC_VALID = ( 1UL << PTP_FLAG_UTC_VALID ), ///< see ::PTP_FLAG_UTC_VALID
+ PTP_FLAG_MSK_ONE_STEP = ( 1UL << PTP_FLAG_ONE_STEP ) ///< see ::PTP_FLAG_ONE_STEP
+};
@@ -4641,76 +13042,89 @@ enum
*/
typedef struct
{
- //##++++ Do we need a port identifier ??
- uint16_t nw_prot; /**< one of the enumerated and supported protocols (@see N_PTP_NW_PROT) */
- uint8_t profile; /**< PTP profile, currently only 0 = default */
- uint8_t domain_number; /**< the PTP clock domain number, 0:3 */
+ uint16_t nw_prot; ///< see ::PTP_NW_PROTS
+ uint8_t selected_presets; ///< selected PTP presets, see ::PTP_PRESETS
+ uint8_t domain_number; ///< the PTP clock domain number, 0:3
- uint8_t delay_mech; /**< PTP_DELAY_MECH_BIT_E2E or PTP_DELAY_MECH_BIT_P2P, if supported */
- uint8_t ptp_role; /**< one of the enumerated PTP roles (@see N_PTP_ROLES) */
- uint8_t priority_1; /**< priority 1 */
- uint8_t priority_2; /**< priority 2 */
+ uint8_t delay_mech; ///< see ::PTP_DELAY_MECHS
+ uint8_t ptp_role; ///< one of the supported PTP roles, see ::PTP_ROLES
+ uint8_t priority_1; ///< priority 1
+ uint8_t priority_2; ///< priority 2
uint8_t dflt_clk_class_unsync_cold; // 6:255
uint8_t dflt_clk_class_unsync_warm; // 6:255
uint8_t dflt_clk_class_sync_cold; // 6:255
uint8_t dflt_clk_class_sync_warm; // 6:255
- uint8_t reserved_1; /**< reserved, currently always 0 */
- uint8_t reserved_2; /**< reserved, currently always 0 */
- int16_t sync_intv; /**< log2 of the sync interval [s] */
+ uint8_t ann_rcpt_timeout; ///< announce msg. receipt timeout, see ::PTP_ANN_RCPT_TIMEOUT_LIMITS
+ uint8_t opt_ext; ///< optional configuration extension, see ::PTP_OPT_EXTS
+ int16_t sync_intv; ///< log2 of the sync interval [s]
- int16_t ann_intv; /**< log2 of the announce interval [s] */
- int16_t delay_req_intv; /**< log2 of the delay request interval [s] */
+ int16_t ann_intv; ///< log2 of the announce interval [s]
+ int16_t delay_req_intv; ///< log2 of the delay request interval [s]
- uint32_t upper_bound; /**< sync state set to false if above this limit [ns] */
- uint32_t lower_bound; /**< sync state set to true if below this limit [ns] */
+ uint32_t upper_bound; ///< sync state set to false if above this limit [ns]
+ uint32_t lower_bound; ///< sync state set to true if below this limit [ns]
- uint32_t reserved_3; /**< reserved, currently always 0 */
- uint32_t flags; /**< bit masks as defined below */
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see @ref PTP_CFG_FLAG_MASKS
} PTP_CFG_SETTINGS;
-#define _mbg_swab_ptp_cfg_settings( _p ) \
-{ \
- _mbg_swab16( &(_p)->nw_prot ); \
- _mbg_swab16( &(_p)->sync_intv ); \
- _mbg_swab16( &(_p)->ann_intv ); \
- _mbg_swab16( &(_p)->delay_req_intv ); \
- _mbg_swab32( &(_p)->upper_bound ); \
- _mbg_swab32( &(_p)->lower_bound ); \
- _mbg_swab32( &(_p)->reserved_3 ); \
- _mbg_swab32( &(_p)->flags ); \
-}
+#define _mbg_swab_ptp_cfg_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->nw_prot ); \
+ _mbg_swab16( &(_p)->sync_intv ); \
+ _mbg_swab16( &(_p)->ann_intv ); \
+ _mbg_swab16( &(_p)->delay_req_intv ); \
+ _mbg_swab32( &(_p)->upper_bound ); \
+ _mbg_swab32( &(_p)->lower_bound ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Possible values for PTP_CFG_SETTINGS::ann_rcpt_timeout
+ */
+enum PTP_ANN_RCPT_TIMEOUT_LIMITS
+{
+ PTP_ANN_RCPT_TIMEOUT_MIN = 2,
+ PTP_ANN_RCPT_TIMEOUT_MAX = 8,
+ DEFAULT_PTP_ANN_RCPT_TIMEOUT = 3
+};
/**
- * @brief A structure to used to query the current configurration and capabilities of a PTP port
+ * @brief A structure to used to query the current configuration and capabilities of a PTP port
*/
typedef struct
{
- PTP_CFG_SETTINGS settings; /**< the current configuration */
+ PTP_CFG_SETTINGS settings; ///< the current configuration
- uint8_t ptp_proto_version; /**< PTP protocol version, 1, or 2, usually 2 for v2 */
- uint8_t reserved_1; /**< reserved, currently always 0 */
- uint16_t reserved_2; /**< reserved, currently always 0 */
+ uint8_t ptp_proto_version; ///< PTP protocol version, 1, or 2, usually 2 for v2
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t reserved_2; ///< reserved, currently always 0
- int16_t sync_intv_min; /**< log2 of minimum sync interval [s] */
- int16_t sync_intv_max; /**< log2 of maximum sync interval [s] */
- int16_t ann_intv_min; /**< log2 of minimum announce interval [s] */
- int16_t ann_intv_max; /**< log2 of maximum announce interval [s] */
- int16_t delay_req_intv_min; /**< log2 of minimum delay request interval [s] */
- int16_t delay_req_intv_max; /**< log2 of maximum delay request interval [s] */
+ int16_t sync_intv_min; ///< log2 of minimum sync interval [s]
+ int16_t sync_intv_max; ///< log2 of maximum sync interval [s]
+ int16_t ann_intv_min; ///< log2 of minimum announce interval [s]
+ int16_t ann_intv_max; ///< log2 of maximum announce interval [s]
+ int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s]
+ int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s]
- uint32_t supp_flags; /**< a bit mask of supported features (see below) */
- uint32_t supp_nw_prot; /**< a bit mask of supported network protocols */
- uint32_t supp_profiles; /**< a bit mask of supported profiles */
- uint32_t supp_delay_mech; /**< a bit mask of supported delay mechanisms */
+ uint32_t supp_flags; ///< a bit mask of supported features, see @ref PTP_CFG_FLAG_MASKS
+ uint32_t supp_nw_prot; ///< a bit mask of supported network protocols, see ::PTP_NW_PROT_MASKS
+ uint32_t supp_opt_ext; ///< a bit mask of supported optional extensions, see ::PTP_OPT_EXT_MASKS
+ uint32_t supp_delay_mech; ///< a bit mask of supported delay mechanisms, see ::PTP_DELAY_MECH_MASKS
} PTP_CFG_INFO;
#define _mbg_swab_ptp_cfg_info( _p ) \
+do \
{ \
_mbg_swab_ptp_cfg_settings( &(_p)->settings ); \
_mbg_swab16( &(_p)->reserved_2 ); \
@@ -4722,62 +13136,772 @@ typedef struct
_mbg_swab16( &(_p)->delay_req_intv_max ); \
_mbg_swab32( &(_p)->supp_flags ); \
_mbg_swab32( &(_p)->supp_nw_prot ); \
- _mbg_swab32( &(_p)->supp_profiles ); \
+ _mbg_swab32( &(_p)->supp_opt_ext ); \
_mbg_swab32( &(_p)->supp_delay_mech ); \
-}
+} while ( 0 )
/**
- * @brief Flags used with PTP_CFG_SETTINGS::flags and PTP_CFG_INFO::supp_flags
+ * @brief Flags bits used with PTP configuration
+ *
+ * Flags labeled [R/-] can only be used with ::PTP_CFG_INFO::supp_flags
+ * to indicate that the associated feature is supported in general.
+ *
+ * If a flag labeled [R/W] is set in ::PTP_CFG_INFO::supp_flags then
+ * this flag can also be used with ::PTP_CFG_SETTINGS::flags to control
+ * the associated feature.
+ *
+ * @note Originally, all devices supported the multicast slave role, so
+ * there was no extra flag to indicate this. However, some newer devices
+ * may not support the multicast slave role, so two new flags have been
+ * introduced to cope with this:
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is set then a different flag
+ * ::PTP_CFG_CAN_BE_MULTICAST_SLAVE needs to be checked to tell if
+ * the multicast slave role is supported, or not.
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is not set then the device
+ * definitely supports the multicast slave role.
+ *
+ * @see @ref PTP_CFG_FLAG_MASKS
*/
-enum
+enum PTP_CFG_FLAGS
{
- PTP_CFG_BIT_TIME_SCALE_IS_PTP, /**< time scale is PTP/TAI, else arbitrary */
- PTP_CFG_BIT_V1_HW_COMPAT, /**< maybe required for certain NIC chips, not used by Meinberg */
- PTP_CFG_BIT_CAN_BE_UNICAST_SLAVE, /**< the PTP port can take the role of a unicast slave */
- PTP_CFG_BIT_CAN_BE_MULTICAST_MASTER, /**< the PTP port can take the role of a multicast master */
- PTP_CFG_BIT_CAN_BE_UNICAST_MASTER, /**< the PTP port can take the role of a unicast master */
- N_PTP_CFG_BIT /**< the number of defined bits */
+ PTP_CFG_TIME_SCALE_IS_PTP, ///< [R/W] time scale is PTP/TAI, else arbitrary
+ PTP_CFG_V1_HW_COMPAT, ///< [R/W] maybe required for certain NIC chips, not used by Meinberg
+ PTP_CFG_CAN_BE_UNICAST_SLAVE, ///< [R/-] supports unicast slave role, see ::PTP_ROLE_UNICAST_SLAVE
+ PTP_CFG_CAN_BE_MULTICAST_MASTER, ///< [R/-] supports multicast master role, see ::PTP_ROLE_MULTICAST_MASTER
+ PTP_CFG_CAN_BE_UNICAST_MASTER, ///< [R/-] supports unicast master, see ::PTP_ROLE_UNICAST_MASTER
+ PTP_CFG_CAN_BE_MULTICAST_AUTO, ///< [R/-] can automatically become multicast master or slave, see ::PTP_CFG_CAN_BE_MULTICAST_AUTO
+ PTP_CFG_SUPP_UTC_VALID, ///< [R/-] ::PTP_FLAG_UTC_VALID bit in ::PTP_STATE::flags is supported
+ PTP_CFG_CAN_BE_BOTH_MASTER, ///< [R/-] supports unicast and multicast master role at the same time, see ::PTP_CFG_CAN_BE_BOTH_MASTER
+
+ PTP_CFG_HYBRID_MASTER, ///< [R/W] supports hybrid mode in master roles
+ PTP_CFG_HYBRID_SLAVE, ///< [R/W] supports hybrid mode in slave roles
+ PTP_CFG_ONE_STEP_MASTER, ///< [R/W] supports one-step mode in master roles
+ PTP_CFG_MNGMNT_MSGS_DISB, ///< [R/W] supports disabling of PTP management messages
+ PTP_CFG_SUPP_MCAST_SLAVE_FLAG, ///< [R/-] indicates that ::PTP_CFG_CAN_BE_MULTICAST_SLAVE flag is supported and can be checked
+ PTP_CFG_CAN_BE_MULTICAST_SLAVE, ///< [R/-] if ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG bit set, indicates if multicast slave role is supported
+ PTP_CFG_ONE_STEP_L2, ///< [R/-] supports the combination of One-Step and Layer2 mode
+ PTP_CFG_ONE_STEP_P2P, ///< [R/-] supports the combination of One-Step and P2P Delay Mechanism
+
+ PTP_CFG_TSU_RESET, ///< [R/-] supports TSU reset via register cmd
+ PTP_CFG_NTP_HW_TS_MASTER, ///< [R/-] supports the NTP HW time stamping in Master mode
+ PTP_CFG_NTP_HW_TS_SLAVE, ///< [R/-] supports the NTP HW time stamping in Slave mode
+ PTP_CFG_SYNCE_MASTER, ///< [R/-] Hardware supports Synchronous Ethernet Out
+ PTP_CFG_SYNCE_SLAVE, ///< [R/-] Hardware supports Synchronous Ethernet In
+ PTP_CFG_HAS_MUX, ///< [R/-] Hardware supports multiplexed signal outputs
+ PTP_CFG_CAN_BE_TIME_MONITOR, ///< [R/-] can be Monitoring device for external PTP or NTP devices //### TODO Shouldn't this be an XFEATURE flag?
+ PTP_CFG_HAS_STATISTICS, ///< [R/-] ::MBG_PTP_STATISTICS_INFO can be queried
+
+ PTP_CFG_CAN_BE_V1_MASTER, ///< [R/-] supports PTPv1 MASTER role
+ PTP_CFG_CAN_BE_V1_SLAVE, ///< [R/-] supports PTPv1 SLAVE role
+ PTP_CFG_HAS_V2_COMMON_DATASETS, ///< [R/-] PTPv2 common dataset structures (see IEEE1588-2008, chapter 8.2) can be queried
+ PTP_CFG_HAS_V1_COMMON_DATASETS, ///< [R/-] PTPv1 common dataset structures can be queried
+
+ N_PTP_CFG_FLAGS ///< the number of defined flags
};
-#define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_BIT_TIME_SCALE_IS_PTP )
-#define PTP_CFG_MSK_V1_HW_COMPAT ( 1UL << PTP_CFG_BIT_V1_HW_COMPAT )
-#define PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE ( 1UL << PTP_CFG_BIT_CAN_BE_UNICAST_SLAVE )
-#define PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER ( 1UL << PTP_CFG_BIT_CAN_BE_MULTICAST_MASTER )
-#define PTP_CFG_MSK_CAN_BE_UNICAST_MASTER ( 1UL << PTP_CFG_BIT_CAN_BE_UNICAST_MASTER )
-
-#define PTP_CFG_MSK_SUPPORT_PTP_ROLES ( PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE | \
- PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER | \
- PTP_CFG_MSK_CAN_BE_UNICAST_MASTER )
+/**
+ * @defgroup group_PTP_CFG_FLAG_MASKS Bit masks used with PTP_CFG_INFO::supp_flags and PTP_CFG_SETTINGS::flags
+ *
+ * @see ::PTP_CFG_INFO::supp_flags
+ * @see ::PTP_CFG_SETTINGS::flags
+ * @see ::PTP_CFG_FLAGS
+ *
+ * @anchor PTP_CFG_FLAG_MASKS
+ *
+ * @{ */
+#define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_TIME_SCALE_IS_PTP ) ///< see ::PTP_CFG_TIME_SCALE_IS_PTP
+#define PTP_CFG_MSK_V1_HW_COMPAT ( 1UL << PTP_CFG_V1_HW_COMPAT ) ///< see ::PTP_CFG_V1_HW_COMPAT
+#define PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_UNICAST_SLAVE ) ///< see ::PTP_CFG_CAN_BE_UNICAST_SLAVE
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_MULTICAST_MASTER ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_MASTER
+#define PTP_CFG_MSK_CAN_BE_UNICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_UNICAST_MASTER ) ///< see ::PTP_CFG_CAN_BE_UNICAST_MASTER
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_AUTO ( 1UL << PTP_CFG_CAN_BE_MULTICAST_AUTO ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_AUTO
+#define PTP_CFG_MSK_SUPP_UTC_VALID ( 1UL << PTP_CFG_SUPP_UTC_VALID ) ///< see ::PTP_CFG_SUPP_UTC_VALID
+#define PTP_CFG_MSK_CAN_BE_BOTH_MASTER ( 1UL << PTP_CFG_CAN_BE_BOTH_MASTER ) ///< see ::PTP_CFG_CAN_BE_BOTH_MASTER
+
+#define PTP_CFG_MSK_HYBRID_MASTER ( 1UL << PTP_CFG_HYBRID_MASTER ) ///< see ::PTP_CFG_HYBRID_MASTER
+#define PTP_CFG_MSK_HYBRID_SLAVE ( 1UL << PTP_CFG_HYBRID_SLAVE ) ///< see ::PTP_CFG_HYBRID_SLAVE
+#define PTP_CFG_MSK_ONE_STEP_MASTER ( 1UL << PTP_CFG_ONE_STEP_MASTER ) ///< see ::PTP_CFG_ONE_STEP_MASTER
+#define PTP_CFG_MSK_MNGMNT_MSGS_DISB ( 1UL << PTP_CFG_MNGMNT_MSGS_DISB ) ///< see ::PTP_CFG_MNGMNT_MSGS_DISB
+#define PTP_CFG_MSK_SUPP_MCAST_SLAVE_FLAG ( 1UL << PTP_CFG_SUPP_MCAST_SLAVE_FLAG ) ///< see ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG
+#define PTP_CFG_MSK_CAN_BE_MULTICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_MULTICAST_SLAVE ) ///< see ::PTP_CFG_CAN_BE_MULTICAST_SLAVE
+#define PTP_CFG_MSK_ONE_STEP_L2 ( 1UL << PTP_CFG_ONE_STEP_L2 ) ///< see ::PTP_CFG_ONE_STEP_L2
+#define PTP_CFG_MSK_ONE_STEP_P2P ( 1UL << PTP_CFG_ONE_STEP_P2P ) ///< see ::PTP_CFG_ONE_STEP_P2P
+
+#define PTP_CFG_MSK_TSU_RESET ( 1UL << PTP_CFG_TSU_RESET ) ///< see ::PTP_CFG_TSU_RESET
+#define PTP_CFG_MSK_NTP_HW_TS_MASTER ( 1UL << PTP_CFG_NTP_HW_TS_MASTER ) ///< see ::PTP_CFG_NTP_HW_TS_MASTER
+#define PTP_CFG_MSK_NTP_HW_TS_SLAVE ( 1UL << PTP_CFG_NTP_HW_TS_SLAVE) ///< see ::PTP_CFG_NTP_HW_TS_SLAVE
+#define PTP_CFG_MSK_SYNCE_MASTER ( 1UL << PTP_CFG_SYNCE_MASTER ) ///< see ::PTP_CFG_SYNCE_MASTER
+#define PTP_CFG_MSK_SYNCE_SLAVE ( 1UL << PTP_CFG_SYNCE_SLAVE ) ///< see ::PTP_CFG_SYNCE_SLAVE
+#define PTP_CFG_MSK_HAS_MUX ( 1UL << PTP_CFG_HAS_MUX ) ///< see ::PTP_CFG_HAS_MUX
+#define PTP_CFG_MSK_CAN_BE_TIME_MONITOR ( 1UL << PTP_CFG_CAN_BE_TIME_MONITOR ) ///< see ::PTP_CFG_CAN_BE_TIME_MONITOR
+#define PTP_CFG_MSK_HAS_STATISTICS ( 1UL << PTP_CFG_HAS_STATISTICS ) ///< see ::PTP_CFG_HAS_STATISTICS
+
+#define PTP_CFG_MSK_CAN_BE_V1_MASTER ( 1UL << PTP_CFG_CAN_BE_V1_MASTER ) ///< see ::PTP_CFG_CAN_BE_V1_MASTER
+#define PTP_CFG_MSK_CAN_BE_V1_SLAVE ( 1UL << PTP_CFG_CAN_BE_V1_SLAVE ) ///< see ::PTP_CFG_CAN_BE_V1_SLAVE
+#define PTP_CFG_MSK_HAS_V2_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V2_COMMON_DATASETS ) ///< see ::PTP_CFG_HAS_V2_COMMON_DATASETS
+#define PTP_CFG_MSK_HAS_V1_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V1_COMMON_DATASETS ) ///< see ::PTP_CFG_HAS_V1_COMMON_DATASETS
+
+/** @} defgroup group_PTP_CFG_FLAG_MASKS */
+
+
+
+/** @brief A bit mask of the unicast role bits within the flag bits */
#define PTP_CFG_MSK_SUPPORT_PTP_UNICAST ( PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE | \
PTP_CFG_MSK_CAN_BE_UNICAST_MASTER )
+
+
+/**
+ * @brief Register in TSU-GbE FPGA to determine board features of the current TSU board revision
+ */
+typedef uint16_t PTP_HW_FEATURES;
+
+
+
+/**
+ * @brief Bits used to define ::PTP_HW_FEAT_MASKS
+ */
+enum PTP_HW_FEAT_BITS
+{
+ PTP_FEAT_SYNCE_EXT_MUX, ///< [R] supports SyncE and external signal multiplexer
+ N_PTP_HW_FEAT ///< the number of defined features
+};
+
+
+// TODO fix comment linkage
/**
- * @brief Derive a "supported PTP roles" bit mask from PTP_CFG_INFO::supp_flags
+ * @brief Bit masks used with ::PTP_HW_FEATURES
*
- * There's no explicite flag to indicate that the role of a multicast slave
- * is supported, since this role is always supported. The sequence of flags
- * indicating that a specific optional role is supported matches the enumerated
- * roles above, but don't start at bit 0. So we compine the optional flag bits
- * with the LSB always set for the implicite multicast slave role to yield
- * a bit mask which according to the enumerated roles.
+ * @see ::PTP_HW_FEAT_BITS
*/
-#define _get_supp_ptp_role_idx_msk( _f ) \
- ( 1UL | ( ( (_f) & PTP_CFG_MSK_SUPPORT_PTP_ROLES ) >> ( PTP_CFG_BIT_CAN_BE_UNICAST_SLAVE - 1 ) ) )
-//##+++++++++ #define _get_supp_ptp_roles( _r ) ((((_r) & ~3UL) >> PTP_CFG_BIT_V1_HW_COMPAT ) | 1UL)
+enum PTP_HW_FEAT_MASKS
+{
+ PTP_HW_FEAT_MSK_SYNCE_EXT_MUX = ( 1UL << PTP_FEAT_SYNCE_EXT_MUX ) ///< see ::PTP_FEAT_SYNCE_EXT_MUX
+};
+
/**
- * @brief A host's fully qualified domain name (FQDN), or a numeric IP address string
+ * @brief Known optional PTP protocol extensions, see ::PTP_CFG_SETTINGS::opt_ext
*
- * In theory each single component (host name, domain name, top level domain name)
- * of a FQDN can have up to 63 characters, but the overall length is limited to
- * 255 characters. We specify one more character for the trailing 0.
+ * @see ::PTP_OPT_EXT_MASKS
+ */
+enum PTP_OPT_EXTS
+{
+ PTP_OPT_EXT_NONE, ///< no extension used
+ PTP_OPT_EXT_POWER, ///< IEEE C37.238-2011 profile extension
+ PTP_OPT_EXT_TELECOM, ///< ITU-T G.8265.1 profile extension
+ PTP_OPT_EXT_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension
+ PTP_OPT_EXT_SMPTE, ///< SMPTE ST 2059-2 profile extension
+ PTP_OPT_EXT_8021AS, ///< IEEE 802.1AS profile extension
+ PTP_OPT_EXT_6185093, ///< IEC/IEEE FDIS 61850-9-3 Power Utility profile extension
+ PTP_OPT_EXT_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension
+ N_PTP_OPT_EXT ///< number of known optional extensions
+};
+
+
+/**
+ * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext
+ *
+ * @see ::PTP_OPT_EXTS
+ */
+enum PTP_OPT_EXT_MASKS
+{
+ PTP_MSK_OPT_EXT_NONE = ( 1UL << PTP_OPT_EXT_NONE ), ///< this is actually not used, see ::PTP_OPT_EXT_NONE
+ PTP_MSK_OPT_EXT_POWER = ( 1UL << PTP_OPT_EXT_POWER ), ///< see ::PTP_OPT_EXT_POWER
+ PTP_MSK_OPT_EXT_TELECOM = ( 1UL << PTP_OPT_EXT_TELECOM ), ///< see ::PTP_OPT_EXT_TELECOM
+ PTP_MSK_OPT_EXT_TELECOM_PHASE = ( 1UL << PTP_OPT_EXT_TELECOM_PHASE ), ///< see ::PTP_OPT_EXT_TELECOM_PHASE
+ PTP_MSK_OPT_EXT_SMPTE = ( 1UL << PTP_OPT_EXT_SMPTE ), ///< see ::PTP_OPT_EXT_SMPTE
+ PTP_MSK_OPT_EXT_8021AS = ( 1UL << PTP_OPT_EXT_8021AS ), ///< see ::PTP_OPT_EXT_8021AS
+ PTP_MSK_OPT_EXT_6185093 = ( 1UL << PTP_OPT_EXT_6185093 ), ///< see ::PTP_OPT_EXT_6185093
+ PTP_MSK_OPT_EXT_TELECOM_PTS = ( 1UL << PTP_OPT_EXT_TELECOM_PTS ) ///< see ::PTP_OPT_EXT_TELECOM_PTS
+};
+
+
+
+/**
+ * @brief Enumeration of PTP cfg presets used with ::PTP_CFG_SETTINGS::selected_presets
+ *
+ * This can be used by configuration programs to determine
+ * the last recently selected presets.
+ *
+ * @see ::PTP_PRESETS_STRS
+ * @see ::PTP_PRESETS_MASKS
+ */
+enum PTP_PRESETS
+{
+ PTP_PRESETS_CUSTOM, ///< customizable, always supported
+ PTP_PRESETS_DFLT_E2E, ///< pure IEEE1588-2008 (PTPv2) with E2E
+ PTP_PRESETS_DFLT_P2P, ///< pure IEEE1588-2008 (PTPv2) with P2P
+ PTP_PRESETS_POWER, ///< IEEE C37.238 profile extension, only if ::PTP_MSK_OPT_EXT_POWER is set
+ PTP_PRESETS_TELECOM, ///< ITU-T G.8265.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM is set
+ PTP_PRESETS_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set
+ PTP_PRESETS_SMPTE, ///< SMPTE ST 2059-2 profile extension, only if ::PTP_MSK_OPT_EXT_SMPTE is set
+ PTP_PRESETS_AES67, ///< AES67 media profile
+ PTP_PRESETS_8021AS, ///< IEEE 802.1AS -like profile, only if ::PTP_MSK_OPT_EXT_8021AS is set
+ PTP_PRESETS_6185093, ///< IEC/IEEE FDIS 61850-9-3, only if ::PTP_MSK_OPT_EXT_6185093 is set
+ PTP_PRESETS_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PTS is set
+ PTP_PRESETS_DOCSIS_31, ///< only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set
+ N_PTP_PRESETS ///< number of supported presets
+};
+
+
+/**
+ * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext
+ *
+ * @see ::PTP_PRESETS
+ */
+enum PTP_PRESETS_MASKS
+{
+ PTP_MSK_PRESETS_CUSTOM = ( 1UL << PTP_PRESETS_CUSTOM ), ///< see ::PTP_PRESETS_CUSTOM
+ PTP_MSK_PRESETS_DFLT_E2E = ( 1UL << PTP_PRESETS_DFLT_E2E ), ///< see ::PTP_PRESETS_DFLT_E2E
+ PTP_MSK_PRESETS_DFLT_P2P = ( 1UL << PTP_PRESETS_DFLT_P2P ), ///< see ::PTP_PRESETS_DFLT_P2P
+ PTP_MSK_PRESETS_POWER = ( 1UL << PTP_PRESETS_POWER ), ///< see ::PTP_PRESETS_POWER
+ PTP_MSK_PRESETS_TELECOM = ( 1UL << PTP_PRESETS_TELECOM ), ///< see ::PTP_PRESETS_TELECOM
+ PTP_MSK_PRESETS_TELECOM_PHASE = ( 1UL << PTP_PRESETS_TELECOM_PHASE ), ///< see ::PTP_PRESETS_TELECOM_PHASE
+ PTP_MSK_PRESETS_SMPTE = ( 1UL << PTP_PRESETS_SMPTE ), ///< see ::PTP_PRESETS_SMPTE
+ PTP_MSK_PRESETS_AES67 = ( 1UL << PTP_PRESETS_AES67 ), ///< see ::PTP_PRESETS_AES67
+ PTP_MSK_PRESETS_8021AS = ( 1UL << PTP_PRESETS_8021AS ), ///< see ::PTP_PRESETS_8021AS
+ PTP_MSK_PRESETS_6185093 = ( 1UL << PTP_PRESETS_6185093), ///< see ::PTP_PRESETS_6185093
+ PTP_MSK_PRESETS_TELECOM_PTS = ( 1UL << PTP_PRESETS_TELECOM_PTS), ///< see ::PTP_PRESETS_TELECOM_PTS
+ PTP_MSK_PRESETS_DOCSIS_31 = ( 1UL << PTP_PRESETS_DOCSIS_31) ///< see ::PTP_PRESETS_DOCSIS_31
+};
+
+
+/**
+ * @brief Name strings for defined PTP presets
+ *
+ * @see ::PTP_PRESETS
+ */
+#define PTP_PRESETS_STRS \
+{ \
+ "Custom", \
+ "Default E2E IEEE1588-2008", \
+ "Default P2P IEEE1588-2008", \
+ "Power IEEE C37.238", \
+ "Telecom ITU-T G.8265.1", \
+ "Telecom ITU-T G.8275.1", \
+ "SMPTE ST 2059-2", \
+ "AES67 Media Profile", \
+ "IEEE 802.1AS", \
+ "Utility IEC 61850-9-3", \
+ "Telecom ITU-T G.8275.2", \
+ "DOCSIS 3.1" \
+}
+
+
+
+/**
+ * @brief Additional parameters for Power Profile
+ */
+#define PTP_POWER_PROFILE_GM_ID_MIN 3
+#define PTP_POWER_PROFILE_GM_ID_MAX 255
+
+typedef struct
+{
+ uint32_t network_incaccuracy; ///< Pre-defined network inaccuracy from master in [ns]
+ uint8_t grandmaster_id; ///< [::PTP_POWER_PROFILE_GM_ID_MIN..::PTP_POWER_PROFILE_GM_ID_MAX]
+ uint8_t reserved_1;
+ uint16_t reserved_2;
+ TZDL tzdl;
+
+} PTP_POWER_PROFILE_CFG;
+
+#define _mbg_swab_ptp_power_profile_cfg( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->network_incaccuracy ); \
+ _mbg_swab8( &(_p)->grandmaster_id ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab_tzdl( &(_p)->tzdl ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+#if defined( _PRELIMINARY_CODE )
+
+// TODO: These definitions are preliminary and maybe subject to changes.
+
+/**
+ * @brief SMPTE System Frame Rates according to SMPTE ST 2059-2
+ *
+ * @see ::TODO
+ */
+enum SMPTE_SYSTEM_FRAME_RATES
+{
+ SMPTE_23_98HZ,
+ SMPTE_24HZ,
+ SMPTE_25HZ,
+ SMPTE_29_97HZ,
+ SMPTE_50HZ,
+ SMPTE_59_94HZ,
+ N_SMPTE_SYSTEM_FRAME_RATES
+};
+
+
+#define SMPTE_SYSTEM_FRAME_RATE_STR \
+{ \
+ "24Hz (23.98)", \
+ "24Hz", \
+ "25Hz", \
+ "30Hz (29.97)", \
+ "50Hz", \
+ "60Hz (59.94)" \
+}
+
+
+#define SMPTE_FRAME_RATE_NUM \
+{ \
+ 24000, \
+ 24000, \
+ 25000, \
+ 30000, \
+ 50000, \
+ 60000, \
+}
+
+#define SMPTE_FRAME_RATE_DENUM \
+{ \
+ 1001, \
+ 1000, \
+ 1000, \
+ 1001, \
+ 1000, \
+ 1001, \
+}
+
+
+/**
+ * @brief Additional parameters for SMPTE ST 2059-2 profile
+ *
+ * This stucture holds the synchronization metadata required for the SMPTE profile.
+ * This structure is only used for internal storage of the data. The data is
+ * distributed through a network by using management messages and the dedicated
+ * organization extension TLV defined in the SMPTE profile.
+ */
+typedef struct
+{
+ /// Default system frame rate
+ /// Default video frame rate of the slave system as a lowest term rational.
+ /// The data type shall be composed of a pair of unsigned Int32 values coded
+ /// in big-endian form where the first shall be the numerator and the second
+ /// shall be the denominator. The denominator shall be the smallest value
+ /// that represents the frame rate denominator
+ /// For example, 29.97 Hz: (30000/1001) or 25 Hz: (25/1).
+ uint32_t defaultSystemFrameRateNum;
+ uint32_t defaultSystemFrameRateDenum;
+ /// Master locking status
+ /// Complementary information to clockClass (0: Not in use, 1: Free Run,
+ /// 2: Cold Locking, 3: Warm Locking, 4: Locked)
+ uint8_t masterLockingStatus;
+ /// Time Address Flags
+ /// Indicates the intended ST 12-1 flags.
+ /// Bit 0: Drop frame (0: Non-drop-frame, 1: Drop-frame)
+ /// Bit 1: Color Frame Identification (0: Not in use, 1: In use)
+ /// Bits 2-7: Reserved
+ uint8_t timeAddressFlags;
+ /// Current local offset
+ /// Offset in seconds of Local Time from grandmaster PTP time. For example,
+ /// if Local Time is Eastern Standard Time (North America) UTC-5 and the
+ /// number of leap seconds is 35, the value will be -18035 (decimal).
+
+ uint8_t reserved_1;
+ uint8_t reserved_2;
+
+ int32_t currentLocalOffset;
+ /// Jump seconds
+ /// The size of the next discontinuity, in seconds, of Local Time. A value
+ /// of zero indicates that no discontinuity is expected. A positive value
+ /// indicates that the discontinuity will cause the currentLocalOffset to increase.
+ int32_t jumpSeconds;
+ /// Time of next jump
+ /// The value of the seconds portion of the grandmastermaster PTP time at the time
+ /// that the next discontinuity of the currentLocalOffset will occur. The
+ /// discontinuity occurs at the start of the second indicated
+ uint8_t timeOfNextJump[6];
+ /// Time of next jam
+ /// The value of the seconds portion of the PTP time corresponding to the next
+ /// scheduled occurrence of the Daily Jam. If no Daily Jam is scheduled, the
+ /// value of timeOfNextJam shall be zero.
+ uint8_t timeOfNextJam[6];
+ /// Time of previous jam
+ /// The value of the seconds portion of the PTP time corresponding to the
+ /// previous occurrence of the Daily Jam.
+ uint8_t timeOfPreviousJam[6];
+ /// Previous jam local offset
+ /// The value of currentLocalOffset at the previous daily jam time.
+ /// If a discontinuity of Local Time occurs at the jam time, this parameter
+ /// reflects the offset after the discontinuity.
+ uint8_t reserved_3;
+ uint8_t reserved_4;
+ uint32_t reserved_5;
+
+ int32_t previousJamLocalOffset;
+ /// Daylight saving
+ /// Bit 0: Current Daylight Saving (0: Not in effect, 1: In effect)
+ /// Bit 1: Daylight Saving at next discontinuity (0: Not in effect, 1: In effect)
+ /// Bit 2: Daylight Saving at previous daily jam time (0: Not in effect, 1: In effect)
+ /// Bits 3-7: Reserved
+ uint8_t daylightSaving;
+ /// Leap second jump
+ /// The reason for the forthcoming discontinuity of currentLocalOffset indicated by
+ /// timeOfNextJump
+ /// Bit 0:
+ /// 0: Other than a change in the number of leap seconds (default)
+ /// 1: A change in number of leap seconds
+ /// Bits 1-7: Reserved
+ uint8_t leapSecondJump;
+
+ uint8_t reserved_6;
+ uint8_t reserved_7;
+
+ uint32_t reserved_8;
+ uint32_t reserved_9;
+ uint32_t reserved_10;
+
+} PTP_SMPTE_PROFILE_CFG;
+
+
+
+/**
+ * @brief Additional parameters for Telecom8275.1 profile
+ */
+typedef struct
+{
+ uint8_t use_alternate_multicast_address;
+ uint8_t reserved_1;
+ uint8_t reserved_2;
+ uint8_t reserved_3;
+ uint32_t reserved_4;
+
+} PTP_TELECOMG8275_PROFILE_CFG;
+
+#define _mbg_swab_ptp_telecom8275_profile_cfg( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->use_alternate_multicast_mac_address ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab8( &(_p)->reserved_2 ); \
+ _mbg_swab8( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief A type which holds one of the ITU-T SSM codes
+ *
+ * @see ::ITU_SSM_CODES
+ */
+typedef uint16_t ITU_SSM_CODE;
+
+
+
+/**
+ * @brief ITU-T SSM codes acc. to Recommendation G.781
+ *
+ * @see ::ITU_SSM_CODE
+ */
+enum ITU_SSM_CODES
+{
+ ITU_SSM_CODE_STU_UKN,
+ ITU_SSM_CODE_PRS,
+ ITU_SSM_CODE_PRC,
+ ITU_SSM_CODE_INV3,
+ ITU_SSM_CODE_SSU_A_TNC,
+ ITU_SSM_CODE_INV5,
+ ITU_SSM_CODE_INV6,
+ ITU_SSM_CODE_ST2,
+ ITU_SSM_CODE_SSU_B,
+ ITU_SSM_CODE_INV9,
+ ITU_SSM_CODE_ST3,
+ ITU_SSM_CODE_SEC,
+ ITU_SSM_CODE_SMC,
+ ITU_SSM_CODE_ST3E,
+ ITU_SSM_CODE_PROV,
+ ITU_SSM_CODE_DNU_DUS,
+ N_ITU_SSM_CODES
+};
+
+
+#define N_SSM_CODES_OPTION_1 5
+#define N_SSM_CODES_OPTION_2 9
+
+
+/**
+ * @brief Name strings for SSM codes, network option I
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_OPT_1_STRS \
+{ \
+ "", \
+ "", \
+ "QL-PRC", \
+ "", \
+ "QL-SSU-A", \
+ "", \
+ "", \
+ "", \
+ "QL-SSU-B", \
+ "", \
+ "", \
+ "QL-SEC", \
+ "", \
+ "", \
+ "", \
+ "QL-DNU" \
+}
+
+
+
+/**
+ * @brief Name strings for SSM codes, network option II
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_OPT_2_STRS \
+{ \
+ "QL-STU", \
+ "QL-PRS", \
+ "", \
+ "", \
+ "QL-TNC", \
+ "", \
+ "", \
+ "QL-ST2", \
+ "", \
+ "", \
+ "QL-ST3", \
+ "", \
+ "QL-SMC", \
+ "QL-ST3E", \
+ "QL-PROV", \
+ "QL-DUS" \
+}
+
+
+
+/**
+ * @brief Name strings for SSM codes, option I and II combined
+ *
+ * @see ::ITU_SSM_CODES
+ */
+#define ITU_SSM_CODE_STRS_COMBINED \
+{ \
+ "QL-STU/UKN", \
+ "QL-PRS", \
+ "QL-PRC", \
+ "QL-INV3", \
+ "QL-SSU-A/TNC", \
+ "QL-INV5", \
+ "QL-INV6", \
+ "QL-ST2", \
+ "QL-SSU-B", \
+ "QL-INV9", \
+ "QL-EEC2/ST3", \
+ "QL-EEC1/SEC", \
+ "QL-SMC", \
+ "QL-ST3E", \
+ "QL-PROV", \
+ "QL-DNU/DUS", \
+}
+
+
+
+/**
+ * @brief Maximum T1 SSM only quality levels
+ *
+ * @see ::T1_SSM_QLVL
+ * @see ::T1_SSM_QLVL_STRS
+ * @see ::T1_SSM_QLVL_ARRAY
+ */
+#define MAX_T1_SSM_QLVL 8
+
+
+
+/**
+ * @brief T1 SSM only quality level (6 bit encoded)
+ *
+ * @see ::MAX_T1_SSM_QLVL
+ * @see ::T1_SSM_QLVL_STRS
+ * @see ::T1_SSM_QLVL_ARRAY
+ */
+enum T1_SSM_QLVL
+{
+ T1_SSM_QLVL_ST1_TRACE = 2,
+ T1_SSM_QLVL_SYNC_TRACE_UNKNOWN = 4,
+ T1_SSM_QLVL_ST2_TRACE = 6,
+ T1_SSM_QLVL_ST3_TRACE = 8,
+ T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE = 17,
+ T1_SSM_QLVL_ST4_TRACE = 20,
+ T1_SSM_QLVL_DNU_FOR_SYNC = 24,
+ T1_SSM_QLVL_RESERVED = 32
+};
+
+
+
+/**
+ * @brief T1 SSM only quality level array
+ *
+ * @see ::MAX_T1_SSM_QLVL
+ * @see ::T1_SSM_QLVL_STRS
+ * @see ::T1_SSM_QLVL
+ */
+#define T1_SSM_QLVL_ARRAY \
+{ \
+ T1_SSM_QLVL_ST1_TRACE, \
+ T1_SSM_QLVL_SYNC_TRACE_UNKNOWN, \
+ T1_SSM_QLVL_ST2_TRACE, \
+ T1_SSM_QLVL_ST3_TRACE, \
+ T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE, \
+ T1_SSM_QLVL_ST4_TRACE, \
+ T1_SSM_QLVL_DNU_FOR_SYNC, \
+ T1_SSM_QLVL_RESERVED \
+}
+
+
+
+/**
+ * @brief Name strings for T1 SSM quality levels
+ *
+ * @see ::MAX_T1_SSM_QLVL
+ * @see ::T1_SSM_QLVL
+ * @see ::T1_SSM_QLVL_ARRAY
+ */
+#define T1_SSM_QLVL_STRS \
+{ \
+ "Stratum 1 traceable", \
+ "Synchronized traceability unknown", \
+ "Stratum 2 traceable", \
+ "Stratum 3 traceable", \
+ "SONET minimum clock traceable", \
+ "Stratum 4 traceable", \
+ "Do not use for sync", \
+ "Reserved for network sync" \
+}
+
+
+
+/**
+ * @brief SDH network options
+ *
+ * @see ::SDH_NETWORK_OPTION_MASKS
+ */
+enum SDH_NETWORK_OPTIONS
+{
+ SDH_NETWORK_OPTION_1,
+ SDH_NETWORK_OPTION_2,
+ N_SDH_NETWORK_OPTIONS
+
+};
+
+
+
+/**
+ * @brief Flag masks used with MBG_SYNC_E_INFO::supp_sdh_network_opts ::FIXME
+ *
+ * @see ::SDH_NETWORK_OPTIONS
+ */
+enum SDH_NETWORK_OPTION_MASKS
+{
+ SDH_NETWORK_OPTION_1_MSK = ( 1UL << SDH_NETWORK_OPTION_1 ), ///< see ::SDH_NETWORK_OPTION_1
+ SDH_NETWORK_OPTION_2_MSK = ( 1UL << SDH_NETWORK_OPTION_2 ), ///< see ::SDH_NETWORK_OPTION_2
+};
+
+
+
+/**
+ * @brief Name strings for SDH network options
+ *
+ * @see ::SDH_NETWORK_OPTIONS
+ */
+#define SDH_NETWORK_OPTION_STRS \
+{ \
+ "SDH Network Opt. 1", \
+ "SDH Network Opt. 2", \
+}
+
+
+
+//##++++ TODO: shouldn't this be merged with / replaced by MBG_NET_LINK_MODES?
+/**
+ * @brief Link modes for SyncE on a 1000BASE-T interface
+ *
+ * @see ::GBIT_LINK_COPPER_MODE_MASKS
+ */
+enum GBIT_LINK_COPPER_MODES
+{
+ GBIT_LINK_COPPER_AUTO, // valid if synce is disabled
+ GBIT_LINK_COPPER_FORCE_SYNCE_AUTO,
+ GBIT_LINK_COPPER_FORCE_OR_IS_MASTER, // Used in both structures, settings and status
+ GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE, // Used in both structures, settings and status
+ GBIT_LINK_COPPER_PREFER_MASTER,
+ GBIT_LINK_COPPER_PREFER_SLAVE,
+ N_GBIT_LINK_COPPER_MODES
+};
+
+
+
+/**
+ * @brief Flag masks used with MBG_SYNC_E_INFO::supp_gbit_link_copper_modes ::FIXME
+ *
+ * @see ::GBIT_LINK_COPPER_MODES
*/
-typedef char MBG_HOSTNAME[256];
+enum GBIT_LINK_COPPER_MODE_MASKS
+{
+ GBIT_LINK_COPPER_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_AUTO ), ///< see ::GBIT_LINK_COPPER_AUTO_MSK
+ GBIT_LINK_COPPER_FORCE_SYNCE_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_SYNCE_AUTO ), ///< see ::GBIT_LINK_COPPER_FORCE_SYNCE_AUTO
+ GBIT_LINK_COPPER_FORCE_OR_IS_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_MASTER ), ///< see ::GBIT_LINK_COPPER_FORCE_OR_IS_MASTER
+ GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE ), ///< see ::GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE
+ GBIT_LINK_COPPER_PREFER_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_MASTER ), ///< see ::GBIT_LINK_COPPER_PREFER_MASTER
+ GBIT_LINK_COPPER_PREFER_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_SLAVE ) ///< see ::GBIT_LINK_COPPER_PREFER_SLAVE
+};
+
+
+
+//##++++ TODO: shouldn't this be merged with MBG_NET_LINK_ROLE_BITS / MBG_NET_LINK_ROLE_MASKS?
+/**
+ * @brief Link status for SyncE on a 1000BASE-T interface
+ *
+ * @see ::TODO
+ */
+enum GBIT_LINK_STATUS
+{
+ GBIT_LINK_COPPER_IS_MASTER, ///< GBIT Link is currently clock master
+ GBIT_LINK_COPPER_IS_SLAVE, ///< GBIT Link is currently clock slave
+ GBIT_LINK_COPPER_CFG_FAULT, ///< GBIT Link has a configruation fault (conflict with link partner
+ GBIT_LINK_COPPER_IS_FE, ///< Link is running on Fast Ethernet (no MASTER/SLAVE decision)
+ GBIT_LINK_DOWN, ///< Currently no link
+ GBIT_LINK_FIBER, ///< GBIT Linkup on SFP interface
+ N_GBIT_LINK_STATUS
+};
+
+
+#define GBIT_LINK_STATUS_STRS \
+{ \
+ "MASTER (1000BASE-T)", \
+ "SLAVE (1000BASE-T)", \
+ "CFG FAULT", \
+ "AUTO (100BASE-TX)", \
+ "LINK DOWN", \
+ "AUTO (SFP LINK UP)", \
+}
+
+#else // !defined( _PRELIMINARY_CODE ), dummy declarations
+
+typedef int PTP_SMPTE_PROFILE_CFG;
+typedef int PTP_TELECOMG8275_PROFILE_CFG;
+typedef int ITU_SSM_CODE;
+
+#endif // defined( _PRELIMINARY_CODE )
+
/**
@@ -4785,20 +13909,21 @@ typedef char MBG_HOSTNAME[256];
*/
typedef struct
{
- uint16_t n_supp_master; /**< number of unicast masters which can be specified */
- int16_t sync_intv_min; /**< log2 of minimum sync interval [s] */
- int16_t sync_intv_max; /**< log2 of maximum sync interval [s] */
- int16_t ann_intv_min; /**< log2 of minimum announce interval [s] */
- int16_t ann_intv_max; /**< log2 of maximum announce interval [s] */
- int16_t delay_req_intv_min; /**< log2 of minimum delay request interval [s] */
- int16_t delay_req_intv_max; /**< log2 of maximum delay request interval [s] */
- uint16_t reserved_0; /**< reserved, currently always 0 */
- uint32_t supp_flags; /**< a bit mask indicating which flags are supported */
- uint32_t reserved_1; /**< reserved, currently always 0 */
+ uint16_t n_supp_master; ///< number of unicast masters which can be specified
+ int16_t sync_intv_min; ///< log2 of minimum sync interval [s]
+ int16_t sync_intv_max; ///< log2 of maximum sync interval [s]
+ int16_t ann_intv_min; ///< log2 of minimum announce interval [s]
+ int16_t ann_intv_max; ///< log2 of maximum announce interval [s]
+ int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s]
+ int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s]
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< a bit mask indicating which flags are supported
+ uint32_t reserved_1; ///< reserved, currently always 0
} PTP_UC_MASTER_CFG_LIMITS;
#define _mbg_swab_ptp_uc_master_cfg_limits( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->n_supp_master ); \
_mbg_swab16( &(_p)->sync_intv_min ); \
@@ -4810,34 +13935,39 @@ typedef struct
_mbg_swab16( &(_p)->reserved_0 ); \
_mbg_swab32( &(_p)->supp_flags ); \
_mbg_swab32( &(_p)->reserved_1 ); \
-}
+} while ( 0 )
+
/**
- * @brief Specification of unicast masters
+ * @brief Configuration settings specifiying how to query a PTP unicast master
*
* This structure is used on a unicast slave to specify the settings of
* a unicast master polled by the slave. The number of unicast masters
* which can be specified depends on the capabilities of the slave device
- * and is returned in PTP_UC_MASTER_CFG_LIMITS::n_supp_master.
+ * and is returned in ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master.
+ *
+ * The structure ::PTP_UC_MASTER_SETTINGS_IDX should be sent to the device
+ * to save the configuration.
*/
typedef struct
{
- MBG_HOSTNAME gm_host; /**< grandmaster's hostname or IP address */
- PTP_CLOCK_ID gm_clock_id; /**< use clock ID of master port, or PTP_CLOCK_ID_WILDCARD */
- PTP_PORT_ID gm_port_id; /**< use target port ID of master port (e.g. 135) or PTP_PORT_ID_WILDCARD */
- int16_t sync_intv; /**< sync interval [log2 s] */
- int16_t ann_intv; /**< announce interval [log2 s] */
- int16_t delay_req_intv; /**< delay request interval [log2 s]*/
- int32_t fix_offset; /**< constant time offset to be compensated [ns] */
- uint16_t message_duration; /**< time period until master stops sending messages [s] */
- uint16_t reserved_0; /**< reserved, currently always 0 */
- uint32_t reserved_1; /**< reserved, currently always 0 */
- uint32_t flags; /**< bit masks as specified below */
+ MBG_HOSTNAME gm_host; ///< grandmaster's hostname or IP address
+ PTP_CLOCK_ID gm_clock_id; ///< use clock ID of master port, or ::PTP_CLOCK_ID_WILDCARD
+ PTP_PORT_ID gm_port_id; ///< use target port ID of master port (e.g. 135) or ::PTP_PORT_ID_WILDCARD
+ int16_t sync_intv; ///< sync interval [log2 s]
+ int16_t ann_intv; ///< announce interval [log2 s]
+ int16_t delay_req_intv; ///< delay request interval [log2 s]
+ int32_t fix_offset; ///< constant time offset to be compensated [ns]
+ uint16_t message_duration; ///< time period until master stops sending messages [s]
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint32_t reserved_1; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
} PTP_UC_MASTER_SETTINGS;
#define _mbg_swab_ptp_uc_master_settings( _p ) \
+do \
{ \
_mbg_swab_ptp_clock_id( &(_p)->gm_clock_id ); \
_mbg_swab_ptp_port_id( &(_p)->gm_port_id ); \
@@ -4849,176 +13979,4200 @@ typedef struct
_mbg_swab16( &(_p)->reserved_0 ); \
_mbg_swab32( &(_p)->reserved_1 ); \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
+
+
+
+/**
+ * @brief Unicast PTP master message duration limits
+ *
+ * Each unicast PTP master sends messages to a unicast slave only
+ * for a given interval as requested by the particular slave, which
+ * is called message duration.
+ * These symbols define the minimum and maximum message duration
+ * configured on a slave for a specific unicast master, i.e. for
+ * PTP_UC_MASTER_SETTINGS::message_duration. The values are defined
+ * in the PTP v2 standard.
+ */
+enum PTP_UC_MSG_DURATION_LIMITS
+{
+ PTP_UC_MSG_DURATION_MIN = 10, ///< minimum message duration [s]
+ PTP_UC_MSG_DURATION_MAX = 1000 ///< maximum message duration [s]
+};
+
/**
- * @brief Specification of a certain unicast master
+ * @brief Configuration settings for a specific PTP unicast master
*/
typedef struct
{
- uint32_t idx; /**< index, 0..(PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1) */
- PTP_UC_MASTER_SETTINGS settings; /**< specification for the unicast master with that index */
+ uint32_t idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1
+ PTP_UC_MASTER_SETTINGS settings; ///< specification for the unicast master with that index
} PTP_UC_MASTER_SETTINGS_IDX;
#define _mbg_swab_ptp_uc_master_settings_idx( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->idx ); \
_mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \
-}
+} while ( 0 )
+
/**
- * @brief Capabilities and current settings of a unicast master
+ * @brief Current settings and general capabilities of a unicast master
+ *
+ * This structure is used with a PTP unicast slave device to specify
+ * a PTP unicast master which can be queried by the slave device.
*/
typedef struct
{
- PTP_UC_MASTER_SETTINGS settings; /**< current settings */
- uint32_t reserved; /**< reserved, currently always 0 */
- uint32_t flags; /**< reserved, currently always 0 */
+ PTP_UC_MASTER_SETTINGS settings; ///< current settings
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< reserved, currently always 0
} PTP_UC_MASTER_INFO;
#define _mbg_swab_ptp_uc_master_info( _p ) \
+do \
{ \
_mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \
_mbg_swab32( &(_p)->reserved ); \
_mbg_swab32( &(_p)->flags ); \
-}
+} while ( 0 )
+
/**
- * @brief Capabilities and current settings of a specific unicast master
+ * @brief Current settings and general capabilities of a specific unicast master
+ *
+ * This structure is used with a PTP unicast slave device to specify
+ * a PTP unicast master which can be queried by the slave device.
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings and capabilities. The number of supported
+ * configuration records is PTP_UC_MASTER_CFG_LIMITS::n_supp_master.
+ *
+ * @note The ::PTP_UC_MASTER_SETTINGS_IDX structure should be send back
+ * to the device to save the configuration.
*/
typedef struct
{
- uint32_t idx; /**< index, 0..(PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1) */
- PTP_UC_MASTER_INFO info; /**< capabilities and current settings */
+ uint32_t idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1
+ PTP_UC_MASTER_INFO info; ///< capabilities and current settings
} PTP_UC_MASTER_INFO_IDX;
#define _mbg_swab_ptp_uc_master_info_idx( _p ) \
+do \
{ \
_mbg_swab32( &(_p)->idx ); \
_mbg_swab_ptp_uc_master_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t counter_cfg;
+ uint32_t flags;
+ uint32_t reserved_1;
+ uint32_t reserved_2;
+
+} MBG_PTP_STATISTICS_SETTINGS;
+
+
+
+typedef struct
+{
+ MBG_PTP_STATISTICS_SETTINGS settings;
+ uint32_t supp_flags; ///< Supported settings, currently 0
+ uint32_t reserved_1;
+
+} MBG_PTP_STATISTICS_INFO;
+
+
+
+typedef struct
+{
+ uint32_t status; ///< status word flags (use PacketCounterStat_e)
+ uint32_t rx; ///< overall Rx packet counter
+ uint32_t rxPerSec; ///< overall Rx packet counter
+ uint32_t tx; ///< overall Tx packet counter
+ uint32_t txPerSec; ///< overall Tx packet counter
+ /// invalid Rx packet counter
+ /// Indicates one of the following issues: wrong PTP version, wrong domain number,
+ /// message from self, message from other BC port, multicast message in unicast mode
+ /// or message extraction error (size error or inconsistent format).
+ uint32_t errorRx;
+ uint32_t announceMsgRx; ///< Accepted Announce message Rx counter
+ uint32_t announceMsgPerSecRx; ///< Accepted Announce message Rx counter
+ uint32_t announceMsgTx; ///< Announce message Tx counter
+ uint32_t announceMsgPerSecTx; ///< Announce message Tx counter
+ uint32_t syncMsgRx; ///< Accepted Sync message Rx counter
+ uint32_t syncMsgPerSecRx; ///< Accepted Sync message Rx counter
+ uint32_t syncMsgTx; ///< Sync message Tx counter
+ uint32_t syncMsgPerSecTx; ///< Sync message Tx counter
+ uint32_t followUpMsgRx; ///< Accepted Follow-up message Rx counter
+ uint32_t followUpMsgPerSecRx; ///< Accepted Follow-up message Rx counter
+ uint32_t followUpMsgTx; ///< Follow-up message Tx counter
+ uint32_t followUpMsgPerSecTx; ///< Follow-up message Tx counter
+ uint32_t dlyReqMsgRx; ///< Accepted Delay request message Rx counter
+ uint32_t dlyReqMsgPerSecRx; ///< Accepted Delay request message Rx counter
+ uint32_t dlyReqMsgTx; ///< Delay request message Tx counter
+ uint32_t dlyReqMsgPerSecTx; ///< Delay request message Tx counter
+ uint32_t dlyRespMsgRx; ///< Accepted Delay response message Rx counter
+ uint32_t dlyRespMsgPerSecRx; ///< Accepted Delay response message Rx counter
+ uint32_t dlyRespMsgTx; ///< Delay response message Tx counter
+ uint32_t dlyRespMsgPerSecTx; ///< Delay response message Tx counter
+ uint32_t pDlyReqMsgRx; ///< Accepted PDelay Request message Rx counter
+ uint32_t pDlyReqMsgPerSecRx; ///< Accepted PDelay Request message Rx counter
+ uint32_t pDlyReqMsgTx; ///< PDelay Request message Tx counter
+ uint32_t pDlyReqMsgPerSecTx; ///< PDelay Request message Tx counter
+ uint32_t pDlyRespMsgRx; ///< Accepted PDelay Response message Rx counter
+ uint32_t pDlyRespMsgPerSecRx; ///< Accepted PDelay Response message Rx counter
+ uint32_t pDlyRespMsgTx; ///< PDelay Response message Tx counter
+ uint32_t pDlyRespMsgPerSecTx; ///< PDelay Response message Tx counter
+ uint32_t pDlyFollowUpRx; ///< Accepted PDelay Follow-Up message Rx counter
+ uint32_t pDlyFollowUpPerSecRx; ///< Accepted PDelay Follow-Up message Rx counter
+ uint32_t pDlyFollowUpTx; ///< PDelay Follow-Up message Tx counter
+ uint32_t pDlyFollowUpPerSecTx; ///< PDelay Follow-Up message Tx counter
+ uint32_t signallingRx; ///< Accepted Signalling message Rx counter
+ uint32_t signallingPerSecRx; ///< Accepted Signalling message Rx counter
+ uint32_t signallingTx; ///< Signalling message Tx counter
+ uint32_t signallingPerSecTx; ///< Signalling message Tx counter
+ uint32_t mgmtRx; ///< Accepted Management message Rx counter
+ uint32_t mgmtPerSecRx; ///< Accepted Management message Rx counter
+ uint32_t mgmtTx; ///< Management message Tx counter
+ uint32_t mgmtPerSecTx; ///< Management message Tx counter
+ uint32_t mgmtErr; ///< Management error counter (rx)
+ uint32_t annReceptTout; ///< Announce recept timeout count
+
+ uint32_t numUcConn; ///< Number of current Unicast client connections
+ uint32_t maxNumUcConn; ///< Maximum Number of Unicast client connections (due to licence or CPU performance)
+ uint32_t numMsgPerSec; ///< Number of all messages per second (TX/RX)
+ uint32_t maxMsgPerSec; ///< max allowed number of all messages per second in Multicast/Hybrid mode (due to licence or CPU performance)
+
+} MBG_PTP_STATISTICS_STATUS;
+
+
+
+enum PTP_V1_COMM_IDS
+{
+ V1_PTP_CLOSED,
+ V1_PTP_ETHER,
+ /* reserved */
+ V1_PTP_FFBUS = 4,
+ V1_PTP_PROFIBUS,
+ V1_PTP_LON,
+ V1_PTP_DNET,
+ V1_PTP_SDS,
+ V1_PTP_CONTROLNET,
+ V1_PTP_CANOPEN,
+ /* reserved */
+ V1_PTP_IEEE1394 = 243,
+ V1_PTP_IEEE802_11A,
+ V1_PTP_IEEE_WIRELESS,
+ V1_PTP_INFINIBAND,
+ V1_PTP_BLUETOOTH,
+ V1_PTP_IEEE802_15_1,
+ V1_PTP_IEEE1451_3,
+ V1_PTP_IEEE1451_5,
+ V1_PTP_USB,
+ V1_PTP_ISA,
+ V1_PTP_PCI,
+ V1_PTP_VXI,
+ V1_PTP_DEFAULT
+};
+
+
+
+#define PTP_CODE_STRING_LENGTH 4
+#define PTP_SUBDOMAIN_NAME_LENGTH 16
+
+
+/**
+ * @brief PTPv1 UUID structure used in ::MBG_PTP_V1_DEFAULT_DATASET
+ *
+ * @see ::MBG_PTP_V1_DEFAULT_DATASET
+ */
+typedef struct
+{
+ uint8_t communication_technology;
+ uint8_t reserved_1;
+ uint16_t reserved_2;
+ PTP_CLOCK_ID clock_uuid;
+ PTP_PORT_ID port_id;
+ uint16_t reserved_3;
+} PTP_V1_UUID;
+
+
+#define _mbg_swab_ptp_v1_uuid( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab_ptp_clock_id( &(_p)->clock_uuid ); \
+ _mbg_swab_ptp_port_id( &(_p)->port_id ); \
+ _mbg_swab16( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief PTPv1 default dataset flags
+ *
+ * @see ::PTP_V1_DEFAULT_DATASET_FLAGS_MASKS
+ */
+enum PTP_V1_DEFAULT_DATASET_FLAGS
+{
+ V1_DFLT_CLK_FOLLOWUP_CAPABLE,
+ V1_DFLT_PREFERRED,
+ V1_DFLT_INITIALIZABLE,
+ V1_DFLT_EXT_TIMING,
+ V1_DFLT_IS_BC
+};
+
+
+
+/**
+ * @brief PTPv1 default dataset flag masks used with ::MBG_PTP_V1_DEFAULT_DATASET::flags
+ *
+ * @see ::PTP_V1_DEFAULT_DATASET_FLAGS
+ */
+enum PTP_V1_DEFAULT_DATASET_FLAGS_MASKS
+{
+ V1_DFLT_MSK_CLK_FOLLOWUP_CAPABLE = ( 1UL << V1_DFLT_CLK_FOLLOWUP_CAPABLE ), ///< see ::V1_DFLT_CLK_FOLLOWUP_CAPABLE
+ V1_DFLT_MSK_PREFERRED = ( 1UL << V1_DFLT_PREFERRED ), ///< see ::V1_DFLT_PREFERRED
+ V1_DFLT_MSK_INITIALIZABLE = ( 1UL << V1_DFLT_INITIALIZABLE ), ///< see ::V1_DFLT_INITIALIZABLE
+ V1_DFLT_MSK_EXT_TIMING = ( 1UL << V1_DFLT_EXT_TIMING), ///< see ::V1_DFLT_EXT_TIMING
+ V1_DFLT_MSK_IS_BC = ( 1UL << V1_DFLT_IS_BC ) ///< see ::V1_DFLT_IS_BC
+};
+
+
+
+/**
+ * @brief PTPv1 default dataset containing global information about the device
+ *
+ * @see ::PTP_V1_UUID
+ */
+typedef struct {
+ PTP_V1_UUID uuid;
+ uint8_t clock_stratum;
+ uint8_t clock_identifier[PTP_CODE_STRING_LENGTH];
+ uint16_t clock_variance;
+ int8_t sync_interval;
+ uint8_t subdomain_name[PTP_SUBDOMAIN_NAME_LENGTH];
+ uint16_t number_ports;
+ uint16_t number_foreign_records;
+ uint32_t flags;
+} MBG_PTP_V1_DEFAULT_DATASET;
+
+
+#define _mbg_swab_ptp_v1_default_dataset( _p ) \
+do \
+{ \
+ _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \
+ _mbg_swab16( &(_p)->clock_variance ); \
+ _mbg_swab16( &(_p)->number_ports ); \
+ _mbg_swab16( &(_p)->number_foreign_records ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief PTPv1 current dataset containing information about the synchronization status of the device
+ *
+ * @see ::NANO_TIME
+ */
+typedef struct
+{
+ uint16_t steps_removed;
+ uint16_t reserved_1;
+ NANO_TIME offset_from_master;
+ NANO_TIME one_way_delay;
+} MBG_PTP_V1_CURRENT_DATASET;
+
+
+#define _mbg_swab_ptp_v1_current_dataset( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->steps_removed ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab_nano_time( &(_p)->offset_from_master ); \
+ _mbg_swab_nano_time( &(_p)->one_way_delay ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief PTPv1 parent dataset flags
+ *
+ * @see ::PTP_V1_PARENT_DATASET_FLAGS_MASKS
+ */
+enum PTP_V1_PARENT_DATASET_FLAGS
+{
+ V1_PARENT_FOLLOWUP_CAPABLE,
+ V1_PARENT_EXT_TIMING,
+ V1_PARENT_STATS,
+ V1_PARENT_UTC_REASONABLE,
+ V1_PARENT_GM_PREFERRED,
+ V1_PARENT_GM_IS_BC
+};
+
+
+
+/**
+ * @brief PTPv1 parent dataset flag masks used with ::MBG_PTP_V1_PARENT_DATASET::flags
+ *
+ * @see ::PTP_V1_PARENT_DATASET_FLAGS
+ */
+enum PTP_V1_PARENT_DATASET_FLAGS_MASKS
+{
+ V1_PARENT_MSK_FOLLOWUP_CAPABLE = ( 1UL << V1_PARENT_FOLLOWUP_CAPABLE ), ///< see ::V1_PARENT_FOLLOWUP_CAPABLE
+ V1_PARENT_MSK_EXT_TIMING = ( 1UL << V1_PARENT_EXT_TIMING ), ///< see ::V1_PARENT_EXT_TIMING
+ V1_PARENT_MSK_STATS = ( 1UL << V1_PARENT_STATS ), ///< see ::V1_PARENT_STATS
+ V1_PARENT_MSK_UTC_REASONABLE = ( 1UL << V1_PARENT_UTC_REASONABLE ), ///< see ::V1_PARENT_UTC_REASONABLE
+ V1_PARENT_MSK_GM_PREFERRED = ( 1UL << V1_PARENT_GM_PREFERRED ), ///< see ::V1_PARENT_GM_PREFERRED
+ V1_PARENT_MSK_GM_IS_BC = ( 1UL << V1_PARENT_GM_IS_BC ) ///< see ::V1_PARENT_GM_IS_BC
+};
+
+
+
+/**
+ * @brief PTPv1 parent dataset containing information about the master (parent) of the device
+ *
+ * @see ::PTP_V1_UUID
+ */
+typedef struct
+{
+ PTP_V1_UUID uuid;
+ uint16_t parent_last_sync_sequence_number;
+ int16_t parent_variance;
+ int16_t observed_variance;
+ uint16_t reserved_1;
+ int32_t observed_drift;
+ PTP_V1_UUID grandmaster_uuid;
+ uint8_t grandmaster_stratum;
+ uint8_t grandmaster_identifier[PTP_CODE_STRING_LENGTH];
+ int16_t grandmaster_variance;
+ uint16_t grandmaster_sequence_number;
+ uint16_t reserved_2;
+ uint32_t flags; ///< see ::PTP_V1_PARENT_DATASET_FLAGS_MASKS
+
+} MBG_PTP_V1_PARENT_DATASET;
+
+
+#define _mbg_swab_ptp_v1_parent_dataset( _p ) \
+do \
+{ \
+ _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \
+ _mbg_swab16( &(_p)->parent_last_sync_sequence_number ); \
+ _mbg_swab16( &(_p)->parent_variance ); \
+ _mbg_swab16( &(_p)->observed_variance ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->observed_drift ); \
+ _mbg_swab_ptp_v1_uuid( &(_p)->grandmaster_uuid ); \
+ _mbg_swab16( &(_p)->grandmaster_variance ); \
+ _mbg_swab16( &(_p)->grandmaster_sequence_number ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief PTPv1 time drop dataset flags
+ *
+ * @see ::PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS
+ */
+enum PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS
+{
+ V1_TPROP_LEAP_59,
+ V1_TPROP_LEAP_61
+};
+
+
+
+/**
+ * @brief PTPv1 time drop dataset flag masks used with ::MBG_PTP_V1_TIME_PROPERTIES_DATASET::flags
+ *
+ * @see ::PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS
+ */
+enum PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS
+{
+ V1_TPROP_MSK_LEAP_59 = ( 1UL << V1_TPROP_LEAP_59 ), ///< see ::V1_TPROP_LEAP_59
+ V1_TPROP_MSK_LEAP_61 = ( 1UL << V1_TPROP_LEAP_61 ) ///< see ::V1_TPROP_LEAP_61
+};
+
+
+
+/**
+ * @brief PTPv1 time drop dataset
+ *
+ */
+typedef struct
+{
+ int16_t current_utc_offset;
+ uint16_t epoch_number;
+ uint32_t flags; ///< see ::PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS
+
+} MBG_PTP_V1_TIME_PROPERTIES_DATASET;
+
+
+#define _mbg_swab_ptp_v1_time_properties_dataset( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->current_utc_offset ); \
+ _mbg_swab16( &(_p)->epoch_number ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief PTPv1 port dataset flags
+ *
+ * @see ::PTP_V1_PORT_DATASET_FLAGS_MASKS
+ */
+enum PTP_V1_PORT_DATASET_DATASET_FLAGS
+{
+ V1_PORT_DATASET_BURST_ENB,
+};
+
+
+
+/**
+ * @brief PTPv1 port dataset flag masks used with ::MBG_PTP_V1_PORT_DATASET::flags
+ *
+ * @see ::PTP_V1_PORT_DATASET_DATASET_FLAGS
+ */
+enum PTP_V1_PORT_DATASET_FLAGS_MASKS
+{
+ V1_PORT_DATASET_MSK_BURST_ENB = ( 1UL << V1_PORT_DATASET_BURST_ENB ), ///< see ::V1_PORT_DATASET_BURST_ENB
+};
+
+
+
+/**
+ * @brief PTPv1 port dataset containing information about the appropriate port of the device
+ *
+ * @see ::PTP_V1_UUID
+ */
+typedef struct
+{
+ uint8_t port_state;
+ uint8_t reserved_1;
+ uint16_t last_sync_event_sequence_number;
+ uint16_t last_general_event_sequence_number;
+ uint16_t reserved_2;
+ uint32_t subdomain_address;
+ uint16_t event_port_address;
+ uint16_t general_port_address;
+ PTP_V1_UUID uuid;
+ uint32_t flags;
+} MBG_PTP_V1_PORT_DATASET;
+
+
+#define _mbg_swab_ptp_v1_port_dataset( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->last_sync_event_sequence_number ); \
+ _mbg_swab16( &(_p)->last_general_event_sequence_number ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->subdomain_address ); \
+ _mbg_swab16( &(_p)->event_port_address ); \
+ _mbg_swab16( &(_p)->general_port_address ); \
+ _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Index structure for PTPv1 port dataset
+ *
+ * @note Port dataset with index 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 can be queried from a device
+ *
+ * @see ::MBG_PTP_V1_PORT_DATASET
+ */
+typedef struct
+{
+ uint16_t idx; ///< Index of the port dataset, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1
+ MBG_PTP_V1_PORT_DATASET port_dataset; ///< see ::MBG_PTP_V1_PORT_DATASET
+
+} MBG_PTP_V1_PORT_DATASET_IDX;
+
+
+#define _mbg_swab_ptp_v1_port_dataset_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_ptp_v1_port_dataset( &(_p)->port_dataset ); \
}
-/** @} group_ptp */
+/**
+ * @brief Flags structure for the PTPv2 default dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1
+ *
+ * @see ::MBG_PTP_V2_DEFAULT_DATASET
+ */
+typedef struct
+{
+ uint8_t two_step : 1; ///< indicates, whether the clock is a two-step clock
+ uint8_t slave_only : 1; ///< indicates, whether the clock is a slave-only clock
+ uint8_t reserved : 6; ///< reserved, currently always 0
+} MBG_PTP_V2_DEFAULT_DATASET_FLAGS;
+#define _mbg_swab_ptp_v2_default_dataset_flags( _p ) \
+ _nop_macro_fnc()
-/*------------------------------------------------------------------------*/
-/* Ephemeris parameters of one specific SV. Needed to compute the position */
-/* of a satellite at a given time with high precision. Valid for an */
-/* interval of 4 to 6 hours from start of transmission. */
-
-typedef struct
-{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
-
- HEALTH health; /* health indication of transmitting SV [---] */
- IOD IODC; /* Issue Of Data, Clock */
- IOD IODE2; /* Issue of Data, Ephemeris (Subframe 2) */
- IOD IODE3; /* Issue of Data, Ephemeris (Subframe 3) */
- T_GPS tt; /* time of transmission */
- T_GPS t0c; /* Reference Time Clock [---] */
- T_GPS t0e; /* Reference Time Ephemeris [---] */
-
- double sqrt_A; /* Square Root of semi-major Axis [sqrt(m)] */
- double e; /* Eccentricity [---] */
- double M0; /* +- Mean Anomaly at Ref. Time [rad] */
- double omega; /* +- Argument of Perigee [rad] */
- double OMEGA0; /* +- Longit. of Asc. Node of orbit plane [rad] */
- double OMEGADOT; /* +- Rate of Right Ascension [rad/sec] */
- double deltan; /* +- Mean Motion Diff. from computed value [rad/sec] */
- double i0; /* +- Inclination Angle [rad] */
- double idot; /* +- Rate of Inclination Angle [rad/sec] */
- double crc; /* +- Cosine Corr. Term to Orbit Radius [m] */
- double crs; /* +- Sine Corr. Term to Orbit Radius [m] */
- double cuc; /* +- Cosine Corr. Term to Arg. of Latitude [rad] */
- double cus; /* +- Sine Corr. Term to Arg. of Latitude [rad] */
- double cic; /* +- Cosine Corr. Term to Inclination Angle [rad] */
- double cis; /* +- Sine Corr. Term to Inclination Angle [rad] */
-
- double af0; /* +- Clock Correction Coefficient 0 [sec] */
- double af1; /* +- Clock Correction Coefficient 1 [sec/sec] */
- double af2; /* +- Clock Correction Coefficient 2 [sec/sec^2] */
- double tgd; /* +- estimated group delay differential [sec] */
-
- uint16_t URA; /* predicted User Range Accuracy */
-
- uint8_t L2code; /* code on L2 channel [---] */
- uint8_t L2flag; /* L2 P data flag [---] */
-} EPH;
+/**
+ * @brief PTPv2 default dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1
+ *
+ * @see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS
+ * @see ::PTP_CLOCK_QUALITY
+ * @see ::PTP_CLOCK_ID
+ */
+typedef struct
+{
+ MBG_PTP_V2_DEFAULT_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t number_ports; ///< number of PTP ports on the device
+ uint8_t priority_1; ///< priority 1 attribute for the local clock
+ PTP_CLOCK_QUALITY clock_quality; ///< quality of the local clock, see ::PTP_CLOCK_QUALITY
+ uint8_t priority_2; ///< priority 2 attribute for the local clock
+ PTP_CLOCK_ID clock_identity; ///< identity of the local clock, see ::PTP_CLOCK_ID
+ uint8_t domain_number; ///< domain attribute of the local clock
+ uint8_t reserved_2; ///< reserved, currently always 0
+} MBG_PTP_V2_DEFAULT_DATASET;
-/* 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. */
+#define _mbg_swab_ptp_v2_default_dataset( _p ) \
+{ \
+ _mbg_swab_ptp_v2_default_dataset_flags( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab16( &(_p)->number_ports ); \
+ _mbg_swab8( &(_p)->priority_1 ); \
+ _mbg_swab_ptp_clock_quality( &(_p)->clock_quality ); \
+ _mbg_swab8( &(_p)->priority_2 ); \
+ _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \
+ _mbg_swab8( &(_p)->domain_number ); \
+ _mbg_swab8( &(_p)->reserved_2 ); \
+}
+
+/**
+ * @brief PTPv2 current dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.2 and 15.5.3.4.1
+ *
+ * @see ::PTP_TIME_INTERVAL
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
+ uint16_t steps_removed; ///< number of communication paths between local clock and grandmaster
+ PTP_TIME_INTERVAL offset_from_master; ///< current time difference between master and slave, see ::PTP_TIME_INTERVAL
+ PTP_TIME_INTERVAL mean_path_delay; ///< current mean propagation time between master and slave, see ::PTP_TIME_INTERVAL
- HEALTH health; /* [---] */
- T_GPS t0a; /* Reference Time Almanac [sec] */
+} MBG_PTP_V2_CURRENT_DATASET;
+
+
+#define _mbg_swab_ptp_v2_current_dataset( _p ) \
+{ \
+ _mbg_swab16( &(_p)->steps_removed ); \
+ _mbg_swab_ptp_time_interval( &(_p)->offset_from_master ); \
+ _mbg_swab_ptp_time_interval( &(_p)->mean_path_delay ); \
+}
+
+
+/**
+ * @brief Flags structure for the PTPv2 parent dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.3.3 and 15.5.3.5.1.2
+ *
+ * @see ::MBG_PTP_V2_PARENT_DATASET
+ */
+typedef struct
+{
+ uint8_t parent_stats : 1; ///< indicates whether the variance and change rate values are valid
+ uint8_t reserved : 7; ///< reserved, currently always 0
+
+} MBG_PTP_V2_PARENT_DATASET_FLAGS;
+
+#define _mbg_swab_ptp_v2_parent_dataset_flags( _p )\
+ _nop_macro_fnc()
+
+
+
+/**
+ * @brief PTPv2 parent dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.3 and 15.5.3.5.1
+ *
+ * @see ::PTP_PORT_IDENTITY
+ * @see ::MBG_PTP_V2_PARENT_DATASET_FLAGS
+ * @see ::PTP_CLOCK_QUALITY
+ * @see ::PTP_CLOCK_ID
+ */
+typedef struct
+{
+ PTP_PORT_IDENTITY parent_port_identity; ///< Identity of the master port, that issues the sync messages, see ::PTP_PORT_IDENTITY
+ MBG_PTP_V2_PARENT_DATASET_FLAGS flags; ///< Flags field, see ::MBG_PTP_V2_PARENT_DATASET_FLAGS
+ uint8_t reserved; ///< Reserved, currently always 0
+ uint16_t parent_log_variance; ///< Estimate of the parent clock's PTP variance, only valid if
+ ///< ::MBG_PTP_V2_PARENT_DATASET_FLAGS::parent_stats is set in ::MBG_PTP_V2_PARENT_DATASET::flags
+ int32_t parent_phase_change_rate; ///< Estimate of the parent clock's phase change rate, only valid if
+ ///< ::MBG_PTP_V2_PARENT_DATASET_FLAGS::parent_stats is set in ::MBG_PTP_V2_PARENT_DATASET::flags
+ uint8_t grandmaster_priority_1; ///< Priority 1 attribute of the grandmaster clock
+ PTP_CLOCK_QUALITY grandmaster_clock_quality; ///< Quality of the grandmaster clock, see ::PTP_CLOCK_QUALITY
+ uint8_t grandmaster_priority_2; ///< Priority 2 attribute of the grandmaster clock
+ PTP_CLOCK_ID grandmaster_identity; ///< Identity of the grandmaster clock, see ::PTP_CLOCK_ID
+
+} MBG_PTP_V2_PARENT_DATASET;
+
+
+#define _mbg_swab_ptp_v2_parent_dataset( _p ) \
+{ \
+ _mbg_swab_ptp_port_identity( &(_p)->parent_port_identity ); \
+ _mbg_swab_ptp_v2_parent_dataset_flags( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->reserved ); \
+ _mbg_swab16( &(_p)->parent_log_variance ); \
+ _mbg_swab32( &(_p)->parent_phase_change_rate ); \
+ _mbg_swab8( &(_p)->grandmaster_priority_1 ); \
+ _mbg_swab_ptp_clock_quality( &(_p)->grandmaster_clock_quality ); \
+ _mbg_swab8( &(_p)->grandmaster_priority_2 ); \
+ _mbg_swab_ptp_clock_id( &(_p)->grandmaster_identity ); \
+}
+
+
+/**
+ * @brief Flags structure for the PTPv2 time properties dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1
+ *
+ * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET
+ */
+typedef struct
+{
+ uint8_t leap_61 : 1; ///< set, if the last minute of the current UTC day containts 61 seconds
+ uint8_t leap_59 : 1; ///< set, if the last minute of the current UTC day containts 59 seconds
+ uint8_t utc_offset_valid : 1; ///< set, if the current UTC offset is known to be correct
+ uint8_t ptp_timescale : 1; ///< set, if the timescale of the grandmaster clock is PTP
+ uint8_t time_traceable : 1; ///< set, if timescale and utc offset are traceable to a primary reference
+ uint8_t frequency_traceable : 1; ///< set, if the frequency determining the timescale is traceable to a primary reference
+ uint8_t reserved : 2; ///< reserved, currently always 0
+
+} MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS;
+
+
+#define _mbg_swab_ptp_v2_time_properties_dataset_flags( _p ) \
+ _nop_macro_fnc()
+
+
+/**
+ * @brief PTPv2 time properties dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1
+ *
+ * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS
+ */
+typedef struct
+{
+ int16_t current_utc_offset; ///< offset between TAI and UTC in seconds
+ MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS
+ uint8_t time_source; ///< source of time used by the grandmaster clock, see ::PTP_TIME_SOURCES
+
+} MBG_PTP_V2_TIME_PROPERTIES_DATASET;
+
+
+#define _mbg_swab_ptp_v2_time_properties_dataset( _p ) \
+{ \
+ _mbg_swab16( &(_p)->current_utc_offset ); \
+ _mbg_swab_ptp_v2_time_properties_dataset_flags( &(_p)->flags ); \
+ _mbg_swab8( &(_p)->time_source ); \
+}
+
+
+/**
+ * @brief PTPv2 port dataset
+ *
+ * @note For further information, see IEEE 1588-2008, chapters 8.2.5 and 15.5.3.7.1
+ *
+ * @see ::PTP_PORT_IDENTITY
+ * @see ::PTP_TIME_INTERVAL
+ * @see ::MBG_PTP_V2_PORT_DATASET_IDX
+ */
+typedef struct
+{
+ PTP_PORT_IDENTITY port_identity; ///< identity of the local port, see ::PTP_PORT_IDENTITY
+ uint8_t port_state; ///< state of the protocol engine associated with this port, see ::PTP_PORT_STATES
+ int8_t log_min_delay_req_interval; ///< minimum delay request interval for this port
+ PTP_TIME_INTERVAL peer_mean_path_delay; ///< estimate of the current one-way propagation delay on the link, only valid if P2P is used, see ::PTP_TIME_INTERVAL
+ int8_t log_announce_interval; ///< announce interval to be used by this port
+ uint8_t announce_receipt_timeout; ///< shall be an integral multiple of ::MBG_PTP_V2_PORT_DATASET::log_announce_interval
+ int8_t log_sync_interval; ///< mean sync interval to be used for multicast messages
+ uint8_t delay_mechanism; ///< propagation delay measuring option, see ::PTP_DELAY_MECHS
+ int8_t log_min_pdelay_req_interval; ///< minimum peer delay request interval for this port
+ uint8_t version_number : 4; ///< PTP version in use on the port
+ uint8_t reserved : 4; ///< reserved, currently always 0
+
+} MBG_PTP_V2_PORT_DATASET;
+
+
+#define _mbg_swab_ptp_v2_port_dataset( _p ) \
+{ \
+ _mbg_swab_ptp_port_identity( &(_p)->port_identity ); \
+ _mbg_swab8( &(_p)->port_state ); \
+ _mbg_swab8( &(_p)->log_min_delay_req_interval ); \
+ _mbg_swab_ptp_time_interval( &(_p)->peer_mean_path_delay ); \
+ _mbg_swab8( &(_p)->log_announce_interval ); \
+ _mbg_swab8( &(_p)->announce_receipt_timeout ); \
+ _mbg_swab8( &(_p)->log_sync_interval ); \
+ _mbg_swab8( &(_p)->delay_mechanism ); \
+ _mbg_swab8( &(_p)->log_min_pdelay_req_interval ); \
+}
+
+
+/**
+ * @brief Index structure for PTPv2 port dataset
+ *
+ * @note Port dataset with index 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 can be queried from a device
+ *
+ * @see ::MBG_PTP_V2_PORT_DATASET
+ */
+typedef struct
+{
+ uint16_t idx; ///< Index of the port dataset, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1
+ MBG_PTP_V2_PORT_DATASET port_dataset; ///< see ::MBG_PTP_V2_PORT_DATASET
+
+} MBG_PTP_V2_PORT_DATASET_IDX;
+
+
+#define _mbg_swab_ptp_v2_port_dataset_idx( _p ) \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_ptp_v2_port_dataset( &(_p)->port_dataset ); \
+}
+
+
+/** @} defgroup group_ptp */
+
+
+
+/**
+ * @defgroup group_ntp Definitions used with NTP
+ *
+ * @{ */
+
+
+/**
+ * @brief Enumeration of known NTP roles
+ *
+ * @see ::NTP_GLB_SETTINGS::ntp_role
+ */
+enum NTP_ROLES
+{
+ NTP_ROLE_NONE = 0, ///< NTP services disabled
+ NTP_ROLE_CLIENT, ///< NTP client
+ NTP_ROLE_SERVER, ///< NTP server
+ NTP_ROLE_CLIENT_SERVER, ///< both NTP client and server
+ N_NTP_ROLES ///< number of supported roles
+};
+
+
+/**
+ * @brief Flag masks associated with NTP roles
+ *
+ * @see ::NTP_GLB_INFO::supp_ntp_roles
+ */
+enum NTP_ROLE_MASKS
+{
+ NTP_MSK_ROLE_NONE = ( 1UL << NTP_ROLE_NONE ), ///< see ::NTP_ROLE_NONE
+ NTP_MSK_ROLE_CLIENT = ( 1UL << NTP_ROLE_CLIENT ), ///< see ::NTP_ROLE_CLIENT
+ NTP_MSK_ROLE_SERVER = ( 1UL << NTP_ROLE_SERVER ), ///< see ::NTP_ROLE_SERVER
+ NTP_MSK_ROLE_CLIENT_SERVER = ( 1UL << NTP_ROLE_CLIENT_SERVER ), ///< see ::NTP_ROLE_CLIENT_SERVER
+};
+
+
+/**
+ * @brief Enumeration of global NTP flags
+ *
+ * @see @ref NTP_FLAG_MASKS
+ */
+enum NTP_FLAGS
+{
+ NTP_IPV4, ///< NTP via IPv4/UDP
+ NTP_IPV6, ///< NTP via IPv6/UDP
+ NTP_SYMM_KEYS, ///< support symmetric key authentication (MD5)
+ NTP_AUTOKEY, ///< include authentication fields encrypted using the autokey scheme
+ NTP_BURST, ///< send a burst of eight packets at each polling cycle
+ NTP_IBURST, ///< send a burst of eight packets at the first polling cycle
+ NTP_NO_SELECT, ///< marks a server as not to be selected for time synchronization
+ NTP_PREEMPT, ///< specifies the association as preemptable rather than the default persistent
+ NTP_PREFER, ///< marks a server as preferred peer for time synchronization
+ NTP_TRUE, ///< force the association to assume truechimer status; always survive the selection and clustering algorithms
+ NTP_BROADCAST, ///< transmission via broadcast, point to multipoint
+ NTP_MULTICAST, ///< transmission via multicast, point to multipoint
+ NTP_MANYCAST, ///< transmission via manycast, point to multipoint
+ NTP_POOL, ///< peer shall be treated as a pool server
+ NTP_PEER, ///< specifies a symmetric-active association should be used with this server
+ NTP_BROADCASTCLIENT, ///< receive broadcast messages on all interfaces
+ NTP_MULTICASTCLIENT, ///< receive messages from the given multicast group
+ NTP_MANYCASTCLIENT, ///< manycast shall be used on the given multicast address to discover peers
+ NTP_RESTRICTIONS, ///< NTP supports restrictions
+ NTP_DISCARD, ///< NTP supports "discard" rate limiting
+ NTP_REFCLOCKS, ///< NTP supports refclocks
+ NTP_STATISTICS, ///< NTP supports statistics (e.g. clockstats, loopstats, etc...)
+ NTP_MISCELLANEOUS, ///< NTP supports misc options (e.g. tinker, driftfile, orphan mode, etc...)
+ NTP_TRUSTED_KEYS, ///< NTP supports specifying trusted symmetric keys
+ NTP_FIXED_REFCLOCKS, ///< NTP refclocks not configurable
+
+ N_NTP_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_FLAGS
+ *
+ * Used with ::NTP_GLB_INFO::supp_flags, ::NTP_GLB_SETTINGS::flags, NTP_CLNT_MODE_INFO::supp_flags,
+ * ::NTP_CLNT_MODE_INFO::supp_peer_flags, ::NTP_CLNT_MODE_SETTINGS::flags, ::NTP_PEER_SETTINGS::flags,
+ * ::NTP_SRV_MODE_SETTINGS::flags, and ::NTP_SRV_MODE_INFO::supp_flags.
+ *
+ * @todo We may need structures to configure symmetric keys, and autokey certificates.
+ *
+ * @see ::NTP_FLAGS
+ *
+ * @anchor NTP_FLAG_MASKS @{ */
+
+#define NTP_MSK_IPV4 ( 1UL << NTP_IPV4 ) ///< see ::NTP_IPV4
+#define NTP_MSK_IPV6 ( 1UL << NTP_IPV6 ) ///< see ::NTP_IPV6
+#define NTP_MSK_SYMM_KEYS ( 1UL << NTP_SYMM_KEYS ) ///< see ::NTP_SYMM_KEYS; if set, ::NTP_SYMM_KEY_LIMITS can be queried
+#define NTP_MSK_AUTOKEY ( 1UL << NTP_AUTOKEY ) ///< see ::NTP_AUTOKEY
+#define NTP_MSK_BURST ( 1UL << NTP_BURST ) ///< see ::NTP_BURST
+#define NTP_MSK_IBURST ( 1UL << NTP_IBURST ) ///< see ::NTP_IBURST
+#define NTP_MSK_NO_SELECT ( 1UL << NTP_NO_SELECT ) ///< see ::NTP_NO_SELECT
+#define NTP_MSK_PREEMPT ( 1UL << NTP_PREEMPT ) ///< see ::NTP_PREEMPT
+#define NTP_MSK_PREFER ( 1UL << NTP_PREFER ) ///< see ::NTP_PREFER
+#define NTP_MSK_TRUE ( 1UL << NTP_TRUE ) ///< see ::NTP_TRUE
+#define NTP_MSK_BROADCAST ( 1UL << NTP_BROADCAST ) ///< see ::NTP_BROADCAST
+#define NTP_MSK_MULTICAST ( 1UL << NTP_MULTICAST ) ///< see ::NTP_MULTICAST
+#define NTP_MSK_MANYCAST ( 1UL << NTP_MANYCAST ) ///< see ::NTP_MANYCAST
+#define NTP_MSK_POOL ( 1UL << NTP_POOL ) ///< see ::NTP_POOL
+#define NTP_MSK_PEER ( 1UL << NTP_PEER ) ///< see ::NTP_PEER
+#define NTP_MSK_BROADCASTCLIENT ( 1UL << NTP_BROADCASTCLIENT) ///< see ::NTP_BROADCASTCLIENT
+#define NTP_MSK_MULTICASTCLIENT ( 1UL << NTP_MULTICASTCLIENT) ///< see ::NTP_MULTICASTCLIENT
+#define NTP_MSK_MANYCASTCLIENT ( 1UL << NTP_MANYCASTCLIENT) ///< see ::NTP_MANYCASTCLIENT
+#define NTP_MSK_RESTRICTIONS ( 1UL << NTP_RESTRICTIONS ) ///< see ::NTP_RESTRICTIONS
+#define NTP_MSK_DISCARD ( 1UL << NTP_DISCARD ) ///< see ::NTP_DISCARD
+#define NTP_MSK_REFCLOCKS ( 1UL << NTP_REFCLOCKS ) ///< see ::NTP_REFCLOCKS
+#define NTP_MSK_STATISTICS ( 1UL << NTP_STATISTICS ) ///< see ::NTP_STATISTICS; if set, ::NTP_STATS_GLB_INFO can be queried
+#define NTP_MSK_MISCELLANEOUS ( 1UL << NTP_MISCELLANEOUS ) ///< see ::NTP_MISCELLANEOUS
+#define NTP_MSK_TRUSTED_KEYS ( 1UL << NTP_TRUSTED_KEYS ) ///< see ::NTP_TRUSTED_KEYS
+#define NTP_MSK_FIXED_REFCLOCKS ( 1UL << NTP_FIXED_REFCLOCKS ) ///< see ::NTP_FIXED_REFCLOCKS
+
+
+/** @} anchor NTP_FLAG_MASKS */
+
+
+
+/**
+ * @brief Global configuration settings of an NTP device (client/server)
+ *
+ * This structure should be sent to an NTP device to configure global settings
+ */
+typedef struct
+{
+ uint8_t ntp_role; ///< one of the supported NTP roles, see ::NTP_ROLES
+ uint8_t num_symm_keys; ///< number of configured symm keys
+ uint8_t num_trusted_keys; ///< number of activated symm keys
+ uint8_t reserved_1; ///< reserved, currently 0
+
+ uint32_t reserved_2; ///< reserved, currently 0
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS
+
+} NTP_GLB_SETTINGS;
+
+#define _mbg_swab_ntp_glb_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Global configuration info of an NTP device (client/server)
+ *
+ * This structure can be used to determine possible configurations of an NTP device
+ */
+typedef struct
+{
+ NTP_GLB_SETTINGS settings; ///< current configuration settings
+
+ uint8_t max_symm_keys; ///< number of available symm keys that can be generated, see ::NTP_SYMM_KEY_INFO_IDX
+ uint8_t max_trusted_keys; ///< number of available trusted keys, see ::NTP_TRUSTED_KEY_INFO_IDX
+
+ uint16_t reserved_2; ///< reserved, currently 0
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t supp_ntp_roles; ///< supported NTP roles, see ::NTP_ROLE_MASKS
+ uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS
+
+} NTP_GLB_INFO;
+
+#define _mbg_swab_ntp_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_glb_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_ntp_roles ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+#if defined( _PRELIMINARY_CODE )
+
+/**
+ * @brief Enumeration of supported NTP restriction types/keywords
+ *
+ * Used with ::NTP_RESTR::type
+ *
+ * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict
+ * @see ::NTP_RESTR_TYPE_MSKS
+ */
+enum NTP_RESTR_TYPES
+{
+ NTP_RESTR_TYPE_DEFAULT,
+ NTP_RESTR_TYPE_SOURCE,
+ NTP_RESTR_TYPE_ADDRESS,
+ N_NTP_RESTR_TYPES
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::NTP_RESTR_TYPES
+ *
+ * Used with ::NTP_RESTR_LIMITS::supp_types
+ *
+ * @see ::NTP_RESTR_TYPES
+ */
+enum NTP_RESTR_TYPE_MSKS
+{
+ NTP_RESTR_TYPE_MSK_DEFAULT = ( 1UL << NTP_RESTR_TYPE_DEFAULT ), ///< see ::NTP_RESTR_TYPE_DEFAULT
+ NTP_RESTR_TYPE_MSK_SOURCE = ( 1UL << NTP_RESTR_TYPE_SOURCE ), ///< see ::NTP_RESTR_TYPE_SOURCE
+ NTP_RESTR_TYPE_MSK_ADDRESS = ( 1UL << NTP_RESTR_TYPE_ADDRESS ) ///< see ::NTP_RESTR_TYPE_ADDRESS
+};
+
+
+
+/**
+ * @brief Enumeration of supported NTP restriction flags
+ *
+ * Used to define ::NTP_RESTR_FLAG_MSKS
+ *
+ * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict
+ * @see ::NTP_RESTR_FLAG_MSKS
+ */
+enum NTP_RESTR_FLAGS
+{
+ NTP_RESTR_FLAG_FLAKE,
+ NTP_RESTR_FLAG_IGNORE,
+ NTP_RESTR_FLAG_KOD,
+ NTP_RESTR_FLAG_LIMITED,
+ NTP_RESTR_FLAG_LOWPRIOTRAP,
+ NTP_RESTR_FLAG_MSSNTP,
+ NTP_RESTR_FLAG_NOMODIFY,
+ NTP_RESTR_FLAG_NOQUERY,
+ NTP_RESTR_FLAG_NOPEER,
+ NTP_RESTR_FLAG_NOSERVE,
+ NTP_RESTR_FLAG_NOTRAP,
+ NTP_RESTR_FLAG_NOTRUST,
+ NTP_RESTR_FLAG_NTPPORT,
+ NTP_RESTR_FLAG_VERSION,
+ NTP_RESTR_FLAG_IPV4, ///< This default restriction only applies to IPv4
+ NTP_RESTR_FLAG_IPV6, ///< This default restriction only applies to IPv6
+ N_NTP_RESTR_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_RESTR_FLAGS
+ *
+ * Used with ::NTP_RESTR::flags and ::NTP_RESTR_LIMITS::supp_flags
+ *
+ * @see ::NTP_RESTR_FLAGS
+ */
+enum NTP_RESTR_FLAG_MSKS
+{
+ NTP_RESTR_FLAG_MSK_FLAKE = ( 1UL << NTP_RESTR_FLAG_FLAKE ), ///< see ::NTP_RESTR_FLAG_FLAKE
+ NTP_RESTR_FLAG_MSK_IGNORE = ( 1UL << NTP_RESTR_FLAG_IGNORE ), ///< see ::NTP_RESTR_FLAG_IGNORE
+ NTP_RESTR_FLAG_MSK_KOD = ( 1UL << NTP_RESTR_FLAG_KOD ), ///< see ::NTP_RESTR_FLAG_KOD
+ NTP_RESTR_FLAG_MSK_LIMITED = ( 1UL << NTP_RESTR_FLAG_LIMITED ), ///< see ::NTP_RESTR_FLAG_LIMITED
+ NTP_RESTR_FLAG_MSK_LOWPRIOTRAP = ( 1UL << NTP_RESTR_FLAG_LOWPRIOTRAP ),///< see ::NTP_RESTR_FLAG_LOWPRIOTRAP
+ NTP_RESTR_FLAG_MSK_MSSNTP = ( 1UL << NTP_RESTR_FLAG_MSSNTP ), ///< see ::NTP_RESTR_FLAG_MSSNTP
+ NTP_RESTR_FLAG_MSK_NOMODIFY = ( 1UL << NTP_RESTR_FLAG_NOMODIFY ), ///< see ::NTP_RESTR_FLAG_NOMODIFY
+ NTP_RESTR_FLAG_MSK_NOQUERY = ( 1UL << NTP_RESTR_FLAG_NOQUERY ), ///< see ::NTP_RESTR_FLAG_NOQUERY
+ NTP_RESTR_FLAG_MSK_NOPEER = ( 1UL << NTP_RESTR_FLAG_NOPEER ), ///< see ::NTP_RESTR_FLAG_NOPEER
+ NTP_RESTR_FLAG_MSK_NOSERVE = ( 1UL << NTP_RESTR_FLAG_NOSERVE ), ///< see ::NTP_RESTR_FLAG_NOSERVE
+ NTP_RESTR_FLAG_MSK_NOTRAP = ( 1UL << NTP_RESTR_FLAG_NOTRAP ), ///< see ::NTP_RESTR_FLAG_NOTRAP
+ NTP_RESTR_FLAG_MSK_NOTRUST = ( 1UL << NTP_RESTR_FLAG_NOTRUST ), ///< see ::NTP_RESTR_FLAG_NOTRUST
+ NTP_RESTR_FLAG_MSK_NTPPORT = ( 1UL << NTP_RESTR_FLAG_NTPPORT ), ///< see ::NTP_RESTR_FLAG_NTPPORT
+ NTP_RESTR_FLAG_MSK_VERSION = ( 1UL << NTP_RESTR_FLAG_VERSION ), ///< see ::NTP_RESTR_FLAG_VERSION
+ NTP_RESTR_FLAG_MSK_IPV4 = ( 1UL << NTP_RESTR_FLAG_IPV4 ), ///< see ::NTP_RESTR_FLAG_IPV4
+ NTP_RESTR_FLAG_MSK_IPV6 = ( 1UL << NTP_RESTR_FLAG_IPV6 ) ///< see ::NTP_RESTR_FLAG_IPV6
+};
+
+
+
+/**
+ * @brief General NTP restriction limits to be read from a device
+ *
+ * Used to query from a device how many NTP restrictions are supported
+ * by the device, then index 0..::NTP_RESTR_LIMITS::cur_restrs-1
+ * restriction records can be read from a device. A maximum of
+ * ::NTP_RESTR_LIMITS::max_restrs can be configured at all.
+ */
+typedef struct
+{
+ uint16_t max_restrs; ///< Number of maximum supported restrictions
+ uint16_t cur_restrs; ///< Number of currently configured restrictions
+ uint32_t supp_types; ///< Supported restriction types, see ::NTP_RESTR_TYPE_MSKS
+ uint32_t supp_flags; ///< Supported restriction flags, see ::NTP_RESTR_FLAG_MSKS
+ uint32_t reserved; ///< Future use
+
+} NTP_RESTR_LIMITS;
+
+#define _mbg_swab_ntp_restr_limits( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->max_restrs ); \
+ _mbg_swab16( &(_p)->cur_restrs ); \
+ _mbg_swab32( &(_p)->supp_types ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+/**
+ * @brief NTP restriction
+ *
+ * Structure contains all flags and information needed for a valid NTP restriction
+ * as described at ntp.org's manual page.
+ */
+typedef struct
+{
+ uint8_t type; ///< Restriction type, see ::NTP_RESTR_TYPES
+ uint8_t reserved_1; ///< Future use
+ uint16_t reserved_2; ///< Future use
+ uint32_t flags; ///< Restriction flags, see ::NTP_RESTR_FLAG_MSKS
+
+ MBG_HOSTNAME addr; ///< used if ::NTP_RESTR::type == ::NTP_RESTR_TYPE_ADDRESS
+ ///< can contain a hostname, or an IPv4 or IPv6 address
+ ///< with or without CIDR extension (eg. 172.16.0.0/16).
+} NTP_RESTR;
+
+#define _mbg_swab_ntp_restr( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab_ntp_restr_discard( &(_p)->u.discard ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP restriction, plus index
+ *
+ * @see ::NTP_RESTR
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_RESTR restr;
+
+} NTP_RESTR_IDX;
+
+#define _mbg_swab_ntp_restr_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_restr( &(_p)->restr ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief General NTP "discard" rate limiting limits to be read from a device
+ *
+ * Used to query from a device what range of values is supported
+ * for the NTP "discard" rate limiting configuration.
+ */
+typedef struct
+{
+ uint8_t avg_min; ///< Minimum value for avg
+ uint8_t avg_max; ///< Maximum value for avg
+ uint8_t min_min; ///< Minimum value for min
+ uint8_t min_max; ///< Maximum value for min
+ uint16_t monitor_min; ///< Maximum value for min
+ uint16_t monitor_max; ///< Maximum value for min
+
+ uint32_t reserved; ///< Future use
+
+} NTP_DISCARD_LIMITS;
+
+#define _mbg_swab_ntp_discard_limits( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->monitor_min ); \
+ _mbg_swab16( &(_p)->monitor_max ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP "discard" rate limiting settings as described at ntp.org's manual
+ */
+typedef struct
+{
+ uint8_t avg; ///< Specify the minimum average interpacket spacing in log2 s.
+ uint8_t min; ///< Specify the minimum interpacket spacing (guard time) in seconds.
+ uint16_t monitor; ///< ### TODO Which is the unit of this field?
+ uint32_t reserved; ///< Possible future use
+
+} NTP_DISCARD_SETTINGS;
+
+#define _mbg_swab_ntp_discard_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->monitor ); \
+ _mbg_swab32( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of supported refclock types
+ *
+ * Used with ::NTP_REFCLK_CFG_SETTINGS::type
+ *
+ * @see https://www.eecis.udel.edu/~mills/ntp/html/refclock.html
+ * @see ::NTP_REFCLK_TYPE_MSKS
+ */
+enum NTP_REFCLK_TYPES
+{
+ NTP_REFCLK_TYPE_LOCAL, ///< NTP local clock
+ NTP_REFCLK_TYPE_TRUETIME, ///< NTP Truetime driver
+ NTP_REFCLK_TYPE_PARSE, ///< NTP parse driver
+ NTP_REFCLK_TYPE_NMEA, ///< NTP NMEA driver
+ NTP_REFCLK_TYPE_PPS, ///< NTP atom driver (standalone PPS)
+ NTP_REFCLK_TYPE_SHM, ///< NTP shared memory driver
+ N_NTP_REFCLK_TYPES
+};
+
+
+
+/**
+ * @brief Bit masks associated with ::NTP_REFCLK_TYPES
+ *
+ * Used with ::NTP_REFCLK_CFG_INFO::supp_refclk_types
+ *
+ * @see ::NTP_REFCLK_TYPES
+ */
+enum NTP_REFCLK_TYPE_MSKS
+{
+ NTP_REFCLK_TYPE_MSK_LOCAL = ( 1UL << NTP_REFCLK_TYPE_LOCAL ), ///< see ::NTP_REFCLK_TYPE_LOCAL
+ NTP_REFCLK_TYPE_MSK_TRUETIME = ( 1UL << NTP_REFCLK_TYPE_TRUETIME ), ///< see ::NTP_REFCLK_TYPE_TRUETIME
+ NTP_REFCLK_TYPE_MSK_PARSE = ( 1UL << NTP_REFCLK_TYPE_PARSE ), ///< see ::NTP_REFCLK_TYPE_PARSE
+ NTP_REFCLK_TYPE_MSK_NMEA = ( 1UL << NTP_REFCLK_TYPE_NMEA ), ///< see ::NTP_REFCLK_TYPE_NMEA
+ NTP_REFCLK_TYPE_MSK_PPS = ( 1UL << NTP_REFCLK_TYPE_PPS ), ///< see ::NTP_REFCLK_TYPE_PPS
+ NTP_REFCLK_TYPE_MSK_SHM = ( 1UL << NTP_REFCLK_TYPE_SHM ) ///< see ::NTP_REFCLK_TYPE_SHM
+};
+
+
+
+
+
+/**
+ * @brief Numbers related to the "fudge" flags used with ntpd's refclock interface
+ *
+ * Used with ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable
+ * and ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value
+ *
+ * The refclock interface provided by ntpd supports a number of flags
+ * (flag1..flag4) which can be "fudged" in ntp.conf to control specific
+ * features of a particular refclock driver, e.g.:
+ * "fudge 127.127.8.0 flag1 1"
+ *
+ * Which feature is controlled by which flag depends on the refclock
+ * driver type, so usually each flag has a different meaning for
+ * different refclock types.
+ *
+ * There are different cases to be distinguished:
+ *
+ * - if a flag is not specified at all in ntp.conf then
+ * the controlled feature is enabled or disabled
+ * according to the driver's default settings
+ *
+ * - if a flag is specified as '0' or '1' in ntp.conf then
+ * the controlled feature is enabled or disabled
+ * according to the flag's setting.
+ *
+ * Thus, the bit mask in ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable
+ * controls if the associated fudge flag should be specified in ntp.conf,
+ * and if it is specified then the associated bit in
+ * ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value controls if the fudge flag
+ * is set to 0 or 1.
+ *
+ * @anchor NTP_FUDGE_FLAG_NUMBERS @{ */
+
+#define NTP_MIN_REFCLOCK_FUDGE_FLAG 1 ///< minimum refclock fudge flag number, associated with bit 0
+#define N_NTP_REFCLOCK_FUDGE_FLAGS 4 ///< the number of supported fudge flags
+
+/** @} anchor NTP_FUDGE_FLAG_NUMBERS */
+
+
+
+/**
+ * @brief NTP refclock specific settings
+ *
+ * Used to configure a NTP refclock.
+ */
+typedef struct
+{
+ uint8_t type; ///< See ::NTP_REFCLK_TYPES
+ uint8_t instance; ///< Refclock instance of the specified type. Usually up to 4 instances of the same type are supported by ntpd.
+ uint8_t mode; ///< Driver specific "mode" ::FIXME Flag to enable "mode"?
+ int8_t stratum; ///< Stratum number to be fudged; -1 if unspecified and thus default is to be used
+
+ int8_t refid[4]; ///< Reference id used by driver ::FIXME Flag to enable "refid"?
+
+ uint8_t minpoll; ///< Minimum polling interval, [log2 seconds], 0 if unused/unspecified
+ uint8_t maxpoll; ///< Maximum polling interval, [log2 seconds], 0 if unused/unspecified
+ uint8_t reserved_1; ///< Reserved for future use
+ uint8_t reserved_2; ///< Future use
+
+ NANO_TIME_64 time1; ///< Driver specific
+ NANO_TIME_64 time2; ///< Driver specific
+
+ uint16_t drv_flags_enable; ///< Enable/disable driver specific flags, see @ref NTP_FUDGE_FLAG_NUMBERS
+ uint16_t drv_flags_value; ///< 0 or 1, if (drv_flags_enable & x) == 1, see @ref NTP_FUDGE_FLAG_NUMBERS
+
+ uint32_t flags; ///< See @ref NTP_FLAG_MASKS. Only flags specified in ::FIXME can be used here.
+
+ uint32_t reserved_3; ///< Future use
+
+} NTP_REFCLK_CFG_SETTINGS;
+
+#define _mbg_swab_ntp_refclk_cfg_settings( _p ) \
+do \
+{ \
+ _mbg_swab_nano_time_64( &(_p)->time1 ); \
+ _mbg_swab_nano_time_64( &(_p)->time2 ); \
+ _mbg_swab16( &(_p)->drv_flags_enable ); \
+ _mbg_swab16( &(_p)->drv_flags_value ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP refclock settings index
+ *
+ * @see ::NTP_REFCLK_CFG_SETTINGS
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS
+
+} NTP_REFCLK_CFG_SETTINGS_IDX;
+
+#define _mbg_swab_ntp_refclk_cfg_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP refclock configuration and supported refclock types
+ *
+ * This structure can be used to set a NTP refclock's configuration
+ * and get to know its overall supported refclocks.
+ */
+typedef struct
+{
+ NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS
+
+ uint32_t supp_refclk_types; ///< See ::NTP_REFCLK_TYPE_MSKS
+
+} NTP_REFCLK_CFG_INFO;
+
+#define _mbg_swab_ntp_refclk_cfg_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_refclk_types ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP refclock info, with index
+ *
+ * @see ::NTP_REFCLK_CFG_INFO
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_REFCLK_CFG_INFO info;
+
+} NTP_REFCLK_CFG_INFO_IDX;
+
+#define _mbg_swab_ntp_refclk_cfg_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_refclk_cfg_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief Enumeration of NTP supported symmetric key hashing algorithms
+ *
+ * @see ::NTP_SYMM_KEY_HASH_MASKS
+ *
+ * @note Support of external libraries (e.g.: OpenSSL) may be needed for
+ * some hashing algorithms.
+ */
+enum NTP_SYMM_KEY_HASHES
+{
+ NTP_SYMM_KEY_HASH_MD5, ///< NTP supports MD5 as key hashing algorithm
+ NTP_SYMM_KEY_HASH_SHA1, ///< NTP supports SHA1 as key hashing algorithm
+ N_NTP_SYMM_KEY_HASHES
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_SYMM_KEY_HASHES
+ *
+ * @see ::NTP_SYMM_KEY_HASHES
+ */
+enum NTP_SYMM_KEY_HASH_MASKS
+{
+ NTP_SYMM_KEY_HASH_MSK_MD5 = ( 1UL << NTP_SYMM_KEY_HASH_MD5 ), ///< see ::NTP_SYMM_KEY_HASH_MD5
+ NTP_SYMM_KEY_HASH_MSK_SHA1 = ( 1UL << NTP_SYMM_KEY_HASH_SHA1 ), ///< see ::NTP_SYMM_KEY_HASH_SHA1
+};
+
+
+/**
+ * @brief Name strings for defined NTP symm key hashes
+ *
+ * @see ::NTP_SYMM_KEY_HASHES
+ */
+#define NTP_SYMM_KEY_HASHES_STRS \
+{ \
+ "MD5", \
+ "SHA1" \
+}
+
+
+
+/**
+ * @brief General NTP symmetric key limits to be read from a device
+ *
+ * ::NTP_SYMM_KEY_LIMITS::supp_hashes specifies supported hashing algorithms
+ * to create keys with. See ::NTP_SYMM_KEY_HASH_MASKS. Structure can be queried
+ * if ::NTP_MSK_SYMM_KEYS is set in ::NTP_GLB_INFO::supp_flags
+ */
+typedef struct
+{
+ uint16_t supp_hashes; ///< See ::NTP_SYMM_KEY_HASH_MASKS
+ uint16_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+ uint32_t reserved_4; ///< Future use
+
+} NTP_SYMM_KEY_LIMITS;
+
+#define _mbg_swab_ntp_symm_key_limits( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->supp_hashes ); \
+} while ( 0 )
+
+
+
+/// Maximum length of a symmetric key. 128 byte was chosen to be
+/// prepared for hash algorithms like SHA256, SH384, up to SHA512.
+#define N_NTP_SYMM_KEY_LEN 128
+
+/// Maximum number of ip addresses which can be assign to each key in
+/// order to limit usage
+#define N_NTP_SYMM_KEY_MAX_IP_ADDR 8
+
+
+
+/**
+ * @brief NTP symmetric key specific settings
+ *
+ * This structure is used to configure a symmetric key for NTP.
+ */
+typedef struct
+{
+ uint16_t id; ///< Configurable key id (1..65534)
+ uint8_t hash; ///< See ::NTP_SYMM_KEY_HASHES
+ uint8_t reserved_1; ///< Future use
+
+ uint16_t reserved_2; ///< Future use
+ uint8_t num_ip_addr; ///< Number of configured ip addresses
+ uint8_t reserved_3; ///< Future use
+
+ uint8_t key[N_NTP_SYMM_KEY_LEN]; ///< Hashed phrase, see ::N_NTP_SYMM_KEY_LEN
+
+ MBG_IP_ADDR ip_addr[N_NTP_SYMM_KEY_MAX_IP_ADDR]; ///< Whitelist of ip addresses see ::N_NTP_SYMM_KEY_MAX_IP_ADDR
+
+} NTP_SYMM_KEY_SETTINGS;
+
+#define _mbg_swab_ntp_symm_key_settings( _p ) \
+do \
+{ \
+ unsigned i; \
+ \
+ _mbg_swab16( &(_p)->id ); \
+ \
+ for ( i = 0; i < N_NTP_SYMM_KEY_MAX_IP_ADDR; ++i) \
+ _mbg_swab_ip_addr( &(_p)->ip_addr[i] ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP symmetric key settings, with index
+ *
+ * @see ::NTP_SYMM_KEY_SETTINGS
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_SYMM_KEY_SETTINGS settings;
+
+} NTP_SYMM_KEY_SETTINGS_IDX;
+
+#define _mbg_swab_ntp_symm_key_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP symmkey info
+ *
+ * This structure is used to query a symmetric key for NTP.
+ */
+typedef struct
+{
+ NTP_SYMM_KEY_SETTINGS settings;
+
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+ uint32_t reserved_4; ///< Future use
+
+} NTP_SYMM_KEY_INFO;
+
+#define _mbg_swab_ntp_symm_key_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP symm key info, with index
+ *
+ * @see ::NTP_SYMM_KEY_INFO
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_SYMM_KEY_INFO info;
+
+} NTP_SYMM_KEY_INFO_IDX;
+
+#define _mbg_swab_ntp_symm_key_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_symm_key_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP trusted key settings
+ *
+ * This structure is used to configure a trusted symmetric key for NTP.
+ */
+typedef struct
+{
+ uint16_t id; ///< Configurable key id (1..65534)
+ uint16_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+
+} NTP_TRUSTED_KEY_SETTINGS;
+
+#define _mbg_swab_ntp_trusted_key_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->id ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP trusted key settings, with index
+ *
+ * @see ::NTP_TRUSTED_KEY_SETTINGS
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_TRUSTED_KEY_SETTINGS settings;
+
+} NTP_TRUSTED_KEY_SETTINGS_IDX;
+
+#define _mbg_swab_ntp_trusted_key_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \
+} while ( 0 )
+
+/**
+ * @brief NTP trusted key info
+ *
+ * This structure is used to query a trusted symmetric key for NTP.
+ */
+typedef struct
+{
+ NTP_TRUSTED_KEY_SETTINGS settings;
+
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+ uint32_t reserved_4; ///< Future use
+
+} NTP_TRUSTED_KEY_INFO;
+
+#define _mbg_swab_ntp_trusted_key_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP trusted key info, with index
+ *
+ * @see ::NTP_TRUSTED_KEY_INFO
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_TRUSTED_KEY_INFO info;
+
+} NTP_TRUSTED_KEY_INFO_IDX;
+
+#define _mbg_swab_ntp_trusted_key_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_trusted_key_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief Enumeration of NTP supported statistics
+ *
+ * @see ::NTP_GLB_STATS_MASKS
+ */
+enum NTP_GLB_STATS_FLAGS
+{
+ NTP_GLB_STATS_FLAG_ENABLE, ///< NTP stats can generally be enabled or disabled
+ NTP_GLB_STATS_FLAG_CLOCKSTATS, ///< NTP supports clockstats
+ NTP_GLB_STATS_FLAG_CRYPTOSTATS, ///< NTP supports cryptostats
+ NTP_GLB_STATS_FLAG_LOOPSTATS, ///< NTP supports loopstats
+ NTP_GLB_STATS_FLAG_PEERSTATS, ///< NTP supports peerstats
+ NTP_GLB_STATS_FLAG_RAWSTATS, ///< NTP supports rawstats
+ NTP_GLB_STATS_FLAG_SYSSTATS, ///< NTP supports sysstats
+ NTP_GLB_STATS_FLAG_FILEGEN, ///< NTP supports sets of files
+ ///< If flag is set there are structures needed
+ ///< that are not avail right now. Future use
+ N_NTP_GLB_STATS_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_GLB_STATS_FLAGS
+ *
+ * @see ::NTP_GLB_STATS_FLAGS
+ */
+enum NTP_GLB_STATS_MASKS
+{
+ NTP_GLB_STATS_MSK_ENABLE = ( 1UL << NTP_GLB_STATS_FLAG_ENABLE ), ///< See ::NTP_GLB_STATS_FLAG_ENABLE
+ NTP_GLB_STATS_MSK_CLOCKSTATS = ( 1UL << NTP_GLB_STATS_FLAG_CLOCKSTATS ), ///< See ::NTP_GLB_STATS_FLAG_CLOCKSTATS
+ NTP_GLB_STATS_MSK_CRYPTOSTATS = ( 1UL << NTP_GLB_STATS_FLAG_CRYPTOSTATS ), ///< See ::NTP_GLB_STATS_FLAG_CRYPTOSTATS
+ NTP_GLB_STATS_MSK_LOOPSTATS = ( 1UL << NTP_GLB_STATS_FLAG_LOOPSTATS ), ///< See ::NTP_GLB_STATS_FLAG_LOOPSTATS
+ NTP_GLB_STATS_MSK_PEERSTATS = ( 1UL << NTP_GLB_STATS_FLAG_PEERSTATS ), ///< See ::NTP_GLB_STATS_FLAG_PEERSTATS
+ NTP_GLB_STATS_MSK_RAWSTATS = ( 1UL << NTP_GLB_STATS_FLAG_RAWSTATS ), ///< See ::NTP_GLB_STATS_FLAG_RAWSTATS
+ NTP_GLB_STATS_MSK_SYSSTATS = ( 1UL << NTP_GLB_STATS_FLAG_SYSSTATS ), ///< See ::NTP_GLB_STATS_FLAG_SYSSTATS
+ NTP_GLB_STATS_MSK_FILEGEN = ( 1UL << NTP_GLB_STATS_FLAG_FILEGEN ) ///< See ::NTP_GLB_STATS_FLAG_FILEGEN
+};
+
+
+
+/**
+ * @brief Global NTP statistics settings to be read from / written to a device
+ *
+ * ::NTP_GLB_STATS_MSK_ENABLE is the switch to enable / disable statistics in
+ * general. In case the bit is set all other bits stand for special statistic
+ * types that can be enabled or disabled by setting or deleting its specific bit.
+ */
+typedef struct
+{
+ uint32_t flags; ///< See ::NTP_GLB_STATS_MASKS
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+
+} NTP_STATS_GLB_SETTINGS;
+
+#define _mbg_swab_ntp_stats_glb_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP statistics settings
+ *
+ * This structure can be used to determine possible NTP statistic options
+ * and can be queried if ::NTP_MSK_STATISTICS bit is set in ::NTP_GLB_INFO::supp_flags.
+ */
+typedef struct
+{
+ NTP_STATS_GLB_SETTINGS settings; ///< See ::NTP_STATS_GLB_SETTINGS
+
+ uint32_t supp_stats; ///< See ::NTP_GLB_STATS_MASKS
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+
+} NTP_STATS_GLB_INFO;
+
+#define _mbg_swab_ntp_stats_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_stats_glb_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_stats ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of NTP supported (various) misc options
+ *
+ * @see ::NTP_MISC_MSKS
+ */
+enum NTP_MISC_FLAGS
+{
+ NTP_MISC_FLAG_DRIFTFILE, ///< NTP supports driftfile
+ NTP_MISC_FLAG_ORPHAN_MODE, ///< NTP supports orphan mode
+ NTP_MISC_FLAG_LEAPFILE, ///< NTP supports leapfile
+ N_NTP_MISC_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_MISC_FLAGS
+ *
+ * @see ::NTP_MISC_FLAGS
+ */
+enum NTP_MISC_MSKS
+{
+ NTP_MISC_MSK_DRIFTFILE = ( 1UL << NTP_MISC_FLAG_DRIFTFILE ), ///< See ::NTP_MISC_FLAG_DRIFTFILE
+ NTP_MISC_MSK_ORPHAN_MODE = ( 1UL << NTP_MISC_FLAG_ORPHAN_MODE ), ///< See ::NTP_MISC_FLAG_ORPHAN_MODE
+ NTP_MISC_MSK_LEAPFILE = ( 1UL << NTP_MISC_FLAG_LEAPFILE ) ///< See ::NTP_MISC_FLAG_LEAPFILE
+};
+
+
+
+/**
+ * @brief General NTP misc limits to be read from a device
+ *
+ * This structure can be used to determine various NTP options
+ * and can be queried if ::NTP_MSK_MISCELLANEOUS bit is set in ::NTP_GLB_INFO::supp_flags.
+ */
+typedef struct
+{
+ uint32_t supp_flags; ///< See ::NTP_MISC_MSKS
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+
+} NTP_MISC_LIMITS;
+
+#define _mbg_swab_ntp_misc_limits( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief NTP driftfile settings to be read from / written to a device
+ *
+ * If ::NTP_MISC_MSK_DRIFTFILE is set in ::NTP_MISC_LIMITS::supp_flags
+ * ::NTP_MISC_DRIFTFILE_SETTINGS can be read / written.
+ */
+typedef struct
+{
+ uint8_t enable; ///< Enable / disable writing a driftfile
+ uint8_t reserved_1; ///< Future use
+ uint16_t reserved_2; ///< Future use
+
+} NTP_MISC_DRIFTFILE_SETTINGS;
+
+#define _mbg_swab_ntp_misc_driftfile_settings( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+/**
+ * @brief Enumeration of NTP supported (various) misc options
+ *
+ * @see ::NTP_ORPHAN_MODE_MSK
+ */
+enum NTP_ORPHAN_MODE_FLAGS
+{
+ NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE, ///< Orphan Mode support disabling
+
+ N_NTP_ORPHAN_MODE_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks associated with ::NTP_ORPHAN_MODE_FLAGS
+ *
+ * @see ::NTP_ORPHAN_MODE_FLAGS
+ */
+enum NTP_ORPHAN_MODE_MSK
+{
+ NTP_ORPHAN_MODE_MSK_SUPP_DISABLE = ( 1UL << NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE ) ///< See ::NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE
+};
+
+
+/**
+ * @brief NTP orphan mode settings to be read from / written to a device
+ *
+ * If ::NTP_MISC_MSK_ORPHAN_MODE is set in ::NTP_MISC_LIMITS::supp_flags
+ * ::NTP_MISC_ORPHAN_MODE_SETTINGS can be read / written.
+ */
+typedef struct
+{
+ uint8_t enable; ///< Generally enable / disable orphan mode
+ uint8_t mode; ///< Stratum level when no ref source available
+ uint16_t reserved_1; ///< Future use
+
+ uint32_t reserved_2; ///< Future use
+
+} NTP_MISC_ORPHAN_MODE_SETTINGS;
+
+#define _mbg_swab_ntp_misc_orphan_mode_settings( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+/**
+ * @brief NTP orphan mode info
+ *
+ */
+typedef struct
+{
+ NTP_MISC_ORPHAN_MODE_SETTINGS settings; ///< See ::NTP_MISC_ORPHAN_MODE_SETTINGS
+
+ uint32_t supp_flags; ///< See ::NTP_ORPHAN_MODE_MSK
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+
+} NTP_MISC_ORPHAN_MODE_INFO;
+
+#define _mbg_swab_ntp_misc_orphan_mode_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_misc_orphan_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief NTP leapfile settings to be read from / written to a device
+ *
+ * If ::NTP_MISC_MSK_LEAPFILE is set in ::NTP_MISC_LIMITS::supp_flags
+ * ::NTP_MISC_LEAPFILE_SETTINGS can be read / written.
+ */
+typedef struct
+{
+ uint8_t enable; ///< Generally enable / disable leapfile
+ uint8_t reserved_1; ///< Stratum level when no ref source available
+ uint16_t reserved_2; ///< Future use
+
+} NTP_MISC_LEAPFILE_SETTINGS;
+
+#define _mbg_swab_ntp_misc_leapfile_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+#else // !defined( _PRELIMINARY_CODE ), dummy declarations
+
+ typedef int NTP_RESTR_LIMITS;
+ typedef int NTP_RESTR;
+ typedef int NTP_RESTR_IDX;
+ typedef int NTP_DISCARD_LIMITS;
+ typedef int NTP_DISCARD_SETTINGS;
+ typedef int NTP_REFCLK_CFG_SETTINGS;
+ typedef int NTP_REFCLK_CFG_SETTINGS_IDX;
+ typedef int NTP_REFCLK_CFG_INFO;
+ typedef int NTP_REFCLK_CFG_INFO_IDX;
+ typedef int NTP_SYMM_KEY_LIMITS;
+ typedef int NTP_SYMM_KEY_SETTINGS;
+ typedef int NTP_SYMM_KEY_SETTINGS_IDX;
+ typedef int NTP_SYMM_KEY_INFO;
+ typedef int NTP_SYMM_KEY_INFO_IDX;
+ typedef int NTP_TRUSTED_KEY_SETTINGS;
+ typedef int NTP_TRUSTED_KEY_SETTINGS_IDX;
+ typedef int NTP_TRUSTED_KEY_INFO;
+ typedef int NTP_TRUSTED_KEY_INFO_IDX;
+ typedef int NTP_STATS_GLB_SETTINGS;
+ typedef int NTP_STATS_GLB_INFO;
+ typedef int NTP_MISC_LIMITS;
+ typedef int NTP_MISC_DRIFTFILE_SETTINGS;
+ typedef int NTP_MISC_ORPHAN_MODE_SETTINGS;
+ typedef int NTP_MISC_ORPHAN_MODE_INFO;
+ typedef int NTP_MISC_LEAPFILE_SETTINGS;
+
+#endif // defined( _PRELIMINARY_CODE )
+
+
+/**
+ * @brief Client settings of an NTP device
+ *
+ * This structure should be sent to an NTP client to configure client parameters
+ */
+typedef struct
+{
+ uint8_t num_peers; ///< number available peers
+ uint8_t reserved_1; ///< reserved, currently 0
+ uint16_t reserved_2; ///< reserved, currently 0
+
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS
+
+} NTP_CLNT_MODE_SETTINGS;
+
+#define _mbg_swab_ntp_clnt_mode_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Client settings info of an NTP device
+ *
+ * This structure can be used to determine possible NTP client settings and the current configuration
+ */
+typedef struct
+{
+ NTP_CLNT_MODE_SETTINGS settings;
+
+ uint8_t n_supp_peers; ///< maximal number of configurable peers
+ uint8_t n_supp_pref_peers; ///< maximal number of configurable preferred ref sources
+ uint8_t poll_intv_min; ///< minimal supported NTP polling interval
+ uint8_t poll_intv_max; ///< maximal supported NTP polling interval
+
+ uint32_t reserved_1; ///< reserved, currently 0
+ uint32_t reserved_2; ///< reserved, currently 0
+
+ uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS
+ uint32_t supp_peer_flags; ///< supported NTP flags for peers, see @ref NTP_FLAG_MASKS
+
+} NTP_CLNT_MODE_INFO;
+
+#define _mbg_swab_ntp_clnt_mode_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_clnt_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_peer_flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief General NTP peer settings limits to be read from a device
+ *
+ * Used to query from a device how many NTP associations are supported
+ * by the device, then index 0..::NTP_PEER_LIMITS::n_cur_peers-1
+ * peer records can be read from a device. A maximum of
+ * ::NTP_PEER_LIMITS::n_supp_peers can be configured at all.
+ */
+typedef struct
+{
+ uint16_t n_supp_peers; ///< maximum number of configurable peers
+ uint16_t n_cur_peers; ///< current number of configured peers
+
+ uint8_t poll_intv_min; ///< minimum supported NTP polling interval
+ uint8_t poll_intv_max; ///< maximum supported NTP polling interval
+ uint8_t reserved_1; ///< reserved, currently 0
+ uint8_t reserved_2; ///< reserved, currently 0
+
+ uint32_t supp_assoc_types; ///< supported types of NTP associations
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t supp_flags_server; ///< supported flags for unicast associations
+ uint32_t supp_flags_peer; ///< supported flags for unicast symmetric-active assocations
+ uint32_t supp_flags_pool; ///< supported flags for unicast pool associations
+ uint32_t supp_flags_broadcast; ///< supported flags for broadcast associations
+ uint32_t supp_flags_multicast; ///< supported flags for multicast associations
+ uint32_t supp_flags_manycast; ///< supported flags for manycast associations
+ uint32_t supp_flags_broadcastclient; ///< supported flags for broadcast client associations
+ uint32_t supp_flags_multicastclient; ///< supported flags for multicast client associations
+ uint32_t supp_flags_manycastclient; ///< supported flags for manycast client associations
+ uint32_t reserved_4; ///< reserved, currently 0
+ uint32_t reserved_5; ///< reserved, currently 0
+ uint32_t reserved_6; ///< reserved, currently 0
+
+} NTP_PEER_LIMITS;
+
+#define _mbg_swab_ntp_peer_limits( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->n_supp_peers ); \
+ _mbg_swab16( &(_p)->n_cur_peers ); \
+ _mbg_swab32( &(_p)->supp_assoc_types ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->supp_flags_server ); \
+ _mbg_swab32( &(_p)->supp_flags_peer ); \
+ _mbg_swab32( &(_p)->supp_flags_pool ); \
+ _mbg_swab32( &(_p)->supp_flags_broadcast ); \
+ _mbg_swab32( &(_p)->supp_flags_multicast ); \
+ _mbg_swab32( &(_p)->supp_flags_manycast ); \
+ _mbg_swab32( &(_p)->supp_flags_broadcastclient ); \
+ _mbg_swab32( &(_p)->supp_flags_multicastclient ); \
+ _mbg_swab32( &(_p)->supp_flags_manycastclient ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->reserved_5 ); \
+ _mbg_swab32( &(_p)->reserved_6 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Peer settings for NTP devices to configure an upload NTP server
+ *
+ * This structure should be read from the NTP client device to retrieve the
+ * current settings and capabilities. The number of supported peers is
+ * ::NTP_CLNT_MODE_INFO::n_supp_peers.
+ *
+ * @note The ::NTP_PEER_SETTINGS_IDX structure should be send back
+ * to the device to save the configuration.
+ */
+typedef struct
+{
+ MBG_HOSTNAME hostname; ///< hostname or IP address of the peer, not used
+ ///< when the NTP_BROADCASTCLIENT flag is set
+
+ uint8_t min_poll; ///< minimal configurable NTP polling interval
+ uint8_t max_poll; ///< maximal configurable NTP polling interval
+ uint8_t ttl; ///< time-to-live to use with broadcast/multicast/manycast
+ uint8_t reserved_1; ///< reserved, currently 0
+
+ uint32_t key; ///< ID of the symmetric key used with this association,
+ ///< this must be in the range 1-65534, 0 = disabled
+ uint32_t reserved_3; ///< reserved, currently 0
+ uint32_t reserved_4; ///< reserved, currently 0
+
+ uint32_t flags; ///< additional options configured, see @ref NTP_FLAG_MASKS
+
+} NTP_PEER_SETTINGS;
+
+#define _mbg_swab_ntp_peer_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->key ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Peer settings for NTP devices
+ *
+ * @see ::NTP_PEER_SETTINGS
+ */
+typedef struct
+{
+ uint32_t idx;
+ NTP_PEER_SETTINGS peer_settings;
+
+} NTP_PEER_SETTINGS_IDX;
+
+#define _mbg_swab_ntp_peer_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_peer_settings( &(_p)->peer_settings ); \
+} while ( 0 )
+
+
+/**
+ * @brief Server settings of an NTP device
+ *
+ * This structure should be sent to an NTP server to configure server parameters
+ */
+typedef struct
+{
+ uint8_t num_refclks; ///< number of available refclks @ref NTP_REFCLK_CFG_INFO
+ uint8_t reserved_1; ///< reserved, currently 0
+ uint16_t reserved_2; ///< reserved, currently 0
+
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS
+
+} NTP_SRV_MODE_SETTINGS;
+
+#define _mbg_swab_ntp_srv_mode_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Server settings info of an NTP device
+ *
+ * This structure should be used to query an NTP server configuration from a device
+ */
+typedef struct
+{
+ NTP_SRV_MODE_SETTINGS settings;
+
+ uint8_t max_refclks; ///< number of supported refclks @ref NTP_REFCLK_CFG_INFO
+ uint8_t reserved_1; ///< reserved, currently 0
+ uint16_t reserved_2; ///< reserved, currently 0
+
+ uint32_t reserved_3; ///< reserved, currently 0
+
+ uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS
+
+} NTP_SRV_MODE_INFO;
+
+#define _mbg_swab_ntp_srv_mode_info( _p ) \
+do \
+{ \
+ _mbg_swab_ntp_srv_mode_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Structure that represents a timestamp in NTP Short Format
+ *
+ * Maximal value for seconds is 65535.
+ * Resolution of fractions is 15 microseconds.
+ */
+typedef struct
+{
+ uint16_t seconds;
+ uint16_t fractions;
+
+} NTP_SHORT_TSTAMP;
+
+#define _mbg_swab_ntp_short_tstamp( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->seconds ); \
+ _mbg_swab16( &(_p)->fractions ); \
+}
+
+
+
+/**
+ * @brief Structure that represents a timestamp in NTP Timestamp Format
+ */
+typedef struct
+{
+ uint32_t seconds; ///< seconds since NTP epoch, see ::NTP_SEC_BIAS
+ uint32_t fractions; ///< binary fractional part of a second, 0xFFFFFFFF -> 0.9999999... s (resolution 2^-32s =~ 233 ps)
+
+} NTP_TSTAMP;
+
+#define _mbg_swab_ntp_tstamp( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->seconds ); \
+ _mbg_swab32( &(_p)->fractions ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of known NTP implementations
+ *
+ * Used with ::NTP_SYS_STATE::impl_type
+ */
+enum NTP_IMPL
+{
+ NTP_IMPL_UNKNOWN = 0, ///< Unknown NTP implementation
+ NTP_IMPL_NTPD, ///< Network Time Protocol daemon (ntpd)
+ NTP_IMPL_NTPDATE, ///< NTP client only (ntpdate)
+ NTP_IMPL_SNTP, ///< Simple Network Time Protocol (sntp)
+ NTP_IMPL_W32TIME, ///< Windows time service (w32time)
+ NTP_IMPL_MBGNTP, ///< Meinberg NTP implementation (mbgntp)
+ N_NTP_IMPLS
+};
+
+/*
+ * Default initializers for English leapsecond string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_IMPL_STR_ENG "Implemetation Type:"
+
+#define MBG_NTP_IMPL_STR_ENG_UNKNOWN "Unknown NTP implementation"
+#define MBG_NTP_IMPL_STR_ENG_NTPD "Network Time Protocol daemon (ntpd)"
+#define MBG_NTP_IMPL_STR_ENG_NTPDATE "NTP client only (ntpdate)"
+#define MBG_NTP_IMPL_STR_ENG_SNTP "Simple Network Time Protocol (sntp)"
+#define MBG_NTP_IMPL_STR_ENG_W32TIME "Windows time service (w32time)"
+#define MBG_NTP_IMPL_STR_ENG_MBGNTP "Meinberg NTP implementation (mbgntp)"
+
+
+#define MBG_NTP_IMPL_NAMES_ENG \
+{ \
+ MBG_NTP_IMPL_STR_ENG_UNKNOWN, \
+ MBG_NTP_IMPL_STR_ENG_NTPD, \
+ MBG_NTP_IMPL_STR_ENG_NTPDATE, \
+ MBG_NTP_IMPL_STR_ENG_SNTP, \
+ MBG_NTP_IMPL_STR_ENG_W32TIME, \
+ MBG_NTP_IMPL_STR_ENG_MBGNTP \
+}
+
+
+
+/**
+ * @brief Enumeration of CPU types using NTP
+ *
+ * Used with ::NTP_SYS_STATE::cpu_type
+ */
+enum NTP_CPU_TYPES
+{
+ NTP_CPU_TYPE_UNKNOWN = 0,
+ NTP_CPU_TYPE_X86,
+ NTP_CPU_TYPE_I386,
+ NTP_CPU_TYPE_I486,
+ NTP_CPU_TYPE_I586,
+ NTP_CPU_TYPE_I686,
+ NTP_CPU_TYPE_X64,
+ NTP_CPU_TYPE_X86_64,
+ NTP_CPU_TYPE_AMD64,
+ NTP_CPU_TYPE_SUN4U,
+ NTP_CPU_TYPE_ARM,
+ N_NTP_CPU_TYPES
+};
+
+
+
+/**
+ * @brief Name strings for known CPU types using NTP
+ *
+ * @see ::NTP_CPU_TYPES
+ */
+#define NTP_CPU_TYPES_STRS \
+{ \
+ "Unknown", \
+ "x86", \
+ "i386", \
+ "i486", \
+ "i586", \
+ "i686", \
+ "x64", \
+ "x86_64", \
+ "amd64", \
+ "sun4u", \
+ "arm" \
+}
+
+
+
+/**
+ * @brief Enumeration of operating systems using NTP
+ *
+ * Used with ::NTP_SYS_STATE::system
+*/
+enum NTP_SYSTEMS
+{
+ NTP_SYSTEM_UNKNOWN = 0,
+ NTP_SYSTEM_NONE,
+ NTP_SYSTEM_WINDOWS,
+ NTP_SYSTEM_LINUX,
+ NTP_SYSTEM_BSD,
+ NTP_SYSTEM_SOLARIS,
+ N_NTP_SYSTEMS
+};
+
+
+
+/**
+ * @brief Name strings for operating systens using NTP
+ *
+ * @see ::NTP_SYSTEMS
+ */
+#define NTP_SYSTEMS_STRS \
+{ \
+ "Unknown", \
+ "No OS", \
+ "Windows", \
+ "Linux", \
+ "BSD", \
+ "Solaris" \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP leap indication bits
+ *
+ * Used with ::NTP_SYS_STATE::leap_ind
+ *
+ */
+enum NTP_LI_BITS
+{
+ NTP_LEAP_NONE = 0, ///< normal synchronized state
+ NTP_LEAP_ADD_SEC, ///< insert second after 23:59:59 of the current day
+ NTP_LEAP_DEL_SEC, ///< delete second 23:59:59 of the current day
+ NTP_LEAP_ALARM, ///< never synchronized
+ N_NTP_LI_BITS
+};
+
+
+
+/*
+ * Default initializers for English leapsecond string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_LEAP_STR_ENG "Leapsecond indication:"
+
+#define MBG_NTP_LEAP_STR_ENG_NONE "None"
+#define MBG_NTP_LEAP_STR_ENG_ADD_SEC "Insert second"
+#define MBG_NTP_LEAP_STR_ENG_DEL_SEC "Delete second"
+#define MBG_NTP_LEAP_STR_ENG_ALARM "Alarm"
+
+#define MBG_NTP_LEAP_NAMES_ENG \
+{ \
+ MBG_NTP_LEAP_STR_ENG_NONE, \
+ MBG_NTP_LEAP_STR_ENG_ADD_SEC, \
+ MBG_NTP_LEAP_STR_ENG_DEL_SEC, \
+ MBG_NTP_LEAP_STR_ENG_ALARM \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP synchronization source bits
+ *
+ * Used with ::NTP_SYS_STATE::sys_sync_src
+ *
+ */
+enum NTP_SYNC_SRC_BITS
+{
+ NTP_SYNC_SRC_UNSPEC = 0, ///< not yet synchronized
+ NTP_SYNC_SRC_PPS, ///< pulse-per-second signal (Cs, Ru, GPS, etc.)
+ NTP_SYNC_SRC_LF_RADIO, ///< VLF/LF radio (WWVB, DCF77, etc.)
+ NTP_SYNC_SRC_HF_RADIO, ///< MF/HF radio (WWV, etc.)
+ NTP_SYNC_SRC_UHF_RADIO, ///< VHF/UHF radio/satellite (GPS, Galileo, etc.)
+ NTP_SYNC_SRC_LOCAL, ///< local timecode (IRIG, LOCAL driver, etc.)
+ NTP_SYNC_SRC_NTP, ///< NTP
+ NTP_SYNC_SRC_OTHER, ///< other (IEEE 1588, openntp, crony, etc.)
+ NTP_SYNC_SRC_WRISTWATCH, ///< eyeball and wristwatch
+ NTP_SYNC_SRC_TELEPHONE, ///< telephone modem (ACTS, PTB, etc.)
+ N_NTP_SYNC_SRC_BITS
+};
+
+
+
+/*
+ * Default initializers for English sync source string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_SYNC_SRC_STR_ENG_LABEL "Sync Source:"
+
+#define MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC "Not yet synchronized"
+#define MBG_NTP_SYNC_SRC_STR_ENG_PPS "Pulse per second signal"
+#define MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO "VLF/LF radio"
+#define MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO "MF/HF radio"
+#define MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO "VHF/UHF radio/satellite"
+#define MBG_NTP_SYNC_SRC_STR_ENG_LOCAL "local timecode"
+#define MBG_NTP_SYNC_SRC_STR_ENG_NTP "NTP"
+#define MBG_NTP_SYNC_SRC_STR_ENG_OTHER "other"
+#define MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH "eyeball and wristwatch"
+#define MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE "telephone modem"
+
+#define MBG_NTP_SYNC_SRC_NAMES_ENG \
+{ \
+ MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC, \
+ MBG_NTP_SYNC_SRC_STR_ENG_PPS, \
+ MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO, \
+ MBG_NTP_SYNC_SRC_STR_ENG_LOCAL, \
+ MBG_NTP_SYNC_SRC_STR_ENG_NTP, \
+ MBG_NTP_SYNC_SRC_STR_ENG_OTHER, \
+ MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH, \
+ MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP system event message bits
+ *
+ * Used with ::NTP_SYS_STATE::sys_rec_evt
+ *
+ */
+enum NTP_SYS_EVT_BITS
+{
+ NTP_SYS_EVT_UNSPEC = 0, ///< unspecified NTP event
+ NTP_SYS_EVT_FREQ_NOT_SET, ///< frequency file not available
+ NTP_SYS_EVT_FREQ_SET, ///< frequency set from frequency file
+ NTP_SYS_EVT_SPIKE_DETECT, ///< spike detected
+ NTP_SYS_EVT_FREQ_MODE, ///< initial frequency training mode
+ NTP_SYS_EVT_CLOCK_SYNC, ///< clock synchronized
+ NTP_SYS_EVT_RESTART, ///< program restart
+ NTP_SYS_EVT_PANIC_STOP, ///< clock error more than 600 s
+ NTP_SYS_EVT_NO_SYSTEM_PEER, ///< no system peer
+ NTP_SYS_EVT_LEAP_ARMED, ///< leap second armed from file or autokey
+ NTP_SYS_EVT_LEAP_DISARMED, ///< leap second disarmed
+ NTP_SYS_EVT_LEAP_EVENT, ///< leap event
+ NTP_SYS_EVT_CLOCK_STEP, ///< clock stepped
+ NTP_SYS_EVT_KERNEL, ///< kernel information message
+ NTP_SYS_EVT_TAI, ///< leapsecond values update from file
+ NTP_SYS_EVT_STALE_LS_VALUES, ///< new NIST leapseconds file needed
+ N_NTP_SYS_EVT_BITS
+};
+
+
+
+/*
+ * Default initializers for English sync source string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_SYS_EVT_STR_ENG_CNT_LABEL "System Event Counter:"
+#define MBG_NTP_SYS_EVT_STR_ENG_MSG_LABEL "System Event Message:"
+
+#define MBG_NTP_SYS_EVT_STR_ENG_UNSPEC "Unspecified NTP event"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET "Frequency file not available"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET "Frequency set from frequency file"
+#define MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT "Spike detected"
+#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE "Initial frequency training mode"
+#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC "Clock synchronized"
+#define MBG_NTP_SYS_EVT_STR_ENG_RESTART "Program restart"
+#define MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP "Clock error more than 600 s"
+#define MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER "No system peer"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED "Leap second armed from file or autokey"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED "Leap second disarmed"
+#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT "Leap event"
+#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP "Clock stepped"
+#define MBG_NTP_SYS_EVT_STR_ENG_KERNEL "Kernel information message"
+#define MBG_NTP_SYS_EVT_STR_ENG_TAI "Leap second values update from file"
+#define MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES "New NIST leapseconds file needed"
+
+
+#define MBG_NTP_SYS_EVT_NAMES_ENG \
+{ \
+ MBG_NTP_SYS_EVT_STR_ENG_UNSPEC, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET, \
+ MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT, \
+ MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE, \
+ MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC, \
+ MBG_NTP_SYS_EVT_STR_ENG_RESTART, \
+ MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP, \
+ MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED, \
+ MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT, \
+ MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP, \
+ MBG_NTP_SYS_EVT_STR_ENG_KERNEL, \
+ MBG_NTP_SYS_EVT_STR_ENG_TAI, \
+ MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES \
+}
+
+
+
+/**
+ * @brief Enumeration of supported NTP system state values
+ *
+ * @see ::NTP_SYS_STATE_SUPP_FLAG_MASKS
+ */
+enum NTP_SYS_STATE_SUPP_FLAGS
+{
+ NTP_SYS_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_SYS_STATE, all fields except below and reserved
+ NTP_SYS_STATE_SUPP_EVENTS, ///< supports sys state events (::NTP_SYS_STATE::sys_evt_cnt, ::NTP_SYS_STATE::sys_rec_evt)
+ NTP_SYS_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_SYS_STATE::precision
+ NTP_SYS_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_SYS_STATE::root_delay
+ NTP_SYS_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_SYS_STATE::root_disp
+ NTP_SYS_STATE_SUPP_FREQ, ///< supports frequency offset, see ::NTP_SYS_STATE::freq
+ NTP_SYS_STATE_SUPP_SYS_JITTER, ///< supports combined jitter, see ::NTP_SYS_STATE::sys_jitter
+ NTP_SYS_STATE_SUPP_CLK_JITTER, ///< supports clock jitter, see ::NTP_SYS_STATE::clk_jitter
+ NTP_SYS_STATE_SUPP_CLK_WANDER, ///< supports clock wander, see ::NTP_SYS_STATE::clk_wander
+ NTP_SYS_STATE_SUPP_SYS_ASSOC, ///< supports sys assoc ID as sys peer, see ::NTP_SYS_STATE::sys_assoc
+ N_NTP_SYS_STATE_SUPP_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks for NTP_SYS_STATE_SUPP_FLAGS
+ *
+ * Used with ::NTP_SYS_STATE::supp_flags
+ *
+ * @see ::NTP_SYS_STATE_SUPP_FLAGS
+ */
+enum NTP_SYS_STATE_SUPP_FLAG_MASKS
+{
+ NTP_SYS_STATE_SUPP_STD_MSK = ( 1UL << NTP_SYS_STATE_SUPP_STD ), ///< see ::NTP_SYS_STATE_SUPP_STD
+ NTP_SYS_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_SYS_STATE_SUPP_EVENTS ), ///< see ::NTP_SYS_STATE_SUPP_EVENTS
+ NTP_SYS_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_SYS_STATE_SUPP_PRECISION ), ///< see ::NTP_SYS_STATE_SUPP_PRECISION
+ NTP_SYS_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DELAY
+ NTP_SYS_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DISP
+ NTP_SYS_STATE_SUPP_FREQ_MSK = ( 1UL << NTP_SYS_STATE_SUPP_FREQ ), ///< see ::NTP_SYS_STATE_SUPP_FREQ
+ NTP_SYS_STATE_SUPP_SYS_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_SYS_JITTER
+ NTP_SYS_STATE_SUPP_CLK_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_JITTER
+ NTP_SYS_STATE_SUPP_CLK_WANDER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_WANDER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_WANDER
+ NTP_SYS_STATE_SUPP_SYS_ASSOC_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_ASSOC ) ///< see ::NTP_SYS_STATE_SUPP_SYS_ASSOC
+};
+
+
+
+/**
+ * @brief Structure that represents the current system status of an NTP device
+ *
+ * This structure can be requested from a monitoring program to determine the device system status
+ */
+typedef struct
+{
+ uint32_t supp_flags; ///< Supported NTP system state values, see ::NTP_SYS_STATE_SUPP_FLAG_MASKS
+
+ uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS
+ uint8_t sys_sync_src; ///< Current synchronization source, see ::NTP_SYNC_SRC_BITS
+ uint8_t sys_evt_cnt; ///< Number of events, since the last time the event code changed
+ uint8_t sys_rec_evt; ///< Most recent event message, see ::NTP_SYS_EVT_BITS
+
+ uint8_t impl_type; ///< NTP implementation type, see ::NTP_IMPL
+ uint8_t major_version; ///< Major version number
+ uint8_t minor_version; ///< Minor version number
+ uint8_t micro_version; ///< Micro version number
+
+ uint16_t patch_lvl; ///< Patch level number
+ uint8_t cpu_type; ///< Processor type, see ::NTP_CPU_TYPES
+ uint8_t system; ///< Operating system, see ::NTP_SYSTEMS
+
+ uint8_t stratum; ///< Current stratum level of the system
+ int8_t precision; ///< Precision of the system clock (2^precision)
+ uint16_t sys_assoc; ///< Association ID of the current system peer, do not use NTP_SYS_STATE::sys_peer if this is supported
+
+ int32_t root_delay; ///< [us] Total roundtrip delay to the system peer
+ int32_t root_disp; ///< [us] Total dispersion to the system peer
+
+ MBG_IP_ADDR ref_id; ///< Reference ID of the current system peer, see ::MBG_IP_ADDR
+
+ NTP_TSTAMP ref_time; ///< Last time the system time has been adjusted, see ::NTP_TSTAMP
+ NTP_TSTAMP sys_time; ///< Current system time, see ::NTP_TSTAMP
+
+ uint16_t sys_peer; ///< Index of the current system peer
+ uint8_t poll; ///< Current polling interval for the system peer (tc)
+ uint8_t minpoll; ///< Minimal polling interval for the system peer (mintc)
+
+ int64_t offset; ///< [ns] Combined offset to the system peer
+
+ int32_t freq; ///< [ppb] Frequency offset relative to hardware clock
+ int32_t sys_jitter; ///< [us] Combined jitter of the system
+ int32_t clk_jitter; ///< [us] Jitter of the clock
+ int32_t clk_wander; ///< [ppb] Frequency wander of the clock
+
+ uint8_t cfg_counter; ///< Updated (increased) when config changes
+ uint8_t reserved_1; ///< Reserved, currently always 0
+ uint16_t reserved_2; ///< Reserved, currently always 0
+
+ uint32_t reserved_3; ///< Reserved, currently always 0
+
+} NTP_SYS_STATE;
+
+#define _mbg_swab_ntp_sys_state( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ \
+ _mbg_swab8( &(_p)->leap_ind ); \
+ _mbg_swab8( &(_p)->sys_sync_src ); \
+ _mbg_swab8( &(_p)->sys_evt_cnt ); \
+ _mbg_swab8( &(_p)->sys_rec_evt ); \
+ \
+ _mbg_swab8( &(_p)->impl_type ); \
+ _mbg_swab8( &(_p)->major_version ); \
+ _mbg_swab8( &(_p)->minor_version ); \
+ _mbg_swab8( &(_p)->micro_version ); \
+ \
+ _mbg_swab16( &(_p)->patch_lvl ); \
+ _mbg_swab8( &(_p)->cpu_type ); \
+ _mbg_swab8( &(_p)->system ); \
+ \
+ _mbg_swab8( &(_p)->stratum ); \
+ _mbg_swab8( &(_p)->precision ); \
+ _mbg_swab16( &(_p)->sys_assoc ); \
+ \
+ _mbg_swab32( &(_p)->root_delay ); \
+ _mbg_swab32( &(_p)->root_disp ); \
+ \
+ _mbg_swab_ip_addr( &(_p)->ref_id ); \
+ \
+ _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \
+ _mbg_swab_ntp_tstamp( &(_p)->sys_time ); \
+ \
+ _mbg_swab16( &(_p)->sys_peer ); \
+ _mbg_swab8( &(_p)->poll ); \
+ _mbg_swab8( &(_p)->minpoll ); \
+ \
+ _mbg_swab64( &(_p)->offset ); \
+ \
+ _mbg_swab32( &(_p)->freq ); \
+ _mbg_swab32( &(_p)->sys_jitter ); \
+ _mbg_swab32( &(_p)->clk_jitter ); \
+ _mbg_swab32( &(_p)->clk_wander ); \
+ \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of NTP mode bits
+ *
+ * Used with ::NTP_PEER_STATE::host_mode and ::NTP_PEER_STATE::peer_mode
+ *
+ */
+enum NTP_MODE_BITS
+{
+ NTP_MODE_RESERVED = 0,
+ NTP_MODE_SYMM_ACT,
+ NTP_MODE_SYMM_PASS,
+ NTP_MODE_CLIENT,
+ NTP_MODE_SERVER,
+ NTP_MODE_BROADCAST,
+ NTP_MODE_CONTROL,
+ NTP_MODE_PRIVATE,
+ N_NTP_MODE_BITS
+};
+
+
+
+/*
+ * Default initializers for English NTP peer mode string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_MODE_STR_ENG_HOST_LABEL "Host Mode:"
+#define MBG_NTP_MODE_STR_ENG_PEER_LABEL "Peer Mode:"
+
+#define MBG_NTP_PEER_MODE_STR_ENG_RESERVED "Reserved"
+#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT "Symm Act"
+#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS "Symm Pass"
+#define MBG_NTP_PEER_MODE_STR_ENG_CLIENT "Client"
+#define MBG_NTP_PEER_MODE_STR_ENG_SERVER "Server"
+#define MBG_NTP_PEER_MODE_STR_ENG_BROADCAST "Broadcast"
+#define MBG_NTP_PEER_MODE_STR_ENG_CONTROL "Control"
+#define MBG_NTP_PEER_MODE_STR_ENG_PRIVATE "Private"
+
+#define MBG_NTP_MODE_STAT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_MODE_STR_ENG_RESERVED, \
+ MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT, \
+ MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS, \
+ MBG_NTP_PEER_MODE_STR_ENG_CLIENT, \
+ MBG_NTP_PEER_MODE_STR_ENG_SERVER, \
+ MBG_NTP_PEER_MODE_STR_ENG_BROADCAST, \
+ MBG_NTP_PEER_MODE_STR_ENG_CONTROL, \
+ MBG_NTP_PEER_MODE_STR_ENG_PRIVATE \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP peer reach status
+ *
+ * Used with ::NTP_PEER_STATE::peer_reach_stat
+ */
+enum NTP_REACH_STAT_BITS
+{
+ NTP_REACH_STAT_UNKNOWN = 0, ///< unknown reach status
+ NTP_REACH_STAT_NO_LINK, ///< no network connection
+ NTP_REACH_STAT_DNS_UNREACH, ///< DNS server could not be reached
+ NTP_REACH_STAT_DNS_UNRESOLVED, ///< DNS name could not be resolved
+ NTP_REACH_STAT_PEER_UNREACH, ///< peer could not be reached
+ NTP_REACH_STAT_PEER_NOT_SYNC, ///< peer is not sync (leap alarm, stratum 16)
+ NTP_REACH_STAT_PEER_BAD_QUALITY, ///< peer has bad quality (dispersion, ...)
+ NTP_REACH_STAT_OK, ///< reach status is fine
+ N_NTP_REACH_STAT_BITS
+};
+
+
+
+/*
+ * Default initializers for English reach status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_LABEL "Reach State:"
+
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN "Unknown"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK "No link"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH "DNS Server unreached"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED "DNS name not resolved"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH "Peer not reached"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC "Peer not sync"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY "Peer has bad quality"
+#define MBG_NTP_PEER_REACH_STAT_STR_ENG_OK "Good"
+
+#define MBG_NTP_PEER_REACH_STAT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY, \
+ MBG_NTP_PEER_REACH_STAT_STR_ENG_OK \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP peer selection status
+ *
+ * Used with ::NTP_PEER_STATE::peer_sel_stat
+ *
+ */
+enum NTP_PEER_SEL_STATUS_BITS
+{
+ NTP_PEER_SEL_REJECT = 0, ///< discarded as not valid (TEST10-TEST13)
+ NTP_PEER_SEL_FALSETICK, ///< discarded by intersection algorithm
+ NTP_PEER_SEL_EXCESS, ///< discarded by table overflow (not used)
+ NTP_PEER_SEL_OUTLYER, ///< discarded by the cluster algorithm
+ NTP_PEER_SEL_CANDIDATE, ///< included by the combine algorithm
+ NTP_PEER_SEL_BACKUP, ///< backup (more than tos maxclock sources)
+ NTP_PEER_SEL_SYS_PEER, ///< system peer
+ NTP_PEER_SEL_PPS_PEER, ///< PPS peer (when the prefer peer is valid)
+ N_NTP_PEER_SEL_STATUS_BITS
+};
+
+
+
+/*
+ * Default initializers for English peer select status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_LABEL "Selected Status:"
+
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT "Not valid"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK "Falsetick"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS "Excess"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER "Outlyer"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE "Candidate"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP "Backup"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER "System Peer"
+#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER "PPS Peer"
+
+#define MBG_NTP_PEER_SEL_STATUS_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER, \
+ MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP peer status codes
+ *
+ * @see ::NTP_PEER_STATUS_FLAG_MASKS
+ *
+ */
+enum NTP_PEER_STATUS_FLAGS
+{
+ NTP_PEER_STATUS_BCST = 0, ///< broadcast association
+ NTP_PEER_STATUS_REACH, ///< host reachable
+ NTP_PEER_STATUS_AUTHENB, ///< authentication enabled
+ NTP_PEER_STATUS_AUTH, ///< authentication ok
+ NTP_PEER_STATUS_CONFIG, ///< persistent association
+ N_NTP_PEER_STATUS_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for NTP_PEER_STATUS_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::peer_status_flags
+ *
+ * @see ::NTP_PEER_STATUS_FLAGS
+ */
+enum NTP_PEER_STATUS_FLAG_MASKS
+{
+ NTP_PEER_STATUS_BCST_MSK = ( 1UL << NTP_PEER_STATUS_BCST ), ///< see ::NTP_PEER_STATUS_BCST
+ NTP_PEER_STATUS_REACH_MSK = ( 1UL << NTP_PEER_STATUS_REACH ), ///< see ::NTP_PEER_STATUS_REACH
+ NTP_PEER_STATUS_AUTHENB_MSK = ( 1UL << NTP_PEER_STATUS_AUTHENB ), ///< see ::NTP_PEER_STATUS_AUTHENB
+ NTP_PEER_STATUS_AUTH_MSK = ( 1UL << NTP_PEER_STATUS_AUTH ), ///< see ::NTP_PEER_STATUS_AUTH
+ NTP_PEER_STATUS_CONFIG_MSK = ( 1UL << NTP_PEER_STATUS_CONFIG ), ///< see ::NTP_PEER_STATUS_CONFIG
+};
+
+
+/*
+ * Default initializers for English peer status string names. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_STATUS_STR_ENG_LABEL "Peer Status:"
+
+#define MBG_NTP_PEER_STATUS_STR_ENG_BCST "Broadcast association"
+#define MBG_NTP_PEER_STATUS_STR_ENG_REACH "Host reachable"
+#define MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB "Authentication enabled"
+#define MBG_NTP_PEER_STATUS_STR_ENG_CONFIG "Persistant assosiation"
+
+#define MBG_NTP_PEER_STATUS_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_STATUS_STR_ENG_BCST, \
+ MBG_NTP_PEER_STATUS_STR_ENG_REACH, \
+ MBG_NTP_PEER_STATUS_STR_ENG_REACH, \
+ MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB, \
+ MBG_NTP_PEER_STATUS_STR_ENG_CONFIG \
+}
+
+
+
+/**
+ * @brief Enumeration of NTP peer event message codes
+ *
+ * Used with ::NTP_PEER_STATE::peer_rec_evt
+ *
+ */
+enum NTP_PEER_EVT_BITS
+{
+ NTP_PEER_EVT_UNSPEC = 0, ///< unspecified NTP event
+ NTP_PEER_EVT_MOBILIZE, ///< association mobilized
+ NTP_PEER_EVT_DEMOBILIZE, ///< association demobilized
+ NTP_PEER_EVT_UNREACHABLE, ///< server unreachable
+ NTP_PEER_EVT_REACHABLE, ///< server reachable
+ NTP_PEER_EVT_RESTART, ///< association restart
+ NTP_PEER_EVT_NO_REPLY, ///< no server found (ntpdate mode)
+ NTP_PEER_EVT_RATE_EXCEEDED, ///< rate exceeded (kiss code RATE)
+ NTP_PEER_EVT_ACCESS_DENIED, ///< access denied (kiss code DENY)
+ NTP_PEER_EVT_LEAP_ARMED, ///< leap armed from server LI code
+ NTP_PEER_EVT_SYS_PEER, ///< become system peer
+ NTP_PEER_EVT_CLOCK_EVENT, ///< see clock status word
+ NTP_PEER_EVT_BAD_AUTH, ///< authentication failure
+ NTP_PEER_EVT_POPCORN, ///< popcorn spike suppressor
+ NTP_PEER_EVT_INTERLEAVE_MODE, ///< entering interleave mode
+ NTP_PEER_EVT_INTERLEAVE_ERROR, ///< interleave error (recovered)
+ N_NTP_PEER_EVT_BITS
+};
+
+
+
+/*
+ * Default initializers for English event message codes. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_PEER_EVT_STR_ENG_CNT_LABEL "Peer Event Counter:"
+#define MBG_NTP_PEER_EVT_STR_ENG_MSG_LABEL "Peer Event Message:"
+
+#define MBG_NTP_PEER_EVT_STR_ENG_UNSPEC "Unspecified NTP event"
+#define MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE "Association mobilized"
+#define MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE "Association demobilized"
+#define MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE "Server unreachable"
+#define MBG_NTP_PEER_EVT_STR_ENG_REACHABLE "Server reachable"
+#define MBG_NTP_PEER_EVT_STR_ENG_RESTART "Association restart"
+#define MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY "No server found"
+#define MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED "Rate exceeded"
+#define MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED "Access denied"
+#define MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED "Leap second armed from LI code"
+#define MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER "Become system Peer"
+#define MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT "Clock event"
+#define MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH "Authentication failure"
+#define MBG_NTP_PEER_EVT_STR_ENG_POPCORN "Popcorn Spike suspressor"
+#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE "Entering Interleave mode"
+#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR "Interleave error"
+
+
+#define MBG_NTP_PEER_EVT_NAMES_ENG \
+{ \
+ MBG_NTP_PEER_EVT_STR_ENG_UNSPEC, \
+ MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE, \
+ MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE, \
+ MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE, \
+ MBG_NTP_PEER_EVT_STR_ENG_REACHABLE, \
+ MBG_NTP_PEER_EVT_STR_ENG_RESTART, \
+ MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY, \
+ MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED, \
+ MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED, \
+ MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED, \
+ MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER, \
+ MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT, \
+ MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH, \
+ MBG_NTP_PEER_EVT_STR_ENG_POPCORN, \
+ MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE, \
+ MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR \
+}
+
+
+/**
+ * @brief Enumeration of NTP flash status bit codes
+ *
+ * @see ::NTP_FLASH_STAT_FLAG_MASKS
+ *
+ */
+enum NTP_FLASH_STAT_FLAGS
+{
+ NTP_FLASH_STAT_PKT_DUP = 0, ///< duplicate packet
+ NTP_FLASH_STAT_PKT_BOGUS, ///< bogus packet
+ NTP_FLASH_STAT_PKT_UNSYNC, ///< server not synchronized
+ NTP_FLASH_STAT_PKT_DENIED, ///< access denied
+ NTP_FLASH_STAT_PKT_AUTH, ///< authentication failure
+ NTP_FLASH_STAT_PKT_STRATUM, ///< invalid leap or stratum
+ NTP_FLASH_STAT_PKT_HEADER, ///< header distance exceeded
+ NTP_FLASH_STAT_PKT_AUTOKEY, ///< Autokey sequence error
+ NTP_FLASH_STAT_PKT_CRYPTO, ///< Autokey protocol error
+ NTP_FLASH_STAT_PEER_STRATUM, ///< invalid header or stratum
+ NTP_FLASH_STAT_PEER_DIST, ///< distance threshold exceeded
+ NTP_FLASH_STAT_PEER_LOOP, ///< synchronization loop
+ NTP_FLASH_STAT_PEER_UNREACH, ///< unreachable or nonselect
+ N_NTP_FLASH_STAT_FLAGS
+};
+
+
+
+/**
+ * @brief Flag masks for ::NTP_FLASH_STAT_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::flash_stat_flags
+ *
+ * @see ::NTP_FLASH_STAT_FLAGS
+ */
+enum NTP_FLASH_STAT_FLAG_MASKS
+{
+ NTP_FLASH_STAT_PKT_DUP_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DUP ), ///< see ::NTP_FLASH_STAT_PKT_DUP
+ NTP_FLASH_STAT_PKT_BOGUS_MSK = ( 1UL << NTP_FLASH_STAT_PKT_BOGUS ), ///< see ::NTP_FLASH_STAT_PKT_BOGUS
+ NTP_FLASH_STAT_PKT_UNSYNC_MSK = ( 1UL << NTP_FLASH_STAT_PKT_UNSYNC ), ///< see ::NTP_FLASH_STAT_PKT_UNSYNC
+ NTP_FLASH_STAT_PKT_DENIED_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DENIED ), ///< see ::NTP_FLASH_STAT_PKT_DENIED
+ NTP_FLASH_STAT_PKT_AUTH_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTH ), ///< see ::NTP_FLASH_STAT_PKT_AUTH
+ NTP_FLASH_STAT_PKT_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PKT_STRATUM ), ///< see ::NTP_FLASH_STAT_PKT_STRATUM
+ NTP_FLASH_STAT_PKT_HEADER_MSK = ( 1UL << NTP_FLASH_STAT_PKT_HEADER ), ///< see ::NTP_FLASH_STAT_PKT_HEADER
+ NTP_FLASH_STAT_PKT_AUTOKEY_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTOKEY ), ///< see ::NTP_FLASH_STAT_PKT_AUTOKEY
+ NTP_FLASH_STAT_PKT_CRYPTO_MSK = ( 1UL << NTP_FLASH_STAT_PKT_CRYPTO ), ///< see ::NTP_FLASH_STAT_PKT_CRYPTO
+ NTP_FLASH_STAT_PEER_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PEER_STRATUM ), ///< see ::NTP_FLASH_STAT_PEER_STRATUM
+ NTP_FLASH_STAT_PEER_DIST_MSK = ( 1UL << NTP_FLASH_STAT_PEER_DIST ), ///< see ::NTP_FLASH_STAT_PEER_DIST
+ NTP_FLASH_STAT_PEER_LOOP_MSK = ( 1UL << NTP_FLASH_STAT_PEER_LOOP ), ///< see ::NTP_FLASH_STAT_PEER_LOOP
+ NTP_FLASH_STAT_PEER_UNREACH_MSK = ( 1UL << NTP_FLASH_STAT_PEER_UNREACH ), ///< see ::NTP_FLASH_STAT_PEER_UNREACH
+};
- 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;
+
+/*
+ * Default initializers for English ntp flash state mask. Initializers
+ * for multi-language strings can be found in tmonlstr.h.
+ */
+#define MBG_NTP_FLASH_STR_ENG_LABEL "Flash Status:"
+
+#define MBG_NTP_FLASH_STR_ENG_PKT_DUP "Duplicate packet"
+#define MBG_NTP_FLASH_STR_ENG_PKT_BOGUS "Bogus packet"
+#define MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC "Server not synchronized"
+#define MBG_NTP_FLASH_STR_ENG_PKT_DENIED "Access denied"
+#define MBG_NTP_FLASH_STR_ENG_PKT_AUTH "Authentication failure"
+#define MBG_NTP_FLASH_STR_ENG_PKT_STRATUM "Invalid leap or stratum"
+#define MBG_NTP_FLASH_STR_ENG_PKT_HEADER "Header distance exceeded"
+#define MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY "Autokey sequence error"
+#define MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO "Autokey protocol error"
+#define MBG_NTP_FLASH_STR_ENG_PEER_STRATUM "Invalid header or stratum"
+#define MBG_NTP_FLASH_STR_ENG_PEER_DIST "Distance threshold exceeded"
+#define MBG_NTP_FLASH_STR_ENG_PEER_LOOP "Synchronization loop"
+#define MBG_NTP_FLASH_STR_ENG_PEER_UNREACH "Unreachable or nonselect"
+
+
+#define MBG_NTP_FLASH_NAMES_ENG \
+{ \
+ MBG_NTP_FLASH_STR_ENG_PKT_DUP, \
+ MBG_NTP_FLASH_STR_ENG_PKT_BOGUS, \
+ MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC, \
+ MBG_NTP_FLASH_STR_ENG_PKT_DENIED, \
+ MBG_NTP_FLASH_STR_ENG_PKT_AUTH, \
+ MBG_NTP_FLASH_STR_ENG_PKT_STRATUM, \
+ MBG_NTP_FLASH_STR_ENG_PKT_HEADER, \
+ MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY, \
+ MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO, \
+ MBG_NTP_FLASH_STR_ENG_PEER_STRATUM, \
+ MBG_NTP_FLASH_STR_ENG_PEER_DIST, \
+ MBG_NTP_FLASH_STR_ENG_PEER_LOOP, \
+ MBG_NTP_FLASH_STR_ENG_PEER_UNREACH \
+}
+
+
+
+/**
+ * @brief Enumeration of supported NTP peer state values
+ *
+ * @see ::NTP_PEER_STATE_SUPP_FLAG_MASKS
+ */
+enum NTP_PEER_STATE_SUPP_FLAGS
+{
+ NTP_PEER_STATE_SUPP_STD, ///< supports standard values of ::NTP_PEER_STATE, all fields except below and reserved
+ NTP_PEER_STATE_SUPP_ASS_ID, ///< supports association ID, see ::NTP_PEER_STATE::ass_id
+ NTP_PEER_STATE_SUPP_EVENTS, ///< supports peer state events (NTP_PEER_STATE::peer_evt_cnt, NTP_PEER_STATE::peer_rec_evt)
+ NTP_PEER_STATE_SUPP_REACH_STAT, ///< supports peer reach status, see ::NTP_PEER_STATE::peer_reach_stat
+ NTP_PEER_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_PEER_STATE::precision
+ NTP_PEER_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_PEER_STATE::root_delay
+ NTP_PEER_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_PEER_STATE::root_disp
+ NTP_PEER_STATE_SUPP_HEADWAY, ///< supports headway, see ::NTP_PEER_STATE::headway
+ NTP_PEER_STATE_SUPP_FLASH_STAT, ///< supports flash status word, see ::NTP_PEER_STATE::flash_stat_flags
+ NTP_PEER_STATE_SUPP_KEY_ID, ///< supports symmetric key id, see ::NTP_PEER_STATE::key_id
+ NTP_PEER_STATE_SUPP_DISP, ///< supports filter dispersion, see ::NTP_PEER_STATE::disp
+ NTP_PEER_STATE_SUPP_JITTER, ///< supports filter jitter, see ::NTP_PEER_STATE::jitter
+ NTP_PEER_STATE_SUPP_XLEAVE, ///< supports interleave delay, see ::NTP_PEER_STATE::xleave
+ N_NTP_PEER_STATE_SUPP_FLAGS
+};
+
+
+/**
+ * @brief Flag masks for NTP_PEER_STATE_SUPP_FLAGS
+ *
+ * Used with ::NTP_PEER_STATE::supp_flags
+ *
+ * @see ::NTP_PEER_STATE_SUPP_FLAGS
+ */
+enum NTP_PEER_STATE_SUPP_FLAG_MASKS
+{
+ NTP_PEER_STATE_SUPP_STD_MSK = ( 1UL << NTP_PEER_STATE_SUPP_STD ), ///< see ::NTP_PEER_STATE_SUPP_STD
+ NTP_PEER_STATE_SUPP_ASS_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ASS_ID ), ///< see ::NTP_PEER_STATE_SUPP_ASS_ID
+ NTP_PEER_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_PEER_STATE_SUPP_EVENTS ), ///< see ::NTP_PEER_STATE_SUPP_EVENTS
+ NTP_PEER_STATE_SUPP_REACH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_REACH_STAT ), ///< see ::NTP_PEER_STATE_SUPP_REACH_STAT
+ NTP_PEER_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_PEER_STATE_SUPP_PRECISION ), ///< see ::NTP_PEER_STATE_SUPP_PRECISION
+ NTP_PEER_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_PEER_STATE_SUPP_ROOT_DELAY
+ NTP_PEER_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_PEER_STATE_SUPP_ROOT_DISP
+ NTP_PEER_STATE_SUPP_HEADWAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_HEADWAY ), ///< see ::NTP_PEER_STATE_SUPP_HEADWAY
+ NTP_PEER_STATE_SUPP_FLASH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_FLASH_STAT ), ///< see ::NTP_PEER_STATE_SUPP_FLASH_STAT
+ NTP_PEER_STATE_SUPP_KEY_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_KEY_ID ), ///< see ::NTP_PEER_STATE_SUPP_KEY_ID
+ NTP_PEER_STATE_SUPP_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_DISP ), ///< see ::NTP_PEER_STATE_SUPP_DISP
+ NTP_PEER_STATE_SUPP_JITTER_MSK = ( 1UL << NTP_PEER_STATE_SUPP_JITTER ), ///< see ::NTP_PEER_STATE_SUPP_JITTER
+ NTP_PEER_STATE_SUPP_XLEAVE_MSK = ( 1UL << NTP_PEER_STATE_SUPP_XLEAVE ), ///< see ::NTP_PEER_STATE_SUPP_XLEAVE
+};
+
+
+
+/**
+ * @brief Structure that represents the status of an NTP peer
+ *
+ * This structure should be requested via ::NTP_PEER_STATE_IDX
+ *
+ * @see ::NTP_PEER_STATE_IDX
+ */
+typedef struct
+{
+ uint32_t supp_flags; ///< Supported NTP peer state values, see ::NTP_PEER_STATE_SUPP_FLAG_MASKS
+
+ uint16_t ass_id; ///< Association ID of the peer
+ uint16_t peer_status_flags; ///< Peer status flags, see ::NTP_PEER_STATUS_FLAG_MASKS
+
+ uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS
+ uint8_t peer_sel_stat; ///< Current selection status of the peer, see ::NTP_PEER_SEL_STATUS_BITS
+ uint8_t peer_evt_cnt; ///< Number of events, since the last time the event code changed
+ uint8_t peer_rec_evt; ///< Most recent event message, see ::NTP_PEER_EVT_BITS
+
+ uint8_t peer_reach_stat; ///< Current reach status of the peer, see ::NTP_REACH_STAT_BITS
+ uint8_t reserved_1; ///< Reserved, currently always 0
+ uint16_t reserved_2; ///< Reserved, currently always 0
+
+ MBG_IP_ADDR_PORT src_addr; ///< Source address of the NTP peer, see ::MBG_IP_ADDR_PORT
+ MBG_IP_ADDR_PORT dst_addr; ///< Destination address of the NTP peer, see ::MBG_IP_ADDR_PORT
+
+ uint8_t stratum; ///< Current stratum level of the NTP peer
+ int8_t precision; ///< Precision of the peer clock (2^precision)
+ uint16_t reserved_3; ///< Reserved, currently always 0
+
+ int32_t root_delay; ///< [us] Total roundtrip delay to the system peer of the NTP peer
+ int32_t root_disp; ///< [us] Total dispersion to the system peer of the NTP peer
+
+ MBG_IP_ADDR ref_id; ///< Reference ID of the NTP peer, see ::MBG_IP_ADDR
+
+ NTP_TSTAMP ref_time; ///< Last time the NTP peers time has been adjusted, see ::NTP_TSTAMP
+ NTP_TSTAMP rec_time; ///< Current system time of the NTP peer, see ::NTP_TSTAMP
+
+ uint8_t reach; ///< Shift register for the last 8 polling intervals
+ uint8_t reserved_4; ///< Reserved, currently always 0
+ uint16_t unreach; ///< Counter for the number of unsuccessful polling intervals
+
+ uint8_t host_mode; ///< NTP mode of the requesting host, see ::NTP_MODE_BITS
+ uint8_t peer_mode; ///< NTP mode of the peer, see ::NTP_MODE_BITS
+ uint8_t host_poll; ///< Host NTP polling interval
+ uint8_t peer_poll; ///< Peer NTP polling interval
+
+ uint8_t headway; ///< Indicator for the KoD packet, TODO: further investigation
+ uint8_t reserved_5; ///< Reserved, currently always 0
+ uint16_t flash_stat_flags; ///< Flash status flags, see ::NTP_FLASH_STAT_FLAG_MASKS
+
+ uint16_t key_id; ///< ID of symmetric authentication key
+ uint16_t reserved_6; ///< Reserved, currently always 0
+
+ int64_t offset; ///< [ns] filter offset to this NTP peer
+ int64_t delay; ///< [ns] filter delay to this NTP peer
+
+ int32_t disp; ///< [us] filter dispersion of the NTP peer
+ int32_t jitter; ///< [us] filter jitter of the NTP peer
+
+ uint32_t xleave; ///< [ns] interleave delay of the NTP peer
+
+ uint8_t n_filter_values; ///< Number of filter values available, currently always 0
+ uint8_t reserved_7; ///< Reserved, currently always 0
+ uint16_t reserved_8; ///< Reserved, currently always 0
+
+ uint32_t reserved_9; ///< Reserved, currently always 0
+
+} NTP_PEER_STATE, NTP_REFCLK_STATE;
+
+
+
+#define _mbg_swab_ntp_peer_state( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ \
+ _mbg_swab16( &(_p)->ass_id ); \
+ _mbg_swab16( &(_p)->peer_status_flags ); \
+ \
+ _mbg_swab8( &(_p)->leap_ind ); \
+ _mbg_swab8( &(_p)->peer_sel_stat ); \
+ _mbg_swab8( &(_p)->peer_evt_cnt ); \
+ _mbg_swab8( &(_p)->peer_rec_evt ); \
+ \
+ _mbg_swab8( &(_p)->peer_reach_stat ); \
+ _mbg_swab8( &(_p)->reserved_1 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ \
+ _mbg_swab_ip_addr_port( &(_p)->src_addr ); \
+ _mbg_swab_ip_addr_port( &(_p)->dst_addr ); \
+ \
+ _mbg_swab8( &(_p)->stratum ); \
+ _mbg_swab8( &(_p)->precision ); \
+ _mbg_swab16( &(_p)->reserved_3 ); \
+ \
+ _mbg_swab32( &(_p)->root_delay ); \
+ _mbg_swab32( &(_p)->root_disp ); \
+ \
+ _mbg_swab_ip_addr( &(_p)->ref_id ); \
+ \
+ _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \
+ _mbg_swab_ntp_tstamp( &(_p)->rec_time ); \
+ \
+ _mbg_swab8( &(_p)->reach ); \
+ _mbg_swab8( &(_p)->reserved_4 ); \
+ _mbg_swab16( &(_p)->unreach ); \
+ \
+ _mbg_swab8( &(_p)->host_mode ); \
+ _mbg_swab8( &(_p)->peer_mode ); \
+ _mbg_swab8( &(_p)->host_poll ); \
+ _mbg_swab8( &(_p)->peer_poll ); \
+ \
+ _mbg_swab8( &(_p)->headway ); \
+ _mbg_swab8( &(_p)->reserved_5 ); \
+ _mbg_swab16( &(_p)->flash_stat_flags ); \
+ \
+ _mbg_swab16( &(_p)->key_id ); \
+ _mbg_swab16( &(_p)->reserved_6 ); \
+ \
+ _mbg_swab64( &(_p)->offset ); \
+ _mbg_swab64( &(_p)->delay ); \
+ \
+ _mbg_swab32( &(_p)->disp ); \
+ _mbg_swab32( &(_p)->jitter ); \
+ \
+ _mbg_swab32( &(_p)->xleave ); \
+ \
+ _mbg_swab8( &(_p)->n_filter_values ); \
+ _mbg_swab8( &(_p)->reserved_7 ); \
+ _mbg_swab16( &(_p)->reserved_8 ); \
+ \
+ _mbg_swab32( &(_p)->reserved_9 ); \
+ \
+} while ( 0 )
+
+#define _mbg_swab_ntp_refclk_state ( _p ) _mbg_swab_ntp_peer_state( _p )
+
+
+/**
+ * @brief Structure that contains an index value and the NTP peer state
+ *
+ * This structure can be requested by a monitoring program to observe the status of configured NTP peers
+ *
+ * @see ::NTP_PEER_STATE
+ */
+typedef struct
+{
+ uint32_t idx; ///< The index of the observed NTP peer
+ NTP_PEER_STATE peer_state; ///< Peer state, see ::NTP_PEER_STATE
+
+} NTP_PEER_STATE_IDX, NTP_REFCLK_STATE_IDX;
+
+
+#define _mbg_swab_ntp_peer_state_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_ntp_peer_state( &(_p)->peer_state ); \
+} while ( 0 )
+
+
+#define _mbg_swab_ntp_refclk_state_idx( _p ) _mbg_swab_ntp_peer_state_idx( _p )
+
+
+/** @} defgroup group_ntp */
+
+
+
+/**
+ * @defgroup group_lno Definitions used with LNO devices
+ *
+ * @{ */
+
+#define MAX_LNO_OUTPUT 4
+
+/**
+ * @brief LNO state
+ */
+typedef struct
+{
+ uint16_t sine_lvl[MAX_LNO_OUTPUT]; ///< signal levels at the outputs
+
+ uint16_t max_sine_lvl; ///< max level of an output, e.g. 1024
+ uint8_t n_outputs; ///< actual number of outputs [0..::MAX_LNO_OUTPUT-1]
+ uint8_t out_enb_state; ///< e.g. bit 0 is set if corresponding output 0 is enabled, etc.
+
+ uint16_t reserved_0; ///< reserved, currently always 0
+ uint16_t flags; ///< status flags, see ::LNO_STATE_FLAG_BITS
+
+} LNO_STATE;
+
+#define _mbg_swab_lno_state( _p ) \
+do \
+{ \
+ int i; \
+ \
+ for ( i = 0; i < MAX_LNO_OUTPUT; i++ ) \
+ _mbg_swab16( &(_p)->sine_lvl[i] ); \
+ \
+ _mbg_swab_16( &(_p)->max_sine_lvl ); \
+ _mbg_swab_16( &(_p)->reserved_0 ); \
+ _mbg_swab_16( &(_p)->flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Flags used with ::LNO_STATE::flags
+ */
+enum LNO_STATE_FLAG_BITS
+{
+ LNO_FLAG_BIT_PLL_LOCKED, ///< PLL is locked
+ N_LNO_FLAG_BIT ///< number of known bits
+};
+
+#define LNO_FLAG_PLL_LOCKED ( 1UL << LNO_FLAG_BIT_PLL_LOCKED )
+
+/** @} defgroup group_lno */
+
+
+
+/**
+ * @defgroup group_vst Definitions used with Versatile Storage
+ *
+ * Versatile storage is used to store binary data on a device where the storage
+ * device must not necessarily know about the data structure. It just stores
+ * a piece of data, and retrieves it on demand.
+ *
+ * The structures and associated API calls are only supported if the
+ * ::GPS_HAS_VST bit is set in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief Known common VST data types
+ */
+enum VST_DATA_TYPES
+{
+ VST_DATA_TYPE_MAC_ADDR, //##++++++++++++ This is just an example. More to be added.
+ N_VST_DATA_TYPES
+};
+
+
+/**
+ * @brief
+ */
+typedef struct
+{
+ uint16_t data_type; ///< data type identifier, see ::VST_DATA_TYPES for common types
+ uint16_t idx; ///< Index for several sets of the same type
+ uint16_t data_len; ///< length of the data set appended to the header
+ uint16_t reserved; ///< reserved, currently always 0
+
+} VST_HEADER;
+
+#define _mbg_swab_vst_header( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->data_type ); \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab16( &(_p)->data_len ); \
+ _mbg_swab16( &(_p)->reserved ); \
+} while ( 0 )
+
+/** @} defgroup group_vst */
+
+
+
+/**
+ * @defgroup group_shs Definitions used with SHS devices
+ *
+ * An SHS (Secure Hybrid System) device compares the times from 2 sources
+ * and eventually sets an alarm (warning and/or error) flag if the difference
+ * between the 2 time sources exceeds a configurable limit.
+ *
+ * These structures and associated definitions are used to query the SHS
+ * capabilities, configure the SHS device according to its capabilities,
+ * and query the SHS status.
+ *
+ * The structures and associated API calls are only supported if the
+ * ::GPS_HAS_SHS bit is set in ::RECEIVER_INFO::features.
+ *
+ * The ::SHS_INFO structure can be read to retrieve the capabilities and
+ * current settings of the device. The ::SHS_SETTINGS structure can then
+ * be set up according to the capabilities, and be written back to configure
+ * the device.
+ *
+ * If ::SHS_SETTINGS::err_limit and/or ::SHS_SETTINGS::warn_limit are
+ * not 0 then the SHS device checks if the time difference between the
+ * 2 clocks exceeds these limits and sets ::SHS_STATUS::shs_state
+ * as appropriate.
+ *
+ * If indicated by ::SHS_INFO::supp_flags the SHS device can also take
+ * certain actions if the time difference exceeds the error limit.
+ * If this happens then the same flags are set in ::SHS_STATUS::flags
+ * to indicate the action has been taken.
+ *
+ * @{ */
+
+/**
+ * @brief Current configuration of an SHS controller
+ *
+ * @see ::SHS_INFO
+ * @see ::SHS_STATUS
+ */
+typedef struct
+{
+ NANO_TIME err_limit; ///< time difference limit above which an error is indicated
+ NANO_TIME warn_limit; ///< time difference limit above which a warning is indicated
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::SHS_FLAG_MASKS
+
+} SHS_SETTINGS;
+
+#define _mbg_swab_shs_settings( _p ) \
+do \
+{ \
+ _mbg_swab_nano_time( &(_p)->err_limit ); \
+ _mbg_swab_nano_time( &(_p)->warn_limit ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current SHS settings and general SHS capabilities
+ *
+ * @see ::SHS_SETTINGS
+ * @see ::SHS_STATUS
+ */
+typedef struct
+{
+ SHS_SETTINGS settings; ///< current configuration settings
+ NANO_TIME max_limit; ///< if not 0, the max. allowed value for ::SHS_SETTINGS::err_limit and ::SHS_SETTINGS::warn_limit
+ uint32_t reserved; ///< reserved, currently always 0
+ uint32_t supp_flags; ///< indicates which flags are supported for ::SHS_SETTINGS::flags, see ::SHS_FLAG_MASKS
+
+} SHS_INFO;
+
+#define _mbg_swab_shs_info( _p ) \
+do \
+{ \
+ _mbg_swab_shs_settings( &(_p)->settings ); \
+ _mbg_swab_nano_time( &(_p)->max_limit ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current SHS status
+ */
+typedef struct
+{
+ NANO_TIME time_diff; ///< current time difference between the 2 clocks
+ TM_STATUS_EXT clk_status_1; ///< status of first clock
+ TM_STATUS_EXT clk_status_2; ///< status of second clock
+ uint8_t shs_state; ///< see ::SHS_STATES
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t reserved_2; ///< reserved, currently always 0
+ uint32_t flags; ///< see ::SHS_FLAG_MASKS
+
+} SHS_STATUS;
+
+#define _mbg_swab_shs_status( _p ) \
+do \
+{ \
+ _mbg_swab_nano_time( &(_p)->time_diff ); \
+ _mbg_swab32( &(_p)->clk_status_1 ); \
+ _mbg_swab32( &(_p)->clk_status_2 ); \
+ _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief SHS configuration flag bits
+ *
+ * Codes used with ::SHS_STATUS::shs_state
+ */
+enum SHS_STATES
+{
+ SHS_STATE_DISABLED, ///< time difference not checked, eventually no limits configured
+ SHS_STATE_OK, ///< time difference OK, below warning limit
+ SHS_STATE_WARNING, ///< time difference exceeds warning limit
+ SHS_STATE_ERROR, ///< time difference exceeds error limit
+ SHS_STATE_FATAL, ///< one or both time sources disconnected
+ N_SHS_STATES
+};
+
+
+
+/**
+ * @brief SHS flag bits
+ *
+ * @see ::SHS_FLAG_MASKS
+ */
+enum SHS_FLAG_BITS
+{
+ SHS_FLAG_BIT_DISB_SERIAL, ///< disable serial output in state ::SHS_STATE_ERROR
+ SHS_FLAG_BIT_DISB_PPS, ///< disable PPS output in state ::SHS_STATE_ERROR
+ SHS_FLAG_BIT_DISB_10MHZ, ///< disable 10 MHz output in state ::SHS_STATE_ERROR
+ N_SHS_FLAG_BITS
+};
+
+
+/**
+ * @brief SHS flag masks
+ *
+ * With ::SHS_INFO::supp_flags these flags indicate what is supported
+ * by the SHS controller, e.g. what action can be taken automatically.
+ * Each bit set in ::SHS_INFO::supp_flags can be set by a configuration
+ * tool in ::SHS_SETTINGS::flags to enable the associated feature.
+ * If a corresponding bit is set in ::SHS_STATUS::flags this means the
+ * associated feature has been enabled, e.g. an action has been taken.
+ *
+ * @see ::SHS_FLAG_BITS
+ */
+enum SHS_FLAG_MASKS
+{
+ SHS_FLAG_DISB_SERIAL = ( 1UL << SHS_FLAG_BIT_DISB_SERIAL ), ///< see ::SHS_FLAG_BIT_DISB_SERIAL
+ SHS_FLAG_DISB_PPS = ( 1UL << SHS_FLAG_BIT_DISB_PPS ), ///< see ::SHS_FLAG_BIT_DISB_PPS
+ SHS_FLAG_DISB_10MHZ = ( 1UL << SHS_FLAG_BIT_DISB_10MHZ ) ///< see ::SHS_FLAG_BIT_DISB_10MHZ
+};
+
+/** @} defgroup group_shs */
+
+
+
+/**
+ * @defgroup group_xbp eXtended Binary Protocol definitions
+ *
+ * @note These structures are only supported if ::GPS_HAS_XBP is set
+ * in ::RECEIVER_INFO::features.
+ *
+ * @{ */
+
+/**
+ * @brief An XBP port specifier
+ *
+ * Each controller can provide up to 255 ports with numbers 0..254.
+ * XBP port number ::XBP_PORT_RESERVED is reserved to mark unused ports.
+ */
+typedef uint8_t XBP_PORT;
+
+
+/**
+ * @brief An identifier used to mark an XBP port unused
+ */
+#define XBP_PORT_RESERVED ( (XBP_PORT) -1 )
+
+
+/**
+ * @brief Maximum XBP bus/controller cascading level
+ *
+ * Should be 7 so the total size of ::XBP_ADDR is 8 bytes.
+ */
+#define MAX_XBP_CASC_LVL 7
+
+
+/**
+ * @brief An XBP address specifier
+ *
+ * A generic scheme to address devices connected to cascaded controllers.
+ */
+typedef struct
+{
+ uint8_t hop_count; ///< Used as index to the addr array
+ XBP_PORT addr[MAX_XBP_CASC_LVL]; ///< An array of port numbers on cascaded controllers
+
+} XBP_ADDR;
+
+#define _mbg_swab_xbp_addr( _p ) _nop_macro_fnc() // only single bytes
+
+
+
+/**
+ * @brief A structure used to report XBP features and limits
+ */
+typedef struct
+{
+ uint32_t features; ///< Mask of XBP features, see ::XBP_FEAT_MASKS
+ uint32_t flags; ///< XBP flags, currently not used
+ uint32_t reserved_0; ///< reserved, currently not used
+ uint32_t reserved_1; ///< reserved, currently not used
+ uint32_t reserved_2; ///< reserved, currently not used
+ uint32_t reserved_3; ///< reserved, currently not used
+
+} XBP_LIMITS;
+
+#define _mbg_swab_xbp_limits( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->features ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of bits used to define ::XBP_FEAT_MASKS
+ */
+enum XBP_FEAT_BITS
+{
+ XBP_FEAT_BIT_NODES, ///< Supports ::XBP_NODE_LIMITS and associated structures
+ N_XBP_FEAT_BITS
+};
+
+
+/**
+ * @brief XBP feature masks used with ::XBP_LIMITS::features
+ *
+ * @see ::XBP_FEAT_BITS
+ */
+enum XBP_FEAT_MASKS
+{
+ XBP_FEAT_MASK_NODES = ( 1UL << XBP_FEAT_BIT_NODES ) ///< See ::XBP_FEAT_BIT_NODES
+};
+
+
+
+/**
+ * @brief Information on available XBP nodes
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ */
+typedef struct
+{
+ uint32_t node_count; ///< Number of XBP nodes available in the system
+ uint32_t reserved_0; ///< Currently reserved, always 0
+ uint32_t reserved_1; ///< Currently reserved, always 0
+ // TODO: do we need additional fields here?
+
+} XBP_NODE_LIMITS;
+
+#define _mbg_swab_xbp_node_limits( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->node_count ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Possible states of an XBP device
+ *
+ * Used with ::XBP_NODE_INFO::state.
+ */
+enum XBP_DEVICE_STATES
+{
+ XBP_DEVICE_STATE_UNKNOWN,
+ XBP_DEVICE_STATE_NOT_AVAILABLE,
+ XBP_DEVICE_STATE_INITIALIZING,
+ XBP_DEVICE_STATE_AVAILABLE,
+ XBP_DEVICE_STATE_DISCONNECTED,
+ N_XBP_DEVICE_STATES
+};
+
+
+
+/**
+ * @brief Information on a specific XBP node
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ * The number of instances supported by a device is specified
+ * in ::XBP_NODE_LIMITS::node_count.
+ */
+typedef struct
+{
+ XBP_ADDR addr; ///< The address of the specific node
+
+ /// ::RECEIVER_INFO of the device connected to this node.
+ /// If no device is available then ::RECEIVER_INFO::model_code
+ /// is set to ::GPS_MODEL_UNKNOWN (== 0).
+ RECEIVER_INFO ri;
+
+ uint8_t state; ///< The device state, see ::XBP_DEVICE_STATES
+ uint8_t reserved; ///< Currently reserved, always 0
+ uint32_t flags; ///< Currently reserved, always 0
+
+} XBP_NODE_INFO;
+
+#define _mbg_swab_xbp_node_info( _p ) \
+do \
+{ \
+ _mbg_swab_xbp_addr( &(_p)->addr ); \
+ _mbg_swab_receiver_info( &(_p)->ri ); \
+ _mbg_swab8( &(_p)->state ); \
+ _mbg_swab8( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Information on an XBP node with specific index
+ *
+ * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features.
+ */
+typedef struct
+{
+ uint32_t idx; ///< node index, 0..::XBP_NODE_LIMITS::node_count-1
+ XBP_NODE_INFO node_info; ///< ::RECEIVER_INFO of the device behind this node
+
+} XBP_NODE_INFO_IDX;
+
+#define _mbg_swab_xbp_node_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_xbp_node_info( &(_p)->node_info ); \
+} while ( 0 )
+
+
+/** @} defgroup group_xbp */
+
+
+
+/**
+ * @defgroup group_tlv_api Meinberg TLV API definitions
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::MBG_XFEATURE_TLV_API is set in the extended device features.
+ *
+ * @{ */
+
+
+/**
+ * @brief A data type used to hold a unique ID (UID) for a TLV transaction
+ */
+typedef uint32_t MBG_TLV_UID;
+
+#define _mbg_swab_tlv_uid( _p ) \
+ _mbg_swab32( _p )
+
+
+
+/**
+ * @brief A data type to hold one of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES
+ *
+ * @see ::MBG_TLV_TYPES
+ * @see ::MBG_TLV_FEAT_TYPES
+ */
+typedef uint32_t MBG_TLV_TYPE;
+
+#define _mbg_swab_tlv_type( _p ) \
+ _mbg_swab32( _p )
+
+
+
+/**
+ * @defgroup group_tlv_feat Meinberg TLV feature definitions
+ *
+ * @{ */
+
+
+/**
+ * @brief The maximum number of TLV feature types.
+ *
+ * Warning: Changing this number breaks API compatibility!
+ *
+ * @see ::MBG_TLV_FEAT_TYPES
+ */
+#define MAX_MBG_TLV_FEAT_TYPES 128 //### TODO Is this sufficient?
+
+
+/**
+ * @brief Enumeration of known TLV feature types.
+ *
+ * TLV feature types are used to specify the content of a binary TLV message
+ * so that the receiver knows how to interpret the content.
+ *
+ * Used with ::MBG_TLV_INFO::supp_tlv_feat and ::MBG_TLV_DATA::type. ### TODO
+ *
+ * @see ::MBG_TLV_FEAT_BUFFER
+ * @see ::MBG_TLV_FEAT_TYPE_NAMES
+ * @see ::MBG_TLV_TYPES
+ * @see ::MBG_TLV_TYPE
+ */
+enum MBG_TLV_FEAT_TYPES
+{
+ /// Expects two TLV types in order:
+ /// 1) ::MBG_TLV_TYPE_STR => Firmware version as string
+ /// 2) ::MBG_TLV_TYPE_FILE => Firmware file as data blob
+ MBG_TLV_FEAT_TYPE_FW_UPDATE,
+
+ /// If announce message's total bytes are 0, it is a diagnostics file
+ /// request. If its total bytes are not 0, TLV type ::MBG_TLV_TYPE_FILE
+ /// is expected and it should contain a file as data blob.
+ MBG_TLV_FEAT_TYPE_DIAG_FILE,
+
+ /// Only used as action trigger on a remote site, expects no data.
+ MBG_TLV_FEAT_TYPE_FW_ROLLBACK,
+
+ /// Expects two TLV types in order:
+ /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system
+ /// 2) ::MBG_TLV_TYPE_FILE => File as data blob
+ MBG_TLV_FEAT_TYPE_FILE_TRANSFER,
+
+ /// 1) ::MBG_TLV_TYPE_STR => Command line call as string
+ MBG_TLV_FEAT_TYPE_EXEC_CMD,
+
+ /// 1) ::MBG_TLV_TYPE_FILE => Encrypted license file as data blob
+ MBG_TLV_FEAT_TYPE_LICENSE_UPGRADE,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_LIMITS, see @ref group_license_limits
+ MBG_TLV_FEAT_TYPE_LICENSE_LIMITS,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV2_IDX, see @ref group_license_limits
+ MBG_TLV_FEAT_TYPE_LICENSE_PTPV2_IDX,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_NTP_IDX, see @ref group_license_limits
+ MBG_TLV_FEAT_TYPE_LICENSE_NTP_IDX,
+
+ /// Expects two TLV types in order:
+ /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system
+ MBG_TLV_FEAT_TYPE_FILE_REQUEST,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV1_IDX, see @ref group_license_limits
+ MBG_TLV_FEAT_TYPE_LICENSE_PTPV1_IDX,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_TIME_MONITOR_IDX, see @ref group_license_limits
+ MBG_TLV_FEAT_TYPE_LICENSE_TIME_MONITOR_IDX,
+
+ /// 1) ::MBG_TLV_TYPE_BLOB => Unified Firmware Update (UFU) file, see mbg_ufu.h
+ MBG_TLV_FEAT_TYPE_UFU,
+
+ N_MBG_TLV_FEAT_TYPES
+ // NOTE If new TLV feature types are appended here then an appropriate
+ // name string has to be appended to ::MBG_TLV_FEAT_TYPE_NAMES, and care must
+ // be taken that ::N_MBG_TLV_FEAT_TYPES doesn't exceed ::MAX_MBG_TLV_FEAT_TYPES.
+};
+
+
+/**
+ * @brief Names of TLV API features
+ *
+ * Can be used to initialize a string array of ::N_MBG_TLV_FEAT_TYPES entries,
+ * so the number of strings must correspond to ::N_MBG_TLV_FEAT_TYPES.
+ *
+ * @see ::MBG_TLV_FEAT_TYPES
+ */
+#define MBG_TLV_FEAT_TYPE_NAMES \
+{ \
+ "TLV Firmware Update", \
+ "TLV Diagnostics File", \
+ "TLV Firmware Rollback", \
+ "TLV File Transfer", \
+ "TLV Execute Command", \
+ "TLV License Upgrade", \
+ "TLV License Limits", \
+ "TLV License PTPV2", \
+ "TLV License NTP", \
+ "TLV File Request", \
+ "TLV License PTPV1 IDX", \
+ "TLV License Time Monitor", \
+ "TLV Unified Firmware Update" \
+}
+
+
+
+/**
+ * @brief Array size required to store up to ::MAX_MBG_TLV_FEAT_TYPES bits
+ *
+ * The number of bytes required to store up to ::MAX_MBG_TLV_FEAT_TYPES
+ * feature bits in a byte array.
+ */
+#define MAX_MBG_TLV_FEAT_BYTES ( MAX_MBG_TLV_FEAT_TYPES / 8 )
+
+
+/**
+ * @brief A structure used to store a bit mask of supported TLV context types.
+ *
+ * Bit masks for up to ::MAX_MBG_TLV_FEAT_TYPES totally can be stored,
+ * but only ::N_MBG_TLV_FEAT_TYPES types are currently defined.
+ * The ::_set_tlv_feat_bit macro should be used by the firmware
+ * to set a bit mask in the buffer, and the ::check_tlv_feat_supp
+ * function should be used to implement API calls which test if an
+ * extended TLV context type is supported.
+ *
+ * @see ::_set_tlv_feat_bit
+ * @see ::check_tlv_feat_supp
+ */
+typedef struct
+{
+ uint8_t b[MAX_MBG_TLV_FEAT_BYTES];
+
+} MBG_TLV_FEAT_BUFFER;
+
+
+
+/**
+ * @brief Set a TLV context type bit in a ::MBG_TLV_FEAT_BUFFER
+ *
+ * Should be used by the firmware only to set one of the ::MBG_TLV_FEAT_TYPES
+ * bits in an ::MBG_TLV_FEAT_BUFFER after power-up.
+ *
+ * @param[in] _tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES
+ * @param[in] _tlv_feat_buffp Pointer to a ::MBG_TLV_FEAT_BUFFER
+ */
+#define _set_tlv_feat_bit( _tlv_feat_type, _tlv_feat_buffp ) \
+ _set_array_bit( _tlv_feat_type, (_tlv_feat_buffp)->b, MAX_MBG_TLV_FEAT_BYTES )
+
+
+/** @} defgroup group_tlv_feat */
+
+
+
+/**
+ * @brief A structure used to query current TLV capabilities
+ *
+ * This is only supported by a device if the ::MBG_XFEATURE_TLV_API bit
+ * is set in the extended device features.
+ */
+typedef struct
+{
+ uint32_t reserved; ///< Future use
+ uint32_t flags; ///< Future use
+ MBG_TLV_FEAT_BUFFER supp_tlv_feat; ///< A byte array of supported TLV feature bits, see ::MBG_TLV_FEAT_TYPES
+
+} MBG_TLV_INFO;
+
+#define _mbg_swab_tlv_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Enumeration of known TLV types
+ *
+ * Used with ::MBG_TLV_TYPE types, e.g. in ::MBG_TLV_HDR::tlv_type
+ * or ::MBG_TLV_DATA::type.
+ *
+ * @see ::MBG_TLV_FEAT_TYPES
+ * @see ::MBG_TLV_TYPE
+ */
+enum MBG_TLV_TYPES
+{
+ MBG_TLV_TYPE_STR,
+ MBG_TLV_TYPE_FILE,
+ MBG_TLV_TYPE_BLOB, ///< In fact, a file is also a blob but
+ ///< give the child a different name to avoid confusion.
+ ///< Use this for getting/setting fixed structures!
+ N_MBG_TLV_TYPES
+};
+
+
+
+/**
+ * @brief General TLV data structure
+ *
+ * Structure containing common, additional data required to send
+ * an announce message for following TLVs.
+ */
+typedef struct
+{
+ MBG_TLV_UID uid; ///< Unique ID identifying following TLVs, 0 if empty/not set.
+ MBG_TLV_TYPE type; ///< One of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES depending on the type of message.
+ uint32_t total_bytes; ///< Number of all bytes including header(s) that are related to a TLV block transaction.
+ uint32_t reserved_1; ///< Reserved for future use
+
+} MBG_TLV_DATA;
+
+#define _mbg_swab_tlv_data( _p ) \
+do \
+{ \
+ _mbg_swab_tlv_uid( &(_p)->uid ); \
+ _mbg_swab_tlv_type( &(_p)->type ); \
+ _mbg_swab32( &(_p)->total_bytes ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Structure containing state information while reading TLV data.
+ */
+typedef struct
+{
+ MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA
+ uint32_t read_bytes; ///< Number of bytes read
+ uint32_t reserved_1; ///< Future use
+
+} MBG_TLV_RCV_STATE;
+
+
+
+/**
+ * @brief A structure initiating a TLV transfer
+ *
+ * ::MBG_TLV_ANNOUNCE should be sent first, before starting a
+ * TLV transfer, to inform the remote site about following TLVs.
+ * Following sequence of TLVs is not fixed and implementation
+ * dependent.
+ */
+typedef struct
+{
+ MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+
+} MBG_TLV_ANNOUNCE;
+
+#define _mbg_swab_tlv_announce( _p ) \
+do \
+{ \
+ _mbg_swab_tlv_data( &(_p)->data ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+#define MSG_TLV_MAX_VALUE_SIZE 480
+
+/**
+ * @brief TLV header structure containing information on current TLV transaction
+ */
+typedef struct
+{
+ MBG_TLV_UID uid; ///< Unique source ID. See ::MBG_TLV_DATA::uid
+ MBG_TLV_UID tlv_type; ///< "Subtype" identifying current TLV, see ::MBG_TLV_TYPES
+ uint32_t cur_bytes; ///< Number of bytes in ::MBG_TLV::value
+ uint32_t trans_bytes; ///< Number of bytes transferred so far related to this TLV type.
+ uint32_t total_bytes; ///< Number of total bytes (size) of this TLV type without header.
+ ///< It is fixed and must not be changed during a TLV transaction.
+ uint32_t reserved_1; ///< Future use
+ uint32_t reserved_2; ///< Future use
+ uint32_t reserved_3; ///< Future use
+
+} MBG_TLV_HDR;
+
+#define _mbg_swab_tlv_header( _p ) \
+do \
+{ \
+ _mbg_swab_tlv_uid( &(_p)->uid ); \
+ _mbg_swab_tlv_type( &(_p)->tlv_type ); \
+ _mbg_swab32( &(_p)->cur_bytes ); \
+ _mbg_swab32( &(_p)->trans_bytes ); \
+ _mbg_swab32( &(_p)->total_bytes ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief TLV structure containing information on current TLV transaction and its current data.
+ */
+typedef struct
+{
+ MBG_TLV_HDR hdr; ///< See ::MBG_TLV_HDR
+ uint8_t value[MSG_TLV_MAX_VALUE_SIZE]; ///< See ::MSG_TLV_MAX_VALUE_SIZE
+
+} MBG_TLV;
+
+#define _mbg_swab_tlv( _p ) \
+do \
+{ \
+ _mbg_swab_tlv_header( &(_p)->hdr ); \
+} while ( 0 )
+
+/** @} defgroup group_tlv_api */
+
+
+
+/**
+ * @defgroup group_gps_nav_data Definitions used with navigational data received from GPS satellites
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::GPS_MODEL_IS_GPS is set in the @ref GPS_BUILTIN_FEATURE_MASKS
+ *
+ * @{ */
+
+
+/**
+ * @brief Ephemeris parameters of one specific satellite
+ *
+ * Needed to compute the position of a satellite at a given time with
+ * high precision. Valid for an interval of 4 to 6 hours from start
+ * of transmission.
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ HEALTH health; ///< health indication of transmitting SV [---]
+ IOD IODC; ///< Issue Of Data, Clock
+ IOD IODE2; ///< Issue of Data, Ephemeris (Subframe 2)
+ IOD IODE3; ///< Issue of Data, Ephemeris (Subframe 3)
+ T_GPS tt; ///< time of transmission
+ T_GPS t0c; ///< Reference Time Clock [---]
+ T_GPS t0e; ///< Reference Time Ephemeris [---]
+
+ double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ double e; ///< Eccentricity [---]
+ double M0; ///< +- Mean Anomaly at Ref. Time [rad]
+ double omega; ///< +- Argument of Perigee [rad]
+ double OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad]
+ double OMEGADOT; ///< +- Rate of Right Ascension [rad/sec]
+ double deltan; ///< +- Mean Motion Diff. from computed value [rad/sec]
+ double i0; ///< +- Inclination Angle [rad]
+ double idot; ///< +- Rate of Inclination Angle [rad/sec]
+ double crc; ///< +- Cosine Corr. Term to Orbit Radius [m]
+ double crs; ///< +- Sine Corr. Term to Orbit Radius [m]
+ double cuc; ///< +- Cosine Corr. Term to Arg. of Latitude [rad]
+ double cus; ///< +- Sine Corr. Term to Arg. of Latitude [rad]
+ double cic; ///< +- Cosine Corr. Term to Inclination Angle [rad]
+ double cis; ///< +- Sine Corr. Term to Inclination Angle [rad]
+
+ double af0; ///< +- Clock Correction Coefficient 0 [sec]
+ double af1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+ double af2; ///< +- Clock Correction Coefficient 2 [sec/sec^2]
+ double tgd; ///< +- estimated group delay differential [sec]
+
+ uint16_t URA; ///< predicted User Range Accuracy
+
+ uint8_t L2code; ///< code on L2 channel [---]
+ uint8_t L2flag; ///< L2 P data flag [---]
+
+} EPH;
+
+/**
+ * @brief Almanac parameters of one specific satellite
+ *
+ * A reduced precision set of parameters used to check if a satellite
+ * is in view at a given time. Valid for an interval of more than 7 days
+ * from start of transmission.
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ HEALTH health; ///< [---]
+ T_GPS t0a; ///< Reference Time Almanac [sec]
+
+ double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ double e; ///< Eccentricity [---]
-/* Summary of configuration and health data of all SVs. */
+ 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;
+
+
+
+/**
+ * @brief Summary of configuration and health data of all satellites
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
- T_GPS tot_51; /* time of transmission, page 51 */
- T_GPS tot_63; /* time of transmission, page 63 */
- T_GPS t0a; /* complete reference time almanac */
+ T_GPS tot_51; ///< time of transmission, page 51
+ T_GPS tot_63; ///< time of transmission, page 63
+ T_GPS t0a; ///< complete reference time almanac
+
+ CFG cfg[N_SVNO_GPS]; ///< 4 bit SV configuration code from page 63
+ HEALTH health[N_SVNO_GPS]; ///< 6 bit SV health codes from pages 51, 63
- CFG cfg[N_SVNO]; /* SV configuration from page 63 */
- HEALTH health[N_SVNO]; /* SV health from pages 51, 63 */
} CFGH;
/**
- * @brief GPS UTC correction parameters
+ * @brief GPS %UTC correction parameters
+ *
+ * %UTC correction parameters basically as sent by the GPS satellites.
+ *
+ * The csum field is only used by the card's firmware to check the
+ * consistency of the structure in non-volatile memory.
+ *
+ * The field labeled valid indicates if the parameter set is valid, i.e.
+ * if it contains data received from the satellites.
+ *
+ * t0t, A0 and A1 contain fractional correction parameters for the current
+ * GPS-%UTC time offset in addition to the whole seconds. This is evaluated
+ * by the receivers' firmware to convert GPS time to %UTC time.
+ *
+ * The delta_tls field contains the current full seconds offset between
+ * GPS time and %UTC, which corresponds to the number of leap seconds inserted
+ * into the %UTC time scale since GPS was put into operation in January 1980.
+ *
+ * delta_tlfs holds the number of "future" leap seconds, i.e. the %UTC offset
+ * after the next leap second event defined by WNlsf and DNt.
+ *
+ * The fields WNlsf and DNt specify the GPS week number and the day number
+ * in that week for the end of which a leap second has been scheduled.
+ *
+ * @note: The satellites transmit WNlsf only as a signed 8 bit value, so it
+ * can only define a point in time which is +/- 127 weeks off the current time.
+ * The firmware tries to expand this based on the current week number, but
+ * the result is ambiguous if the leap second occurs or occurred more
+ * than 127 weeks in the future or past.
+ *
+ * So the leap second date should <b>only</b> be evaluated and displayed
+ * in a user interface if the fields delta_tls and delta_tlsf have
+ * different values, in which case there is indeed a leap second announcement
+ * inside the +/- 127 week range.
*/
typedef struct
{
- CSUM csum; /**< Checksum of the remaining bytes */
- int16_t valid; /**< Flag indicating UTC parameters are valid */
+ CSUM csum; ///< Checksum of the remaining bytes
+ int16_t valid; ///< Flag indicating %UTC parameters are valid
- T_GPS t0t; /**< Reference Time UTC Parameters [wn|sec] */
- double A0; /**< +- Clock Correction Coefficient 0 [sec] */
- double A1; /**< +- Clock Correction Coefficient 1 [sec/sec] */
+ T_GPS t0t; ///< Reference Time %UTC Parameters [wn|sec]
+ double A0; ///< +- Clock Correction Coefficient 0 [sec]
+ double A1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+
+ uint16_t WNlsf; ///< Week number of nearest leap second
+ int16_t DNt; ///< The day number at the end of which a leap second occurs
+ int8_t delta_tls; ///< Current %UTC offset to GPS system time [sec]
+ int8_t delta_tlsf; ///< Future %UTC offset to GPS system time after next leap second transition [sec]
- uint16_t WNlsf; /**< Week number of nearest leap second */
- int16_t DNt; /**< The day number at the end of which a leap second occurs */
- int8_t delta_tls; /**< Current UTC offset to GPS system time [sec] */
- int8_t delta_tlsf; /**< Future UTC offset to GPS system time after next leap second transition [sec] */
} UTC;
#define _mbg_swab_utc_parm( _p ) \
+do \
{ \
_mbg_swab_csum( &(_p)->csum ); \
_mbg_swab16( &(_p)->valid ); \
@@ -5027,42 +18181,48 @@ typedef struct
_mbg_swab_double( &(_p)->A1 ); \
_mbg_swab16( &(_p)->WNlsf ); \
_mbg_swab16( &(_p)->DNt ); \
-}
-
+} while ( 0 )
-/* Ionospheric correction parameters */
+/**
+ * @brief Ionospheric correction parameters
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
- double alpha_0; /* Ionosph. Corr. Coeff. Alpha 0 [sec] */
- double alpha_1; /* Ionosph. Corr. Coeff. Alpha 1 [sec/deg] */
- double alpha_2; /* Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2] */
- double alpha_3; /* Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3] */
+ double alpha_0; ///< Ionosph. Corr. Coeff. Alpha 0 [sec]
+ double alpha_1; ///< Ionosph. Corr. Coeff. Alpha 1 [sec/deg]
+ double alpha_2; ///< Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2]
+ double alpha_3; ///< Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3]
- double beta_0; /* Ionosph. Corr. Coeff. Beta 0 [sec] */
- double beta_1; /* Ionosph. Corr. Coeff. Beta 1 [sec/deg] */
- double beta_2; /* Ionosph. Corr. Coeff. Beta 2 [sec/deg^2] */
- double beta_3; /* Ionosph. Corr. Coeff. Beta 3 [sec/deg^3] */
-} IONO;
+ double beta_0; ///< Ionosph. Corr. Coeff. Beta 0 [sec]
+ double beta_1; ///< Ionosph. Corr. Coeff. Beta 1 [sec/deg]
+ double beta_2; ///< Ionosph. Corr. Coeff. Beta 2 [sec/deg^2]
+ double beta_3; ///< Ionosph. Corr. Coeff. Beta 3 [sec/deg^3]
+} IONO;
-/* GPS ASCII message */
+/**
+ * @brief GPS ASCII message
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
- char s[23]; /* 22 chars GPS ASCII message plus trailing zero */
+ CSUM csum; ///< checksum of the remaining bytes */
+ int16_t valid; ///< flag data are valid
+ char s[23]; ///< 22 chars GPS ASCII message plus trailing zero
+
} ASCII_MSG;
+/** @} defgroup group_gps_nav_data */
-enum
+
+enum GPS_PLATFORMS
{
GPS_PLATFORM_PORTABLE,
GPS_PLATFORM_FIXED,
@@ -5092,11 +18252,12 @@ enum
-enum
+enum TIME_MODES
{
TIME_MODE_DISABLED,
TIME_MODE_SURVEY_IN,
- TIME_MODE_FIXED
+ TIME_MODE_FIXED,
+ N_TIME_MODES
};
@@ -5110,15 +18271,17 @@ typedef struct
int32_t fixedPosY; // cm
int32_t fixedPosZ; // cm
uint32_t fixedPosVar; // cm
- uint32_t flags; // currently 0
- uint32_t reserved; // currently 0
+ uint32_t flags; // currently 0
+ uint32_t reserved; // currently 0
+
} NAV_TIME_MODE_SETTINGS;
+
/**
- Navigation Engine settings to set configuration
- parameters of a dynamic platform model.
-*/
+ * Navigation Engine settings to set configuration
+ * parameters of a dynamic platform model.
+ */
typedef struct
{
uint8_t dynamic_platform;
@@ -5130,9 +18293,2900 @@ typedef struct
uint32_t flags; // currently 0
uint32_t reserved; // currently 0
NAV_TIME_MODE_SETTINGS nav_time_mode_settings;
+
} NAV_ENGINE_SETTINGS;
+
+/**
+ * @defgroup group_led_api Meinberg LED API definitions
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::MBG_XFEATURE_LED_API is set in the extended device features.
+ *
+ * @{ */
+
+
+/**
+ * @brief General LED info to be read from a device
+ *
+ * Used to query from a device how many LEDs are supported
+ * by the device, then index 0..::MBG_LED_LIMITS::num_leds-1
+ * ::MBG_LED_INFO_IDX or ::MBG_LED_SETTINGS_IDX structures
+ * can be read from or written to the device.
+ *
+ * @see ::MBG_LED_SETTINGS_IDX
+ * @see ::MBG_LED_INFO_IDX
+ */
+typedef struct
+{
+ uint8_t num_leds; ///< Number of supported LEDs, see ::MBG_LED_SETTINGS_IDX::idx and ::MBG_LED_INFO_IDX::idx
+ uint8_t reserved_0; ///< Currently reserved, unused, always 0
+ uint16_t reserved_1; ///< Currently reserved, unused, always 0
+ uint32_t reserved_2; ///< Currently reserved, unused, always 0
+
+} MBG_LED_LIMITS;
+
+#define _mbg_swab_mbg_led_limits( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->num_leds ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Possible modes of LEDs
+ *
+ * Used with ::MBG_LED_SETTINGS::mode
+ *
+ * @see ::MBG_LED_MODE_MASKS
+ */
+enum MBG_LED_MODES
+{
+ MBG_LED_MODE_OFF,
+ MBG_LED_MODE_ON,
+ MBG_LED_MODE_FLASH,
+ MBG_LED_MODE_FLASH_5S,
+ N_MBG_LED_MODES
+};
+
+
+
+/**
+ * @brief Bit masks associated with LED modes
+ *
+ * Used with ::MBG_LED_INFO::supp_modes
+ *
+ * @see ::MBG_LED_MODES
+ */
+enum MBG_LED_MODE_MASKS
+{
+ MBG_LED_MODE_MASK_OFF = ( 1UL << MBG_LED_MODE_OFF ), ///< see ::MBG_LED_MODE_OFF
+ MBG_LED_MODE_MASK_ON = ( 1UL << MBG_LED_MODE_ON ), ///< see ::MBG_LED_MODE_ON
+ MBG_LED_MODE_MASK_FLASH = ( 1UL << MBG_LED_MODE_FLASH ), ///< see ::MBG_LED_MODE_FLASH
+ MBG_LED_MODE_MASK_FLASH_5S = ( 1UL << MBG_LED_MODE_FLASH_5S ) ///< see ::MBG_LED_MODE_FLASH_5S
+};
+
+
+/**
+ * @brief Names of LED modes
+ *
+ * Can be used to initialize a string array of ::N_MBG_LED_MODES entries,
+ * so the number of strings must correspond to ::N_MBG_LED_MODES.
+ *
+ * @see ::MBG_LED_MODES
+ * @see ::MBG_LED_MODE_MASKS
+ */
+#define MBG_LED_MODE_STRS \
+{ \
+ "Off", \
+ "On", \
+ "Flash", \
+ "Flash 5s" \
+}
+
+
+
+/**
+ * @brief Possible colors of LEDs
+ *
+ * Used with ::MBG_LED_SETTINGS::color
+ *
+ * @see ::MBG_LED_COLOR_MASKS
+ */
+enum MBG_LED_COLORS
+{
+ MBG_LED_COLOR_GREEN,
+ MBG_LED_COLOR_RED,
+ MBG_LED_COLOR_YELLOW,
+ MBG_LED_COLOR_BLUE,
+ N_MBG_LED_COLORS
+};
+
+
+
+/**
+ * @brief Bit masks of possible LED colors
+ *
+ * Used with ::MBG_LED_INFO::supp_colors
+ *
+ * @see ::MBG_LED_COLORS
+ */
+enum MBG_LED_COLOR_MASKS
+{
+ MBG_LED_COLOR_MASK_GREEN = ( 1UL << MBG_LED_COLOR_GREEN ), ///< see ::MBG_LED_COLOR_GREEN
+ MBG_LED_COLOR_MASK_RED = ( 1UL << MBG_LED_COLOR_RED ), ///< see ::MBG_LED_COLOR_RED
+ MBG_LED_COLOR_MASK_YELLOW = ( 1UL << MBG_LED_COLOR_YELLOW ), ///< see ::MBG_LED_COLOR_YELLOW
+ MBG_LED_COLOR_MASK_BLUE = ( 1UL << MBG_LED_COLOR_BLUE ) ///< see ::MBG_LED_COLOR_BLUE
+};
+
+
+
+/**
+ * @brief Names of LED colors
+ *
+ * Can be used to initialize a string array of ::N_MBG_LED_COLORS entries,
+ * so the number of strings must correspond to ::N_MBG_LED_COLORS.
+ *
+ * @see ::MBG_LED_COLORS
+ * @see ::MBG_LED_COLOR_MASKS
+ */
+#define MBG_LED_COLOR_STRS \
+{ \
+ "Green", \
+ "Red", \
+ "Yellow", \
+ "Blue" \
+}
+
+
+
+/**
+ * @brief Configuration settings for a single LED
+ *
+ * @see ::MBG_LED_SETTINGS_IDX
+ */
+typedef struct
+{
+ uint8_t mode; ///< LED mode, see ::MBG_LED_MODES
+ uint8_t color; ///< LED color, see ::MBG_LED_COLORS
+ uint16_t reserved; ///< Currently reserved, unused, always 0
+
+} MBG_LED_SETTINGS;
+
+#define _mbg_swab_mbg_led_settings( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->mode ); \
+ _mbg_swab8( &(_p)->color ); \
+ _mbg_swab16( &(_p)->reserved ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Configuration settings for a single LED, plus index
+ *
+ * @see ::MBG_LED_SETTINGS
+ * @see ::MBG_LED_LIMITS
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1
+ MBG_LED_SETTINGS settings; ///< LED settings
+
+} MBG_LED_SETTINGS_IDX;
+
+#define _mbg_swab_mbg_led_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_mbg_led_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current settings and general capabilities of an LED
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of an LED plus its capabilities, e.g. the
+ * supported modes, colors, etc.
+ *
+ * @see ::MBG_LED_INFO_IDX
+ */
+typedef struct
+{
+ MBG_LED_SETTINGS settings; ///< Current LED settings
+ uint32_t supp_modes; ///< Supported modes, see ::MBG_LED_MODE_MASKS
+ uint32_t supp_colors; ///< Supported colors, see ::MBG_LED_COLOR_MASKS
+ uint32_t reserved; ///< Currently reserved, unused, always 0
+ uint32_t flags; ///< Currently reserved, unused, always 0
+
+} MBG_LED_INFO;
+
+#define _mbg_swab_mbg_led_info( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_led_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_modes ); \
+ _mbg_swab32( &(_p)->supp_colors ); \
+ _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current settings and general capabilities of an LED, plus index
+ *
+ * @see ::MBG_LED_INFO
+ * @see ::MBG_LED_LIMITS
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1
+ MBG_LED_INFO info; ///< LED info
+
+} MBG_LED_INFO_IDX;
+
+#define _mbg_swab_mbg_led_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_mbg_led_info( &(_p)->info ); \
+} while ( 0 )
+
+/** @} defgroup group_led_api */
+
+
+
+/**
+ * @defgroup group_lne_api Definitions specific to LNE devices
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::MBG_XFEATURE_LNE_API is set in the extended device features.
+ *
+ * @{ */
+
+
+/**
+ * @brief General info to be read from an LNE device
+ *
+ * Used to query from a device e.g. how many LNE ports are provided
+ * by the device, then index 0..::MBG_LNE_LIMITS::num_ports-1
+ * ::MBG_LNE_PORT_INFO_IDX or ::MBG_LNE_PORT_SETTINGS_IDX structures
+ * can be read from or written to the device.
+ *
+ * @see ::MBG_LNE_PORT_SETTINGS_IDX
+ * @see ::MBG_LNE_PORT_INFO_IDX
+ */
+typedef struct
+{
+ uint8_t num_ports; ///< Number of supported ports, see ::MBG_LNE_PORT_SETTINGS_IDX::idx and ::MBG_LNE_PORT_INFO_IDX::idx
+ uint8_t reserved_0; ///< Currently reserved, unused, always 0
+ uint16_t reserved_1; ///< Currently reserved, unused, always 0
+ uint32_t features; // ### TODO Mask of supported features, see ::MBG_LNE_FEAT_MASKS
+ ///< Currently reserved, unused, always 0
+ uint32_t reserved_2; ///< Currently reserved, unused, always 0
+
+} MBG_LNE_LIMITS;
+
+#define _mbg_swab_mbg_lne_limits( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->num_ports ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->features ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+} while ( 0 )
+
+
+
+#if 0 //### TODO //#################
+
+/**
+ * @brief LNE feature bits
+ *
+ * Used to define ::MBG_LNE_FEAT_MASKS
+ *
+ * @see ::MBG_LNE_FEAT_MASKS
+ */
+enum MBG_LNE_FEAT_BITS
+{
+ MBG_LNE_FEAT_BIT_SWITCH_PWR, ///< Power switching off all LNE ports at once supported, see ::MBG_LNE_PWR_STATE
+ N_MBG_LNE_FEAT_BITS
+};
+
+
+
+/**
+ * @brief LNE feature bit masks
+ *
+ * Used with ::MBG_LNE_LIMITS::features
+ *
+ * @see ::MBG_LNE_FEAT_BITS
+ */
+enum MBG_LNE_FEAT_MASKS
+{
+ MBG_LNE_FEAT_MASK_SWITCH_PWR = ( 1UL << MBG_LNE_FEAT_BIT_SWITCH_PWR ) ///< see ::MBG_LNE_FEAT_BIT_SWITCH_PWR
+};
+
+#endif
+
+
+
+/**
+ * @brief Configuration settings for a single LNE port
+ *
+ * @see ::MBG_LNE_PORT_SETTINGS_IDX
+ */
+typedef struct
+{
+ uint32_t reserved_0; ///< currently reserved, unused, always 0
+ uint32_t reserved_1; ///< currently reserved, unused, always 0
+ uint32_t reserved_2; ///< currently reserved, unused, always 0
+ uint32_t flags; ///< currently reserved, unused, always 0
+
+} MBG_LNE_PORT_SETTINGS;
+
+#define _mbg_swab_mbg_lne_port_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Configuration settings for a single LNE port, plus index
+ *
+ * @see ::MBG_LNE_PORT_SETTINGS
+ * @see ::MBG_LNE_LIMITS
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_LNE_LIMITS::num_ports-1
+ MBG_LNE_PORT_SETTINGS settings; ///< LNE settings
+
+} MBG_LNE_PORT_SETTINGS_IDX;
+
+#define _mbg_swab_mbg_lne_port_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current settings and general capabilities of an LNE port
+ *
+ * This structure should be read from the device to retrieve the
+ * current settings of an LNE port plus its capabilities, ### e.g. the
+ * supported modes, colors, etc.
+ *
+ * @see ::MBG_LNE_PORT_INFO_IDX
+ */
+typedef struct
+{
+ MBG_LNE_PORT_SETTINGS settings; ///< Current LNE port settings
+ MBG_MAC_ADDR mac_addr; ///< The MAC address assigned to this port
+ uint32_t reserved_0; ///< currently reserved, unused, always 0
+ uint32_t reserved_1; ///< currently reserved, unused, always 0
+ uint32_t reserved_2; ///< currently reserved, unused, always 0
+ uint32_t flags; ///< see ::LNE_PORT_FLAG_MASKS
+
+} MBG_LNE_PORT_INFO;
+
+#define _mbg_swab_mbg_lne_port_info( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \
+ _mbg_swab_mbg_mac_addr( &(_p)->mac_addr ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Current settings and general capabilities of an LNE port, plus index
+ *
+ * @see ::MBG_LNE_PORT_INFO
+ * @see ::MBG_LNE_LIMITS
+ */
+typedef struct
+{
+ uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1
+ MBG_LNE_PORT_INFO info; ///< LNE port info
+
+} MBG_LNE_PORT_INFO_IDX;
+
+#define _mbg_swab_mbg_lne_port_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_mbg_lne_port_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief LNE port flag bits
+ *
+ * Used to define ::LNE_PORT_FLAG_MASKS
+ *
+ * @see ::LNE_PORT_FLAG_MASKS
+ */
+enum LNE_PORT_FLAG_BITS
+{
+ LNE_PORT_FLAG_BIT_IS_SFP,
+ N_LNE_PORT_FLAG_BITS
+};
+
+
+
+/**
+ * @brief LNE port flag bit masks
+ *
+ * Used with ::MBG_LNE_PORT_INFO::flags
+ *
+ * @see ::LNE_PORT_FLAG_BITS
+ */
+enum LNE_PORT_FLAG_MASKS
+{
+ LNE_PORT_FLAG_MASK_IS_SFP = ( 1UL << LNE_PORT_FLAG_BIT_IS_SFP ) ///< see ::LNE_PORT_FLAG_BIT_IS_SFP
+};
+
+
+/** @} defgroup group_lne_api */
+
+
+
+/**
+ * @defgroup group_pwr_ctl_api Definitions for power control API
+ *
+ * @note These structures and definitions are only supported by a device
+ * if ::MBG_XFEATURE_PWR_CTL_API is set in the extended device features.
+ *
+ * @{ */
+
+
+/**
+ * @brief Device power states
+ *
+ * Used with ::MBG_PWR_CTL::state.
+ */
+enum MBG_PWR_STATES
+{
+ MBG_PWR_STATE_OFF,
+ MBG_PWR_STATE_ON,
+ N_MBG_PWR_STATES
+};
+
+
+
+/**
+ * @brief Device power control
+ *
+ * Used to change or retrieve a device's power state
+ */
+typedef struct
+{
+ uint8_t state; ///< see ::MBG_PWR_STATES
+ uint8_t reserved_0; ///< Currently reserved, unused, always 0
+ uint16_t reserved_1; ///< Currently reserved, unused, always 0
+
+} MBG_PWR_CTL;
+
+#define _mbg_swab_mbg_pwr_ctl( _p ) \
+do \
+{ \
+ _mbg_swab8( &(_p)->state ); \
+ _mbg_swab8( &(_p)->reserved_0 ); \
+ _mbg_swab16( &(_p)->reserved_1 ); \
+} while ( 0 )
+
+/** @} defgroup group_pwr_ctl_api */
+
+
+
+
+/**
+ * @defgroup group_ext_sys_info Extended system information
+ *
+ * @note This structure and its definitions are only supported by a device
+ * if ::MBG_XFEATURE_EXT_SYS_INFO is set in the extended device features.
+ *
+ * @{ */
+
+
+/**
+ * @brief Bits used to define ::MBG_EXT_SYS_INFO_MSKS
+ *
+ * @see ::MBG_EXT_SYS_INFO_MSKS
+ */
+enum MBG_EXT_SYS_INFO_BITS
+{
+ MBG_EXT_SYS_INFO_BIT_SW_REV,
+ MBG_EXT_SYS_INFO_BIT_HW_REV,
+ MBG_EXT_SYS_INFO_BIT_OS_REV,
+ MBG_EXT_SYS_INFO_BIT_FPGA_REV,
+ MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV,
+ N_MBG_EXT_SYS_INFO_BITS
+};
+
+
+
+/**
+ * @brief Bit masks of supported revision numbers
+ *
+ * Used with ::MBG_EXT_SYS_INFO::supp_members
+ *
+ * @see ::MBG_EXT_SYS_INFO_BITS
+ */
+enum MBG_EXT_SYS_INFO_MSKS
+{
+ MBG_EXT_SYS_INFO_MSK_SW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_SW_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_SW_REV
+ MBG_EXT_SYS_INFO_MSK_HW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_HW_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_HW_REV
+ MBG_EXT_SYS_INFO_MSK_OS_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_OS_REV
+ MBG_EXT_SYS_INFO_MSK_FPGA_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_FPGA_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_FPGA_REV
+ MBG_EXT_SYS_INFO_MSK_CORE_MOD_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV ) ///< see ::MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV
+};
+
+
+enum MBG_EXT_SYS_INFO_PROC_TYPES
+{
+ MBG_EXT_SYS_INFO_PROC_TYPE_NONE,
+ MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_A9,
+ MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3u,
+ MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3s,
+ MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_STM32F4,
+ N_MBG_EXT_SYS_INFO_PROC_TYPES
+};
+
+#define MBG_EXT_SYS_INFO_PROC_STRS \
+{ \
+ "None", \
+ "Cortex A9", \
+ "Cortex SAM3u", \
+ "Cortex SAM3s", \
+ "Cortex STM32F4" \
+}
+
+enum MBG_EXT_SYS_INFO_FPGA_TYPES
+{
+ MBG_EXT_SYS_INFO_FPGA_TYPE_NONE,
+ MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5_SOC, ///< System on chip
+ MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5, ///< Stand alone FPGA
+ MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE4GX15,
+ MBG_EXT_SYS_INFO_FPGA_TYPE_CYLCONE4CE22,
+ N_MBG_EXT_SYS_INFO_FPGA_TYPES
+};
+
+#define MBG_EXT_SYS_INFO_FPGA_STRS \
+{ \
+ "None", \
+ "Cyclone5 SoC", \
+ "Cyclone5", \
+ "Cyclone4GX15", \
+ "Cyclone4CE22" \
+}
+
+enum MBG_EXT_SYS_INFO_CORE_MOD_TYPES
+{
+ MBG_EXT_SYS_INFO_CORE_MOD_TYPE_NONE,
+ MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8F, ///< u-blox GNSS module without Galileo support
+ MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8T, ///< u-blox GNSS module with Galileo support
+ N_MBG_EXT_SYS_INFO_CORE_MOD_TYPES
+};
+
+#define MBG_EXT_SYS_INFO_CORE_MOD_STRS \
+{ \
+ "None", \
+ "u-blox LEA-M8F", \
+ "u-blox LEA-M8T" \
+}
+
+typedef struct
+{
+ uint32_t supp_members; ///< ::MBG_EXT_SYS_INFO_MSKS
+
+ uint32_t sw_rev;
+ uint32_t hw_rev;
+ uint32_t os_rev;
+ uint32_t fpga_rev;
+
+ uint16_t proc_type; ///< See ::MBG_EXT_SYS_INFO_PROC_TYPES
+ uint16_t fpga_type; ///< See ::MBG_EXT_SYS_INFO_FPGA_TYPES
+ uint16_t core_mod_type; ///< See ::MBG_EXT_SYS_INFO_CORE_MOD_TYPES
+ uint16_t reserved;
+
+ uint32_t core_mod_rev;
+
+ /* Reserved for future use, currently 0 */
+ uint32_t reserved_rev_3;
+ uint32_t reserved_rev_4;
+ uint32_t reserved_rev_5;
+ uint32_t reserved_rev_6;
+ uint32_t reserved_rev_7;
+ uint32_t reserved_rev_8;
+ uint32_t reserved_rev_9;
+ uint32_t reserved_rev_10;
+ uint32_t reserved_rev_11;
+
+} MBG_EXT_SYS_INFO;
+
+#define _mbg_swab_ext_sys_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab32( &(_p)->sw_rev ); \
+ _mbg_swab32( &(_p)->hw_rev ); \
+ _mbg_swab32( &(_p)->os_rev ); \
+ _mbg_swab32( &(_p)->fpga_rev ); \
+ _mbg_swab16( &(_p)->proc_type ); \
+ _mbg_swab16( &(_p)->fpga_type ); \
+ _mbg_swab16( &(_p)->core_mod_type ); \
+ _mbg_swab16( &(_p)->reserved ); \
+ _mbg_swab32( &(_p)->core_mod_rev ); \
+} while ( 0 )
+
+
+#define _mbg_encode_revision( _major, _minor, _patch ) \
+ ( ( (_major) << 24) | ( (_minor) << 16 ) | (_patch) )
+
+
+#define _mbg_decode_revision( _rev, _major, _minor, _patch ) \
+{ \
+ (_major) = ( (_rev) >> 24 ) & 0xff; \
+ (_minor) = ( (_rev) >> 16 ) & 0xff; \
+ (_patch) = (_rev) & 0xffff; \
+}
+
+
+/** @} defgroup group_ext_sys_info */
+
+
+/**
+ * @defgroup group_license_limits License information
+ *
+ * @note This is probably obsolete.
+ *
+ * @{ */
+
+
+#define MBG_MAX_LICENSES 32
+
+
+/**
+ * @brief General license information to be read from a device
+ *
+ * Used to query from a device how many and which different license types
+ * are supported. If a special type is supported (licenses[MBG_LICENSE_BASE_TYPES] > 0), its
+ * license specific information can be queried from 0..licenses[MBG_LICENSE_BASE_TYPES]-1 via
+ * its license specific [...]_IDX structures and TLV API command codes.
+ * See ::MBG_XFEATURE_TLV_API and ::MBG_TLV_FEAT_TYPES.
+ */
+typedef struct
+{
+ uint8_t licenses[MBG_MAX_LICENSES]; ///< To get the number of supported licenses
+ ///< of a specific type you need to access the array
+ ///< with the specififc license index defined at ::MBG_LICENSE_BASE_TYPES.
+} MBG_LICENSE_LIMITS;
+
+
+enum MBG_LICENSE_BASE_TYPES
+{
+ MBG_LICENSE_BASE_TYPE_PTPV2,
+ MBG_LICENSE_BASE_TYPE_NTP,
+ MBG_LICENSE_BASE_TYPE_PTPV1,
+ MBG_LICENSE_BASE_TYPE_TIME_MONITOR,
+ N_MBG_LICENSE_BASE_TYPES
+};
+
+
+/**
+ * @brief Bits used to define ::MBG_LICENSE_BASE_MSKS
+ *
+ * @see ::MBG_LICENSE_BASE_MSKS
+ */
+enum MBG_LICENSE_BASE_FLAGS
+{
+ MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE, ///< License supports upgrading / modifying
+ N_MBG_LICENSE_BASE_FLAGS
+};
+
+
+/**
+ * @brief Bit masks of common supported base license flags
+ *
+ * Used with ::MBG_LICENSE_BASE::supp_flags
+ *
+ * @see ::MBG_LICENSE_BASE_FLAGS
+ */
+enum MBG_LICENSE_BASE_MSKS
+{
+ MBG_LICENSE_BASE_MSK_SUPP_UPGRADE = ( 1UL << MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE ) ///< See ::MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE
+};
+
+
+/**
+ * @brief Common license information
+ *
+ * Should be part of each individual license type.
+ */
+typedef struct
+{
+ uint8_t type; ///< See ::MBG_LICENSE_BASE_TYPES
+ uint8_t reserved_1; ///< Reserved for future use, currently 0
+ uint16_t reserved_2; ///< Reserved for future use, currently 0
+ uint32_t supp_flags; ///< See ::MBG_LICENSE_BASE_MSKS
+ uint32_t reserved_3; ///< Reserved for future use, currently 0
+ uint32_t reserved_4; ///< Reserved for future use, currently 0
+
+} MBG_LICENSE_BASE;
+
+#define _mbg_swab_license_base( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+/**
+ * @brief Bits used to define ::MBG_LICENSE_PTPV2_MEMBER_MSKS
+ *
+ * @see ::MBG_LICENSE_PTPV2_MEMBER_MSKS
+ */
+enum MBG_LICENSE_PTPV2_MEMBERS
+{
+ MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS,
+ MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS,
+ N_MBG_LICENSE_PTPV2_MEMBERS
+};
+
+
+/**
+ * @brief Bit masks of PTPV2 license specific members
+ *
+ * Used with ::MBG_LICENSE_PTPV2::supp_members
+ *
+ * @see ::MBG_LICENSE_PTPV2_MEMBERS
+ */
+enum MBG_LICENSE_PTPV2_MEMBER_MSKS
+{
+ MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_UCLIENTS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS ), ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS
+ MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_MTRANS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS ) ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS
+};
+
+
+/**
+ * @brief PTPV2 specific license information
+ *
+ */
+typedef struct
+{
+ MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE
+ uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV2_MEMBER_MSKS
+ uint32_t reserved_1; ///< Reserved for future use, currently 0
+ uint16_t max_uclients; ///< Maximal number of supported unicast clients.
+ uint16_t reserved_2; ///< Reserved for future use, currently 0
+ uint32_t max_mtrans; ///< Maximal number of supported multicast transactions per second.
+ uint32_t reserved_3; ///< Reserved for future use, currently 0
+ uint32_t reserved_4; ///< Reserved for future use, currently 0
+ uint32_t reserved_5; ///< Reserved for future use, currently 0
+ uint32_t reserved_6; ///< Reserved for future use, currently 0
+
+} MBG_LICENSE_PTPV2;
+
+#define _mbg_swab_license_ptpv2( _p ) \
+do \
+{ \
+ _mbg_swab_license_base( &(_p)->base ); \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab16( &(_p)->max_uclients ); \
+ _mbg_swab32( &(_p)->max_mtrans ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_LICENSE_PTPV2 license;
+
+} MBG_LICENSE_PTPV2_IDX;
+
+#define _mbg_swab_license_ptpv2_idx( _p ) \
+do \
+{ \
+ _mbg_swab_license_ptpv2( &(_p)->license ); \
+ _mbg_swab32( &(_p)->idx ); \
+} while ( 0 )
+
+
+/**
+ * @brief Bits used to define ::MBG_LICENSE_NTP_MEMBER_MSKS
+ *
+ * @see ::MBG_LICENSE_NTP_MEMBER_MSKS
+ */
+enum MBG_LICENSE_NTP_MEMBERS
+{
+ MBG_LICENSE_NTP_MEMBER_MAX_RPS,
+ N_MBG_LICENSE_NTP_MEMBERS
+};
+
+
+/**
+ * @brief Bit masks of NTP license specific members
+ *
+ * Used with ::MBG_LICENSE_NTP::supp_members
+ *
+ * @see ::MBG_LICENSE_PTPV2_MEMBERS
+ */
+enum MBG_LICENSE_NTP_MEMBER_MSKS
+{
+ MBG_LICENSE_NTP_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_NTP_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_NTP_MEMBER_MAX_RPS
+};
+
+
+/**
+ * @brief NTP specific license information
+ */
+typedef struct
+{
+ MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE
+ uint32_t supp_members; ///< See ::MBG_LICENSE_NTP_MEMBER_MSKS
+ uint32_t max_rps; ///< Maximum number of supported NTP requests per second
+ uint32_t reserved_1; ///< Reserved for future use, currently 0
+ uint32_t reserved_2; ///< Reserved for future use, currently 0
+ uint32_t reserved_3; ///< Reserved for future use, currently 0
+ uint32_t reserved_4; ///< Reserved for future use, currently 0
+ uint32_t reserved_5; ///< Reserved for future use, currently 0
+ uint32_t reserved_6; ///< Reserved for future use, currently 0
+
+} MBG_LICENSE_NTP;
+
+#define _mbg_swab_license_ntp( _p ) \
+do \
+{ \
+ _mbg_swab_license_base( &(_p)->base ); \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab32( &(_p)->max_rps ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_LICENSE_NTP license;
+
+} MBG_LICENSE_NTP_IDX;
+
+#define _mbg_swab_license_ntp_idx( _p ) \
+do \
+{ \
+ _mbg_swab_license_ntp( &(_p)->license ); \
+ _mbg_swab32( &(_p)->idx ); \
+} while ( 0 )
+
+/**
+ * @brief Bits used to define ::MBG_LICENSE_PTPV1_MEMBER_MSKS
+ *
+ * @see ::MBG_LICENSE_PTPV1_MEMBER_MSKS
+ */
+enum MBG_LICENSE_PTPV1_MEMBERS
+{
+ MBG_LICENSE_PTPV1_MEMBER_MAX_RPS,
+ N_MBG_LICENSE_PTPV1_MEMBERS
+};
+
+
+/**
+ * @brief Bit masks of PTPV1 license specific members
+ *
+ * Used with ::MBG_LICENSE_PTPV1::supp_members
+ *
+ * @see ::MBG_LICENSE_PTPV2_MEMBERS
+ */
+enum MBG_LICENSE_PTPV1_MEMBER_MSKS
+{
+ MBG_LICENSE_PTPV1_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_PTPV1_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_PTPV1_MEMBER_MAX_RPS
+};
+
+
+/**
+ * @brief NTP specific license information
+ */
+typedef struct
+{
+ MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE
+ uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV1_MEMBER_MSKS
+ uint32_t max_rps; ///< Maximum number of supported PTPv1 delay requests per second
+ uint32_t reserved_1; ///< Reserved for future use, currently 0
+ uint32_t reserved_2; ///< Reserved for future use, currently 0
+ uint32_t reserved_3; ///< Reserved for future use, currently 0
+ uint32_t reserved_4; ///< Reserved for future use, currently 0
+ uint32_t reserved_5; ///< Reserved for future use, currently 0
+ uint32_t reserved_6; ///< Reserved for future use, currently 0
+
+} MBG_LICENSE_PTPV1;
+
+#define _mbg_swab_license_ptpv1( _p ) \
+do \
+{ \
+ _mbg_swab_license_base( &(_p)->base ); \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab32( &(_p)->max_rps ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_LICENSE_PTPV1 license;
+
+} MBG_LICENSE_PTPV1_IDX;
+
+#define _mbg_swab_license_ptpv1_idx( _p ) \
+do \
+{ \
+ _mbg_swab_license_ptpv1( &(_p)->license ); \
+ _mbg_swab32( &(_p)->idx ); \
+} while ( 0 )
+
+/**
+ * @brief Bits used to define ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS
+ *
+ * @see ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS
+ */
+enum MBG_LICENSE_TIME_MONITOR_MEMBERS
+{
+ MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS,
+ MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS,
+ N_MBG_LICENSE_TIME_MONITOR_MEMBERS
+};
+
+
+/**
+ * @brief Bit masks of Time Monitor license specific members
+ *
+ * Used with ::MBG_LICENSE_TIME_MONITOR::supp_members
+ *
+ * @see ::MBG_LICENSE_TIME_MONITOR_MEMBERS
+ */
+enum MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS
+{
+ MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_PTPV2_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS ), ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS
+ MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_NTP_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS ) ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS
+};
+
+
+/**
+ * @brief Time Monitor specific license information
+ *
+ */
+typedef struct
+{
+ MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE
+ uint32_t supp_members; ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS
+ uint32_t reserved_1; ///< Reserved for future use, currently 0
+ uint16_t max_ptpv2_clients; ///< Maximum number of supported PTPv2 clients to be monitored
+ uint16_t max_ntp_clients; ///< Maximum number of supported NTP clients to be monitored
+ uint32_t reserved_2; ///< Reserved for future use, currently 0
+ uint32_t reserved_3; ///< Reserved for future use, currently 0
+ uint32_t reserved_4; ///< Reserved for future use, currently 0
+ uint32_t reserved_5; ///< Reserved for future use, currently 0
+ uint32_t reserved_6; ///< Reserved for future use, currently 0
+
+} MBG_LICENSE_TIME_MONITOR;
+
+#define _mbg_swab_license_time_monitor( _p ) \
+do \
+{ \
+ _mbg_swab_license_base( &(_p)->base ); \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab16( &(_p)->max_ptpv2_clients ); \
+ _mbg_swab16( &(_p)->max_ntp_clients ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_LICENSE_TIME_MONITOR license;
+
+} MBG_LICENSE_TIME_MONITOR_IDX;
+
+#define _mbg_swab_license_time_monitor_idx( _p ) \
+do \
+{ \
+ _mbg_swab_license_time_monitor( &(_p)->license ); \
+ _mbg_swab32( &(_p)->idx ); \
+} while ( 0 )
+
+/** @} defgroup group_license_limits */
+
+
+
+/**
+ * @defgroup group_clk_res_info Clock resolution info
+ *
+ * @note This structure and its definitions are only supported by a device
+ * if ::MBG_XFEATURE_CLK_RES_INFO is set in the extended device features.
+ *
+ * @{ */
+
+/**
+ * @brief Clock resolution information
+ *
+ * @see @ref group_clk_res_info
+ */
+typedef struct
+{
+ uint32_t base_clk; ///< Base clock of the internal time base [MHz]
+ uint32_t num_clk_phase; ///< Number of multi-phase clock signals
+ uint32_t reserved_9;
+ uint32_t reserved_8;
+ uint32_t reserved_7;
+ uint32_t reserved_6;
+ uint32_t reserved_5;
+ uint32_t reserved_4;
+ uint32_t reserved_3;
+ uint32_t reserved_2;
+ uint32_t reserved_1;
+ uint32_t reserved_0;
+
+} MBG_CLK_RES_INFO;
+
+#define _mbg_swab_mbg_clk_res_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->base_clk ); \
+ _mbg_swab32( &(_p)->num_clk_phase ); \
+ _mbg_swab32( &(_p)->reserved_9 ); \
+ _mbg_swab32( &(_p)->reserved_8 ); \
+ _mbg_swab32( &(_p)->reserved_7 ); \
+ _mbg_swab32( &(_p)->reserved_6 ); \
+ _mbg_swab32( &(_p)->reserved_5 ); \
+ _mbg_swab32( &(_p)->reserved_4 ); \
+ _mbg_swab32( &(_p)->reserved_3 ); \
+ _mbg_swab32( &(_p)->reserved_2 ); \
+ _mbg_swab32( &(_p)->reserved_1 ); \
+ _mbg_swab32( &(_p)->reserved_0 ); \
+} while ( 0 )
+
+/** @} defgroup group_clk_res_info */
+
+
+
+/**
+ * @brief Type of upcoming transaction sequence
+ *
+ * Used in combination with ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION
+ * to announce which type of transaction is going to be started. Thus the receiver
+ * can prepare for following actions.
+ */
+enum MBG_TRANSACTION_TYPES
+{
+ MBG_TRANSACTION_TYPE_NONE,
+ /* ### TODO FIXME
+ * Network transaction requires at least and as first command:
+ * - ::GPS_NET_GLB_CFG (::MBG_NET_GLB_CFG_INFO)
+ * Depending on ::MBG_NET_GLB_CFG_INFO::glb_settings and its num_[...]
+ * members there are a couple of index commands which should be handled in any order:
+ * - ::GPS_NET_DNS_SRVR (::MBG_IP_ADDR_IDX)
+ * - ::GPS_NET_DNS_SRCH_DOM (::MBG_NET_NAME_IDX)
+ * - ::GPS_NET_INTF_LINK_IDX (::MBG_NET_INTF_LINK_INFO_IDX)
+ * - ::GPS_NET_INTF_ADDR_IDX (::MBG_NET_INTF_ADDR_INFO_IDX)
+ * - ::GPS_NET_INTF_ROUTE_IDX (::MBG_NET_INTF_ROUTE_INFO_IDX)
+ */
+ MBG_TRANSACTION_TYPE_NETWORK,
+ MBG_TRANSACTION_TYPE_PTP,
+ /*
+ * Commands in any order if supp. by ::MBG_SNMP_GLB_INFO::max_[...]
+ * and ::MBG_SNMP_GLB_INFO::supp_versions
+ *
+ * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be
+ * used stand-alone.
+ *
+ * - ::GPS_SNMP_GLB_SETTINGS
+ * - ::GPS_SNMP_V12_SETTINGS_IDX
+ * - ::GPS_SNMP_V12_TRAP_SETTINGS_IDX
+ * - ::GPS_SNMP_V3_SETTINGS_IDX
+ * - ::GPS_SNMP_V3_TRAP_SETTINGS_IDX
+ */
+ MBG_TRANSACTION_TYPE_MONITORING_SNMP,
+ /*
+ * NTP transaction requires at least and as first command:
+ * ::GPS_NTP_GLB_CFG
+ * Commands in any order if supp. by ::MBG_NTP_GLB_INFO
+ * and ::MBG_SNMP_GLB_INFO::supp_versions
+ *
+ * - ::GPS_NTP_REFCLK_CFG
+ * - ::GPS_NTP_MISC_LIMITS
+ * - ::GPS_NTP_MISC_ORPHAN_MODE
+ * - ::GPS_NTP_SYMM_KEY_LIMITS
+ * - ::GPS_NTP_SYMM_KEY_CFG
+ * - ::GPS_NTP_TRUSTED_KEY_CFG
+ * - ::GPS_NTP_CLNT_MODE_CFG
+ * - ::GPS_NTP_SRV_MODE_CFG
+ * - ::GPS_NTP_PEER_SETTINGS_IDX
+ * - ::GPS_NTP_SYS_STATE
+ * - ::GPS_NTP_PEER_STATE_IDX
+ */
+ MBG_TRANSACTION_TYPE_NTP,
+ /*
+ * IO Port transaction used to read or write ALL_IO_PORT_INFO
+ * Commands related to this transaction:
+ *
+ * - ::GPS_IO_PORT_LIMITS
+ * - ::GPS_IO_PORT_SETTINGS_IDX
+ * - ::GPS_IO_PORT_INFO_IDX
+ * - ::GPS_IO_PORT_TYPE_INFO_IDX
+ * - ::GPS_IO_PORT_STATUS_IDX
+ */
+ MBG_TRANSACTION_TYPE_IO_PORT,
+ /*
+ * Commands in any order if ::MBG_XFEATURE_MONITORING is set in
+ * ::MBG_XFEATURE_BUFFER.
+ *
+ * Transactions ::MBG_TRANSACTION_TYPE_MONITORING_SNMP and
+ * ::MBG_TRANSACTION_TYPE_EVENTS may also be opened within
+ * ::MBG_TRANSACTION_TYPE_MONITORING transaction.
+ *
+ * - ::GPS_MONITORING_LIMITS
+ * - ::GPS_MONITORING_STATUS
+ */
+ MBG_TRANSACTION_TYPE_MONITORING,
+ /*
+ * Commands in any order if ::MBG_XFEATURE_MONITORING is set in
+ * ::MBG_XFEATURE_BUFFER.
+ *
+ * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be
+ * used stand-alone.
+ *
+ * - ::GPS_EVENT_IDX
+ * - ::GPS_EVENT_STAT_IDX
+ */
+ MBG_TRANSACTION_TYPE_EVENTS,
+
+ MAX_MBG_TRANSACTION_TYPES
+};
+
+
+#define MBG_TRANSACTION_MSK_SET 0x8000
+#define _mbg_is_set_transaction( _type ) ( ( _type ) & MBG_TRANSACTION_MSK_SET )
+#define _mbg_transaction_type_set( _type ) ( ( _type ) |= MBG_TRANSACTION_MSK_SET )
+
+
+/**
+ * @defgroup group_io_ports IO Port API
+ *
+ * @note This structure and its definitions are only supported by a device
+ * if ::MBG_XFEATURE_IO_PORTS is set in the extended device features.
+ *
+ * @{ */
+
+/**
+ * @brief IO Port types
+ *
+ * Used with ::MBG_IO_PORT_TYPE_INFO::port_type and ::MBG_IO_PORT_SETTINGS::port_type
+ */
+enum MBG_IO_PORT_TYPES
+{
+ MBG_IO_PORT_TYPE_PPS,
+ MBG_IO_PORT_TYPE_10MHz,
+ MBG_IO_PORT_TYPE_2048KHz,
+ MBG_IO_PORT_TYPE_GPIO,
+ MBG_IO_PORT_TYPE_ETHERNET,
+ MBG_IO_PORT_TYPE_TERMINAL,
+ MBG_IO_PORT_TYPE_MULTI,
+ MBG_IO_PORT_TYPE_POUT,
+ N_MBG_IO_PORT_TYPES
+};
+
+/**
+ * @brief Port type to be used for an undefined/unassigned port
+ *
+ * Only use this for ::MBG_IO_PORT_SETTINGS::port_type
+ * if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE
+ */
+#define MBG_IO_PORT_TYPE_NONE ( (uint16_t) -1 )
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_TYPES
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_TYPES entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_TYPES.
+ *
+ * @see ::MBG_IO_PORT_TYPES
+ */
+#define MBG_IO_PORT_TYPE_STRS \
+{ \
+ "PPS", \
+ "10 MHz", \
+ "2048 KHz", \
+ "GPIO", \
+ "Ethernet", \
+ "Terminal", \
+ "Multi", \
+ "Prog. Output" \
+}
+
+
+/**
+ * @brief Port directions (input or output)
+ *
+ * @see ::MBG_IO_PORT_DIR_MSKS
+ */
+enum MBG_IO_PORT_DIRS
+{
+ MBG_IO_PORT_DIR_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::direction if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE
+ MBG_IO_PORT_DIR_IN, ///< Port is input like PPS In
+ MBG_IO_PORT_DIR_OUT, ///< Port is output like 10Mhz
+ MBG_IO_PORT_DIR_IN_OUT, ///< Port can be in- & output in parallel like network port
+ N_MBG_IO_PORT_DIRS
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_DIRS
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_DIRS entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_DIRS.
+ *
+ * @see ::MBG_IO_PORT_DIRS
+ */
+#define MBG_IO_PORT_DIR_STRS \
+{ \
+ "Input", \
+ "Output", \
+ "Input/Output" \
+}
+
+
+/**
+ * @brief Bit masks of Meinberg I/O port directions
+ *
+ * Used with ::MBG_IO_PORT_TYPE_INFO::supp_dirs
+ *
+ * @see ::MBG_IO_PORT_DIRS
+ */
+enum MBG_IO_PORT_DIR_MSKS
+{
+ MBG_IO_PORT_MSK_DIR_IN = ( 1UL << MBG_IO_PORT_DIR_IN ), ///< See ::MBG_IO_PORT_DIR_IN
+ MBG_IO_PORT_MSK_DIR_OUT = ( 1UL << MBG_IO_PORT_DIR_OUT ), ///< See ::MBG_IO_PORT_DIR_OUT
+ MBG_IO_PORT_MSK_DIR_IN_OUT = ( 1UL << MBG_IO_PORT_DIR_IN_OUT ) ///< See ::MBG_IO_PORT_DIR_IN_OUT
+};
+
+
+/**
+ * @brief Port type sources
+ *
+ * Configurable sources for an I/O port type
+ *
+ * @see ::MBG_IO_PORT_SRC_MSKS
+ */
+enum MBG_IO_PORT_SRCS
+{
+ MBG_IO_PORT_SRC_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::source if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE
+ MBG_IO_PORT_SRC_STATIC, ///< Static, not configurable
+ MBG_IO_PORT_SRC_LOCAL, ///< Locally generated, e.g. on (carrier) board
+ MBG_IO_PORT_SRC_ASSOC_CLOCK, ///< Fixed (wired) clock from back plane (e.g. refclock 1 in M500 IMS)
+ MBG_IO_PORT_SRC_ACTIVE_CLOCK, ///< Switched clock from back plane (e.g. selected by RSC)
+ MBG_IO_PORT_SRC_CLK1, ///< Clock 1 fixed (CPU board only)
+ MBG_IO_PORT_SRC_CLK2, ///< Clock 2 fixed (CPU board only)
+ MBG_IO_PORT_SRC_ARC, ///< Any rate converter
+ MBG_IO_PORT_SRC_OSC, ///< Oscillator
+ MBG_IO_PORT_SRC_SYNCE, ///< SyncE
+ N_MBG_IO_PORT_SRCS
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_SRCS
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_SRCS entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_SRCS.
+ *
+ * @see ::MBG_IO_PORT_SRCS
+ */
+#define MBG_IO_PORT_SRC_STRS \
+{ \
+ "Static", \
+ "Locally generated", \
+ "Associated clock", \
+ "Active clock", \
+ "Clock 1 fixed", \
+ "Clock 2 fixed", \
+ "Any rate converter", \
+ "Oscillator", \
+ "SyncE" \
+}
+
+
+/**
+ * @brief Bit masks of Meinberg I/O port attitudes
+ *
+ * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs
+ *
+ * @see ::MBG_IO_PORT_SRCS
+ */
+enum MBG_IO_PORT_SRC_MSKS
+{
+ MBG_IO_PORT_SRC_MSK_STATIC = (1UL << MBG_IO_PORT_SRC_STATIC), ///< See ::MBG_IO_PORT_SRC_STATIC
+ MBG_IO_PORT_SRC_MSK_LOCAL = (1UL << MBG_IO_PORT_SRC_LOCAL), ///< See ::MBG_IO_PORT_SRC_LOCAL
+ MBG_IO_PORT_SRC_MSK_ASSOC_CLOCK = (1UL << MBG_IO_PORT_SRC_ASSOC_CLOCK), ///< See ::MBG_IO_PORT_SRC_ASSOC_CLOCK
+ MBG_IO_PORT_SRC_MSK_ACTIVE_CLOCK = (1UL << MBG_IO_PORT_SRC_ACTIVE_CLOCK), ///< See ::MBG_IO_PORT_SRC_ACTIVE_CLOCK
+ MBG_IO_PORT_SRC_MSK_CLK1 = (1UL << MBG_IO_PORT_SRC_CLK1), ///< See ::MBG_IO_PORT_SRC_CLK1
+ MBG_IO_PORT_SRC_MSK_CLK2 = (1UL << MBG_IO_PORT_SRC_CLK2), ///< See ::MBG_IO_PORT_SRC_CLK2
+ MBG_IO_PORT_SRC_MSK_ARC = (1UL << MBG_IO_PORT_SRC_ARC), ///< See ::MBG_IO_PORT_SRC_ARC
+ MBG_IO_PORT_SRC_MSK_OSC = (1UL << MBG_IO_PORT_SRC_OSC), ///< See ::MBG_IO_PORT_SRC_OSC
+ MBG_IO_PORT_SRC_MSK_SYNCE = (1UL << MBG_IO_PORT_SRC_SYNCE) ///< See ::MBG_IO_PORT_SRC_SYNCE
+};
+
+
+/**
+ * @brief Port connector types
+ *
+ * Used with ::MBG_IO_PORT_INFO::conn_type
+ *
+ */
+enum MBG_IO_PORT_CONN_TYPES
+{
+ MBG_IO_PORT_CONN_TYPE_SMA,
+ MBG_IO_PORT_CONN_TYPE_BNC,
+ MBG_IO_PORT_CONN_TYPE_DSUB25,
+ MBG_IO_PORT_CONN_TYPE_RJ45,
+ MBG_IO_PORT_CONN_TYPE_SFP,
+ MBG_IO_PORT_CONN_TYPE_USB_MICRO_B,
+ MBG_IO_PORT_CONN_TYPE_USB_A,
+ MBG_IO_PORT_CONN_TYPE_USB_B,
+ MBG_IO_PORT_CONN_TYPE_SMA_ANT,
+ MBG_IO_PORT_CONN_TYPE_RJ45_ETH,
+ MBG_IO_PORT_CONN_TYPE_2_PIN_DFK,
+ MBG_IO_PORT_CONN_TYPE_3_PIN_DFK,
+ MBG_IO_PORT_CONN_TYPE_16_PIN_DFK,
+ MBG_IO_PORT_CONN_TYPE_BNC_ISO,
+ MBG_IO_PORT_CONN_TYPE_DSUB9,
+ MBG_IO_PORT_CONN_TYPE_FIBRE_ST,
+ MBG_IO_PORT_CONN_TYPE_XHE_SPI,
+ N_MBG_IO_PORT_CONN_TYPES
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_CONN_TYPES
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_CONN_TYPES entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_CONN_TYPES.
+ *
+ * @see ::MBG_IO_PORT_CONN_TYPES
+ */
+#define MBG_IO_PORT_CONN_TYPE_STRS \
+{ \
+ "SMA", \
+ "BNC", \
+ "D-Sub 25", \
+ "RJ45", \
+ "SFP", \
+ "USB Micro B", \
+ "USB A", \
+ "USB B", \
+ "SMA Antenna", \
+ "RJ45 Ethernet", \
+ "DFK 2-Pin", \
+ "DFK 3-Pin", \
+ "DFK 16-Pin", \
+ "BNC isolated", \
+ "D-Sub 9", \
+ "Fibre ST", \
+ "XHE SPI" \
+}
+
+
+/**
+ * @brief Position of a port on a card
+ *
+ * Used with ::MBG_IO_PORT_INFO::position
+ *
+ */
+enum MBG_IO_PORT_POS
+{
+ MBG_IO_PORT_POS_FRONT_COL_1, ///> Connector column 1, front
+ MBG_IO_PORT_POS_REAR_COL_1, ///> Connector column 1, rear
+ MBG_IO_PORT_POS_FRONT_COL_2, ///> Connector column 2, front
+ MBG_IO_PORT_POS_REAR_COL_2, ///> Connector column 2, rear
+ MBG_IO_PORT_POS_FRONT_COL_3, ///> Connector column 3, front
+ MBG_IO_PORT_POS_REAR_COL_3, ///> Connector column 3, rear
+ MBG_IO_PORT_POS_FRONT_COL_4, ///> Connector column 4, front
+ MBG_IO_PORT_POS_REAR_COL_4, ///> Connector column 4, rear
+ N_MBG_IO_PORT_POS
+};
+
+
+/**
+ * @brief Bit masks of Meinberg I/O port attitudes
+ *
+ * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs
+ *
+ * @see ::MBG_IO_PORT_POS
+ */
+enum MBG_IO_PORT_POS_MSKS
+{
+ MBG_IO_PORT_POS_MSK_FRONT_COL_1 = (1UL << MBG_IO_PORT_POS_FRONT_COL_1), ///< See ::MBG_IO_PORT_POS_FRONT_COL_1
+ MBG_IO_PORT_POS_MSK_REAR_COL_1 = (1UL << MBG_IO_PORT_POS_REAR_COL_1), ///< See ::MBG_IO_PORT_POS_REAR_COL_1
+ MBG_IO_PORT_POS_MSK_FRONT_COL_2 = (1UL << MBG_IO_PORT_POS_FRONT_COL_2), ///< See ::MBG_IO_PORT_POS_FRONT_COL_2
+ MBG_IO_PORT_POS_MSK_REAR_COL_2 = (1UL << MBG_IO_PORT_POS_REAR_COL_2), ///< See ::MBG_IO_PORT_POS_REAR_COL_2
+ MBG_IO_PORT_POS_MSK_FRONT_COL_3 = (1UL << MBG_IO_PORT_POS_FRONT_COL_3), ///< See ::MBG_IO_PORT_POS_FRONT_COL_3
+ MBG_IO_PORT_POS_MSK_REAR_COL_3 = (1UL << MBG_IO_PORT_POS_REAR_COL_3), ///< See ::MBG_IO_PORT_POS_REAR_COL_3
+ MBG_IO_PORT_POS_MSK_FRONT_COL_4 = (1UL << MBG_IO_PORT_POS_FRONT_COL_4), ///< See ::MBG_IO_PORT_POS_FRONT_COL_4
+ MBG_IO_PORT_POS_MSK_REAR_COL_4 = (1UL << MBG_IO_PORT_POS_REAR_COL_4) ///< See ::MBG_IO_PORT_POS_REAR_COL_4
+};
+
+
+/**
+ * @brief IO Port Limits
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef struct
+{
+ uint8_t num_ports;
+ uint8_t reserved_1[3]; ///< Reserved, currently 0
+ uint32_t supp_positions; ///< Determines the size of the card (i.e. 2 rows, front/rear) See ::MBG_IO_PORT_POS_MSKS
+ uint32_t reserved_2[10]; ///< Reserved, currently 0
+
+} MBG_IO_PORT_LIMITS;
+
+#define _mbg_swab_io_port_limits( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_positions ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Port Operation Bits
+ *
+ * Used with ::MBG_IO_PORT_SETTINGS::op_mode
+ *
+ * For now, there is a per port operation mode setting which
+ * is quite equal to ::ENABLE_FLAGS.
+ *
+ * @see ::MBG_IO_PORT_OP_MODE_MSKS
+ */
+enum MBG_IO_PORT_OP_MODE_BITS
+{
+ MBG_IO_PORT_OP_MODE_NONE = -1, ///< Current mode cannot be determined
+ MBG_IO_PORT_OP_MODE_DISABLED, ///< Disabled port
+ MBG_IO_PORT_OP_MODE_ALWAYS, ///< Always enable port
+ MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY, ///< Enable port if sync only
+ MBG_IO_PORT_OP_MODE_AFTER_SYNC, ///< Always enable port after being sync once
+ N_MBG_IO_PORT_OP_MODE_BITS
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_OP_MODE_BITS
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_OP_MODE_BITS entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_OP_MODE_BITS.
+ *
+ * @see ::MBG_IO_PORT_OP_MODE_BITS
+ */
+#define MBG_IO_PORT_OP_MODE_STRS \
+{ \
+ "Disabled", \
+ "Always enabled", \
+ "If sync only", \
+ "Always after sync" \
+}
+
+
+
+/**
+ * @brief Masks for ::MBG_IO_PORT_OP_MODE_BITS
+ *
+ * Used with ::MBG_IO_PORT_INFO::supp_op_modes
+ *
+ * @see ::MBG_IO_PORT_OP_MODE_BITS
+ */
+enum MBG_IO_PORT_OP_MODE_MSKS
+{
+ MBG_IO_PORT_OP_MODE_MSK_DISABLED = (1UL << MBG_IO_PORT_OP_MODE_DISABLED), ///< See ::MBG_IO_PORT_OP_MODE_DISABLED
+ MBG_IO_PORT_OP_MODE_MSK_ALWAYS = (1UL << MBG_IO_PORT_OP_MODE_ALWAYS), ///< See ::MBG_IO_PORT_OP_MODE_ALWAYS
+ MBG_IO_PORT_OP_MODE_MSK_IF_SYNC_ONLY = (1UL << MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY), ///< See ::MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY
+ MBG_IO_PORT_OP_MODE_MSK_AFTER_SYNC = (1UL << MBG_IO_PORT_OP_MODE_AFTER_SYNC) ///< See ::MBG_IO_PORT_OP_MODE_AFTER_SYNC
+};
+
+
+/**
+ * @brief Physical or logical group role bits
+ *
+ * Used with ::MBG_IO_PORT_STATUS::phys_grp_role, ::MBG_IO_PORT_STATUS::log_grp_role
+ *
+ * @see ::MBG_IO_PORT_GRP_ROLE_MSKS
+ */
+enum MBG_IO_PORT_GRP_ROLE_BITS
+{
+ MBG_IO_PORT_GRP_ROLE_NONE, ///< No group role, only possible if port is not assigned to any group
+ MBG_IO_PORT_GRP_ROLE_MASTER, ///< Master port in group, i.e. configurable port of LIU
+ MBG_IO_PORT_GRP_ROLE_SLAVE, ///< Slave port in group, i.e. non-configurable port of LIU
+ MBG_IO_PORT_GRP_ROLE_PASSIVE, ///< Passive port in group, i.e. passive port of network group (i.e. SFP or RJ45)
+ N_MBG_IO_PORT_GRP_ROLE_BITS
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_GRP_ROLE_BITS
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_GRP_ROLE_BITS entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_GRP_ROLE_BITS.
+ *
+ * @see ::MBG_IO_PORT_GRP_ROLE_BITS
+ */
+#define MBG_IO_PORT_GRP_ROLE_STRS \
+{ \
+ "None", \
+ "Master", \
+ "Slave", \
+ "Passive" \
+}
+
+
+/**
+ * @brief Masks for ::MBG_IO_PORT_GRP_ROLE_BITS
+ *
+ * Used with ::MBG_IO_PORT_INFO::supp_phys_grp_roles
+ *
+ * @see ::MBG_IO_PORT_GRP_ROLE_BITS
+ */
+enum MBG_IO_PORT_GRP_ROLE_MSKS
+{
+ MBG_IO_PORT_GRP_ROLE_MSK_NONE = (1UL << MBG_IO_PORT_GRP_ROLE_NONE), ///< See ::MBG_IO_PORT_GRP_ROLE_NONE
+ MBG_IO_PORT_GRP_ROLE_MSK_MASTER = (1UL << MBG_IO_PORT_GRP_ROLE_MASTER), ///< See ::MBG_IO_PORT_GRP_ROLE_MASTER
+ MBG_IO_PORT_GRP_ROLE_MSK_SLAVE = (1UL << MBG_IO_PORT_GRP_ROLE_SLAVE), ///< See ::MBG_IO_PORT_GRP_ROLE_SLAVE
+ MBG_IO_PORT_GRP_ROLE_MSK_PASSIVE = (1UL << MBG_IO_PORT_GRP_ROLE_PASSIVE) ///< See ::MBG_IO_PORT_GRP_ROLE_PASSIVE
+};
+
+
+/**
+ * @brief IO Port Settings Union
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef union
+{
+ MBG_GPIO_SETTINGS gpio_settings;
+ POUT_SETTINGS pout_settings;
+
+} MBG_IO_PORT_SETTINGS_U;
+
+#define _mbg_swab_io_port_settings_u( _type, _p, _recv ) \
+do \
+{ \
+ switch ( (_type) ) \
+ { \
+ case MBG_IO_PORT_TYPE_GPIO: \
+ _mbg_swab_mbg_gpio_settings( &(_p)->gpio_settings, (_recv) ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_POUT: \
+ if ( _recv ) \
+ _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \
+ else _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \
+ break; \
+ \
+ default: break; \
+ } \
+} while ( 0 )
+
+
+#define MBG_IO_PORT_SETTINGS_MIN_SIZE 32
+
+
+/**
+ * @brief IO Port Settings
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef struct
+{
+ uint16_t port_type; ///< ::MBG_IO_PORT_TYPES
+ uint8_t direction; ///< ::MBG_IO_PORT_DIRS
+ uint8_t source; ///< ::MBG_IO_PORT_SRCS
+ uint8_t op_mode; ///< ::MBG_IO_PORT_OP_MODE_BITS
+ uint8_t reserved_1[3]; ///< Future use and padding, currently 0
+ uint32_t reserved_2[6]; ///< Future use and padding, currently 0
+
+ /*
+ * Struct members above represent minimum amount of data to be sent.
+ * See ::MBG_IO_PORT_SETTINGS_MIN_SIZE
+ */
+
+ MBG_IO_PORT_SETTINGS_U data; ///< Data union for settings' type
+
+} MBG_IO_PORT_SETTINGS;
+
+#define _mbg_swab_io_port_settings( _p, _recv ) \
+do \
+{ \
+ uint16_t t = (_p)->port_type; \
+ if ( (_recv) ) \
+ _mbg_swab16( &t ); \
+ _mbg_swab16( &(_p)->port_type ); \
+ _mbg_swab_io_port_settings_u( t, &(_p)->data, (_recv) ); \
+} while ( 0 )
+
+
+
+
+/**
+ * @brief IO Port Settings Index
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ *
+ * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used
+ * to set ::MBG_IO_PORT_SETTINGS wrapped in ::MBG_IO_PORT_SETTINGS_IDX.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IO_PORT_SETTINGS settings;
+
+} MBG_IO_PORT_SETTINGS_IDX;
+
+#define _mbg_swab_io_port_settings_idx( _p, _recv ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \
+} while ( 0 )
+
+
+#define MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE (MBG_IO_PORT_SETTINGS_MIN_SIZE + sizeof( uint32_t ))
+
+
+#define MBG_IO_PORT_SETTINGS_IDX_SIZES \
+{ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ) /* MBG_IO_PORT_TYPE_POUT */ \
+}
+
+
+#define MBG_NO_PHYS_GROUP 0xFF
+#define MBG_NO_LOG_GROUP 0xFF
+
+/**
+ * @brief IO Port Info
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef struct
+{
+ uint8_t num_types; ///< See ::MBG_IO_PORT_TYPE_INFO
+ uint8_t conn_type; ///< See ::MBG_IO_PORT_CONN_TYPES
+ uint8_t position; ///< See ::MBG_IO_PORT_POS
+ uint8_t reserved_1; ///< Future use and padding, currently 0
+ uint16_t supp_op_modes; ///< See ::MBG_IO_PORT_OP_MODE_MSKS
+ uint16_t supp_phys_grp_roles; ///< Supported roles in ::MBG_IO_PORT_STATUS::phys_grp_role, see ::MBG_IO_PORT_GRP_ROLE_MSKS
+ uint8_t phys_grp; ///< Physical group number (i.e. SFP/RJ45 on HPS100), or ::MBG_NO_PHYS_GROUP
+ uint8_t reserved_2[3]; ///< Future use and padding, currently 0
+ uint32_t reserved_3[8]; ///< Future use and padding, currently 0
+ char rel_str[16]; ///< Indicates internal relation, i.e. "lan0", "fpga0" or "/dev/ttyS0"
+ MBG_IO_PORT_SETTINGS settings; ///< See ::MBG_IO_PORT_SETTINGS
+
+} MBG_IO_PORT_INFO;
+
+#define _mbg_port_has_phys_group( _p ) ( ( _p )->phys_grp != MBG_NO_PHYS_GROUP )
+
+#define _mbg_swab_io_port_info( _p, _recv ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->supp_op_modes ); \
+ _mbg_swab16( &(_p)->supp_phys_grp_roles ); \
+ _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \
+} while ( 0 )
+
+
+
+#define MBG_IO_PORT_INFO_MIN_SIZE ( 60 + MBG_IO_PORT_SETTINGS_MIN_SIZE )
+
+
+/**
+ * @brief IO Port Info Index
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_U
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ *
+ * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used
+ * to query ::MBG_IO_PORT_INFO wrapped in ::MBG_IO_PORT_INFO_IDX.
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IO_PORT_INFO info;
+
+} MBG_IO_PORT_INFO_IDX;
+
+#define _mbg_swab_io_port_info_idx( _p, _recv ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_io_port_info( &(_p)->info, (_recv) ); \
+} while ( 0 )
+
+
+
+#define MBG_IO_PORT_INFO_IDX_MIN_SIZE (MBG_IO_PORT_INFO_MIN_SIZE + sizeof( uint32_t ))
+
+
+#define MBG_IO_PORT_INFO_IDX_SIZES \
+{ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ) /* MBG_IO_PORT_TYPE_POUT */ \
+}
+
+
+/**
+ * @brief IO Port Type Info Union
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef union
+{
+ MBG_GPIO_LIMITS gpio_limits;
+ POUT_INFO pout_info;
+
+} MBG_IO_PORT_TYPE_INFO_U;
+
+#define _mbg_swab_io_port_type_info_u( _type, _p, _recv ) \
+do \
+{ \
+ switch ( (_type) ) \
+ { \
+ case MBG_IO_PORT_TYPE_GPIO: \
+ _mbg_swab_mbg_gpio_limits( &(_p)->gpio_limits, (_recv) ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_POUT: \
+ _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \
+ break; \
+ \
+ default: break; \
+ } \
+} while ( 0 )
+
+
+
+#define MBG_IO_PORT_TYPE_INFO_MIN_SIZE 32
+
+
+/**
+ * @brief IO Port Type Info
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_INFO_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO_U
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ */
+typedef struct
+{
+ uint16_t port_type; ///< See ::MBG_IO_PORT_TYPES
+ uint16_t reserved_1; ///< Future use and padding, currently 0
+ uint8_t supp_dirs; ///< See ::MBG_IO_PORT_DIR_MSKS
+ uint8_t reserved_2[3]; ///< Future use and padding, currently 0
+ uint32_t supp_srcs; ///< See ::MBG_IO_PORT_SRC_MSKS
+ uint32_t reserved_3[5]; ///< Future use and padding, currently 0
+
+ /*
+ * Struct members above represent minimum amount of data to be sent.
+ * See ::MBG_IO_PORT_TYPE_INFO_MIN_SIZE
+ */
+
+ MBG_IO_PORT_TYPE_INFO_U data; ///< Port type specific data
+
+} MBG_IO_PORT_TYPE_INFO;
+
+#define _mbg_swab_io_port_type_info( _p, _recv ) \
+do \
+{ \
+ uint16_t t = (_p)->port_type; \
+ if ( (_recv) ) \
+ _mbg_swab16( &t ); \
+ _mbg_swab16( &(_p)->port_type ); \
+ _mbg_swab_io_port_type_info_u( t, &(_p)->data, (_recv) ); \
+ _mbg_swab32( &(_p)->supp_srcs ); \
+} while ( 0 )
+
+
+#define MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE (MBG_IO_PORT_TYPE_INFO_MIN_SIZE + 2 * sizeof( uint32_t ))
+
+
+#define MBG_IO_PORT_TYPE_INFO_IDX_SIZES \
+{ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_LIMITS ), /* MBG_IO_PORT_TYPE_GPIO */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( POUT_INFO ) /* MBG_IO_PORT_TYPE_POUT */ \
+}
+
+
+/**
+ * @brief IO Port Type Info Index
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_U
+ * @see ::MBG_IO_PORT_STATUS
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ *
+ * Indexes from 0..::MBG_IO_PORT_INFO::num_types - 1 are used
+ * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX.
+ *
+ */
+typedef struct
+{
+ uint32_t port_idx;
+ uint32_t port_type_idx;
+ MBG_IO_PORT_TYPE_INFO info;
+
+} MBG_IO_PORT_TYPE_INFO_IDX;
+
+#define _mbg_swab_io_port_type_info_idx( _p, _recv ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->port_idx ); \
+ _mbg_swab32( &(_p)->port_type_idx ); \
+ _mbg_swab_io_port_type_info( &(_p)->info, (_recv) ); \
+} while ( 0 )
+
+
+
+#define MAX_IO_PORT_STATUS_BITS 64
+
+
+/**
+ * @brief Port Type Status Bits
+ *
+ */
+enum MBG_IO_PORT_STATUS_BITS
+{
+ MBG_IO_PORT_STATUS_BIT_DISABLED, ///< See ::MBG_IO_PORT_OP_MODE_DISABLED. Other bits should be 0 in this case
+ MBG_IO_PORT_STATUS_BIT_CARRIER_DETECTED, ///< Port has physical carrier connection (e.g. BNC cable in BPE's case)
+ MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_NEVER_AVAIL, ///< Input signal has NEVER been avail
+ MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_AVAIL, ///< Input signal is avail right now
+ MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_LOST, ///< Input signal is currently not avail, but has been avail before
+ MBG_IO_PORT_STATUS_BIT_SHORT_CIRCUIT, ///< Short circuit
+ N_MBG_IO_PORT_STATUS_BITS
+};
+
+
+/**
+ * @brief Strings descriptions for ::MBG_IO_PORT_STATUS_BITS
+ *
+ * Can be used to initialize a string array of ::N_MBG_IO_PORT_STATUS_BITS entries,
+ * so the number of strings must correspond to ::N_MBG_IO_PORT_STATUS_BITS.
+ *
+ * @see ::MBG_IO_PORT_STATUS_BITS
+ */
+#define MBG_IO_PORT_STATUS_STRS \
+{ \
+ "Disabled", \
+ "Carrier detected", \
+ "Input signal has never been avail", \
+ "Input signal is avail", \
+ "Input signal is currently lost", \
+ "Short circuit" \
+}
+
+
+/**
+ * @brief Array size required to store all status bits
+ *
+ * The number of bytes required to store up to ::MAX_IO_PORT_STATUS_BITS
+ * feature bits in a byte array.
+ */
+#define MAX_IO_PORT_STATUS_BYTES ( MAX_IO_PORT_STATUS_BITS / 8 )
+
+
+/**
+ * @brief A structure used to store port status bits
+ *
+ * Up to ::MAX_IO_PORT_STATUS_BITS totally can be stored, but only
+ * ::N_MBG_IO_PORT_STATUS_BITS are currently defined.
+ *
+ * The ::_set_io_port_status_bit macro should be used by the firmware
+ * to set a status bit in the buffer, and the ::check_feat_supp_byte_array
+ * to check if a bit is set
+ *
+ * @see ::_set_io_port_status_bit
+ * @see ::check_feat_supp_byte_array
+ */
+typedef struct
+{
+ uint8_t b[MAX_IO_PORT_STATUS_BYTES];
+
+} MBG_IO_PORT_STATUS_BUFFER;
+
+#define _mbg_swab_io_port_status_buffer( _p ) \
+ _nop_macro_fnc()
+
+
+
+/**
+ * @brief Set an port status bit in a ::MBG_IO_PORT_STATUS_BUFFER
+ *
+ * Should be used by the firmware only to set one of the ::N_MBG_IO_PORT_STATUS_BITS
+ * in an ::MBG_IO_PORT_STATUS_BUFFER after power-up.
+ *
+ * @param[in] _status_bit One of the ::MBG_IO_PORT_STATUS_BITS
+ * @param[in] _status_buffp Pointer to an ::MBG_IO_PORT_STATUS_BUFFER
+ */
+#define _set_io_port_status_bit( _status_bit, _status_buffp ) \
+ _set_array_bit( _status_bit, (_status_buffp)->b, MAX_IO_PORT_STATUS_BYTES )
+
+
+/**
+ * @brief IO Port Type Status
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_U
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS_IDX
+ *
+ */
+typedef struct
+{
+ MBG_IO_PORT_STATUS_BUFFER supp_stati; ///< Supported ::MBG_IO_PORT_STATUS_BITS in ::MBG_IO_PORT_STATUS_BUFFER
+ MBG_IO_PORT_STATUS_BUFFER status; ///< See ::MBG_IO_PORT_STATUS_BUFFER
+
+ uint8_t cfg_counter; ///< Updated (increased) when config changes
+ uint8_t phys_grp_role; ///< Physical group role state, see ::MBG_IO_PORT_GRP_ROLE_BITS
+ uint8_t log_grp; ///< Logical group number (i.e. bond0), or ::MBG_NO_LOG_GROUP
+ uint8_t log_grp_role; ///< Logical group role (i.e. bond master, bond slave), see ::MBG_IO_PORT_GRP_ROLE_BITS
+
+ uint32_t reserved_2[4]; ///< Future use, currently 0
+
+} MBG_IO_PORT_STATUS;
+
+#define _mbg_port_has_log_group( _p ) ( ( _p )->log_grp != MBG_NO_LOG_GROUP )
+
+#define _mbg_swab_io_port_status( _p ) \
+do \
+{ \
+ _mbg_swab_io_port_status_buffer( &(_p)->supp_stati ); \
+ _mbg_swab_io_port_status_buffer( &(_p)->status ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief IO Port Type Status
+ *
+ * @see @ref group_io_ports
+ * @see ::MBG_IO_PORT_SETTINGS_U
+ * @see ::MBG_IO_PORT_LIMITS
+ * @see ::MBG_IO_PORT_SETTINGS
+ * @see ::MBG_IO_PORT_SETTINGS_IDX
+ * @see ::MBG_IO_PORT_TYPE_INFO
+ * @see ::MBG_IO_PORT_TYPE_INFO_U
+ * @see ::MBG_IO_PORT_TYPE_INFO_IDX
+ * @see ::MBG_IO_PORT_STATUS
+ *
+ * Indexes from 0..::MBG_IO_PORT_INFO::num_types - 1 are used
+ * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX.
+ *
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_IO_PORT_STATUS status;
+
+} MBG_IO_PORT_STATUS_IDX;
+
+#define _mbg_swab_io_port_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_io_port_status( &(_p)->status ); \
+} while ( 0 )
+
+
+/** @} defgroup group_io_ports */
+
+
+
+/**
+ * @defgroup group_monitoring Monitoring / notification
+ *
+ * @note This structure and its definitions are only supported by a device
+ * if ::MBG_XFEATURE_MONITORING is set in the extended device features.
+ *
+ * TODO: Add proper Doxygen documentation
+ *
+ * @{ */
+
+
+#define MBG_MONITORING_STR_SIZE 32
+
+enum MBG_MONITORING_TYPES
+{
+ MBG_MONITORING_TYPE_SNMP,
+ MBG_MONITORING_TYPE_EMAIL,
+ MBG_MONITORING_TYPE_SYSLOG,
+ N_MBG_MONITORING_TYPES
+};
+
+#define MBG_MONITORING_TYPE_STRS \
+{ \
+ "SNMP", \
+ "Email", \
+ "Syslog" \
+}
+
+enum MBG_MONITORING_TYPE_MSKS
+{
+ MBG_MONITORING_TYPE_MSK_SNMP = (1UL << MBG_MONITORING_TYPE_SNMP),
+ MBG_MONITORING_TYPE_MSK_EMAIL = (1UL << MBG_MONITORING_TYPE_EMAIL),
+ MBG_MONITORING_TYPE_MSK_SYSLOG = (1UL << MBG_MONITORING_TYPE_SYSLOG)
+};
+
+
+
+typedef struct
+{
+ uint16_t supp_types; ///< See ::MBG_MONITORING_TYPE_MSKS
+ uint16_t supp_num_events; ///< Supported number of events. See ::MBG_EVENT_TYPES
+ uint32_t reserved_2[3];
+
+} MBG_MONITORING_LIMITS;
+
+#define _mbg_swab_monitoring_limits( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->supp_types ); \
+ _mbg_swab16( &(_p)->supp_num_events ); \
+} while ( 0 )
+
+
+
+/* If ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types */
+
+enum MBG_SNMP_VERSIONS
+{
+ MBG_SNMP_VERSION_V1,
+ MBG_SNMP_VERSION_V2c,
+ MBG_SNMP_VERSION_V3,
+ N_MBG_SNMP_VERSIONS
+};
+
+#define MBG_SNMP_VERSION_STRS \
+{ \
+ "Version 1", \
+ "Version 2c", \
+ "Version 3" \
+}
+
+enum MBG_SNMP_VERSION_MSKS
+{
+ MBG_SNMP_VERSION_MSK_V1 = (1UL << MBG_SNMP_VERSION_V1),
+ MBG_SNMP_VERSION_MSK_V2c = (1UL << MBG_SNMP_VERSION_V2c),
+ MBG_SNMP_VERSION_MSK_V3 = (1UL << MBG_SNMP_VERSION_V3)
+};
+
+
+
+typedef struct
+{
+ uint8_t num_v12_settings; ///< Number of configured v1/v2 settings, see ::MBG_SNMP_V12_INFO_IDX
+ uint8_t num_v3_settings; ///< Number of configured v1/v2 trap receivers, see ::MBG_SNMP_V12_TRAP_INFO_IDX
+ uint8_t num_v12_trap_receivers; ///< Number of configured v3 settings, see ::MBG_SNMP_V3_INFO_IDX
+ uint8_t num_v3_trap_receivers; ///< Number of configured v3 trap receivers, see ::MBG_SNMP_V3_TRAP_INFO_IDX
+ uint16_t listening_port; ///< snmpd listening port, 161 by default
+ uint16_t reserved_1;
+ uint32_t reserved_2[3];
+ char location[MBG_MONITORING_STR_SIZE];
+ char contact[MBG_MONITORING_STR_SIZE];
+ char name[MBG_MONITORING_STR_SIZE];
+ char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use
+ char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use
+
+} MBG_SNMP_GLB_SETTINGS;
+
+#define _mbg_swab_snmp_glb_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->listening_port ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ MBG_SNMP_GLB_SETTINGS settings;
+ uint8_t supp_versions; ///< See ::MBG_SNMP_VERSION_MSKS
+ uint8_t max_v12_settings; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V1 or ::MBG_SNMP_VERSION_MSK_V2c
+ uint8_t max_v3_settings; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3
+ uint8_t max_v12_trap_receivers; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V1 or ::MBG_SNMP_VERSION_MSK_V2c
+ uint8_t max_v3_trap_receivers; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[2];
+
+} MBG_SNMP_GLB_INFO;
+
+#define _mbg_swab_snmp_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_glb_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+enum MBG_SNMP_ACCESS_TYPES
+{
+ MBG_SNMP_ACCESS_TYPE_RO,
+ MBG_SNMP_ACCESS_TYPE_RW,
+ N_MBG_SNMP_ACCESS_TYPES
+};
+
+
+#define MBG_SNMP_ACCESS_TYPE_STRS \
+{ \
+ "Read-only", \
+ "Read-write" \
+}
+
+
+
+typedef struct
+{
+ uint8_t version; ///< See ::MBG_SNMP_VERSIONS
+ uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings
+ uint8_t reserved_1[2];
+ uint32_t reserved_2[3];
+ char community[MBG_MONITORING_STR_SIZE];
+
+} MBG_SNMP_V12_SETTINGS;
+
+#define _mbg_swab_snmp_v12_settings( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V12_SETTINGS settings;
+
+} MBG_SNMP_V12_SETTINGS_IDX;
+
+#define _mbg_swab_snmp_v12_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v12_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ MBG_SNMP_V12_SETTINGS settings;
+ uint32_t reserved_1[4];
+
+} MBG_SNMP_V12_INFO;
+
+#define _mbg_swab_snmp_v12_info( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v12_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V12_INFO info;
+
+} MBG_SNMP_V12_INFO_IDX;
+
+#define _mbg_swab_snmp_v12_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v12_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint8_t timeout; ///< In seconds
+ uint8_t retries;
+ uint16_t reserved_1;
+ uint32_t reserved_2[3];
+ char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use
+ char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use
+ MBG_SNMP_V12_SETTINGS v12_settings;
+ MBG_HOSTNAME receiver_addr;
+ uint16_t dest_port; ///< receiver destination port, 162 by default
+ uint16_t reserved_5;
+
+} MBG_SNMP_V12_TRAP_SETTINGS;
+
+#define _mbg_swab_snmp_v12_trap_settings( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v12_settings( &(_p)->v12_settings ); \
+ _mbg_swab16( &(_p)->dest_port ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V12_TRAP_SETTINGS settings;
+
+} MBG_SNMP_V12_TRAP_SETTINGS_IDX;
+
+#define _mbg_swab_snmp_v12_trap_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ MBG_SNMP_V12_TRAP_SETTINGS settings;
+ uint32_t reserved_1[4];
+
+} MBG_SNMP_V12_TRAP_INFO;
+
+#define _mbg_swab_snmp_v12_trap_info( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V12_TRAP_INFO info;
+
+} MBG_SNMP_V12_TRAP_INFO_IDX;
+
+#define _mbg_swab_snmp_v12_trap_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v12_trap_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+enum MBG_SNMP_V3_SEC_LEVELS
+{
+ MBG_SNMP_V3_SEC_LEVEL_NO_AUTH_NO_PRIV,
+ MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV,
+ MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV,
+ N_MBG_SNMP_V3_SEC_LEVELS
+};
+
+#define MBG_SNMP_V3_SEC_LEVEL_STRS \
+{ \
+ "No auth no priv", \
+ "Auth no priv", \
+ "Auth priv" \
+}
+
+
+enum MBG_SNMP_V3_AUTH_PROTOCOLS
+{
+ MBG_SNMP_V3_AUTH_PROTOCOL_NONE,
+ MBG_SNMP_V3_AUTH_PROTOCOL_MD5,
+ MBG_SNMP_V3_AUTH_PROTOCOL_SHA,
+ N_MBG_SNMP_V3_AUTH_PROTOCOLS
+};
+
+#define MBG_SNMP_V3_AUTH_PROTOCOL_STRS \
+{ \
+ "None", \
+ "MD5", \
+ "SHA" \
+}
+
+
+enum MBG_SNMP_V3_PRIV_PROTOCOLS
+{
+ MBG_SNMP_V3_PRIV_PROTOCOL_NONE,
+ MBG_SNMP_V3_PRIV_PROTOCOL_DES,
+ MBG_SNMP_V3_PRIV_PROTOCOL_AES,
+ N_MBG_SNMP_V3_PRIV_PROTOCOLS
+};
+
+
+#define MBG_SNMP_V3_PRIV_PROTOCOL_STRS \
+{ \
+ "None", \
+ "DES", \
+ "AES" \
+}
+
+
+
+typedef struct
+{
+ uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings
+ uint8_t sec_level; ///< See ::MBG_SNMP_V3_SEC_LEVELS
+ uint8_t auth_protocol; ///< See ::MBG_SNMP_V3_AUTH_PROTOCOLS if ::MBG_SNMP_V3_SETTINGS::sec_level
+ ///< is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV or ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV
+ uint8_t priv_protocol; ///< See ::MBG_SNMP_V3_PRIV_PROTOCOLS if ::MBG_SNMP_V3_SETTINGS::sec_level
+ ///< is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV
+ uint32_t reserved_1[3];
+ char user_name[MBG_MONITORING_STR_SIZE]; ///< User name used for authentication, always required.
+ char auth_passwd[MBG_MONITORING_STR_SIZE]; ///< Password associated with ::MBG_SNMP_V3_SETTINGS::user_name, if ::MBG_SNMP_V3_SETTINGS::auth_protocol
+ ///< is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV or ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV
+ char sec_engine_id[MBG_MONITORING_STR_SIZE]; ///< Mandatory
+ char context_engine_id[MBG_MONITORING_STR_SIZE]; ///< Ignore
+ char context_name[MBG_MONITORING_STR_SIZE]; ///< Ignore
+ char reserved_2[MBG_MONITORING_STR_SIZE]; ///< Future use
+ char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use
+ char priv_passwd[MBG_MONITORING_STR_SIZE]; ///< Encryption passwd if ::MBG_SNMP_V3_SETTINGS::auth_protocol is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV
+ uint32_t boots; ///< Number of system/deamon restarts -> Ignore
+ uint32_t time; ///< Timeticks since last "boots" event -> Ignore
+ uint32_t reserved_4[2];
+
+} MBG_SNMP_V3_SETTINGS;
+
+#define _mbg_swab_snmp_v3_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->boots ); \
+ _mbg_swab32( &(_p)->time ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V3_SETTINGS settings;
+
+} MBG_SNMP_V3_SETTINGS_IDX;
+
+#define _mbg_swab_snmp_v3_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v3_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ MBG_SNMP_V3_SETTINGS settings;
+ uint32_t reserved_1[4];
+
+} MBG_SNMP_V3_INFO;
+
+#define _mbg_swab_snmp_v3_info( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v3_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V3_INFO info;
+
+} MBG_SNMP_V3_INFO_IDX;
+
+#define _mbg_swab_snmp_v3_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v3_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint8_t timeout; ///< In seconds
+ uint8_t retries;
+ uint8_t reserved_1[2];
+ uint32_t reserved_2[3];
+ MBG_SNMP_V3_SETTINGS v3_settings;
+ MBG_HOSTNAME receiver_addr;
+ uint16_t dest_port; ///< receiver destination port, 162 by default
+ uint16_t reserved_3;
+
+} MBG_SNMP_V3_TRAP_SETTINGS;
+
+#define _mbg_swab_snmp_v3_trap_settings( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v3_settings( &(_p)->v3_settings ); \
+ _mbg_swab16( &(_p)->dest_port ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V3_TRAP_SETTINGS settings;
+
+} MBG_SNMP_V3_TRAP_SETTINGS_IDX;
+
+#define _mbg_swab_snmp_v3_trap_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ MBG_SNMP_V3_TRAP_SETTINGS settings;
+ uint32_t reserved_1[4];
+
+} MBG_SNMP_V3_TRAP_INFO;
+
+#define _mbg_swab_snmp_v3_trap_info( _p ) \
+do \
+{ \
+ _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SNMP_V3_TRAP_INFO info;
+
+} MBG_SNMP_V3_TRAP_INFO_IDX;
+
+#define _mbg_swab_snmp_v3_trap_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_snmp_v3_trap_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+enum MBG_EVENT_TYPES
+{
+ MBG_EVENT_TYPE_NTP_STATE,
+ MBG_EVENT_TYPE_HEARTBEAT,
+ N_MBG_EVENT_TYPES
+};
+
+#define MBG_EVENT_TYPE_STRS \
+{ \
+ "NTP state", \
+ "Heartbeat" \
+}
+
+enum MBG_EVENT_SEVERITIES
+{
+ MBG_EVENT_SEVERITY_INFO,
+ MBG_EVENT_SEVERITY_WARNING,
+ MBG_EVENT_SEVERITY_ERROR,
+ MBG_EVENT_SEVERITY_CRITICAL,
+ N_MBG_EVENT_SEVERITIES
+};
+
+#define MBG_EVENT_SEVERITY_STRS \
+{ \
+ "Info", \
+ "Warning", \
+ "Error", \
+ "Critical" \
+}
+
+enum MBG_EVENT_SEVERITY_MSKS
+{
+ MBG_EVENT_SEVERITY_MSK_INFO = (1UL << MBG_EVENT_SEVERITY_INFO),
+ MBG_EVENT_SEVERITY_MSK_WARNING = (1UL << MBG_EVENT_SEVERITY_WARNING),
+ MBG_EVENT_SEVERITY_MSK_ERROR = (1UL << MBG_EVENT_SEVERITY_ERROR),
+ MBG_EVENT_SEVERITY_MSK_CRITICAL = (1UL << MBG_EVENT_SEVERITY_CRITICAL)
+};
+
+typedef struct
+{
+ uint8_t severity; ///< See ::MBG_EVENT_SEVERITIES
+ uint8_t reserved_1;
+ uint16_t triggers; ///< See ::MBG_MONITORING_TYPE_MSKS if set in ::MBG_MONITORING_LIMITS::supp_types
+ uint16_t interval; ///< [s], only if ::MBG_EVENT_SUPP_FLAG_INTERVAL is set in ::MBG_EVENT_INFO::supp_flags, else 0.
+ uint16_t reserved_2;
+ uint32_t reserved_3[6];
+
+} MBG_EVENT_SETTINGS;
+
+#define _mbg_swab_event_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->triggers ); \
+ _mbg_swab16( &(_p)->interval ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Structure for monitoring event settings
+ *
+ * @see ::MBG_EVENT_INFO_IDX
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_EVENT_SETTINGS settings;
+
+} MBG_EVENT_SETTINGS_IDX;
+
+#define _mbg_swab_event_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_event_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+
+enum MBG_EVENT_SUPP_FLAGS
+{
+ MBG_EVENT_SUPP_FLAG_INTERVAL, ///< Event can be sent cyclically
+ N_MBG_EVENT_SUPP_FLAGS
+};
+
+
+enum MBG_EVENT_SUPP_FLAG_MSKS
+{
+ MBG_EVENT_SUPP_FLAG_MSK_INTERVAL = ( 1UL << MBG_EVENT_SUPP_FLAG_INTERVAL )
+};
+
+
+
+enum MBG_EVENT_FLAGS
+{
+ MBG_EVENT_FLAG_NOT_AVAIL, ///< Event is currently not available, i.e. card in slot has been removed
+ N_MBG_EVENT_FLAGS
+};
+
+
+enum MBG_EVENT_FLAG_MSKS
+{
+ MBG_EVENT_FLAG_MSK_NOT_AVAIL = ( 1UL << MBG_EVENT_FLAG_NOT_AVAIL )
+};
+
+#define MBG_OWN_EVENT_CHASSIS 0xFF
+#define MBG_OWN_EVENT_SLOT 0xFF
+#define MBG_INV_EVENT_PORT 0xFF
+
+
+
+typedef struct
+{
+ MBG_EVENT_SETTINGS settings;
+ uint16_t type; ///< See ::MBG_EVENT_TYPES
+ uint8_t chassis_idx; ///< Index of the associated IMS chassis
+ uint8_t slot_idx; ///< Index of the associated IMS slot
+ uint8_t port_idx; ///< Index of the associated IO port
+ uint8_t reserved_1; ///< Reserved, currently 0
+ uint16_t reserved_2; ///< Reserved, currently 0
+
+ uint16_t supp_severities; ///< See ::MBG_EVENT_SEVERITY_MSKS
+ uint16_t supp_flags; ///< See ::MBG_EVENT_SUPP_FLAG_MSKS
+ uint16_t supp_triggers; ///< See ::MBG_MONITORING_TYPE_MSKS
+ uint16_t flags; ///< See ::MBG_EVENT_FLAG_MSKS
+
+ uint32_t reserved_3[4];
+
+} MBG_EVENT_INFO;
+
+#define _mbg_swab_event_info( _p ) \
+do \
+{ \
+ _mbg_swab_event_settings( &(_p)->settings ); \
+ _mbg_swab16( &(_p)->type ); \
+ _mbg_swab16( &(_p)->supp_severities ); \
+ _mbg_swab16( &(_p)->supp_flags ); \
+ _mbg_swab16( &(_p)->supp_triggers ); \
+ _mbg_swab16( &(_p)->flags ); \
+} while ( 0 )
+
+
+
+/**
+ * @brief Structure for monitoring event info
+ *
+ * @note idx represents the event type, see ::MBG_EVENT_TYPES
+ * Before requesting the struct, its availability should be checked
+ * in ::MBG_MONITORING_LIMITS::supp_num_events.
+ *
+ * @see ::MBG_EVENT_TYPES
+ * @see ::MBG_MONITORING_LIMITS
+ */
+typedef struct
+{
+ uint32_t idx;
+ MBG_EVENT_INFO info;
+
+} MBG_EVENT_INFO_IDX;
+
+#define _mbg_swab_event_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_event_info( &(_p)->info ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint8_t snmp_cfg_counter; ///< Updated (increased) when SNMP config changes
+ uint8_t email_cfg_counter; ///< Updated (increased) when Email config changes
+ uint8_t syslog_cfg_counter; ///< Updated (increased) when Syslog config changes
+ uint8_t event_cfg_counter; ///< Updated (increased) when event config changes
+ uint32_t reserved_2[3];
+
+} MBG_MONITORING_STATUS;
+
+#define _mbg_swab_monitoring_status( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+
+enum MBG_EVENT_STATUS_FLAGS
+{
+ MBG_EVENT_STATUS_FLAG_ACTIVE, ///< Event is currently active
+ N_MBG_EVENT_STATUS_FLAGS
+};
+
+
+enum MBG_EVENT_STATUS_FLAG_MSKS
+{
+ MBG_EVENT_STATUS_FLAG_MSK_ACTIVE = (1UL << MBG_EVENT_STATUS_FLAG_ACTIVE)
+};
+
+
+
+typedef struct
+{
+ uint16_t flags; ///< See ::MBG_EVENT_STATUS_FLAGS
+ uint16_t reserved_1;
+ uint32_t last_triggered; ///< Unix timestamp when this event has been triggered
+ uint32_t reserved_2[6];
+
+} MBG_EVENT_STATUS;
+
+#define _mbg_swab_event_status( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->last_triggered ); \
+} while ( 0 )
+
+
+
+typedef struct
+{
+ uint16_t idx;
+ MBG_EVENT_STATUS status;
+
+} MBG_EVENT_STATUS_IDX;
+
+#define _mbg_swab_event_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->idx ); \
+ _mbg_swab_event_status( &(_p)->status ); \
+} while ( 0 )
+
+/** @} defgroup group_monitoring */
+
+
+/**
+ * @defgroup group_usb_lock USB locks
+ *
+ * @note This structure and its definitions are only supported by a device
+ * if ::MBG_XFEATURE_USB_LOCK is set in the extended device features.
+ * Feature can electrically disconnect an USB slave device from
+ * the USB host bus. It cannot be reset via software, it's a one way action only.
+ *
+ * TODO: Add proper Doxygen documentation
+ *
+ * @{ */
+
+
+enum MBG_USB_LOCK_FLAGS
+{
+ MBG_USB_LOCK_FLAG_ACTIVE, ///< USB connection is interrupted
+ N_MBG_USB_LOCK_FLAGS
+};
+
+
+enum MBG_USB_LOCK_FLAG_MSKS
+{
+ MBG_USB_LOCK_FLAG_MSK_ACTIVE = (1UL << MBG_USB_LOCK_FLAG_ACTIVE) ///< See ::MBG_USB_LOCK_FLAG_ACTIVE
+};
+
+
+typedef struct
+{
+ uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[3];
+
+} MBG_USB_LOCK_SETTINGS;
+
+#define _mbg_swab_usb_lock_settings( _p ) do {} while ( 0 )
+
+
+typedef struct
+{
+ MBG_USB_LOCK_SETTINGS settings;
+ uint8_t supp_flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[3];
+
+} MBG_USB_LOCK_INFO;
+
+#define _mbg_swab_usb_lock_info( _p ) \
+do \
+{ \
+ _mbg_swab_usb_lock_settings( _p ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[3];
+
+} MBG_USB_LOCK_STATUS;
+
+#define _mbg_swab_usb_lock_status( _p ) do {} while ( 0 )
+
+
+/** @} defgroup group_usb_lock */
+
+
#if defined( _USING_BYTE_ALIGNMENT )
#pragma pack() // set default alignment
#undef _USING_BYTE_ALIGNMENT
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.c b/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.c
index f493af9..48cefc1 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsutils.c 1.4.1.3 2010/07/15 13:33:43 martin TEST $
+ * $Id: gpsutils.c 1.10 2017/07/05 13:57:06 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,12 +10,22 @@
*
* -----------------------------------------------------------------------
* $Log: gpsutils.c $
- * Revision 1.4.1.3 2010/07/15 13:33:43 martin
+ * Revision 1.10 2017/07/05 13:57:06 martin
+ * Use save string functions from str_util.c.
+ * Quieted some compiler warninges.
+ * Added doxygen comments.
+ * Revision 1.9 2013/01/30 16:10:08 martin
+ * Exclude some code from compiling by default, and
+ * thus don't require pcpslstr.h by default.
+ * Revision 1.8 2012/10/15 14:27:05Z martin
+ * Exclude sprint_fixed_freq() from build except for Borland C / Windows.
+ * Revision 1.7 2010/07/15 09:32:09 martin
* Use DEG character definition from pcpslstr.h.
- * Revision 1.4.1.2 2004/11/09 14:42:36Z martin
- * Use C99 fixed-size types in swap_double().
- * Revision 1.4.1.1 2003/05/16 08:36:27 MARTIN
- * Fixed sprint_dms() to work correctly under QNX.
+ * Revision 1.6 2004/12/28 11:21:26Z martin
+ * Omit trap if fixed_freq is 0.
+ * Use C99 fixed-size data types were required.
+ * Revision 1.5 2003/02/04 09:20:04Z MARTIN
+ * New functions sprint_alt(), sprint_fixed_freq().
* Revision 1.4 2003/01/31 13:45:19 MARTIN
* sprint_pos_geo() returns N/A if position not valid.
* Revision 1.3 2002/12/12 16:07:04 martin
@@ -32,26 +42,71 @@
#include <gpsutils.h>
#undef _GPSUTILS
-#include <pcpslstr.h>
+#if defined( USE_SPRINTF )
+ #error USE_SPRINTF was obsoleted by USE_SNPRINTF. Please update project settings.
+#endif
+
+#if !defined( USE_SNPRINTF )
+ #define USE_SNPRINTF 0
+#endif
+
+#if !defined( _USE_GPSUTILS_FULL )
+ #if defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ )
+ #define _USE_GPSUTILS_FULL 1
+ #else
+ #define _USE_GPSUTILS_FULL 0
+ #endif
+#endif
+
+#if USE_SNPRINTF
+ #include <str_util.h>
+
+ #define DEG "deg"
+#endif
+
+#if _USE_GPSUTILS_FULL
+ #include <str_util.h>
+ #include <math.h>
+#endif
#include <stdio.h>
#include <string.h>
+#if USE_SNPRINTF || _USE_GPSUTILS_FULL
+
+static const char str_na[] = "N/A";
+
+#endif
-#define _eos( _s ) ( &(_s)[strlen( _s )] )
/*HDR*/
-void swap_double( double *d )
+/**
+ * @brief Swap the bytes of a single variable of type "double"
+ *
+ * The memory layout of a "double" on Meinberg bus level devices
+ * and computers usually differs. This function can be used to
+ * fix this and is usually called from inside API functions,
+ * if required.
+ *
+ * @param[in,out] p Pointer to a "double" to be swapped
+ *
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+void swap_double( double *p )
{
uint16_t *wp1;
uint16_t *wp2;
uint16_t w;
int i;
- wp1 = (uint16_t *) d;
- wp2 = ( (uint16_t *) d ) + 3;
+ wp1 = (uint16_t *) p;
+ wp2 = ( (uint16_t *) p ) + 3;
for ( i = 0; i < 2; i++ )
{
@@ -62,133 +117,370 @@ void swap_double( double *d )
wp2--;
}
-} /* swap_double */
+} // swap_double
/*HDR*/
-void swap_eph_doubles( EPH *ephp )
+/**
+ * @brief Swap the "double" fields in an ::EPH structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to an ::EPH structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+void swap_eph_doubles( EPH *p )
{
- swap_double( &ephp->sqrt_A );
- swap_double( &ephp->e );
- swap_double( &ephp->M0 );
- swap_double( &ephp->omega );
- swap_double( &ephp->i0 );
- swap_double( &ephp->OMEGA0 );
- swap_double( &ephp->OMEGADOT );
-
- swap_double( &ephp->deltan );
- swap_double( &ephp->idot );
-
- swap_double( &ephp->crc );
- swap_double( &ephp->crs );
- swap_double( &ephp->cuc );
- swap_double( &ephp->cus );
- swap_double( &ephp->cic );
- swap_double( &ephp->cis );
-
- swap_double( &ephp->af0 );
- swap_double( &ephp->af1 );
- swap_double( &ephp->af2 );
-
- swap_double( &ephp->tgd );
+ swap_double( &p->sqrt_A );
+ swap_double( &p->e );
+ swap_double( &p->M0 );
+ swap_double( &p->omega );
+ swap_double( &p->i0 );
+ swap_double( &p->OMEGA0 );
+ swap_double( &p->OMEGADOT );
+
+ swap_double( &p->deltan );
+ swap_double( &p->idot );
+
+ swap_double( &p->crc );
+ swap_double( &p->crs );
+ swap_double( &p->cuc );
+ swap_double( &p->cus );
+ swap_double( &p->cic );
+ swap_double( &p->cis );
+
+ swap_double( &p->af0 );
+ swap_double( &p->af1 );
+ swap_double( &p->af2 );
+
+ swap_double( &p->tgd );
} /* swap_eph_doubles */
/*HDR*/
-void swap_alm_doubles( ALM *almp )
+/**
+ * @brief Swap the "double" fields in an ::ALM structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to an ::ALM structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+void swap_alm_doubles( ALM *p )
{
- swap_double( &almp->sqrt_A );
- swap_double( &almp->e );
- swap_double( &almp->deltai );
- swap_double( &almp->OMEGA0 );
- swap_double( &almp->OMEGADOT );
- swap_double( &almp->omega );
- swap_double( &almp->M0 );
- swap_double( &almp->af0 );
- swap_double( &almp->af1 );
+ swap_double( &p->sqrt_A );
+ swap_double( &p->e );
+ swap_double( &p->deltai );
+ swap_double( &p->OMEGA0 );
+ swap_double( &p->OMEGADOT );
+ swap_double( &p->omega );
+ swap_double( &p->M0 );
+ swap_double( &p->af0 );
+ swap_double( &p->af1 );
} /* swap_alm_doubles */
/*HDR*/
-void swap_utc_doubles( UTC *utcp )
+/**
+ * @brief Swap the "double" fields in a ::UTC structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::UTC structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+void swap_utc_doubles( UTC *p )
{
- swap_double( &utcp->A0 );
- swap_double( &utcp->A1 );
+ swap_double( &p->A0 );
+ swap_double( &p->A1 );
} /* swap_utc_doubles */
/*HDR*/
-void swap_iono_doubles( IONO *ionop )
+/**
+ * @brief Swap the "double" fields in a ::IONO structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::IONO structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_pos_doubles
+ */
+void swap_iono_doubles( IONO *p )
{
- swap_double( &ionop->alpha_0 );
- swap_double( &ionop->alpha_1 );
- swap_double( &ionop->alpha_2 );
- swap_double( &ionop->alpha_3 );
+ swap_double( &p->alpha_0 );
+ swap_double( &p->alpha_1 );
+ swap_double( &p->alpha_2 );
+ swap_double( &p->alpha_3 );
- swap_double( &ionop->beta_0 );
- swap_double( &ionop->beta_1 );
- swap_double( &ionop->beta_2 );
- swap_double( &ionop->beta_3 );
+ swap_double( &p->beta_0 );
+ swap_double( &p->beta_1 );
+ swap_double( &p->beta_2 );
+ swap_double( &p->beta_3 );
} /* swap_iono_doubles */
/*HDR*/
-void swap_pos_doubles( POS *posp )
+/**
+ * @brief Swap the "double" fields in a ::POS structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::POS structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ */
+void swap_pos_doubles( POS *p )
{
int i;
for ( i = 0; i < N_XYZ; i++ )
- swap_double( &posp->xyz[i] );
+ swap_double( &p->xyz[i] );
for ( i = 0; i < N_LLA; i++ )
- swap_double( &posp->lla[i] );
+ swap_double( &p->lla[i] );
- swap_double( &posp->longitude.sec );
- swap_double( &posp->latitude.sec );
+ swap_double( &p->longitude.sec );
+ swap_double( &p->latitude.sec );
} /* swap_pos_doubles */
+#if USE_SNPRINTF
+
/*HDR*/
-void sprint_dms( char *s, DMS *pdms, int prec )
+/**
+ * @brief Print the ::DMS part of a geo position into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p Pointer to a ::DMS structure to be printed
+ * @param[in] prec Precision, i.e. number of fractions of the seconds
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_pos_geo
+ * @see snprint_fixed_freq
+ */
+size_t snprint_dms( char *s, size_t max_len, const DMS *p, int prec )
{
- sprintf( s, "%c %i" DEG "%02i'%02.*f\"",
- pdms->prefix,
- pdms->deg,
- pdms->min,
- prec,
- pdms->sec
- );
+ size_t n = snprintf_safe( s, max_len, "%c %i" DEG "%02i'%02.*f\"",
+ p->prefix, p->deg, p->min,
+ prec, p->sec );
+
+ return n;
-} /* sprint_dms */
+} // snprint_dms
/*HDR*/
-void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec )
+/**
+ * @brief Print the altitude part of a geo position into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] alt The altitude value to be printed, in [m]
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_pos_geo
+ * @see snprint_fixed_freq
+ */
+size_t snprint_alt( char *s, size_t max_len, double alt )
+{
+ size_t n = snprintf_safe( s, max_len, "%.0fm", alt );
+
+ return n;
+
+} // snprint_alt
+
+
+
+/*HDR*/
+/**
+ * @brief Print a geo position in ::POS format into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p Pointer to a ::POS structure to be printed
+ * @param[in] sep Separator character for the ::DMS part
+ * @param[in] prec Precision, i.e. number of fractions of the seconds of the ::DMS part
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_fixed_freq
+ */
+size_t snprint_pos_geo( char *s, size_t max_len, const POS *p, char sep, int prec )
{
- if ( ppos->lla[LON] && ppos->lla[LAT] && ppos->lla[ALT] )
+ size_t n = 0;
+
+ if ( p->lla[LON] && p->lla[LAT] && p->lla[ALT] )
+ {
+ n += snprint_dms( &s[n], max_len - n, &p->latitude, prec );
+ n += snprintf_safe( &s[n], max_len - n, "%c", sep );
+ n += snprint_dms( &s[n], max_len - n, &p->longitude, prec );
+ n += snprintf_safe( &s[n], max_len - n, "%c", sep );
+ n += snprint_alt( &s[n], max_len - n, p->lla[ALT] );
+ }
+ else
+ n = sn_cpy_str_safe( s, max_len, str_na );
+
+ return n;
+
+} // snprint_pos_geo
+
+#endif // USE_SNPRINTF
+
+
+
+#if _USE_GPSUTILS_FULL
+
+/*HDR*/
+/**
+ * @brief Print a formatted ::FIXED_FREQ_INFO into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_ff Pointer to a ::FIXED_FREQ_INFO structure to be printed
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_pos_geo
+ */
+size_t snprint_fixed_freq( char *s, size_t max_len, FIXED_FREQ_INFO *p_ff )
+{
+ double freq;
+ int range;
+ ushort unit;
+ ushort format;
+ size_t n = 0;
+
+ // Before re-calculating frequency, range is the base 10 exponent
+ // to the frequency value which is represented in kHz.
+ // After calculating range from real frequency, range is represented
+ // as follows:
+ // range display format divisor format index calculation
+ // -3 100mHz 1.000 [/1e-3] -3 % 3 = -3 + 3 = 0 % 3 = 0
+ // -2 100mHz 10.00 [/1e-3] -2 % 3 = -2 + 3 = 1 % 3 = 1
+ // -1 100mHz 100.0 [/1e-3] -1 % 3 = -1 + 3 = 2 % 3 = 2
+ // 0 1Hz 1.000 [/1e0] 0 % 3 = 0 + 3 = 3 % 3 = 0
+ // 1 10Hz 10.00 [/1e0] 1 % 3 = 1 + 3 = 1 % 3 = 1
+ // 2 100Hz 100.0 [/1e0] 2 % 3 = 2 + 3 = 2 % 3 = 2
+ // 3 1kHz 1.000 [/1e3] 3 % 3 = 0 + 3 = 3 % 3 = 0
+ // 4 10kHz 10.00 [/1e3] 4 % 3 = 1 + 3 = 4 % 3 = 1
+ // 5 100kHz 100.0 [/1e3] 5 % 3 = 2 + 3 = 5 % 3 = 2
+ // 6 1MHz 1.000 [/1e6] 6 % 3 = 0 + 3 = 3 % 3 = 0
+ // 7 10MHz 10.00 [/1e6] 7 % 3 = 1 + 3 = 4 % 3 = 1
+ // 8 100MHz 100.0 [/1e6] 8 % 3 = 2 + 3 = 5 % 3 = 2
+
+ // format string for fp output
+ static const char *fmt_str[] =
+ {
+ "%4.3lf%s",
+ "%4.2lf%s",
+ "%4.1lf%s",
+ };
+
+ // Unit index and divisor are calculated as follows:
+ // range unit index calculation divisor calculation
+ // -3 mHz ( int )( ( -3 + 3 ) / 3 ) = 0
+ // -2 mHz ( int )( ( -2 + 3 ) / 3 ) = 0
+ // -1 mHz ( int )( ( -1 + 3 ) / 3 ) = 0 / 10e-3 = 10e( 3 * 0 - 3 )
+ // 0 Hz ( int )( ( 0 + 3 ) / 3 ) = 1
+ // 1 Hz ( int )( ( 1 + 3 ) / 3 ) = 1
+ // 2 Hz ( int )( ( 2 + 3 ) / 3 ) = 1 / 1e0 = 10e( 3 * 1 - 3 )
+ // 3 kHz ( int )( ( 3 + 3 ) / 3 ) = 2
+ // 4 kHz ( int )( ( 4 + 3 ) / 3 ) = 2
+ // 5 kHz ( int )( ( 5 + 3 ) / 3 ) = 2 / 10e3 = 10e( 3 * 2 - 3 )
+ // 6 MHz ( int )( ( 6 + 3 ) / 3 ) = 3
+ // 7 MHz ( int )( ( 7 + 3 ) / 3 ) = 3
+ // 8 MHz ( int )( ( 8 + 3 ) / 3 ) = 3 / 10e6 =10e( 3 * 3 - 3 )
+
+ // unit string
+ static const char *unit_str[] =
+ {
+ "mHz",
+ "Hz",
+ "kHz",
+ "MHz"
+ };
+
+
+ if ( p_ff->khz_val )
{
- sprint_dms( s, &ppos->latitude, prec );
- strcat( s, sep );
- sprint_dms( _eos( s ), &ppos->longitude, prec );
- strcat( s, sep );
- sprintf( _eos( s ), "%.0fm", ppos->lla[ALT] );
+ // calculate frequency in Hz
+ freq = ( double ) p_ff->khz_val * pow( 10, ( p_ff->range + 3 ) );
+
+ // calculate decimal exponent
+ range = ( ( int ) log10( freq ) );
+
+ // check whether range is in the allowed range
+ // if so display frequency in broken format
+ if ( ( range >= -3 ) && ( range <= 8 ) )
+ {
+ // calculate format index ( see above )
+ format = ( ( ( range % 3 ) + 3 ) % 3 );
+
+ // calculate unit index
+ unit = ( ushort )( range + 3 ) / 3;
+
+ // calculate display value
+ freq = freq / pow( 10, ( ( 3 * unit ) - 3 ) );
+ n = snprintf_safe( s, max_len, fmt_str[format], freq, unit_str[unit] );
+ }
+ else
+ {
+ // out of range display fequency in Hz
+ n = snprintf_safe( s, max_len, "%fHz", freq );
+ }
}
else
- strcpy( s, "N/A" );
+ n = sn_cpy_str_safe( s, max_len, str_na );
-} /* sprint_pos_geo */
+ return n;
+} // snprint_fixed_freq
+#endif // _USE_GPSUTILS_FULL
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.h b/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.h
index 8716adf..fd25e3e 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/gpsutils.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsutils.h 1.4.1.2 2010/07/15 09:19:04 martin REL_M $
+ * $Id: gpsutils.h 1.8 2017/07/05 13:58:25 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,10 +10,15 @@
*
* -----------------------------------------------------------------------
* $Log: gpsutils.h $
- * Revision 1.4.1.2 2010/07/15 09:19:04 martin
+ * Revision 1.8 2017/07/05 13:58:25 martin
+ * Include stddef.h.
+ * Updated function prototypes.
+ * Revision 1.7 2010/07/15 09:32:09 martin
* Use DEG character definition from pcpslstr.h.
- * Revision 1.4.1.1 2003/05/15 09:40:25Z martin
- * Changed degree string/char for QNX.
+ * 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.
@@ -32,6 +37,8 @@
#include <mbggeo.h>
+#include <stddef.h>
+
#ifdef _GPSUTILS
#define _ext
@@ -43,26 +50,174 @@
/* Start of header body */
-
-/* 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_pos_geo( char *s, POS *ppos, const char *sep, int prec ) ;
+ /**
+ * @brief Swap the bytes of a single variable of type "double"
+ *
+ * The memory layout of a "double" on Meinberg bus level devices
+ * and computers usually differs. This function can be used to
+ * fix this and is usually called from inside API functions,
+ * if required.
+ *
+ * @param[in,out] p Pointer to a "double" to be swapped
+ *
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+ void swap_double( double *p ) ;
+
+ /**
+ * @brief Swap the "double" fields in an ::EPH structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to an ::EPH structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+ void swap_eph_doubles( EPH *p ) ;
+
+ /**
+ * @brief Swap the "double" fields in an ::ALM structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to an ::ALM structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+ void swap_alm_doubles( ALM *p ) ;
+
+ /**
+ * @brief Swap the "double" fields in a ::UTC structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::UTC structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_iono_doubles
+ * @see ::swap_pos_doubles
+ */
+ void swap_utc_doubles( UTC *p ) ;
+
+ /**
+ * @brief Swap the "double" fields in a ::IONO structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::IONO structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_pos_doubles
+ */
+ void swap_iono_doubles( IONO *p ) ;
+
+ /**
+ * @brief Swap the "double" fields in a ::POS structure
+ *
+ * See comments for ::swap_double
+ *
+ * @param[in,out] p Pointer to a ::POS structure to be converted
+ *
+ * @see ::swap_double
+ * @see ::swap_eph_doubles
+ * @see ::swap_alm_doubles
+ * @see ::swap_utc_doubles
+ * @see ::swap_iono_doubles
+ */
+ void swap_pos_doubles( POS *p ) ;
+
+ /**
+ * @brief Print the ::DMS part of a geo position into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p Pointer to a ::DMS structure to be printed
+ * @param[in] prec Precision, i.e. number of fractions of the seconds
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_pos_geo
+ * @see snprint_fixed_freq
+ */
+ size_t snprint_dms( char *s, size_t max_len, const DMS *p, int prec ) ;
+
+ /**
+ * @brief Print the altitude part of a geo position into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] alt The altitude value to be printed, in [m]
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_pos_geo
+ * @see snprint_fixed_freq
+ */
+ size_t snprint_alt( char *s, size_t max_len, double alt ) ;
+
+ /**
+ * @brief Print a geo position in ::POS format into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p Pointer to a ::POS structure to be printed
+ * @param[in] sep Separator character for the ::DMS part
+ * @param[in] prec Precision, i.e. number of fractions of the seconds of the ::DMS part
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_fixed_freq
+ */
+ size_t snprint_pos_geo( char *s, size_t max_len, const POS *p, char sep, int prec ) ;
+
+ /**
+ * @brief Print a formatted ::FIXED_FREQ_INFO into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_ff Pointer to a ::FIXED_FREQ_INFO structure to be printed
+ *
+ * @return Length of the string in the buffer
+ *
+ * @see snprint_dms
+ * @see snprint_alt
+ * @see snprint_pos_geo
+ */
+ size_t snprint_fixed_freq( char *s, size_t max_len, FIXED_FREQ_INFO *p_ff ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/identdec.h b/src/external/bsd/meinberg/dist/mbglib/common/identdec.h
index 6054ec7..2eff9fc 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/identdec.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/identdec.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: identdec.h 1.1 2002/02/19 13:46:19 MARTIN REL_M $
+ * $Id: identdec.h 1.2 2017/05/10 15:21:36 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,8 @@
*
* -----------------------------------------------------------------------
* $Log: identdec.h $
+ * Revision 1.2 2017/05/10 15:21:36 martin
+ * Tiny cleanup.
* Revision 1.1 2002/02/19 13:46:19 MARTIN
* Initial revision
*
@@ -34,16 +36,11 @@
/* Start of header body */
-
-
-
-
-/* function prototypes: */
-
#ifdef __cplusplus
extern "C" {
#endif
+
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/lan_util.c b/src/external/bsd/meinberg/dist/mbglib/common/lan_util.c
index 03734c4..5fc9de1 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/lan_util.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/lan_util.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: lan_util.c 1.1.1.3 2011/06/21 15:23:30 martin TRASH $
+ * $Id: lan_util.c 1.12 2017/07/05 14:07:56 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,12 +10,54 @@
*
* -----------------------------------------------------------------------
* $Log: lan_util.c $
- * Revision 1.1.1.3 2011/06/21 15:23:30 martin
- * Fixed build under DOS.
- * Revision 1.1.1.2 2011/04/20 16:08:55Z martin
- * Revision 1.1.1.1 2011/03/04 10:33:22 martin
- * Implemented dummy snprintf() function for environments
- * which don't provide this.
+ * Revision 1.12 2017/07/05 14:07:56 martin
+ * IPv6 support functions added by hannes.
+ * Function snprint_ip4_cidr_mask() fixed by hannes. It now behaves
+ * as expected and appends the CIDR mask bits to the IP address now.
+ * Mostly use safe string functions from str_util.c.
+ * New function snprint_ptp_clock_id().
+ * Compiler warnings due to uninitialized vars quieted by thomas-b.
+ * Renamed check_octets_not_all_zero() to octets_are_all_zero(),
+ * which returns a bool now.
+ * Renamed check_mac_addr_not_all_zero() to mac_addr_all_zero(),
+ * which returns a bool now.
+ * Removed get_port_mac_addr_check().
+ * Removed definitions of old MBG_LU_... return codes, and
+ * only use standard MBG_RETURN_CODES instead.
+ * Fixed macro definition syntax to quiet clang compiler warnings.
+ * Let get_port_ip4_settings() check port link even if it
+ * returns an error (changed by daniel).
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Doxygen comments.
+ * Revision 1.11 2015/04/01 14:31:14 hannes
+ * Fix: cidr_str_to_ip4_addr_and_net_mask: Defaults correctly to
+ * netmask 0.0.0.0 (/0) for no CIDR extension in cidr_str.
+ * Revision 1.10 2014/10/17 12:45:48 martin
+ * Let str_to_ip4_addr() return 0 if an empty string has been passed.
+ * Revision 1.9 2014/09/24 08:31:00 martin
+ * Exclude get_ip4_gateway() from build if USE_MBG_TSU is defined.
+ * Fixed some compiler warnings.
+ * Added and modified some comments.
+ * Revision 1.8 2013/10/02 07:19:13 martin
+ * New function get_port_intf_idx.
+ * Fixed naming.of local netlink support functions.
+ * Revision 1.7 2013/05/22 16:49:42 martin
+ * Fixed some return codes.
+ * Revision 1.6 2013/03/19 10:24:51 martin
+ * Fixed bugs in get_ip4_gateway(): A skipped routing entry was
+ * taken as default route, and thus a wrong default route 0.0.0.0
+ * could be returned erraneously. Also, malloc() was used without
+ * checking the result.
+ * Added conditional debug code.
+ * Revision 1.5 2013/02/19 15:13:10 martin
+ * Added some new functions.
+ * Updated doxygen comments.
+ * Revision 1.4 2012/11/02 09:16:57 martin
+ * Fixed build under Windows.
+ * Revision 1.3 2012/10/02 18:23:28Z martin
+ * Removed obsolete code to avoid compiler warning.
+ * Revision 1.2 2012/03/09 08:49:19 martin
+ * Added some commonly used functions.
* Revision 1.1 2011/03/04 10:01:32Z martin
* Initial revision.
*
@@ -25,61 +67,932 @@
#include <lan_util.h>
#undef _LAN_UTIL
+#include <words.h>
+#include <str_util.h>
+#include <mbgerror.h>
+
#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#if defined( MBG_TGT_POSIX )
-#if defined( __BORLANDC__ ) \
- && ( __BORLANDC__ <= 0x410 ) // BC3.1 defines 0x410 !
+ #if defined( MBG_TGT_LINUX )
+ #include <linux/types.h>
-#include <stdarg.h>
+ // Some older versions of linux/types.h don't define u8..u64
+ // for user space applications. However, if they do they also
+ // define BITS_PER_LONG, so we use this symbol to figure out
+ // if we need to define u8..u64 by ourselves.
+ #if !defined( BITS_PER_LONG )
+ typedef uint8_t u8;
+ typedef uint16_t u16;
+ typedef uint32_t u32;
+ typedef uint64_t u64;
+ #endif
-static /*HDR*/
-int snprintf( char *s, size_t max_len, const char *fmt, ... )
+ #include <linux/sockios.h>
+ #include <linux/ethtool.h>
+ #include <linux/rtnetlink.h>
+ #endif
+
+ #include <unistd.h>
+ #include <syslog.h>
+ #include <sys/ioctl.h>
+ #include <arpa/inet.h>
+ #include <netinet/in.h>
+
+#else
+
+ // dummy codes, the functions will report an error ...
+ #define SIOCGIFADDR 0
+ #define SIOCGIFNETMASK 0
+ #define SIOCGIFBRDADDR 0
+
+ #if defined( MBG_TGT_WIN32 )
+ #define snprintf _snprintf
+ #endif
+
+#endif
+
+
+#if !defined( DEBUG_NETLINK )
+ #if ( 0 && defined( DEBUG ) && defined( MBG_TGT_LINUX ) )
+ #define DEBUG_NETLINK 1
+ #else
+ #define DEBUG_NETLINK 0
+ #endif
+#endif
+
+
+#if DEBUG_NETLINK
+ // we need a function to output debugging information
+ #if !defined STANDALONE
+ #include <ptp2_cnf.h> // for mbglog() from the ARM PTP projects
+ #else
+ // to be provided by the application
+ extern __attribute__( ( format( printf, 2, 3 ) ) ) void mbglog( int priority, const char *fmt, ... );
+ #endif
+#endif // DEBUG_NETLINK
+
+
+
+// Maximum size of an IPv4 address string in dotted quad format,
+// including a terminating 0, and thus the required minimum size
+// for a buffer to take such a string. i.e. "aaa.bbb.ccc.ddd\0".
+#define MAX_IP4_ADDR_STR_SIZE 16
+
+
+#if defined( MBG_TGT_LINUX )
+
+struct route_info
+{
+ struct in_addr dstAddr;
+ struct in_addr srcAddr;
+ struct in_addr gateWay;
+ char ifName[IF_NAMESIZE];
+};
+
+#endif
+
+
+
+/*HDR*/
+/**
+ * @brief Count the number of sequential bits in an IPv4 net mask
+ *
+ * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results
+ * are both 2 since only the 2 MSBs are sequentially set.
+ *
+ * @param[in] p_mask The IPv4 net mask to be evaluated
+ *
+ * @return The number of sequential MSB bits set in *p_mask
+ *
+ * @see ::ip4_net_mask_from_cidr
+ */
+int get_ip4_net_mask_bits( const IP4_ADDR *p_mask )
+{
+ IP4_ADDR msb_mask = IP4_MSB_MASK;
+ int i;
+
+ for ( i = 0; i < MAX_IP4_BITS; i++ )
+ {
+ if ( ( *p_mask & msb_mask ) == 0 )
+ break;
+
+ msb_mask >>= 1;
+ }
+
+ return i;
+
+} // get_ip4_net_mask_bits
+
+
+
+/*HDR*/
+/**
+ * @brief Print an IPv4 address to a dotted quad formatted string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv4 address to be evaluated
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
+ */
+size_t snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const char *info )
{
- int n;
- va_list arg_list;
+ size_t n = 0;
+ ulong ul = *p_addr;
- va_start( arg_list, fmt );
- n = vsprintf( s, fmt, arg_list );
- va_end( arg_list );
+ if ( info )
+ n += snprintf_safe( s, max_len, "%s", info );
+ // Don't use byte pointers here since this is not safe
+ // for both little and big endian targets.
+ n += snprintf_safe( &s[n], max_len - n, "%u.%u.%u.%u",
+ BYTE_3( ul ), BYTE_2( ul ),
+ BYTE_1( ul ), BYTE_0( ul )
+ );
return n;
-} // snprintf
+} // snprint_ip4_addr
-#endif
+
+
+/*HDR*/
+/**
+ * @brief Print an IPv4 address plus net mask in CIDR notation to a string
+ *
+ * The printed CIDR string is something like "172.16.3.250/24"
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv4 address to be evaluated
+ * @param[in] p_mask The associated IPv4 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::str_to_ip4_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
+ */
+size_t snprint_ip4_cidr_addr( char *s, size_t max_len, const IP4_ADDR *p_addr,
+ const IP4_ADDR *p_mask, const char *info )
+{
+ int cidr_mask_bits;
+ size_t n = snprint_ip4_addr( s, max_len, p_addr, info );
+
+ cidr_mask_bits = get_ip4_net_mask_bits( p_mask );
+
+ if ( ( cidr_mask_bits >= MIN_IP4_CIDR_NETMASK_BITS ) &&
+ ( cidr_mask_bits <= MAX_IP4_CIDR_NETMASK_BITS ) )
+ n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits );
+
+ return n;
+
+} // snprint_ip4_cidr_addr
/*HDR*/
/**
- * @brief Print a MAC ID or similar array of octets to a string.
+ * @brief Convert a string to an ::IP4_ADDR
+ *
+ * If output parameter is specified as NULL then this function
+ * can be used to check if the IPv4 address string is formally correct.
*
- * @param s The string buffer into which to print
- * @param max_len Maximum length of the string, i.e. size of the buffer
- * @param octets An array of octets
- * @param num_octets The number of octets to be printed from the array
- * @param sep The separator printed between the bytes, or 0
- * @param info An optional string which is prepended to the output, or NULL
+ * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled, or NULL
+ * @param[in] s An IPv4 address string to be converted
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
+ */
+int str_to_ip4_addr( IP4_ADDR *p_addr, const char *s )
+{
+ IP4_ADDR tmp_ip4_addr = 0;
+ const char *cp = s;
+ int i;
+
+ if ( strlen( s ) )
+ {
+ for ( i = 0; ; )
+ {
+ unsigned long ul = strtoul( (char *) cp, (char **) &cp, 10 );
+
+ if ( ul > 0xFFUL ) // invalid number
+ return MBG_ERR_PARM_FMT;
+
+ tmp_ip4_addr |= ul << ( 8 * (3 - i) );
+
+ if ( ++i >= 4 )
+ break; // done
+
+ if ( *cp != '.' )
+ return MBG_ERR_PARM_FMT; // invalid string format, dot expected
+
+ cp++; // skip dot
+ }
+ }
+
+ if ( p_addr )
+ *p_addr = tmp_ip4_addr;
+
+ // success: return the number of evaluated chars
+ return (int) ( cp - s );
+
+} // str_to_ip4_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Convert a string in CIDR notation to an ::IP4_ADDR and net mask
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled with
+ * the IPv4 address, or NULL
+ * @param[out] p_mask Pointer to an ::IP4_ADDR variable to be filled with
+ * the IPv4 net mask, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "172.16.3.250/24"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ */
+int cidr_str_to_ip4_addr_and_net_mask( IP4_ADDR *p_addr, IP4_ADDR *p_mask,
+ const char *cidr_str )
+{
+ IP4_ADDR mask;
+ long cidr_mask_bits;
+ const char *cp;
+ int l;
+ int rc = str_to_ip4_addr( p_addr, cidr_str );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+
+ l = (int) strlen( cidr_str );
+
+ if ( l < rc ) // input string too short
+ return MBG_ERR_PARM_FMT;
+
+
+ cp = &cidr_str[rc];
+
+ if ( *cp == 0 ) // end of string
+ {
+ // The string has no CIDR extension, so
+ // assume "/0", i.e. host mask 0.0.0.0;
+ mask = (IP4_ADDR) 0;
+ goto done;
+ }
+
+
+ if ( *cp != '/' )
+ return MBG_ERR_PARM_FMT;
+
+
+ cp++;
+ cidr_mask_bits = strtol( (char *) cp, (char **) &cp, 10 );
+
+ if ( ( cidr_mask_bits < MIN_IP4_CIDR_NETMASK_BITS ) ||
+ ( cidr_mask_bits > MAX_IP4_CIDR_NETMASK_BITS ) )
+ return MBG_ERR_RANGE;
+
+
+ mask = ip4_net_mask_from_cidr( (int) cidr_mask_bits );
+
+done:
+ if ( p_mask )
+ *p_mask = mask;
+
+ // success: return the number of evaluated chars
+ return (int) ( cp - cidr_str );
+
+} // cidr_str_to_ip4_addr_and_net_mask
+
+
+
+/*HDR*/
+/**
+ * @brief Count the number of sequential bits in an IPv6 net mask
+ *
+ * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results
+ * are both 2 since only the 2 MSBs are sequentially set.
+ *
+ * @param[in] p_mask The IPv6 net mask to be evaluated
+ *
+ * @return The number of sequential MSB bits set in *p_mask
+ *
+ * @see ::ip6_net_mask_from_cidr
+ */
+int get_ip6_net_mask_bits( const IP6_ADDR *p_mask )
+{
+ int i;
+ int cnt = 0;
+ uint8_t msb_mask = IP6_MSB_MASK;
+
+ for ( i = IP6_ADDR_BYTES - 1 ; i >= 0; i-- )
+ {
+ if ( p_mask->b[i] == 0xff )
+ cnt += 8;
+ else
+ {
+ for ( ; cnt < MAX_IP6_CIDR_NETMASK_BITS; cnt++ )
+ {
+ if ( ( p_mask->b[i] & msb_mask ) == 0 )
+ break;
+
+ msb_mask >>= 1;
+ }
+ break;
+ }
+ }
+
+ return cnt;
+
+} // get_ip6_net_mask_bits
+
+
+
+/*HDR*/
+/**
+ * @brief Print an IPv6 address in optimized format to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] info An optional string which is prepended to the string, or NULL
*
* @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
*/
-int snprint_octets( char *s, size_t max_len, const uint8_t *octets,
- int num_octets, char sep, const char *info )
+size_t snprint_ip6_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const char *info )
{
- int n = 0;
+ // Copied from inet_ntop.c, and reversed byte order
+
+ IP6_ADDR_STR tmp;
+ char *tp;
+ #define NUM_WORDS ( (int) ( sizeof( IP6_ADDR_STR ) / sizeof( uint16_t ) ) )
+ uint16_t words[NUM_WORDS] = { 0 };
int i;
+ size_t n = 0;
+ struct
+ {
+ int base;
+ int len;
+ } best = { 0 }, cur = { 0 };
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in p_addr->b[] for :: shorthanding.
+ */
+ for ( i = IP6_ADDR_BYTES - 1; i >= 0; i-- )
+ words[(IP6_ADDR_BYTES - 1 - i) / 2] |= (p_addr->b[i] << ((1 - ((IP6_ADDR_BYTES - 1 - i) % 2)) << 3));
+
+ best.base = -1;
+ cur.base = -1;
+
+ for ( i = 0; i < NUM_WORDS; i++ )
+ {
+ if ( words[i] == 0 )
+ {
+ if ( cur.base == -1 )
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ }
+ else
+ {
+ if ( cur.base != -1 )
+ {
+ if ( best.base == -1 || cur.len > best.len )
+ best = cur;
+
+ cur.base = -1;
+ }
+ }
+ }
+
+ if ( cur.base != -1 )
+ {
+ if ( best.base == -1 || cur.len > best.len )
+ best = cur;
+ }
+
+ if ( best.base != -1 && best.len < 2 )
+ best.base = -1;
+
+ // Format the result.
+
+ tp = tmp;
+
+ for ( i = 0; i < NUM_WORDS; i++ )
+ {
+ /* Are we inside the best run of 0x00's? */
+ if ( best.base != -1 && i >= best.base && i < ( best.base + best.len ) )
+ {
+ if (i == best.base)
+ *tp++ = ':';
+
+ continue;
+ }
+
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if ( i != 0 )
+ *tp++ = ':';
+
+ /* Is this address an encapsulated IPv4? */
+ if ( i == 6 && best.base == 0 && ( best.len == 6 || ( best.len == 5 && words[5] == 0xffff ) ) )
+ return MBG_ERR_INV_PARM; // we don't support encapsulated IPv4
+
+ sprintf( tp, "%x", words[i] );
+ tp += strlen( tp );
+ }
+
+ /* Was it a trailing run of 0x00's? */
+ if ( best.base != -1 && ( best.base + best.len ) == NUM_WORDS )
+ *tp++ = ':';
+
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ( ( tp - tmp ) > (int) max_len )
+ return MBG_ERR_OVERFLOW;
if ( info )
- n += snprintf( s, max_len, "%s", info );
+ n += snprintf_safe( s, max_len, "%s", info );
+
+ n += snprintf_safe( &s[n], max_len - n, "%s", tmp );
+
+ return n;
+
+ #undef NUM_WORDS
+
+} // snprint_ip6_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Print an IPv6 address plus net mask to string in CIDR notation
+ *
+ * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64"
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] p_mask The associated IPv6 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+size_t snprint_ip6_cidr_addr( char *s, size_t max_len, const IP6_ADDR *p_addr,
+ const IP6_ADDR *p_mask, const char *info )
+{
+ size_t n = snprint_ip6_addr( s, max_len, p_addr, info );
+
+ int cidr_mask_bits = get_ip6_net_mask_bits( p_mask );
+
+ if ( ( cidr_mask_bits >= MIN_IP6_CIDR_NETMASK_BITS ) &&
+ ( cidr_mask_bits <= MAX_IP6_CIDR_NETMASK_BITS ) )
+ n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits );
+
+ return n;
+
+} // snprint_ip6_cidr_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Print an IPv6 address plus number of net mask bits to string in CIDR notation
+ *
+ * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64"
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] cidr_mask_bits The CIDR number of bits specifying the IPv6 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+size_t snprint_ip6_cidr_mask_addr( char *s, size_t max_len, const IP6_ADDR *p_addr,
+ const int cidr_mask_bits, const char* info )
+{
+ size_t n;
+ IP6_ADDR mask;
+
+ ip6_net_mask_from_cidr( &mask, cidr_mask_bits );
+
+ n = snprint_ip6_addr( s, max_len, p_addr, info );
+
+ if ( ( cidr_mask_bits >= MIN_IP6_CIDR_NETMASK_BITS ) &&
+ ( cidr_mask_bits <= MAX_IP6_CIDR_NETMASK_BITS ) )
+ n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits );
+
+ return n;
+
+} // snprint_ip6_cidr_mask_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Convert a string to an ::IP6_ADDR
+ *
+ * If the output parameter is specified as NULL then this function
+ * can be used to check if the string is formally correct.
+ *
+ * On success ::IP6_ADDR variable contains the IPv6 address
+ * in little endian byte order.
+ *
+ * @param[out] p_addr Pointer to the ::IP6_ADDR variable, or NULL
+ * @param[in] s A string containing an IPv6 address
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+int str_to_ip6_addr( IP6_ADDR *p_addr, const char *s )
+{
+ // copied from inet_pton.c and reversed byte order
+ IP6_ADDR tmp = { { 0 } };
+ static const char xdigits[] = "0123456789abcdef";
+ uint8_t *tp;
+ uint8_t *startp;
+ uint8_t *colonp;
+ int ch;
+ int saw_xdigit;
+ int read_cnt = 0;
+ unsigned int val;
+
+ if ( p_addr )
+ memset( p_addr, 0, sizeof( *p_addr ) ); // set IP address to ::
+
+ startp = tmp.b - 1;
+ tp = startp + sizeof( tmp );
+
+ colonp = NULL;
+
+ /* Leading :: requires some special handling. */
+ if ( *s == ':' )
+ {
+ read_cnt++;
+
+ if ( *++s != ':' )
+ return MBG_ERR_PARM_FMT;
+ }
+
+ saw_xdigit = 0;
+ val = 0;
+
+ while ( ( ch = tolower( *s++ ) ) != '\0' )
+ {
+ const char *pch;
+
+ read_cnt++;
+
+ pch = strchr( xdigits, ch );
+
+ if ( pch != NULL )
+ {
+ val <<= 4;
+ val |= ( pch - xdigits );
+
+ if ( val > 0xffff ) //### TODO signed? unsigned?
+ return MBG_ERR_PARM_FMT;
+
+ saw_xdigit = 1;
+ continue;
+ }
+
+ if ( ch == ':' )
+ {
+ if ( !saw_xdigit )
+ {
+ if ( colonp )
+ return MBG_ERR_PARM_FMT;
+
+ colonp = tp;
+ continue;
+
+ }
+ else
+ if ( *s == '\0' )
+ return MBG_ERR_PARM_FMT;
+
+ if ( tp - sizeof( uint16_t ) < startp )
+ return MBG_ERR_PARM_FMT;
+
+ *tp-- = (uint8_t) ( val >> 8 ) & 0xff;
+ *tp-- = (uint8_t) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+
+ if ( ch == '/' ) // cidr notation. we reached the end
+ {
+ read_cnt--;
+ break;
+ }
+
+ return MBG_ERR_PARM_FMT;
+ }
+
+ if ( saw_xdigit )
+ {
+ if ( tp - sizeof( uint16_t ) < startp )
+ return MBG_ERR_PARM_FMT;
+
+ *tp-- = (uint8_t) (val >> 8) & 0xff;
+ *tp-- = (uint8_t) val & 0xff;
+ }
+
+ if ( colonp != NULL )
+ {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const size_t n = colonp - tp;
+ size_t i;
+
+ if ( tp == startp )
+ return MBG_ERR_PARM_FMT;
+
+ for ( i = 0; i <= n; i++ )
+ {
+ startp[i] = colonp[i - n];
+ colonp[i - n] = 0;
+ }
+
+ tp = startp;
+ }
+
+ if ( tp != startp )
+ return MBG_ERR_PARM_FMT;
+
+ if ( p_addr )
+ *p_addr = tmp;
+
+ return read_cnt;
+
+} // str_to_ip6_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP6_ADDR variable to be filled up
+ * with the IPv6 address, or NULL
+ * @param[out] p_mask Pointer to an ::IP6_ADDR variable to be filled up
+ with the net mask bits, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ */
+int cidr_str_to_ip6_addr_and_net_mask( IP6_ADDR *p_addr, IP6_ADDR *p_mask, const char *cidr_str )
+{
+ int mask = 0;
+ int rc = cidr_str_to_ip6_addr_and_cidr_bits( p_addr, &mask, cidr_str );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+ if ( p_mask )
+ ip6_net_mask_from_cidr( p_mask, mask );
+
+ return rc;
+
+} // cidr_str_to_ip6_addr_and_net_mask
+
+
+
+/*HDR*/
+/**
+ * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask bits
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP6_ADDR variable for the IPv6 address, or NULL
+ * @param[out] p_cidr Pointer to an int variable for the net mask bits, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::str_to_ip6_addr
+ */
+int cidr_str_to_ip6_addr_and_cidr_bits( IP6_ADDR *p_addr, int *p_cidr,
+ const char *cidr_str )
+{
+ long cidr_mask_bits;
+ const char *cp;
+ ssize_t l;
+ int rc = str_to_ip6_addr( p_addr, cidr_str );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+ l = strlen( cidr_str );
+
+ if ( l < rc ) // input string too short
+ return MBG_ERR_PARM_FMT;
+
+ cp = &cidr_str[rc];
+
+ if ( *cp == 0 ) // end of string
+ {
+ // The string has no CIDR extension, so
+ // assume "/0", i.e. host mask ::
+ cidr_mask_bits = 0;
+ goto done;
+ }
+
+ if ( *cp != '/' )
+ return MBG_ERR_PARM_FMT;
+
+ cp++;
+ cidr_mask_bits = strtol( (char *) cp, (char **) &cp, 10 );
+
+ if ( ( cidr_mask_bits < MIN_IP6_CIDR_NETMASK_BITS ) ||
+ ( cidr_mask_bits > MAX_IP6_CIDR_NETMASK_BITS ) )
+ return MBG_ERR_RANGE;
+
+done:
+ if ( p_cidr )
+ *p_cidr = (int) cidr_mask_bits;
+
+ // success: return the number of evaluated chars
+ return (int) ( cp - cidr_str );
+
+} // cidr_str_to_ip6_addr_and_cidr_bits
+
+
+
+/*HDR*/
+/**
+ * @brief Compute an IPv6 net mask according to the number of CIDR netmask bits
+ *
+ * E.g. the 64 bits mentioned in "2001:0DB8:0:CD30::/64" result in 2^64,
+ * corresponding to FFFF:FFFF:FFFF:FFFF:: in IPv6 notation.
+ *
+ * @param[out] p_mask Pointer to an ::IP6_ADDR variable for the IPv6 netmask
+ * @param[in] netmask_bits Number of netmask bits from CIDR notation
+ *
+ * @see ::get_ip6_net_mask_bits
+ */
+void ip6_net_mask_from_cidr( IP6_ADDR *p_mask, int netmask_bits )
+{
+ int i = 0;
+
+ if ( p_mask )
+ {
+ memset( p_mask, 0, sizeof( *p_mask ) );
+
+ if ( netmask_bits < 0 )
+ netmask_bits = 0;
+ else
+ if ( netmask_bits >= IP6_ADDR_BITS )
+ netmask_bits = IP6_ADDR_BITS;
+
+ for ( i = IP6_ADDR_BYTES - 1; i >= 0; i-- )
+ {
+ if ( netmask_bits > 8 )
+ {
+ p_mask->b[i] = 0xff;
+ netmask_bits -= 8;
+ }
+ else
+ {
+ p_mask->b[i] = (0xff << ( 8 - netmask_bits ) ) & 0xff;
+ netmask_bits = 0;
+ }
+ }
+ }
+
+} // ip6_net_mask_from_cidr
+
+
+
+/*HDR*/
+/**
+ * @brief Determine the network part of an IPv6 address based on the net mask
+ *
+ * E.g. IP "2001:0DB8:0:CD30::", net mask "FFFF:FFFF::" yields network part "2001:0DB8::".
+ *
+ * @param[out] p_net_part The extracted network part of the IPv6 address
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] p_mask The associated IPv6 net mask
+ */
+void ip6_net_part_from_addr( IP6_ADDR *p_net_part, const IP6_ADDR *p_addr,
+ const IP6_ADDR *p_mask )
+{
+ int i;
+
+ for ( i = IP6_ADDR_BYTES; i-- > 0; )
+ p_net_part->b[i] = p_addr->b[i] & p_mask->b[i];
+
+} // ip6_net_part_from_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Print a MAC ID or similar array of octets to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] octets An array of octets
+ * @param[in] num_octets The number of octets to be printed from the array
+ * @param[in] sep The separator printed between the bytes, or 0
+ * @param[in] info An optional string which is prepended to the output, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_mac_addr
+ * @see ::str_to_octets
+ * @see ::octets_are_all_zero
+ */
+size_t snprint_octets( char *s, size_t max_len, const uint8_t *octets,
+ int num_octets, char sep, const char *info )
+{
+ size_t n = 0;
+ int i;
+
+ if ( info )
+ n += snprintf_safe( s, max_len, "%s", info );
for ( i = 0; i < num_octets; i++ )
{
if ( i && sep )
- n += snprintf( &s[n], max_len - n, "%c", sep );
+ n += snprintf_safe( &s[n], max_len - n, "%c", sep );
- n += snprintf( &s[n], max_len - n, "%02X", octets[i] );
+ n += snprintf_safe( &s[n], max_len - n, "%02X", octets[i] );
}
return n;
@@ -90,13 +1003,61 @@ int snprint_octets( char *s, size_t max_len, const uint8_t *octets,
/*HDR*/
/**
- * @brief Set a MAC ID or a similar array of bytes from a string.
+ * @brief Print a ::PTP_CLOCK_ID to a string
+ *
+ * @todo Eventually this function should be moved to a different module.
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] p The ::PTP_CLOCK_ID to be printed
*
- * @param octets An array of octets to be set up
- * @param num_octets The number of octets which can be stored
- * @param s The string to be converted
+ * @return The overall number of characters printed to the string
*
- * @return The overall number of octets decoded from the string
+ * @see ::snprint_octets
+ */
+size_t snprint_ptp_clock_id( char *s, size_t max_len, const PTP_CLOCK_ID *p )
+{
+ return snprint_octets( s, max_len, p->b, sizeof( *p ), ':', NULL );
+
+} // snprint_ptp_clock_id
+
+
+
+/*HDR*/
+/**
+ * @brief Print a MAC address to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] p_mac_addr The MAC address to be printed
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_octets
+ * @see ::str_to_octets
+ * @see ::octets_are_all_zero
+ */
+size_t snprint_mac_addr( char *s, size_t max_len, const MBG_MAC_ADDR *p_mac_addr )
+{
+ return snprint_octets( s, max_len, p_mac_addr->b, sizeof( *p_mac_addr ), MAC_SEP_CHAR, NULL );
+
+} // snprint_mac_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Set a MAC ID or a similar array of octets from a string
+ *
+ * @param[out] octets An array of octets to be set up
+ * @param[in] num_octets The number of octets which can be stored
+ * @param[in] s The string to be converted
+ *
+ * @return The overall number of octets decoded from the string
+ *
+ * @see ::snprint_octets
+ * @see ::snprint_mac_addr
+ * @see ::octets_are_all_zero
*/
int str_to_octets( uint8_t *octets, int num_octets, const char *s )
{
@@ -126,74 +1087,838 @@ int str_to_octets( uint8_t *octets, int num_octets, const char *s )
/*HDR*/
/**
- * @brief Print an IPv4 address to a dotted quad format string.
+ * @brief Check if an array of octets is all zero
*
- * @param s The string buffer into which to print
- * @param max_len Maximum length of the string, i.e. size of the buffer
- * @param addr The IPv4 address
- * @param info An optional string which is prepended to the string, or NULL
+ * @param[in] octets Pointer to the array of octets
+ * @param[in] num_octets Number of octets
*
- * @return The overall number of characters printed to the string
+ * @return true if all bytes are 0, else false
+ *
+ * @see ::snprint_octets
+ * @see ::snprint_mac_addr
+ * @see ::str_to_octets
*/
-int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr, const char *info )
+bool octets_are_all_zero( const uint8_t *octets, int num_octets )
{
- int n = 0;
+ int i;
- if ( info )
- n += snprintf( s, max_len, "%s", info );
+ // check if any of the bytes is != 0
+ for ( i = 0; i < num_octets; i++ )
+ if ( octets[i] != 0 )
+ break;
- n += snprintf( &s[n], max_len - n, "%i.%i.%i.%i",
- BYTE_OF( *addr, 3 ),
- BYTE_OF( *addr, 2 ),
- BYTE_OF( *addr, 1 ),
- BYTE_OF( *addr, 0 )
- );
- return n;
+ return i == num_octets; // true if *all* bytes are 0
-} // snprint_ip4_addr
+} // octets_are_all_zero
/*HDR*/
/**
- * @brief Convert a string to an IP4_ADDR.
+ * @brief Check if a MAC address is all zero
*
- * @param p Pointer to the IP4_ADDR variable, or NULL, in which case this
- * function can be used to check if the string is formally correct.
- * @param s The string to be converted
+ * @param[in] p_addr Pointer to a MAC address to be checked
*
- * @return >= 0 on success, number of characters evaluated from the input string
- * -1 if invalid number found in string
- * -2 if separator is not a dot '.'
+ * @return true if all bytes of the MAC address are 0, else false
+ *
+ * @see ::octets_are_all_zero
*/
-int str_to_ip4_addr( IP4_ADDR *p, const char *s )
+bool mac_addr_is_all_zero( const MBG_MAC_ADDR *p_addr )
{
- IP4_ADDR tmp_ip4_addr = 0;
- char *cp;
+ return octets_are_all_zero( p_addr->b, sizeof( p_addr->b ) );
+
+} // mac_addr_is_all_zero
+
+
+
+#if defined( MBG_TGT_POSIX )
+
+/*HDR*/
+/**
+ * @brief Do a SIOCGxxx IOCTL call to read specific information from a LAN interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[in] ioctl_code One of the predefined system SIOCGxxx IOCTL codes
+ * @param[out] p_ifreq Pointer to a request buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+int do_siocg_ioctl( const char *if_name, int ioctl_code, struct ifreq *p_ifreq )
+{
+ int sock_fd;
+ int rc;
+
+ if ( strlen( if_name ) > ( IFNAMSIZ - 1 ) )
+ return MBG_ERR_PARM_FMT;
+
+ sock_fd = socket( AF_INET, SOCK_DGRAM, 0 ); //### TODO: or AF_INET6/PF_INET6 for IPv6
+
+ if ( sock_fd == -1 ) // failed to open socket
+ return mbg_get_last_socket_error( "failed to open socket in do_siocg_ioctl" );
+
+ strncpy_safe( p_ifreq->ifr_name, if_name, sizeof( p_ifreq->ifr_name ) );
+
+ rc = ioctl( sock_fd, ioctl_code, p_ifreq );
+
+ if ( rc == -1 ) // ioctl failed, errno has been set appropriately
+ rc = mbg_get_last_socket_error( "ioctl failed in do_siocg_ioctl" );
+ else
+ rc = MBG_SUCCESS;
+
+ close( sock_fd );
+
+ return rc;
+
+} // do_siocg_ioctl
+
+#endif // defined( MBG_TGT_POSIX )
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the index of a specific network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_intf_idx Pointer to a variable to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES.
+ * On error, *p_intf_idx is set to -1.
+ */
+int get_port_intf_idx( const char *if_name, int *p_intf_idx )
+{
+ int rc = MBG_ERR_NOT_SUPP_ON_OS;
+
+ #if defined( MBG_TGT_LINUX )
+ struct ifreq ifr = { { { 0 } } };
+
+ rc = do_siocg_ioctl( if_name, SIOCGIFINDEX, &ifr );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ *p_intf_idx = ifr.ifr_ifindex;
+ return rc;
+ }
+ #endif
+
+ // we get here on error only
+ *p_intf_idx = -1;
+
+ return rc;
+
+} // get_port_intf_idx
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the MAC address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_mac_addr Pointer to the MAC address buffer to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, the MAC address is set to all 0
+ */
+int get_port_mac_addr( const char *if_name, MBG_MAC_ADDR *p_mac_addr )
+{
+ int rc = MBG_ERR_NOT_SUPP_ON_OS;
+
+ #if defined( MBG_TGT_LINUX )
+ struct ifreq ifr = { { { 0 } } };
+
+ rc = do_siocg_ioctl( if_name, SIOCGIFHWADDR, &ifr );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ memcpy( p_mac_addr, ifr.ifr_hwaddr.sa_data, sizeof( *p_mac_addr ) );
+ return rc;
+ }
+ #endif
+
+ // we get here on error only
+ memset( p_mac_addr, 0, sizeof( *p_mac_addr ) );
+
+ return rc;
+
+} // get_port_mac_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Check the link state of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ *
+ * @return 1 if link detected on port,
+ * 0 if no link detected on port,
+ * one of the @ref MBG_ERROR_CODES in case of an error
+ */
+int check_port_link( const char *if_name )
+{
+ int rc = MBG_ERR_NOT_SUPP_ON_OS;
+
+ #if defined( MBG_TGT_LINUX )
+ struct ifreq ifr = { { { 0 } } };
+ struct ethtool_value edata = { 0 };
+
+ edata.cmd = ETHTOOL_GLINK; // defined in ethtool.h
+ ifr.ifr_data = (caddr_t) &edata;
+
+ rc = do_siocg_ioctl( if_name, SIOCETHTOOL, &ifr );
+
+ if ( mbg_rc_is_success( rc ) )
+ rc = ( edata.data == 0 ) ? 0 : 1;
+ #endif
+
+ return rc;
+
+} // check_port_link
+
+
+
+static /*HDR*/
+/**
+ * @brief Retrieve some IPv4 address-like info from a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ * @param[in] sigioc_code The IOCTL code associated with the address
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ */
+int get_specific_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr, int sigioc_code )
+{
+ int rc = MBG_ERR_NOT_SUPP_ON_OS;
+
+ #if defined( MBG_TGT_LINUX )
+ struct ifreq ifr = { { { 0 } } };
+
+ rc = do_siocg_ioctl( if_name, sigioc_code, &ifr );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ *p_addr = ntohl( ( (struct sockaddr_in *) &ifr.ifr_addr )->sin_addr.s_addr );
+ return rc;
+ }
+ #endif
+
+ // we get here on error only
+ *p_addr = 0; // make empty address
+
+ return rc;
+
+} // get_specific_port_ip4_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr )
+{
+ return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFADDR );
+
+} // get_port_ip4_addr
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 net mask of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_netmask( const char *if_name, IP4_ADDR *p_addr )
+{
+ return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFNETMASK );
+
+} // get_port_ip4_netmask
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 broadcast address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_broad_addr( const char *if_name, IP4_ADDR *p_addr )
+{
+ return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFBRDADDR );
+
+} // get_port_ip4_broad_addr
+
+
+
+#if defined( MBG_TGT_LINUX )
+
+static /*HDR*/
+/**
+ * @brief Read a requested message from the netlink socket
+ *
+ * @return Message length (>= 0) on success, or of the @ref MBG_ERROR_CODES
+ */
+int nl_read( int sock_fd, char *buf_ptr, size_t buf_size, int seq_num, int pid )
+{
+ struct nlmsghdr *nl_hdr;
+ int read_len = 0;
+ int msg_len = 0;
+
+ do
+ {
+ // receive response from the kernel, can be several chunks
+ if ( ( read_len = recv( sock_fd, buf_ptr, buf_size - msg_len, 0 ) ) == -1 )
+ {
+ int rc = mbg_get_last_socket_error( NULL );
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Failed to receive netlink packet: %s",
+ __func__, mbg_strerror( rc ) );
+ #endif
+ return rc;
+ }
+
+ nl_hdr = (struct nlmsghdr *) buf_ptr;
+
+ // check if the header is valid
+ if ( ( NLMSG_OK( nl_hdr, read_len ) == 0 ) || ( nl_hdr->nlmsg_type == NLMSG_ERROR ) )
+ {
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Invalid header in received netlink packet",
+ __func__ );
+ #endif
+ return MBG_ERR_DATA_FMT;
+ }
+
+ // check if the its the last message
+ if ( nl_hdr->nlmsg_type == NLMSG_DONE )
+ {
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Reached last message in received packet",
+ __func__ );
+ #endif
+ break;
+ }
+
+ // move the pointer to buffer appropriately
+ buf_ptr += read_len;
+ msg_len += read_len;
+
+ // check if its a multi part message
+ if ( ( nl_hdr->nlmsg_flags & NLM_F_MULTI ) == 0 )
+ {
+ // return if it's not a multi part message
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Received packet is not a multi part message",
+ __func__ );
+ #endif
+ break;
+ }
+
+ } while ( ( nl_hdr->nlmsg_seq != seq_num ) || ( nl_hdr->nlmsg_pid != pid ) );
+
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Received packet has len %i",
+ __func__, msg_len );
+ #endif
+
+ return msg_len;
+
+} // nl_read
+
+
+
+#if DEBUG_NETLINK
+
+static /*HDR*/
+void nl_log_bytes( const char *fnc, const char *info, const void *p, int n_bytes )
+{
+ char ws[80];
+ size_t n = 0;
int i;
- for ( i = 0, cp = (char *) s; ; )
+ for ( i = 0; i < n_bytes; i++ )
+ n += snprintf_safe( &ws[n], sizeof( ws ) - n, " %i", BYTE_OF( * (uint8_t *) p, i ) );
+
+ mbglog( LOG_INFO, "%s: attibute %s, copying %i bytes:%s",
+ fnc, info, n_bytes, ws );
+
+} // nl_log_bytes
+
+#endif
+
+
+
+static /*HDR*/
+int nl_parse_routes( struct nlmsghdr *nl_hdr, struct route_info *rt_info )
+{
+ // parse the route info returned
+ struct rtmsg *rt_msg;
+ struct rtattr *rt_attr;
+ int rt_len;
+
+ rt_msg = (struct rtmsg *) NLMSG_DATA( nl_hdr );
+
+ // If the route is not for AF_INET then return.
+ // This could be also IPv6 routes.
+ if ( rt_msg->rtm_family != AF_INET ) //##++ TODO: PF_INET6 for IPv6
+ {
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Route is not AF_INET (%li), but %li",
+ __func__, (long) AF_INET, (long) rt_msg->rtm_family );
+ #endif
+ return -1;
+ }
+
+ // If the route does not belong to main routing table then return.
+ if ( rt_msg->rtm_table != RT_TABLE_MAIN )
{
- unsigned long ul = strtoul( cp, &cp, 10 );
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Route does not belong to main table (%li), but %li",
+ __func__, (long) RT_TABLE_MAIN, (long) rt_msg->rtm_table );
+ #endif
+ return -1;
+ }
- if ( ul > 255 ) // invalid number
- return -1;
- tmp_ip4_addr |= ul << ( 8 * (3 - i) );
+ // get the rtattr field
+ rt_attr = (struct rtattr *) RTM_RTA( rt_msg );
+ rt_len = RTM_PAYLOAD( nl_hdr );
+
+ for ( ; RTA_OK( rt_attr, rt_len ); rt_attr = RTA_NEXT( rt_attr, rt_len ) )
+ {
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "rt_attr at %p, %i bytes left", rt_attr, rt_len );
+ #endif
- if ( ++i >= 4 )
- break; // done
+ switch ( rt_attr->rta_type )
+ {
+ case RTA_OIF:
+ if_indextoname( *(int *)RTA_DATA( rt_attr ), rt_info->ifName );
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: attibute RTA_OIF, IF name: %s",
+ __func__, rt_info->ifName );
+ #endif
+ break;
- if ( *cp != '.' )
- return -2; // invalid string format, dot expected
+ case RTA_GATEWAY:
+ memcpy( &rt_info->gateWay, RTA_DATA( rt_attr ), sizeof( rt_info->gateWay ) );
+ #if DEBUG_NETLINK
+ nl_log_bytes( __func__, "RTA_GATEWAY", &rt_info->gateWay, sizeof( rt_info->gateWay ) );
+ #endif
+ break;
- cp++; // skip dot
+ case RTA_PREFSRC:
+ memcpy( &rt_info->srcAddr , RTA_DATA( rt_attr ), sizeof( rt_info->srcAddr ) );
+ #if DEBUG_NETLINK
+ nl_log_bytes( __func__, "RTA_PREFSRC", &rt_info->srcAddr, sizeof( rt_info->srcAddr ) );
+ #endif
+ break;
+
+ case RTA_DST:
+ memcpy( &rt_info->dstAddr, RTA_DATA( rt_attr ), sizeof( rt_info->dstAddr ) );
+ #if DEBUG_NETLINK
+ nl_log_bytes( __func__, "RTA_DST", &rt_info->dstAddr, sizeof( rt_info->dstAddr ) );
+ #endif
+ break;
+
+ #if DEBUG_NETLINK
+ case RTA_TABLE:
+ {
+ // The RTA_TABLE attribute was added to the kernel source in 2006 to support
+ // more than 255 routing tables. Originally the number of the routing table
+ // to which an entry belongs had been passed only in struct rtmsg::rtm_table,
+ // which is only 8 bits wide and should still hold the 8 LSBs of the full
+ // routing table number for compatibility, so this should still work for the
+ // standard routing tables, including the main table we are inspecting here.
+ //
+ // Whether this can be compiled in depends on the version of linux/rtnetlink.h
+ // used by the compiler. Unfortunately RTA_TABLE is part of an enum, so you
+ // can't simply use #ifdef RTA_TABLE to include this code conditionally.
+ uint32_t rta_table;
+ memcpy( &rta_table, RTA_DATA( rt_attr ), sizeof( rta_table ) );
+ mbglog( LOG_ERR, "%s: attibute RTA_TABLE %i (%i)",
+ __func__, rta_table, rt_msg->rtm_table );
+ }
+ break;
+
+ default:
+ mbglog( LOG_ERR, "%s: Found unknown route type %li",
+ __func__, (long) rt_attr->rta_type );
+ #endif
+ }
}
- if ( p )
- *p = tmp_ip4_addr;
+ return 0;
- return cp - (char *) s; // success
+} // nl_parse_routes
+
+#endif // defined( MBG_TGT_LINUX )
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 gateway (default route)
+ *
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ */
+int get_ip4_gateway( IP4_ADDR *p_addr )
+{
+ int rc = MBG_ERR_NOT_SUPP_ON_OS;
+
+#if defined( MBG_TGT_LINUX )
+ struct nlmsghdr *nlmsg;
+ struct route_info route_info;
+ char msg_buf[8192]; // pretty large buffer, why 8192 ?
+ int sock_fd;
+ int len;
+ int msg_seq = 0;
+ int idx;
+
+ // create socket
+ if ( ( sock_fd = socket( PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE ) ) == -1 )
+ {
+ rc = mbg_get_last_socket_error( NULL );
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Failed to create netlink socket: %s",
+ __func__, mbg_strerror( rc ) );
+ #endif
+ goto out;
+ }
+
+
+ // initialize buffer with request message
+ memset( msg_buf, 0, sizeof( msg_buf ) );
+
+ // point the header and the msg structure pointers into the buffer
+ nlmsg = (struct nlmsghdr *) msg_buf;
+
+ // fill in the nlmsg header
+ nlmsg->nlmsg_len = NLMSG_LENGTH( sizeof( struct rtmsg ) ); // length of message
+ nlmsg->nlmsg_type = RTM_GETROUTE; // get the routes from kernel routing table
+
+ nlmsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // the message is a request for dump
+ nlmsg->nlmsg_seq = msg_seq++; // sequence of the message packet
+ nlmsg->nlmsg_pid = getpid(); // PID of process sending the request
+
+ // send the request
+ if ( send( sock_fd, nlmsg, nlmsg->nlmsg_len, 0 ) == -1 )
+ {
+ rc = mbg_get_last_socket_error( NULL );
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Failed to write to netlink socket: %s",
+ __func__, mbg_strerror( rc ) );
+ #endif
+ goto out;
+ }
+
+ // read the response
+ if ( ( len = nl_read( sock_fd, msg_buf, sizeof( msg_buf ), msg_seq, getpid() ) ) < 0 )
+ {
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Failed to read from netlink socket",
+ __func__ );
+ #endif
+ rc = len;
+ goto out;
+ }
+
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "%s: Read %i bytes from netlink socket", __func__, len );
+ #endif
+
+ // parse and print the response
+ for ( idx = 0; NLMSG_OK( nlmsg, len ); nlmsg = NLMSG_NEXT( nlmsg, len ), idx++ )
+ {
+ memset( &route_info, 0, sizeof( route_info ) );
+
+ #if DEBUG_NETLINK
+ mbglog( LOG_ERR, "\nnl_msg at %p, %i bytes left", nlmsg, len );
+ #endif
+
+
+ if ( nl_parse_routes( nlmsg, &route_info ) < 0 )
+ continue; // don't check route_info if it has not been set up
+
+ #if DEBUG_NETLINK
+ {
+ char ws[100];
+ int l = sizeof( ws );
+ int n = 0;
+
+ // inet_ntoa() uses a static buffer which is overwritten on every call
+ //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6
+ n += snprintf_safe( &ws[n], l - n, "src %s", (char *) inet_ntoa( route_info.srcAddr ) );
+ n += snprintf_safe( &ws[n], l - n, ", dst %s", (char *) inet_ntoa( route_info.dstAddr ) );
+ n += snprintf_safe( &ws[n], l - n, ", gw %s", (char *) inet_ntoa( route_info.gateWay ) );
+
+ mbglog( LOG_ERR, "%s: route %i: %s, if \"%s\"",
+ __func__, idx, ws, route_info.ifName );
+ }
+ #endif
+
+ // check if default IPv4 gateway
+ //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6
+ if ( strstr( (char *) inet_ntoa( route_info.dstAddr ), "0.0.0.0" ) )
+ {
+ *p_addr = ntohl( route_info.gateWay.s_addr );
+ rc = MBG_SUCCESS;
+ // Actually we could stop searching now. However, in case of debug
+ // we'll continue to examine the rest of the routing message.
+ #if DEBUG_NETLINK
+ //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6
+ mbglog( LOG_ERR, "%s: Default gateway found: %s",
+ __func__, (char *) inet_ntoa( route_info.gateWay ) );
+ #else
+ break;
+ #endif
+ }
+ }
+
+out:
+ if ( sock_fd >= 0 )
+ close( sock_fd );
+
+#endif // defined( MBG_TGT_LINUX )
+
+ if ( mbg_rc_is_error( rc ) )
+ *p_addr = 0;
+
+ return rc;
+
+} // get_ip4_gateway
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 address of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_addr_str( const char *if_name, char *p_addr_buf, int buf_size )
+{
+ IP4_ADDR addr;
+
+ int rc = get_port_ip4_addr( if_name, &addr );
+
+ snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL );
+
+ return rc;
+
+} // get_port_ip4_addr_str
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 net mask of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_netmask_str( const char *if_name, char *p_addr_buf, int buf_size )
+{
+ IP4_ADDR addr;
+
+ int rc = get_port_ip4_netmask( if_name, &addr );
+
+ snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL );
+
+ return rc;
+
+} // get_port_ip4_netmask_str
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the IPv4 broadcast address of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_broad_addr_str( const char *if_name, char *p_addr_buf, int buf_size )
+{
+ IP4_ADDR addr;
+
+ int rc = get_port_ip4_broad_addr( if_name, &addr );
+
+ snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL );
+
+ return rc;
+
+} // get_port_ip4_broad_addr_str
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve the current IPv4 settings of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p Pointer to a IP4_SETTINGS structure to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+int get_port_ip4_settings( const char *if_name, IP4_SETTINGS *p )
+{
+ int link_up;
+ int rc;
+
+ memset( p, 0, sizeof( *p ) );
+
+ rc = get_port_ip4_addr( if_name, &p->ip_addr );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ rc = get_port_ip4_netmask( if_name, &p->netmask );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+ rc = get_port_ip4_broad_addr( if_name, &p->broad_addr );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+
+
+#ifndef USE_MBG_TSU
+ rc = get_ip4_gateway( &p->gateway );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
+#endif
+
+#if 0 //### TODO
+ // We could also try to check VLAN and DHCP settings here,
+ // but as of now, this is specific to an application.
+
+ // ##++++ The VLAN and DHCP status info collected below
+ // just return what has been configured previously by this program,
+ // however, it does not reflect any changes which have been made
+ // manually, e.g. via the command line.
+ if ( vlan_enabled )
+ {
+ p->flags |= IP4_MSK_VLAN;
+ p->vlan_cfg = vlan_cfg;
+ }
+
+ if ( dhcp_enabled )
+ p->flags |= IP4_MSK_DHCP;
+#endif
+
+out:
+
+ // Check linkup independent from success of getting IP4 parameters
+ link_up = check_port_link( if_name );
+
+ if ( link_up )
+ p->flags |= IP4_MSK_LINK;
+
+ return rc;
+
+} // get_port_ip4_settings
-} // str_to_ip4_addr
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/lan_util.h b/src/external/bsd/meinberg/dist/mbglib/common/lan_util.h
index 2092760..27d49a3 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/lan_util.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/lan_util.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: lan_util.h 1.1.1.2 2011/06/22 07:47:48 martin TRASH $
+ * $Id: lan_util.h 1.7 2017/07/05 14:10:58 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,9 +10,23 @@
*
* -----------------------------------------------------------------------
* $Log: lan_util.h $
- * Revision 1.1.1.2 2011/06/22 07:47:48 martin
- * Cleaned up handling of pragma pack().
- * Revision 1.1.1.1 2011/04/20 16:09:02 martin
+ * Revision 1.7 2017/07/05 14:10:58 martin
+ * Some definitions used with IPv6 added by hannes.
+ * Removed definitions of old MBG_LU_... return codes.
+ * Standard MBG_RETURN_CODES are now used instead.
+ * Updated function prototypes.
+ * Revision 1.6 2014/09/24 08:32:58 martin
+ * Fixed a POSIX header file dependency.
+ * Revision 1.5 2013/10/02 07:20:36 martin
+ * Updated function prototypes.
+ * Revision 1.4 2013/02/19 15:15:53 martin
+ * Added some inline functions.
+ * Redefined return codes as named enum.
+ * Updated function prototypes.
+ * Revision 1.3 2012/10/02 18:24:29 martin
+ * Added some macros to simpliy conversion to string.
+ * Revision 1.2 2012/03/09 08:51:44 martin
+ * Updated function prototypes.
* Revision 1.1 2011/03/04 10:01:32 martin
* Initial revision.
*
@@ -24,10 +38,33 @@
/* Other headers to be included */
-#include <gpsdefs.h>
+#include <mbg_tgt.h>
+#include <gpsdefs.h> // for some Meinberg data structures
#include <stdlib.h>
+#if defined( MBG_TGT_POSIX )
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+ #include <ifaddrs.h> // *must* be included *after* net/if.h
+#else
+ // A dummy declaration to prevent from warnings due to usage
+ // of this type with function prototypes.
+ struct ifreq
+ {
+ int dummy;
+ };
+#endif
+
+
+#if defined( IFHWADDRLEN ) // usually defined in net/if.h
+ #if ( IFHWADDRLEN != 6 )
+ #error Warning: IFHWADDRLEN is not 6!
+ #endif
+#endif
+
+
#ifdef _LAN_UTIL
#define _ext
@@ -44,6 +81,10 @@
#define _USING_BYTE_ALIGNMENT
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if !defined( MAC_SEP_CHAR )
#define MAC_SEP_CHAR ':' // character used to separate octets of a MAC ID
@@ -54,12 +95,111 @@
#endif
+#define MAX_IP4_BITS ( 8 * (int) sizeof( IP4_ADDR ) )
+
+#define IP4_MSB_MASK ( 1UL << ( MAX_IP4_BITS - 1 ) )
+
+#define MIN_IP4_CIDR_NETMASK_BITS 0
+#define MAX_IP4_CIDR_NETMASK_BITS MAX_IP4_BITS
+
+
+#define IP6_MSB_MASK ( 1UL << ( 8 - 1 ) )
+
+#define MIN_IP6_CIDR_NETMASK_BITS 0
+#define MAX_IP6_CIDR_NETMASK_BITS IP6_ADDR_BITS
+
+
+
+/**
+ * @brief Compute an IP4 net mask according to the number of CIDR netmask bits
+ *
+ * E.g. the 24 bits mentioned in "172.16.3.250/24" result in 0xFFFFFF00,
+ * corresponding to 255.255.255.0 in dotted quad notation.
+ *
+ * @param netmask_bits Number of netmask bits from CIDR notation
+ *
+ * @return The IPv4 net mask
+ *
+ * @see get_ip4_net_mask_bits()
+ */
+static __mbg_inline
+IP4_ADDR ip4_net_mask_from_cidr( int netmask_bits )
+{
+ return (IP4_ADDR) ~( ( 1UL << ( MAX_IP4_BITS - netmask_bits ) ) - 1 );
+
+} // ip4_net_mask_from_cidr
+
+
+
+/**
+ * @brief Determine the broadcast address for an IP4 address plus net mask
+ *
+ * E.g. IP 0xAC1003FA, net mask 0xFFFFFF00 yields broadcast addr 0xAC1003FF.
+ * In dotted quad notation, IP 172.16.3.250 with net mask 255.255.255.0
+ * result in broadcast address 172.16.3.255.
+ *
+ * @param p_addr The full IP4 address
+ * @param p_mask The IP4 net mask
+ *
+ * @return The determined IP4 broadcast address
+ */
+static __mbg_inline
+IP4_ADDR ip4_broad_addr_from_addr( const IP4_ADDR *p_addr, const IP4_ADDR *p_mask )
+{
+ return *p_addr | ~(*p_mask);
+
+} // ip4_broad_addr_from_addr
+
+
+
+/**
+ * @brief Determine the network part of an IP4 address based on the net mask
+ *
+ * E.g. IP 0xAC1003FA, net mask 0xFFFFFF00 yields network part 0xAC100300.
+ * In dotted quad notation, IP 172.16.3.250 with net mask 255.255.255.0
+ * results in network part 172.16.3.0.
+ *
+ * @param p_addr The full IP4 address
+ * @param p_mask The IP4 net mask
+ *
+ * @return The network part of the IP4 address
+ */
+static __mbg_inline
+IP4_ADDR ip4_net_part_from_addr( const IP4_ADDR *p_addr, const IP4_ADDR *p_mask )
+{
+ return *p_addr & *p_mask;
+
+} // ip4_net_part_from_addr
+
+
+
+/**
+ * @brief Check if two IP4 addresses have the same network part.
+ *
+ * @param p_addr1 The first IP4 address to check
+ * @param p_addr2 The second IP4 address to check
+ * @param p_mask The IP4 net mask
+ *
+ * @return true, if the network parts are matching
+ */
+static __mbg_inline
+int ip4_net_part_matches( const IP4_ADDR *p_addr1, const IP4_ADDR *p_addr2,
+ const IP4_ADDR *p_mask )
+{
+ return ip4_net_part_from_addr( p_addr1, p_mask )
+ == ip4_net_part_from_addr( p_addr2, p_mask );
+
+} // ip4_net_part_matches
+
+
+
+#define _ip4_addr_to_str( _s, _a ) \
+ snprint_ip4_addr( _s, sizeof( _s ), _a, NULL )
+
+#define _mac_addr_to_str( _s, _a ) \
+ snprint_mac_addr( _s, sizeof( _s ), _a )
-/* function prototypes: */
-#ifdef __cplusplus
-extern "C" {
-#endif
/* ----- function prototypes begin ----- */
@@ -67,54 +207,536 @@ extern "C" {
/* by MAKEHDR, do not remove the comments. */
/**
- * @brief Print a MAC ID or similar array of octets to a string.
+ * @brief Count the number of sequential bits in an IPv4 net mask
+ *
+ * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results
+ * are both 2 since only the 2 MSBs are sequentially set.
+ *
+ * @param[in] p_mask The IPv4 net mask to be evaluated
*
- * @param s The string buffer into which to print
- * @param max_len Maximum length of the string, i.e. size of the buffer
- * @param octets An array of octets
- * @param num_octets The number of octets to be printed from the array
- * @param sep The separator printed between the bytes, or 0
- * @param info An optional string which is prepended to the output, or NULL
+ * @return The number of sequential MSB bits set in *p_mask
+ *
+ * @see ::ip4_net_mask_from_cidr
+ */
+ int get_ip4_net_mask_bits( const IP4_ADDR *p_mask ) ;
+
+ /**
+ * @brief Print an IPv4 address to a dotted quad formatted string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv4 address to be evaluated
+ * @param[in] info An optional string which is prepended to the string, or NULL
*
* @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
*/
- int snprint_octets( char *s, size_t max_len, const uint8_t *octets, int num_octets, char sep, const char *info ) ;
+ size_t snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const char *info ) ;
/**
- * @brief Set a MAC ID or a similar array of bytes from a string.
+ * @brief Print an IPv4 address plus net mask in CIDR notation to a string
+ *
+ * The printed CIDR string is something like "172.16.3.250/24"
*
- * @param octets An array of octets to be set up
- * @param num_octets The number of octets which can be stored
- * @param s The string to be converted
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv4 address to be evaluated
+ * @param[in] p_mask The associated IPv4 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
*
- * @return The overall number of octets decoded from the string
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::str_to_ip4_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
*/
- int str_to_octets( uint8_t *octets, int num_octets, const char *s ) ;
+ size_t snprint_ip4_cidr_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const IP4_ADDR *p_mask, const char *info ) ;
+
+ /**
+ * @brief Convert a string to an ::IP4_ADDR
+ *
+ * If output parameter is specified as NULL then this function
+ * can be used to check if the IPv4 address string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled, or NULL
+ * @param[in] s An IPv4 address string to be converted
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::cidr_str_to_ip4_addr_and_net_mask
+ */
+ int str_to_ip4_addr( IP4_ADDR *p_addr, const char *s ) ;
+
+ /**
+ * @brief Convert a string in CIDR notation to an ::IP4_ADDR and net mask
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled with
+ * the IPv4 address, or NULL
+ * @param[out] p_mask Pointer to an ::IP4_ADDR variable to be filled with
+ * the IPv4 net mask, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "172.16.3.250/24"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ */
+ int cidr_str_to_ip4_addr_and_net_mask( IP4_ADDR *p_addr, IP4_ADDR *p_mask, const char *cidr_str ) ;
/**
- * @brief Print an IPv4 address to a dotted quad format string.
+ * @brief Count the number of sequential bits in an IPv6 net mask
+ *
+ * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results
+ * are both 2 since only the 2 MSBs are sequentially set.
+ *
+ * @param[in] p_mask The IPv6 net mask to be evaluated
*
- * @param s The string buffer into which to print
- * @param max_len Maximum length of the string, i.e. size of the buffer
- * @param addr The IPv4 address
- * @param info An optional string which is prepended to the string, or NULL
+ * @return The number of sequential MSB bits set in *p_mask
+ *
+ * @see ::ip6_net_mask_from_cidr
+ */
+ int get_ip6_net_mask_bits( const IP6_ADDR *p_mask ) ;
+
+ /**
+ * @brief Print an IPv6 address in optimized format to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] info An optional string which is prepended to the string, or NULL
*
* @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+ size_t snprint_ip6_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const char *info ) ;
+
+ /**
+ * @brief Print an IPv6 address plus net mask to string in CIDR notation
+ *
+ * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64"
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] p_mask The associated IPv6 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+ size_t snprint_ip6_cidr_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const IP6_ADDR *p_mask, const char *info ) ;
+
+ /**
+ * @brief Print an IPv6 address plus number of net mask bits to string in CIDR notation
+ *
+ * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64"
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] cidr_mask_bits The CIDR number of bits specifying the IPv6 net mask
+ * @param[in] info An optional string which is prepended to the string, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+ size_t snprint_ip6_cidr_mask_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const int cidr_mask_bits, const char* info ) ;
+
+ /**
+ * @brief Convert a string to an ::IP6_ADDR
+ *
+ * If the output parameter is specified as NULL then this function
+ * can be used to check if the string is formally correct.
+ *
+ * On success ::IP6_ADDR variable contains the IPv6 address
+ * in little endian byte order.
+ *
+ * @param[out] p_addr Pointer to the ::IP6_ADDR variable, or NULL
+ * @param[in] s A string containing an IPv6 address
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::snprint_ip6_cidr_mask_addr
+ * @see ::str_to_ip6_addr
+ * @see ::cidr_str_to_ip6_addr_and_cidr_bits
+ * @see ::cidr_str_to_ip6_addr_and_net_mask
+ */
+ int str_to_ip6_addr( IP6_ADDR *p_addr, const char *s ) ;
+
+ /**
+ * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP6_ADDR variable to be filled up
+ * with the IPv6 address, or NULL
+ * @param[out] p_mask Pointer to an ::IP6_ADDR variable to be filled up
+ with the net mask bits, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip4_addr
+ * @see ::snprint_ip4_cidr_addr
+ * @see ::str_to_ip4_addr
+ */
+ int cidr_str_to_ip6_addr_and_net_mask( IP6_ADDR *p_addr, IP6_ADDR *p_mask, const char *cidr_str ) ;
+
+ /**
+ * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask bits
+ *
+ * If output parameters are specified as NULL then this function
+ * can be used to check if the CIDR string is formally correct.
+ *
+ * @param[out] p_addr Pointer to an ::IP6_ADDR variable for the IPv6 address, or NULL
+ * @param[out] p_cidr Pointer to an int variable for the net mask bits, or NULL
+ * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64"
+ *
+ * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated
+ * from the input string, or one of the @ref MBG_ERROR_CODES on error,
+ * specifically ::MBG_ERR_PARM_FMT if an invalid number or character was found in the string.
+ *
+ * @see ::snprint_ip6_addr
+ * @see ::snprint_ip6_cidr_addr
+ * @see ::str_to_ip6_addr
+ */
+ int cidr_str_to_ip6_addr_and_cidr_bits( IP6_ADDR *p_addr, int *p_cidr, const char *cidr_str ) ;
+
+ /**
+ * @brief Compute an IPv6 net mask according to the number of CIDR netmask bits
+ *
+ * E.g. the 64 bits mentioned in "2001:0DB8:0:CD30::/64" result in 2^64,
+ * corresponding to FFFF:FFFF:FFFF:FFFF:: in IPv6 notation.
+ *
+ * @param[out] p_mask Pointer to an ::IP6_ADDR variable for the IPv6 netmask
+ * @param[in] netmask_bits Number of netmask bits from CIDR notation
+ *
+ * @see ::get_ip6_net_mask_bits
+ */
+ void ip6_net_mask_from_cidr( IP6_ADDR *p_mask, int netmask_bits ) ;
+
+ /**
+ * @brief Determine the network part of an IPv6 address based on the net mask
+ *
+ * E.g. IP "2001:0DB8:0:CD30::", net mask "FFFF:FFFF::" yields network part "2001:0DB8::".
+ *
+ * @param[out] p_net_part The extracted network part of the IPv6 address
+ * @param[in] p_addr The IPv6 address to be evaluated
+ * @param[in] p_mask The associated IPv6 net mask
+ */
+ void ip6_net_part_from_addr( IP6_ADDR *p_net_part, const IP6_ADDR *p_addr, const IP6_ADDR *p_mask ) ;
+
+ /**
+ * @brief Print a MAC ID or similar array of octets to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] octets An array of octets
+ * @param[in] num_octets The number of octets to be printed from the array
+ * @param[in] sep The separator printed between the bytes, or 0
+ * @param[in] info An optional string which is prepended to the output, or NULL
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_mac_addr
+ * @see ::str_to_octets
+ * @see ::octets_are_all_zero
+ */
+ size_t snprint_octets( char *s, size_t max_len, const uint8_t *octets, int num_octets, char sep, const char *info ) ;
+
+ /**
+ * @brief Print a ::PTP_CLOCK_ID to a string
+ *
+ * @todo Eventually this function should be moved to a different module.
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] p The ::PTP_CLOCK_ID to be printed
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_octets
+ */
+ size_t snprint_ptp_clock_id( char *s, size_t max_len, const PTP_CLOCK_ID *p ) ;
+
+ /**
+ * @brief Print a MAC address to a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Maximum length of the string, i.e. size of the buffer
+ * @param[in] p_mac_addr The MAC address to be printed
+ *
+ * @return The overall number of characters printed to the string
+ *
+ * @see ::snprint_octets
+ * @see ::str_to_octets
+ * @see ::octets_are_all_zero
+ */
+ size_t snprint_mac_addr( char *s, size_t max_len, const MBG_MAC_ADDR *p_mac_addr ) ;
+
+ /**
+ * @brief Set a MAC ID or a similar array of octets from a string
+ *
+ * @param[out] octets An array of octets to be set up
+ * @param[in] num_octets The number of octets which can be stored
+ * @param[in] s The string to be converted
+ *
+ * @return The overall number of octets decoded from the string
+ *
+ * @see ::snprint_octets
+ * @see ::snprint_mac_addr
+ * @see ::octets_are_all_zero
+ */
+ int str_to_octets( uint8_t *octets, int num_octets, const char *s ) ;
+
+ /**
+ * @brief Check if an array of octets is all zero
+ *
+ * @param[in] octets Pointer to the array of octets
+ * @param[in] num_octets Number of octets
+ *
+ * @return true if all bytes are 0, else false
+ *
+ * @see ::snprint_octets
+ * @see ::snprint_mac_addr
+ * @see ::str_to_octets
*/
- int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr, const char *info ) ;
+ bool octets_are_all_zero( const uint8_t *octets, int num_octets ) ;
/**
- * @brief Convert a string to an IP4_ADDR.
+ * @brief Check if a MAC address is all zero
+ *
+ * @param[in] p_addr Pointer to a MAC address to be checked
+ *
+ * @return true if all bytes of the MAC address are 0, else false
+ *
+ * @see ::octets_are_all_zero
+ */
+ bool mac_addr_is_all_zero( const MBG_MAC_ADDR *p_addr ) ;
+
+ /**
+ * @brief Do a SIOCGxxx IOCTL call to read specific information from a LAN interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[in] ioctl_code One of the predefined system SIOCGxxx IOCTL codes
+ * @param[out] p_ifreq Pointer to a request buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ */
+ int do_siocg_ioctl( const char *if_name, int ioctl_code, struct ifreq *p_ifreq ) ;
+
+ /**
+ * @brief Retrieve the index of a specific network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_intf_idx Pointer to a variable to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES.
+ * On error, *p_intf_idx is set to -1.
+ */
+ int get_port_intf_idx( const char *if_name, int *p_intf_idx ) ;
+
+ /**
+ * @brief Retrieve the MAC address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_mac_addr Pointer to the MAC address buffer to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, the MAC address is set to all 0
+ */
+ int get_port_mac_addr( const char *if_name, MBG_MAC_ADDR *p_mac_addr ) ;
+
+ /**
+ * @brief Check the link state of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ *
+ * @return 1 if link detected on port,
+ * 0 if no link detected on port,
+ * one of the @ref MBG_ERROR_CODES in case of an error
+ */
+ int check_port_link( const char *if_name ) ;
+
+ /**
+ * @brief Retrieve the IPv4 address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr ) ;
+
+ /**
+ * @brief Retrieve the IPv4 net mask of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_netmask( const char *if_name, IP4_ADDR *p_addr ) ;
+
+ /**
+ * @brief Retrieve the IPv4 broadcast address of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_broad_addr( const char *if_name, IP4_ADDR *p_addr ) ;
+
+ /**
+ * @brief Retrieve the IPv4 gateway (default route)
+ *
+ * @param[out] p_addr Pointer to address field to be filled up
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, *p_addr is set to all 0.
+ */
+ int get_ip4_gateway( IP4_ADDR *p_addr ) ;
+
+ /**
+ * @brief Retrieve the IPv4 address of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) ;
+
+ /**
+ * @brief Retrieve the IPv4 net mask of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_netmask_str( const char *if_name, char *p_addr_buf, int buf_size ) ;
+
+ /**
+ * @brief Retrieve the IPv4 broadcast address of a network interface as string
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p_addr_buf Pointer to the string buffer to be filled up
+ * @param[in] buf_size size of the string buffer
+ *
+ * @return One of the @ref MBG_RETURN_CODES
+ * On error, a string according to "0.0.0.0" is generated.
+ *
+ * @see ::get_port_ip4_settings
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_specific_port_ip4_addr
+ */
+ int get_port_ip4_broad_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) ;
+
+ /**
+ * @brief Retrieve the current IPv4 settings of a network interface
+ *
+ * @param[in] if_name Name of the interface
+ * @param[out] p Pointer to a IP4_SETTINGS structure to be filled up
*
- * @param p Pointer to the IP4_ADDR variable, or NULL, in which case this
- * function can be used to check if the string is formally correct.
- * @param s The string to be converted
+ * @return One of the @ref MBG_RETURN_CODES
*
- * @return >= 0 on success, number of characters evaluated from the input string
- * -1 if invalid number found in string
- * -2 if separator is not a dot '.'
+ * @see ::get_port_ip4_addr
+ * @see ::get_port_ip4_addr_str
+ * @see ::get_port_ip4_netmask
+ * @see ::get_port_ip4_netmask_str
+ * @see ::get_port_ip4_broad_addr
+ * @see ::get_port_ip4_broad_addr_str
+ * @see ::get_specific_port_ip4_addr
*/
- int str_to_ip4_addr( IP4_ADDR *p, const char *s ) ;
+ int get_port_ip4_settings( const char *if_name, IP4_SETTINGS *p ) ;
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/macioctl.h b/src/external/bsd/meinberg/dist/mbglib/common/macioctl.h
index e3c0fbe..3cb0dff 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/macioctl.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/macioctl.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: macioctl.h 1.33.1.25 2011/07/20 15:48:22 martin TRASH $
+ * $Id: macioctl.h 1.38 2017/07/05 14:20:58 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,67 +11,58 @@
*
* -----------------------------------------------------------------------
* $Log: macioctl.h $
- * Revision 1.33.1.25 2011/07/20 15:48:22 martin
+ * Revision 1.38 2017/07/05 14:20:58 martin
+ * Support GNSS, GPIO and xmulti_ref stuff.
+ * Support new way to check if a feature is supported.
+ * Attribute always_inline is now in __mbg_inline.
+ * Fixed macro definition syntax to avoid clang compiler warnings.
+ * Account for frac_sec_from_bin() obsoleted by bin_frac_32_to_dec_frac().
+ * IOCTL debugging code.
+ * Removed trailing spaces.
+ * Revision 1.37 2014/05/19 15:57:25 martin
+ * Fixed grammar in a comment.
+ * Revision 1.36 2013/09/26 07:54:22 martin
+ * Support GNSS API.
+ * Revision 1.35 2013/04/11 13:46:05 martin
+ * Account for modified spinlock handling under Windows.
+ * Revision 1.34 2012/10/02 18:29:49Z martin
+ * Account for some renamed library symbols.
+ * Account for renamed structures.
+ * Support on-board event logs.
+ * Support debug status.
+ * Made inline functions static.
+ * Include cfg_hlp.h.
+ * Always read receiver info directly from the device.
* Conditionally use older IOCTL request buffer structures.
- * Revision 1.33.1.24 2011/07/19 12:52:05 martin
- * Revision 1.33.1.23 2011/07/14 14:53:58 martin
* Modified generic IOCTL handling such that for calls requiring variable sizes
* a fixed request block containing input and output buffer pointers and sizes is
* passed down to the kernel driver. This simplifies implementation under *BSD
* and also works for other target systems.
- * Revision 1.33.1.22 2011/07/06 11:19:19 martin
* Support reading CORR_INFO, and reading/writing TR_DISTANCE.
- * Revision 1.33.1.21 2011/06/29 10:51:16 martin
* Support IOCTL_DEV_HAS_PZF.
- * Revision 1.33.1.20 2011/05/18 10:08:13 martin
- * Re-ordered IOCTL evaluation to match ioctl_get_required_privilege()
- * which also makes sure calls requiring lowest latency are handled first.
- * Revision 1.33.1.19 2011/05/17 16:05:06 martin
* Use a single union type buffer instead of a large number of local
* variables in ioctl_switch().
* The accumulated size of all local variables required much stack
* space which led to problems under Windows.
- * Revision 1.33.1.18 2011/05/17 09:37:31 martin
* Support PTP unicast configuration.
* Account for some IOCTL codes renamed to follow common naming conventions.
- * Revision 1.33.1.17 2011/04/12 15:28:54 martin
* Use common mutex primitives from mbgmutex.h.
- * Revision 1.33.1.16 2011/03/31 10:57:00 martin
- * Revision 1.33.1.15 2011/03/31 07:32:09 martin
- * This version is the same as 1.33.1.12.
- * Revision 1.33.1.14 2011/03/31 07:16:34 martin
* Changes by Frank Kardel: Don't require copyin/copyout under NetBSD.
- * Revision 1.33.1.13 2011/03/23 16:50:30 martin
* Support NetBSD beside FreeBSD.
- * Revision 1.33.1.12 2011/03/21 16:25:23 martin
* Account for modified _pcpc_kfree().
- * Revision 1.33.1.11 2011/03/02 09:59:50 daniel
- * Bug fix: Use PCPS_TIME_STAMP with
+ * Bug fix: Use PCPS_TIME_STAMP with
* IOCTL_GET_FAST_HR_TIMESTAMP as output size.
- * Revision 1.33.1.10 2011/02/15 14:50:39Z martin
- * In a call to retrieve RECEIVER_INFO don't read from device
- * but just copy the field from the device info structure.
- * Revision 1.33.1.9 2011/02/15 11:08:33 daniel
- * Preliminary support for PTP unicast
- * Revision 1.33.1.8 2011/02/09 17:08:27Z martin
* Specify I/O range number when calling port I/O macros
* so they can be used for different ranges under BSD.
- * Revision 1.33.1.7 2011/01/26 16:37:55 martin
* Modified inline declarations for gcc.
- * Revision 1.33.1.6 2011/01/24 17:08:40 martin
* Fixed build under FreeBSD.
- * Revision 1.33.1.5 2010/11/09 10:57:33 martin
* Added _sem_inc_safe_no_irp() macro (Windows only).
- * Revision 1.33.1.4 2010/07/16 08:31:32Z martin
- * Revision 1.33.1.3 2010/07/15 15:47:07 martin
- * Revision 1.33.1.2 2010/07/14 14:48:52 martin
* Simplified code and renamed some inline functions.
- * Revision 1.33.1.1 2010/03/03 15:11:51 martin
* Fixed macro.
* Revision 1.33 2009/12/21 16:22:55 martin
* Moved code reading memory mapped timestamps to inline functions.
* Revision 1.32 2009/12/15 15:34:57 daniel
- * Support reading the raw IRIG data bits for firmware versions
+ * Support reading the raw IRIG data bits for firmware versions
* which support this feature.
* Revision 1.31 2009/11/04 14:58:52Z martin
* Conditionally exclude port status query from build.
@@ -105,7 +96,7 @@
* Revision 1.23 2008/12/11 10:30:38Z martin
* _pcps_get_cycles() is now called inside the low level routines
* immediately when the command byte is written.
- * Mutex for hardware access is now acquired/released in _pcps_sem_inc()
+ * Mutex for hardware access is now acquired/released in _pcps_sem_inc()
* and _pcps_sem_dec(), so other IOCTLs which don't access the card
* can be run in parallel.
* Moved definitions of _pcps_sem_inc(), _pcps_sem_dec(), and
@@ -114,14 +105,14 @@
* with certain PEX cards which have IRQs enabled).
* Use _pcps_sem_inc_safe() macro to check if access is safe and
* inhibit access if this is not the case.
- * Consistenly use pcps_drvr_name instead of mbgclock_name
+ * Consistenly use pcps_drvr_name instead of mbgclock_name
* for debug messages.
* Don't return error for unmap_mm...() under Linux.
* Account for ASIC_FEATURES being coded as flags, and account
* for new symbol PCI_ASIC_HAS_MM_IO.
* Handle new IOCTLs IOCTL_HAS_PCI_ASIC_FEATURES, IOCTL_HAS_PCI_ASIC_VERSION,
- * IOCTL_DEV_IS_MSF, IOCTL_DEV_IS_LWR, IOCTL_DEV_IS_WWVB,
- * IOCTL_GET_IRQ_STAT_INFO, IOCTL_GET_CYCLES_FREQUENCY,
+ * IOCTL_DEV_IS_MSF, IOCTL_DEV_IS_LWR, IOCTL_DEV_IS_WWVB,
+ * IOCTL_GET_IRQ_STAT_INFO, IOCTL_GET_CYCLES_FREQUENCY,
* IOCTL_HAS_FAST_HR_TIMESTAMP, and IOCTL_GET_FAST_HR_TIMESTAMP.
* Support mapped I/O resources.
* Revision 1.22 2008/01/17 09:28:49 daniel
@@ -153,17 +144,17 @@
* Revision 1.14 2004/12/09 11:03:36Z martin
* Support configuration of on-board frequency synthesizer.
* Revision 1.13 2004/11/09 12:47:19Z martin
- * Use new macro _pcps_ddev_has_gps_data() to check whether GPS large
+ * Use new macro _pcps_ddev_has_gps_data() to check whether GPS large
* data I/O is supported.
* Changes due to renamed symbols, IRIG RX/TX.
- * Modifications were required in order to be able to configure IRIG
+ * Modifications were required in order to be able to configure IRIG
* settings of cards which provide both IRIG input and output.
- * GPS169PCI cards with IRIG output and early firmware versions
- * used the same codes to configure the IRIG output as the TCR
- * cards use to configure the IRIG input. Those codes are now
+ * GPS169PCI cards with IRIG output and early firmware versions
+ * used the same codes to configure the IRIG output as the TCR
+ * cards use to configure the IRIG input. Those codes are now
* exclusively used to configure the IRIG input. A workaround
- * has been included for those GPS169PCI cards, because otherwise
- * the IRIG configuration would not work properly after a driver
+ * has been included for those GPS169PCI cards, because otherwise
+ * the IRIG configuration would not work properly after a driver
* update, without also doing a firmware update.
* Show debug msg if GPS169PCI workaround for IRIG cfg in effect.
* Use more specific data types than generic types.
@@ -196,7 +187,7 @@
* Support almost all IOCTL codes.
* Support for Win32.
* Revision 1.3 2001/11/30 09:52:47Z martin
- * Added support for event_time which, however, requires
+ * Added support for event_time which, however, requires
* a custom GPS firmware.
* Revision 1.2 2001/09/14 12:01:17 martin
* Decode PCPS_IOCTL_SET_GPS_CMD.
@@ -208,8 +199,9 @@
#ifndef _MACIOCTL_H
#define _MACIOCTL_H
-#include <pcpsdrvr.h>
#include <mbgioctl.h>
+#include <cfg_hlp.h>
+#include <pcpsdrvr.h>
#include <pci_asic.h>
#include <mbgddmsg.h>
@@ -387,7 +379,7 @@ typedef struct
rc = _pcps_read_var( _pddev, _cmd, iob._fld ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
\
_iob_to_pout_var( iob._fld, _pout ); \
@@ -405,7 +397,7 @@ typedef struct
rc = _pcps_write_var( _pddev, _cmd, iob._fld ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
}
@@ -418,7 +410,7 @@ typedef struct
rc = _pcps_write_byte( _pddev, _cmd ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
}
@@ -435,7 +427,7 @@ typedef struct
rc = pcps_read_gps( _pddev, _cmd, (uchar FAR *) &iob._fld, _size ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
\
_iob_to_pout( &iob._fld, _pout, _size ); \
@@ -454,7 +446,7 @@ typedef struct
rc = _pcps_read_gps_var( _pddev, _cmd, iob._fld ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
\
_iob_to_pout_var( iob._fld, _pout ); \
@@ -475,7 +467,7 @@ typedef struct
rc = _pcps_write_gps_var( _pddev, _cmd, iob._fld ); \
_pcps_sem_dec( _pddev ); \
\
- if ( rc != MBG_SUCCESS ) \
+ if ( mbg_rc_is_error( rc ) ) \
goto err_access; \
}
@@ -550,9 +542,14 @@ typedef struct
-#define TEST_MM_ACCESS_TIME ( 0 && defined( MBG_TGT_LINUX ) )
-#define TEST_MM_ACCESS_64 0
-#define TEST_FRAC_ONLY 0
+#if ( 0 && defined( MBG_TGT_LINUX ) )
+ #define TEST_MM_ACCESS_TIME 1
+#else
+ #define TEST_MM_ACCESS_TIME 0
+#endif
+
+#define TEST_MM_ACCESS_64 0
+#define TEST_FRAC_ONLY 0
#if TEST_MM_ACCESS_TIME
#include <pcpsutil.h>
@@ -583,6 +580,7 @@ typedef union
ANT_INFO ant_info;
ENABLE_FLAGS enable_flags;
STAT_INFO stat_info;
+ RECEIVER_INFO receiver_info;
GPS_CMD gps_cmd;
IDENT ident;
POS pos;
@@ -592,11 +590,11 @@ typedef union
PORT_SETTINGS_IDX port_settings_idx;
SYNTH synth;
SYNTH_STATE synth_state;
- ALL_POUT_INFO all_pout_info;
+ ALL_POUT_INFO_IDX all_pout_info_idx;
POUT_SETTINGS_IDX pout_settings_idx;
- ALL_STR_TYPE_INFO all_str_type_info;
- ALL_PORT_INFO all_port_info;
- ALL_PTP_UC_MASTER_INFO all_ptp_uc_master_info;
+ ALL_STR_TYPE_INFO_IDX all_str_type_info_idx;
+ ALL_PORT_INFO_IDX all_port_info_idx;
+ ALL_PTP_UC_MASTER_INFO_IDX all_ptp_uc_master_info_idx;
MBG_TIME_SCALE_INFO mbg_time_scale_info;
MBG_TIME_SCALE_SETTINGS mbg_time_scale_settings;
UTC utc;
@@ -620,6 +618,22 @@ typedef union
MBG_TIME_INFO_TSTAMP mbg_time_info_tstamp;
CORR_INFO corr_info;
TR_DISTANCE tr_distance;
+ MBG_DEBUG_STATUS debug_status;
+ MBG_NUM_EVT_LOG_ENTRIES num_evt_log_entries;
+ MBG_EVT_LOG_ENTRY evt_log_entry;
+ MBG_GNSS_MODE_SETTINGS gnss_mode_settings;
+ MBG_GNSS_MODE_INFO gnss_mode_info;
+ ALL_GNSS_SAT_INFO_IDX all_gnss_sat_info_idx;
+ MBG_GPIO_CFG_LIMITS mbg_gpio_cfg_limits;
+ ALL_GPIO_INFO_IDX all_gpio_info_idx;
+ ALL_GPIO_STATUS_IDX all_gpio_status_idx;
+ MBG_GPIO_SETTINGS_IDX mbg_gpio_settings_idx;
+ XMULTI_REF_INSTANCES xmulti_ref_instances;
+ ALL_XMULTI_REF_STATUS_IDX all_xmulti_ref_status_idx;
+ ALL_XMULTI_REF_INFO_IDX all_xmulti_ref_info_idx;
+ XMULTI_REF_SETTINGS_IDX xmulti_ref_settings_idx;
+ XMR_HOLDOVER_STATUS xmr_holdover_status;
+ IOCTL_DEV_FEAT_REQ dev_feat_req;
PCPS_MAPPED_MEM mapped_mem;
@@ -637,11 +651,11 @@ typedef union
#if defined( __GNUC__ )
// Avoid "no previous prototype" with some gcc versions.
-__mbg_inline
-void swap_tstamp( PCPS_TIME_STAMP *p_ts ) __attribute__((always_inline));
+static __mbg_inline
+void swap_tstamp( PCPS_TIME_STAMP *p_ts );
#endif
-__mbg_inline
+static __mbg_inline
void swap_tstamp( PCPS_TIME_STAMP *p_ts )
{
uint32_t tmp = p_ts->sec;
@@ -654,14 +668,18 @@ void swap_tstamp( PCPS_TIME_STAMP *p_ts )
#if defined( __GNUC__ )
// Avoid "no previous prototype" with some gcc versions.
-__mbg_inline
-void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts ) __attribute__((always_inline));
+static __mbg_inline
+void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts );
#endif
-__mbg_inline
+static __mbg_inline
void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts )
{
+ #if defined( MBG_TGT_WIN32 )
+ KIRQL OldIrql;
+ #endif
+
#if TEST_MM_ACCESS_64
volatile uint64_t *p = (volatile uint64_t *) pddev->mm_tstamp_addr;
#else
@@ -727,7 +745,7 @@ void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts )
#if TEST_MM_ACCESS_TIME
delta_frac = (long) ( tmp.frac - p_ts->frac );
- delta_ns = (unsigned) frac_sec_from_bin( delta_frac, 1000000000UL );
+ delta_ns = (unsigned) bin_frac_32_to_dec_frac( delta_frac, NSECS_PER_SEC );
printk( KERN_INFO "MM tstamp dev %04X: %li/%li cyc (%lu kHz)"
" %08lX.%08lX->%08lX.%08lX: %li (%u.%03u us)"
@@ -750,13 +768,17 @@ void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts )
#if defined( __GNUC__ )
// Avoid "no previous prototype" with some gcc versions.
-__mbg_inline
-void do_get_fast_hr_timestamp_cycles_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYCLES *p_ts_cyc ) __attribute__((always_inline));
+static __mbg_inline
+void do_get_fast_hr_timestamp_cycles_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYCLES *p_ts_cyc );
#endif
-__mbg_inline
+static __mbg_inline
void do_get_fast_hr_timestamp_cycles_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYCLES *p_ts_cyc )
{
+ #if defined( MBG_TGT_WIN32 )
+ KIRQL OldIrql;
+ #endif
+
volatile uint32_t *p = (volatile uint32_t *) pddev->mm_tstamp_addr;
_mbg_spin_lock_acquire( &pddev->mm_lock );
@@ -768,36 +790,41 @@ void do_get_fast_hr_timestamp_cycles_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYC
} // do_get_fast_hr_timestamp_cycles_safe
+
#if defined( __GNUC__ )
// Avoid "no previous prototype" with some gcc versions.
-__mbg_inline
+static __mbg_inline
int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
#if defined( MBG_TGT_WIN32 )
IRP *pIrp, int *ret_size, uint16_t pout_size,
#endif
- void *pin, void *pout ) __attribute__((always_inline));
+ void *pin, void *pout );
#endif
/**
- * @brief Decode an handle IOCTL commands.
+ * @brief Decode and handle IOCTL commands
*
- * This function is called from the OS dependent IOCTL handlers.
+ * This function is called from the OS-specific IOCTL handlers, so eventually
+ * the calling function needs to translate the Meinberg return codes to appropriate
+ * OS-specific return codes.
*
- * @param pddev Pointer to the device structure
- * @param ioctl_code The IOCTL code to be handled
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] ioctl_code The IOCTL code to be handled
+ */
#if defined( MBG_TGT_WIN32 )
- * @param pIrp The IRP associated to the IOCTL call
- * @param ret_size The number of bytes to be returned
- * @param pout_size The size of the output buffer
+/**
+ * @param[in] pIrp The IRP associated with the IOCTL call
+ * @param[in] ret_size The number of bytes to be returned
+ * @param[in] pout_size The size of the output buffer
+ */
#endif
- * @param pin The input buffer
- * @param pout The output buffer
+ /**
+ * @param[in] pin The input buffer
+ * @param[in] pout The output buffer
*
- * @return MBG_SUCCESS or one of the Meinberg error codes which need to be translated
- * by the calling function to the OS dependent error code.
- * @return -1 for unknown IOCTL codes
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
*/
-__mbg_inline
+static __mbg_inline
int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
#if defined( MBG_TGT_WIN32 )
IRP *pIrp, int *ret_size, uint16_t pout_size,
@@ -854,7 +881,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
iob.pcps_hr_time_cycles.cycles = pddev->acc_cycles;
_pcps_sem_dec( pddev );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
_iob_to_pout_var( iob.pcps_hr_time_cycles, pout );
@@ -883,7 +910,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
mbg_get_pc_cycles( &iob.pcps_time_cycles.cycles );
_pcps_sem_dec( pddev );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
_iob_to_pout_var( iob.pcps_time_cycles, pout );
@@ -932,7 +959,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
iob.mbg_time_info_hrt.ref_hr_time_cycles.cycles = pddev->acc_cycles;
_pcps_sem_dec( pddev );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
_iob_to_pout_var( iob.mbg_time_info_hrt, pout );
@@ -997,9 +1024,12 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
case IOCTL_GET_GPS_RECEIVER_INFO:
- _io_chk_cond( _pcps_ddev_has_receiver_info( pddev ) );
- // Just return the saved RECEIVER_INFO ...
- _iob_to_pout_var( pddev->ri, pout );
+ // Always read the receiver info directly from the device. Never
+ // just return a previous copy which has been read earlier since
+ // something may just have been changed by a configuration API call.
+ _io_read_gps_var_chk( pddev, PC_GPS_RECEIVER_INFO,
+ receiver_info, pout,
+ _pcps_ddev_has_receiver_info( pddev ) );
break;
@@ -1066,6 +1096,39 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_GET_DEBUG_STATUS:
+ _io_read_var_chk( pddev, PCPS_GET_DEBUG_STATUS, debug_status,
+ pout, _pcps_ddev_has_debug_status( pddev ) );
+ break;
+
+
+ case IOCTL_GET_NUM_EVT_LOG_ENTRIES:
+ _io_read_var_chk( pddev, PCPS_NUM_EVT_LOG_ENTRIES, num_evt_log_entries,
+ pout, _pcps_ddev_has_evt_log( pddev ) );
+ break;
+
+
+ case IOCTL_GET_FIRST_EVT_LOG_ENTRY:
+ _io_read_var_chk( pddev, PCPS_FIRST_EVT_LOG_ENTRY, evt_log_entry,
+ pout, _pcps_ddev_has_evt_log( pddev ) );
+ break;
+
+
+ case IOCTL_GET_NEXT_EVT_LOG_ENTRY:
+ _io_read_var_chk( pddev, PCPS_NEXT_EVT_LOG_ENTRY, evt_log_entry,
+ pout, _pcps_ddev_has_evt_log( pddev ) );
+ break;
+
+
+ #if _MBG_SUPP_VAR_ACC_SIZE // otherwise generic IOCTL functions are used instead
+ case IOCTL_GET_ALL_GNSS_SAT_INFO:
+ _io_read_gps_chk( pddev, PC_GPS_ALL_GNSS_SAT_INFO, all_gnss_sat_info_idx, pout,
+ pout_size, _pcps_ddev_is_gnss( pddev ) );
+ break;
+ #endif
+
+
+
// Commands returning device capabilities and features
case IOCTL_DEV_IS_GPS:
@@ -1093,6 +1156,11 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_DEV_IS_GNSS:
+ _report_cond( _pcps_ddev_is_gnss( pddev ), pout );
+ break;
+
+
case IOCTL_DEV_IS_IRIG_RX:
_report_cond( _pcps_ddev_is_irig_rx( pddev ), pout );
break;
@@ -1273,6 +1341,36 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_DEV_HAS_DEBUG_STATUS:
+ _report_cond( _pcps_ddev_has_debug_status( pddev ), pout );
+ break;
+
+
+ case IOCTL_DEV_HAS_EVT_LOG:
+ _report_cond( _pcps_ddev_has_evt_log( pddev ), pout );
+ break;
+
+
+ case IOCTL_DEV_HAS_GPIO:
+ _report_cond( _pcps_ddev_has_gpio( pddev ), pout );
+ break;
+
+
+ case IOCTL_DEV_HAS_XMR:
+ _report_cond( _pcps_ddev_has_xmr( pddev ), pout );
+ break;
+
+ case IOCTL_CHK_DEV_FEAT:
+ _iob_from_pin_var( iob.dev_feat_req, pin );
+ rc = pcps_chk_dev_feat( pddev, iob.dev_feat_req.feat_req_type, iob.dev_feat_req.feat_num );
+ #if 0
+ _mbgddmsg_4( MBG_DBG_INFO, "%s: chk_dev_feat %i:%i returned %i",
+ pcps_driver_name, iob.dev_feat_req.feat_req_type,
+ iob.dev_feat_req.feat_num, rc );
+ #endif
+ break;
+
+
// The next codes are somewhat special since they change something
// on the board but do not affect basic operation
@@ -1289,6 +1387,12 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_CLR_EVT_LOG:
+ _io_write_cmd_chk( pddev, PCPS_CLR_EVT_LOG, _pcps_ddev_has_evt_log( pddev ) );
+ break;
+
+
+
// Status information which may not be available for everybody
case IOCTL_GET_GPS_POS:
@@ -1296,6 +1400,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+
// Codes reading device configuration
case IOCTL_GET_PCPS_SERIAL:
@@ -1431,6 +1536,116 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_PCPS_GENERIC_READ:
+ #if USE_IOCTL_GENERIC_REQ
+ _iob_from_pin_var( iob.req, pin );
+ p_buff_out = _pcps_kmalloc( iob.req.out_sz );
+
+ if ( p_buff_out == NULL )
+ {
+ _mbgddmsg_4( MBG_DBG_INFO, "%s: unable to alloc %lu bytes for %s, cmd: %02lX",
+ pcps_driver_name, (ulong) iob.req.out_sz,
+ "IOCTL_PCPS_GENERIC_READ", (ulong) iob.req.info );
+ goto err_no_mem;
+ }
+
+ _pcps_sem_inc_safe( pddev );
+ rc = _pcps_read( pddev, (uint8_t) iob.req.info, p_buff_out,
+ (uint8_t) iob.req.out_sz );
+ _pcps_sem_dec( pddev );
+
+ if ( rc == MBG_SUCCESS )
+ _frc_iob_to_pout( p_buff_out, iob.req.out_p, iob.req.out_sz );
+
+ _pcps_kfree( p_buff_out, iob.req.out_sz );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto err_access;
+
+ #else
+
+ _iob_from_pin_var( iob.ctl, pin );
+ buffer_size = sizeof( iob.ctl ) + iob.ctl.data_size_out;
+ p_buff = _pcps_kmalloc( buffer_size );
+
+ if ( p_buff == NULL )
+ goto err_no_mem;
+
+ _pcps_sem_inc_safe( pddev );
+ rc = _pcps_read( pddev, (uint8_t) iob.ctl.info, p_buff->data,
+ (uint8_t) iob.ctl.data_size_out );
+ _pcps_sem_dec( pddev );
+
+ if ( rc == MBG_SUCCESS )
+ {
+ p_buff->ctl = iob.ctl;
+ _iob_to_pout( p_buff, pout, buffer_size ); //##+++++++ need to check this !!
+ }
+
+ _pcps_kfree( p_buff, buffer_size );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto err_access;
+
+ #endif
+ break;
+
+
+ case IOCTL_PCPS_GENERIC_READ_GPS:
+ #if USE_IOCTL_GENERIC_REQ
+ _iob_from_pin_var( iob.req, pin );
+ p_buff_out = _pcps_kmalloc( iob.req.out_sz );
+
+ if ( p_buff_out == NULL )
+ {
+ _mbgddmsg_4( MBG_DBG_INFO, "%s: unable to alloc %lu bytes for %s, GPS cmd: %02lX",
+ pcps_driver_name, (ulong) iob.req.out_sz,
+ "IOCTL_PCPS_GENERIC_READ_GPS", (ulong) iob.req.info );
+ goto err_no_mem;
+ }
+
+ _pcps_sem_inc_safe( pddev );
+ rc = pcps_read_gps( pddev, (uint8_t) iob.req.info, p_buff_out,
+ (uint16_t) iob.req.out_sz );
+ _pcps_sem_dec( pddev );
+
+ if ( rc == MBG_SUCCESS )
+ _frc_iob_to_pout( p_buff_out, iob.req.out_p, iob.req.out_sz );
+
+ _pcps_kfree( p_buff_out, iob.req.out_sz );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto err_access;
+
+ #else
+
+ _iob_from_pin_var( iob.ctl, pin );
+ buffer_size = sizeof( iob.ctl ) + iob.ctl.data_size_out;
+ p_buff = _pcps_kmalloc( buffer_size );
+
+ if ( p_buff == NULL )
+ goto err_no_mem;
+
+ _pcps_sem_inc_safe( pddev );
+ rc = pcps_read_gps( pddev, (uint8_t) iob.ctl.info, p_buff->data,
+ (uint16_t) iob.ctl.data_size_out );
+ _pcps_sem_dec( pddev );
+
+ if ( rc == MBG_SUCCESS )
+ {
+ p_buff->ctl = iob.ctl;
+ _iob_to_pout( p_buff, pout, buffer_size ); //##+++++++ need to check this !!
+ }
+
+ _pcps_kfree( p_buff, buffer_size );
+
+ if ( mbg_rc_is_error( rc ) )
+ goto err_access;
+
+ #endif
+ break;
+
+
#if _MBG_SUPP_VAR_ACC_SIZE
// These codes are only supported on target systems where a variable size of
@@ -1438,31 +1653,77 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
// generic IOCTL functions are used instead.
case IOCTL_GET_GPS_ALL_STR_TYPE_INFO:
- _io_read_gps_chk( pddev, PC_GPS_ALL_STR_TYPE_INFO, all_str_type_info, pout,
+ _io_read_gps_chk( pddev, PC_GPS_ALL_STR_TYPE_INFO, all_str_type_info_idx, pout,
pout_size, _pcps_ddev_has_receiver_info( pddev ) );
break;
case IOCTL_GET_GPS_ALL_PORT_INFO:
- _io_read_gps_chk( pddev, PC_GPS_ALL_PORT_INFO, all_port_info, pout,
+ _io_read_gps_chk( pddev, PC_GPS_ALL_PORT_INFO, all_port_info_idx, pout,
pout_size, _pcps_ddev_has_receiver_info( pddev ) );
break;
case IOCTL_GET_GPS_ALL_POUT_INFO:
- _io_read_gps_chk( pddev, PC_GPS_ALL_POUT_INFO, all_pout_info, pout,
+ _io_read_gps_chk( pddev, PC_GPS_ALL_POUT_INFO, all_pout_info_idx, pout,
pout_size, _pcps_ddev_has_receiver_info( pddev ) );
break;
case IOCTL_GET_ALL_PTP_UC_MASTER_INFO:
- _io_read_gps_chk( pddev, PC_GPS_ALL_PTP_UC_MASTER_INFO, all_ptp_uc_master_info,
+ _io_read_gps_chk( pddev, PC_GPS_ALL_PTP_UC_MASTER_INFO, all_ptp_uc_master_info_idx,
pout, pout_size, _pcps_ddev_has_ptp_unicast( pddev ) );
break;
+
+ case IOCTL_GET_ALL_GPIO_INFO:
+ _io_read_gps_chk( pddev, PC_GPS_ALL_GPIO_INFO, all_gpio_info_idx,
+ pout, pout_size, _pcps_ddev_has_gpio( pddev ) );
+ break;
+
+
+ case IOCTL_GET_ALL_GPIO_STATUS:
+ _io_read_gps_var_chk( pddev, PC_GPS_ALL_GPIO_STATUS, all_gpio_status_idx,
+ pout, _pcps_ddev_has_gpio( pddev ) ); //##++++++++++++++++++++++++ condition??
+ break;
+
+
+ case IOCTL_GET_ALL_XMR_STATUS:
+ _io_read_gps_chk( pddev, PC_GPS_ALL_XMR_STATUS, all_xmulti_ref_status_idx,
+ pout, pout_size, _pcps_ddev_has_xmr( pddev ) );
+ break;
+
+
+ case IOCTL_GET_ALL_XMR_INFO:
+ _io_read_gps_chk( pddev, PC_GPS_ALL_XMR_INFO, all_xmulti_ref_info_idx,
+ pout, pout_size, _pcps_ddev_has_xmr( pddev ) );
+ break;
+
#endif // _MBG_SUPP_VAR_ACC_SIZE
+ case IOCTL_GET_GNSS_MODE_INFO:
+ _io_read_gps_var_chk( pddev, PC_GPS_GNSS_MODE, gnss_mode_info,
+ pout, _pcps_ddev_is_gnss( pddev ) );
+ break;
+
+ case IOCTL_GET_GPIO_CFG_LIMITS:
+ _io_read_gps_var_chk( pddev, PC_GPS_GPIO_CFG_LIMITS, mbg_gpio_cfg_limits,
+ pout, _pcps_ddev_has_gpio( pddev ) );
+ break;
+
+ case IOCTL_GET_XMR_INSTANCES:
+ _io_read_gps_var_chk( pddev, PC_GPS_XMR_INSTANCES, xmulti_ref_instances,
+ pout, _pcps_ddev_has_xmr( pddev ) );
+ break;
+
+ case IOCTL_GET_XMR_HOLDOVER_STATUS:
+ _io_read_gps_var_chk( pddev, PC_GPS_XMR_HOLDOVER_STATUS, xmr_holdover_status,
+ pout, _pcps_ddev_has_xmr( pddev ) );
+ break;
+
+
+
// Codes writing device configuration
case IOCTL_SET_PCPS_SERIAL:
@@ -1582,6 +1843,19 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
+ case IOCTL_SET_GNSS_MODE_SETTINGS:
+ _io_write_gps_var_chk( pddev, PC_GPS_GNSS_MODE, gnss_mode_settings, pin,
+ _pcps_ddev_is_gnss( pddev ) );
+ break;
+
+
+ case IOCTL_SET_GPIO_SETTINGS_IDX:
+ _io_write_var_chk( pddev, PC_GPS_GPIO_SETTINGS_IDX, mbg_gpio_settings_idx,
+ pin, _pcps_ddev_has_gpio( pddev ) );
+ break;
+
+
+
// Operations which may severely affect system operation
case IOCTL_SET_PCPS_TIME:
@@ -1622,62 +1896,13 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
break;
- // Generic read/write operations which can do anything
-
- case IOCTL_PCPS_GENERIC_READ:
- #if USE_IOCTL_GENERIC_REQ
- _iob_from_pin_var( iob.req, pin );
- p_buff_out = _pcps_kmalloc( iob.req.out_sz );
-
- if ( p_buff_out == NULL )
- {
- _mbgddmsg_4( MBG_DBG_INFO, "%s: unable to alloc %lu bytes for %s, cmd: %02lX",
- pcps_driver_name, (ulong) iob.req.out_sz,
- "IOCTL_PCPS_GENERIC_READ", (ulong) iob.req.info );
- goto err_no_mem;
- }
-
- _pcps_sem_inc_safe( pddev );
- rc = _pcps_read( pddev, (uint8_t) iob.req.info, p_buff_out,
- (uint8_t) iob.req.out_sz );
- _pcps_sem_dec( pddev );
-
- if ( rc == MBG_SUCCESS )
- _frc_iob_to_pout( p_buff_out, iob.req.out_p, iob.req.out_sz );
-
- _pcps_kfree( p_buff_out, iob.req.out_sz );
-
- if ( rc != MBG_SUCCESS )
- goto err_access;
-
- #else
-
- _iob_from_pin_var( iob.ctl, pin );
- buffer_size = sizeof( iob.ctl ) + iob.ctl.data_size_out;
- p_buff = _pcps_kmalloc( buffer_size );
-
- if ( p_buff == NULL )
- goto err_no_mem;
-
- _pcps_sem_inc_safe( pddev );
- rc = _pcps_read( pddev, (uint8_t) iob.ctl.info, p_buff->data,
- (uint8_t) iob.ctl.data_size_out );
- _pcps_sem_dec( pddev );
-
- if ( rc == MBG_SUCCESS )
- {
- p_buff->ctl = iob.ctl;
- _iob_to_pout( p_buff, pout, buffer_size ); //##+++++++ need to check this !!
- }
+ case IOCTL_SET_XMR_SETTINGS_IDX:
+ _io_write_gps_var( pddev, PC_GPS_XMR_SETTINGS_IDX, xmulti_ref_settings_idx, pin );
+ break;
- _pcps_kfree( p_buff, buffer_size );
- if ( rc != MBG_SUCCESS )
- goto err_access;
-
- #endif
- break;
+ // Generic read/write operations which can do anything
case IOCTL_PCPS_GENERIC_WRITE:
#if USE_IOCTL_GENERIC_REQ
@@ -1692,7 +1917,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
goto err_no_mem;
}
- _frc_iob_from_pin( p_buff_in, pin, iob.req.in_sz );
+ _frc_iob_from_pin( p_buff_in, iob.req.in_p, iob.req.in_sz );
_pcps_sem_inc_safe( pddev );
rc = pcps_write( pddev, (uint8_t) iob.req.info, p_buff_in,
@@ -1701,7 +1926,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
_pcps_kfree( p_buff_in, iob.req.in_sz );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#else
@@ -1722,62 +1947,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
_pcps_kfree( p_buff, buffer_size );
- if ( rc != MBG_SUCCESS )
- goto err_access;
-
- #endif
- break;
-
-
- case IOCTL_PCPS_GENERIC_READ_GPS:
- #if USE_IOCTL_GENERIC_REQ
- _iob_from_pin_var( iob.req, pin );
- p_buff_out = _pcps_kmalloc( iob.req.out_sz );
-
- if ( p_buff_out == NULL )
- {
- _mbgddmsg_4( MBG_DBG_INFO, "%s: unable to alloc %lu bytes for %s, GPS cmd: %02lX",
- pcps_driver_name, (ulong) iob.req.out_sz,
- "IOCTL_PCPS_GENERIC_READ_GPS", (ulong) iob.req.info );
- goto err_no_mem;
- }
-
- _pcps_sem_inc_safe( pddev );
- rc = pcps_read_gps( pddev, (uint8_t) iob.req.info, p_buff_out,
- (uint16_t) iob.req.out_sz );
- _pcps_sem_dec( pddev );
-
- if ( rc == MBG_SUCCESS )
- _frc_iob_to_pout( p_buff_out, iob.req.out_p, iob.req.out_sz );
-
- _pcps_kfree( p_buff_out, iob.req.out_sz );
-
- if ( rc != MBG_SUCCESS )
- goto err_access;
-
- #else
-
- _iob_from_pin_var( iob.ctl, pin );
- buffer_size = sizeof( iob.ctl ) + iob.ctl.data_size_out;
- p_buff = _pcps_kmalloc( buffer_size );
-
- if ( p_buff == NULL )
- goto err_no_mem;
-
- _pcps_sem_inc_safe( pddev );
- rc = pcps_read_gps( pddev, (uint8_t) iob.ctl.info, p_buff->data,
- (uint16_t) iob.ctl.data_size_out );
- _pcps_sem_dec( pddev );
-
- if ( rc == MBG_SUCCESS )
- {
- p_buff->ctl = iob.ctl;
- _iob_to_pout( p_buff, pout, buffer_size ); //##+++++++ need to check this !!
- }
-
- _pcps_kfree( p_buff, buffer_size );
-
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#endif
@@ -1797,7 +1967,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
goto err_no_mem;
}
- _frc_iob_from_pin( p_buff_in, pin, iob.req.in_sz );
+ _frc_iob_from_pin( p_buff_in, iob.req.in_p, iob.req.in_sz );
_pcps_sem_inc_safe( pddev );
rc = pcps_write_gps( pddev, (uint8_t) iob.req.info, p_buff_in,
@@ -1806,7 +1976,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
_pcps_kfree( p_buff_in, iob.req.in_sz );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#else
@@ -1827,7 +1997,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
_pcps_kfree( p_buff, buffer_size );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#endif
@@ -1851,7 +2021,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
goto err_no_mem;
}
- _frc_iob_from_pin( p_buff_in, pin, iob.req.in_sz );
+ _frc_iob_from_pin( p_buff_in, iob.req.in_p, iob.req.in_sz );
}
else
{
@@ -1895,7 +2065,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
if ( p_buff_out )
_pcps_kfree( p_buff_out, iob.req.out_sz );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#else
@@ -1927,7 +2097,7 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
_pcps_kfree( p_buff, buffer_size );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto err_access;
#endif
@@ -1991,28 +2161,39 @@ int ioctl_switch( PCPS_DDEV *pddev, unsigned int ioctl_code,
#endif // USE_DEBUG_PORT
- default:
+ default: // Unknown IOCTL code
goto err_inval;
}
+ // We get here in case of success.
return rc;
err_inval:
+ // We get here if the IOCTL code is inappropriate
+ // for this target / OS.
+ // POSIX return code would probably be -ENODEV.
return MBG_ERR_INV_DEV_REQUEST;
err_support:
+ // We get here if the IOCTL code is inappropriate
+ // for this device.
+ // POSIX return code would be -ENOTTY.
return MBG_ERR_NOT_SUPP_BY_DEV;
err_no_mem:
+ // We get here if we were unable to allocate memory.
+ // POSIX return code would be -ENOMEM.
return MBG_ERR_NO_MEM;
err_busy_unsafe:
return MBG_ERR_IRQ_UNSAFE;
err_access:
- return rc; // return the rc from the low level routine
-
+ // We get here if device access failed.
+ // POSIX return code would probably be -EIO.
+ // Return the rc from the low level routine.
+ return rc;
#if defined( USE_COPY_KERNEL_USER )
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbg_arch.h b/src/external/bsd/meinberg/dist/mbglib/common/mbg_arch.h
index ebfe035..a08ec76 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbg_arch.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbg_arch.h
@@ -1,20 +1,28 @@
/**************************************************************************
*
- * $Id: mbg_arch.h 1.3.1.4 2011/06/27 16:12:59 martin TRASH $
+ * $Id: mbg_arch.h 1.6 2017/01/27 09:03:16 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* Definitions to support different computer hardware architectures.
*
+ * For a good summary of predefined macros which can be used to determine
+ * the build environment, the target environment, and architecture, see:
+ * http://sourceforge.net/p/predef/wiki/Home/
+ *
* -----------------------------------------------------------------------
* $Log: mbg_arch.h $
- * Revision 1.3.1.4 2011/06/27 16:12:59 martin
- * Revision 1.3.1.3 2011/04/12 12:55:28 martin
- * Include words.h.
- * Revision 1.3.1.2 2011/02/09 15:46:48 martin
- * Revision 1.3.1.1 2011/02/09 15:26:58 martin
+ * Revision 1.6 2017/01/27 09:03:16 martin
+ * Added macros _mbg_swab8() and _mbg_swab64().
+ * Fixed macro syntax.
+ * Modified _swab_dummy() to avoid compiler warnings due to unused variables.
+ * Revision 1.5 2014/03/11 16:01:55 martin
+ * Added a comment.
+ * Revision 1.4 2012/10/02 18:32:00 martin
+ * Include words.h and, conditionally, stdlib.h.
+ * Use generic preprocessor symbol MBG_TGT_KERNEL.
* Revision 1.3 2009/06/12 13:12:37Z martin
* Fixed compiler warning.
* Revision 1.2 2009/03/19 15:14:15 martin
@@ -66,7 +74,7 @@
// to access unaligned data.
#if !defined( _mbg_put_unaligned )
- #define _mbg_put_unaligned( _v, _p ) ((void)( *(_p) = (_v) ))
+ #define _mbg_put_unaligned( _v, _p ) do { ((void)( *(_p) = (_v) )); } while ( 0 )
#endif
#if !defined( _mbg_get_unaligned )
@@ -119,8 +127,9 @@
-// swap a double type variable bytewise e.g. to convert the endianess
-
+/**
+ * @brief Swap a 'double' type variable bytewise e.g. to convert the endianess
+ */
static __mbg_inline
void mbg_swab_double( double *p )
{
@@ -143,22 +152,27 @@ void mbg_swab_double( double *p )
#if defined( MBG_ARCH_BIG_ENDIAN )
- #define _mbg_swab16( _p ) *(_p) = __swab16( *(_p) )
- #define _mbg_swab32( _p ) *(_p) = __swab32( *(_p) )
+ #define _mbg_swab8( _p ) _nop_macro_fnc() // always a dummy, but for completeness ...
+ #define _mbg_swab16( _p ) do { *(_p) = __swab16( *(_p) ); } while ( 0 )
+ #define _mbg_swab32( _p ) do { *(_p) = __swab32( *(_p) ); } while ( 0 )
+ #define _mbg_swab64( _p ) do { *(_p) = __swab64( *(_p) ); } while ( 0 )
#define _mbg_swab_double( _p ) mbg_swab_double( _p )
#define _mbg_swab_doubles( _p, _n ) \
+ do \
{ \
int i; \
for ( i = 0; i < (_n); i++ ) \
_mbg_swab_double( &_p[i] ); \
- }
+ } while ( 0 )
#else
+ #define _mbg_swab8( _p ) _nop_macro_fnc()
#define _mbg_swab16( _p ) _nop_macro_fnc()
#define _mbg_swab32( _p ) _nop_macro_fnc()
+ #define _mbg_swab64( _p ) _nop_macro_fnc()
#define _mbg_swab_double( _p ) _nop_macro_fnc()
@@ -166,4 +180,16 @@ void mbg_swab_double( double *p )
#endif
+
+
+
+/**
+ * @brief A placeholder for yet missing _mbg_swab_..() macros
+ *
+ * We don't just use the _nop_macro_fnc() macros here to avoid
+ * compiler warnings 'unused variable'.
+ */
+#define _mbg_swab_dummy( _x ) do { (void) _x; } while ( 0 )
+
+
#endif /* _MBG_ARCH_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbg_cof.h b/src/external/bsd/meinberg/dist/mbglib/common/mbg_cof.h
new file mode 100755
index 0000000..ced7988
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbg_cof.h
@@ -0,0 +1,83 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_cof.h 1.2 2017/07/05 14:25:12 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Container macros (see Linux Kernel)
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_cof.h $
+ * Revision 1.2 2017/07/05 14:25:12 martin
+ * Reformatted code to conform to standard header file format.
+ * Changes tfor improved cross-platform compatibility.
+ * Revision 1.1 2015/09/09 10:42:27 martin
+ * Initial revision by philipp.
+ *
+ **************************************************************************/
+
+#ifndef _MBG_COF_H
+#define _MBG_COF_H
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+
+#if !defined( MBG_TGT_KERNEL )
+ #include <stddef.h> // for offsetof()
+#endif
+
+
+#ifdef _MBG_COF
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined( MBG_TGT_POSIX )
+
+ // A special construct supported by gcc/clang and and implemented
+ // e.g. in the Linux kernel, which is said to be very type-safe:
+ #define mbg_container_of( _ptr, _type, _member ) ({ \
+ const typeof( ((_type *)0)->_member ) *__mptr = (_ptr); \
+ (_type *)((char *)__mptr - offsetof(_type,_member));})
+
+#else
+
+ // A different implementation in ANSI C, which supports type-checking anyway:
+ #define mbg_container_of( _ptr, _type, _member ) \
+ ( (_type *)( (char *)(1 ? (_ptr) : &((_type *)0)->_member) - offsetof( _type, _member )))
+
+#endif
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+/* (no header definitions found) */
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBG_COF_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbg_tgt.h b/src/external/bsd/meinberg/dist/mbglib/common/mbg_tgt.h
index a2eaaa2..2a63b1a 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbg_tgt.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbg_tgt.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_tgt.h 1.22.2.13 2011/06/22 07:51:03 martin TRASH $
+ * $Id: mbg_tgt.h 1.36 2017/07/04 12:35:11 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,29 +11,121 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_tgt.h $
- * Revision 1.22.2.13 2011/06/22 07:51:03 martin
+ * Revision 1.36 2017/07/04 12:35:11 martin
+ * Fixed build for Windows kernel space.
+ * Don't define ssize_t if HAVE_SSIZE_T is already defined.
+ * Added definition for _NO_MBG_API.
+ * Fixed missing 'bool' type for old Linux kernels.
+ * Fixed missing 'struct timespec' for DOS.
+ * Evaluate preprocessor symbol KERNEL_HAS_BOOL to avoid
+ * compiler errors due to duplicate definitions in specific
+ * Linux kernels patched by the distro maintainers.
+ * Provide ssize_t for C++Builder 5.
+ * Improved Visual Studio version checking.
+ * New define MBG_TGT_HAS_NODE_NAME.
+ * Revision 1.35 2016/08/05 12:21:34 martin
+ * Conditionally define a macro _DEPRECATED_BY which can be used to
+ * tag functions as deprecated, so compilers can emit appropriate warnings.
+ * New symbol MBG_TGT_HAS_ABS64.
+ * Moved some compatibility definitions from gpsserio.h here.
+ * Define ssize_t for Windows, if required.
+ * Conditionally provided struct timespec for Windows.
+ * Added compatible 64 bit type print format specifiers.
+ * Include inttypes.h for all targets providing also stdint.h.
+ * Added some MSVC version code information.
+ * Fixes for FreeBSD.
+ * Fixed some spelling.
+ * Tmp workaround for 2.6.32-5-sparc64.
+ * Proper fix required.
+ * Revision 1.34.1.26 2016/08/05 10:38:10 martin
+ * Revision 1.34.1.25 2016/08/04 14:51:25Z martin
+ * Moved some compatibility definitions from gpsserio.h to mbg_tgt.h.
+ * Revision 1.34.1.24 2016/08/02 13:10:58 martin
+ * Define ssize_t for Windows, if required.
+ * Revision 1.34.1.23 2016/07/18 14:41:27Z martin
+ * New symbol MBG_TGT_HAS_ABS64.
+ * Revision 1.34.1.22 2016/07/14 09:00:58Z martin
+ * Conditionally provided struct timespec for Windows.
+ * Revision 1.34.1.21 2016/07/07 10:01:28Z martin
+ * Modified inclusion of Windows header files.
+ * Revision 1.34.1.20 2016/06/06 12:59:03 thomas-b
+ * Include all necessary Windows headers in the needed sequence
+ * Revision 1.34.1.19 2016/04/26 14:53:06 martin
+ * Revision 1.34.1.18 2016/04/26 13:31:08Z martin
+ * Added compatible 64 bit type print format specifiers.
+ * Revision 1.34.1.17 2016/04/25 14:46:20Z martin
+ * Include inttypes.h for all targets providing also stdint.h.
+ * Revision 1.34.1.16 2016/03/02 12:26:15 martin
+ * *** empty log message ***
+ * Revision 1.34.1.15 2016/02/26 09:12:11 paul
+ * Revision 1.34.1.14 2015/12/10 12:34:14Z martin
+ * *** empty log message ***
+ * Revision 1.34.1.13 2015/12/01 14:55:52 martin
+ * Revision 1.34.1.12 2015/12/01 14:54:08Z martin
+ * *** empty log message ***
+ * Revision 1.34.1.11 2015/12/01 14:52:20 martin
+ * *** empty log message ***
+ * Revision 1.34.1.10 2015/12/01 14:43:44 martin
+ * *** empty log message ***
+ * Revision 1.34.1.9 2015/12/01 13:55:09 martin
+ * Conditionally define a macro _DEPRECATED_BY which can be used to
+ * tag functions as deprecated, so compilers can emit appropriate warnings.
+ * Revision 1.34.1.8 2015/10/28 13:45:25 martin
+ * Added some MSVC version code information.
+ * Revision 1.34.1.7 2015/10/19 09:34:56 martin
+ * Fixed some spelling.
+ * Revision 1.34.1.6 2015/10/15 12:49:10 marvin
+ * Revision 1.34.1.5 2015/10/08 08:55:16Z martin
+ * Revision 1.34.1.4 2015/10/05 15:07:23Z marvin
+ * Unicode support.
+ * Revision 1.34.1.3 2015/09/21 08:58:27Z martin
+ * *** empty log message ***
+ * Revision 1.34.1.2 2015/09/18 14:53:25 martin
+ * Fixes for FreeBSD.
+ * Revision 1.34.1.1 2015/04/07 15:40:59 martin
+ * Tmp workaround for 2.6.32-5-sparc64.
+ * Proper fix required.
+ * Revision 1.34 2015/03/03 13:32:49 martin
+ * Provide __func__ for MS Visual Studio.
+ * Revision 1.33 2015/03/02 11:27:59Z martin
+ * Windows only:
+ * Define _CRT_SECURE_NO_WARNINGS to quiet compiler warnings.
+ * Define WIN32_LEAN_AND_MEAN only if it hasn't been defined before.
+ * Revision 1.32 2014/06/24 09:21:44 martin
+ * Update for newer C++Builder versions.
+ * Revision 1.31 2014/05/27 10:23:33 martin
+ * Finer control of which types are required for or already
+ * available on particular target systems.
+ * First definitions to support SunOS/Solaris.
+ * Revision 1.30 2014/04/01 12:55:58 martin
+ * Define MBG_TGT_WIN32 also for MS resource compiler.
+ * New target MBG_TGT_POSIX.
+ * Always include winsock2.h and windows.h for MBG_TGT_WIN32.
+ * Always include unistd.h for MBG_TGT_POSIX.
+ * Define empty __attribute__ macro for non-gcc environments.
+ * Revision 1.29 2013/02/01 14:50:46 martin
+ * Fixed a typo which caused an error under Borland CBuilder 5.
+ * Revision 1.28 2012/12/12 10:03:16Z martin
+ * Fix for Borland C 3.1.
+ * Revision 1.27 2012/11/29 12:03:14Z martin
+ * Moved definition of _no_macro_fnc() to words.h.
+ * Revision 1.26 2012/11/02 09:01:47Z martin
+ * Merged some stuff depending on the build environment here
+ * and cleaned up.
+ * Revision 1.25 2012/04/04 07:17:18 martin
+ * Treat QNX Neutrino as Unix target.
+ * Revision 1.24 2011/08/23 10:21:23 martin
+ * New symbol _NO_MBG_API_ATTR which can be used with functions
+ * which are going to be exported by a DLL, but actually aren't, yet.
+ * Revision 1.23 2011/08/19 10:47:00 martin
+ * Don't include stddef.h.
+ * Distinguish between different gcc target platforms.
+ * Initial support for IA64 platform.
+ * Support wchar_t for BSD.
* Defined _NO_USE_PACK_INTF for Sparc and IA64.
- * Revision 1.22.2.12 2011/04/12 15:36:00 martin
- * Revision 1.22.2.11 2011/03/22 10:25:26Z martin
* Fixed typo in comment.
- * Revision 1.22.2.10 2011/02/09 15:46:48 martin
- * Revision 1.22.2.9 2011/02/09 15:27:10 martin
- * Revision 1.22.2.8 2011/02/04 10:15:54Z martin
- * Revision 1.22.2.7 2011/02/01 17:11:54 martin
- * Revision 1.22.2.6 2011/01/27 16:16:28 martin
- * Support wchar_t for BSD.
- * Revision 1.22.2.5 2011/01/24 17:08:40 martin
- * Fixed build under FreeBSD.
- * Revision 1.22.2.4 2010/12/14 11:04:02 martin
- * Revision 1.22.2.3 2010/05/25 14:42:32Z martin
- * Don't use MM I/O on IA64 platform.
- * Revision 1.22.2.2 2010/05/21 13:09:35 martin
- * Initial support for IA64 platform.
- * Revision 1.22.2.1 2010/04/22 09:35:56 martin
- * Distinguish between different gcc target platforms.
* Revision 1.22 2009/10/01 08:20:50 martin
* Fixed inline code support with different BC versions.
- * Revision 1.1 2009/11/20 12:24:05 philipp
* Revision 1.21 2009/09/01 10:34:23Z martin
* Don't define __mbg_inline for CVI and undefined targets.
* Revision 1.20 2009/08/18 15:14:26 martin
@@ -60,9 +152,9 @@
* Recognize DOS target under Watcom compilers.
* Flag Watcom C always supports wchar_t.
* Revision 1.12 2008/01/17 09:38:50Z daniel
- * Added macros to determine whether C language extensions
+ * Added macros to determine whether C language extensions
* (e.g. C94, C99) are supported by the target environment.
- * Added macro to check whether wchar_t and friends are
+ * Added macro to check whether wchar_t and friends are
* supported, and some compatibility stuff.
* Revision 1.11 2007/10/31 16:58:03 martin
* Fixed __mbg_inline for Borland C (DOS).
@@ -71,7 +163,7 @@
* Added MBG_PORT_HANDLE type for serial ports.
* Added macros for unified inline code syntax.
* Revision 1.9 2006/12/08 12:45:54Z martin
- * Under Windows include ntddk.h rather than windows.h
+ * Under Windows include ntddk.h rather than windows.h
* if building kernel driver .
* Revision 1.8 2006/10/25 12:20:45Z martin
* Initial support for FreeBSD, NetBSD, and OpenBSD.
@@ -88,7 +180,7 @@
* Revision 1.3 2003/04/09 13:37:20Z martin
* Added definition for _MBG_API.
* Revision 1.2 2003/02/24 16:08:45Z martin
- * Don't setup for Win32 PNP if explicitely configured non-PNP.
+ * Don't setup for Win32 PNP if explicitly configured non-PNP.
* Revision 1.1 2002/02/19 13:46:20Z MARTIN
* Initial revision
*
@@ -109,11 +201,21 @@
/* Start of header body */
-#if defined( _CVI ) || defined( _CVI_ )
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined( _CVI_ )
- #define MBG_TGT_WIN32
#define MBG_TGT_CVI
+ #if defined( _NI_mswin_ )
+ #define MBG_TGT_WIN32
+ #else
+ #error Unsupported CVI target platform.
+ #endif
+
#elif defined( _WIN32_WINNT )
// MS platform SDK
@@ -123,7 +225,7 @@
#if ( _WIN32_WINNT >= 0x0500 )
// Win2k and above
#if !defined( MBG_TGT_WIN32_NON_PNP )
- // only if not explicitely disabled
+ // only if not explicitly disabled
#define MBG_TGT_WIN32_PNP
#endif
#endif
@@ -149,6 +251,11 @@
// MS Visual C++
#define MBG_TGT_WIN32
+#elif defined( RC_INVOKED )
+
+ //MS resource compiler
+ #define MBG_TGT_WIN32
+
#elif defined( __WINDOWS_386__ )
// Watcom C/C++ for target Win32
@@ -189,6 +296,17 @@
// GCC for target OpenBSD
#define MBG_TGT_OPENBSD
+#elif defined( __sun ) // Oracle Solaris or other SunOS derived operating system
+
+ // __SUNPRO_C Oracle Solaris Studio C compiler, __SUNPRO_C value is the version number
+ // __SUNPRO_CC Oracle Solaris Studio C++ compiler, __SUNPRO_CC value is the version number
+ // __sparc generate code for SPARC (R) architecture (32-bit or 64-bit)
+ // __sparcv9 generate code for 64-bit SPARC architecture
+ // __i386 generate code for 32-bit x86 architecture
+ // __amd64 generate code for 64-bit x64 architecture
+
+ #define MBG_TGT_SUNOS
+
#elif defined( __QNX__ )
// any compiler for target QNX
@@ -212,13 +330,48 @@
#endif
-// Some definitions which depend on the type of compiler ...
-#if defined( __GNUC__ )
- #define __mbg_inline __inline__
+#if defined( MBG_TGT_FREEBSD ) \
+ || defined( MBG_TGT_NETBSD ) \
+ || defined( MBG_TGT_OPENBSD )
+ #define MBG_TGT_BSD
+
+ #if defined( _KERNEL )
+ #define MBG_TGT_KERNEL
+ #endif
+
+#endif
+
+#if defined( MBG_TGT_LINUX ) \
+ || defined( MBG_TGT_BSD ) \
+ || defined( MBG_TGT_QNX_NTO ) \
+ || defined( MBG_TGT_SUNOS )
+
+ #define MBG_TGT_POSIX
+ #define MBG_TGT_UNIX
+#endif
+
+#if defined( MBG_TGT_WIN32 )
+
+ #define _CRT_SECURE_NO_WARNINGS 1
+
+#endif
+
+
+// Some definitions depending on the build environment ...
- #define MBG_TGT_HAS_WCHAR_T 1
+#if defined( __GNUC__ ) || defined( __clang__ )
+
+ #if defined( __clang__ )
+ #define _CLANG_VERSION ( __clang_major__ * 10000 \
+ + __clang_minor__ * 100 \
+ + __clang_patchlevel__ )
+ #endif // defined( __clang__ )
+
+ #define _GCC_VERSION ( __GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__ )
#if defined( __i386__ )
@@ -249,19 +402,301 @@
#endif
+ #if defined( MBG_TGT_LINUX )
+
+ #if defined( MBG_TGT_KERNEL )
+
+ #include <linux/types.h>
+ #include <linux/version.h>
+
+ #if ( LINUX_VERSION_CODE <= KERNEL_VERSION( 2, 6, 4 ) ) || \
+ ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 4 ) ) // must be true for 2.6.32-5-sparc64
+ #define _ULONG_DEFINED 1
+ #define _USHORT_DEFINED 1
+ #define _UINT_DEFINED 1
+ #endif
+
+ // The 'bool' type is supported by the vanilla Linux kernel 2.6.19 and later.
+ // However, looks like at least the RedHat folks have backported this to 2.6.18,
+ // so KERNEL_HAS_BOOL can be defined to avoid a compiler error due to
+ // duplicate definition.
+ #if ( ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 19 ) ) && !defined( KERNEL_HAS_BOOL ) )
+ typedef _Bool bool;
+ #define bool bool
+ #endif
+
+ // 'true' and 'false' are also defined by newer kernel versions
+ // as enum in linux/stddef.h, but may not be defined by
+ // older kernels.
+
+ #else
+
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+
+ #if defined( __u_char_defined )
+ #define _ULONG_DEFINED 1
+ #define _USHORT_DEFINED 1
+ #define _UINT_DEFINED 1
+ #endif
+
+ #endif
+
+ #define MBG_TGT_HAS_DEV_FN 1
+
+ #elif defined( MBG_TGT_BSD )
+
+ #if defined( MBG_TGT_KERNEL )
+ #include <sys/types.h>
+ #else
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ #endif
+
+ #define MBG_TGT_HAS_DEV_FN 1
+
+ #elif defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino)
+
+ #include <unistd.h>
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+
+ #else
+
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+
+ #endif
+
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+
+ #define MBG_TGT_HAS_WCHAR_T 1
+
+
+ #if defined( __clang__ )
+ #define _DEPRECATED_BY( _s ) __attribute__((deprecated("use \"" _s "\" instead"))) // works with clang 3.4.1
+ #elif ( _GCC_VERSION > 40500 ) // gcc 4.5.0 and newer
+ #define _DEPRECATED_BY( _s ) __attribute__((deprecated("use \"" _s "\" instead")))
+ #elif ( _GCC_VERSION > 30100 ) // gcc 3.1 and newer
+ #define _DEPRECATED_BY( _s ) __attribute__((deprecated))
+ #else
+ // Not supported at all, use empty default definiton below.
+ #endif
+
+ #if ( _GCC_VERSION > 30100 ) // gcc 3.1 and newer
+ #define __mbg_inline __inline__ __attribute__((always_inline))
+ #else
+ // Not supported at all, use empty default definiton below.
+ #define __mbg_inline __inline__
+ #endif
+
#elif defined( _MSC_VER )
+ // Known predifined MS compiler version codes:
+ // 1910: MSVC++ 15.0 (Visual Studio 2017)
+ // 1900: MSVC++ 14.0 (Visual Studio 2015)
+ // 1800: MSVC++ 12.0 (Visual Studio 2013)
+ // 1700: MSVC++ 11.0 (Visual Studio 2012)
+ // 1600: MSVC++ 10.0 (Visual Studio 2010)
+ // 1500: MSVC++ 9.0 (Visual Studio 2008)
+ // 1400: MSVC++ 8.0 (Visual Studio 2005, Windows Server 2003 SP1 DDK - AMD64)
+ // 1310: MSVC++ 7.1 (Visual Studio .NET 2003, Windows Server 2003 DDK)
+ // 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK)
+ // 1200: MSVC++ 6.0
+ // 1100: MSVC++ 5.0
+
+ // Enable this to get compile-time messages on the compiler version
+ #if 0
+ #if ( _MSC_VER >= 1910 )
+ #error >= 1910: MSVC++ 15.0 (Visual Studio 2017), or later
+ #elif ( _MSC_VER >= 1900 )
+ #error 1900: MSVC++ 14.0 (Visual Studio 2015)
+ #elif ( _MSC_VER >= 1800 )
+ #error 1800: MSVC++ 12.0 (Visual Studio 2013)
+ #elif ( _MSC_VER >= 1700 )
+ #error 1700: MSVC++ 11.0 (Visual Studio 2012)
+ #elif ( _MSC_VER >= 1600 )
+ #error 1600: MSVC++ 10.0 (Visual Studio 2010)
+ #elif ( _MSC_VER >= 1500 )
+ #error 1500: MSVC++ 9.0 (Visual Studio 2008)
+ #elif ( _MSC_VER >= 1400 )
+ #error STRINGIFY( _MSC_VER ) MSVC++ 8.0 (Visual Studio 2005, Windows Server 2003 SP1 DDK - AMD64)
+ #elif ( _MSC_VER >= 1310 )
+ #error 1310: MSVC++ 7.1 (Visual Studio .NET 2003, Windows Server 2003 DDK)
+ #elif ( _MSC_VER >= 1300 )
+ #error 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK)
+ #elif ( _MSC_VER >= 1200 )
+ #error 1200: MSVC++ 6.0
+ #elif ( _MSC_VER >= 1100 )
+ #error 1100: MSVC++ 5.0
+ #else
+ #error <1100: Older than MSVC 4
+ #endif
+ #endif
+
+ // "struct timespec" is supported only since VS2015
+ // If it is then also the symbol TIME_UTC should be defined.
+ // Functions to read the current time as struct timespec
+ // are timespec_get() and friends, which are also only provided
+ // by VS2015 and later.
+ // As of VS2015, only TIME_UTC is supported to read
+ // the UTC system time, there is no equivalent for
+ // the POSIX CLOCK_MONOTONIC. However, QPC can be used
+ // to get monotonic time stamps and intervals.
+ #if ( _MSC_VER < 1900 )
+ #if !defined( HAVE_STRUCT_TIMESPEC )
+ #define MBG_TGT_MISSING_STRUCT_TIMESPEC 1
+ #endif
+ #endif
+
+ #if ( _MSC_VER >= 1600 )
+ #include <stdint.h>
+ #include <inttypes.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define MBG_TGT_HAS_INT_8_16_32 1
+ #define MBG_PRE64_PREFIX "I64"
+ #endif
+
+ #if !defined( __cplusplus )
+ // no bool support anyway
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #endif
+
+ #define MBG_TGT_HAS_WCHAR_T 1
+
#define __mbg_inline __forceinline
- #define MBG_TGT_HAS_WCHAR_T 1
+ // At least up to VS2008 the C99 builtin symbol __func__
+ // is not supported. Some VS versions support __FUNCTION__
+ // instead, but at least VC6 doesn't support this, either.
+ // of the current function instead.
+ #if ( _MSC_VER >= 1300 )
+ #define __func__ __FUNCTION__
+ #else
+ #define __func__ "func_???"
+ #endif
+
+ // The "deprecated" attribute should be supported since Visual Studio 2005,
+ // but doesn't seem to be supported by the compiler shipped with the
+ // "Windows Server 2003 SP1 DDK", which is used to build kernel drivers
+ // and defines the same _MSC_VER number as VS2005. For now we assume
+ // that this is supported by compilers shipped with newer SDKs.
+ #if ( ( _MSC_VER >= 1500 ) || \
+ ( ( _MSC_VER >= 1400 ) && !defined( _KDD_ ) ) )
+ #define _DEPRECATED_BY( _s ) __declspec(deprecated("deprecated, use \"" _s "\""))
+ #endif
+
+ // availability of _abs64()
+ #if ( _MSC_VER >= 1310 )
+ // This is supported at least since Visual Studio 2008
+ // and Windows Server 2003 SP1 DDK.
+ #define MBG_TGT_HAS_ABS64 1
+ #endif
+
+ #if !defined ( HAVE_SSIZE_T )
-#elif defined( _CVI ) || defined( _CVI_ )
+ // ssize_t support
+ #if ( _MSC_VER >= 1500 )
+ // ssize_t may not be defined, but SSIZE_T is
+ #include <basetsd.h>
+ typedef SSIZE_T ssize_t;
+ #else
+ // At least VC6 hasn't SIZE_T, either, but size_t
+ // is typedef'ed as unsigned int, so we just typedef
+ // the signed variant here.
+ typedef int ssize_t;
+ #endif
+
+ #define HAVE_SSIZE_T 1
- // Inline code is not supported.
+ #endif // !defined ( HAVE_SSIZE_T )
- #define MBG_TGT_HAS_WCHAR_T 0
+#elif defined( _CVI_ )
-#elif defined( __BORLANDC__ )
+ // 1000 for CVI v10.0 (CVI 2010)
+ // 911 for CVI v9.1.1 (CVI 2009 SP1)
+ // 910 for CVI v9.1 (CVI 2009)
+ // 310 for CVI v3.1
+ // 301 for CVI v3.0.1
+ // 1 for CVI v3.0
+
+ #if ( _CVI_ >= 910 )
+ // LabWindows/CVI 2009 is the first version providing stdint.h.
+ #include <stdint.h>
+ #include <inttypes.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define USE_LONG_FOR_INT32 1
+ #endif
+
+ // As of LabWindows/CVI 2010, stdbool.h is still missing.
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+
+ #define MBG_TGT_HAS_WCHAR_T 0
+
+ // Inline code is not supported, though the inline keyword
+ // is silently accepted since CVI v9.0
+
+#elif defined( __BORLANDC__ ) // or __CODEGEARC__ in newer versions
+
+ // 0x0200 Borland C/C++ 2.0
+ // 0x0400 Borland C/C++ 3.0
+ // 0x0410 Borland C/C++ 3.1
+ // 0x0550 Borland C/C++ 5.5 (C++Builder 5.0)
+
+ // Next codes are in addition defined as __CODEGEARC__
+ // See http://docwiki.embarcadero.com
+
+ // 0x0570 for Borland Developer Studio 2006 (BDS 2006)
+ // 0x0590 for C++Builder 2007
+ // 0x0591 for update 1 to C++Builder 2007
+ // 0x0592 for RAD Studio 2007
+ // 0x0593 for the December update to RAD Studio 2007
+ // 0x0610 for C++Builder 2009 and for C++Builder 2009 Update 1
+ // 0x0620 for C++Builder 2010 and for C++Builder 2010 Update 1
+ // 0x0621 for C++Builder 2010 Update 2
+ // 0x0630 for C++Builder XE
+ // 0x0631 for C++Builder XE Update 1
+ // 0x0640 for C++Builder XE2
+ // 0x0650 for C++Builder XE3
+
+ #if ( __BORLANDC__ >= 0x630 )
+ // C++Builder XE starts to provide stdbool.h
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #elif ( __BORLANDC__ >= 0x570 )
+ // BDS/Borland C++ Builder 2006 starts to provide at least stdint.h
+ #include <stdint.h>
+ #include <inttypes.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #if !defined( __cplusplus )
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #endif
+ #elif ( __BORLANDC__ >= 0x0550 )
+ #define MBG_TGT_HAS_INT_8_16_32 1
+ #define MBG_PRE64_PREFIX "I64"
+ #if !defined( __cplusplus )
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #endif
+ #else // e.g. BC 3.1 or earlier
+ #if ( __BORLANDC__ <= 0x410 )
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #define MBG_TGT_MISSING_BOOL_TYPE 1
+ #define USE_LONG_FOR_INT32 1
+ #define MBG_TGT_MISSING_STRUCT_TIMESPEC 1
+
+ typedef int ssize_t;
+ #endif
+ #endif
+
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
#if defined( __cplusplus )
#define __mbg_inline inline // standard C++ syntax
@@ -271,41 +706,71 @@
#define __mbg_inline // up to BC3.1 not supported for C
#endif
- #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+ #if !defined ( HAVE_SSIZE_T )
+ typedef int ssize_t; // required at least for C++ Builder 5
+ #define HAVE_SSIZE_T 1
+ #endif
#elif defined( __WATCOMC__ )
- #define __mbg_inline _inline
+ // 1050 v10.5
+ // 1100 v11.0
+ // 1200 Open Watcom C++ v1.0
+ // 1230 Open Watcom C++ v1.3
+ // 1270 Open Watcom C++ v1.7
- #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+ #if defined( MBG_TGT_QNX ) // QNX 4.x
-#endif
+ #include <sys/types.h>
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #elif ( __WATCOMC__ > 1230 ) // Open Watcom C 1.3 and above
-#if defined( MBG_TGT_FREEBSD ) \
- || defined( MBG_TGT_NETBSD ) \
- || defined( MBG_TGT_OPENBSD )
- #define MBG_TGT_BSD
+ #include <stdint.h>
+ #include <inttypes.h>
+
+ #elif !defined( __WATCOM_INT64__ ) // Watcom C 11
+
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
- #if defined( _KERNEL )
- #define MBG_TGT_KERNEL
#endif
+ #define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+
+ #define __mbg_inline _inline
+
#endif
-#if defined( MBG_TGT_LINUX ) \
- || defined( MBG_TGT_BSD ) \
- || defined( MBG_TGT_QNX_NTO )
- #define MBG_TGT_UNIX
+
+// If the build environment doesn't provide a inttypes.h file
+// with print format specifiers for 64 bit fixed size types
+// then MBG_PRE64_PREFIX should be defined which is used
+// to define our own C99 compatible format specifiers.
+// Eventually, similar definitions are required for 32, 16,
+// and 8 bit fixed size types.
+#if defined( MBG_PRE64_PREFIX )
+ #define PRIi64 MBG_PRE64_PREFIX "i"
+ #define PRId64 MBG_PRE64_PREFIX "d"
+ #define PRIo64 MBG_PRE64_PREFIX "o"
+ #define PRIu64 MBG_PRE64_PREFIX "u"
+ #define PRIx64 MBG_PRE64_PREFIX "x"
+ #define PRIX64 MBG_PRE64_PREFIX "X"
+#endif
+
+#if !defined( __GNUC__ ) && !defined( __attribute__ )
+ #define __attribute__( _x )
#endif
+#if !defined( _DEPRECATED_BY )
+ #define _DEPRECATED_BY( _s ) // empty definition
+#endif
#if defined( MBG_TGT_WIN32 )
#if defined( _AMD64_ )
- // This is used for AMD64 architecture and for
+ // This is used for AMD64 architecture and for
// Intel XEON CPUs with 64 bit extension.
#define MBG_TGT_WIN32_PNP_X64
#define WIN32_FLAVOR "x64"
@@ -317,9 +782,23 @@
#if defined( _KDD_ )
#define MBG_TGT_KERNEL
#include <ntddk.h>
+
+ #define _MBG_API
#else
// This must not be used for kernel drivers.
+
+ // Prevent inclusion of obsolete winsock.h in windows.h
+ #if !defined( WIN32_LEAN_AND_MEAN )
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+ #if !defined( _WINSOCKAPI_ )
+ #define _WINSOCKAPI_
+ #endif
+
#include <windows.h>
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+
typedef HANDLE MBG_HANDLE;
#define MBG_INVALID_HANDLE INVALID_HANDLE_VALUE
@@ -340,9 +819,15 @@
typedef DWORD DWORD_PTR;
#endif
- #endif
+ // socklen_t support
+ #if ( _MSC_VER < 1500 )
+ // At least VS2008 has a socklen_t type
+ typedef int socklen_t;
+ #endif
+
+ #define _MBG_API WINAPI
- #define _MBG_API WINAPI
+ #endif
#if defined( MBG_LIB_EXPORT )
#define _MBG_API_ATTR __declspec( dllexport )
@@ -350,7 +835,11 @@
#define _MBG_API_ATTR __declspec( dllimport )
#endif
-#elif defined( MBG_TGT_UNIX )
+#elif defined( MBG_TGT_POSIX )
+
+ #if !defined( MBG_TGT_KERNEL )
+ #include <unistd.h>
+ #endif
typedef int MBG_HANDLE;
typedef int MBG_PORT_HANDLE;
@@ -367,6 +856,44 @@
#endif
+/**
+ * @brief A socket file descriptor type
+ */
+#if defined( MBG_TGT_WIN32 )
+ #if !defined( MBG_TGT_KERNEL ) // we don't need this in kernel space
+ // usually evaluates to UINT_PTR, which in turn evaluates
+ // to (unsigned int), or (unsigned __int64).
+ typedef SOCKET MBG_SOCK_FD;
+ #endif
+#elif defined( MBG_TGT_POSIX )
+ typedef int MBG_SOCK_FD; //### TODO
+ //### TODO typedef int SOCKET;
+#endif
+
+
+
+/**
+ * @brief A value to mark an ::MBG_SOCK_FD as invalid
+ */
+#if defined( MBG_TGT_WIN32 )
+ #define MBG_INVALID_SOCK_FD INVALID_SOCKET // usually evaluates to (SOCKET)(~0) since SOCKET is unsigned
+#elif defined( MBG_TGT_POSIX )
+ #define MBG_INVALID_SOCK_FD -1
+#endif
+
+
+
+/**
+ * @brief The return code of socket functions in case of error
+ */
+#if defined( MBG_TGT_WIN32 )
+ #define MBG_SOCKET_ERR_RETVAL SOCKET_ERROR // usually evaluates to -1
+#elif defined( MBG_TGT_POSIX )
+ #define MBG_SOCKET_ERR_RETVAL -1
+#endif
+
+
+
#if !defined( _MBG_API )
#define _MBG_API
#endif
@@ -375,6 +902,14 @@
#define _MBG_API_ATTR
#endif
+#if !defined( _NO_MBG_API )
+ #define _NO_MBG_API
+#endif
+
+#if !defined( _NO_MBG_API_ATTR )
+ #define _NO_MBG_API_ATTR
+#endif
+
#if !defined( MBG_INVALID_PORT_HANDLE )
#define MBG_INVALID_PORT_HANDLE MBG_INVALID_HANDLE
#endif
@@ -383,11 +918,22 @@
#define MBG_USE_MM_IO_FOR_PCI 0
#endif
-
-#if !defined( _nop_macro_fnc )
- #define _nop_macro_fnc() do {} while (0)
+#if !defined( MBG_TGT_HAS_DEV_FN )
+ #define MBG_TGT_HAS_DEV_FN 0
#endif
+#if defined( MBG_TGT_MISSING_STRUCT_TIMESPEC )
+
+#include <time.h>
+
+ struct timespec
+ {
+ time_t tv_sec;
+ long tv_nsec;
+ };
+
+#endif // defined( MBG_TGT_MISSING_STRUCT_TIMESPEC )
+
// The macros below are defined in order to be able to check if
// certain C language extensions are available on the target system:
@@ -422,17 +968,6 @@
-/* End of header body */
-
-#undef _ext
-
-
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
@@ -446,6 +981,8 @@ extern "C" {
}
#endif
+/* End of header body */
-#endif /* _MBG_TGT_H */
+#undef _ext
+#endif /* _MBG_TGT_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgddmsg.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgddmsg.h
index 3f9a367..4517d7b 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgddmsg.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgddmsg.h
@@ -1,19 +1,25 @@
/**************************************************************************
*
- * $Id: mbgddmsg.h 1.9.1.1 2011/03/29 13:55:19 martin TRASH $
+ * $Id: mbgddmsg.h 1.11 2017/07/05 14:31:23 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * Print or remove debug messages by redefinitions.
+ * Definitions and function prototypes to deal with messages
+ * generated by kernel mode drivers. Some type of messages are
+ * always generated, others are only generated ibn DEBUG builds
+ * and are defined void in release builds.
*
* -----------------------------------------------------------------------
* $Log: mbgddmsg.h $
- * Revision 1.9.1.1 2011/03/29 13:55:19 martin
- * Also enable debug msgs if MBG_DEBUG is defined.
- * Revision 1.9 2011/01/26 18:13:49 martin
+ * Revision 1.11 2017/07/05 14:31:23 martin
+ * Added _mbg_kdd_msg...() macros.
+ * Code cleanup.
+ * Updated function prototypes.
+ * Revision 1.10 2012/10/02 18:33:21Z martin
* Support for *BSD.
+ * Also enable debug msgs if MBG_DEBUG is defined.
* Revision 1.8 2009/04/22 09:54:55 martin
* Include mbg_tgt.h also if building without DEBUG.
* Revision 1.7 2009/03/19 15:22:54 martin
@@ -38,104 +44,193 @@
#define _MBGDDMSG_H
+/* Other headers to be included */
+
#include <mbg_tgt.h>
-#if defined( DEBUG ) || ( defined( DBG ) && DBG ) || defined( MBG_DEBUG )
+#if defined( MBG_TGT_NETWARE )
+ #include <conio.h>
+#elif defined( MBG_TGT_OS2 )
+ #include <iprintf.h>
+#elif defined( MBG_TGT_WIN32 )
+ #include <ntddk.h>
+#elif defined( MBG_TGT_LINUX )
+ #include <linux/module.h>
+ #include <linux/version.h>
+#elif defined( MBG_TGT_BSD )
+ // nothing to include
+#else // MBG_TGT_QNX, MBG_TGT_DOS, ...
+ //##+++++++++++++
+ #include <stdio.h>
+#endif
-enum
-{
- MBG_DBG_ERR,
- MBG_DBG_WARN,
- MBG_DBG_INFO,
- MBG_DBG_DETAIL,
- MBG_DBG_INIT_DEV,
- MBG_DEBUG_SEM,
- MBG_DBG_IRQ,
- N_MBG_DBG_LVL
-};
-extern int debug;
+#ifdef _MBGDDMSG
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
-#define _chk_lvl( _lvl ) ( (_lvl) < debug )
#if defined( MBG_TGT_NETWARE )
- #include <conio.h>
#define _printf ConsolePrintf
#define _hd
#define _tl "\n"
#elif defined( MBG_TGT_OS2 )
- #include <iprintf.h>
#define _printf iprintf
#define _hd
#define _tl "\n"
#elif defined( MBG_TGT_WIN32 )
- #include <ntddk.h>
- #define _printf DbgPrint
+ #define _printf mbg_kdd_msg
#define _hd
- #define _tl "\n"
+ #define _tl
+ #define USE_MBG_KDD_MSG 1
#elif defined( MBG_TGT_LINUX )
- // #include <printk.h>
- #define _printf printk
- #define _hd KERN_INFO
- #define _tl "\n"
+ #if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 8 ) )
+ // vprintk not supported by the kernel
+ #define _printf printk
+ #define _hd KERN_INFO
+ #define _tl "\n"
+ #else
+ #define _printf mbg_kdd_msg
+ #define _hd KERN_NOTICE
+ #define _tl "\n"
+ #define USE_MBG_KDD_MSG 1
+ #endif
#elif defined( MBG_TGT_BSD )
#define _printf printf
#define _hd
#define _tl "\n"
#else // MBG_TGT_QNX, MBG_TGT_DOS, ...
- #include <stdio.h>
#define _printf printf
#define _hd
#define _tl "\n"
#endif
-#define _mbgddmsg_0( _lvl, _fmt ) \
-do { \
- if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl ); } \
+#if !defined( USE_MBG_KDD_MSG )
+ #define USE_MBG_KDD_MSG 0
+#endif
+
+
+#define _mbg_kdd_msg_0( _fmt ) \
+do { \
+ _printf( _hd _fmt _tl ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_1( _fmt, _p1 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_2( _fmt, _p1, _p2 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_3( _fmt, _p1, _p2, _p3 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2), (_p3) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_4( _fmt, _p1, _p2, _p3, _p4 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_5( _fmt, _p1, _p2, _p3, _p4, _p5 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_6( _fmt, _p1, _p2, _p3, _p4, _p5, _p6 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6) ); \
+} while ( 0 )
+
+#define _mbg_kdd_msg_7( _fmt, _p1, _p2, _p3, _p4, _p5, _p6, _p7 ) \
+do { \
+ _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6), (_p7) ); \
} while ( 0 )
-#define _mbgddmsg_1( _lvl, _fmt, _p1 ) \
+
+
+#if defined( DEBUG ) || ( defined( DBG ) && DBG ) || defined( MBG_DEBUG )
+
+enum
+{
+ MBG_DBG_ERR,
+ MBG_DBG_WARN,
+ MBG_DBG_INFO,
+ MBG_DBG_DETAIL,
+ MBG_DBG_INIT_DEV,
+ MBG_DEBUG_SEM,
+ MBG_DBG_IRQ,
+ N_MBG_DBG_LVL
+};
+
+
+#define _chk_lvl( _lvl ) ( (_lvl) < debug )
+
+#define _mbgddmsg_0( _lvl, _fmt ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1) ); } \
+ { _mbg_kdd_msg_0( _fmt ); } \
} while ( 0 )
-#define _mbgddmsg_2( _lvl, _fmt, _p1, _p2 ) \
+#define _mbgddmsg_1( _lvl, _fmt, _p1 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2) ); } \
+ { _mbg_kdd_msg_1( _fmt, (_p1) ); } \
} while ( 0 )
-#define _mbgddmsg_3( _lvl, _fmt, _p1, _p2, _p3 ) \
+#define _mbgddmsg_2( _lvl, _fmt, _p1, _p2 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2), (_p3) ); } \
+ { _mbg_kdd_msg_2( _fmt, (_p1), (_p2) ); } \
} while ( 0 )
-#define _mbgddmsg_4( _lvl, _fmt, _p1, _p2, _p3, _p4 ) \
+#define _mbgddmsg_3( _lvl, _fmt, _p1, _p2, _p3 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4) ); } \
+ { _mbg_kdd_msg_3( _fmt, (_p1), (_p2), (_p3) ); } \
} while ( 0 )
-#define _mbgddmsg_5( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5 ) \
+#define _mbgddmsg_4( _lvl, _fmt, _p1, _p2, _p3, _p4 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5) ); } \
+ { _mbg_kdd_msg_4( _fmt, (_p1), (_p2), (_p3), (_p4) ); } \
} while ( 0 )
-#define _mbgddmsg_6( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5, _p6 ) \
+#define _mbgddmsg_5( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6) ); } \
+ { _mbg_kdd_msg_5( _fmt, (_p1), (_p2), (_p3), (_p4), (_p5) ); } \
} while ( 0 )
-#define _mbgddmsg_7( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5, _p6, _p7 ) \
+#define _mbgddmsg_6( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5, _p6 ) \
do { \
if ( _chk_lvl( _lvl ) ) \
- { _printf( _hd _fmt _tl, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6), (_p7) ); } \
+ { _mbg_kdd_msg_6( _fmt, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6) ); } \
+} while ( 0 )
+
+#define _mbgddmsg_7( _lvl, _fmt, _p1, _p2, _p3, _p4, _p5, _p6, _p7 ) \
+do { \
+ if ( _chk_lvl( _lvl ) ) \
+ { _mbg_kdd_msg_7( _fmt, (_p1), (_p2), (_p3), (_p4), (_p5), (_p6), (_p7) ); } \
} while ( 0 )
#else
@@ -151,4 +246,30 @@ do {
#endif
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ __attribute__( ( format( printf, 1, 2 ) ) ) void mbg_kdd_msg( const char *fmt, ... ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+#undef _DO_INIT
+
#endif /* _MBGDDMSG_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.c b/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.c
index fb04f1d..a789add 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgdevio.c 1.35.1.25 2011/07/20 15:50:51 martin TRASH $
+ * $Id: mbgdevio.c 1.39 2017/07/05 15:02:47 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,60 +10,81 @@
*
* -----------------------------------------------------------------------
* $Log: mbgdevio.c $
- * Revision 1.35.1.25 2011/07/20 15:50:51 martin
+ * Revision 1.39 2017/07/05 15:02:47 martin
+ * Lots of new API functions provided by thomas-b, philipp, and martin.
+ * Fixed a potential buffer overflow in mbg_open_device_by_name().
+ * Fixed a bug where XYZ and LLA were not written properly
+ * under target systems not using a kernel driver.
+ * Proper return codes from thread functions.
+ * PCPS_DEV * parameter for mbg_setup_receiver_info may now be NULL.
+ * New set of functions to determine if a specific feature is supported.
+ * The functions are named mbg_chk_dev_...(), are combined in a group
+ * mbgdevio_chk_supp_fncs, and replace and deprecate a set of older
+ * functions named mbg_chk_dev_(), which are collected in a group
+ * mbgdevio_chk_supp_fncs_deprecated. The new functions are much easier
+ * to be handled, and return a single, distinct return code which clearly
+ * tells if a feature is not supported, or an error occurred while trying
+ * to find this out.
+ * Older defines N_SUPP_DEV, PCPS_MAX_DDEVS, and MBG_MAX_DEVICES
+ * have been obsoleted by new defines N_SUPP_DEV_BUS, N_SUPP_DEV_EXT,
+ * and N_SUPP_DEV_TOTAL.
+ * Defined many macros in a safer way, and replaced some macros
+ * by inline functions.
+ * Improved doxygen comments.
+ * Revision 1.38 2013/11/08 15:04:54 martin
+ * Fixes for big endian targets.
+ * Revision 1.37 2013/09/26 08:54:22 martin
+ * Support GNSS API.
+ * Support mbg_open_device_by_name() on Unix.
+ * Updated doxygen comments.
+ * Revision 1.36 2012/10/02 18:37:09Z martin
+ * There are some g++ versions which fail to compile source code using
+ * the macros provided by Linux to define IOCTL codes. If only the API
+ * functions are called by an application then the IOCTL codes aren't
+ * required anyway, so we just avoid inclusion of mbgioctl.h in
+ * general and but include it when this module is built.
+ * Updated doxygen comments.
+ * New functions mbg_get_all_irig_rx_info() and
+ * mbg_save_all_irig_rx_settings().
+ * Account for renamed macros.
+ * Support on-board event logs.
+ * New functions mbg_dev_has_debug_status() and
+ * mbg_get_debug_status().
+ * Added a workaround to make mbgmon (BC) build under Windows.
+ * In mbg_get_serial_settings() return an error if the number of provided
+ * serial ports or supported string types exceeds the numbers supported
+ * by the driver.
+ * Moved mbg_get_serial_settings() and mbg_save_serial_settings()
+ * to an extra file. These functions expect parameters the sizes of
+ * which might change in future API versions, which would make
+ * functions exported by shared libraries incompatible across versions.
+ * Made functions mbg_get_gps_all_port_info() and
+ * mbg_get_gps_all_str_type_info() non-static so they are now exported
+ * by the shared libraries built from this module.
+ * Include cfg_hlp.h.
* Conditionally use older IOCTL request buffer structures.
* Moved some macros etc. to the .h file.
- * Modified some macros.
- * Revision 1.35.1.24 2011/07/14 14:54:00 martin
* Modified generic IOCTL handling such that for calls requiring variable sizes
* a fixed request block containing input and output buffer pointers and sizes is
* passed down to the kernel driver. This simplifies implementation under *BSD
* and also works for other target systems.
- * Revision 1.35.1.23 2011/07/08 10:11:00 martin
- * Fixes for DOS.
- * Revision 1.35.1.22 2011/07/06 11:19:20Z martin
* Support reading CORR_INFO, and reading/writing TR_DISTANCE.
- * Revision 1.35.1.21 2011/06/29 11:09:55 martin
* Added mbg_dev_has_pzf() function.
- * Revision 1.35.1.20 2011/06/27 13:02:50 martin
- * Use O_RDWR flag when opening a device.
- * Revision 1.35.1.19 2011/06/24 11:13:36 martin
- * Revision 1.35.1.18 2011/06/22 10:05:45 martin
* Support PTP unicast configuration.
* Account for some IOCTL codes renamed to follow common naming conventions.
- * Revision 1.35.1.17 2011/04/12 12:56:20 martin
* Renamed mutex stuff to critical sections.
- * Revision 1.35.1.16 2011/03/31 13:18:46 martin
- * Coding style.
- * Revision 1.35.1.15 2011/02/16 10:15:13 martin
- * Revision 1.35.1.14 2011/02/15 14:24:55Z martin
- * Revision 1.35.1.13 2011/02/15 11:21:47 daniel
* Added API calls to support PTP unicast.
- * Revision 1.35.1.12 2011/02/09 17:08:28Z martin
* Specify I/O range number when calling port I/O macros
* so they can be used for different ranges under BSD.
- * Revision 1.35.1.11 2011/02/01 15:08:08 martin
- * Revision 1.35.1.10 2011/01/28 09:33:21 martin
* Modifications to support FreeBSD.
- * Revision 1.35.1.9 2010/12/14 11:23:47 martin
* Moved definition of MBG_HW_NAME to the header file.
- * Revision 1.35.1.8 2010/12/14 10:56:33Z martin
- * Revision 1.35.1.7 2010/08/18 13:43:20 martin
- * Revision 1.35.1.6 2010/08/11 13:48:52 martin
- * Cleaned up comments.
- * Revision 1.35.1.5 2010/08/11 12:43:51 martin
- * Revision 1.35.1.4 2010/05/21 13:10:37 martin
- * Fixed platforms where cycles are not supported.
- * Revision 1.35.1.3 2010/04/26 14:46:41 martin
* Compute PC cycles frequency under Linux if cpu_tick is not set by the kernel.
- * Revision 1.35.1.2 2010/02/09 14:05:38 stefan
- * Fixed a bug that kept the function mbg_open_device_by_name in a loop under certain conditions.
- * Revision 1.35.1.1 2010/02/05 11:49:26 martin
+ * Fixed a bug that kept the function mbg_open_device_by_name in a loop under certain conditions.
* Made xhrt leap second check an inline function.
* Revision 1.35 2010/01/12 13:40:25 martin
* Fixed a typo in mbg_dev_has_raw_irig_data().
* Revision 1.34 2009/12/15 15:34:58Z daniel
- * Support reading the raw IRIG data bits for firmware versions
+ * Support reading the raw IRIG data bits for firmware versions
* which support this feature.
* Revision 1.33 2009/09/29 15:08:40Z martin
* Support retrieving time discipline info.
@@ -75,7 +96,7 @@
* Revision 1.30 2009/06/19 12:19:41Z martin
* Support reading raw IRIG time.
* Revision 1.29 2009/06/08 18:23:22 daniel
- * Added PTP configuration functions and PTP state functions, but
+ * Added PTP configuration functions and PTP state functions, but
* they are still excluded from build.
* Added calls to support simple LAN interface configuration.
* Revision 1.28 2009/03/19 15:30:04 martin
@@ -91,30 +112,30 @@
* Account for renamed IOCTL codes.
* Revision 1.27 2008/12/17 10:37:37 martin
* Fixed a bug in mbg_open_device_by_name() with sel. mode MBG_MATCH_ANY.
- * Support variable read buffer sizes under Linux, so
+ * Support variable read buffer sizes under Linux, so
* mbg_get_all_port_info() and mbg_get_all_str_type_info()
* can now be used under Linux.
* Support PC cycles under Linux via inline rdtsc call.
* Use predefined constants to convert fractions.
- * New API calls mbg_get_fast_hr_timestamp_cycles(), and
+ * New API calls mbg_get_fast_hr_timestamp_cycles(), and
* mbg_get_fast_hr_timestamp_comp() which take memory mapped HR time stamps
- * in kernel space, and mbg_dev_has_fast_hr_timestamp() to check whether
+ * in kernel space, and mbg_dev_has_fast_hr_timestamp() to check whether
* this is supported by a device.
* Removed mm_*() functions since these are obsolete now.
- * Support extrapolated HR time (xhrt) for Windows and Linux
- * by providing a function mbg_xhrt_poll_thread_create() which
+ * Support extrapolated HR time (xhrt) for Windows and Linux
+ * by providing a function mbg_xhrt_poll_thread_create() which
* starts a poll thread for a specific device which to read
* HR time plus associated cycles in regular intervals.
* Added functions mbg_get_process_affinity(), mbg_set_process_affinity(),
- * and mbg_set_current_process_affinity_to_cpu(), and mbg_create_thread()
+ * and mbg_set_current_process_affinity_to_cpu(), and mbg_create_thread()
* and mbg_set_thread_affinity() to control the extrapolation feature.
* Use new preprocessor symbol MBGDEVIO_HAVE_THREAD_AFFINITY.
* Added new functions mbg_get_xhrt_time_as_pcps_hr_time() and
- * mbg_get_xhrt_time_as_filetime() (Windows only) to retrieve
+ * mbg_get_xhrt_time_as_filetime() (Windows only) to retrieve
* fast extrapolated timestamps.
- * Added function mbg_get_xhrt_cycles_frequency() to retrieve the
+ * Added function mbg_get_xhrt_cycles_frequency() to retrieve the
* cycles counter frequency computed by the polling thread.
- * Added function mbg_get_default_cycles_frequency_from_dev(),
+ * Added function mbg_get_default_cycles_frequency_from_dev(),
* and mbg_get_default_cycles_frequency() (Windows only).
* Moved mbg_open_device..() functions upwards.
* Made device_info_list common.
@@ -126,7 +147,7 @@
* Account Linux for device names renamed from /dev/mbgclk to /dev/mbgclock.
* Support bigendian target platforms.
* Revision 1.26 2008/02/26 16:54:21 martin
- * New/changed functions for memory mapped access which are
+ * New/changed functions for memory mapped access which are
* currently excluded from build.
* Changed separator for device names from ' ' to '_'.
* Added new type MBG_HW_NAME.
@@ -141,10 +162,10 @@
* Revision 1.23 2008/01/30 10:32:35Z daniel
* Renamed mapped memory funtions.
* Revision 1.22 2008/01/25 15:27:42Z daniel
- * Fixed a bug in mbg_get_hr_time_comp() where an overflow
+ * Fixed a bug in mbg_get_hr_time_comp() where an overflow
* of the fractions was handled with wrong sign.
* Revision 1.21 2008/01/17 15:49:59Z daniel
- * Added functions mbg_find_devices_with_hw_id() and
+ * Added functions mbg_find_devices_with_hw_id() and
* mbg_free_devics_list() to work with Linux Win32 OSs.
* Added Doxygen compliant comments for API functions.
* Support for mapped memory I/O under linux and windows.
@@ -181,27 +202,27 @@
* Unified macros for Win32 and Linux.
* Fixed warning under Win32 using type cast.
* Revision 1.15 2005/01/31 16:44:21Z martin
- * Added function mbg_get_hr_time_comp() which returns HR time stamp
+ * Added function mbg_get_hr_time_comp() which returns HR time stamp
* which has latency compensated.
* Revision 1.14 2005/01/14 10:22:23Z martin
* Added functions which query device features.
* Revision 1.13 2004/12/09 11:23:59Z martin
* Support configuration of on-board frequency synthesizer.
* Revision 1.12 2004/11/09 14:11:07Z martin
- * Modifications were required in order to be able to configure IRIG
+ * Modifications were required in order to be able to configure IRIG
* settings of cards which provide both IRIG input and output.
- * Renamed functions mbg_get_irig_info() and mbg_set_irig_settings()
- * to mbg_get_irig_rx_info() and mbg_set_irig_rx_settings()
+ * Renamed functions mbg_get_irig_info() and mbg_set_irig_settings()
+ * to mbg_get_irig_rx_info() and mbg_set_irig_rx_settings()
* New functions mbg_get_irig_tx_info() and mbg_set_irig_tx_settings().
* All API functions now use well defined parameter types instead of
* generic types. Some new types have been defined therefore.
* Added a workaround for GPS169PCI cards with early firmware versions
- * which used the same codes to configure the IRIG output as the TCR
- * cards use to configure the IRIG input. Those codes are now
+ * which used the same codes to configure the IRIG output as the TCR
+ * cards use to configure the IRIG input. Those codes are now
* exclusively used to configure the IRIG input. The workaround
- * has been included in order to let GPS169PCI cards work properly
+ * has been included in order to let GPS169PCI cards work properly
* after a driver update, without requiring a firmware update.
- * The macro _pcps_ddev_requires_irig_workaround() is used to check
+ * The macro _pcps_ddev_requires_irig_workaround() is used to check
* if the workaround is required.
* Renamed function mbg_get_gps_stat() to mbg_get_gps_bvar_stat().
* Revision 1.11 2004/08/17 11:13:45Z martin
@@ -224,7 +245,7 @@
* New functions mbgdevio_get_version() and mbgdevio_check_version().
* New functions for generic read/write access.
* New functions mbg_get_pcps_tzdl() and mbg_set_pcps_tzdl().
- * Fixed a bug passing the wrong command code to a
+ * Fixed a bug passing the wrong command code to a
* direct access target in mbg_get_sync_time().
* Return driver info for direct access targets.
* Include pcpsdrvr.h and pcps_dos.h, if applicable.
@@ -242,15 +263,15 @@
* Extended macro calls for direct access targets.
* Updated macros for Linux.
* Revision 1.5 2003/04/15 19:35:25Z martin
- * New functions mbg_setup_receiver_info(),
+ * New functions mbg_setup_receiver_info(),
* mbg_get_serial_settings(), mbg_save_serial_settings().
* Revision 1.4 2003/04/09 16:07:16Z martin
* New API functions mostly complete.
* Use renamed IOCTL codes from mbgioctl.h.
- * Added DllEntry function foe Win32.
+ * Added DllEntry function for Win32.
* Made MBG_Device_count and MBG_Device_Path local.
* Revision 1.3 2003/01/24 13:44:40Z martin
- * Fixed get_ref_time_from_driver_at_sec_change() to be used
+ * Fixed get_ref_time_from_driver_at_sec_change() to be used
* with old kernel drivers.
* Revision 1.2 2002/09/06 11:04:01Z martin
* Some old API functions have been replaced by new ones
@@ -266,20 +287,24 @@
#include <mbgdevio.h>
#undef _MBGDEVIO
-#include <parmpcps.h>
-#include <parmgps.h>
+#include <mbgutil.h>
#include <gpsutils.h>
#include <mbgerror.h>
+#include <cfg_hlp.h>
+#include <str_util.h>
#if defined( MBG_TGT_DOS_PM )
#include <mbg_dpmi.h>
#endif
-#if !defined( MBG_USE_KERNEL_DRIVER )
+#if defined( MBG_USE_KERNEL_DRIVER )
+
+ #include <mbgioctl.h>
+
+#else
#include <pcpsdrvr.h>
#include <pci_asic.h>
- #include <stdio.h>
static PCPS_DRVR_INFO drvr_info = { MBGDEVIO_VERSION, 0, "MBGDEVIO direct" };
@@ -287,18 +312,6 @@
-#define MAX_INFO_LEN 260
-
-typedef struct
-{
- MBG_HW_NAME hw_name;
- char model_name[PCPS_CLOCK_NAME_SZ];
- PCPS_SN_STR serial_number;
- char hardware_id[MAX_INFO_LEN]; // OS dependent hardware_id to identify and open the device
-} MBG_DEVICE_INFO;
-
-
-
// target specific code for different environments
#if defined( MBG_TGT_WIN32 )
@@ -306,20 +319,22 @@ typedef struct
#include <mbgsvctl.h>
#include <mbgnames.h>
#include <pci_asic.h>
- #include <mbgutil.h> //##++
+ #include <mbgutil.h>
#include <timecnv.h>
#include <pcpsutil.h>
#include <tchar.h>
#include <stdio.h>
-#elif defined( MBG_TGT_UNIX )
+#elif defined( MBG_TGT_POSIX ) && !defined( MBG_TGT_QNX_NTO )
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
- #include <stdio.h> // sprintf()
- #include <sys/mman.h>
+
+ #if defined( DEBUG )
+ #include <stdio.h> // printf() debug output
+ #endif
#else // other target OSs which access the hardware directly
@@ -343,12 +358,6 @@ typedef struct
#define _pcps_write_gps_var_safe _pcps_write_gps_var
#endif
- #define _mbgdevio_chk_cond( _cond ) \
- { \
- if ( !(_cond) ) \
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV ); \
- }
-
#endif // end of target specific code
@@ -371,122 +380,2771 @@ typedef struct
#define _mbgdevio_read_chk( _dh, _cmd, _ioctl, _p, _sz, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _do_mbgdevio_read( _dh, _cmd, _ioctl, _p, _sz ); \
-}
+} while ( 0 )
#define _mbgdevio_read_var_chk( _dh, _cmd, _ioctl, _p, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _mbgdevio_read_var( _dh, _cmd, _ioctl, _p ); \
-}
+} while ( 0 )
#define _mbgdevio_write_var_chk( _dh, _cmd, _ioctl, _p, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _mbgdevio_write_var( _dh, _cmd, _ioctl, _p ); \
-}
+} while ( 0 )
#define _mbgdevio_write_cmd_chk( _dh, _cmd, _ioctl, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _mbgdevio_write_cmd( _dh, _cmd, _ioctl ); \
-}
+} while ( 0 )
#define _mbgdevio_read_gps_chk( _dh, _cmd, _ioctl, _p, _sz, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _do_mbgdevio_read_gps( _dh, _cmd, _ioctl, _p, _sz ); \
-}
+} while ( 0 )
#define _mbgdevio_read_gps_var_chk( _dh, _cmd, _ioctl, _p, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _mbgdevio_read_gps_var( _dh, _cmd, _ioctl, _p ); \
-}
+} while ( 0 )
#define _mbgdevio_write_gps_var_chk( _dh, _cmd, _ioctl, _p, _cond ) \
+do \
{ \
_mbgdevio_chk_cond( _cond ); \
rc = _mbgdevio_write_gps_var( _dh, _cmd, _ioctl, _p ); \
-}
+} while ( 0 )
#if defined( _MBGIOCTL_H )
- #define _mbgdevio_query_cond( _dh, _cond, _ioctl, _p ) \
- { \
- _mbgdevio_vars(); \
- rc = _mbgdevio_read_var( _dh, -1, _ioctl, _p ); \
- return _mbgdevio_ret_val; \
- }
- #define _mbgdevio_query_ri_cond _mbgdevio_query_cond
+ #define _mbgdevio_old_query_cond( _dh, _cond, _ioctl, _p ) \
+ MBGDEVIO_RET_VAL rc; \
+ rc = _mbgdevio_read_var( _dh, -1, _ioctl, _p ); \
+ return _mbgdevio_cnv_ret_val( rc )
+
+ #define _mbgdevio_old_query_ri_cond _mbgdevio_old_query_cond
+
#else
- #define _mbgdevio_query_cond( _dh, _cond, _ioctl, _p ) \
- { \
- *p = _cond( _dh ); \
- return MBG_SUCCESS; \
+
+ #define _mbgdevio_old_query_cond( _dh, _cond, _ioctl, _p ) \
+ *p = _cond( _dh ); \
+ return MBG_SUCCESS
+
+ #define _mbgdevio_old_query_ri_cond( _dh, _cond, _ioctl, _p ) \
+ *p = _cond( _ri_addr( _dh ) ); \
+ return MBG_SUCCESS
+
+#endif
+
+
+
+#if defined( _MBGIOCTL_H )
+
+static
+int do_ioctl_chk_dev_feat( MBG_DEV_HANDLE dh, uint32_t feat_req_type, uint32_t feat_num )
+{
+ MBGDEVIO_RET_VAL rc;
+ IOCTL_DEV_FEAT_REQ req;
+ req.feat_req_type = feat_req_type;
+ req.feat_num = feat_num;
+ rc = _do_mbg_ioctl( dh, IOCTL_CHK_DEV_FEAT,
+ &req, sizeof( req ), 0 );
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // do_ioctl_chk_dev_feat
+
+#endif // defined( _MBGIOCTL_H )
+
+
+
+static __mbg_inline
+/**
+ * @brief Generic function to determine if a specific feature is supported
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] feat_type One of the defined ::DEV_FEAT_REQ_TYPES.
+ * @param[in] feat_num A feature number with range and meaning depending on the value of feat_type.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, see @ref mbgdevio_chk_supp_fncs
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see @ref mbgdevio_chk_supp_fncs
+ * @see ::mbgdevio_chk_dev_feat_deprecated (which is deprecated)
+ */
+int mbgdevio_chk_dev_feat( MBG_DEV_HANDLE dh, uint32_t feat_type, uint32_t feat_num )
+{
+ #if defined( _MBGIOCTL_H )
+
+ // Use an IOCTL call to retrieve the information
+ // from the kernel driver.
+ return do_ioctl_chk_dev_feat( dh, feat_type, feat_num );
+ #else
+ // This target doesn't use a kernel driver, so we retrieve
+ // the information directly from the device info structure.
+ return pcps_chk_dev_feat( dh, feat_type, feat_num );
+ #endif
+
+} // mbgdevio_chk_dev_feat
+
+
+
+static __mbg_inline
+/**
+ * @brief Deprecated generic function to determine if a specific feature is supported
+ *
+ * @deprecated This function is deprecated, use ::mbgdevio_chk_dev_feat preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] feat_type One of the defined ::DEV_FEAT_REQ_TYPES.
+ * @param[in] feat_num A feature number with range and meaning depending on the value of feat_type.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds, i.e ::MBG_SUCCESS is returned
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS if feature request could be executed without error
+ * and *p was updated accordingly, see @ref mbgdevio_chk_supp_fncs_deprecated
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see @ref mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbgdevio_chk_dev_feat which should be used preferably
+ */
+int mbgdevio_chk_dev_feat_deprecated( MBG_DEV_HANDLE dh, uint32_t feat_type, uint32_t feat_num, int *p )
+{
+ // Emulate the behavior of old feature-check functions.
+ int rc = mbgdevio_chk_dev_feat( dh, feat_type, feat_num );
+
+ // If we could definitely determine if the requested feature
+ // is supported or not then we accordingly update the integer
+ // variable the address of which has been passed by the caller,
+ // and return MBG_SUCCESS since we could determine the information
+ // successfully.
+ if ( mbg_rc_is_success( rc ) || ( rc == MBG_ERR_NOT_SUPP_BY_DEV ) )
+ {
+ *p = mbg_rc_is_success( rc );
+ return MBG_SUCCESS;
}
- #define _mbgdevio_query_ri_cond( _dh, _cond, _ioctl, _p ) \
- { \
- *p = _cond( &(_dh)->ri ); \
- return MBG_SUCCESS; \
+ // If we get here then there was some error when we tried to
+ // determine the requested information, e.g. an IOCTL error
+ // when accessing the kernel driver, so we return the associated
+ // error code.
+ return rc;
+
+} // mbgdevio_chk_dev_feat_deprecated
+
+
+
+#if defined( _MBGIOCTL_H )
+
+ #define _mbgdevio_new_query_condx( _dh, _cond, _ioctl ) \
+ { \
+ MBGDEVIO_RET_VAL rc; \
+ int _flag = 0; \
+ rc = _mbgdevio_read_var( _dh, -1, _ioctl, &_flag ); \
+ \
+ if ( rc == MBG_SUCCESS ) /* no IOCTL error */ \
+ if ( _flag == 0 ) /* if returned value is 0 */ \
+ rc = MBG_ERR_NOT_SUPP_BY_DEV; /* not supp. */ \
+ \
+ /* success or IOCTL error */ \
+ return _mbgdevio_cnv_ret_val( rc ); \
}
+
+#else
+
+ #define _mbgdevio_new_query_condx( _dh, _cond, _ioctl ) \
+ return _cond( _dh ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV
+
#endif
+// ### FIXME
+#define _mbgdevio_new_query_cond _mbgdevio_new_query_condx
+
+
static MBG_PC_CYCLES_FREQUENCY pc_cycles_frequency;
-static MBG_DEVICE_INFO device_info_list[MBG_MAX_DEVICES];
-#if defined( MBG_TGT_WIN32 )
+/*HDR*/
+/**
+ * @brief Get the version number of the precompiled DLL/shared object library
+ *
+ * If this library is used as a DLL/shared object library then the version
+ * number can be checked to see if the header files which are actually used
+ * to build an application are compatible with the header files which have
+ * been used to build the library, and thus the API function are called
+ * in the correct way.
+ *
+ * @return The version number
+ *
+ * @see ::mbgdevio_check_version
+ * @see ::MBGDEVIO_VERSION defined in mbgdevio.h
+ */
+_MBG_API_ATTR int _MBG_API mbgdevio_get_version( void )
+{
+ return MBGDEVIO_VERSION;
+
+} // mbgdevio_get_version
+
-// We don't move this as inline function to mbgdevio.h for now
-// since this function calls mbgsvctl_log_mbgdevio_error() which
-// is defined in mbgsvctl.h, and including mbgsvc.h from within
-// mbgdevio.h results in DLL import/export mismatches.
/*HDR*/
-MBGDEVIO_RET_VAL do_mbg_ioctl( MBG_DEV_HANDLE dh, int ioctl_code,
- const void *in_p, int in_sz, void *out_p, int out_sz )
+/**
+ * @brief Check if the DLL/shared library is compatible with a given version
+ *
+ * If this library is used as a DLL/shared object library then the version
+ * number can be checked to see if the header files which are actually used
+ * to build an application are compatible with the header files which have
+ * been used to build the library, and thus the API functions are called
+ * in the correct way.
+ *
+ * @param[in] header_version Version number to be checked, should be ::MBGDEVIO_VERSION
+ * from the mbgdevio.h file version used to build the application
+ *
+ * @return ::MBG_SUCCESS if compatible, else ::MBG_ERR_LIB_NOT_COMPATIBLE
+ *
+ * @see ::mbgdevio_get_version
+ * @see ::MBGDEVIO_VERSION defined in mbgdevio.h
+ */
+_MBG_API_ATTR int _MBG_API mbgdevio_check_version( int header_version )
{
- DWORD ReturnedLength;
+ if ( header_version >= MBGDEVIO_COMPAT_VERSION )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_LIB_NOT_COMPATIBLE;
+
+} // mbgdevio_check_version
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::RECEIVER_INFO structure and related calls.
+ *
+ * Very old devices may not provide a ::RECEIVER_INFO structure.
+ * The ::mbg_setup_receiver_info call should be used preferably to set up
+ * a ::RECEIVER_INFO for a device. That function uses this call to determine
+ * whether a ::RECEIVER_INFO can be read directly from a device, or sets up
+ * a default structure using default values depending on the device type.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_receiver_info,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_get_gps_receiver_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_receiver_info( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_RECEIVER_INFO );
+
+} // mbg_chk_dev_has_receiver_info
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_receiver_info;
- if ( !DeviceIoControl( dh, ioctl_code,
- (LPVOID) in_p, in_sz, out_p, out_sz,
- &ReturnedLength,
- NULL
- ) )
- {
- DWORD rc = GetLastError();
- // do not report a USB device timeout error
- if ( rc != _mbg_err_to_os( MBG_ERR_USB_ACCESS ) )
- mbgsvctl_log_mbgdevio_error( ioctl_code, rc );
+/*HDR*/
+/**
+ * @brief Check if a device supports large configuration data structures.
+ *
+ * Such structures have been introduced with the first Meinberg GPS receivers.
+ * Mostly all configuration structures are large data structures, and mostly all
+ * current devices support this, but some old devices may not.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_gps_data,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_gps_data( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_GPS_DATA_16 );
+
+} // mbg_chk_dev_has_gps_data
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_gps_data;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_generic_io API call.
+ *
+ * <b>Warning</b>: This call is for debugging purposes and internal use only!
+ *
+ * @note This function should be preferred over ::mbg_dev_has_generic_io,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_generic_io
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_generic_io( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_GENERIC_IO );
+
+} // mbg_chk_dev_has_generic_io
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_generic_io;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_asic_version API call.
+ *
+ * If ::mbg_get_asic_version is supported, or not, depends on
+ * the bus interface chip assembled on the device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_asic_version,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_asic_version
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_asic_version( MBG_DEV_HANDLE dh )
+{
+ // TODO return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, ... );
+ _mbgdevio_new_query_condx( dh, _pcps_ddev_has_asic_version, IOCTL_DEV_HAS_PCI_ASIC_VERSION );
+
+} // mbg_chk_dev_has_asic_version
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_asic_version;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_asic_features call.
+ *
+ * If ::mbg_get_asic_features is supported, or not, depends on
+ * the bus interface chip assembled on the device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_asic_features,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_asic_features
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_asic_features( MBG_DEV_HANDLE dh )
+{
+ // TODO return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, ... );
+ _mbgdevio_new_query_condx( dh, _pcps_ddev_has_asic_features, IOCTL_DEV_HAS_PCI_ASIC_FEATURES );
+
+} // mbg_chk_dev_has_asic_features
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_asic_features;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides eXtended Multi Ref (XMR) inputs.
+ *
+ * Devices providing XMR inputs can receive or decode different timing
+ * signals in parallel, and the supported sources can be prioritized.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_xmr,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_xmr( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_RI, GPS_HAS_XMULTI_REF );
+
+} // mbg_chk_dev_has_xmr
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_xmr;
+
+
+
+static /*HDR*/
+/**
+ * @brief Check if device is a specific bus type
+ *
+ * This function checks if the bus flags associated with
+ * the device match the requested flags. This can be used e.g.
+ * to distinguish if a device is a PCI or USB device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] bus_flag_mask The bus flags to be tested, see @ref PCPS_BUS_FLAG_MASKS
+ *
+ * @return ::MBG_SUCCESS if the bus flags match, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @see @ref PCPS_BUS_FLAG_MASKS
+ */
+int chk_bus_flags( MBG_DEV_HANDLE dh, int bus_flag_mask )
+{
+ PCPS_DEV dev_info;
+
+ int rc = mbg_get_device_info( dh, &dev_info );
+
+ if ( mbg_rc_is_error( rc ) )
return rc;
- }
- return MBG_SUCCESS;
+ return ( dev_info.type.bus_flags & bus_flag_mask ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // chk_bus_flags
+
+
+
+/*HDR*/
+/**
+ * @brief Check if the device is connected via the ISA bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the ISA bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_isa( MBG_DEV_HANDLE dh )
+{
+ return chk_bus_flags( dh, PCPS_BUS_ISA );
+
+} // mbg_chk_dev_is_isa
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_isa;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if the device is connected via the MCA bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the MCA bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_mca( MBG_DEV_HANDLE dh )
+{
+ return chk_bus_flags( dh, PCPS_BUS_MCA );
+
+} // mbg_chk_dev_is_mca
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_mca;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if the device is connected via the PCI bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the PCI bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_pci( MBG_DEV_HANDLE dh )
+{
+ return chk_bus_flags( dh, PCPS_BUS_PCI );
+} // mbg_chk_dev_is_pci
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_pci;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if the device is connected via the PCI Express bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the PCI Express bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_pci_express( MBG_DEV_HANDLE dh )
+{
+ PCPS_DEV dev_info;
+
+ int rc = mbg_get_device_info( dh, &dev_info );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+ // TODO Move this to the kernel driver
+ if ( ( dev_info.type.bus_flags == PCPS_BUS_PCI_MBGPEX ) ||
+ ( dev_info.type.bus_flags == PCPS_BUS_PCI_PEX8311 ) )
+ return MBG_SUCCESS;
+
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+} // mbg_chk_dev_is_pci_express
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_pci_express;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if the device is connected via the USB bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the USB bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_usb( MBG_DEV_HANDLE dh )
+{
+ return chk_bus_flags( dh, PCPS_BUS_USB );
+
+} // mbg_chk_dev_is_usb
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_usb;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports GNSS configuration
+ *
+ * This is usually the case if a device supports reception of
+ * different satellite systems, e.g. GPS, Glonass, Galileo, etc.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_gnss,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_gnss( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_IS_GNSS );
+
+} // mbg_chk_dev_is_gnss
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_gnss;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a GPS receiver
+ *
+ * The function also returns ::MBG_SUCCESS for GNSS receivers
+ * which can track GPS satellites beside other GNSS systems.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_gps,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_gps( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_GPS );
+
+} // mbg_chk_dev_is_gps
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_gps;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a DCF77 receiver.
+ *
+ * Beside standard DCF77 receivers which receive the legacy AM signal
+ * there are also PZF receivers which can decode the pseudo-random phase
+ * modulation and thus yield a higher accuracy. See ::mbg_chk_dev_has_pzf.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_dcf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_dcf( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_DCF );
+
+} // mbg_chk_dev_is_dcf
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_dcf;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports demodulation of the DCF77 PZF code
+ *
+ * Beside the enhanced PZF correlation receivers which decode the DCF77's
+ * pseudo-random phase modulation to yield a better accuracy there are also
+ * legacy DCF77 receivers which just decode the standard AM signal.
+ * See ::mbg_chk_dev_is_dcf.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_pzf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_corr_info
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_chk_dev_is_dcf
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_pzf( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_condx( dh, _pcps_ddev_has_pzf, IOCTL_DEV_HAS_PZF );
+
+} // mbg_chk_dev_has_pzf
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_pzf;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a MSF receiver
+ *
+ * @note This function should be preferred over ::mbg_dev_is_msf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_msf( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_MSF );
+
+} // mbg_chk_dev_is_msf
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_msf;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a WWVB receiver
+ *
+ * @note This function should be preferred over ::mbg_dev_is_wwvb,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_wwvb( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_WWVB );
+
+} // _pcps_ddev_is_wwvb
+
+MBG_CHK_SUPP_FNC _pcps_ddev_is_wwvb;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a JJY receiver.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_jjy( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_JJY );
+
+} // _pcps_ddev_is_jjy
+
+MBG_CHK_SUPP_FNC _pcps_ddev_is_jjy;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is any long wave signal receiver
+ *
+ * Long wave receivers include e.g. DCF77, MSF, WWVB, or JJY.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_lwr,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_dcf
+ * @see ::mbg_chk_dev_is_msf
+ * @see ::mbg_chk_dev_is_wwvb
+ * @see ::mbg_chk_dev_is_jjy
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_lwr( MBG_DEV_HANDLE dh )
+{
+ // TODO Combine to single call
+ return mbg_rc_is_success( mbg_chk_dev_is_dcf( dh ) ) ||
+ mbg_rc_is_success( mbg_chk_dev_is_msf( dh ) ) ||
+ mbg_rc_is_success( mbg_chk_dev_is_wwvb( dh ) ) ||
+ mbg_rc_is_success( mbg_chk_dev_is_jjy( dh ) );
+
+} // mbg_chk_dev_is_lwr
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_lwr;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable IRIG input.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_irig_rx,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_has_irig
+*/
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_is_tcr( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_REF_TYPE, PCPS_REF_IRIG );
+
+} // mbg_chk_dev_is_tcr
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_is_tcr;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports simple LAN interface API calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_lan_intf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_lan_intf( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_LAN_INTF );
+
+} // mbg_chk_dev_has_lan_intf
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_lan_intf;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports PTP configuration/status calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ptp,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ptp( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_PTP );
+
+} // mbg_chk_dev_has_ptp
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_ptp;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports PTP unicast feature/configuration
+ *
+ * Not all devices which support PTP do also support PTP Unicast. This API
+ * call checks if PTP Unicast is supported in addition to the standard
+ * PTP multicast.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ptp_unicast,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ptp_unicast( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_RI, GPS_HAS_PTP_UNICAST );
+
+} // mbg_chk_dev_has_ptp_unicast
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_ptp_unicast;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the mbg_get_hr_time... functions
+ *
+ * @note This function should be preferred over ::mbg_dev_has_hr_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_hr_time( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_HR_TIME );
+
+} // mbg_chk_dev_has_hr_time
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_hr_time;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the mbg_get_fast_hr_timestamp... calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_fast_hr_timestamp,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_FAST_HR_TSTAMP );
+
+} // mbg_chk_dev_has_fast_hr_timestamp
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_fast_hr_timestamp;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configurable time scales.
+ *
+ * By default the devices return %UTC and/or local time. However, some cards
+ * can be configured to return raw GPS time or TAI instead.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_time_scale,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_time_scale_info
+ * @see ::mbg_set_time_scale_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_time_scale( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_time_scale, IOCTL_DEV_HAS_GPS_TIME_SCALE );
+
+} // mbg_chk_dev_has_time_scale
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_time_scale;
+
+
+
+/*HDR*/
+/* (Intentionally excluded from Doxygen)
+ * @brief Check if a device supports setting an event time
+ *
+ * This feature is only supported by some special custom firmware
+ * to preset a %UTC time at which the clock is to generate an output signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_event_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_set_event_time
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_event_time( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_event_time, IOCTL_DEV_HAS_EVENT_TIME );
+
+} // mbg_chk_dev_has_event_time
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_event_time;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_ucap_entries and ::mbg_get_ucap_event calls
+ *
+ * If the device doesn't support this but 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.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ucap,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @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_chk_dev_has_ucap( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_ucap, IOCTL_DEV_HAS_UCAP );
+
+} // mbg_chk_dev_has_ucap
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_ucap;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_clr_ucap_buff call
+ *
+ * The ::mbg_clr_ucap_buff call can be used to clear a device's on-board
+ * time capture FIFO buffer, but the call may not be supported by some
+ * older GPS devices.
+ *
+ * @note This function should be preferred over ::mbg_dev_can_clr_ucap_buff,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_clr_ucap_buff
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_can_clr_ucap_buff( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_can_clr_ucap_buff, IOCTL_DEV_CAN_CLR_UCAP_BUFF );
+
+} // mbg_chk_dev_can_clr_ucap_buff
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_can_clr_ucap_buff;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::TZDL structure
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tzdl,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_tzdl
+ * @see ::mbg_set_gps_tzdl
+ * @see ::mbg_chk_dev_has_tz
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tzdl( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_tzdl, IOCTL_DEV_HAS_TZDL );
+
+} // mbg_chk_dev_has_tzdl
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_tzdl;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZDL structure
+ *
+ * @note This function should be preferred over ::mbg_dev_has_pcps_tzdl,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_chk_dev_has_tz
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_pcps_tzdl( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_pcps_tzdl, IOCTL_DEV_HAS_PCPS_TZDL );
+
+} // mbg_chk_dev_has_pcps_tzdl
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_pcps_tzdl;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZCODE type.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tzcode,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_chk_dev_has_tz
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tzcode( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_tzcode, IOCTL_DEV_HAS_TZCODE );
+
+} // mbg_chk_dev_has_tzcode
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_tzcode;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports any kind of timezone configuration.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tz,
+ * which has been deprecated.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_tzdl
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_chk_dev_has_tzcode
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tz( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_tz, IOCTL_DEV_HAS_TZ );
+
+} // mbg_chk_dev_has_tz
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_tz;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides either an IRIG input or output.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_irig, IOCTL_DEV_HAS_IRIG );
+
+} // mbg_chk_dev_has_irig
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_irig;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable IRIG output.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_tx_info
+ * @see ::mbg_set_irig_tx_settings
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig
+ * @see @ref group_icode
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_tx( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_irig_tx, IOCTL_DEV_HAS_IRIG_TX );
+
+} // mbg_chk_dev_has_irig_tx
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_irig_tx;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_irig_ctrl_bits call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig_ctrl_bits,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_ctrl_bits
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_irig_ctrl_bits, IOCTL_DEV_HAS_IRIG_CTRL_BITS );
+
+} // mbg_chk_dev_has_irig_ctrl_bits
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_irig_ctrl_bits;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_raw_irig_data call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_raw_irig_data,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_raw_irig_data
+ * @see ::mbg_get_raw_irig_data_on_sec_change
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_raw_irig_data( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_RAW_IRIG_DATA );
+
+} // mbg_chk_dev_has_raw_irig_data
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_raw_irig_data;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_irig_time call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_time
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_time( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_irig_time, IOCTL_DEV_HAS_IRIG_TIME );
+
+} // mbg_chk_dev_has_irig_time
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_irig_time;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides the level of its inputs signal
+ *
+ * This is useful to display the signal level of e.g. an IRIG or similar
+ * time code, or a long wave signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_signal,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_signal( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_signal, IOCTL_DEV_HAS_SIGNAL );
+
+} // mbg_chk_dev_has_signal
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_signal;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a modulation signal
+ *
+ * Modulation signals are e.g. the second marks provided by a long wave receiver.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_mod,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_mod( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_mod, IOCTL_DEV_HAS_MOD );
+
+} // mbg_chk_dev_has_mod
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_mod;
+
+
+
+/*HDR*/
+/* (Intentionally excluded from Doxygen)
+ * @brief Check if a device supports higher baud rates than usual
+ *
+ * Check if a device provides a serial output that supports
+ * higher baud rates than older cards, i.e. ::DEFAULT_BAUD_RATES_DCF_HS
+ * rather than ::DEFAULT_BAUD_RATES_DCF.
+ *
+ * The call ::mbg_get_serial_settings takes care of this, so applications
+ * which use that call as suggested don't need to use this call directly.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_serial_hs,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_serial_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_serial_hs( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_serial_hs, IOCTL_DEV_HAS_SERIAL_HS );
+
+} // mbg_chk_dev_has_serial_hs
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_serial_hs;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a programmable frequency synthesizer
+ *
+ * @note This function should be preferred over ::mbg_dev_has_synth,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_synth
+ * @see ::mbg_set_synth
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_synth( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_synth, IOCTL_DEV_HAS_SYNTH );
+
+} // mbg_chk_dev_has_synth
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_synth;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides GPIO signal inputs and/or outputs
+ *
+ * @note This function should be preferred over ::mbg_dev_has_gpio,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_gpio( MBG_DEV_HANDLE dh )
+{
+ return mbgdevio_chk_dev_feat( dh, DEV_FEAT_REQ_TYPE_RI, GPS_HAS_GPIO );
+
+} // mbg_chk_dev_has_gpio
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_gpio;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configuration of antenna cable length
+ *
+ * @note This function should be preferred over ::mbg_dev_has_cab_len,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_ant_cable_len
+ * @see ::mbg_set_gps_ant_cable_len
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_cab_len( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_cab_len, IOCTL_DEV_HAS_CAB_LEN );
+
+} // mbg_chk_dev_has_cab_len
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_cab_len;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable ref time offset
+ *
+ * This may be required to convert the received time to %UTC, if the input
+ * signal doesn't specify this (e.g. with most IRIG code formats).
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ref_offs,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_ref_offs
+ * @see ::mbg_set_ref_offs
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ref_offs( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_ref_offs, IOCTL_DEV_HAS_REF_OFFS );
+
+} // mbg_chk_dev_has_ref_offs
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_ref_offs;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::MBG_OPT_INFO/::MBG_OPT_SETTINGS.
+ *
+ * These structures contain optional settings, controlled by flags.
+ * See ::MBG_OPT_SETTINGS and associated definitions.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_opt_flags,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_opt_info
+ * @see ::mbg_set_opt_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_opt_flags( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_opt_flags, IOCTL_DEV_HAS_OPT_FLAGS );
+
+} // mbg_chk_dev_has_opt_flags
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_opt_flags;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device support reading/writing of UTC parameters.
+ *
+ * This API call checks if a device supports reading/writing a GPS %UTC
+ * parameter set via the PC bus. Reading/writing these parameters via the
+ * serial port using the Meinberg binary data protocol is supported by all
+ * Meinberg GPS and GNSS devices.
+ *
+ * The %UTC parameter set is usually received from the satellites' broadcasts
+ * and contains the current time offset between GPS time and UTC, plus information
+ * on a pending leap second event.
+ *
+ * It may be useful to overwrite them to do some tests, or for applications
+ * where a card is freewheeling.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_utc_parm,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_utc_parm
+ * @see ::mbg_set_utc_parm
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_utc_parm( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_utc_parm, IOCTL_DEV_HAS_GPS_UTC_PARM );
+
+} // mbg_chk_dev_has_utc_parm
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_utc_parm;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports reading correlation info
+ *
+ * The PZF phase modulation decoded by DCF77 PZF receivers is decoded
+ * using a correlation approach, and optionally there's an API call
+ * supported which can be used to retrieve the correlation value
+ * and thus determine the quality of the input signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_corr_info,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_get_corr_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_corr_info( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_corr_info, IOCTL_DEV_HAS_CORR_INFO );
+
+} // mbg_chk_dev_has_corr_info
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_corr_info;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configurable distance from transmitter
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tr_distance,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_get_tr_distance
+ * @see ::mbg_set_tr_distance
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tr_distance( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_tr_distance, IOCTL_DEV_HAS_TR_DISTANCE );
+
+} // mbg_chk_dev_has_tr_distance
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_tr_distance;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a debug status word to be read
+ *
+ * @note This function should be preferred over ::mbg_dev_has_debug_status,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_debug_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_debug_status( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_debug_status, IOCTL_DEV_HAS_DEBUG_STATUS );
+
+} // mbg_chk_dev_has_debug_status
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_debug_status;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides an on-board event log
+ *
+ * @note This function should be preferred over ::mbg_dev_has_evt_log,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+_MBG_API_ATTR int _MBG_API mbg_chk_dev_has_evt_log( MBG_DEV_HANDLE dh )
+{
+ _mbgdevio_new_query_cond( dh, _pcps_ddev_has_evt_log, IOCTL_DEV_HAS_EVT_LOG );
+
+} // mbg_chk_dev_has_evt_log
+
+MBG_CHK_SUPP_FNC mbg_chk_dev_has_evt_log;
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::RECEIVER_INFO structure and related calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_receiver_info preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_receiver_info
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_receiver_info" ) _MBG_API mbg_dev_has_receiver_info( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_receiver_info, IOCTL_DEV_HAS_RECEIVER_INFO, p );
+
+} // mbg_dev_has_receiver_info
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports large configuration data structures
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_gps_data preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_gps_data
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_gps_data" ) _MBG_API mbg_dev_has_gps_data( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_gps_data, IOCTL_DEV_HAS_GPS_DATA, p );
+
+} // mbg_dev_has_gps_data
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_generic_io API call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_generic_io preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_generic_io
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_generic_io" ) _MBG_API mbg_dev_has_generic_io( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_generic_io, IOCTL_DEV_HAS_GENERIC_IO, p );
+
+} // mbg_dev_has_generic_io
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_asic_version call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_asic_version preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_asic_version
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_asic_version" ) _MBG_API mbg_dev_has_asic_version( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_asic_version, IOCTL_DEV_HAS_PCI_ASIC_VERSION, p );
+
+} // mbg_dev_has_asic_version
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_asic_features call.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_asic_features preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_asic_features
+ * @see ::mbg_get_asic_features
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_asic_features" ) _MBG_API mbg_dev_has_asic_features( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_asic_features, IOCTL_DEV_HAS_PCI_ASIC_FEATURES, p );
+
+} // mbg_dev_has_asic_features
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides extended multi ref (XMR) inputs.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_xmr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_xmr
+ * @see @ref group_multi_ref_ext
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_xmr" ) _MBG_API mbg_dev_has_xmr( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_ri_cond( dh, _pcps_has_ri_xmr, IOCTL_DEV_HAS_XMR, p );
+
+} // mbg_dev_has_xmr
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports GNSS configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_gnss preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_gnss
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_gnss" ) _MBG_API mbg_dev_is_gnss( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_gnss, IOCTL_DEV_IS_GNSS, p );
+
+} // mbg_dev_is_gnss
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a GPS receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_gps preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_gps
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_gps" ) _MBG_API mbg_dev_is_gps( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_gps, IOCTL_DEV_IS_GPS, p );
+
+} // mbg_dev_is_gps
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a DCF77 receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_dcf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_dcf
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_dcf" ) _MBG_API mbg_dev_is_dcf( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_dcf, IOCTL_DEV_IS_DCF, p );
+
+} // mbg_dev_is_dcf
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports demodulation of the DCF77 PZF code
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_pzf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_pzf
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_pzf" ) _MBG_API mbg_dev_has_pzf( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_pzf, IOCTL_DEV_HAS_PZF, p );
+
+} // mbg_dev_has_pzf
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a MSF receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_msf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_msf
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_msf" ) _MBG_API mbg_dev_is_msf( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_msf, IOCTL_DEV_IS_MSF, p );
+
+} // mbg_dev_is_msf
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is a WWVB receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_wwvb preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_wwvb
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_wwvb" ) _MBG_API mbg_dev_is_wwvb( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_wwvb, IOCTL_DEV_IS_WWVB, p );
+
+} // mbg_dev_is_wwvb
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device is any long wave signal receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_lwr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_lwr
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_lwr" ) _MBG_API mbg_dev_is_lwr( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_lwr, IOCTL_DEV_IS_LWR, p );
+
+} // mbg_dev_is_lwr
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable IRIG input.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_tcr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_tcr
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_tcr" ) _MBG_API mbg_dev_is_irig_rx( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_is_irig_rx, IOCTL_DEV_IS_IRIG_RX, p );
+
+} // mbg_dev_is_irig_rx
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports simple LAN interface API calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_lan_intf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_lan_intf
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_lan_intf" ) _MBG_API mbg_dev_has_lan_intf( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_lan_intf, IOCTL_DEV_HAS_LAN_INTF, p );
+
+} // mbg_dev_has_lan_intf
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports PTP configuration/status calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ptp preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ptp
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ptp" ) _MBG_API mbg_dev_has_ptp( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_ptp, IOCTL_DEV_HAS_PTP, p );
+
+} // mbg_dev_has_ptp
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports PTP unicast feature/configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ptp_unicast preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ptp_unicast" ) _MBG_API mbg_dev_has_ptp_unicast( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_ri_cond( dh, _pcps_has_ri_ptp_unicast, IOCTL_DEV_HAS_PTP_UNICAST, p );
+
+} // mbg_dev_has_ptp_unicast
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the HR_TIME functions
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_hr_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_hr_time
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_hr_time" ) _MBG_API mbg_dev_has_hr_time( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_hr_time, IOCTL_DEV_HAS_HR_TIME, p );
+
+} // mbg_dev_has_hr_time
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the mbg_get_fast_hr_timestamp_...() calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_fast_hr_timestamp preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_fast_hr_timestamp" ) _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int *p )
+{
+ return mbgdevio_chk_dev_feat_deprecated( dh, DEV_FEAT_REQ_TYPE_PCPS, PCPS_BIT_HAS_FAST_HR_TSTAMP, p );
+
+} // mbg_dev_has_fast_hr_timestamp
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configurable time scales
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_time_scale preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_time_scale
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_time_scale" ) _MBG_API mbg_dev_has_time_scale( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_time_scale, IOCTL_DEV_HAS_GPS_TIME_SCALE, p );
+
+} // mbg_dev_has_time_scale
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports setting an event time
+ *
+ * @note This is only supported by some customized devices
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_event_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_event_time
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_event_time" ) _MBG_API mbg_dev_has_event_time( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_event_time, IOCTL_DEV_HAS_EVENT_TIME, p );
+
+} // mbg_dev_has_event_time
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_ucap_entries and ::mbg_get_ucap_event calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ucap preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ucap
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ucap" ) _MBG_API mbg_dev_has_ucap( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_ucap, IOCTL_DEV_HAS_UCAP, p );
+
+} // mbg_dev_has_ucap
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_clr_ucap_buff call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_can_clr_ucap_buff preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_can_clr_ucap_buff
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_can_clr_ucap_buff" ) _MBG_API mbg_dev_can_clr_ucap_buff( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_can_clr_ucap_buff, IOCTL_DEV_CAN_CLR_UCAP_BUFF, p );
+
+} // mbg_dev_can_clr_ucap_buff
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::TZDL structure
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tzdl preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tzdl
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tzdl" ) _MBG_API mbg_dev_has_tzdl( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_tzdl, IOCTL_DEV_HAS_TZDL, p );
+
+} // mbg_dev_has_tzdl
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZDL structure
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_pcps_tzdl preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_pcps_tzdl" ) _MBG_API mbg_dev_has_pcps_tzdl( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_pcps_tzdl, IOCTL_DEV_HAS_PCPS_TZDL, p );
+
+} // mbg_dev_has_pcps_tzdl
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZCODE type
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tzcode preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tzcode
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tzcode" ) _MBG_API mbg_dev_has_tzcode( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_tzcode, IOCTL_DEV_HAS_TZCODE, p );
+
+} // mbg_dev_has_tzcode
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports any kind of timezone configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tz preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tz
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tz" ) _MBG_API mbg_dev_has_tz( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_tz, IOCTL_DEV_HAS_TZ, p );
+
+} // mbg_dev_has_tz
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides either an IRIG input or output
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig" ) _MBG_API mbg_dev_has_irig( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_irig, IOCTL_DEV_HAS_IRIG, p );
+
+} // mbg_dev_has_irig
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable IRIG output
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_tx preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_tx
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_tx" ) _MBG_API mbg_dev_has_irig_tx( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_irig_tx, IOCTL_DEV_HAS_IRIG_TX, p );
+
+} // mbg_dev_has_irig_tx
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_irig_ctrl_bits call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_ctrl_bits preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_ctrl_bits
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_ctrl_bits" ) _MBG_API mbg_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_irig_ctrl_bits, IOCTL_DEV_HAS_IRIG_CTRL_BITS, p );
+
+} // mbg_dev_has_irig_ctrl_bits
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_raw_irig_data call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_raw_irig_data preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_raw_irig_data" ) _MBG_API mbg_dev_has_raw_irig_data( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_raw_irig_data, IOCTL_DEV_HAS_RAW_IRIG_DATA, p );
+
+} // mbg_dev_has_raw_irig_data
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::mbg_get_irig_time call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_time
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_time" ) _MBG_API mbg_dev_has_irig_time( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_irig_time, IOCTL_DEV_HAS_IRIG_TIME, p );
+
+} // mbg_dev_has_irig_time
-} // do_mbg_ioctl
-#endif // defined( MBG_TGT_WIN32 )
+/*HDR*/
+/**
+ * @brief Check if a device provides the level of its inputs signal
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_signal preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_signal
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_signal" ) _MBG_API mbg_dev_has_signal( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_signal, IOCTL_DEV_HAS_SIGNAL, p );
+
+} // mbg_dev_has_signal
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a modulation signal
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_mod preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_mod
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_mod" ) _MBG_API mbg_dev_has_mod( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_mod, IOCTL_DEV_HAS_MOD, p );
+
+} // mbg_dev_has_mod
+
+
+
+/*HDR*/
+/* (Intentionally excluded from Doxygen)
+ * @brief Check if a device supports higher baud rates than usual
+ *
+ * Check if a device provides a serial output that supports
+ * higher baud rates than older cards, i.e. ::DEFAULT_BAUD_RATES_DCF_HS
+ * rather than ::DEFAULT_BAUD_RATES_DCF.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_serial_hs preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_serial_hs
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_serial_hs" ) _MBG_API mbg_dev_has_serial_hs( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_serial_hs, IOCTL_DEV_HAS_SERIAL_HS, p );
+
+} // mbg_dev_has_serial_hs
-static /*HDR*/ //##++ make this public ?
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a programmable frequency synthesizer
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_synth preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_synth
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_synth" ) _MBG_API mbg_dev_has_synth( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_synth, IOCTL_DEV_HAS_SYNTH, p );
+
+} // mbg_dev_has_synth
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides GPIO signal inputs and/or outputs
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_gpio preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_gpio
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_gpio" ) _MBG_API mbg_dev_has_gpio( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_ri_cond( dh, _pcps_has_ri_gpio, IOCTL_DEV_HAS_GPIO, p );
+
+} // mbg_dev_has_gpio
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configuration of antenna cable length
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_cab_len preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_cab_len
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_cab_len" ) _MBG_API mbg_dev_has_cab_len( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_cab_len, IOCTL_DEV_HAS_CAB_LEN, p );
+
+} // mbg_dev_has_cab_len
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a configurable ref time offset
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ref_offs preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ref_offs
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ref_offs" ) _MBG_API mbg_dev_has_ref_offs( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_ref_offs, IOCTL_DEV_HAS_REF_OFFS, p );
+
+} // mbg_dev_has_ref_offs
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports the ::MBG_OPT_INFO/::MBG_OPT_SETTINGS
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_opt_flags preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_opt_flags
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_opt_flags" ) _MBG_API mbg_dev_has_opt_flags( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_opt_flags, IOCTL_DEV_HAS_OPT_FLAGS, p );
+
+} // mbg_dev_has_opt_flags
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device support reading/writing of ::UTC parameters
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_utc_parm preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_utc_parm
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_utc_parm" ) _MBG_API mbg_dev_has_utc_parm( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_utc_parm, IOCTL_DEV_HAS_GPS_UTC_PARM, p );
+
+} // mbg_dev_has_utc_parm
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports reading correlation info
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_corr_info preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_corr_info
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_corr_info" ) _MBG_API mbg_dev_has_corr_info( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_corr_info, IOCTL_DEV_HAS_CORR_INFO, p );
+
+} // mbg_dev_has_corr_info
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device supports configurable distance from transmitter
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tr_distance preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tr_distance
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tr_distance" ) _MBG_API mbg_dev_has_tr_distance( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_tr_distance, IOCTL_DEV_HAS_TR_DISTANCE, p );
+
+} // mbg_dev_has_tr_distance
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides a debug status word to be read
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_debug_status preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_debug_status
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_debug_status" ) _MBG_API mbg_dev_has_debug_status( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_debug_status, IOCTL_DEV_HAS_DEBUG_STATUS, p );
+
+} // mbg_dev_has_debug_status
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a device provides an on-board event log.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_evt_log preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_evt_log
+ */
+_MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_evt_log" ) _MBG_API mbg_dev_has_evt_log( MBG_DEV_HANDLE dh, int *p )
+{
+ _mbgdevio_old_query_cond( dh, _pcps_ddev_has_evt_log, IOCTL_DEV_HAS_EVT_LOG, p );
+
+} // mbg_dev_has_evt_log
+
+
+
+static /*HDR*/
+/**
+ * @brief Update a ::PCPS_TIME_STAMP to compensate the latency of an API call
+ *
+ * @param[in,out] ts The timestamp to be updated
+ * @param[in] p_cyc_ts Cycles value taken when the function was called
+ * @param[in] p_cyc_ontime Cycles value taken when access to the device was made
+ * @param[in] p_cyc_freq Cycles frequency determined by the application, depending on the type of cycles counter
+ * @param[out] hns_latency Optional pointer to a variable to receive the computed latency, or NULL
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int mbg_comp_hr_latency( PCPS_TIME_STAMP *ts,
const MBG_PC_CYCLES *p_cyc_ts,
const MBG_PC_CYCLES *p_cyc_ontime,
const MBG_PC_CYCLES_FREQUENCY *p_cyc_freq,
int32_t *hns_latency )
{
- #if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_POSIX )
int64_t cyc_latency;
int64_t frac_latency;
@@ -505,28 +3163,28 @@ int mbg_comp_hr_latency( PCPS_TIME_STAMP *ts,
);
#endif
- // Account for cycles counter overflow. This is
- // supposed to happen once every 2^^63 units of the
- // cycles counter frequency, i.e. about every
- // 97 years on a system with 3 GHz clock.
+ // Account for cycles counter overflow. If the CPU's TSC is used
+ // this is supposed to happen once every 2^^63 units of the
+ // cycles counter frequency, i.e. about every 97 years on a system
+ // with 3 GHz clock.
if ( cyc_latency < 0 )
{
cyc_latency += ( (uint64_t) -1 ) >> 1;
#if DEBUG && defined( MBG_TGT_LINUX )
- printf( "->%lli (%llX)",
+ printf( "->%lli (%llX)",
(unsigned long long) cyc_latency,
(unsigned long long) ( ( (uint64_t) -1 ) >> 1 )
);
#endif
}
- // convert latency to binary fractions of seconds,
+ // Convert latency to binary fractions of seconds,
// i.e. units of 2^^-32.
frac_latency = (*p_cyc_freq) ? ( cyc_latency * ( ( (int64_t) 1 ) << 32 ) / *p_cyc_freq ) : 0;
- // compute the compensated fractional part of the HR time stamp
- // and account for borrows from the sec field
+ // Compute the compensated fractional part of the HR time stamp
+ // and account for borrows from the sec field.
comp_frac = ts->frac - frac_latency;
ts->frac = (uint32_t) comp_frac; // yields 32 LSBs
ts->sec += (uint32_t) ( comp_frac >> 32 ); // yields 32 MSBs
@@ -568,7 +3226,7 @@ int mbg_comp_hr_latency( PCPS_TIME_STAMP *ts,
#else
// This is currently not supported by the target environment.
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -578,202 +3236,202 @@ int mbg_comp_hr_latency( PCPS_TIME_STAMP *ts,
/*HDR*/
/**
- 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 )
+ * @brief Create a device file name according to an index number
+ *
+ * Create a system-specific device file name string, e.g. "/dev/mbgclock0"
+ * under Linux and similar systems, which can be used with the
+ * open() call on systems which support this.
+ *
+ * Under Windows a hardware ID string is used, so a Windows-specific function
+ * is called to retrieve the string
+ *
+ * @param[out] s Pointer to the output buffer.
+ * @param[in] max_len Size of the output buffer.
+ * @param[in] dev_idx The device index number.
+ *
+ * @see mbg_svc_get_device_path under Windows
+ */
+_MBG_API_ATTR int _MBG_API mbg_dev_fn_from_dev_idx( char *s, int max_len, int dev_idx )
{
+ size_t n = 0;
- return MBGDEVIO_VERSION;
-
-} // mbgdevio_get_version
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- if ( header_version >= MBGDEVIO_COMPAT_VERSION )
- return MBG_SUCCESS;
+ #if MBG_TGT_HAS_DEV_FN
+ n = snprintf_safe( s, max_len, mbg_dev_fn_fmt, dev_idx );
+ #elif defined( MBG_TGT_WIN32 )
+ n = sn_cpy_str_safe( s, max_len, mbg_svc_get_device_path( dev_idx ) );
+ #else
+ n = snprintf_safe( s, max_len, "index #%i", dev_idx );
+ #endif
- return _mbg_err_to_os( MBG_ERR_LIB_NOT_COMPATIBLE );
+ return _int_from_size_t( n );
-} // mbgdevio_check_version
+} // mbg_dev_fn_from_dev_idx
/*HDR*/
/**
- 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 )
+ * @brief Open a device by index number
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_idx Device index number, starting from 0.
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ */
+MBG_DEV_HANDLE _MBG_API mbg_open_device( int dev_idx )
{
-#if defined( MBG_TGT_WIN32 )
-
- const char *device_path;
- HANDLE dh;
-
- device_path = mbg_svc_get_device_path( device_index );
-
- if ( device_path == NULL )
+ if ( dev_idx < 0 )
goto fail;
-
- dh = CreateFile(
- device_path, // file name
- GENERIC_READ | GENERIC_WRITE, // access mode
- 0, // share mode
- NULL, // security descriptor
- OPEN_EXISTING, // how to create
- 0, // file attributes
- NULL // handle to template file
- );
-
- if ( INVALID_HANDLE_VALUE == dh )
+ #if defined( MBG_TGT_WIN32 )
{
- #if 0 //##++
- printf( "mbg_open_device: CreateFile failed for index %i\n", device_index );
- #endif
+ const char *device_path = mbg_svc_get_device_path( dev_idx );
- goto fail;
+ return mbg_open_device_by_dev_fn( device_path );
}
+ #elif MBG_TGT_HAS_DEV_FN
+ {
+ MBG_DEV_FN dev_fn;
- return dh;
-
-fail:
- return MBG_INVALID_DEV_HANDLE;
-
-#elif defined( MBG_TGT_UNIX )
-
- MBG_DEV_HANDLE dh;
- char dev_fn[50];
-
- if ( device_index > MBG_MAX_DEVICES )
- device_index = MBG_MAX_DEVICES;
-
- sprintf( dev_fn, "/dev/mbgclock%d", device_index ); //##++
-
- dh = open( dev_fn, O_RDWR );
+ mbg_dev_fn_from_dev_idx( dev_fn, sizeof( dev_fn ), dev_idx );
- return ( dh < 0 ) ? MBG_INVALID_DEV_HANDLE : dh;
+ return mbg_open_device_by_dev_fn( dev_fn );
+ }
+ #else
-#else
+ #if defined( _PCPSDRVR_H )
+ if ( dev_idx < n_ddevs )
+ return &pcps_ddev[dev_idx];
+ #endif
- return ( device_index < n_ddevs ) ? &pcps_ddev[device_index] : NULL;
+ // intentionally fall-through to "fail"
+ #endif
-#endif
+fail:
+ errno = ENODEV; // No such device
+ return MBG_INVALID_DEV_HANDLE;
} // mbg_open_device
-static /*HDR*/
-/* (Intentionally excluded from Doxygen)
- Return a handle to a device specified by a given hardware_id.
- The format the hardware_id depends on the operating system, so
- this function is used only internally to detect devices for
- which a unique name of the format MBG_HW_NAME is generated,
- which is in turn used with the public API functions.
- */
-MBG_DEV_HANDLE _MBG_API mbg_open_device_by_hw_id( const char* hw_id )
+/*HDR*/
+/**
+ * @brief Open a device specified by a device file name
+ *
+ * The format the device file name depends on the operating system.
+ * see ::MBG_DEV_FN.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_fn The device file name
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_FN
+ */
+_MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device_by_dev_fn( const char *dev_fn )
{
#if defined( MBG_TGT_WIN32 )
- HANDLE dh;
- int ret = 0;
- BOOL usb = FALSE;
-
- if ( hw_id == NULL )
- goto fail;
+ if ( dev_fn == NULL )
+ {
+ SetLastError( ERROR_INVALID_PARAMETER ); // TODO Is this error code appropriate?
+ return MBG_INVALID_DEV_HANDLE;
+ }
- dh = CreateFile(
- hw_id, // file name
+ return CreateFileA(
+ dev_fn, // file name
GENERIC_READ | GENERIC_WRITE, // access mode
0, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
- strstr(hw_id,"usb") ? FILE_FLAG_OVERLAPPED : 0, // file attributes
+ strstr( dev_fn, "usb" ) ? FILE_FLAG_OVERLAPPED : 0, // file attributes
NULL // handle to template file
);
- if ( INVALID_HANDLE_VALUE == dh )
- goto fail;
-
- return dh;
+#elif defined( MBG_TGT_POSIX ) && !defined( MBG_TGT_QNX_NTO )
-fail:
- return MBG_INVALID_DEV_HANDLE;
-
-#elif defined ( MBG_TGT_UNIX )
-
- MBG_DEV_HANDLE dh = -1;
-
- if ( strlen( hw_id ) > 0 )
- dh = open( hw_id, O_RDWR );
+ if ( dev_fn == NULL )
+ {
+ errno = EFAULT; // Bad address, invalid pointer
+ return MBG_INVALID_DEV_HANDLE;
+ }
- return ( dh < 0 ) ? MBG_INVALID_DEV_HANDLE : dh;
+ return open( dev_fn, O_RDWR );
#else
+ errno = ( dev_fn == NULL ) ? EFAULT : ENODEV;
return MBG_INVALID_DEV_HANDLE;
#endif
-} // mbg_open_device_by_hw_id
+} // mbg_open_device_by_dev_fn
+
/*HDR*/
/**
- 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.
+ * @brief Open a device specified by a device file name
+ *
+ * @deprecated This function is deprecated, use
+ * ::mbg_open_device_by_dev_fn preferably.
+ *
+ * The format the device file name depends on the operating system.
+ * see ::MBG_DEV_FN.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_fn The device file name, see ::MBG_DEV_FN
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_FN
+ */
+_MBG_API_ATTR MBG_DEV_HANDLE _DEPRECATED_BY( "mbg_open_device_by_dev_fn" ) _MBG_API mbg_open_device_by_hw_id( const char *dev_fn )
+{
+ return mbg_open_device_by_dev_fn( dev_fn );
- <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
+} // mbg_open_device_by_hw_id
- @return The number of devices found.
- @see mbg_find_devices_with_names()
- */
+
+/*HDR*/
+/**
+ * @brief Get the number of devices installed on the computer
+ *
+ * The function ::mbg_find_devices_with_names should eventually
+ * be used preferafly. See @ref mbgdevio_open_fncs.
+ *
+ * @return The number of devices found
+ *
+ * @see ::mbg_find_devices_with_names
+ * @see ::mbg_open_device
+ * @see @ref mbgdevio_open_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_find_devices( void )
{
#if defined( _PCPSDRVR_H )
#if defined( MBG_TGT_QNX_NTO )
// Since this program accessed the hardware directly
- // I/O privileges must be assigned to the thread.
+ // I/O privileges have to be assigned to the thread.
if ( ThreadCtl( _NTO_TCTL_IO, NULL ) == -1 )
{
- perror( "Fatal error" );
+ fprintf( stderr, "** ThreadCtl() failed to request I/O privileges: %s\n\n", strerror( errno ) );
exit( 1 );
}
#endif
@@ -784,11 +3442,11 @@ _MBG_API_ATTR int _MBG_API mbg_find_devices( void )
pcps_detect_any_tsr();
prv_busy = pcps_tsr_set_busy_flag( 1 );
- pcps_detect_clocks( pcps_isa_ports, NULL );
+ pcps_detect_devices( pcps_isa_ports, NULL );
pcps_tsr_set_busy_flag( prv_busy );
}
#else
- pcps_detect_clocks( pcps_isa_ports, NULL );
+ pcps_detect_devices( pcps_isa_ports, NULL );
#endif
return n_ddevs;
@@ -797,13 +3455,13 @@ _MBG_API_ATTR int _MBG_API mbg_find_devices( void )
return mbg_svc_find_devices();
-#elif defined ( MBG_TGT_UNIX )
+ #elif defined( MBG_TGT_POSIX )
MBG_DEV_HANDLE dh;
int i = 0;
int n = 0;
- while( i < MBG_MAX_DEVICES )
+ while ( i < N_SUPP_DEV_BUS )
{
dh = mbg_open_device( i );
@@ -824,457 +3482,573 @@ _MBG_API_ATTR int _MBG_API mbg_find_devices( void )
-#if defined( MBG_TGT_WIN32 ) || defined ( MBG_TGT_UNIX )
+#if MBG_TGT_HAS_DEV_FN
+/**
+ * @brief Free a list of device names that has been allocated before
+ *
+ * This function should be called to free a list that has been
+ * allocated by ::setup_dev_fn_list.
+ *
+ * @param[out] list Pointer to a list to be allocated and
+ *
+ * @see ::setup_dev_fn_list
+ * @see ::setup_dev_details_from_dev_fn
+ */
static /*HDR*/
-int mbg_find_devices_with_hw_id( MBG_DEVICE_LIST ** list, int max_devs )
+void free_dev_fn_list( MBG_DEV_FN_LIST_ENTRY *list )
{
- #if defined ( MBG_TGT_WIN32 )
-
- return mbg_svc_find_devices_with_hw_id( list, max_devs );
-
- #elif defined ( MBG_TGT_UNIX )
-
- MBG_DEVICE_LIST *ListBegin;
- int n = 0;
- int i = 0;
-
- (*list) = (MBG_DEVICE_LIST *) malloc( sizeof( **list ) );
- memset( *list, 0, sizeof( **list ) );
-
- ListBegin = (*list);
-
- for (;;)
+ #if defined( MBG_TGT_WIN32 )
+ mbg_svc_free_device_list( list ); // TODO
+ #else
+ while ( list )
{
- char dev_name[100];
- MBG_DEV_HANDLE dh;
-
- sprintf( dev_name, "/dev/mbgclock%d", i );
+ MBG_DEV_FN_LIST_ENTRY *next;
- dh = mbg_open_device_by_hw_id( dev_name );
-
- if ( dh != MBG_INVALID_HANDLE )
+ if ( list->dev_fn_ptr )
{
- mbg_close_device( &dh );
-
- (*list)->device_path = (char *) malloc( strlen( dev_name ) + 1 );
- strcpy( (*list)->device_path, dev_name );
-
- (*list)->next = (MBG_DEVICE_LIST *) malloc( sizeof( **list ) );
- (*list) = (*list)->next;
-
- memset( *list, 0, sizeof( **list ) );
- n++;
+ free( list->dev_fn_ptr );
+ list->dev_fn_ptr = NULL;
}
- if ( ++i >= MBG_MAX_DEVICES )
- break;
+ next = list->next;
+ free( list );
+ list = next;
}
+ #endif
- if ( n > 0 )
- *list = ListBegin;
- else
- {
- free( *list );
- *list = NULL;
- }
+} // free_dev_fn_list
- return n;
+#endif // MBG_TGT_HAS_DEV_FN
- #else
- return 0;
-
- #endif
-}
-#endif
+#if MBG_TGT_HAS_DEV_FN
+static /*HDR*/
+/**
+ * @brief Allocate and fill a list of device file names
+ *
+ * The function ::setup_dev_details_from_dev_fn can be called
+ * to get the model name / serial number ID associated with
+ * the device file name.
+ *
+ * The function ::free_dev_fn_list should be called when the
+ * returned list has been evaliuated and isn't needed anymore.
+ *
+ * @param[out] p_list Pointer to a list to be allocated and
+ * set up, set to NULL if no devices were found.
+ * @param[in] max_devs Max. number of devices to be added to the list.
+ *
+ * @return The number of devices found
+ *
+ * @see ::free_dev_fn_list
+ * @see ::setup_dev_details_from_dev_fn
+ */
+int setup_dev_fn_list( MBG_DEV_FN_LIST_ENTRY **p_list, int max_devs )
+{
+ // The way to retrieve a list of devices currently present
+ // in the system depends on the operating system.
+ #if defined( MBG_TGT_WIN32 )
-#if defined ( MBG_TGT_WIN32 ) || defined ( MBG_TGT_UNIX )
+ return mbg_svc_find_devices_with_hw_id( p_list, max_devs );
-static /*HDR*/
-void _MBG_API mbg_free_device_list( MBG_DEVICE_LIST *devices )
-{
+ #elif defined( MBG_TGT_POSIX )
- #if defined ( MBG_TGT_WIN32 )
- mbg_svc_free_device_list( devices );
- #else
- int i = 0;
- MBG_DEVICE_LIST *Next = NULL;
+ MBG_DEV_FN_LIST_ENTRY *list_head = NULL;
+ MBG_DEV_FN_LIST_ENTRY *pos = NULL;
+ int n_dev_fn = 0;
+ int i;
- while ( i < MBG_MAX_DEVICES)
+ for ( i = 0; i < max_devs; i++ )
{
- if ( devices )
+ MBG_DEV_FN dev_fn;
+ MBG_DEV_HANDLE dh;
+
+ mbg_dev_fn_from_dev_idx( dev_fn, sizeof( dev_fn ), i );
+ dh = mbg_open_device_by_dev_fn( dev_fn );
+
+ if ( dh != MBG_INVALID_DEV_HANDLE )
{
- if ( devices->device_path )
- {
- free( devices->device_path );
- devices->device_path = NULL;
- }
+ size_t sz = strlen( dev_fn ) + 1; // including terminating 0
- if ( devices->next )
+ if ( list_head == NULL ) // first turn
{
- Next = devices->next;
- free(devices);
- devices = Next;
+ list_head = (MBG_DEV_FN_LIST_ENTRY *) calloc( 1, sizeof( *list_head ) );
+ pos = list_head;
}
else
{
- if ( devices )
- {
- free( devices );
- devices = NULL;
- }
- break;
+ pos->next = (MBG_DEV_FN_LIST_ENTRY *) calloc( 1, sizeof( *pos ) );
+ pos = pos->next;
}
- }
- else
- break;
- i++;
+ if ( pos == NULL )
+ goto out_free;
+
+ pos->dev_fn_ptr = (char *) calloc( 1, sz );
+
+ if ( pos->dev_fn_ptr == NULL )
+ goto out_free;
+
+ strncpy_safe( pos->dev_fn_ptr, dev_fn, sz );
+ n_dev_fn++;
+
+ mbg_close_device( &dh );
+ }
}
+ if ( n_dev_fn )
+ goto out;
+
+
+out_free:
+ free_dev_fn_list( list_head );
+ list_head = NULL;
+ n_dev_fn = 0;
+
+out:
+ *p_list = list_head; // Return the list
+ return n_dev_fn;
+
+ #else
+
+ *p_list = NULL;
+ return 0;
+
#endif
-}
-#endif
+} // setup_dev_fn_list
+
+#endif // MBG_TGT_HAS_DEV_FN
-#if ( defined( MBG_TGT_WIN32 ) || defined ( MBG_TGT_UNIX ) )
+#if MBG_TGT_HAS_DEV_FN
static /*HDR*/
-void get_hw_name_from_hw_id( MBG_DEVICE_INFO *dev_info )
+/**
+ * @brief Open a device, retrieve the ::PCPS_DEV info, then close it
+ *
+ * @param[out] p Pointer to a ::PCPS_DEV to be filled.
+ * @param[in] dev_fn The device file name of the device to be used.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int get_dev_info_for_dev_fn( PCPS_DEV *p, const char *dev_fn )
{
MBG_DEV_HANDLE dh;
- PCPS_DEV pdev;
+ int rc;
- dh = MBG_INVALID_HANDLE;
- memset( &pdev, 0, sizeof( pdev ) );
+ memset( p, 0, sizeof( *p ) );
- // Default initializers
- strcpy( dev_info->model_name, "N/A" );
- strcpy( dev_info->serial_number, "N/A" );
- strcpy( dev_info->hw_name, "N/A" );
+ // Try to retrieve device information.
+ dh = mbg_open_device_by_dev_fn( dev_fn );
- dh = mbg_open_device_by_hw_id( dev_info->hardware_id );
+ if ( dh == MBG_INVALID_DEV_HANDLE )
+ return mbg_get_last_error( NULL );
- if ( dh != MBG_INVALID_HANDLE )
- {
- if ( mbg_get_device_info( dh, &pdev ) == MBG_SUCCESS )
- {
- strcpy( dev_info->model_name, _pcps_type_name( &pdev ) );
- strcpy( dev_info->serial_number, _pcps_sernum( &pdev ) );
- sprintf( dev_info->hw_name, "%s_%s", _pcps_type_name( &pdev ), _pcps_sernum( &pdev ) );
- }
+ rc = mbg_get_device_info( dh, p );
- mbg_close_device( &dh );
- }
+ mbg_close_device( &dh );
-} // get_hw_name_from_hw_id
+ return rc;
-#endif
+} // get_dev_info_for_dev_fn
+#endif // MBG_TGT_HAS_DEV_FN
-/*HDR*/
+
+#if MBG_TGT_HAS_DEV_FN
+
+static /*HDR*/
/**
- Return the number of supported devices installed on the system and
- set up a list of unique names of those devices.
+ * @brief Create a string with a unique device name
+ *
+ * The device name is composed of the device's type name and
+ * its serial number which is appended after an underscore '_'.
+ * So the string buffer is typically an ::MBG_DEV_NAME.
+ *
+ * @param[out] s Pointer to the output buffer for the string.
+ * @param[in] max_len Size of the output buffer.
+ * @param[in] p_dev Pointer to a ::PCPS_DEV structure providing the required information.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::MBG_DEV_NAME
+ */
+int snprint_dev_name( char *s, size_t max_len, const PCPS_DEV *p_dev )
+{
+ size_t n = snprintf_safe( s, max_len, "%s_%s",
+ _pcps_type_name( p_dev ), _pcps_sernum( p_dev ) );
+ return _int_from_size_t( n );
- This function should be used preferably instead of mbg_find_devices().
+} // snprint_dev_name
- @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).
+#endif // MBG_TGT_HAS_DEV_FN
- @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 )
+
+static /*HDR*/
+/**
+ * @brief Lookup a specific device in an array of ::PCPS_DEV structures
+ *
+ * Look for a matching name, if a type name is specified, and for
+ * a matching serial number if that is also given.
+ *
+ * @param[in] dev_array The array of ::PCPS_DEV structures to be searched.
+ * @param[in] n_dev The number of entries in @p dev_array.
+ * @param[in] type_name An optional type name to search for, may be NULL.
+ * @param[in] sernum An optional serial number to search for, may be NULL.
+ *
+ * @return An index value >= 0 on success, or -1 if no entry was found
+ *
+ * @see ::lookup_dev_idx_ex
+ */
+int lookup_dev_idx( const PCPS_DEV *dev_array, int n_dev,
+ const char *type_name, const char *sernum )
{
-#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+ int i;
- MBG_DEVICE_LIST *hardware_list = NULL;
- MBG_DEVICE_LIST *hardware_list_begin = NULL;
- MBG_DEVICENAME_LIST *ListBegin = NULL;
- MBG_DEVICE_INFO dev_info;
+ for ( i = 0; i < n_dev; i++ )
+ {
+ const PCPS_DEV *p_dev = &dev_array[i];
- int n_devices = 0;
- int i = 0;
+ if ( type_name && strcmp( _pcps_type_name( p_dev ), type_name ) )
+ continue; // Type name given, but doesn't match.
- n_devices = mbg_find_devices_with_hw_id( &hardware_list, max_devices );
+ if ( sernum && strcmp( _pcps_sernum( p_dev ), sernum ) )
+ continue; // Serial number given, but doesn't match.
- hardware_list_begin = hardware_list;
+ return i; // Matching device found.
+ }
- if ( n_devices )
- {
- *device_list = (MBG_DEVICENAME_LIST *) malloc( sizeof( MBG_DEVICENAME_LIST ) );
- (*device_list)->next = NULL;
+ return -1; // No matching device found.
- // Save begin of the list
- ListBegin = *device_list;
+} // lookup_dev_idx
- // Loop through the list of hardware_ids and get their readable names
- for (;;)
- {
- if ( hardware_list->device_path && i++ < MBG_MAX_DEVICES )
- {
- strcpy( dev_info.hardware_id, hardware_list->device_path );
- get_hw_name_from_hw_id( &dev_info );
- strcpy( (*device_list)->device_name, dev_info.hw_name );
+static /*HDR*/
+/**
+ * @brief Lookup a specific device in an array, depending on a match code
+ *
+ * The function first looks for an exact match of type name
+ * and serial number, then for a matching type name only, if
+ * @p selection_mode allows, and if no matching devic model
+ * can be found at all, returns the index of the first device
+ * found, if an appropriate @p selection_mode has been specified.
+ *
+ * @param[in] dev_array The array of ::PCPS_DEV structures to be searched.
+ * @param[in] n_dev The number of entries in @p dev_array.
+ * @param[in] type_name An optional type name to search for, may be NULL.
+ * @param[in] sernum An optional serial number to search for, may be NULL.
+ * @param[in] selection_mode One of the ::MBG_MATCH_MODES.
+ *
+ * @return An index value >= 0 on success, or -1 if no entry was found
+ *
+ * @see ::lookup_dev_idx
+ * @see ::MBG_MATCH_MODES
+ */
+int lookup_dev_idx_ex( const PCPS_DEV *dev_array, int n_dev,
+ const char *type_name, const char *sernum,
+ int selection_mode )
+{
+ int dev_idx = -1;
- if ( hardware_list->next )
- {
- hardware_list = hardware_list->next;
- (*device_list)->next = (MBG_DEVICENAME_LIST *) malloc( sizeof( MBG_DEVICENAME_LIST ) );
- (*device_list) = (*device_list)->next;
- (*device_list)->next = NULL;
- }
- else
- break;
- }
- else
- break;
- }
+ if ( n_dev == 0 ) // no devices available
+ goto out;
- *device_list = ListBegin;
- }
+ dev_idx = lookup_dev_idx( dev_array, n_dev, type_name, sernum );
- if ( hardware_list_begin )
- mbg_free_device_list( hardware_list_begin );
+ if ( dev_idx >= 0 )
+ goto out;
- return n_devices;
-#else
+ // The requested combination of a clock model name and
+ // serial number was not found. If an exact match was
+ // requested then we're done anyway.
+ if ( selection_mode == MBG_MATCH_EXACTLY )
+ goto out;
- return 0;
-#endif
+ // Look for device with matching name only, ignoring
+ // the serial number.
+ dev_idx = lookup_dev_idx( dev_array, n_dev, type_name, NULL );
-} // mbg_find_devices_with_names
+ if ( dev_idx >= 0 )
+ goto out;
+
+
+ // As a last resort select the first device that
+ // has been found, if the selection mode allows.
+ if ( selection_mode == MBG_MATCH_ANY )
+ dev_idx = 0;
+
+out:
+ return dev_idx;
+
+} // lookup_dev_idx_ex
/*HDR*/
/**
- Free the memory of the ::MBG_DEVICENAME_LIST that has been allocated before
- by mbg_find_devices_with_names().
+ * @brief Allocate memory and set up a list of installed and supported devices
+ *
+ * Allocate and fill a list with the names of Meinberg devices currently
+ * present in the system.
+ *
+ * This can be used e.g. to populate a device selection dialog
+ * in a configuration program.
+ *
+ * When the list is not used anymore it can be freed by calling
+ * ::mbg_free_device_name_list.
+ *
+ * @param[in] p_list Pointer to a linked list to be allocated.
+ * @param[in] max_devices Maximum number of devices to be searched for
+ * (must not exceed ::N_SUPP_DEV_BUS).
+ *
+ * @return The number of present devices
+ *
+ * @see ::mbg_free_device_name_list
+ * @see ::mbg_find_devices
+ * @see ::MBG_DEV_NAME
+ */
+_MBG_API_ATTR int _MBG_API mbg_find_devices_with_names( MBG_DEV_NAME_LIST_ENTRY **p_list,
+ int max_devices )
+{
+#if MBG_TGT_HAS_DEV_FN
- @param *list Linked list of type ::MBG_DEVICENAME_LIST
+ MBG_DEV_FN_LIST_ENTRY *dev_fn_list_head = NULL;
+ MBG_DEV_FN_LIST_ENTRY *dev_fn_pos = NULL;
- @see mbg_find_devices_with_names()
- */
-_MBG_API_ATTR void _MBG_API mbg_free_device_name_list( MBG_DEVICENAME_LIST *list)
-{
-#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+ MBG_DEV_NAME_LIST_ENTRY *list_head = NULL;
+ MBG_DEV_NAME_LIST_ENTRY *pos = NULL;
- MBG_DEVICENAME_LIST *Next = NULL;
- int i = 0;
+ int n_dev_fn = 0;
+ int n_dev_name = 0;
- // Deallocate members of linked list
- while ( i < MBG_MAX_DEVICES )
- {
- if ( list )
- {
- Next = list->next;
+ // First set up a list of device names, the format of which
+ // depends on the OS.
+ n_dev_fn = setup_dev_fn_list( &dev_fn_list_head, max_devices );
- free( list );
- list = NULL;
+ // Now iterate through the device *file name* list
+ // and set up a *device name* list.
+ for ( dev_fn_pos = dev_fn_list_head; dev_fn_pos; dev_fn_pos = dev_fn_pos->next )
+ {
+ PCPS_DEV dev;
+ int rc;
- if ( Next )
- list = Next->next;
- else
- break;
+ if ( list_head == NULL ) // first turn
+ {
+ list_head = (MBG_DEV_NAME_LIST_ENTRY *) calloc( 1, sizeof( *list_head ) );
+ pos = list_head;
}
else
+ {
+ pos->next = (MBG_DEV_NAME_LIST_ENTRY *) calloc( 1, sizeof( *pos ) );
+ pos = pos->next;
+ }
+
+ if ( pos == NULL ) // failed to allocate memory
+ {
+ mbg_free_device_name_list( list_head ); // free this list
+ list_head = NULL;
+ n_dev_name = 0;
break;
+ }
+
+ // Get device details for the device.
+ rc = get_dev_info_for_dev_fn( &dev, dev_fn_pos->dev_fn_ptr );
+
+ if ( mbg_rc_is_success( rc ) )
+ snprint_dev_name( pos->dev_name, sizeof( pos->dev_name ),
+ &dev );
- i++;
+ if ( ++n_dev_name > n_dev_fn ) // This should never happen
+ break;
}
-#endif
+ // Free the device name list which we don't need anymore
+ free_dev_fn_list( dev_fn_list_head );
-} // mbg_free_device_list
+ *p_list = list_head; // Return the list
+ return n_dev_name;
+#else
-/*HDR*/
-/**
- 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().
+ *p_list = NULL;
+ return 0;
- This function should be used preferably instead of mbg_open_device().
+#endif
- @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
+} // mbg_find_devices_with_names
- @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 ) //##++++
-{
-#if ( defined( MBG_TGT_WIN32 ) || defined ( MBG_TGT_UNIX ) )
+/*HDR*/
+/**
+ * @brief Free the memory allocated for a list of ::MBG_DEV_NAME_LIST_ENTRY entries.
+ *
+ * The list may have been set up and allocated before
+ * by ::mbg_find_devices_with_names.
+ *
+ * @param[in,out] list Linked list of ::MBG_DEV_NAME_LIST_ENTRY entries.
+ *
+ * @see ::mbg_find_devices_with_names
+ */
+_MBG_API_ATTR void _MBG_API mbg_free_device_name_list( MBG_DEV_NAME_LIST_ENTRY *list )
+{
+ while ( list )
+ {
+ MBG_DEV_NAME_LIST_ENTRY *next = list->next;
- MBG_DEV_HANDLE dh;
+ free( list );
+ list = next;
+ }
- MBG_DEVICE_LIST *devices = NULL;
- MBG_DEVICE_LIST *ListBegin = NULL;
- char hw_id[MAX_INFO_LEN];
- char tmp_model_name[PCPS_CLOCK_NAME_SZ];
- PCPS_SN_STR tmp_sn;
- int n_devices = 0;
- int i = 0;
- int j = 0;
+} // mbg_free_device_name_list
- hw_id[0] = '\0';
- memset( tmp_model_name, 0, sizeof( tmp_model_name) );
- memset( device_info_list, 0, sizeof( device_info_list ) );
- memset( tmp_sn, 0, sizeof( tmp_sn ) );
- // separate hw_name into clock model and serial number
- if ( hw_name && ( strlen( hw_name ) > 0 ) )
+/*HDR*/
+/**
+ * @brief Return a handle to a device with a particular device name
+ *
+ * See ::MBG_DEV_NAME for the possible formats of a device name.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] srch_name String with the ::MBG_DEV_NAME of a device to be opened
+ * @param[in] selection_mode One of the ::MBG_MATCH_MODES
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_NAME
+ * @see ::MBG_MATCH_MODES
+ */
+_MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device_by_name( const char *srch_name, int selection_mode )
+{
+ PCPS_DEV dev_array[N_SUPP_DEV_BUS] = { { { 0 } } };
+ PCPS_CLOCK_NAME type_name = { 0 };
+ PCPS_SN_STR sernum = { 0 };
+ size_t srch_name_len = 0;
+ size_t i = 0;
+ const char *cp;
+ char c;
+ int dev_idx = -1;
+
+ if ( srch_name )
+ srch_name_len = strlen( srch_name );
+
+ if ( srch_name_len )
{
- // clock model
- for ( i = 0; ( i < PCPS_CLOCK_NAME_SZ ) && ( hw_name[i] != '_' ) && ( (unsigned int) i < strlen( hw_name ) ); i++ )
- tmp_model_name[i] = hw_name[i];
-
- tmp_model_name[i] = 0;
- i++;
+ // clock model name
+ cp = srch_name;
+ i = 0;
- // serial number
- if ( ( unsigned int ) i < strlen( hw_name ) )
+ for (;;)
{
- j = 0;
+ c = *cp++;
- while( ( unsigned int ) i < strlen(hw_name) && j < PCPS_SN_SIZE )
- {
- tmp_sn[j] = hw_name[i];
- j++;
- i++;
- }
- tmp_sn[j] = '\0';
- }
- }
- else
- goto fail;
+ if ( c == 0 ) // end of string
+ break;
- i = 0;
+ if ( c == '_' ) // separator before S/N
+ break;
+
+ type_name[i] = ( c >= 'a' && c <= 'z' ) ? ( c - 0x20 ) : c;
- // get OS-dependent hardware_id strings for devices that are present on the system
- n_devices = mbg_find_devices_with_hw_id( &devices, MBG_MAX_DEVICES );
+ if ( ++i >= ( sizeof( type_name ) - 1 ) )
+ break;
+ }
- ListBegin = devices;
+ type_name[i] = 0; // terminate string
- if ( n_devices )
- {
- for (;;)
+ if ( c == '_' )
{
- if ( devices->device_path && i < MBG_MAX_DEVICES )
- {
- strncpy( device_info_list[i].hardware_id, devices->device_path, MAX_INFO_LEN );
+ // Serial number
+ i = 0;
- // get readable hw_name for the device
- get_hw_name_from_hw_id( &device_info_list[i] );
+ for (;;)
+ {
+ c = *cp++;
- if ( hw_name && device_info_list[i].hw_name && strcmp( device_info_list[i].hw_name, hw_name ) == 0 ) //##+++++
- {
- // The requested device was found
- strcpy( hw_id, device_info_list[i].hardware_id );
+ if ( c == 0 ) // end of string
break;
- }
- else if ( devices->next )
- devices = devices->next;
- else
+
+ if ( c < '0' || c > '9' ) // not a digit
break;
- }
- else
- break;
- i++;
- }
- // If the requested CLOCK_MODEL/SN combination was not found,
- // decide what to do depending on the selection mode
- if ( ( hw_id[0] == '\0' ) && ( selection_mode != MBG_MATCH_EXACTLY ) )
- {
- for ( j = 0; j <= i; j++ )
- {
- // Search for the same clock model
- if ( ( tmp_model_name[0] != '\0' ) && strcmp( device_info_list[j].model_name, tmp_model_name ) == 0 )
- {
- strcpy( hw_id, device_info_list[j].hardware_id );
+ sernum[i] = c;
+
+ if ( ++i >= ( sizeof( sernum ) - 1 ) )
break;
- }
}
- // Finally select the first device found on the system, if the clock model was not found
- if ( ( selection_mode == MBG_MATCH_ANY ) && ( hw_id[0] == '\0' ) )
- strcpy( hw_id, device_info_list[0].hardware_id );
+ sernum[i] = 0; // terminate string
}
}
- mbg_free_device_list( ListBegin );
-
-#endif
+ #if MBG_TGT_HAS_DEV_FN
+ {
+ MBG_DEV_FN dev_fn_array[N_SUPP_DEV_BUS] = { { 0 } };
+ MBG_DEV_FN_LIST_ENTRY *list_head = NULL;
-#if defined ( MBG_TGT_WIN32 )
+ // Set up a temporary list with file names of devices
+ // that are currently present in the system.
+ int n_devices = setup_dev_fn_list( &list_head, N_SUPP_DEV_BUS );
- if ( hw_id[0] == '\0' )
- goto fail;
-
- dh = CreateFile(
- hw_id, // file name
- GENERIC_READ | GENERIC_WRITE, // access mode
- 0, // share mode
- NULL, // security descriptor
- OPEN_EXISTING, // how to create
- strstr(hw_id,"usb") ? FILE_FLAG_OVERLAPPED : 0, // file attributes
- NULL // handle to template file
- );
+ if ( n_devices )
+ {
+ MBG_DEV_FN_LIST_ENTRY *pos;
- if ( INVALID_HANDLE_VALUE == dh )
- goto fail;
+ for ( i = 0, pos = list_head; pos && pos->dev_fn_ptr; pos = pos->next )
+ {
+ int rc = get_dev_info_for_dev_fn( &dev_array[i], pos->dev_fn_ptr );
- return dh;
+ if ( mbg_rc_is_success( rc ) )
+ {
+ // Save the associated device file name.
+ sn_cpy_str_safe( dev_fn_array[i], sizeof( dev_fn_array[i] ), pos->dev_fn_ptr );
+ i++;
+ }
+ }
-fail:
- return MBG_INVALID_DEV_HANDLE;
+ dev_idx = lookup_dev_idx_ex( dev_array, i, type_name, sernum, selection_mode );
+ }
-#elif defined ( MBG_TGT_UNIX )
+ free_dev_fn_list( list_head );
- if ( hw_id[0] != '\0' )
- dh = open( hw_id, O_RDWR );
- else
- goto fail;
+ // We even try to open the device if no match was found.
+ // This causes an "invalid device handle" value to be
+ // returned, and sets an appropriate "last error" code.
+ return mbg_open_device_by_dev_fn( ( dev_idx >= 0 ) ? dev_fn_array[dev_idx] : "" );
+ }
+ #else
+ #if defined( _PCPSDRVR_H )
+ mbg_find_devices();
- return ( dh < 0 ) ? MBG_INVALID_DEV_HANDLE : dh;
+ for ( i = 0; i < n_ddevs; i++ )
+ dev_array[i] = pcps_ddev[i].dev;
-fail:
- return MBG_INVALID_DEV_HANDLE;
+ dev_idx = lookup_dev_idx_ex( dev_array, i, type_name, sernum, selection_mode );
-#else
+ if ( dev_idx >= 0 )
+ return mbg_open_device( dev_idx );
+ #endif
- //return ( device_index < n_ddevs ) ? &pcps_ddev[device_index] : NULL;
- return MBG_INVALID_DEV_HANDLE;
+ errno = ENODEV;
+ return MBG_INVALID_DEV_HANDLE;
-#endif
+ #endif
} // mbg_open_device_by_name
@@ -1282,18 +4056,19 @@ fail:
/*HDR*/
/**
- 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.
- */
+ * @brief Close a device handle and set the handle value to ::MBG_INVALID_DEV_HANDLE
+ *
+ * @param[in,out] dev_handle Pointer to a Meinberg device handle
+ *
+ * @see @ref mbgdevio_open_fncs
+ */
_MBG_API_ATTR void _MBG_API mbg_close_device( MBG_DEV_HANDLE *dev_handle )
{
if ( *dev_handle != MBG_INVALID_DEV_HANDLE && *dev_handle != 0 ) //##++++ dev_handle NULL/0 ???
{
#if defined( MBG_TGT_WIN32 )
CloseHandle( *dev_handle );
- #elif defined( MBG_TGT_UNIX )
+ #elif defined( MBG_TGT_POSIX ) && !defined( MBG_TGT_QNX_NTO )
close( *dev_handle );
#endif
}
@@ -1306,24 +4081,21 @@ _MBG_API_ATTR void _MBG_API mbg_close_device( MBG_DEV_HANDLE *dev_handle )
/*HDR*/
/**
- 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
- */
+ * @brief Read information about the driver handling a given device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::PCPS_DRVR_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_MBG_API_ATTR int _MBG_API mbg_get_drvr_info( MBG_DEV_HANDLE dh, PCPS_DRVR_INFO *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCPS_DRVR_INFO, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
- #if defined( __BORLANDC__ )
- dh; // avoid warnings "never used"
- #endif
+ (void) dh; // avoid warning "never used"
drvr_info.n_devs = n_ddevs;
*p = drvr_info;
return MBG_SUCCESS;
@@ -1335,20 +4107,20 @@ _MBG_API_ATTR int _MBG_API mbg_get_drvr_info( MBG_DEV_HANDLE dh, PCPS_DRVR_INFO
/*HDR*/
/**
- 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
- */
+ * @brief Read detailed device information
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] *p A ::PCPS_DEV structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_MBG_API_ATTR int _MBG_API mbg_get_device_info( MBG_DEV_HANDLE dh, PCPS_DEV *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCPS_DEV, p );
// Endianess is converted inside the kernel driver, if necessary.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
*p = dh->dev;
return MBG_SUCCESS;
@@ -1360,22 +4132,26 @@ _MBG_API_ATTR int _MBG_API mbg_get_device_info( MBG_DEV_HANDLE dh, PCPS_DEV *p )
/*HDR*/
/**
- 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"
- */
+ * @brief Read the current state of the on-board ::PCPS_STATUS_PORT
+ *
+ * This function is useful to read the device's status port which
+ * also includes the ::PCPS_ST_MOD bit reflecting the time code
+ * modulation of long wave receivers.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::PCPS_STATUS_PORT value to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see @ref group_status_port "bitmask" //### TODO check syntax
+ */
_MBG_API_ATTR int _MBG_API mbg_get_status_port( MBG_DEV_HANDLE dh, PCPS_STATUS_PORT *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCPS_STATUS_PORT, p );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
*p = _pcps_ddev_read_status_port( dh );
// No endianess conversion required.
@@ -1388,33 +4164,33 @@ _MBG_API_ATTR int _MBG_API mbg_get_status_port( MBG_DEV_HANDLE dh, PCPS_STATUS_P
/*HDR*/
/* (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()
- */
+ * Generic read function which writes a command code to a 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.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd Can be any @ref PCPS_CMD_CODES "command code" supported by the device
+ * @param[out] p Pointer to a buffer to be filled up
+ * @param[in] size Size of the output buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_gen_read( dh, cmd, p, size );
- // No type information available, so endianess must be
+ // No type information available, so endianess has to be
// converted by the caller, if required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_generic_read
@@ -1422,36 +4198,36 @@ _MBG_API_ATTR int _MBG_API mbg_generic_read( MBG_DEV_HANDLE dh, int cmd,
/*HDR*/
/* (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()
- */
+ * Generic read function which writes a GPS command code to a device
+ * and reads a number of data bytes back into a generic buffer.
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[out] p Pointer to a buffer to be filled up
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_gen_read_gps( dh, cmd, p, size );
- // No type information available, so endianess must be
+ // No type information available, so endianess has to be
// converted by the caller, if required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_generic_read_gps
@@ -1459,33 +4235,33 @@ _MBG_API_ATTR int _MBG_API mbg_generic_read_gps( MBG_DEV_HANDLE dh, int cmd,
/*HDR*/
/* (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()
- */
+ * Generic write function which writes a command code plus an
+ * associated number of data bytes to a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[in] p Pointer to a buffer of data to be written
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
- // No type information available, so endianess must be
+ MBGDEVIO_RET_VAL rc;
+ // No type information available, so endianess has to be
// converted by the caller, if required.
rc = _mbgdevio_gen_write( dh, cmd, p, size );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_generic_write
@@ -1493,36 +4269,36 @@ _MBG_API_ATTR int _MBG_API mbg_generic_write( MBG_DEV_HANDLE dh, int cmd,
/*HDR*/
/* (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()
- */
+ * Generic write function which writes a GPS command code plus an
+ * associated number of data bytes to a device.
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[in] p Pointer to a buffer of data to be written
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
- // No type information available, so endianess must be
+ MBGDEVIO_RET_VAL rc;
+ // No type information available, so endianess has to be
// converted by the caller, if required.
rc = _mbgdevio_gen_write_gps( dh, cmd, p, size );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_generic_write_gps
@@ -1530,25 +4306,25 @@ _MBG_API_ATTR int _MBG_API mbg_generic_write_gps( MBG_DEV_HANDLE dh, int cmd,
/*HDR*/
/* (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()
- */
+ * Write and/or read generic data to/from a device.
+ * The function ::mbg_chk_dev_has_generic_io checks
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This call is for debugging purposes and internal use only!
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if !defined( _MBGIOCTL_H )
// The hardware is accessed directly, so we must check
@@ -1556,10 +4332,10 @@ _MBG_API_ATTR int _MBG_API mbg_generic_io( MBG_DEV_HANDLE dh, int type,
_mbgdevio_chk_cond( _pcps_ddev_has_generic_io( dh ) );
#endif
- // No type information available, so endianess must be
+ // No type information available, so endianess must be
// converted by the caller, if required.
rc = _mbgdevio_gen_io( dh, type, in_p, in_sz, out_p, out_sz );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_generic_io
@@ -1567,29 +4343,32 @@ _MBG_API_ATTR int _MBG_API mbg_generic_io( MBG_DEV_HANDLE dh, int type,
/*HDR*/
/**
- 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()
- */
+ * @brief 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) only.
+ *
+ * This call is supported by any device manufactured by Meinberg.
+ * However, for higher accuracy and resolution the @ref mbgdevio_hr_time_fncs or
+ * the @ref mbgdevio_fast_timestamp_fncs group of calls should be used preferably,
+ * if supported by the device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, PCPS_GIVE_TIME, IOCTL_GET_PCPS_TIME, p );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_time
@@ -1597,24 +4376,27 @@ _MBG_API_ATTR int _MBG_API mbg_get_time( MBG_DEV_HANDLE dh, PCPS_TIME *p )
/*HDR*/
/**
- 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()
- */
+ * @brief Set the device's on-board clock to a given date and time.
+ *
+ * The macro ::_pcps_can_set_time checks whether
+ * this call is supported by a device.
+ *
+ * @todo Provide an API function replacing ::_pcps_can_set_time.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_STIME structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time
+ */
_MBG_API_ATTR int _MBG_API mbg_set_time( MBG_DEV_HANDLE dh, const PCPS_STIME *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
// No endianess conversion required.
_mbgdevio_write_var_chk( dh, PCPS_SET_TIME, IOCTL_SET_PCPS_TIME, p,
_pcps_ddev_can_set_time( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_time
@@ -1622,34 +4404,36 @@ _MBG_API_ATTR int _MBG_API mbg_set_time( MBG_DEV_HANDLE dh, const PCPS_STIME *p
/*HDR*/
/**
- 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()
- */
+ * @brief Read the time when the device has last recently synchronized
+ *
+ * Fills a ::PCPS_TIME structure with the date/time/status reporting
+ * when the device was synchronized the last time to its time source,
+ * e.g. the DCF77 signal, the GPS satellites, or similar.
+ *
+ * The macro ::_pcps_has_sync_time checks whether
+ * this call is supported by a device.
+ *
+ * <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 set".
+ *
+ * @todo Provide an API function replacing ::_pcps_has_sync_time.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time
+ */
_MBG_API_ATTR int _MBG_API mbg_get_sync_time( MBG_DEV_HANDLE dh, PCPS_TIME *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GIVE_SYNC_TIME, IOCTL_GET_PCPS_SYNC_TIME,
p, _pcps_ddev_has_sync_time( dh ) );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_sync_time
@@ -1657,32 +4441,34 @@ _MBG_API_ATTR int _MBG_API mbg_get_sync_time( MBG_DEV_HANDLE dh, PCPS_TIME *p )
/*HDR*/
/**
- 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()
- */
+ * @brief Wait until the next second change, then return current time
+ *
+ * Returns time in 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. The accuracy of this call is limited
+ * to a few milliseconds.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @see ::mbg_get_time
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_sec_change( MBG_DEV_HANDLE dh, PCPS_TIME *p )
{
#if defined( MBG_TGT_WIN32 )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCPS_TIME_SEC_CHANGE, p );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
- #if defined( __BORLANDC__ )
- dh; p; // avoid warnings "never used"
- #endif
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ (void) dh; // avoid warning "never used"
+ (void) p; // avoid warning "never used"
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
} // mbg_get_time_sec_change
@@ -1691,34 +4477,33 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_sec_change( MBG_DEV_HANDLE dh, PCPS_TIME
/*HDR*/
/**
- 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()
- */
+ * @brief Read the card's current time with high resolution, including status
+ *
+ * Fills up a ::PCPS_HR_TIME (High Resolution time) structure containing
+ * the current %UTC time (seconds since 1970), %UTC offset, and status.
+ *
+ * The API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by a device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_hr_time( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GIVE_HR_TIME, IOCTL_GET_PCPS_HR_TIME,
p, _pcps_ddev_has_hr_time( dh ) );
_mbg_swab_pcps_hr_time( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_hr_time
@@ -1726,23 +4511,23 @@ _MBG_API_ATTR int _MBG_API mbg_get_hr_time( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p )
/*HDR*/
/* (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()
- */
+ * Write a high resolution time stamp ::PCPS_TIME_STAMP to a device
+ * to configure a %UTC time when the clock shall generate an event.
+ * The API call ::mbg_chk_dev_has_event_time checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This is only supported by some special firmware.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TIME_STAMP structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_event_time
+ */
_MBG_API_ATTR int _MBG_API mbg_set_event_time( MBG_DEV_HANDLE dh, const PCPS_TIME_STAMP *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PCPS_TIME_STAMP tmp = *p;
_mbg_swab_pcps_time_stamp( &tmp );
@@ -1750,7 +4535,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_event_time( MBG_DEV_HANDLE dh, const PCPS_TIM
#endif
_mbgdevio_write_var_chk( dh, PCPS_SET_EVENT_TIME, IOCTL_SET_PCPS_EVENT_TIME,
p, _pcps_ddev_has_event_time( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_event_time
@@ -1758,28 +4543,28 @@ _MBG_API_ATTR int _MBG_API mbg_set_event_time( MBG_DEV_HANDLE dh, const PCPS_TIM
/*HDR*/
/**
- 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()
- */
+ * @brief Read the serial port configuration from an old type of device
+ *
+ * @deprecated Direct usage of this function is deprecated. The generic
+ * API function ::mbg_get_serial_settings should be used instead
+ * which fully supports the capabilities of current devices.
+ *
+ * The macro ::_pcps_has_serial checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_SERIAL structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_serial( MBG_DEV_HANDLE dh, PCPS_SERIAL *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, PCPS_GET_SERIAL, IOCTL_GET_PCPS_SERIAL, p );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_serial
@@ -1787,28 +4572,28 @@ _MBG_API_ATTR int _MBG_API mbg_get_serial( MBG_DEV_HANDLE dh, PCPS_SERIAL *p )
/*HDR*/
/**
- 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()
- */
+ * @brief Write the serial port configuration to an old type of device
+ *
+ * @deprecated Direct usage of this function is deprecated. The generic
+ * API function ::mbg_save_serial_settings should be used instead
+ * which fully supports the capabilities of current devices.
+ *
+ * The macro ::_pcps_has_serial checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_SERIAL structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_set_serial( MBG_DEV_HANDLE dh, const PCPS_SERIAL *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
// No endianess conversion required.
rc = _mbgdevio_write_var( dh, PCPS_SET_SERIAL, IOCTL_SET_PCPS_SERIAL, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_serial
@@ -1816,33 +4601,35 @@ _MBG_API_ATTR int _MBG_API mbg_set_serial( MBG_DEV_HANDLE dh, const PCPS_SERIAL
/*HDR*/
/**
- 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
- */
+ * @brief Read time zone/daylight saving configuration code from a device.
+ *
+ * The APIs using ::TZCODE are only supported by some simpler cards
+ * and allow just a very basic configuration.
+ *
+ * The API call ::mbg_chk_dev_has_tzcode checks whether
+ * this call is supported by a device.
+ *
+ * Other devices 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TZCODE structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_tzcode
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_get_gps_tzdl
+ */
_MBG_API_ATTR int _MBG_API mbg_get_tzcode( MBG_DEV_HANDLE dh, PCPS_TZCODE *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_TZCODE, IOCTL_GET_PCPS_TZCODE,
p, _pcps_ddev_has_tzcode( dh ) );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_tzcode
@@ -1850,33 +4637,35 @@ _MBG_API_ATTR int _MBG_API mbg_get_tzcode( MBG_DEV_HANDLE dh, PCPS_TZCODE *p )
/*HDR*/
/**
- 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
- */
+ * @brief Write time zone/daylight saving configuration code to a device.
+ *
+ * The APIs using ::TZCODE are only supported by some simpler cards
+ * and allow just a very basic configuration.
+ *
+ * The API call ::mbg_chk_dev_has_tzcode checks whether
+ * this call is supported by a device.
+ *
+ * Other devices 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TZCODE structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_tzcode
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_set_gps_tzdl
+ */
_MBG_API_ATTR int _MBG_API mbg_set_tzcode( MBG_DEV_HANDLE dh, const PCPS_TZCODE *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
// No endianess conversion required.
_mbgdevio_write_var_chk( dh, PCPS_SET_TZCODE, IOCTL_SET_PCPS_TZCODE,
p, _pcps_ddev_has_tzcode( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_tzcode
@@ -1884,31 +4673,35 @@ _MBG_API_ATTR int _MBG_API mbg_set_tzcode( MBG_DEV_HANDLE dh, const PCPS_TZCODE
/*HDR*/
/**
- 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
- */
+ * @brief Read time zone/daylight saving parameters from a device.
+ *
+ * This function fills up a ::PCPS_TZDL structure which supports a more
+ * detailed configuration of time zone and daylight saving than the ::TZCODE
+ * structure.
+ *
+ * The API call ::mbg_chk_dev_has_pcps_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * Other devices may support the ::mbg_get_tzcode or ::mbg_get_gps_tzdl
+ * calls instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TZDL structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_get_gps_tzdl
+ */
_MBG_API_ATTR int _MBG_API mbg_get_pcps_tzdl( MBG_DEV_HANDLE dh, PCPS_TZDL *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_PCPS_TZDL, IOCTL_GET_PCPS_TZDL,
p, _pcps_ddev_has_pcps_tzdl( dh ) );
_mbg_swab_pcps_tzdl( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_pcps_tzdl
@@ -1916,27 +4709,30 @@ _MBG_API_ATTR int _MBG_API mbg_get_pcps_tzdl( MBG_DEV_HANDLE dh, PCPS_TZDL *p )
/*HDR*/
/**
- 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
- */
+ * @brief Write time zone/daylight saving parameters to a device.
+ *
+ * This function passes a ::PCPS_TZDL structure to a device which supports
+ * a more detailed configuration of time zone and daylight saving than the
+ * ::TZCODE structure.
+ *
+ * The API call ::mbg_chk_dev_has_pcps_tzdl checks whether
+ * this call is supported by a device.
+ * Other cards may support the ::mbg_set_tzcode or ::mbg_set_gps_tzdl
+ * calls instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TZDL structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_set_gps_tzdl
+ */
_MBG_API_ATTR int _MBG_API mbg_set_pcps_tzdl( MBG_DEV_HANDLE dh, const PCPS_TZDL *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PCPS_TZDL tmp = *p;
_mbg_swab_pcps_tzdl( &tmp );
@@ -1944,7 +4740,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_pcps_tzdl( MBG_DEV_HANDLE dh, const PCPS_TZDL
#endif
_mbgdevio_write_var_chk( dh, PCPS_SET_PCPS_TZDL, IOCTL_SET_PCPS_TZDL,
p, _pcps_ddev_has_pcps_tzdl( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_pcps_tzdl
@@ -1952,27 +4748,30 @@ _MBG_API_ATTR int _MBG_API mbg_set_pcps_tzdl( MBG_DEV_HANDLE dh, const PCPS_TZDL
/*HDR*/
/**
- 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
- */
+ * @brief Read the %UTC offset configuration of the reference time from a device
+ *
+ * This parameter is used to specify the %UTC offset of an incoming
+ * reference time signal if a kind of time signal e.g. an IRIG input
+ * signal) does not provide this information.
+ *
+ * The API call ::mbg_chk_dev_has_ref_offs checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_REF_OFFS value to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ref_offs
+ * @see ::mbg_set_ref_offs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ref_offs( MBG_DEV_HANDLE dh, MBG_REF_OFFS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_REF_OFFS, IOCTL_GET_REF_OFFS,
p, _pcps_ddev_has_ref_offs( dh ) );
_mbg_swab_mbg_ref_offs( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ref_offs
@@ -1980,23 +4779,26 @@ _MBG_API_ATTR int _MBG_API mbg_get_ref_offs( MBG_DEV_HANDLE dh, MBG_REF_OFFS *p
/*HDR*/
/**
- 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
- */
+ * @brief Write the %UTC offset configuration of the reference time to a device.
+ *
+ * This parameter is used to specify the %UTC offset of an incoming
+ * reference time signal if a kind of time signal e.g. an IRIG input
+ * signal) does not provide this information.
+ *
+ * The API call ::mbg_chk_dev_has_ref_offs checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::MBG_REF_OFFS value to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ref_offs
+ * @see ::mbg_get_ref_offs
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ref_offs( MBG_DEV_HANDLE dh, const MBG_REF_OFFS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
MBG_REF_OFFS tmp = *p;
_mbg_swab_mbg_ref_offs( &tmp );
@@ -2004,7 +4806,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_ref_offs( MBG_DEV_HANDLE dh, const MBG_REF_OF
#endif
_mbgdevio_write_var_chk( dh, PCPS_SET_REF_OFFS, IOCTL_SET_REF_OFFS,
p, _pcps_ddev_has_ref_offs( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_ref_offs
@@ -2012,27 +4814,29 @@ _MBG_API_ATTR int _MBG_API mbg_set_ref_offs( MBG_DEV_HANDLE dh, const MBG_REF_OF
/*HDR*/
/**
- 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()
- */
+ * @brief 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 API call ::mbg_chk_dev_has_opt_flags checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_OPT_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_OPT_INFO, IOCTL_GET_MBG_OPT_INFO,
p, _pcps_ddev_has_opt_flags( dh ) );
_mbg_swab_mbg_opt_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_opt_info
@@ -2040,23 +4844,25 @@ _MBG_API_ATTR int _MBG_API mbg_get_opt_info( MBG_DEV_HANDLE dh, MBG_OPT_INFO *p
/*HDR*/
/**
- 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()
- */
+ * @brief Write a ::MBG_OPT_SETTINGS structure containing optional device settings.
+ *
+ * The API call ::mbg_chk_dev_has_opt_flags checks whether
+ * this call is supported by a device.
+ *
+ * ::mbg_get_opt_info should be called first to check which of
+ * the specified flags is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_OPT_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
MBG_OPT_SETTINGS tmp = *p;
_mbg_swab_mbg_opt_settings( &tmp );
@@ -2065,7 +4871,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_opt_settings( MBG_DEV_HANDLE dh, const MBG_OP
_mbgdevio_write_var_chk( dh, PCPS_SET_OPT_SETTINGS,
IOCTL_SET_MBG_OPT_SETTINGS, p,
_pcps_ddev_has_opt_flags( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_opt_settings
@@ -2073,29 +4879,34 @@ _MBG_API_ATTR int _MBG_API mbg_set_opt_settings( MBG_DEV_HANDLE dh, const MBG_OP
/*HDR*/
/**
- 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
- */
+ * @brief Read the current IRIG input settings plus capabilities
+ *
+ * @deprecated Calling this function directly is deprecated. The function
+ * ::mbg_get_all_irig_rx_info should be used instead which also reads some
+ * other associated parameters affecting the behaviour of the IRIG input.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] *p An ::IRIG_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_all_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_IRIG_RX_INFO, IOCTL_GET_PCPS_IRIG_RX_INFO,
p, _pcps_ddev_is_irig_rx( dh ) );
_mbg_swab_irig_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_irig_rx_info
@@ -2103,26 +4914,32 @@ _MBG_API_ATTR int _MBG_API mbg_get_irig_rx_info( MBG_DEV_HANDLE dh, IRIG_INFO *p
/*HDR*/
/**
- 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
- */
+ * @brief Write an ::IRIG_SETTINGS structure to a device to configure an IRIG input.
+ *
+ * @deprecated Calling this function directly is deprecated. The function
+ * ::mbg_save_all_irig_rx_settings should be used instead which also writes some
+ * other associated parameters affecting the behaviour of the IRIG input.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ * ::mbg_get_irig_rx_info should be called first to determine
+ * the possible settings supported by the device's IRIG input.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::IRIG_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_all_irig_rx_settings
+ * @see ::mbg_get_irig_rx_info
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
IRIG_SETTINGS tmp = *p;
_mbg_swab_irig_settings( &tmp );
@@ -2131,7 +4948,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_irig_rx_settings( MBG_DEV_HANDLE dh, const IR
_mbgdevio_write_var_chk( dh, PCPS_SET_IRIG_RX_SETTINGS,
IOCTL_SET_PCPS_IRIG_RX_SETTINGS, p,
_pcps_ddev_is_irig_rx( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_irig_rx_settings
@@ -2139,95 +4956,162 @@ _MBG_API_ATTR int _MBG_API mbg_set_irig_rx_settings( MBG_DEV_HANDLE dh, const IR
/*HDR*/
/**
- Check if a specific device supports the mbg_get_irig_ctrl_bits() call.
+ * @brief Read all IRIG input configuration information from a device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] pdev Pointer to the device's ::PCPS_DEV structure //### TODO Make this obsolete
+ * @param[in] p_irig_info Pointer to a ::IRIG_SETTINGS structure to be written
+ * @param[in] p_ref_offs Pointer to a ::MBG_REF_OFFS structure to be written
+ * @param[in] p_opt_info Pointer to a ::MBG_OPT_SETTINGS structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_all_irig_rx_settings
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_set_ref_offs
+ * @see ::mbg_set_opt_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_all_irig_rx_info( MBG_DEV_HANDLE dh,
+ const PCPS_DEV *pdev,
+ IRIG_INFO *p_irig_info,
+ MBG_REF_OFFS *p_ref_offs,
+ MBG_OPT_INFO *p_opt_info )
+{
+ int rc;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+ if ( !_pcps_is_irig_rx( pdev ) )
+ return MBG_ERR_NOT_SUPP_BY_DEV;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ rc = mbg_get_irig_rx_info( dh, p_irig_info );
- @see mbg_get_irig_ctrl_bits()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_irig_ctrl_bits, IOCTL_DEV_HAS_IRIG_CTRL_BITS, p );
+ if ( mbg_rc_is_success( rc ) && _pcps_has_ref_offs( pdev ) )
+ rc = mbg_get_ref_offs( dh, p_ref_offs );
-} // mbg_dev_has_irig_ctrl_bits
+ if ( mbg_rc_is_success( rc ) && _pcps_has_opt_flags( pdev ) )
+ rc = mbg_get_opt_info( dh, p_opt_info );
+
+ return rc;
+
+} // mbg_get_all_irig_rx_info
/*HDR*/
/**
- Read a ::MBG_IRIG_CTRL_BITS type which contains the control function
- bits of the latest IRIG input frame. Those bits may carry some
- well-known information, as in the IEEE1344 code, but may also contain
- some customized information, depending on the IRIG frame type and
- the configuration of the IRIG generator. So these bits are returned
- as-is and must be interpreted by the application.
- The macro _pcps_has_irig_ctrl_bits() or the API call mbg_dev_has_irig_ctrl_bits()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_IRIG_CTRL_BITS type to be filled up
+ * @brief Write all IRIG input configuration settings to a device.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ * ::mbg_get_all_irig_rx_info should be called before to determine
+ * the possible settings supported by the IRIG input.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] pdev Pointer to the device's ::PCPS_DEV structure //### TODO Make this obsolete
+ * @param[out] p_irig_settings Pointer to a ::IRIG_SETTINGS structure to be written
+ * @param[out] p_ref_offs Pointer to a ::MBG_REF_OFFS structure to be written
+ * @param[out] p_opt_settings Pointer to a ::MBG_OPT_SETTINGS structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_all_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_set_ref_offs
+ * @see ::mbg_set_opt_settings
+ */
+_MBG_API_ATTR int _MBG_API mbg_save_all_irig_rx_settings( MBG_DEV_HANDLE dh,
+ const PCPS_DEV *pdev,
+ const IRIG_SETTINGS *p_irig_settings,
+ const MBG_REF_OFFS *p_ref_offs,
+ const MBG_OPT_SETTINGS *p_opt_settings )
+{
+ int rc;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ if ( !_pcps_is_irig_rx( pdev ) )
+ return MBG_ERR_NOT_SUPP_BY_DEV;
- @see mbg_dev_has_irig_ctrl_bits()
-*/
-_MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh,
- MBG_IRIG_CTRL_BITS *p )
-{
- _mbgdevio_vars();
- rc = _mbgdevio_read_var( dh, PCPS_GET_IRIG_CTRL_BITS, IOCTL_GET_IRIG_CTRL_BITS, p );
- _mbg_swab_irig_ctrl_bits( p );
- return _mbgdevio_ret_val;
+ rc = mbg_set_irig_rx_settings( dh, p_irig_settings );
-} // mbg_get_irig_ctrl_bits
+ if ( mbg_rc_is_success( rc ) && _pcps_has_ref_offs( pdev ) )
+ rc = mbg_set_ref_offs( dh, p_ref_offs );
+ if ( mbg_rc_is_success( rc ) && _pcps_has_opt_flags( pdev ) )
+ rc = mbg_set_opt_settings( dh, p_opt_settings );
+ return rc;
-/*HDR*/
-/**
- Check if a specific device supports the mbg_get_raw_irig_data() call.
+} // mbg_save_all_irig_rx_settings
- @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_raw_irig_data()
- @see mbg_get_raw_irig_data_on_sec_change()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_raw_irig_data( MBG_DEV_HANDLE dh, int *p )
+/*HDR*/
+/**
+ * @brief Read the control function bits received from an incoming IRIG signal.
+ *
+ * This function fills an ::MBG_IRIG_CTRL_BITS structure with the control function
+ * bits decoded from the incoming IRIG signal.
+ *
+ * The meaning of these bits depends on the type of IRIG code frame format.
+ *
+ * In some IRIG formats these bits provide some well-known information which can
+ * also be evaluated by the device. For example, in IEEE 1344 or IEEE C37.118 code
+ * the control function bits are used to provide the year number, UTC offset,
+ * DST status, leap second warning, etc.
+ *
+ * For most IRIG code formats, however, these bits are reserved, i.e. not used
+ * at all, or application defined, depending on the configuration of the IRIG
+ * generator providing the IRIG signal.
+ *
+ * In the latter case the application has to evaluate the received control function
+ * bits and can use this function to retrieve these bits from the receiver device.
+ *
+ * The API call ::mbg_chk_dev_has_irig_ctrl_bits checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_IRIG_CTRL_BITS type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_irig_ctrl_bits
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh,
+ MBG_IRIG_CTRL_BITS *p )
{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_raw_irig_data, IOCTL_DEV_HAS_RAW_IRIG_DATA, p );
+ MBGDEVIO_RET_VAL rc;
+ rc = _mbgdevio_read_var( dh, PCPS_GET_IRIG_CTRL_BITS, IOCTL_GET_IRIG_CTRL_BITS, p );
+ _mbg_swab_irig_ctrl_bits( p );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_dev_has_raw_irig_data
+} // mbg_get_irig_ctrl_bits
/*HDR*/
/**
- Read a ::MBG_RAW_IRIG_DATA type which contains all data
- bits of the latest IRIG input frame.
- The macro _pcps_has_raw_irig_data() or the API call mbg_dev_has_raw_irig_data()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_raw_irig_data()
- @see mbg_get_raw_irig_data_on_sec_change()
-*/
+ * @brief Read raw IRIG data from an IRIG receiver.
+ *
+ * This function reads an ::MBG_RAW_IRIG_DATA structure with the raw data bits received
+ * from the incoming IRIG signal. This enables an application itself to decode the
+ * information provided by the IRIG signal.
+ *
+ * The API call ::mbg_chk_dev_has_raw_irig_data checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ * @see ::mbg_get_raw_irig_data_on_sec_change
+ */
_MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh,
MBG_RAW_IRIG_DATA *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, PCPS_GET_RAW_IRIG_DATA, IOCTL_GET_RAW_IRIG_DATA, p );
// No endianess conversion required.
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_raw_irig_data
@@ -2235,34 +5119,39 @@ _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Read a ::MBG_RAW_IRIG_DATA type just after a second change which contains all data
- bits of the latest IRIG input frame.
- The macro _pcps_has_raw_irig_data() or the API call mbg_dev_has_raw_irig_data()
- check whether this call is supported by a specific card.
-
- <b>Note:</b> The mbg_get_time_sec_change() function called by this function is
- supported under Windows only, so this function can also only be used under Windows.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_raw_irig_data()
- @see mbg_get_raw_irig_data()
-*/
+ * @brief Wait for second changeover then read raw IRIG data from an IRIG receiver.
+ *
+ * This function waits until the second of the device's on-board time rolls over,
+ * and then reads the last recent raw IRIG data from the device.
+ *
+ * The API call ::mbg_chk_dev_has_raw_irig_data checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> The ::mbg_get_time_sec_change function called
+ * by this function is supported under Windows only, so this function
+ * can also be used under Windows only.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ * @see ::mbg_get_raw_irig_data
+ * @see ::mbg_get_time_sec_change
+ */
_MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data_on_sec_change( MBG_DEV_HANDLE dh,
MBG_RAW_IRIG_DATA *p )
{
PCPS_TIME t;
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = mbg_get_time_sec_change( dh, &t );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
rc = mbg_get_raw_irig_data( dh, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_raw_irig_data_on_sec_change
@@ -2270,46 +5159,30 @@ _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data_on_sec_change( MBG_DEV_HANDLE d
/*HDR*/
/**
- Check if a specific device supports the mbg_get_irig_time() 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_irig_time()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_irig_time( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_irig_time, IOCTL_DEV_HAS_IRIG_TIME, p );
-
-} // mbg_dev_has_irig_time
-
-
-
-/*HDR*/
-/**
- Read a ::PCPS_IRIG_TIME type which returns the raw IRIG day-of-year number
- and time decoded from the latest IRIG input frame. If the configured IRIG code
- also contains the year number then the year number is also returned, otherwise
- the returned year number is 0xFF.
- The macro _pcps_has_irig_time() or the API call mbg_dev_has_irig_time()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_IRIG_TIME type to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_irig_time()
-*/
+ * @brief Read the IRIG time and day-of-year number from an IRIG receiver.
+ *
+ * Reads a ::PCPS_IRIG_TIME structure with the raw IRIG day-of-year number
+ * and time decoded from the latest IRIG input frame. If the configured IRIG code
+ * also contains the year number then the year number is also returned, otherwise
+ * the returned year number is 0xFF.
+ *
+ * The API call ::mbg_chk_dev_has_irig_time checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_IRIG_TIME type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_irig_time
+ */
_MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh,
PCPS_IRIG_TIME *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, PCPS_GIVE_IRIG_TIME, IOCTL_GET_IRIG_TIME, p );
_mbg_swab_pcps_irig_time( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_irig_time
@@ -2317,24 +5190,25 @@ _MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
- */
+ * @brief Clear a device's on-board time capture FIFO buffer.
+ *
+ * The API call ::mbg_chk_dev_can_clr_ucap_buff checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_write_cmd_chk( dh, PCPS_CLR_UCAP_BUFF, IOCTL_PCPS_CLR_UCAP_BUFF,
_pcps_ddev_can_clr_ucap_buff( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_clr_ucap_buff
@@ -2342,28 +5216,32 @@ _MBG_API_ATTR int _MBG_API mbg_clr_ucap_buff( MBG_DEV_HANDLE dh )
/*HDR*/
/**
- 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()
- */
+ * @brief Read information on a device's event capture buffer.
+ *
+ * Reads a ::PCPS_UCAP_ENTRIES structure with the number of user capture
+ * events actually stored in the FIFO buffer, and the maximum number of
+ * events that can be held by the buffer.
+ *
+ * The API call ::mbg_chk_dev_has_ucap checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_UCAP_ENTRIES structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GIVE_UCAP_ENTRIES,
IOCTL_GET_PCPS_UCAP_ENTRIES, p,
_pcps_ddev_has_ucap( dh ) );
_mbg_swab_pcps_ucap_entries( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ucap_entries
@@ -2371,35 +5249,38 @@ _MBG_API_ATTR int _MBG_API mbg_get_ucap_entries( MBG_DEV_HANDLE dh, PCPS_UCAP_EN
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve a single time capture event from the on-board FIFO buffer
+ *
+ * The capture event is returned in a ::PCPS_HR_TIME structure. The oldest entry
+ * in 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 API call ::mbg_chk_dev_has_ucap checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GIVE_UCAP_EVENT,
IOCTL_GET_PCPS_UCAP_EVENT, p,
_pcps_ddev_has_ucap( dh ) );
_mbg_swab_pcps_hr_time( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ucap_event
@@ -2407,32 +5288,35 @@ _MBG_API_ATTR int _MBG_API mbg_get_ucap_event( MBG_DEV_HANDLE dh, PCPS_HR_TIME *
/*HDR*/
/**
- 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
- */
+ * @brief Read the card's time zone/daylight saving parameters
+ *
+ * This function returns the time zone/daylight saving parameters
+ * in a ::TZDL structure.
+ *
+ * The API call ::mbg_chk_dev_has_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TZDL structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_TZDL, IOCTL_GET_GPS_TZDL, p );
_mbg_swab_tzdl( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_tzdl
@@ -2440,36 +5324,39 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_tzdl( MBG_DEV_HANDLE dh, TZDL *p )
/*HDR*/
/**
- 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
- */
+ * @brief Write the card's time zone/daylight saving parameters.
+ *
+ * This function writes the time zone/daylight saving parameters
+ * in a ::TZDL structure to a device.
+ *
+ * The API call ::mbg_chk_dev_has_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TZDL structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
TZDL tmp = *p;
_mbg_swab_tzdl( &tmp );
p = &tmp;
#endif
rc = _mbgdevio_write_gps_var( dh, PC_GPS_TZDL, IOCTL_SET_GPS_TZDL, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_tzdl
@@ -2477,29 +5364,33 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_tzdl( MBG_DEV_HANDLE dh, const TZDL *p )
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve the software revision of a GPS receiver
+ *
+ * @deprecated This function is deprecated.
+ *
+ * This function is deprecated, but still supported
+ * for compatibility with older GPS cards. Normally
+ * the software revision is part of the ::RECEIVER_INFO
+ * structure. See ::mbg_setup_receiver_info which takes
+ * care of the different options.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SW_REV structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_chk_dev_is_gps
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_sw_rev( MBG_DEV_HANDLE dh, SW_REV *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_SW_REV, IOCTL_GET_GPS_SW_REV, p );
_mbg_swab_sw_rev( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_sw_rev
@@ -2507,23 +5398,37 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_sw_rev( MBG_DEV_HANDLE dh, SW_REV *p )
/*HDR*/
/**
- 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.
-*/
+ * @brief Retrieve the status of the battery buffered GPS variables.
+ *
+ * GPS receivers require some navigational data set to be available
+ * to be able to decode position and time accurately. This data set
+ * is transmitted periodically by the satellites, so it can
+ * simply be collected if it's not available.
+ *
+ * The ::BVAR_STAT type reports which parts of the data set are
+ * available in the receiver, and which are not.
+ *
+ * If the available data set is not complete then the receiver
+ * stays in COLD BOOT mode until all data have been received
+ * and thus all data sets are valid.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::BVAR_STAT structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_is_gps
+ * @see ::BVAR_FLAGS
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_bvar_stat( MBG_DEV_HANDLE dh, BVAR_STAT *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_BVAR_STAT, IOCTL_GET_GPS_BVAR_STAT, p );
_mbg_swab_bvar_stat( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_stat
@@ -2531,24 +5436,28 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_bvar_stat( MBG_DEV_HANDLE dh, BVAR_STAT *
/*HDR*/
/**
- 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.
-*/
+ * @brief Read the current board time using a ::TTM structure
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This API call is pretty slow, so ::mbg_get_hr_time or
+ * ::mbg_get_fast_hr_timestamp or associated calls should be used preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TTM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_fast_hr_timestamp
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_time( MBG_DEV_HANDLE dh, TTM *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_TIME, IOCTL_GET_GPS_TIME, p );
_mbg_swab_ttm( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_time
@@ -2556,26 +5465,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_time( MBG_DEV_HANDLE dh, TTM *p )
/*HDR*/
/**
- 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.
-*/
+ * @brief Set the time on a GPS receiver device
+ *
+ * Write a ::TTM structure to a GPS receiver in order to set
+ * the on-board date and time. Date and time must be local time
+ * according to the device's on-board time zone configuration
+ * (::TZDL).
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TTM structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_MBG_API_ATTR int _MBG_API mbg_set_gps_time( MBG_DEV_HANDLE dh, const TTM *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
TTM tmp = *p;
_mbg_swab_ttm( &tmp );
p = &tmp;
#endif
rc = _mbgdevio_write_gps_var( dh, PC_GPS_TIME, IOCTL_SET_GPS_TIME, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_time
@@ -2583,29 +5497,31 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_time( MBG_DEV_HANDLE dh, const TTM *p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Read a ::PORT_PARM structure with a device's serial port configuration.
+ *
+ * @deprecated This function is deprecated, use ::mbg_get_serial_settings preferably.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This function is deprecated since it is only
+ * supported by a certain class of devices and can handle only
+ * up to 2 serial ports. The generic function ::mbg_get_serial_settings
+ * should be used instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PORT_PARM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_port_parm( MBG_DEV_HANDLE dh, PORT_PARM *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_PORT_PARM, IOCTL_GET_GPS_PORT_PARM, p );
_mbg_swab_port_parm( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_port_parm
@@ -2613,33 +5529,35 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_port_parm( MBG_DEV_HANDLE dh, PORT_PARM *
/*HDR*/
/**
- 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()
-*/
+ * @brief Write a ::PORT_PARM structure to configure the on-board serial ports.
+ *
+ * @deprecated This function is deprecated, use ::mbg_save_serial_settings preferably.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This function is deprecated 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_PARM structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_set_gps_port_parm( MBG_DEV_HANDLE dh, const PORT_PARM *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PORT_PARM tmp = *p;
_mbg_swab_port_parm( &tmp );
p = &tmp;
#endif
rc = _mbgdevio_write_gps_var( dh, PC_GPS_PORT_PARM, IOCTL_SET_GPS_PORT_PARM, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_port_parm
@@ -2647,25 +5565,28 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_parm( MBG_DEV_HANDLE dh, const PORT_
/*HDR*/
/**
- 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.
-*/
+ * @brief Read an ::ANT_INFO structure to retrieve an extended GPS antenna status.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> Normally the current antenna connection status can also be
+ * determined by evaluation of the ::PCPS_TIME::signal or ::PCPS_HR_TIME::signal
+ * fields. The "disconnected" status reported by ::ANT_INFO disappears only if
+ * the antenna has been reconnected <b>and</b> the receiver has synchronized
+ * to the GPS satellites again.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::ANT_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_ant_info( MBG_DEV_HANDLE dh, ANT_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_ANT_INFO, IOCTL_GET_GPS_ANT_INFO, p );
_mbg_swab_ant_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_ant_info
@@ -2673,30 +5594,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_ant_info( MBG_DEV_HANDLE dh, ANT_INFO *p
/*HDR*/
/**
- 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()
-*/
+ * @brief Read a time capture event from the on-board FIFO buffer using a ::TTM structure
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <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 device. Anyway, this call is still supported for compatibility
+ * with older devices which don't support ::mbg_get_ucap_event.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TTM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_UCAP, IOCTL_GET_GPS_UCAP, p );
_mbg_swab_ttm( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_ucap
@@ -2704,30 +5626,35 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_ucap( MBG_DEV_HANDLE dh, TTM *p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the ::ENABLE_FLAGS structure controlling when outputs are to be enabled
+ *
+ * The ::ENABLE_FLAGS structure controls whether certain signal outputs
+ * are to be enabled immediately after the device's power-up, or only
+ * after the device has synchronized to its input signal.
+ *
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Not all of the input signals specified for the
+ * ::ENABLE_FLAGS structure can be modified individually.
+ * See ::ENABLE_FLAGS_CODES.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::ENABLE_FLAGS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::ENABLE_FLAGS
+ * @see ::ENABLE_FLAGS_CODES
+ * @see ::mbg_set_gps_enable_flags
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_enable_flags( MBG_DEV_HANDLE dh, ENABLE_FLAGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_ENABLE_FLAGS,
IOCTL_GET_GPS_ENABLE_FLAGS, p );
_mbg_swab_enable_flags( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_enable_flags
@@ -2735,27 +5662,32 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_enable_flags( MBG_DEV_HANDLE dh, ENABLE_F
/*HDR*/
/**
- 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()
-*/
+ * @brief Write an ;;ENABLE_FLAGS structure to configure when outputs shall be enabled.
+ *
+ * The ::ENABLE_FLAGS structure controls whether certain signal outputs
+ * are to be enabled immediately after the device's power-up, or only
+ * after the device has synchronized to its input signal.
+ *
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Not all of the input signals specified for the
+ * ::ENABLE_FLAGS structure can be modified individually.
+ * See ::ENABLE_FLAGS_CODES.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ENABLE_FLAGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::ENABLE_FLAGS
+ * @see ::ENABLE_FLAGS_CODES
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
ENABLE_FLAGS tmp = *p;
_mbg_swab_enable_flags( &tmp );
@@ -2763,7 +5695,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_enable_flags( MBG_DEV_HANDLE dh,
#endif
rc = _mbgdevio_write_gps_var( dh, PC_GPS_ENABLE_FLAGS,
IOCTL_SET_GPS_ENABLE_FLAGS, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_enable_flags
@@ -2771,25 +5703,27 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_enable_flags( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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
-*/
+ * @brief Read the extended GPS receiver status from a device.
+ *
+ * The ::STAT_INFO structure reports the status of the GPS receiver,
+ * including mode of operation and number of visible/usable satellites.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::STAT_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::STAT_INFO
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_stat_info( MBG_DEV_HANDLE dh, STAT_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_STAT_INFO, IOCTL_GET_GPS_STAT_INFO, p );
_mbg_swab_stat_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_stat_info
@@ -2797,53 +5731,59 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_stat_info( MBG_DEV_HANDLE dh, STAT_INFO *
/*HDR*/
/**
- 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
-*/
+ * @brief Send one of the ::PC_GPS_COMMANDS to a GPS receiver device
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::GPS_CMD
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::PC_GPS_COMMANDS
+ */
_MBG_API_ATTR int _MBG_API mbg_set_gps_cmd( MBG_DEV_HANDLE dh, const GPS_CMD *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
GPS_CMD tmp = *p;
_mbg_swab_gps_cmd( &tmp );
p = &tmp;
#endif
rc = _mbgdevio_write_gps_var( dh, PC_GPS_CMD, IOCTL_SET_GPS_CMD, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_cmd
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the current geographic position from a GPS device.
+ *
+ * The returned ::POS structure contains the current position in
+ * ECEF (Earth Centered, Earth Fixed) kartesian coordinates, and in
+ * geographic coordinates with different formats, using the WGS84
+ * geographic datum.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::POS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_gps_var( dh, PC_GPS_POS, IOCTL_GET_GPS_POS, p );
swap_pos_doubles( p );
_mbg_swab_pos( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_pos
@@ -2851,22 +5791,25 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_pos( MBG_DEV_HANDLE dh, POS *p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Set the GPS receiver position using ::XYZ coordinates
+ *
+ * The structure ::XYZ must specify the new position in ECEF
+ * (Earth Centered, Earth Fixed) kartesian coordinates.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Position in ::XYZ format to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
XYZ xyz;
int i;
@@ -2877,8 +5820,11 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_xyz( MBG_DEV_HANDLE dh, const XYZ p )
_mbg_swab_double( &xyz[i] );
}
- rc = _mbgdevio_write_gps_var( dh, PC_GPS_POS_XYZ, IOCTL_SET_GPS_POS_XYZ, xyz );
- return _mbgdevio_ret_val;
+ // _mbgdevio_write_gps_var() would fail here since
+ // XYZ is an array, not a structure.
+ rc = _mbgdevio_write_gps( dh, PC_GPS_POS_XYZ, IOCTL_SET_GPS_POS_XYZ,
+ xyz, sizeof( XYZ ) );
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_pos_xyz
@@ -2886,22 +5832,25 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_xyz( MBG_DEV_HANDLE dh, const XYZ p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Set the GPS receiver position using ::LLA coordinates
+ *
+ * The structure ::LLA must specify the new position as longitude,
+ * latitude, and altitude, using the WGS84 geographic datum.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Position in ::LLA format to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
LLA lla;
int i;
@@ -2912,8 +5861,11 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_lla( MBG_DEV_HANDLE dh, const LLA p )
_mbg_swab_double( &lla[i] );
}
- rc = _mbgdevio_write_gps_var( dh, PC_GPS_POS_LLA, IOCTL_SET_GPS_POS_LLA, lla );
- return _mbgdevio_ret_val;
+ // _mbgdevio_write_gps_var() would fail here since
+ // LLA is an array, not a structure.
+ rc = _mbgdevio_write_gps( dh, PC_GPS_POS_LLA, IOCTL_SET_GPS_POS_LLA, lla, sizeof( LLA ) );
+
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_pos_lla
@@ -2921,27 +5873,31 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pos_lla( MBG_DEV_HANDLE dh, const LLA p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the configured antenna cable length from a device
+ *
+ * The antenna cable length parameter is used by GPS/GNSS receivers
+ * to compensate the propagation delay of the RF signal over the antenna
+ * cable, which is about 5 ns/m.
+ *
+ * The API call ::mbg_chk_dev_has_cab_len checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::ANT_CABLE_LEN structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_ANT_CABLE_LEN,
IOCTL_GET_GPS_ANT_CABLE_LEN, p,
_pcps_ddev_has_cab_len( dh ) );
_mbg_swab_ant_cable_len( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_ant_cable_len
@@ -2949,23 +5905,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_ant_cable_len( MBG_DEV_HANDLE dh, ANT_CAB
/*HDR*/
/**
- 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()
-*/
+ * @brief Write the GPS antenna cable length configuration to a device.
+ *
+ * The antenna cable length parameter is used by GPS/GNSS receivers
+ * to compensate the propagation delay of the RF signal over the antenna
+ * cable, which is about 5 ns/m.
+ *
+ * The API call ::mbg_chk_dev_has_cab_len checks whether
+ * this call is supported by a device.
+ *
+ * @note Different devices may accept different maximum values, so the
+ * written value should be re-read using ::mbg_get_gps_ant_cable_len
+ * to check if the parameter has been accepted.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::ANT_CABLE_LEN structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
ANT_CABLE_LEN tmp = *p;
_mbg_swab_ant_cable_len( &tmp );
@@ -2974,7 +5938,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_ant_cable_len( MBG_DEV_HANDLE dh,
_mbgdevio_write_gps_var_chk( dh, PC_GPS_ANT_CABLE_LEN,
IOCTL_SET_GPS_ANT_CABLE_LEN, p,
_pcps_ddev_has_cab_len( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_ant_cable_len
@@ -2982,30 +5946,32 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_ant_cable_len( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the ::RECEIVER_INFO structure from a device
+ *
+ * The API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Applications should call ::mbg_setup_receiver_info
+ * preferably, which also sets up a basic ::RECEIVER_INFO structure
+ * for devices which don't provide that structure by themselves.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::RECEIVER_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_chk_dev_has_receiver_info
+ */
_MBG_API_ATTR int _MBG_API mbg_get_gps_receiver_info( MBG_DEV_HANDLE dh, RECEIVER_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_RECEIVER_INFO,
IOCTL_GET_GPS_RECEIVER_INFO, p,
_pcps_ddev_has_receiver_info( dh ) );
_mbg_swab_receiver_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_receiver_info
@@ -3013,30 +5979,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_receiver_info( MBG_DEV_HANDLE dh, RECEIVE
#if !MBGDEVIO_SIMPLE
-static /*HDR*/
-/* (Intentionally excluded from Doxygen)
- Read a ::STR_TYPE_INFO_IDX array of supported string types.
- The function mbg_setup_receiver_info() must have been called before,
- and the returned ::RECEIVER_INFO structure passed to this function.
-
- <b>Note:</b> The function mbg_get_serial_settings() should be used preferably
- to get retrieve the cuurrent port settings and configuration options.
-
- @param dh Valid handle to a Meinberg device.
- @param stii Pointer to a an array of string type information 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_setup_receiver_info()
- @see mbg_get_gps_all_port_info()
- @see mbg_get_serial_settings()
-*/
-int _MBG_API mbg_get_gps_all_str_type_info( MBG_DEV_HANDLE dh,
- STR_TYPE_INFO_IDX stii[],
- const RECEIVER_INFO *p_ri )
+/*HDR*/
+/**
+ * @brief Read a ::STR_TYPE_INFO_IDX array of supported string types.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be passed to this function.
+ *
+ * <b>Note:</b> The function ::mbg_get_serial_settings should be used preferably
+ * to get retrieve the current port settings and configuration options.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] stii Pointer to a an array of string type information to be filled up.
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ * @see ::mbg_get_gps_all_port_info
+ * @see ::mbg_setup_receiver_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_str_type_info( MBG_DEV_HANDLE dh,
+ STR_TYPE_INFO_IDX stii[],
+ const RECEIVER_INFO *p_ri )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if _MBG_SUPP_VAR_ACC_SIZE
_mbgdevio_read_gps_chk( dh, PC_GPS_ALL_STR_TYPE_INFO,
@@ -3051,11 +6018,11 @@ int _MBG_API mbg_get_gps_all_str_type_info( MBG_DEV_HANDLE dh,
rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_STR_TYPE_INFO, stii,
p_ri->n_str_type * sizeof( stii[0] ) );
else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
#endif
#if defined( MBG_ARCH_BIG_ENDIAN )
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
int i;
for ( i = 0; i < p_ri->n_str_type; i++ )
@@ -3066,36 +6033,37 @@ int _MBG_API mbg_get_gps_all_str_type_info( MBG_DEV_HANDLE dh,
}
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_all_str_type_info
-static /*HDR*/
-/* (Intentionally excluded from Doxygen)
- Read a ::PORT_INFO_IDX array of supported serial port configurations.
- The function mbg_setup_receiver_info() must have been called before,
- and the returned ::RECEIVER_INFO structure passed to this function.
-
- <b>Note:</b> The function mbg_get_serial_settings() should be used preferably
- to get retrieve the cuurrent port settings and configuration options.
-
- @param dh Valid handle to a Meinberg device.
- @param pii Pointer to a an array of port configuration information 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_setup_receiver_info()
- @see mbg_get_gps_all_str_type_info()
- @see mbg_get_serial_settings()
-*/
-int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh,
- PORT_INFO_IDX pii[],
- const RECEIVER_INFO *p_ri )
+/*HDR*/
+/**
+ * @brief Read a ::PORT_INFO_IDX array of supported serial port configurations.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be passed to this function.
+ *
+ * <b>Note:</b> The function ::mbg_get_serial_settings should be used preferably
+ * to get retrieve the current port settings and configuration options.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of port configuration information to be filled up.
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ * @see ::mbg_get_gps_all_str_type_info
+ * @see ::mbg_setup_receiver_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh,
+ PORT_INFO_IDX pii[],
+ const RECEIVER_INFO *p_ri )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if _MBG_SUPP_VAR_ACC_SIZE
_mbgdevio_read_gps_chk( dh, PC_GPS_ALL_PORT_INFO,
@@ -3110,11 +6078,11 @@ int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh,
rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_PORT_INFO, pii,
p_ri->n_com_ports * sizeof( pii[0] ) );
else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
#endif
#if defined( MBG_ARCH_BIG_ENDIAN )
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
int i;
for ( i = 0; i < p_ri->n_com_ports; i++ )
@@ -3125,7 +6093,7 @@ int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh,
}
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_all_port_info
@@ -3133,28 +6101,31 @@ int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Write the configuration for a single serial port to a device.
+ *
+ * The ::PORT_SETTINGS_IDX structure 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 API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> The function ::mbg_save_serial_settings should be used preferably
+ * to write new port configuration to the board.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_SETTINGS_IDX structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ * @see ::mbg_set_gps_port_settings
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PORT_SETTINGS_IDX tmp = *p;
_mbg_swab_port_settings_idx( &tmp );
@@ -3163,7 +6134,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_settings_idx( MBG_DEV_HANDLE dh,
_mbgdevio_write_gps_var_chk( dh, PC_GPS_PORT_SETTINGS_IDX,
IOCTL_SET_GPS_PORT_SETTINGS_IDX, p,
_pcps_ddev_has_receiver_info( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_port_settings_idx
@@ -3171,25 +6142,28 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_settings_idx( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Write the configuration for a single serial port to a device.
+ *
+ * The ::PORT_SETTINGS structure does not contain the port index, so the
+ * the port index must be given separately. Except for the parameter types
+ * this call is equivalent to ::mbg_set_gps_port_settings_idx.
+ *
+ * The API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> The function ::mbg_save_serial_settings should be used preferably
+ * to write new port configuration to the board.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_SETTINGS structure to be written.
+ * @param[in] idx Index of the serial port to be configured (starting from 0).
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ * @see ::mbg_set_gps_port_settings_idx
+ * @see ::mbg_chk_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 )
{
@@ -3209,54 +6183,73 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_port_settings( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief 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.
+ *
+ * Optionally, the function ::mbg_get_device_info may have been called
+ * before, and the returned ::PCPS_DEV structure can be passed to this
+ * function.
+ *
+ * If a NULL pointer is passed instead, the device info is retrieved
+ * directly from the device, using the device handle.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p_dev Optional pointer to a ::PCPS_DEV structure, may be NULL.
+ * @param[out] p Pointer to a ::RECEIVER_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_device_info
+ * @see ::mbg_chk_dev_has_receiver_info
+ */
_MBG_API_ATTR int _MBG_API mbg_setup_receiver_info( MBG_DEV_HANDLE dh,
- const PCPS_DEV *pdev,
+ const PCPS_DEV *p_dev,
RECEIVER_INFO *p )
{
+ PCPS_DEV dev = { { 0 } };
+ int rc;
+
+ if ( p_dev == NULL )
+ {
+ rc = mbg_get_device_info( dh, &dev );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+ p_dev = &dev;
+ }
+
// If the clock supports the receiver_info structure then
// read it from the clock, otherwise set up some default
// values depending on the clock type.
- if ( _pcps_has_receiver_info( pdev ) )
+ if ( _pcps_has_receiver_info( p_dev ) )
{
- int rc = mbg_get_gps_receiver_info( dh, p );
+ rc = mbg_get_gps_receiver_info( dh, p );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
return rc;
goto check;
}
- if ( _pcps_is_gps( pdev ) )
+ if ( _pcps_is_gps( p_dev ) )
_setup_default_receiver_info_gps( p );
else
- _setup_default_receiver_info_dcf( p, pdev );
+ _setup_default_receiver_info_dcf( p, p_dev );
check:
// Make sure this program supports at least as many ports as
// the current clock device.
if ( p->n_com_ports > MAX_PARM_PORT )
- return _mbg_err_to_os( MBG_ERR_N_COM_EXCEEDS_SUPP );
+ return MBG_ERR_N_COM_EXCEEDS_SUPP;
// Make sure this program supports at least as many string types
// as the current clock device.
if ( p->n_str_type > MAX_PARM_STR_TYPE )
- return _mbg_err_to_os( MBG_ERR_N_STR_EXCEEDS_SUPP );
+ return MBG_ERR_N_STR_EXCEEDS_SUPP;
return MBG_SUCCESS;
@@ -3265,199 +6258,29 @@ check:
-#if !MBGDEVIO_SIMPLE
-
-// The functions below can conditionally be excluded from build
-// for simple applications which don't do complex card configuration.
-// This reduces the number of modules needed to be linked to the
-// application.
-
/*HDR*/
/**
- 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 )
-{
- int rc;
- int i;
-
- memset( pcfg, 0, sizeof( *pcfg ) );
-
- if ( _pcps_has_receiver_info( pdev ) )
- {
- rc = mbg_get_gps_all_port_info( dh, pcfg->pii, p_ri );
- if ( rc != MBG_SUCCESS )
- goto error;
-
- rc = mbg_get_gps_all_str_type_info( dh, pcfg->stii, p_ri );
- if ( rc != MBG_SUCCESS )
- goto error;
- }
- else
- {
- if ( _pcps_is_gps( pdev ) )
- {
- rc = mbg_get_gps_port_parm( dh, &pcfg->tmp_pp );
- if ( rc != MBG_SUCCESS )
- goto error;
-
- for ( i = 0; i < p_ri->n_com_ports; i++ )
- {
- PORT_INFO_IDX *p_pii = &pcfg->pii[i];
- PORT_INFO *p_pi = &p_pii->port_info;
-
- p_pii->idx = i;
- port_settings_from_port_parm( &p_pi->port_settings,
- i, &pcfg->tmp_pp, 1 );
-
- p_pi->supp_baud_rates = DEFAULT_GPS_BAUD_RATES_C166;
- p_pi->supp_framings = DEFAULT_GPS_FRAMINGS_C166;
- p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_GPS;
- }
- }
- else
- if ( _pcps_has_serial ( pdev ) ) // Not all non-GPS clocks have a serial port!
- {
- PCPS_SERIAL ser_code;
-
- rc = mbg_get_serial( dh, &ser_code );
- if ( rc != MBG_SUCCESS )
- goto error;
-
-
- port_info_from_pcps_serial( pcfg->pii, ser_code,
- _pcps_has_serial_hs( pdev ) ?
- DEFAULT_BAUD_RATES_DCF_HS :
- DEFAULT_BAUD_RATES_DCF
- );
- }
-
- for ( i = 0; i < p_ri->n_str_type; i++ )
- {
- STR_TYPE_INFO_IDX *stip = &pcfg->stii[i];
- stip->idx = i;
- stip->str_type_info = default_str_type_info[i];
- }
- }
-
- return MBG_SUCCESS;
-
-
-error:
- return rc;
-
-} // mbg_get_serial_settings
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- int rc;
-
- if ( _pcps_has_receiver_info( pdev ) )
- {
- rc = mbg_set_gps_port_settings( dh, &pcfg->pii[port_num].port_info.port_settings, port_num );
- }
- else
- {
- if ( _pcps_is_gps( pdev ) )
- {
- port_parm_from_port_settings( &pcfg->tmp_pp, port_num,
- &pcfg->pii[port_num].port_info.port_settings, 1 );
-
- rc = mbg_set_gps_port_parm( dh, &pcfg->tmp_pp );
- }
- else
- {
- PCPS_SERIAL ser_code;
-
- pcps_serial_from_port_info( &ser_code, pcfg->pii );
-
- rc = mbg_set_serial( dh, &ser_code );
- }
- }
-
- return rc;
-
-} // mbg_save_serial_settings
-
-#endif // !MBGDEVIO_SIMPLE
-
-
-
-/*HDR*/
-/**
- 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()
-*/
+ * @brief Read the version code of the on-board PCI/PCIe interface ASIC.
+ *
+ * The API call ::mbg_chk_dev_has_asic_version checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCI_ASIC_VERSION type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_asic_version
+ */
_MBG_API_ATTR int _MBG_API mbg_get_asic_version( MBG_DEV_HANDLE dh, PCI_ASIC_VERSION *p )
{
-
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCI_ASIC_VERSION, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
if ( !_pcps_ddev_has_asic_version( dh ) )
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
*p = _mbg_inp32_to_cpu( dh, 0, _pcps_ddev_io_base_mapped( dh, 0 )
+ offsetof( PCI_ASIC, raw_version ) );
@@ -3471,30 +6294,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_asic_version( MBG_DEV_HANDLE dh, PCI_ASIC_VER
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the features of the on-board PCI/PCIe interface ASIC
+ *
+ * The API call ::mbg_chk_dev_has_asic_features checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCI_ASIC_FEATURES type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_asic_features
+ */
_MBG_API_ATTR int _MBG_API mbg_get_asic_features( MBG_DEV_HANDLE dh,
PCI_ASIC_FEATURES *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_PCI_ASIC_FEATURES, p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
if ( !_pcps_ddev_has_asic_features( dh ) )
{
*p = 0;
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
}
*p = _mbg_inp32_to_cpu( dh, 0, _pcps_ddev_io_base_mapped( dh, 0 )
@@ -3509,52 +6333,32 @@ _MBG_API_ATTR int _MBG_API mbg_get_asic_features( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Check if a specific device supports configurable time scales.
-
- By default the cards return UTC and/or local time. However, some cards
- can be configured to return pure GPS time or TAI instead.
-
- @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_time_scale_info()
- @see mbg_set_time_scale_settings()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_time_scale( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_time_scale, IOCTL_DEV_HAS_GPS_TIME_SCALE, p );
-
-} // mbg_dev_has_time_scale
-
-
-
-/*HDR*/
-/**
- Read a ::MBG_TIME_SCALE_INFO structure from a card telling which time scales
- are supported by a card, and the current settings of the card.
-
- The macro _pcps_has_time_scale() or the API call mbg_dev_has_time_scale()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_time_scale().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_SCALE_INFO structure to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_set_time_scale_settings()
- @see mbg_dev_has_time_scale()
-*/
+ * @brief Read the current time scale settings and which time scales are supported
+ *
+ * The ::MBG_TIME_SCALE_INFO structure tells which time scale settings are supported
+ * by a device, and which time scale is currently configured.
+ *
+ * The API call ::mbg_chk_dev_has_time_scale checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_time_scale.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_SCALE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_time_scale_settings
+ * @see ::mbg_chk_dev_has_time_scale
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_scale_info( MBG_DEV_HANDLE dh, MBG_TIME_SCALE_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_TIME_SCALE,
IOCTL_GET_GPS_TIME_SCALE_INFO, p,
_pcps_ddev_has_time_scale( dh ) );
_mbg_swab_mbg_time_scale_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_time_scale_info
@@ -3562,27 +6366,30 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_scale_info( MBG_DEV_HANDLE dh, MBG_TIME_
/*HDR*/
/**
- Write a ::MBG_TIME_SCALE_SETTINGS structure to a card which determines
- which time scale shall be represented by time stamps read from the card.
-
- The macro _pcps_has_time_scale() or the API call mbg_dev_has_time_scale()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_time_scale().
-
- The function mbg_get_time_scale_info() should have been called before
- in order to determine which time scales are supported by the card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_SCALE_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_get_time_scale_info()
- @see mbg_dev_has_time_scale()
-*/
-_MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, MBG_TIME_SCALE_SETTINGS *p )
+ * @brief Write the time scale configuration to a device
+ *
+ * The ::MBG_TIME_SCALE_SETTINGS structure determines which time scale
+ * is to be used for the time stamps which can be read from a device.
+ *
+ * The API call ::mbg_chk_dev_has_time_scale checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_time_scale.
+ *
+ * The function ::mbg_get_time_scale_info should have been called before
+ * in order to determine which time scales are supported by the card.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::MBG_TIME_SCALE_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time_scale_info
+ * @see ::mbg_chk_dev_has_time_scale
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, const MBG_TIME_SCALE_SETTINGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
MBG_TIME_SCALE_SETTINGS tmp = *p;
_mbg_swab_mbg_time_scale_settings( &tmp );
@@ -3591,7 +6398,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, MBG_T
_mbgdevio_write_gps_var_chk( dh, PC_GPS_TIME_SCALE,
IOCTL_SET_GPS_TIME_SCALE_SETTINGS, p,
_pcps_ddev_has_time_scale( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_time_scale_settings
@@ -3599,59 +6406,31 @@ _MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, MBG_T
/*HDR*/
/**
- Check if a specific device supports reading/writing a GPS UTC parameter
- set via the PC bus (reading/writing these parameters via the serial port
- is supported by all GPS devices).
-
- The UTC parameters are normally received from the satellites' broadcasts
- and contain the current time offset between GPT time and UTC, plus information
- on a pending leap second.
-
- It may be useful to overwrite them to do some tests, or for applications
- where a card is freewheeling.
-
- @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_utc_parm()
- @see mbg_set_utc_parm()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_utc_parm( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_utc_parm, IOCTL_DEV_HAS_GPS_UTC_PARM, p );
-
-} // mbg_dev_has_utc_parm
-
-
-
-/*HDR*/
-/**
- Read a ::UTC structure from a card.
-
- The macro _pcps_has_utc_parm() or the API call mbg_dev_has_utc_parm()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_utc_parm().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::UTC structure to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_utc_parm()
- @see mbg_set_utc_parm()
-*/
+ * @brief Read a ::UTC parameter structure from a device
+ *
+ * The API call ::mbg_chk_dev_has_utc_parm checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_utc_parm.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::UTC structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_utc_parm
+ * @see ::mbg_set_utc_parm
+ */
_MBG_API_ATTR int _MBG_API mbg_get_utc_parm( MBG_DEV_HANDLE dh, UTC *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_UTC,
IOCTL_GET_GPS_UTC_PARM, p,
_pcps_ddev_has_utc_parm( dh ) );
_mbg_swab_utc_parm( p );
swap_double( &p->A0 );
swap_double( &p->A1 );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_utc_parm
@@ -3659,39 +6438,44 @@ _MBG_API_ATTR int _MBG_API mbg_get_utc_parm( MBG_DEV_HANDLE dh, UTC *p )
/*HDR*/
/**
- Write a ::UTC structure to a card.
-
- This should only be done for testing, or if a card is operated in
- freewheeling mode. If the card receives any satellites the settings
- written to the board are overwritten by the parameters broadcasted
- by the satellites.
-
- The macro _pcps_has_utc_parm() or the API call mbg_dev_has_utc_parm()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_utc_parm().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a valid ::UTC structure to be written
+ * @brief Write a ::UTC parameter structure to a device.
+ *
+ * This should only be done for testing, or if a card is operated in
+ * freewheeling mode. If the receiver is tracking any satellites then the settings
+ * written to the device are overwritten by the parameters broadcast
+ * by the satellites.
+ *
+ * The API call ::mbg_chk_dev_has_utc_parm checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for mbg_chk_dev_has_utc_parm.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a valid ::UTC structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_utc_parm
+ * @see ::mbg_get_utc_parm
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_utc_parm( MBG_DEV_HANDLE dh, const UTC *p )
+{
+ MBGDEVIO_RET_VAL rc;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ // the original parameters need to be modified anyway, so always use a copy
+ UTC tmp = *p;
- @see mbg_dev_has_utc_parm()
- @see mbg_get_utc_parm()
-*/
-_MBG_API_ATTR int _MBG_API mbg_set_utc_parm( MBG_DEV_HANDLE dh, UTC *p )
-{
- _mbgdevio_vars();
#if defined( MBG_ARCH_BIG_ENDIAN )
- UTC tmp = *p;
_mbg_swab_utc_parm( &tmp );
- p = &tmp;
#endif
- swap_double( &p->A0 );
- swap_double( &p->A1 );
+
+ swap_double( &tmp.A0 );
+ swap_double( &tmp.A1 );
+
_mbgdevio_write_gps_var_chk( dh, PC_GPS_UTC,
- IOCTL_SET_GPS_UTC_PARM, p,
+ IOCTL_SET_GPS_UTC_PARM, &tmp,
_pcps_ddev_has_utc_parm( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_utc_parm
@@ -3699,37 +6483,40 @@ _MBG_API_ATTR int _MBG_API mbg_set_utc_parm( MBG_DEV_HANDLE dh, UTC *p )
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the current time plus the associated PC cycles from a device.
+ *
+ * The ::PCPS_TIME_CYCLES structure contains a ::PCPS_TIME structure
+ * and a PC cycles 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_cycles call should be used preferably if supported by
+ * the device since that call provides much better accuracy than this one.
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_CYCLES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, PCPS_GIVE_TIME, IOCTL_GET_PCPS_TIME_CYCLES, p );
// No endianess conversion required.
#if !defined( _MBGIOCTL_H )
@@ -3737,7 +6524,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_cycles( MBG_DEV_HANDLE dh, PCPS_TIME_CYC
// for PCPS_TIME, read stamp AFTER the call
p->cycles = 0; //##++
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_time_cycles
@@ -3745,37 +6532,45 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_cycles( MBG_DEV_HANDLE dh, PCPS_TIME_CYC
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the current high resolution time plus the associated PC cycles from a device.
+ *
+ * The returned ::PCPS_HR_TIME_CYCLES structure contains a ::PCPS_HR_TIME
+ * structure and a PC cycles 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 API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by the device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME_CYCLES structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_hr_time_cycles( MBG_DEV_HANDLE dh,
PCPS_HR_TIME_CYCLES *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if !defined( _MBGIOCTL_H )
// only if not using IOCTLs
// for PCPS_HR_TIME, read stamp BEFORE the call
@@ -3785,7 +6580,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_cycles( MBG_DEV_HANDLE dh,
IOCTL_GET_PCPS_HR_TIME_CYCLES,
p, _pcps_ddev_has_hr_time( dh ) );
_mbg_swab_pcps_hr_time_cycles( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_hr_time_cycles
@@ -3793,34 +6588,42 @@ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_cycles( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Read the current high resolution time, and compensate the call's latency.
+ *
+ * Read a ::PCPS_HR_TIME structure plus cycles 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 API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by the device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ * @param[out] hns_latency Optional pointer to an int32_t value to return
+ * the latency in 100ns units, or NULL, if not used.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_hr_time_comp( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p,
int32_t *hns_latency )
{
@@ -3835,7 +6638,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_comp( MBG_DEV_HANDLE dh, PCPS_HR_TIME
rc = mbg_get_hr_time_cycles( dh, &htc );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
mbg_init_pc_cycles_frequency( dh, &pc_cycles_frequency );
rc = mbg_comp_hr_latency( &htc.t.tstamp, &htc.cycles, &cyc_now, &pc_cycles_frequency, hns_latency );
@@ -3850,25 +6653,28 @@ _MBG_API_ATTR int _MBG_API mbg_get_hr_time_comp( MBG_DEV_HANDLE dh, PCPS_HR_TIME
/*HDR*/
/**
- 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
-*/
+ * @brief Read the current IRIG output settings plus the supported settings.
+ *
+ * The returned ::IRIG_INFO structure contains the configuration of an IRIG output
+ * plus the possible settings supported by that output.
+ *
+ * The API call ::mbg_chk_dev_has_irig_tx checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::IRIG_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_irig_tx_settings
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if !defined( _MBGIOCTL_H )
// This is a workaround for GPS169PCIs with early
@@ -3888,7 +6694,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_irig_tx_info( MBG_DEV_HANDLE dh, IRIG_INFO *p
#undef _PCPS_CMD
_mbg_swab_irig_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_irig_tx_info
@@ -3896,24 +6702,25 @@ _MBG_API_ATTR int _MBG_API mbg_get_irig_tx_info( MBG_DEV_HANDLE dh, IRIG_INFO *p
/*HDR*/
/**
- 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
-*/
+ * @brief Write an ::IRIG_SETTINGS structure to a device to configure the IRIG output
+ *
+ * The API call ::mbg_chk_dev_has_irig_tx checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to an ::IRIG_INFO structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_irig_tx_info
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if !defined( _MBGIOCTL_H )
uint8_t pcps_cmd;
#endif
@@ -3941,7 +6748,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_irig_tx_settings( MBG_DEV_HANDLE dh, const IR
p, _pcps_ddev_has_irig_tx( dh ) );
#undef _PCPS_CMD
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_irig_tx_settings
@@ -3949,28 +6756,31 @@ _MBG_API_ATTR int _MBG_API mbg_set_irig_tx_settings( MBG_DEV_HANDLE dh, const IR
/*HDR*/
/**
- 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
-*/
+ * @brief Read the current frequency synthesizer settings from a device
+ *
+ * Read a ::SYNTH structure containing the configuration of an optional
+ * on-board programmable frequency synthesizer.
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SYNTH structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_SYNTH, IOCTL_GET_SYNTH,
p, _pcps_ddev_has_synth( dh ) );
_mbg_swab_synth( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_synth
@@ -3978,32 +6788,35 @@ _MBG_API_ATTR int _MBG_API mbg_get_synth( MBG_DEV_HANDLE dh, SYNTH *p )
/*HDR*/
/**
- 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
-*/
+ * @brief Write frequency synthesizer configuration settings to a device
+ *
+ * Write a ::SYNTH structure containing the configuration of an optional
+ * on-board programmable frequency synthesizer.
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::SYNTH structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
SYNTH tmp = *p;
_mbg_swab_synth( &tmp );
p = &tmp;
#endif
- _mbgdevio_write_var_chk( dh, PCPS_SET_SYNTH, IOCTL_SET_SYNTH,
+ _mbgdevio_write_var_chk( dh, PCPS_SET_SYNTH, IOCTL_SET_SYNTH,
p, _pcps_ddev_has_synth( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_synth
@@ -4011,28 +6824,28 @@ _MBG_API_ATTR int _MBG_API mbg_set_synth( MBG_DEV_HANDLE dh, const SYNTH *p )
/*HDR*/
/**
- 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
-*/
+ * @brief Read the current status of the on-board frequency synthesizer
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SYNTH_STATE structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, PCPS_GET_SYNTH_STATE, IOCTL_GET_SYNTH_STATE,
p, _pcps_ddev_has_synth( dh ) );
_mbg_swab_synth_state( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_synth_state
@@ -4040,69 +6853,55 @@ _MBG_API_ATTR int _MBG_API mbg_get_synth_state( MBG_DEV_HANDLE dh, SYNTH_STATE *
/*HDR*/
/**
- 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()
- @see mbg_get_fast_hr_timestamp()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_fast_hr_timestamp, IOCTL_DEV_HAS_FAST_HR_TIMESTAMP, p );
-
-} // mbg_dev_has_fast_hr_timestamp
-
-
-
-/*HDR*/
-/**
- 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()
- @see mbg_get_fast_hr_timestamp()
-*/
+ * @brief Read a high resolution ::PCPS_TIME_STAMP_CYCLES structure via memory mapped access.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP_CYCLES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_cycles( MBG_DEV_HANDLE dh,
PCPS_TIME_STAMP_CYCLES *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES, p );
// native endianess, no need to swap bytes
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
// This is currently not supported by the target environment.
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
+
} // mbg_get_fast_hr_timestamp_cycles
/*HDR*/
/**
- 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_cycles()
- @see mbg_get_fast_hr_timestamp()
-*/
+ * @brief Read a high resolution timestamp and compensate the latency of the call
+ *
+ * The retrieved ::PCPS_TIME_STAMP is read from memory mapped registers,
+ * and timestamp is compensated for the call's latency before it is returned.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP structure to be filled up
+ * @param[out] hns_latency Optionally receives the latency in hectonanoseconds //### TODO Check if hns
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see ::mbg_get_fast_hr_timestamp
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh,
PCPS_TIME_STAMP *p,
int32_t *hns_latency )
@@ -4118,7 +6917,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh,
rc = mbg_get_fast_hr_timestamp_cycles( dh, &tc );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
mbg_init_pc_cycles_frequency( dh, &pc_cycles_frequency );
rc = mbg_comp_hr_latency( &tc.tstamp, &tc.cycles, &cyc_now, &pc_cycles_frequency, hns_latency );
@@ -4133,641 +6932,73 @@ _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Read a high resolution ::PCPS_TIME_STAMP structure via memory mapped access.
-
- This function does not return or evaluate a cycles count, so the latency
- of the call can not be determined. However, depending on the timer hardware
- used as cycles counter it may take quite some time to read the cycles count
- on some hardware architectures, so this call can be used to yield lower
- latencies, under the restriction to be unable to determine the exact latency.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME_STAMP 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()
- @see mbg_get_fast_hr_timestamp_cycles()
-*/
+ * @brief Read a high resolution ::PCPS_TIME_STAMP structure via memory mapped access
+ *
+ * This function does not return or evaluate a cycles count, so the latency
+ * of the call can not be determined. However, depending on the timer hardware
+ * used as cycles counter it may take quite some time to read the cycles count
+ * on some hardware architectures, so this call can be used to yield lower
+ * latencies, under the restriction to be unable to determine the exact latency.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp( MBG_DEV_HANDLE dh,
PCPS_TIME_STAMP *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_FAST_HR_TIMESTAMP, p );
// native endianess, no need to swap bytes
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
// This is currently not supported by the target environment.
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
-} // mbg_get_fast_hr_timestamp
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_gps, IOCTL_DEV_IS_GPS, p );
-
-} // mbg_dev_is_gps
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_dcf, IOCTL_DEV_IS_DCF, p );
-
-} // mbg_dev_is_dcf
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_msf, IOCTL_DEV_IS_MSF, p );
-
-} // mbg_dev_is_msf
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_wwvb, IOCTL_DEV_IS_WWVB, p );
-
-} // mbg_dev_is_msf
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_lwr, IOCTL_DEV_IS_LWR, p );
-
-} // mbg_dev_is_lwr
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_is_irig_rx, IOCTL_DEV_IS_IRIG_RX, p );
-} // mbg_dev_is_irig_rx
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_hr_time, IOCTL_DEV_HAS_HR_TIME, p );
-
-} // mbg_dev_has_hr_time
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_cab_len, IOCTL_DEV_HAS_CAB_LEN, p );
-
-} // mbg_dev_has_cab_len
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_tzdl, IOCTL_DEV_HAS_TZDL, p );
-
-} // mbg_dev_has_tzdl
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_pcps_tzdl, IOCTL_DEV_HAS_PCPS_TZDL, p );
-
-} // mbg_dev_has_pcps_tzdl
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_tzcode, IOCTL_DEV_HAS_TZCODE, p );
-
-} // mbg_dev_has_tzcode
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_tz, IOCTL_DEV_HAS_TZ, p );
-
-} // mbg_dev_has_tz
-
-
-
-/*HDR*/
-/* (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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_event_time, IOCTL_DEV_HAS_EVENT_TIME, p );
-
-} // mbg_dev_has_event_time
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_receiver_info, IOCTL_DEV_HAS_RECEIVER_INFO, p );
-
-} // mbg_dev_has_receiver_info
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_can_clr_ucap_buff, IOCTL_DEV_CAN_CLR_UCAP_BUFF, p );
-
-} // mbg_dev_can_clr_ucap_buff
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_ucap, IOCTL_DEV_HAS_UCAP, p );
-
-} // mbg_dev_has_ucap
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_irig_tx, IOCTL_DEV_HAS_IRIG_TX, p );
-
-} // mbg_dev_has_irig_tx
-
-
-
-/*HDR*/
-/* (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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_serial_hs, IOCTL_DEV_HAS_SERIAL_HS, p );
-
-} // mbg_dev_has_serial_hs
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_signal, IOCTL_DEV_HAS_SIGNAL, p );
-
-} // mbg_dev_has_signal
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_mod, IOCTL_DEV_HAS_MOD, p );
-
-} // mbg_dev_has_mod
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_irig, IOCTL_DEV_HAS_IRIG, p );
-
-} // mbg_dev_has_irig
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_ref_offs, IOCTL_DEV_HAS_REF_OFFS, p );
-
-} // mbg_dev_has_ref_offs
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_opt_flags, IOCTL_DEV_HAS_OPT_FLAGS, p );
-
-} // mbg_dev_has_opt_flags
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_gps_data, IOCTL_DEV_HAS_GPS_DATA, p );
-
-} // mbg_dev_has_gps_data
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_synth, IOCTL_DEV_HAS_SYNTH, p );
-
-} // mbg_dev_has_synth
-
-
-
-/*HDR*/
-/* (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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_generic_io, IOCTL_DEV_HAS_GENERIC_IO, p );
-
-} // mbg_dev_has_generic_io
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_version, IOCTL_DEV_HAS_PCI_ASIC_VERSION, p );
-
-} // mbg_dev_has_asic_version
-
-
-
-/*HDR*/
-/**
- 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 )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_features, IOCTL_DEV_HAS_PCI_ASIC_FEATURES, p );
-
-} // mbg_dev_has_asic_features
+} // mbg_get_fast_hr_timestamp
/*HDR*/
/**
- 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()
-*/
+ * @brief Read current configuraton and features provided by the programmable pulse outputs.
+ *
+ * Read a ::POUT_INFO_IDX array of current settings and configuration
+ * options of the device's programmable pulse outputs.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of ::POUT_INFO_IDX structures to be filled up
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if _MBG_SUPP_VAR_ACC_SIZE
_mbgdevio_read_gps_chk( dh, PC_GPS_ALL_POUT_INFO,
@@ -4779,25 +7010,25 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_pout_info( MBG_DEV_HANDLE dh,
// has been read from a device which really supports it, or
// a dummy structure has been setup.
if ( p_ri && ( p_ri->model_code != GPS_MODEL_UNKNOWN ) )
- rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_POUT_INFO, pii,
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_POUT_INFO, pii,
p_ri->n_prg_out * sizeof( pii[0] ) );
else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
#endif
#if defined( MBG_ARCH_BIG_ENDIAN )
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
int i;
for ( i = 0; i < p_ri->n_prg_out; i++ )
{
POUT_INFO_IDX *p = &pii[i];
- _mbg_swab_pout_info_idx( p );
+ _mbg_swab_pout_info_idx_on_get( p );
}
}
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_gps_all_pout_info
@@ -4805,36 +7036,37 @@ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_pout_info( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Write the configuration for a single programmable pulse output
+ *
+ * The ::POUT_SETTINGS_IDX structure 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::POUT_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
POUT_SETTINGS_IDX tmp = *p;
- _mbg_swab_pout_settings_idx( &tmp );
+ _mbg_swab_pout_settings_idx_on_set( &tmp );
p = &tmp;
#endif
_mbgdevio_write_gps_var_chk( dh, PC_GPS_POUT_SETTINGS_IDX,
IOCTL_SET_GPS_POUT_SETTINGS_IDX, p,
_pcps_ddev_has_receiver_info( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_gps_pout_settings_idx
@@ -4842,23 +7074,26 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pout_settings_idx( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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()
-*/
+ * @brief Write the configuration for a single programmable pulse output
+ *
+ * The ::POUT_SETTINGS structure does not contain the index of the
+ * programmable output to be configured, so the index must explicitly
+ * be passed to this function. 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::POUT_SETTINGS structure to be written.
+ * @param[in] idx Index of the programmable pulse output to be configured (starting from 0 ).
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
@@ -4875,22 +7110,26 @@ _MBG_API_ATTR int _MBG_API mbg_set_gps_pout_settings( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- 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.
- */
+ * @brief Read a device's IRQ status information.
+ *
+ * IRQ status information includes flags indicating whether IRQs are
+ * actually enabled, and whether IRQ support by a card is possibly
+ * unsafe due to the firmware and interface chip version.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_IRQ_STAT_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see @ref PCPS_IRQ_STAT_INFO_DEFS
+ */
_MBG_API_ATTR int _MBG_API mbg_get_irq_stat_info( MBG_DEV_HANDLE dh, PCPS_IRQ_STAT_INFO *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_IRQ_STAT_INFO, p );
// native endianess, no need to swap bytes
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
*p = dh->irq_stat_info;
return MBG_SUCCESS;
@@ -4902,50 +7141,29 @@ _MBG_API_ATTR int _MBG_API mbg_get_irq_stat_info( MBG_DEV_HANDLE dh, PCPS_IRQ_ST
/*HDR*/
/**
- Check if a specific device provides simple LAN interface API 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_lan_if_info()
- @see mbg_get_ip4_state()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_lan_intf( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_lan_intf, IOCTL_DEV_HAS_LAN_INTF, p );
-
-} // mbg_dev_has_lan_intf
-
-
-
-/*HDR*/
-/**
- Read LAN interface information from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::LAN_IF_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_ip4_state()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN interface information from a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::LAN_IF_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_lan_if_info( MBG_DEV_HANDLE dh, LAN_IF_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_LAN_IF_INFO,
IOCTL_GET_LAN_IF_INFO, p,
_pcps_ddev_has_lan_intf( dh ) );
_mbg_swab_lan_if_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_lan_if_info
@@ -4953,28 +7171,29 @@ _MBG_API_ATTR int _MBG_API mbg_get_lan_if_info( MBG_DEV_HANDLE dh, LAN_IF_INFO *
/*HDR*/
/**
- Read LAN IPv4 state from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::IP4_SETTINGS variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN IPv4 state from a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::IP4_SETTINGS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ip4_state( MBG_DEV_HANDLE dh, IP4_SETTINGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_IP4_STATE,
IOCTL_GET_IP4_STATE, p,
_pcps_ddev_has_lan_intf( dh ) );
_mbg_swab_ip4_settings( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ip4_state
@@ -4982,28 +7201,29 @@ _MBG_API_ATTR int _MBG_API mbg_get_ip4_state( MBG_DEV_HANDLE dh, IP4_SETTINGS *p
/*HDR*/
/**
- Read LAN IPv4 settings from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::IP4_SETTINGS variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_state()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN IPv4 settings from a device.
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::IP4_SETTINGS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ip4_settings( MBG_DEV_HANDLE dh, IP4_SETTINGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_IP4_SETTINGS,
IOCTL_GET_IP4_SETTINGS, p,
_pcps_ddev_has_lan_intf( dh ) );
_mbg_swab_ip4_settings( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ip4_settings
@@ -5011,23 +7231,24 @@ _MBG_API_ATTR int _MBG_API mbg_get_ip4_settings( MBG_DEV_HANDLE dh, IP4_SETTINGS
/*HDR*/
/**
- Write LAN IPv4 settings to a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::IP4_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_settings()
-*/
+ * @brief Write LAN IPv4 settings to a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::IP4_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ip4_settings( MBG_DEV_HANDLE dh,
const IP4_SETTINGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
IP4_SETTINGS tmp = *p;
_mbg_swab_ip4_settings( &tmp );
@@ -5036,7 +7257,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_ip4_settings( MBG_DEV_HANDLE dh,
_mbgdevio_write_gps_var_chk( dh, PC_GPS_IP4_SETTINGS,
IOCTL_SET_IP4_SETTINGS, p,
_pcps_ddev_has_lan_intf( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_ip4_settings
@@ -5044,70 +7265,30 @@ _MBG_API_ATTR int _MBG_API mbg_set_ip4_settings( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Check if a specific device provides PTP configuration/status 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_ptp_state()
- @see mbg_get_ptp_cfg_info()
- @see mbg_set_ptp_cfg_settings()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_ptp( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_ptp, IOCTL_DEV_HAS_PTP, p );
-
-} // mbg_dev_has_ptp
-
-
-
-/*HDR*/
-/**
- Check if a specific device provides PTP Unicast feature/configuration.
-
- @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_ptp_state()
- @see mbg_get_ptp_uc_master_cfg_limits()
- @see mbg_get_all_ptp_uc_master_info()
- @see mbg_set_ptp_unicast_cfg_settings()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_ptp_unicast( MBG_DEV_HANDLE dh, int *p )
-{
- _mbgdevio_query_ri_cond( dh, _pcps_has_ri_ptp_unicast, IOCTL_DEV_HAS_PTP_UNICAST, p );
-
-} // mbg_dev_has_ptp_unicast
-
-
-
-/*HDR*/
-/**
- Read PTP/IEEE1588 status from a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_cfg_info()
- @see mbg_set_ptp_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 status from a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_STATE variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_state( MBG_DEV_HANDLE dh, PTP_STATE *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_PTP_STATE,
IOCTL_GET_PTP_STATE, p,
_pcps_ddev_has_ptp( dh ) );
_mbg_swab_ptp_state( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ptp_state
@@ -5115,27 +7296,30 @@ _MBG_API_ATTR int _MBG_API mbg_get_ptp_state( MBG_DEV_HANDLE dh, PTP_STATE *p )
/*HDR*/
/**
- Read PTP/IEEE1588 config info and current settings from a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_state()
- @see mbg_set_ptp_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 config info and current settings from a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_CFG_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_cfg_info( MBG_DEV_HANDLE dh, PTP_CFG_INFO *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_PTP_CFG,
IOCTL_GET_PTP_CFG_INFO, p,
_pcps_ddev_has_ptp( dh ) );
_mbg_swab_ptp_cfg_info( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ptp_cfg_info
@@ -5143,23 +7327,26 @@ _MBG_API_ATTR int _MBG_API mbg_get_ptp_cfg_info( MBG_DEV_HANDLE dh, PTP_CFG_INFO
/*HDR*/
/**
- Write PTP/IEEE1588 configuration settings to a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::PTP_CFG_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_state()
- @see mbg_get_ptp_cfg_info()
-*/
+ * @brief Write PTP/IEEE1588 configuration settings to a device.
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::PTP_CFG_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ptp_cfg_settings( MBG_DEV_HANDLE dh,
const PTP_CFG_SETTINGS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PTP_CFG_SETTINGS tmp = *p;
_mbg_swab_ptp_cfg_settings( &tmp );
@@ -5168,7 +7355,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_ptp_cfg_settings( MBG_DEV_HANDLE dh,
_mbgdevio_write_gps_var_chk( dh, PC_GPS_PTP_CFG,
IOCTL_SET_PTP_CFG_SETTINGS, p,
_pcps_ddev_has_ptp( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_ptp_cfg_settings
@@ -5176,26 +7363,31 @@ _MBG_API_ATTR int _MBG_API mbg_set_ptp_cfg_settings( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Read PTP/IEEE1588 unicast config info and current settings from a card which supports this.
- The macro _pcps_has_ri_ptp_unicast() or the API call mbg_dev_has_ptp_unicast()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_UNICAST_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp_unicast()
- @see mbg_set_ptp_unicast_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 unicast master configuration limits from a device.
+ *
+ * The API call ::mbg_chk_dev_has_ptp_unicast checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_UC_MASTER_CFG_LIMITS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_uc_master_cfg_limits( MBG_DEV_HANDLE dh, PTP_UC_MASTER_CFG_LIMITS *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_gps_var_chk( dh, PC_GPS_PTP_UC_MASTER_CFG_LIMITS,
IOCTL_PTP_UC_MASTER_CFG_LIMITS, p,
- _pcps_has_ri_ptp_unicast( &dh->ri ) );
+ _pcps_has_ri_ptp_unicast( _ri_addr( dh ) ) );
+
_mbg_swab_ptp_uc_master_cfg_limits( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_ptp_uc_master_cfg_limits
@@ -5203,31 +7395,28 @@ _MBG_API_ATTR int _MBG_API mbg_get_ptp_uc_master_cfg_limits( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Read a ::IOCTL_SET_PTP_UNICAST_CFG_SETTINGS 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 ::PTP_UC_MASTER_INFO_IDX structures to be filled up
- @param p_umsl Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure returned by mbg_get_ptp_uc_master_cfg_limits()
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see //##++++++++++++++++++++++
- @see
- @see
-*/
+ * @brief Read PTP Unicast master settings and configuration options.
+ *
+ * The array passed to this function to receive the returned data
+ * must be able to hold at least ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master elements.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of ::PTP_UC_MASTER_INFO_IDX structures to be filled up.
+ * @param[in] p_umsl Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure returned by ::mbg_get_ptp_uc_master_cfg_limits
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_get_all_ptp_uc_master_info( MBG_DEV_HANDLE dh,
- PTP_UC_MASTER_INFO_IDX pii[],
- const PTP_UC_MASTER_CFG_LIMITS *p_umsl )
+ PTP_UC_MASTER_INFO_IDX pii[],
+ const PTP_UC_MASTER_CFG_LIMITS *p_umsl )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if _MBG_SUPP_VAR_ACC_SIZE
_mbgdevio_read_gps_chk( dh, PC_GPS_ALL_PTP_UC_MASTER_INFO,
@@ -5239,11 +7428,11 @@ _MBG_API_ATTR int _MBG_API mbg_get_all_ptp_uc_master_info( MBG_DEV_HANDLE dh,
rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_PTP_UC_MASTER_INFO, pii,
p_umsl->n_supp_master * sizeof( pii[0] ) );
else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ return MBG_ERR_NOT_SUPP_BY_DEV;
#endif
#if defined( MBG_ARCH_BIG_ENDIAN )
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
int i;
for ( i = 0; i < p_umsl->n_supp_master; i++ )
@@ -5254,7 +7443,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_all_ptp_uc_master_info( MBG_DEV_HANDLE dh,
}
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_get_all_ptp_uc_master_info
@@ -5262,24 +7451,26 @@ _MBG_API_ATTR int _MBG_API mbg_get_all_ptp_uc_master_info( MBG_DEV_HANDLE dh,
/*HDR*/
/**
- Write PTP/IEEE1588 unicast configuration settings to a card which supports this.
- The macro _pcps_has_ri_ptp_unicast() or the API call mbg_dev_has_ptp_unicast()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::PTP_UNICAST_CFG_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp_unicast()
- @see mbg_get_ptp_state()
- @see mbg_get_ptp_cfg_info()
- @see mbg_get_ptp_unicast_cfg_info()
-*/
+ * @brief Write PTP/IEEE1588 unicast configuration settings to a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp_unicast checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::PTP_UC_MASTER_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ptp_uc_master_settings_idx( MBG_DEV_HANDLE dh,
const PTP_UC_MASTER_SETTINGS_IDX *p )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
PTP_UC_MASTER_SETTINGS_IDX tmp = *p;
_mbg_swab_ptp_uc_master_settings_idx( &tmp );
@@ -5288,7 +7479,7 @@ _MBG_API_ATTR int _MBG_API mbg_set_ptp_uc_master_settings_idx( MBG_DEV_HANDLE dh
_mbgdevio_write_gps_var_chk( dh, PC_GPS_PTP_UC_MASTER_SETTINGS_IDX,
IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX, p,
_pcps_ddev_has_ptp_unicast( dh ) );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbg_set_ptp_uc_master_settings_idx
@@ -5296,39 +7487,40 @@ _MBG_API_ATTR int _MBG_API mbg_set_ptp_uc_master_settings_idx( MBG_DEV_HANDLE dh
/*HDR*/
/**
- Read system time and card time from the kernel driver. The kernel
- driver reads the current system time plus a HR time structure from
- a card immediately after each other. The returned info structure also
- contains some cycles counts to be able to determine the execution times
- required to read those time stamps.
-
- The advantage of this call compared to mbg_get_time_info_tstamp() is
- that this call also returns the card's status. On the other hand, reading
- the HR time from the card may block e.g. if another application accesses
- the board.
-
- This call makes a mbg_get_hr_time_cycles() call internally so the macro
- _pcps_has_hr_time() or the API call mbg_dev_has_hr_time() can be
- used to check whether this call is supported with a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_INFO_HRT variable 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_info_tstamp()
- */
+ * @brief Read both system time and associated device time from the kernel driver
+ *
+ * The kernel driver reads the current system time plus a HR time structure
+ * from a card immediately after each other. The returned info structure also
+ * contains some cycles counts to be able to determine the execution times
+ * required to read those time stamps.
+ *
+ * The advantage of this call compared to ::mbg_get_time_info_tstamp is
+ * that this call also returns the card's status. On the other hand, reading
+ * the HR time from the card may block e.g. if another application accesses
+ * the board.
+ *
+ * This call makes a ::mbg_get_hr_time_cycles call internally so the API call
+ * ::mbg_chk_dev_has_hr_time can be used to check whether this call is supported
+ * by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_INFO_HRT structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_time_info_tstamp
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_info_hrt( MBG_DEV_HANDLE dh, MBG_TIME_INFO_HRT *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, -1, IOCTL_GET_TIME_INFO_HRT, p,
_pcps_ddev_has_hr_time( dh ) );
_mbg_swab_mbg_time_info_hrt( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
} // mbg_get_time_info_hrt
@@ -5337,29 +7529,31 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_info_hrt( MBG_DEV_HANDLE dh, MBG_TIME_IN
/*HDR*/
/**
- This call is similar to mbg_get_time_info_hrt() except that a
- mbg_get_fast_hr_timestamp_cycles() call is made internally, so the macro
- _pcps_has_fast_hr_timestamp() or the API call mbg_dev_has_fast_hr_timestamp()
- can be used to check whether this call is supported with a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_INFO_TSTAMP variable 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_time_info_hrt()
- */
+ * @brief Read both system time and associated device timestamp from the kernel driver
+ *
+ * This call is similar to ::mbg_get_time_info_hrt except that a
+ * ::mbg_get_fast_hr_timestamp_cycles call is made internally, so
+ * the API call ::mbg_chk_dev_has_fast_hr_timestamp can be used to check whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_INFO_TSTAMP structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_time_info_hrt
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_info_tstamp( MBG_DEV_HANDLE dh, MBG_TIME_INFO_TSTAMP *p )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
_mbgdevio_read_var_chk( dh, -1, IOCTL_GET_TIME_INFO_TSTAMP, p,
_pcps_ddev_has_fast_hr_timestamp( dh ) );
_mbg_swab_mbg_time_info_tstamp( p );
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
} // mbg_get_time_info_tstamp
@@ -5368,236 +7562,881 @@ _MBG_API_ATTR int _MBG_API mbg_get_time_info_tstamp( MBG_DEV_HANDLE dh, MBG_TIME
/*HDR*/
/**
- Check if a specific device supports demodulation of the DCF77 PZF code.
+ * @brief Read PZF correlation info from a device
+ *
+ * The API call ::mbg_chk_dev_has_corr_info checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::CORR_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_corr_info
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_corr_info( MBG_DEV_HANDLE dh, CORR_INFO *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_GET_CORR_INFO,
+ IOCTL_GET_CORR_INFO, p,
+ _pcps_ddev_has_corr_info( dh ) );
+ _mbg_swab_corr_info( p );
+ return _mbgdevio_cnv_ret_val( rc );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+} // mbg_get_corr_info
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
- @see mbg_dev_has_corr_info()
- @see mbg_dev_has_tr_distance()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_pzf( MBG_DEV_HANDLE dh, int *p )
+
+/*HDR*/
+/**
+ * @brief Read configurable "distance from transmitter" parameter from a device
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * The API call ::mbg_chk_dev_has_tr_distance checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TR_DISTANCE variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_set_tr_distance
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_tr_distance( MBG_DEV_HANDLE dh, TR_DISTANCE *p )
{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_pzf, IOCTL_DEV_HAS_PZF, p );
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_GET_TR_DISTANCE,
+ IOCTL_GET_TR_DISTANCE, p,
+ _pcps_ddev_has_tr_distance( dh ) );
+ _mbg_swab_tr_distance( p );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_dev_has_pzf
+} // mbg_get_tr_distance
/*HDR*/
/**
- Check if a specific device supports reading correlation info.
+ * @brief Write configurable "distance from transmitter" parameter to a device.
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * The API call ::mbg_chk_dev_has_tr_distance checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TR_DISTANCE variable to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_get_tr_distance
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_tr_distance( MBG_DEV_HANDLE dh, const TR_DISTANCE *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ TR_DISTANCE tmp = *p;
+ _mbg_swab_tr_distance( &tmp );
+ p = &tmp;
+ #endif
+ _mbgdevio_write_var_chk( dh, PCPS_SET_TR_DISTANCE, IOCTL_SET_TR_DISTANCE,
+ p, _pcps_ddev_has_tr_distance( dh ) );
+ return _mbgdevio_cnv_ret_val( rc );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+} // mbg_set_tr_distance
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
- @see mbg_dev_has_pzf()
- @see mbg_get_corr_info()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_corr_info( MBG_DEV_HANDLE dh, int *p )
+
+/*HDR*/
+/**
+ * @brief Read a debug status word from a device
+ *
+ * This is mainly supported by IRIG timecode receiver cards, and the status
+ * word is intended to provide more detailed information why a card might not
+ * synchronize to the incoming timecode signal.
+ *
+ * See ::MBG_DEBUG_STATUS and related definitions for details.
+ *
+ * The API call ::mbg_chk_dev_has_debug_status checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_DEBUG_STATUS variable to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_debug_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_debug_status( MBG_DEV_HANDLE dh, MBG_DEBUG_STATUS *p )
{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_corr_info, IOCTL_DEV_HAS_CORR_INFO, p );
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_GET_DEBUG_STATUS,
+ IOCTL_GET_DEBUG_STATUS, p,
+ _pcps_ddev_has_debug_status( dh ) );
+ _mbg_swab_debug_status( p );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_dev_has_corr_info
+} // mbg_get_debug_status
/*HDR*/
/**
- Check if a specific device supports configurable distance from transmitter
- used to compensate RF propagation delay.
+ * @brief Clear the device's on-board event log
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+_MBG_API_ATTR int _MBG_API mbg_clr_evt_log( MBG_DEV_HANDLE dh )
+{
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_write_cmd_chk( dh, PCPS_CLR_EVT_LOG, IOCTL_CLR_EVT_LOG,
+ _pcps_ddev_has_evt_log( dh ) );
+ return _mbgdevio_cnv_ret_val( rc );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+} // mbg_clr_evt_log
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
- @see mbg_dev_has_pzf()
- @see mbg_get_tr_distance()
- @see mbg_set_tr_distance()
-*/
-_MBG_API_ATTR int _MBG_API mbg_dev_has_tr_distance( MBG_DEV_HANDLE dh, int *p )
+
+/*HDR*/
+/**
+ * @brief Read details about a device's on-board event log buffer
+ *
+ * The returned ::MBG_NUM_EVT_LOG_ENTRIES structure tells how many
+ * event log entries can be saved on the board, and how many entries
+ * actually have been saved.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_NUM_EVT_LOG_ENTRIES variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_num_evt_log_entries( MBG_DEV_HANDLE dh, MBG_NUM_EVT_LOG_ENTRIES *p )
{
- _mbgdevio_query_cond( dh, _pcps_ddev_has_tr_distance, IOCTL_DEV_HAS_TR_DISTANCE, p );
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_NUM_EVT_LOG_ENTRIES,
+ IOCTL_GET_NUM_EVT_LOG_ENTRIES, p,
+ _pcps_ddev_has_evt_log( dh ) );
+ _mbg_swab_mbg_num_evt_log_entries( p );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_dev_has_tr_distance
+} // mbg_get_num_evt_log_entries
/*HDR*/
/**
- Read PZF correlation info from a card which supports this.
- The macro _pcps_has_corr_info() or the API call mbg_dev_has_corr_info()
- check whether this call is supported by a specific card.
+ * @brief Read the first (oldest) event log entry from a device
+ *
+ * @note Subsequent reads should be made using ::mbg_get_next_evt_log_entry.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * If no (more) event log entry is available on the device then
+ * the returned MBG_EVT_LOG_ENTRY::code is MBG_EVT_ID_NONE.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_EVT_LOG_ENTRY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_next_evt_log_entry
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_first_evt_log_entry( MBG_DEV_HANDLE dh, MBG_EVT_LOG_ENTRY *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_FIRST_EVT_LOG_ENTRY,
+ IOCTL_GET_FIRST_EVT_LOG_ENTRY, p,
+ _pcps_ddev_has_evt_log( dh ) );
+ _mbg_swab_mbg_evt_log_entry( p );
+ return _mbgdevio_cnv_ret_val( rc );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::CORR_INFO variable to be filled up
+} // mbg_get_first_evt_log_entry
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_corr_info()
- */
-_MBG_API_ATTR int _MBG_API mbg_get_corr_info( MBG_DEV_HANDLE dh, CORR_INFO *p )
+
+/*HDR*/
+/**
+ * @brief Read the next event log entry from a device
+ *
+ * @note The first read should be made using ::mbg_get_first_evt_log_entry
+ * to set the on-board read index to the oldest entry.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * If no (more) event log entry is available on the device then
+ * the returned MBG_EVT_LOG_ENTRY::code is MBG_EVT_ID_NONE.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_EVT_LOG_ENTRY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_next_evt_log_entry( MBG_DEV_HANDLE dh, MBG_EVT_LOG_ENTRY *p )
{
- _mbgdevio_vars();
- _mbgdevio_read_var_chk( dh, PCPS_GET_CORR_INFO,
- IOCTL_GET_CORR_INFO, p,
- _pcps_ddev_has_corr_info( dh ) );
- _mbg_swab_corr_info( p );
- return _mbgdevio_ret_val;
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_var_chk( dh, PCPS_NEXT_EVT_LOG_ENTRY,
+ IOCTL_GET_NEXT_EVT_LOG_ENTRY, p,
+ _pcps_ddev_has_evt_log( dh ) );
+ _mbg_swab_mbg_evt_log_entry( p );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_get_corr_info
+} // mbg_get_next_evt_log_entry
/*HDR*/
/**
- Read configurable "distance from transmitter" parameter from a card
- which supports this. The parameter is used to compensate the RF signal
- propagation delay.
- The macro _pcps_has_tr_distance() or the API call mbg_dev_has_tr_distance()
- check whether this call is supported by a specific card.
+ * @brief Read the current GNSS mode info including current settings
+ *
+ * The ::MBG_GNSS_MODE_INFO structure tells which GNSS systems are supported
+ * by a device, and also includes the settings currently in effect.
+ *
+ * The API call ::mbg_chk_dev_is_gnss can be used to check whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_is_gnss.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p_mi Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ * @see ::mbg_chk_dev_is_gnss
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_gnss_mode_info( MBG_DEV_HANDLE dh, MBG_GNSS_MODE_INFO *p_mi )
+{
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_gps_var_chk( dh, PC_GPS_GNSS_MODE,
+ IOCTL_GET_GNSS_MODE_INFO, p_mi,
+ _pcps_ddev_is_gnss( dh ) );
+ _mbg_swab_mbg_gnss_mode_info( p_mi );
+ return _mbgdevio_cnv_ret_val( rc );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::TR_DISTANCE variable to be filled up
+} // mbg_get_gps_gnss_mode_info
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_tr_distance()
- @see mbg_set_tr_distance()
- */
-_MBG_API_ATTR int _MBG_API mbg_get_tr_distance( MBG_DEV_HANDLE dh, TR_DISTANCE *p )
+
+/*HDR*/
+/**
+ * @brief Write the GNSS mode configuration to a device
+ *
+ * The ::MBG_GNSS_MODE_SETTINGS structure determines the GNSS settings
+ * for a device, e.g. which satellite systems have to be used.
+ *
+ * The function ::mbg_get_gps_gnss_mode_info should have been called before
+ * to determine which GNSS settings are supported by the device.
+ *
+ * The API call ::mbg_chk_dev_is_gnss can be used to check whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_is_gnss.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p_ms Pointer to a ::MBG_GNSS_MODE_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ * @see ::mbg_chk_dev_is_gnss
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_gps_gnss_mode_settings( MBG_DEV_HANDLE dh,
+ const MBG_GNSS_MODE_SETTINGS *p_ms )
+{
+ MBGDEVIO_RET_VAL rc;
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ MBG_GNSS_MODE_SETTINGS tmp = *p_ms;
+ _mbg_swab_mbg_gnss_mode_settings( &tmp );
+ p_ms = &tmp;
+ #endif
+ _mbgdevio_write_gps_var_chk( dh, PC_GPS_GNSS_MODE,
+ IOCTL_SET_GNSS_MODE_SETTINGS, p_ms,
+ _pcps_ddev_is_gnss( dh ) );
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_set_gps_gnss_mode_settings
+
+
+
+/*HDR*/
+/**
+ * @brief Read a ::GNSS_SAT_INFO_IDX array of satellite status information
+ *
+ * The function ::mbg_get_gps_gnss_mode_info must have been called before,
+ * and the returned ::MBG_GNSS_MODE_INFO structure be passed to this function.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gsii Pointer to a an array of satellite info structures to be filled up.
+ * @param[in] p_mi Pointer to a ::MBG_GNSS_MODE_INFO structure returned by ::mbg_get_gps_gnss_mode_info.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_chk_dev_is_gnss
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_gnss_sat_info( MBG_DEV_HANDLE dh,
+ GNSS_SAT_INFO_IDX gsii[],
+ const MBG_GNSS_MODE_INFO *p_mi )
{
- _mbgdevio_vars();
- _mbgdevio_read_var_chk( dh, PCPS_GET_TR_DISTANCE,
- IOCTL_GET_TR_DISTANCE, p,
- _pcps_ddev_has_tr_distance( dh ) );
- _mbg_swab_tr_distance( p );
- return _mbgdevio_ret_val;
+ MBGDEVIO_RET_VAL rc;
-} // mbg_get_tr_distance
+ int n_supp = num_bits_set( p_mi->supp_gnss_types );
+
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_GNSS_SAT_INFO,
+ IOCTL_GET_ALL_GNSS_SAT_INFO, gsii,
+ n_supp * sizeof( gsii[0] ),
+ _pcps_ddev_is_gnss( dh ) );
+ #else
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_GNSS_SAT_INFO, gsii,
+ n_supp * sizeof( gsii[0] ) );
+ #endif
+
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ if ( mbg_rc_is_success( rc ) )
+ {
+ int i;
+ for ( i = 0; i < n_supp; i++ )
+ {
+ GNSS_SAT_INFO_IDX *p = &gsii[i];
+ _mbg_swab_gnss_sat_info_idx( p );
+ }
+ }
+ #endif
+
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_gps_all_gnss_sat_info
/*HDR*/
/**
- Write configurable "distance from transmitter" parameter to a card
- which supports this. The parameter is used to compensate the RF signal
- propagation delay.
- The macro _pcps_has_tr_distance() or the API call mbg_dev_has_tr_distance()
- check whether this call is supported by a specific card.
+ * @brief Read common GPIO configuration limits
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::MBG_GPIO_CFG_LIMITS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gpio_cfg_limits( MBG_DEV_HANDLE dh, MBG_GPIO_CFG_LIMITS *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_gps_var_chk( dh, PC_GPS_GPIO_CFG_LIMITS,
+ IOCTL_GET_GPIO_CFG_LIMITS, p,
+ _pcps_ddev_has_gpio( dh ) );
+ _mbg_swab_mbg_gpio_cfg_limits( p );
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::TR_DISTANCE variable to be written
+ return _mbgdevio_cnv_ret_val( rc );
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+} // mbg_get_gpio_cfg_limits
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_tr_distance()
- @see mbg_get_tr_distance()
- */
-_MBG_API_ATTR int _MBG_API mbg_set_tr_distance( MBG_DEV_HANDLE dh, const TR_DISTANCE *p )
+
+
+/*HDR*/
+/**
+ * @brief Get all GPIO settings and capabilities.
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gii An array of ::MBG_GPIO_STATUS_IDX structures to be filled up.
+ * @param[in] p_gcl Pointer to a ::MBG_GPIO_CFG_LIMITS structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_gpio_info( MBG_DEV_HANDLE dh,
+ MBG_GPIO_INFO_IDX gii[],
+ const MBG_GPIO_CFG_LIMITS *p_gcl )
{
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
+
+ uint32_t n_supp = p_gcl->num_io;
+
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_GPIO_INFO,
+ IOCTL_GET_ALL_GPIO_INFO, gii,
+ n_supp * sizeof( gii[0] ),
+ _pcps_ddev_has_gpio( dh ) );
+ #else
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_GPIO_INFO, gii,
+ n_supp * sizeof( gii[0] ) );
+ #endif
+
#if defined( MBG_ARCH_BIG_ENDIAN )
- TR_DISTANCE tmp = *p;
- _mbg_swab_tr_distance( &tmp );
+ if ( mbg_rc_is_success( rc ) )
+ {
+ int i;
+ for ( i = 0; i < n_supp; i++ )
+ {
+ MBG_GPIO_INFO_IDX *p = &gii[i];
+ _mbg_swab_mbg_gpio_info_idx( p, 1 );
+ }
+ }
+ #endif
+
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_gps_all_gpio_info
+
+
+
+/*HDR*/
+/**
+ * @brief Write the configuration for a single GPIO port to a device
+ *
+ * The ::MBG_GPIO_SETTINGS_IDX structure contains both the ::MBG_GPIO_SETTINGS
+ * and the port index value.
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_GPIO_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_gps_gpio_settings_idx( MBG_DEV_HANDLE dh,
+ const MBG_GPIO_SETTINGS_IDX *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ MBG_GPIO_SETTINGS_IDX tmp = *p;
+ _mbg_swab_mbg_gpio_settings_idx( &tmp, 1 );
p = &tmp;
#endif
- _mbgdevio_write_var_chk( dh, PCPS_SET_TR_DISTANCE, IOCTL_SET_TR_DISTANCE,
- p, _pcps_ddev_has_tr_distance( dh ) );
- return _mbgdevio_ret_val;
+ _mbgdevio_write_gps_var_chk( dh, PC_GPS_GPIO_SETTINGS_IDX,
+ IOCTL_SET_GPIO_SETTINGS_IDX, p,
+ _pcps_ddev_has_gpio( dh ) );
+ return _mbgdevio_cnv_ret_val( rc );
-} // mbg_set_tr_distance
+} // mbg_set_gps_gpio_settings_idx
/*HDR*/
/**
- Read the CPU affinity of a process, i.e. on which of the available
- CPUs the process can be executed.
+ * @brief Read the status of all GPIO signal ports
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gsi An array of ::MBG_GPIO_STATUS_IDX structures to be filled up.
+ * @param[in] p_gcl Pointer to a ::MBG_GPIO_CFG_LIMITS structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_gpio_status( MBG_DEV_HANDLE dh,
+ MBG_GPIO_STATUS_IDX gsi[],
+ const MBG_GPIO_CFG_LIMITS *p_gcl )
+{
+ MBGDEVIO_RET_VAL rc;
- @param pid The process ID.
- @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ uint32_t n_supp;
- @return ::MBG_SUCCESS or error code returned by the system call.
+ if ( !( p_gcl->flags & MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP ) )
+ return MBG_ERR_NOT_SUPP_BY_DEV;
- @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 )
+ n_supp = p_gcl->num_io;
+
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_GPIO_STATUS,
+ IOCTL_GET_ALL_GPIO_STATUS, gsi,
+ n_supp * sizeof( gsi[0] ),
+ _pcps_ddev_has_gpio( dh ) );
+ #else
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_GPIO_STATUS, gsi,
+ n_supp * sizeof( gsi[0] ) );
+ #endif
+
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ if ( mbg_rc_is_success( rc ) )
+ {
+ int i;
+ for ( i = 0; i < n_supp; i++ )
+ {
+ MBG_GPIO_STATUS_IDX *p = &gsi[i];
+ _mbg_swab_mbg_gpio_status_idx( p );
+ }
+ }
+ #endif
+
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_gps_all_gpio_status
+
+
+
+/*HDR*/
+/**
+ * @brief Read ::XMULTI_REF_INSTANCES
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::XMULTI_REF_INSTANCES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_xmr_instances( MBG_DEV_HANDLE dh, XMULTI_REF_INSTANCES *p )
{
- #if defined( MBG_TGT_LINUX )
+ MBGDEVIO_RET_VAL rc;
+ _mbgdevio_read_gps_var_chk( dh, PC_GPS_XMR_INSTANCES,
+ IOCTL_GET_XMR_INSTANCES, p,
+ _pcps_ddev_has_xmr( dh ) );
+ _mbg_swab_xmulti_ref_instances( p );
+ return _mbgdevio_cnv_ret_val( rc );
- return sched_getaffinity( pid, sizeof( *p ), p );
+} // mbg_get_xmr_instances
- #elif defined( MBG_TGT_WIN32 )
- MBG_CPU_SET system_affinity_mask = 0;
- return GetProcessAffinityMask( pid, p, &system_affinity_mask ) ? 0 : -1;
+/*HDR*/
+/**
+ * @brief Read the status of all XMR sources
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] xmrsi An array of ::XMULTI_REF_STATUS_IDX structures to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_xmr_status( MBG_DEV_HANDLE dh,
+ XMULTI_REF_STATUS_IDX xmrsi[],
+ const XMULTI_REF_INSTANCES *p_xmri )
+{
+ MBGDEVIO_RET_VAL rc;
+
+ int n_supp = p_xmri->n_xmr_settings;
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_XMR_STATUS,
+ IOCTL_GET_ALL_XMR_STATUS, xmrsi,
+ n_supp * sizeof( xmrsi[0] ),
+ _pcps_ddev_has_xmr( dh ) );
#else
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_XMR_STATUS, xmrsi,
+ n_supp * sizeof( xmrsi[0] ) );
+ #endif
+
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ if ( mbg_rc_is_success( rc ) )
+ {
+ int i;
+ for ( i = 0; i < n_supp; i++ )
+ {
+ XMULTI_REF_STATUS_IDX *p = &xmrsi[i];
+ _mbg_swab_xmulti_ref_status_idx( p );
+ }
+ }
+ #endif
+
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_gps_all_xmr_status
+
+
+
+/*HDR*/
+/**
+ * @brief Read all XMR settings and capabilities
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] xmrii An array of ::XMULTI_REF_INFO_IDX structures to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_gps_all_xmr_info( MBG_DEV_HANDLE dh,
+ XMULTI_REF_INFO_IDX xmrii[],
+ const XMULTI_REF_INSTANCES *p_xmri )
+{
+ MBGDEVIO_RET_VAL rc;
- return -1;
+ int n_supp = p_xmri->n_xmr_settings;
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_XMR_INFO,
+ IOCTL_GET_ALL_XMR_INFO, xmrii,
+ n_supp * sizeof( xmrii[0] ),
+ _pcps_ddev_has_xmr( dh ) );
+ #else
+ rc = _mbgdevio_gen_read_gps( dh, PC_GPS_ALL_XMR_INFO, xmrii,
+ n_supp * sizeof( xmrii[0] ) );
#endif
-} // mbg_get_process_affinity
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ if ( mbg_rc_is_success( rc ) )
+ {
+ int i;
+ for ( i = 0; i < n_supp; i++ )
+ {
+ XMULTI_REF_INFO_IDX *p = &xmrii[i];
+ _mbg_swab_xmulti_ref_info_idx( p );
+ }
+ }
+ #endif
+
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_gps_all_xmr_info
/*HDR*/
/**
- Set the CPU affinity of a process, i.e. on which of the available
- CPUs the process is allowed to be executed.
+ * @brief Write a single XMR setting to a device
+ *
+ * The ::XMULTI_REF_SETTINGS_IDX structure contains both the ::XMULTI_REF_SETTINGS
+ * and the index value.
+ *
+ * The API call ::mbg_chk_dev_has_xmr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::XMULTI_REF_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_get_xmr_holdover_status
+ */
+_MBG_API_ATTR int _MBG_API mbg_set_gps_xmr_settings_idx( MBG_DEV_HANDLE dh,
+ const XMULTI_REF_SETTINGS_IDX *p )
+{
+ MBGDEVIO_RET_VAL rc;
+ #if defined( MBG_ARCH_BIG_ENDIAN )
+ XMULTI_REF_SETTINGS_IDX tmp = *p;
+ _mbg_swab_xmulti_ref_settings_idx( &tmp );
+ p = &tmp;
+ #endif
+ _mbgdevio_write_gps_var_chk( dh, PC_GPS_XMR_SETTINGS_IDX,
+ IOCTL_SET_XMR_SETTINGS_IDX, p,
+ _pcps_ddev_has_xmr( dh ) );
+ return _mbgdevio_cnv_ret_val( rc );
- @param pid The process ID.
- @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+} // mbg_set_gps_xmr_settings_idx
- @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 )
+
+/*HDR*/
+/**
+ * @brief Read the current XMR holdover interval from a device
+ *
+ * The API call ::mbg_chk_dev_has_xmr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::XMR_HOLDOVER_INTV structure to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ */
+_MBG_API_ATTR int _MBG_API mbg_get_xmr_holdover_status( MBG_DEV_HANDLE dh, XMR_HOLDOVER_STATUS *p,
+ const XMULTI_REF_INSTANCES *p_xmri )
{
- #if defined( MBG_TGT_LINUX )
+ MBGDEVIO_RET_VAL rc;
+
+ if ( !( p_xmri->flags & XMRIF_MSK_HOLDOVER_STATUS_SUPP ) )
+ return MBG_ERR_NOT_SUPP_BY_DEV;
+
+ _mbgdevio_read_gps_var_chk( dh, PC_GPS_XMR_HOLDOVER_STATUS,
+ IOCTL_GET_XMR_HOLDOVER_STATUS, p,
+ _pcps_ddev_has_xmr( dh ) );
+ _mbg_swab_xmr_holdover_status( p );
- return sched_setaffinity( pid, sizeof( *p ), p );
+ return _mbgdevio_cnv_ret_val( rc );
+
+} // mbg_get_xmr_holdover_status
+
+
+
+/*HDR*/
+/**
+ * @brief Read the CPU affinity of a process
+ *
+ * This means on which of the available CPUs or CPU cores
+ * a process may be executed.
+ *
+ * @param[in] pid The process ID.
+ * @param[out] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
+{
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
+
+ if ( sched_getaffinity( pid, sizeof( *p ), p ) == 0 ) // success
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
#elif defined( MBG_TGT_WIN32 )
- return SetProcessAffinityMask( pid, *p ) ? 0 : -1;
+ MBG_CPU_SET system_affinity_mask = 0;
+
+ if ( GetProcessAffinityMask( pid, p, &system_affinity_mask ) )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
#else
- return -1;
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
-} // mbg_set_process_affinity
+} // mbg_get_process_affinity
/*HDR*/
/**
- Set the CPU affinity of a process for a single CPU only, i.e. the process
- may only be executed on that single CPU.
+ * @brief Set the CPU affinity of a process.
+ *
+ * This determines on which of the available CPUs
+ * or CPU cores the process is allowed to be executed.
+ *
+ * @param[in] pid The process ID.
+ * @param[out] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
+{
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
+
+ if ( sched_setaffinity( pid, sizeof( *p ), p ) == 0 )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ if ( SetProcessAffinityMask( pid, *p ) )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
+
+ #else
- @param cpu_num The number of the CPU.
+ return MBG_ERR_NOT_SUPP_ON_OS;
+
+ #endif
+
+} // mbg_set_process_affinity
- @return ::MBG_SUCCESS or error code returned by the system call.
- @see mbg_get_process_affinity()
- @see mbg_set_process_affinity()
- */
+
+/*HDR*/
+/**
+ * @brief Set the CPU affinity of a process for a single CPU only
+ *
+ * This means the process may only be executed on that single CPU.
+ *
+ * @param[in] cpu_num The number of the CPU.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
MBG_CPU_SET cpu_set;
@@ -5615,25 +8454,29 @@ _MBG_API_ATTR int _MBG_API mbg_set_current_process_affinity_to_cpu( int cpu_num
/*HDR*/
/**
- 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()
- */
+ * @brief Create a new execution thread for the current process.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in] p_ti Pointer to a ::MBG_THREAD_INFO structure to be filled up.
+ * @param[in] fnc The name of the thread function to be started.
+ * @param[in] arg A generic argument passed to the thread function.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
+ MBG_THREAD_FNC fnc, void *arg )
{
- #if defined( MBG_TGT_LINUX )
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
+
+ if ( pthread_create( &p_ti->thread_id, NULL, fnc, arg ) == 0 )
+ return MBG_SUCCESS;
- return pthread_create( &p_ti->thread_id, NULL, fnc, arg );
+ return mbg_get_last_error( NULL );
#elif defined( MBG_TGT_WIN32 )
@@ -5650,19 +8493,19 @@ _MBG_API_ATTR int _MBG_API mbg_thread_create( MBG_THREAD_INFO *p_ti,
if ( h == NULL )
{
CloseHandle( p_ti->exit_request );
- goto fail;
+ goto fail;
}
p_ti->thread_id = h;
- return 0;
+ return MBG_SUCCESS;
fail:
- return GetLastError();
+ return mbg_get_last_error( NULL );
#else
- return -1;
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -5672,25 +8515,30 @@ fail:
/*HDR*/
/**
- 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()
- */
+ * @brief 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 that support threads.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- #if defined( MBG_TGT_LINUX )
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
pthread_cancel( p_ti->thread_id );
- return pthread_join( p_ti->thread_id, NULL );
+ if ( pthread_join( p_ti->thread_id, NULL ) == 0 )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
#elif defined( MBG_TGT_WIN32 )
@@ -5703,14 +8551,14 @@ _MBG_API_ATTR int _MBG_API mbg_thread_stop( MBG_THREAD_INFO *p_ti )
CloseHandle( p_ti->thread_id );
p_ti->thread_id = NULL;
- return 0;
+ return MBG_SUCCESS;
}
- return GetLastError();
+ return mbg_get_last_error( NULL );
#else
- return -1;
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -5720,26 +8568,32 @@ _MBG_API_ATTR int _MBG_API mbg_thread_stop( MBG_THREAD_INFO *p_ti )
/*HDR*/
/**
- 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()
- */
+ * @brief Let the current thread sleep for a certain interval
+ *
+ * The sleep is interrupted if a signal is received indicating
+ * the thread should terminate.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ * @param[in] sleep_ms The number of milliseconds to sleep
+ *
+ * @return MBG_SUCCESS if the sleep interval has expired normally,
+ * MBG_ERR_INTR if a signal to terminate has been received,
+ * or one of the other @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- #if defined( MBG_TGT_LINUX )
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
- usleep( sleep_ms * 1000 );
- return 0;
+ if ( usleep( sleep_ms * 1000 ) == 0 )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
#elif defined( MBG_TGT_WIN32 )
@@ -5748,17 +8602,17 @@ _MBG_API_ATTR int _MBG_API mbg_thread_sleep_interruptible( MBG_THREAD_INFO *p_ti
switch ( dw )
{
case WAIT_OBJECT_0: // has been interrupted to terminate
- return 1;
+ return MBG_ERR_INTR;
case WAIT_TIMEOUT: // sleep interval expired without interruption
- return 0;
+ return MBG_SUCCESS;
}
- return -1;
+ return mbg_get_last_error( NULL );
#else
- return -1;
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -5770,34 +8624,43 @@ _MBG_API_ATTR int _MBG_API mbg_thread_sleep_interruptible( MBG_THREAD_INFO *p_ti
/*HDR*/
/**
- 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()
- */
+ * @brief Set the CPU affinity of a single thread
+ *
+ * This determines on which of the available CPUs the thread
+ * is allowed to be executed.
+ *
+ * This function is only implemented for targets that support thread affinity.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ * @param[in] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
- #if defined( MBG_TGT_LINUX )
+ #if defined( MBG_TGT_LINUX ) // TODO Eventually generally for POSIX?
+
+ if ( pthread_setaffinity_np( tid, sizeof( *p ), p ) == 0 )
+ return MBG_SUCCESS;
- return pthread_setaffinity_np( tid, sizeof( *p ), p );
+ return mbg_get_last_error( NULL );
#elif defined( MBG_TGT_WIN32 )
MBG_CPU_SET prv_thread_affinity = SetThreadAffinityMask( p_ti->thread_id, *p );
- return prv_thread_affinity ? 0 : -1;
+ if ( prv_thread_affinity )
+ return MBG_SUCCESS;
+
+ return mbg_get_last_error( NULL );
#else
- return -1;
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -5809,29 +8672,32 @@ _MBG_API_ATTR int _MBG_API mbg_thread_set_affinity( MBG_THREAD_INFO *p_ti, MBG_C
static /*HDR*/
/**
- A thread function which implements polling of a device at a regular interval.
- At each polling a high resolution time stamp and an associated cycles count
- are saved which can be used to retrieve extrapolated time stamps using the
- cycles counter. The thread also computes the frequency of the system's cycles
- counter.
- 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.
- This function is only implemented for targets which support threads.
-
- @param *p_void Pointer to a ::MBG_POLL_THREAD_INFO structure.
-
- @return ::MBG_SUCCESS or nothing, depending on the taget system.
-
- @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()
- @see mbg_get_xhrt_cycles_frequency()
- */
+ * @brief A thread function implementing polling of a device at regular intervals.
+ *
+ * At each polling a high resolution time stamp and an associated cycles count
+ * are saved which can be used to retrieve extrapolated time stamps using the
+ * cycles counter. The thread also computes the frequency of the system's cycles
+ * counter.
+ *
+ * On systems where the cycles counter is implemented by a CPU's time stamp
+ * counter (TSC) it may be 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.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p_void Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ *
+ * @return ::MBG_SUCCESS or nothing, depending on the taget system.
+ *
+ * @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
+ * @see ::mbg_get_xhrt_cycles_frequency
+ */
MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR mbg_xhrt_poll_thread_fnc( void *p_void )
{
MBG_XHRT_VARS prv_xhrt_vars;
@@ -5849,19 +8715,19 @@ MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR mbg_xhrt_poll_thread_fnc( void *p_voi
int rc = mbg_get_hr_time_cycles( p->dh, &xhrt_vars.htc );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
xhrt_vars.pcps_hr_tstamp64 = pcps_time_stamp_to_uint64( &xhrt_vars.htc.t.tstamp );
if ( prv_xhrt_vars.pcps_hr_tstamp64 && ( ( xhrt_vars.htc.t.status & PCPS_LS_ENB ) == 0 ) )
- freq = ( mbg_delta_pc_cycles( &xhrt_vars.htc.cycles, &prv_xhrt_vars.htc.cycles ) * PCPS_HRT_BIN_FRAC_SCALE )
+ freq = ( mbg_delta_pc_cycles( &xhrt_vars.htc.cycles, &prv_xhrt_vars.htc.cycles ) * MBG_FRAC32_UNITS_PER_SEC )
/ ( xhrt_vars.pcps_hr_tstamp64 - prv_xhrt_vars.pcps_hr_tstamp64 );
}
_mbg_crit_sect_enter( &p->crit_sect );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
p->vars = xhrt_vars;
p->prv_vars = prv_xhrt_vars;
@@ -5877,49 +8743,52 @@ MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR mbg_xhrt_poll_thread_fnc( void *p_voi
_mbg_crit_sect_leave( &p->crit_sect );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
prv_xhrt_vars = xhrt_vars;
- if ( mbg_thread_sleep_interruptible( &p_pti->ti, sleep_ms ) )
+ if ( mbg_rc_is_error( mbg_thread_sleep_interruptible( &p_pti->ti, sleep_ms ) ) )
break;
}
- _mbg_thread_exit( 0 );
+ _mbg_thread_exit( MBG_SUCCESS ); // TODO or an optional error code?
} // mbg_xhrt_poll_thread_fnc
+MBG_THREAD_FNC mbg_xhrt_poll_thread_fnc;
+
/*HDR*/
/**
- 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()
- */
+ * @brief Set up a ::MBG_POLL_THREAD_INFO structure and start a new thread
+ *
+ * The new thread runs a function which periodically reads
+ * a time stamp / cycles pair from a device.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ * @param[in] dh the Handle of the device to be polled.
+ * @param[in] freq_hz The initial cycles frequency, if known, in Hz.
+ * @param[in] 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_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 )
{
- int has_hr_time;
- int rc = mbg_dev_has_hr_time( dh, &has_hr_time );
+ int rc = mbg_chk_dev_has_hr_time( dh );
- if ( ( rc != MBG_SUCCESS ) || !has_hr_time )
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV );
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
memset( p_pti, 0, sizeof( *p_pti ) );
@@ -5938,24 +8807,24 @@ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_create( MBG_POLL_THREAD_INFO *p_
/*HDR*/
/**
- 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()
- */
+ * @brief Stop a polling thread started by ::mbg_xhrt_poll_thread_create
+ *
+ * This call also releases all associated resources.
+ *
+ * @param[in,out] p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ *
+ * @return The result of ::mbg_thread_stop.
+ *
+ * @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 )
{
int rc = mbg_thread_stop( &p_pti->ti );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
_mbg_crit_sect_destroy( &p_pti->xhrt_info.crit_sect );
return rc;
@@ -5964,8 +8833,33 @@ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_stop( MBG_POLL_THREAD_INFO *p_pt
-static /*HDR*/
-int mbg_get_xhrt_data( MBG_XHRT_INFO *p, uint64_t *tstamp, MBG_XHRT_VARS *vars )
+static __mbg_inline /*HDR*/
+/**
+ * @brief Retrieve an extrapolated time stamp
+ *
+ * Get the system's current cycles count and compute the current time
+ * based on last recent time stamp/cycles pair read by the polling thread.
+ *
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in] p Pointer to a ::MBG_XHRT_INFO structure providing data from the polling thread.
+ * @param[out] p_tstamp Optional pointer to a variable to take the extrapolated time stamp, may be NULL.
+ * @param[out] p_vars Optional pointer to a ::MBG_XHRT_VARS structure to be filled up, may be NULL.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
+int mbg_get_xhrt_data( MBG_XHRT_INFO *p, uint64_t *p_tstamp, MBG_XHRT_VARS *p_vars )
{
MBG_XHRT_VARS xhrt_vars;
MBG_PC_CYCLES cyc_now;
@@ -5984,15 +8878,15 @@ int mbg_get_xhrt_data( MBG_XHRT_INFO *p, uint64_t *tstamp, MBG_XHRT_VARS *vars )
if ( freq_hz && xhrt_vars.pcps_hr_tstamp64 )
{
t_now = xhrt_vars.pcps_hr_tstamp64 +
- ( mbg_delta_pc_cycles( &cyc_now, &xhrt_vars.htc.cycles ) * PCPS_HRT_BIN_FRAC_SCALE ) / freq_hz;
+ ( mbg_delta_pc_cycles( &cyc_now, &xhrt_vars.htc.cycles ) * MBG_FRAC32_UNITS_PER_SEC ) / freq_hz;
mbg_chk_tstamp64_leap_sec( &t_now, &xhrt_vars.htc.t.status );
}
- if ( tstamp )
- *tstamp = t_now;
+ if ( p_tstamp )
+ *p_tstamp = t_now;
- if ( vars )
- *vars = xhrt_vars;
+ if ( p_vars )
+ *p_vars = xhrt_vars;
return ioctl_status;
@@ -6002,23 +8896,28 @@ int mbg_get_xhrt_data( MBG_XHRT_INFO *p, uint64_t *tstamp, MBG_XHRT_VARS *vars )
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve an extrapolated time stamp in ::PCPS_HR_TIME format
+ *
+ * The time stamp 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 @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_hrt Pointer to a ::PCPS_HR_TIME structure to be filled up.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_pcps_hr_time( MBG_XHRT_INFO *p, PCPS_HR_TIME *p_hrt )
{
uint64_t tstamp64;
@@ -6047,24 +8946,29 @@ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_pcps_hr_time( MBG_XHRT_INFO *p,
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve an extrapolated time stamp in FILETIME format
+ *
+ * The time stamp 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 @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * Since FILETIME is a Windows-specific type this function is only
+ * implemented under Windows.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_ft Pointer to a FILETIME structure to be filled up.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_filetime( MBG_XHRT_INFO *p, FILETIME *p_ft )
{
uint64_t tstamp64;
@@ -6087,21 +8991,27 @@ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_time_as_filetime( MBG_XHRT_INFO *p, FILE
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve the frequency of the system's cycles counter
+ *
+ * The frequency is determined by the device polling thread.
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_freq_hz Pointer to a ::MBG_PC_CYCLES_FREQUENCY variable in which the frequency is returned.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_MBG_API_ATTR int _MBG_API mbg_get_xhrt_cycles_frequency( MBG_XHRT_INFO *p, MBG_PC_CYCLES_FREQUENCY *p_freq_hz )
{
MBG_PC_CYCLES_FREQUENCY freq_hz;
@@ -6125,35 +9035,32 @@ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_cycles_frequency( MBG_XHRT_INFO *p, MBG_
/*HDR*/
/**
- 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()
- */
+ * @brief Retrieve the system's default cycles counter frequency from the kernel driver
+ *
+ * This API call can be used on systems which don't provide this information in user space.
+ *
+ * @param[in] dh Handle of the device to which the IOCTL call is sent.
+ * @param[out] p Pointer of a ::MBG_PC_CYCLES_FREQUENCY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 )
{
#if defined( _MBGIOCTL_H )
- _mbgdevio_vars();
+ MBGDEVIO_RET_VAL rc;
rc = _mbgdevio_read_var( dh, -1, IOCTL_GET_CYCLES_FREQUENCY, p );
// native endianess, no need to swap bytes
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
*p = 0;
#if defined( MBG_TGT_LINUX )
if ( *p == 0 )
{
- int has_hr_time = 0;
+ rc = mbg_chk_dev_has_hr_time( dh );
- rc = mbg_dev_has_hr_time( dh, &has_hr_time );
-
- if ( rc != MBG_SUCCESS )
- goto done;
-
- if ( has_hr_time )
+ if ( mbg_rc_is_success( rc ) )
{
PCPS_HR_TIME_CYCLES htc1;
PCPS_HR_TIME_CYCLES htc2;
@@ -6162,32 +9069,32 @@ _MBG_API_ATTR int _MBG_API mbg_get_default_cycles_frequency_from_dev( MBG_DEV_HA
rc = mbg_get_hr_time_cycles( dh, &htc1 );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto done;
sleep( 1 );
rc = mbg_get_hr_time_cycles( dh, &htc2 );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto done;
// compute cycles frequency from delta htc
delta_cycles = mbg_delta_pc_cycles( &htc2.cycles, &htc1.cycles );
delta_t = pcps_time_stamp_to_uint64( &htc2.t.tstamp ) - pcps_time_stamp_to_uint64( &htc1.t.tstamp );
- *p = ( delta_cycles * PCPS_HRT_BIN_FRAC_SCALE ) / delta_t;
+ *p = ( delta_cycles * MBG_FRAC32_UNITS_PER_SEC ) / delta_t;
}
}
done:
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
#else
*p = 0;
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_ON_OS );
+ return MBG_ERR_NOT_SUPP_ON_OS;
#endif
@@ -6197,16 +9104,16 @@ done:
/*HDR*/
/**
- Retrieve the default system's cycles counter frequency.
-
- @note This may not be supported on all target platforms, in which case the
- returned frequency is 0 and the mbg_get_default_cycles_frequency_from_dev()
- call should be used.
-
- @return the default cycles counter frequency in Hz, or 0 if the value is not available.
-
- @see mbg_get_default_cycles_frequency_from_dev()
-*/
+ * @brief Retrieve the system's default cycles counter frequency
+ *
+ * @note This may not be supported on all target platforms, in which case the
+ * returned frequency is 0 and the ::mbg_get_default_cycles_frequency_from_dev
+ * call should be used instead.
+ *
+ * @return the default cycles counter frequency in Hz, or 0 if the value is not available.
+ *
+ * @see ::mbg_get_default_cycles_frequency_from_dev
+ */
_MBG_API_ATTR MBG_PC_CYCLES_FREQUENCY _MBG_API mbg_get_default_cycles_frequency( void )
{
#if defined MBG_TGT_WIN32
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.h
index 69cfd5c..440ceda 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgdevio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgdevio.h 1.39.1.20 2011/07/20 15:52:22 martin TRASH $
+ * $Id: mbgdevio.h 1.42 2017/07/05 15:20:32 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,47 +10,50 @@
*
* -----------------------------------------------------------------------
* $Log: mbgdevio.h $
- * Revision 1.39.1.20 2011/07/20 15:52:22 martin
- * Conditionally use older IOCTL request buffer structures.
+ * Revision 1.42 2017/07/05 15:20:32 martin
+ * New MBGDEVIO_VERSION 0x0400, compatibility version unchanged.
+ * Account for MBG_ERROR_CODES returned by the ioctl functions.
+ * New type MBG_DEV_FN used for device file names, formerly often
+ * referred to as 'hardware ID'.
+ * New type MBG_DEV_NAME used for unique device names, composed of
+ * device type name and serial number appended after an underscore.
+ * Renamed and reworked list handling for device lists.
+ * Use functions from new module timeutil.
+ * windows.h is now included in mbg_tgt.h.
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Account for PCPS_HRT_BIN_FRAC_SCALE renamed to MBG_FRAC32_UNITS_PER_SEC.
+ * Fixed macro definition syntax to avoid clang compiler warnings.
+ * Exclude mbg_chk_tstamp64_leap_sec() for BC builds for now.
+ * Lots of new doxygen comments and groups.
+ * Updated function prototypes.
+ * Revision 1.41 2013/09/26 08:54:54 martin
+ * Defined thread function type MBG_THREAD_FNC.
+ * Defined check-if-supported function type MBG_CHK_SUPP_FNC.
+ * Updated function prototypes.
+ * Revision 1.40 2012/10/02 18:40:30Z martin
+ * There are some g++ versions which fail to compile source code using
+ * the macros provided by Linux to define IOCTL codes. If only the API
+ * functions are called by an application then the IOCTL codes aren't
+ * required anyway, so we just avoid inclusion of mbgioctl.h.
+ * Updated doxygen comments.
+ * Updated function prototypes.
+ * Support on-board event logs.
+ * Fixed a bug which caused a crash when generic I/O calls
+ * were used under Windows.
+ * Changes for QNX.
+ * Workaround to make mbgmon (BC) build under Windows.
+ * Cleaned up CPU set support under Linux.
* Moved some macros here so they can be used by other modules.
- * Modified some macros and definitions.
- * Revision 1.39.1.19 2011/07/19 15:46:39 martin
- * Revision 1.39.1.18 2011/07/06 11:19:24 martin
* Support reading CORR_INFO, and reading/writing TR_DISTANCE.
- * Revision 1.39.1.17 2011/06/29 11:10:19 martin
- * Updated function prototypes.
- * Revision 1.39.1.16 2011/06/22 10:16:22 martin
* Cleaned up handling of pragma pack().
* Cleaned up inclusion of header files.
- * Updated function prototypes.
- * Revision 1.39.1.15 2011/04/12 12:57:53 martin
* Moved mutex definitions to new mbgmutex.h.
* Renamed mutex stuff to critical sections.
- * Revision 1.39.1.14 2011/03/31 13:20:55 martin
- * Updated function prototypes.
- * Revision 1.39.1.13 2011/02/15 14:26:22Z martin
- * Revision 1.39.1.12 2011/02/15 11:22:29 daniel
* Updated function prototypes to support PTP unicast configuration
- * Revision 1.39.1.11 2011/02/02 12:21:39Z martin
- * Fixed a type.
- * Revision 1.39.1.10 2011/01/28 09:33:45 martin
- * Cosmetics.
- * Revision 1.39.1.9 2010/12/14 11:23:49 martin
- * Moved definition of MBG_HW_NAME to the header file.
- * Revision 1.39.1.8 2010/12/14 10:56:35Z martin
- * Revision 1.39.1.7 2010/08/11 13:48:53 martin
- * Cleaned up comments.
- * Revision 1.39.1.6 2010/08/11 12:43:52 martin
- * Revision 1.39.1.5 2010/07/15 08:40:57 martin
- * Revision 1.39.1.4 2010/01/08 15:04:17Z martin
- * Revision 1.39.1.3 2010/01/08 11:24:02Z martin
- * Compute and check time of day only if any leap second status bit set.
- * Revision 1.39.1.2 2010/01/08 11:13:57Z martin
* Made xhrt leap second check an inline function.
- * Revision 1.39.1.1 2010/01/07 15:49:37Z martin
* Fixed macro to avoid compiler warning.
* Revision 1.39 2009/12/15 15:34:59Z daniel
- * Support reading the raw IRIG data bits for firmware versions
+ * Support reading the raw IRIG data bits for firmware versions
* which support this feature.
* Revision 1.38.1.2 2009/12/10 09:58:53Z daniel
* Revision 1.38.1.1 2009/12/10 09:45:29Z daniel
@@ -146,11 +149,11 @@
* 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
+ * 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
+ * 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.
@@ -188,20 +191,24 @@
#include <mbg_tgt.h>
#include <mbg_arch.h>
+#include <cfg_hlp.h>
+#include <timeutil.h>
#include <mbgmutex.h>
#include <mbgerror.h>
#include <mbggeo.h>
#include <pcpsdev.h>
#include <pci_asic.h>
#include <use_pack.h>
+
#include <time.h>
+#include <stdio.h>
+#include <errno.h>
-#define MBGDEVIO_VERSION 0x0307
+#define MBGDEVIO_VERSION 0x0400
#define MBGDEVIO_COMPAT_VERSION 0x0210
-#define MBG_MAX_DEVICES 8
#if defined( MBG_TGT_WIN32 )
@@ -218,7 +225,6 @@
#endif
#define MBG_USE_KERNEL_DRIVER 1
- #include <windows.h>
#define MBGDEVIO_RET_VAL DWORD
#define _mbgdevio_cnv_ret_val( _v ) (_v)
@@ -239,13 +245,10 @@
#define MBG_USE_KERNEL_DRIVER 1
#include <sys/ioctl.h>
#include <fcntl.h>
+ #include <sched.h>
- #if !defined( MBG_ARCH_ARM )
- #include <sched.h>
-
- #if MBGDEVIO_USE_THREAD_API
- #include <pthread.h>
- #endif
+ #if MBGDEVIO_USE_THREAD_API
+ #include <pthread.h>
#endif
#elif defined( MBG_TGT_BSD )
@@ -258,6 +261,14 @@
#define MBG_USE_KERNEL_DRIVER 1
+#elif defined( MBG_TGT_QNX_NTO )
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+
+ #include <pcpsdrvr.h>
+
#elif defined( MBG_TGT_DOS )
#if !defined( MBG_USE_DOS_TSR )
@@ -283,6 +294,10 @@
#endif
+#if defined( MBG_TGT_POSIX ) && !defined( MBG_TGT_QNX_NTO )
+ #define MBG_HAS_POSIX_IOCTL 1
+#endif
+
#if !defined( MBGDEVIO_XHRT_API )
#define MBGDEVIO_XHRT_API 0
#endif
@@ -295,8 +310,16 @@
#define MBGDEVIO_HAVE_THREAD_AFFINITY 0
#endif
+#if ( 0 && defined( DEBUG ) )
+ #define DEBUG_IOCTL 1
+#else
+ #define DEBUG_IOCTL 0
+#endif
+
+
#ifdef _MBGDEVIO
#define _ext
+ #define _DO_INIT
#else
#define _ext extern
#endif
@@ -310,9 +333,13 @@
#endif
+#ifdef __cplusplus
+extern "C" {
+#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
+// require some additional mbglib modules to be linked
// to the application.
#if !defined( MBGDEVIO_SIMPLE )
#define MBGDEVIO_SIMPLE 0
@@ -345,42 +372,65 @@
#endif
-#define _mbgdevio_vars() \
- MBGDEVIO_RET_VAL rc
+/**
+ * @brief An string that can take a device file name
+ *
+ * The format of the device file name depends on the type of
+ * operating system.
+ *
+ * On Linux and similar systems this is something like
+ * a regular file name with an index number appended,
+ * e.g. "/dev/mbgclock0". See ::MBGCLOCK_DEV_FN_BASE.
+ *
+ * Under Windows this is a complex string composed of GUIDs,
+ * bus-specific vendor and device ID numbers, etc., which can't
+ * easily be handled manually.
+ */
+typedef char MBG_DEV_FN[260]; // Conforming to MAX_PATH in Windows
-#define _mbgdevio_ret_val \
- _mbgdevio_cnv_ret_val( rc )
+#if MBG_TGT_HAS_DEV_FN
+#define MBGCLOCK_DEV_FN_BASE "/dev/mbgclock"
+#define MBGCLOCK_DEV_FN_FMT MBGCLOCK_DEV_FN_BASE "%i"
-/**
- The type below is used to store a unique ID for a device which
- is made up of the device model name and its serial number, i.e.:
- Format: [model_name]_[serial_number], e.g. "GPS170PCI_028210040670"
- */
-typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1];
+_ext const char mbg_dev_fn_base[]
+#ifdef _DO_INIT
+ = MBGCLOCK_DEV_FN_BASE
+#endif
+;
+
+_ext const char mbg_dev_fn_fmt[]
+#ifdef _DO_INIT
+ = MBGCLOCK_DEV_FN_FMT
+#endif
+;
+
+#endif
-#if defined( MBG_TGT_LINUX ) && !defined( MBG_ARCH_ARM )
+// Definitions specific to the target OS
+
+#if defined( MBG_TGT_LINUX )
#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 defined( __cpu_set_t_defined )
+ #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) )
+ #endif
#if MBGDEVIO_USE_THREAD_API
-
- #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_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)
#endif
#elif defined( MBG_TGT_WIN32 )
@@ -401,12 +451,9 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1];
#if !defined( MBG_TGT_WIN32 )
-
- #define FILETIME int // just a dummy to avoid build errors
-
+ #define FILETIME int // just a dummy to avoid build errors
#endif
-
#if !defined( MBG_PROCESS_ID )
#define MBG_PROCESS_ID int
#endif
@@ -428,7 +475,7 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1];
#endif
#if !defined( _mbg_cpu_set )
- #define _mbg_cpu_set( _i, _ps ) ( *(_ps) |= ( 1UL << (_i) ) )
+ #define _mbg_cpu_set( _i, _ps ) ( *(_ps) |= ( (MBG_CPU_SET) 1UL << (_i) ) )
#endif
#if !defined( _mbg_cpu_isset )
@@ -457,23 +504,57 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1];
#endif
+
+/**
+ * @brief A generic thread info structure
+ */
typedef struct
{
MBG_THREAD_ID thread_id;
#if defined( MBG_TGT_WIN32 )
HANDLE exit_request;
#endif
+
} MBG_THREAD_INFO;
+/**
+ * @brief A generic type of a thread function
+ */
+typedef MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR MBG_THREAD_FNC( void * );
+
+
+
+/**
+ * @brief A structure holding a time stamp / cycles count pair
+ *
+ * This can be used to extrapolate the current time from the current
+ * system cycles count.
+ *
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * @see @ref mbg_xhrt_poll_group
+ */
typedef struct
{
- PCPS_HR_TIME_CYCLES htc;
- uint64_t pcps_hr_tstamp64;
+ PCPS_HR_TIME_CYCLES htc; ///< Cycles count associated with the time stamp
+ uint64_t pcps_hr_tstamp64; ///< Time stamp read from a device
+
} MBG_XHRT_VARS;
+
+/**
+ * @brief A status structure provided by the time polling thread function
+ *
+ * This can be used to get information from the poll thread function
+ * and extrapolate the current time from the current system cycles count.
+ *
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * @see @ref mbg_xhrt_poll_group
+ */
typedef struct
{
MBG_XHRT_VARS vars;
@@ -483,2734 +564,4868 @@ typedef struct
int sleep_ms;
MBG_CRIT_SECT crit_sect;
MBG_DEV_HANDLE dh;
+
} MBG_XHRT_INFO;
+
+/**
+ * @brief A structure used to control a poll thread function
+ *
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * @see ::mbg_xhrt_poll_thread_create
+ * @see ::mbg_xhrt_poll_thread_stop
+ * @see @ref mbg_xhrt_poll_group
+ */
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
+ * @brief Device matching modes
+ *
+ * Match modes to determine how to proceed if a device with
+ * particular model type and serial number has not been detected.
*/
-enum MBG_MATCH_MODE
+enum MBG_MATCH_MODES
{
- 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 */
+ MBG_MATCH_ANY, ///< use the next device available on the system
+ MBG_MATCH_MODEL, ///< use the next available device of the same type
+ MBG_MATCH_EXACTLY, ///< use only exactly the excat matching device, otherwise fail
+ N_MBG_MATCH_MODES ///< 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;
-
+/**
+ * @brief An entry for a list of device file names
+ *
+ * Applications should consider this type as opaque,
+ * and must not rely on the type, number, and order of
+ * the structure members.
+ */
+typedef struct _MBG_DEV_FN_LIST_ENTRY MBG_DEV_FN_LIST_ENTRY;
-typedef struct _MBG_DEVICENAME_LIST
+/**
+ * @brief The structure behind the ::MBG_DEV_FN_LIST_ENTRY type
+ *
+ * Applications should consider this structure as opaque,
+ * and must not rely on the type, number, and order of
+ * the structure members.
+ *
+ * The definition is still in the header file since it
+ * is still required by some Windows-specific code.
+ */
+struct _MBG_DEV_FN_LIST_ENTRY
{
- char device_name[40]; /**< readable name */
- struct _MBG_DEVICENAME_LIST *next;
+ char *dev_fn_ptr; ///< Address of an OS-specific device file name
+ ///< that can be used with an OS-specific open call.
+ MBG_DEV_FN_LIST_ENTRY *next;
+};
-} MBG_DEVICENAME_LIST;
+/**
+ * @brief An entry for a list of device names
+ *
+ * Applications should consider this type as opaque,
+ * and must not rely on the type, number, and order of
+ * the structure members.
+ *
+ * @see ::mbg_find_devices_with_names
+ * @see ::mbg_free_device_name_list
+ */
+typedef struct _MBG_DEV_NAME_LIST_ENTRY MBG_DEV_NAME_LIST_ENTRY;
-/* function prototypes: */
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * @brief The structure behind the ::MBG_DEV_NAME_LIST_ENTRY type
+ *
+ * Applications should actually consider this structure as opaque,
+ * and must not rely on the type, number, and order of
+ * the structure members.
+ *
+ * The definition is still in the header file since it is still
+ * used by some Windows-specific code.
+ */
+struct _MBG_DEV_NAME_LIST_ENTRY
+{
+ char dev_name[40]; ///< Readable device name (Should be ::MBG_DEV_NAME, which is smaller, though)
+ MBG_DEV_NAME_LIST_ENTRY *next;
+};
-/* ----- function prototypes begin ----- */
-/* This section was generated automatically */
-/* by MAKEHDR, do not remove the comments. */
- MBGDEVIO_RET_VAL do_mbg_ioctl( MBG_DEV_HANDLE dh, int ioctl_code, const void *in_p, int in_sz, void *out_p, int out_sz ) ;
- /**
- 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.
+/**
+ * @defgroup mbgdevio_open_fncs API functions that can be used to open a device
+ *
+ * Each of these functions can be used to open a device to obtain a valid
+ * ::MBG_DEV_HANDLE handle which can be used with subsequent API calls to
+ * access the particular device.
+ *
+ * If the device fails to be opened then each of these functions returns
+ * ::MBG_INVALID_DEV_HANDLE, and an OS-specific "last error" code is set
+ * accordingly. The caller can then use ::mbg_get_last_error immediately
+ * to retrieve the OS-specific error code, convert it, and return the
+ * associated Meinberg-specific error code. See @ref MBG_ERROR_CODES.
+ *
+ * Operating systems maintain a list of devices that are currently
+ * present in a system. The function ::mbg_open_device expects a number
+ * that is used as an index to this list. If only a single supported device
+ * is present then index 0 can always be used to open that device.
+ *
+ * The function ::mbg_find_devices can be used to retrieve the number of
+ * devices statically present in the system, and the highest index number
+ * that can be used is the number of devices - 1.
+ *
+ * In a plug-and-play system the device list maintained by the operating
+ * system may change over time, for example if a USB device is plugged in
+ * or out during operation. In this case index numbers may change, and may
+ * not always refer to the same device.
+ *
+ * So the function ::mbg_open_device_by_name can be used instead to open
+ * a specific device identified by model name and optionally serial number.
+ * See ::MBG_DEV_NAME for the format of such device name.
+ *
+ * If a list of unique device names is required e.g. to set up a
+ * device selection dialog in a GUI application then the function
+ * ::mbg_find_devices_with_names can be used to allocate and set up
+ * such a list. When the list has been evaluated and isn't needed
+ * anymore then ::mbg_free_device_name_list should be called to free
+ * the allocated memory.
+ *
+ * Inside the operating system the device is always identified by a
+ * device file name which can be used internally with an OS-specific
+ * "open" function, e.g. "open" on POSIX systems, or ""CreateFile"
+ * on Windows.
+ *
+ * While the device file name is a complex string under Windows,
+ * under Linux and similar systems this is just a device node name
+ * like "/dev/mbgclock0" which can easily be used to specify a
+ * particular device. See ::MBG_DEV_FN.
+ *
+ * On such systems the function ::mbg_open_device_by_dev_fn can be used
+ * to open a device specified by a device file name.
+ *
+ * @see ::mbg_open_device
+ * @see ::mbg_find_devices
+ * @see ::mbg_open_device_by_name
+ * @see ::mbg_find_devices_with_names
+ * @see ::mbg_open_device_by_dev_fn
+ * @see ::mbg_close_device
+ */
- @return The version number
- @see ::MBGDEVIO_VERSION defined in mbgdevio.h.
- */
- _MBG_API_ATTR int _MBG_API mbgdevio_get_version( void ) ;
+/**
+ * @defgroup mbgdevio_hr_time_fncs API functions reading high resolution time, plus status
+ *
+ * These functions return a high resolution time, including status flags and
+ * local time offset according to the time zone configuration on the device.
+ *
+ * The API call ::mbg_chk_dev_has_hr_time checks if these functions are supported
+ * by a device.
+ *
+ * Due to the extended information returned to the caller these function
+ * require interaction with the on-board microcontroller, and thus take
+ * longer to execute than the @ref mbgdevio_fast_timestamp_fncs.
+ *
+ * <b>Note:</b> These API calls provides better accuracy and higher resolution
+ * than the the standard functions in @ref mbgdevio_legacy_time_fncs.
+ *
+ * The ::mbg_get_hr_time function doesn't account for the latency
+ * which is introduced when accessing the board.
+ *
+ * The ::mbg_get_hr_time_cycles and ::mbg_get_hr_time_comp calls
+ * provide ways to account for and/or compensate the latency.
+ *
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
- /**
- 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.
+/**
+ * @defgroup mbgdevio_fast_timestamp_fncs Fast API functions reading high resolution timestamps, but no status
+ *
+ * These functions are fast, but return only the UTC time. No status flags,
+ * no time zone offset. The time stamps are read from a latched counter chain
+ * in the PCI chip set, so this is only supported by cards whose chip set supports this.
+ *
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
- @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 ) ;
+/**
+ * @defgroup mbgdevio_legacy_time_fncs Legacy API functions to read the time
+ *
+ * These functions are supported by all devices, but return time only
+ * as a ::PCPS_TIME structure, which provides local time according to the
+ * local time zone configured on the device, and with 10 ms resolution only.
+ *
+ * <b>Note:</b> The @ref mbgdevio_hr_time_fncs or @ref mbgdevio_fast_timestamp_fncs
+ * should be used preferably, if the device supports these.
+ *
+ * @see ::mbg_get_time
+ * @see ::mbg_get_time_cycles
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
- /**
- 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.
+/**
+ * @defgroup mbgdevio_chk_supp_fncs mbgdevio functions used to check if a particular feature is supported
+ * @ingroup chk_supp_fncs
+ *
+ * These functions can be used to check if a device supports a particular feature.
+ *
+ * ::MBG_SUCCESS is returned if the requested feature is supported,
+ * ::MBG_ERR_NOT_SUPP_BY_DEV if the feature is not supported, or one of the other
+ * @ref MBG_ERROR_CODES is returned if an error occurred when trying to determine
+ * if the feature is supported, e.g. if the IOCTL call itself failed.
+ */
- @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.
+/**
+ * @defgroup mbgdevio_chk_supp_fncs_deprecated Deprecated mbgdevio functions to check if a particular feature is supported
+ * @ingroup chk_supp_fncs
+ *
+ * @deprecated These functions are deprecated. Use the @ref mbgdevio_chk_supp_fncs preferably.
+ *
+ * These are the original functions that were introduced to check if a device supports
+ * a particular feature. The functions are deprecated, but will be kept for compatibility.
+ *
+ * The functions return ::MBG_SUCCESS if the information could be retrieved with out error,
+ * and an error code otherwise, e.g. if the IOCTL call itself failed.
+ *
+ * Only in case of success an integer variable the address of which has to be passed to the
+ * function is set to 1 or 0 depending on whether the requested feature is supported, or not.
+ * So the calling application always has to check 2 values after such function had been called.
+ *
+ * To make applications simpler the @ref mbgdevio_chk_supp_fncs have been introduced instead,
+ * which can be used in a much easier way.
+ *
+ * @see @ref mbgdevio_chk_supp_fncs
+ */
- <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 ) ;
+/**
+ * @defgroup mbg_xhrt_poll_group Extrapolation of high resolution time stamps
+ *
+ * ::TODO
+ */
- /**
- 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).
+/**
+ * @brief The type of functions to check if a feature is supported
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see @ref mbgdevio_chk_supp_fncs
+ */
+typedef int _MBG_API MBG_CHK_SUPP_FNC( MBG_DEV_HANDLE dh );
- @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
+/* ----- function prototypes begin ----- */
- @see mbg_find_devices_with_names()
- */
- _MBG_API_ATTR void _MBG_API mbg_free_device_name_list( MBG_DEVICENAME_LIST *list) ;
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
/**
- 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().
+ * @brief Get the version number of the precompiled DLL/shared object library
+ *
+ * If this library is used as a DLL/shared object library then the version
+ * number can be checked to see if the header files which are actually used
+ * to build an application are compatible with the header files which have
+ * been used to build the library, and thus the API function are called
+ * in the correct way.
+ *
+ * @return The version number
+ *
+ * @see ::mbgdevio_check_version
+ * @see ::MBGDEVIO_VERSION defined in mbgdevio.h
+ */
+ _MBG_API_ATTR int _MBG_API mbgdevio_get_version( void ) ;
- @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
+ /**
+ * @brief Check if the DLL/shared library is compatible with a given version
+ *
+ * If this library is used as a DLL/shared object library then the version
+ * number can be checked to see if the header files which are actually used
+ * to build an application are compatible with the header files which have
+ * been used to build the library, and thus the API functions are called
+ * in the correct way.
+ *
+ * @param[in] header_version Version number to be checked, should be ::MBGDEVIO_VERSION
+ * from the mbgdevio.h file version used to build the application
+ *
+ * @return ::MBG_SUCCESS if compatible, else ::MBG_ERR_LIB_NOT_COMPATIBLE
+ *
+ * @see ::mbgdevio_get_version
+ * @see ::MBGDEVIO_VERSION defined in mbgdevio.h
+ */
+ _MBG_API_ATTR int _MBG_API mbgdevio_check_version( int header_version ) ;
- @return On success, the function returns a handle to the device, otherwise ::MBG_INVALID_DEV_HANDLE
+ /**
+ * @brief Check if a device supports the ::RECEIVER_INFO structure and related calls.
+ *
+ * Very old devices may not provide a ::RECEIVER_INFO structure.
+ * The ::mbg_setup_receiver_info call should be used preferably to set up
+ * a ::RECEIVER_INFO for a device. That function uses this call to determine
+ * whether a ::RECEIVER_INFO can be read directly from a device, or sets up
+ * a default structure using default values depending on the device type.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_receiver_info,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_get_gps_receiver_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_receiver_info( MBG_DEV_HANDLE dh ) ;
- @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 ) //##++++
-;
+ /**
+ * @brief Check if a device supports large configuration data structures.
+ *
+ * Such structures have been introduced with the first Meinberg GPS receivers.
+ * Mostly all configuration structures are large data structures, and mostly all
+ * current devices support this, but some old devices may not.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_gps_data,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_gps_data( MBG_DEV_HANDLE dh ) ;
/**
- Close a handle to a device and set the handle value to ::MBG_INVALID_DEV_HANDLE.
- If required, unmap mapped memory.
+ * @brief Check if a device supports the ::mbg_generic_io API call.
+ *
+ * <b>Warning</b>: This call is for debugging purposes and internal use only!
+ *
+ * @note This function should be preferred over ::mbg_dev_has_generic_io,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_generic_io
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_generic_io( MBG_DEV_HANDLE dh ) ;
- @param dev_handle Handle to a Meinberg device.
- */
- _MBG_API_ATTR void _MBG_API mbg_close_device( MBG_DEV_HANDLE *dev_handle ) ;
+ /**
+ * @brief Check if a device supports the ::mbg_get_asic_version API call.
+ *
+ * If ::mbg_get_asic_version is supported, or not, depends on
+ * the bus interface chip assembled on the device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_asic_version,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_asic_version
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_asic_version( MBG_DEV_HANDLE dh ) ;
/**
- Return a ::PCPS_DRVR_INFO structure that provides information
- about the kernel device driver.
+ * @brief Check if a device supports the ::mbg_get_asic_features call.
+ *
+ * If ::mbg_get_asic_features is supported, or not, depends on
+ * the bus interface chip assembled on the device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_asic_features,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_asic_features
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_asic_features( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_DRVR_INFO structure which is filled up.
+ /**
+ * @brief Check if a device provides eXtended Multi Ref (XMR) inputs.
+ *
+ * Devices providing XMR inputs can receive or decode different timing
+ * signals in parallel, and the supported sources can be prioritized.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_xmr,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_xmr( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if the device is connected via the ISA bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the ISA bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_isa( MBG_DEV_HANDLE dh ) ;
/**
- Return a ::PCPS_DEV structure that provides detailed information about the device.
+ * @brief Check if the device is connected via the MCA bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the MCA bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_mca( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_DEV structure to be filled up
+ /**
+ * @brief Check if the device is connected via the PCI bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the PCI bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_pci( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if the device is connected via the PCI Express bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the PCI Express bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_pci_express( MBG_DEV_HANDLE dh ) ;
/**
- Return the current state of the on-board::PCPS_STATUS_PORT.
+ * @brief Check if the device is connected via the USB bus
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the device is connected via the USB bus,
+ * else ::MBG_ERR_NOT_SUPP_BY_DEV
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_usb( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_STATUS_PORT value to be filled up
+ /**
+ * @brief Check if a device supports GNSS configuration
+ *
+ * This is usually the case if a device supports reception of
+ * different satellite systems, e.g. GPS, Glonass, Galileo, etc.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_gnss,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_gnss( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function
+ /**
+ * @brief Check if a device is a GPS receiver
+ *
+ * The function also returns ::MBG_SUCCESS for GNSS receivers
+ * which can track GPS satellites beside other GNSS systems.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_gps,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_gps( MBG_DEV_HANDLE dh ) ;
- @see \ref group_status_port "bitmask"
- */
- _MBG_API_ATTR int _MBG_API mbg_get_status_port( MBG_DEV_HANDLE dh, PCPS_STATUS_PORT *p ) ;
+ /**
+ * @brief Check if a device is a DCF77 receiver.
+ *
+ * Beside standard DCF77 receivers which receive the legacy AM signal
+ * there are also PZF receivers which can decode the pseudo-random phase
+ * modulation and thus yield a higher accuracy. See ::mbg_chk_dev_has_pzf.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_dcf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_dcf( MBG_DEV_HANDLE dh ) ;
- /* (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.
+ /**
+ * @brief Check if a device supports demodulation of the DCF77 PZF code
+ *
+ * Beside the enhanced PZF correlation receivers which decode the DCF77's
+ * pseudo-random phase modulation to yield a better accuracy there are also
+ * legacy DCF77 receivers which just decode the standard AM signal.
+ * See ::mbg_chk_dev_is_dcf.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_pzf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_corr_info
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_chk_dev_is_dcf
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_pzf( MBG_DEV_HANDLE dh ) ;
- <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.
+ /**
+ * @brief Check if a device is a MSF receiver
+ *
+ * @note This function should be preferred over ::mbg_dev_is_msf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_msf( MBG_DEV_HANDLE dh ) ;
- @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
+ /**
+ * @brief Check if a device is a WWVB receiver
+ *
+ * @note This function should be preferred over ::mbg_dev_is_wwvb,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_wwvb( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device is a JJY receiver.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_jjy( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device is any long wave signal receiver
+ *
+ * Long wave receivers include e.g. DCF77, MSF, WWVB, or JJY.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_lwr,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_dcf
+ * @see ::mbg_chk_dev_is_msf
+ * @see ::mbg_chk_dev_is_wwvb
+ * @see ::mbg_chk_dev_is_jjy
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_lwr( MBG_DEV_HANDLE dh ) ;
- /* (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 ) ;
+ /**
+ * @brief Check if a device provides a configurable IRIG input.
+ *
+ * @note This function should be preferred over ::mbg_dev_is_irig_rx,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_has_irig
+*/
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_is_tcr( MBG_DEV_HANDLE dh ) ;
- /* (Intentionally excluded from Doxygen)
- Generic write function which writes a command code plus an
- associated number of data bytes to the device.
+ /**
+ * @brief Check if a device supports simple LAN interface API calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_lan_intf,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_lan_intf( MBG_DEV_HANDLE dh ) ;
- <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.
+ /**
+ * @brief Check if a device supports PTP configuration/status calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ptp,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ptp( MBG_DEV_HANDLE dh ) ;
- @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
+ /**
+ * @brief Check if a device supports PTP unicast feature/configuration
+ *
+ * Not all devices which support PTP do also support PTP Unicast. This API
+ * call checks if PTP Unicast is supported in addition to the standard
+ * PTP multicast.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ptp_unicast,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ptp_unicast( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the mbg_get_hr_time... functions
+ *
+ * @note This function should be preferred over ::mbg_dev_has_hr_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_hr_time( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports the mbg_get_fast_hr_timestamp... calls
+ *
+ * @note This function should be preferred over ::mbg_dev_has_fast_hr_timestamp,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh ) ;
- /* (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 ) ;
+ /**
+ * @brief Check if a device supports configurable time scales.
+ *
+ * By default the devices return %UTC and/or local time. However, some cards
+ * can be configured to return raw GPS time or TAI instead.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_time_scale,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_time_scale_info
+ * @see ::mbg_set_time_scale_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_time_scale( MBG_DEV_HANDLE dh ) ;
/* (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.
+ * @brief Check if a device supports setting an event time
+ *
+ * This feature is only supported by some special custom firmware
+ * to preset a %UTC time at which the clock is to generate an output signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_event_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_set_event_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_event_time( MBG_DEV_HANDLE dh ) ;
- <b>Warning</b>: This call is for debugging purposes and internal use only!
+ /**
+ * @brief Check if a device supports the ::mbg_get_ucap_entries and ::mbg_get_ucap_event calls
+ *
+ * If the device doesn't support this but 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.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ucap,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @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_chk_dev_has_ucap( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the ::mbg_clr_ucap_buff call
+ *
+ * The ::mbg_clr_ucap_buff call can be used to clear a device's on-board
+ * time capture FIFO buffer, but the call may not be supported by some
+ * older GPS devices.
+ *
+ * @note This function should be preferred over ::mbg_dev_can_clr_ucap_buff,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_clr_ucap_buff
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_can_clr_ucap_buff( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports timezone configuration using the ::TZDL structure
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tzdl,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_tzdl
+ * @see ::mbg_set_gps_tzdl
+ * @see ::mbg_chk_dev_has_tz
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tzdl( MBG_DEV_HANDLE dh ) ;
/**
- 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).
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZDL structure
+ *
+ * @note This function should be preferred over ::mbg_dev_has_pcps_tzdl,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_chk_dev_has_tz
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_pcps_tzdl( MBG_DEV_HANDLE dh ) ;
- 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.
+ /**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZCODE type.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tzcode,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_chk_dev_has_tz
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tzcode( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME structure to be filled up
+ /**
+ * @brief Check if a device supports any kind of timezone configuration.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tz,
+ * which has been deprecated.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_tzdl
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_chk_dev_has_tzcode
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tz( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device provides either an IRIG input or output.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig( MBG_DEV_HANDLE dh ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device provides a configurable IRIG output.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_tx_info
+ * @see ::mbg_set_irig_tx_settings
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig
+ * @see @ref group_icode
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_tx( MBG_DEV_HANDLE dh ) ;
/**
- 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.
+ * @brief Check if a device supports the ::mbg_get_irig_ctrl_bits call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig_ctrl_bits,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_ctrl_bits
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_STIME structure to be written
+ /**
+ * @brief Check if a device supports the ::mbg_get_raw_irig_data call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_raw_irig_data,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_raw_irig_data
+ * @see ::mbg_get_raw_irig_data_on_sec_change
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_raw_irig_data( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the ::mbg_get_irig_time call
+ *
+ * @note This function should be preferred over ::mbg_dev_has_irig_time,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_irig_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_irig_time( MBG_DEV_HANDLE dh ) ;
- @see mbg_get_time()
- */
- _MBG_API_ATTR int _MBG_API mbg_set_time( MBG_DEV_HANDLE dh, const PCPS_STIME *p ) ;
+ /**
+ * @brief Check if a device provides the level of its inputs signal
+ *
+ * This is useful to display the signal level of e.g. an IRIG or similar
+ * time code, or a long wave signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_signal,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_signal( MBG_DEV_HANDLE dh ) ;
/**
- 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.
+ * @brief Check if a device provides a modulation signal
+ *
+ * Modulation signals are e.g. the second marks provided by a long wave receiver.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_mod,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_mod( MBG_DEV_HANDLE dh ) ;
- The macro _pcps_has_sync_time() checks whether this call
- is supported by a specific card.
+ /* (Intentionally excluded from Doxygen)
+ * @brief Check if a device supports higher baud rates than usual
+ *
+ * Check if a device provides a serial output that supports
+ * higher baud rates than older cards, i.e. ::DEFAULT_BAUD_RATES_DCF_HS
+ * rather than ::DEFAULT_BAUD_RATES_DCF.
+ *
+ * The call ::mbg_get_serial_settings takes care of this, so applications
+ * which use that call as suggested don't need to use this call directly.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_serial_hs,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_serial_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_serial_hs( MBG_DEV_HANDLE dh ) ;
- <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.
+ /**
+ * @brief Check if a device provides a programmable frequency synthesizer
+ *
+ * @note This function should be preferred over ::mbg_dev_has_synth,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_synth
+ * @see ::mbg_set_synth
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_synth( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME structure to be filled up
+ /**
+ * @brief Check if a device provides GPIO signal inputs and/or outputs
+ *
+ * @note This function should be preferred over ::mbg_dev_has_gpio,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_gpio( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports configuration of antenna cable length
+ *
+ * @note This function should be preferred over ::mbg_dev_has_cab_len,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_gps_ant_cable_len
+ * @see ::mbg_set_gps_ant_cable_len
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_cab_len( MBG_DEV_HANDLE dh ) ;
- @see mbg_get_time()
- */
- _MBG_API_ATTR int _MBG_API mbg_get_sync_time( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
+ /**
+ * @brief Check if a device provides a configurable ref time offset
+ *
+ * This may be required to convert the received time to %UTC, if the input
+ * signal doesn't specify this (e.g. with most IRIG code formats).
+ *
+ * @note This function should be preferred over ::mbg_dev_has_ref_offs,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_ref_offs
+ * @see ::mbg_set_ref_offs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_ref_offs( MBG_DEV_HANDLE dh ) ;
/**
- Wait until the next second change, then return a ::PCPS_TIME
- structure similar to mbg_get_time().
+ * @brief Check if a device supports the ::MBG_OPT_INFO/::MBG_OPT_SETTINGS.
+ *
+ * These structures contain optional settings, controlled by flags.
+ * See ::MBG_OPT_SETTINGS and associated definitions.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_opt_flags,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_opt_info
+ * @see ::mbg_set_opt_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_opt_flags( MBG_DEV_HANDLE dh ) ;
- <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.
+ /**
+ * @brief Check if a device support reading/writing of UTC parameters.
+ *
+ * This API call checks if a device supports reading/writing a GPS %UTC
+ * parameter set via the PC bus. Reading/writing these parameters via the
+ * serial port using the Meinberg binary data protocol is supported by all
+ * Meinberg GPS and GNSS devices.
+ *
+ * The %UTC parameter set is usually received from the satellites' broadcasts
+ * and contains the current time offset between GPS time and UTC, plus information
+ * on a pending leap second event.
+ *
+ * It may be useful to overwrite them to do some tests, or for applications
+ * where a card is freewheeling.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_utc_parm,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_utc_parm
+ * @see ::mbg_set_utc_parm
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_utc_parm( MBG_DEV_HANDLE dh ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME structure to be filled up
+ /**
+ * @brief Check if a device supports reading correlation info
+ *
+ * The PZF phase modulation decoded by DCF77 PZF receivers is decoded
+ * using a correlation approach, and optionally there's an API call
+ * supported which can be used to retrieve the correlation value
+ * and thus determine the quality of the input signal.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_corr_info,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_get_corr_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_corr_info( MBG_DEV_HANDLE dh ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports configurable distance from transmitter
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * @note This function should be preferred over ::mbg_dev_has_tr_distance,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_get_tr_distance
+ * @see ::mbg_set_tr_distance
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_tr_distance( MBG_DEV_HANDLE dh ) ;
- @see mbg_get_time()
- */
- _MBG_API_ATTR int _MBG_API mbg_get_time_sec_change( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
+ /**
+ * @brief Check if a device provides a debug status word to be read
+ *
+ * @note This function should be preferred over ::mbg_dev_has_debug_status,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_get_debug_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_debug_status( MBG_DEV_HANDLE dh ) ;
/**
- 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.
+ * @brief Check if a device provides an on-board event log
+ *
+ * @note This function should be preferred over ::mbg_dev_has_evt_log,
+ * which has been deprecated.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+ _MBG_API_ATTR int _MBG_API mbg_chk_dev_has_evt_log( MBG_DEV_HANDLE dh ) ;
- <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.
+ /**
+ * @brief Check if a device supports the ::RECEIVER_INFO structure and related calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_receiver_info preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_receiver_info
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_receiver_info" ) _MBG_API mbg_dev_has_receiver_info( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ /**
+ * @brief Check if a device supports large configuration data structures
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_gps_data preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_gps_data
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_gps_data" ) _MBG_API mbg_dev_has_gps_data( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the ::mbg_generic_io API call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_generic_io preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_generic_io
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_generic_io" ) _MBG_API mbg_dev_has_generic_io( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports the ::mbg_get_asic_version call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_asic_version preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_asic_version
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_asic_version" ) _MBG_API mbg_dev_has_asic_version( MBG_DEV_HANDLE dh, int *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.
+ /**
+ * @brief Check if a device supports the ::mbg_get_asic_features call.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_asic_features preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_asic_features
+ * @see ::mbg_get_asic_features
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_asic_features" ) _MBG_API mbg_dev_has_asic_features( MBG_DEV_HANDLE dh, int *p ) ;
- <b>Note:</b> This is only supported by some special firmware.
+ /**
+ * @brief Check if a device provides extended multi ref (XMR) inputs.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_xmr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_xmr
+ * @see @ref group_multi_ref_ext
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_xmr" ) _MBG_API mbg_dev_has_xmr( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME_STAMP structure to be written
+ /**
+ * @brief Check if a device supports GNSS configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_gnss preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_gnss
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_gnss" ) _MBG_API mbg_dev_is_gnss( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device is a GPS receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_gps preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_gps
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_gps" ) _MBG_API mbg_dev_is_gps( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device is a DCF77 receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_dcf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_dcf
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_dcf" ) _MBG_API mbg_dev_is_dcf( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports demodulation of the DCF77 PZF code
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_pzf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_pzf
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_pzf" ) _MBG_API mbg_dev_has_pzf( MBG_DEV_HANDLE dh, int *p ) ;
- <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.
+ /**
+ * @brief Check if a device is a MSF receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_msf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_msf
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_msf" ) _MBG_API mbg_dev_is_msf( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_SERIAL structure to be filled up
+ /**
+ * @brief Check if a device is a WWVB receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_wwvb preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_wwvb
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_wwvb" ) _MBG_API mbg_dev_is_wwvb( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device is any long wave signal receiver
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_lwr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_lwr
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_lwr" ) _MBG_API mbg_dev_is_lwr( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device provides a configurable IRIG input.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_is_tcr preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_is_tcr
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_is_tcr" ) _MBG_API mbg_dev_is_irig_rx( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports simple LAN interface API calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_lan_intf preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_lan_intf
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_lan_intf" ) _MBG_API mbg_dev_has_lan_intf( MBG_DEV_HANDLE dh, int *p ) ;
- <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.
+ /**
+ * @brief Check if a device supports PTP configuration/status calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ptp preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ptp
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ptp" ) _MBG_API mbg_dev_has_ptp( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_SERIAL structure to be written
+ /**
+ * @brief Check if a device supports PTP unicast feature/configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ptp_unicast preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ptp_unicast" ) _MBG_API mbg_dev_has_ptp_unicast( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the HR_TIME functions
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_hr_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_hr_time
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_hr_time" ) _MBG_API mbg_dev_has_hr_time( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports the mbg_get_fast_hr_timestamp_...() calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_fast_hr_timestamp preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_fast_hr_timestamp" ) _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports configurable time scales
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_time_scale preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_time_scale
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_time_scale" ) _MBG_API mbg_dev_has_time_scale( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TZCODE structure to be filled up
+ /**
+ * @brief Check if a device supports setting an event time
+ *
+ * @note This is only supported by some customized devices
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_event_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_event_time
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_event_time" ) _MBG_API mbg_dev_has_event_time( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the ::mbg_get_ucap_entries and ::mbg_get_ucap_event calls
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ucap preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ucap
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ucap" ) _MBG_API mbg_dev_has_ucap( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports the ::mbg_clr_ucap_buff call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_can_clr_ucap_buff preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_can_clr_ucap_buff
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_can_clr_ucap_buff" ) _MBG_API mbg_dev_can_clr_ucap_buff( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports timezone configuration using the ::TZDL structure
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tzdl preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tzdl
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tzdl" ) _MBG_API mbg_dev_has_tzdl( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TZCODE structure to be written
+ /**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZDL structure
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_pcps_tzdl preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_pcps_tzdl" ) _MBG_API mbg_dev_has_pcps_tzdl( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports timezone configuration using the ::PCPS_TZCODE type
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tzcode preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tzcode
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tzcode" ) _MBG_API mbg_dev_has_tzcode( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports any kind of timezone configuration
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tz preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tz
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tz" ) _MBG_API mbg_dev_has_tz( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device provides either an IRIG input or output
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig" ) _MBG_API mbg_dev_has_irig( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TZDL structure to be filled up
+ /**
+ * @brief Check if a device provides a configurable IRIG output
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_tx preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_tx
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_tx" ) _MBG_API mbg_dev_has_irig_tx( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device supports the ::mbg_get_irig_ctrl_bits call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_ctrl_bits preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_ctrl_bits
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_ctrl_bits" ) _MBG_API mbg_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports the ::mbg_get_raw_irig_data call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_raw_irig_data preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_raw_irig_data" ) _MBG_API mbg_dev_has_raw_irig_data( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports the ::mbg_get_irig_time call
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_irig_time preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_irig_time
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_irig_time" ) _MBG_API mbg_dev_has_irig_time( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TZDL structure to be written
+ /**
+ * @brief Check if a device provides the level of its inputs signal
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_signal preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_signal
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_signal" ) _MBG_API mbg_dev_has_signal( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device provides a modulation signal
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_mod preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_mod
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_mod" ) _MBG_API mbg_dev_has_mod( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /* (Intentionally excluded from Doxygen)
+ * @brief Check if a device supports higher baud rates than usual
+ *
+ * Check if a device provides a serial output that supports
+ * higher baud rates than older cards, i.e. ::DEFAULT_BAUD_RATES_DCF_HS
+ * rather than ::DEFAULT_BAUD_RATES_DCF.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_serial_hs preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_serial_hs
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_serial_hs" ) _MBG_API mbg_dev_has_serial_hs( MBG_DEV_HANDLE dh, int *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
+ * @brief Check if a device provides a programmable frequency synthesizer
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_synth preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_synth
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_synth" ) _MBG_API mbg_dev_has_synth( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device provides GPIO signal inputs and/or outputs
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_gpio preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_gpio
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_gpio" ) _MBG_API mbg_dev_has_gpio( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports configuration of antenna cable length
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_cab_len preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_cab_len
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_cab_len" ) _MBG_API mbg_dev_has_cab_len( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device provides a configurable ref time offset
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_ref_offs preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_ref_offs
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_ref_offs" ) _MBG_API mbg_dev_has_ref_offs( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_REF_OFFS value to be written
+ /**
+ * @brief Check if a device supports the ::MBG_OPT_INFO/::MBG_OPT_SETTINGS
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_opt_flags preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_opt_flags
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_opt_flags" ) _MBG_API mbg_dev_has_opt_flags( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device support reading/writing of ::UTC parameters
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_utc_parm preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_utc_parm
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_utc_parm" ) _MBG_API mbg_dev_has_utc_parm( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Check if a device supports reading correlation info
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_corr_info preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_corr_info
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_corr_info" ) _MBG_API mbg_dev_has_corr_info( MBG_DEV_HANDLE dh, int *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.
+ * @brief Check if a device supports configurable distance from transmitter
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_tr_distance preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_tr_distance
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_tr_distance" ) _MBG_API mbg_dev_has_tr_distance( MBG_DEV_HANDLE dh, int *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_OPT_INFO structure to be filled up
+ /**
+ * @brief Check if a device provides a debug status word to be read
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_debug_status preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_debug_status
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_debug_status" ) _MBG_API mbg_dev_has_debug_status( MBG_DEV_HANDLE dh, int *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Check if a device provides an on-board event log.
+ *
+ * @deprecated This function is deprecated, use ::mbg_chk_dev_has_evt_log preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an int which is updated if the API call succeeds.
+ * The flag is set != 0 if the requested feature is supported, else 0.
+ *
+ * @return ::MBG_SUCCESS on success, if *p has been updated, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_chk_supp_fncs_deprecated
+ * @see ::mbg_chk_dev_has_evt_log
+ */
+ _MBG_API_ATTR int _DEPRECATED_BY( "mbg_chk_dev_has_evt_log" ) _MBG_API mbg_dev_has_evt_log( MBG_DEV_HANDLE dh, int *p ) ;
- @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 ) ;
+ /**
+ * @brief Create a device file name according to an index number
+ *
+ * Create a system-specific device file name string, e.g. "/dev/mbgclock0"
+ * under Linux and similar systems, which can be used with the
+ * open() call on systems which support this.
+ *
+ * Under Windows a hardware ID string is used, so a Windows-specific function
+ * is called to retrieve the string
+ *
+ * @param[out] s Pointer to the output buffer.
+ * @param[in] max_len Size of the output buffer.
+ * @param[in] dev_idx The device index number.
+ *
+ * @see mbg_svc_get_device_path under Windows
+ */
+ _MBG_API_ATTR int _MBG_API mbg_dev_fn_from_dev_idx( char *s, int max_len, int dev_idx ) ;
/**
- 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.
+ * @brief Open a device by index number
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_idx Device index number, starting from 0.
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ */
+ MBG_DEV_HANDLE _MBG_API mbg_open_device( int dev_idx ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_OPT_SETTINGS structure to be written
+ /**
+ * @brief Open a device specified by a device file name
+ *
+ * The format the device file name depends on the operating system.
+ * see ::MBG_DEV_FN.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_fn The device file name
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_FN
+ */
+ _MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device_by_dev_fn( const char *dev_fn ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Open a device specified by a device file name
+ *
+ * @deprecated This function is deprecated, use
+ * ::mbg_open_device_by_dev_fn preferably.
+ *
+ * The format the device file name depends on the operating system.
+ * see ::MBG_DEV_FN.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] dev_fn The device file name, see ::MBG_DEV_FN
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_FN
+ */
+ _MBG_API_ATTR MBG_DEV_HANDLE _DEPRECATED_BY( "mbg_open_device_by_dev_fn" ) _MBG_API mbg_open_device_by_hw_id( const char *dev_fn ) ;
- @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 ) ;
+ /**
+ * @brief Get the number of devices installed on the computer
+ *
+ * The function ::mbg_find_devices_with_names should eventually
+ * be used preferafly. See @ref mbgdevio_open_fncs.
+ *
+ * @return The number of devices found
+ *
+ * @see ::mbg_find_devices_with_names
+ * @see ::mbg_open_device
+ * @see @ref mbgdevio_open_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_find_devices( void ) ;
/**
- 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.
+ * @brief Allocate memory and set up a list of installed and supported devices
+ *
+ * Allocate and fill a list with the names of Meinberg devices currently
+ * present in the system.
+ *
+ * This can be used e.g. to populate a device selection dialog
+ * in a configuration program.
+ *
+ * When the list is not used anymore it can be freed by calling
+ * ::mbg_free_device_name_list.
+ *
+ * @param[in] p_list Pointer to a linked list to be allocated.
+ * @param[in] max_devices Maximum number of devices to be searched for
+ * (must not exceed ::N_SUPP_DEV_BUS).
+ *
+ * @return The number of present devices
+ *
+ * @see ::mbg_free_device_name_list
+ * @see ::mbg_find_devices
+ * @see ::MBG_DEV_NAME
+ */
+ _MBG_API_ATTR int _MBG_API mbg_find_devices_with_names( MBG_DEV_NAME_LIST_ENTRY **p_list, int max_devices ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an ::IRIG_INFO structure to be filled up
+ /**
+ * @brief Free the memory allocated for a list of ::MBG_DEV_NAME_LIST_ENTRY entries.
+ *
+ * The list may have been set up and allocated before
+ * by ::mbg_find_devices_with_names.
+ *
+ * @param[in,out] list Linked list of ::MBG_DEV_NAME_LIST_ENTRY entries.
+ *
+ * @see ::mbg_find_devices_with_names
+ */
+ _MBG_API_ATTR void _MBG_API mbg_free_device_name_list( MBG_DEV_NAME_LIST_ENTRY *list ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Return a handle to a device with a particular device name
+ *
+ * See ::MBG_DEV_NAME for the possible formats of a device name.
+ *
+ * For details and similar functions see @ref mbgdevio_open_fncs.
+ *
+ * @param[in] srch_name String with the ::MBG_DEV_NAME of a device to be opened
+ * @param[in] selection_mode One of the ::MBG_MATCH_MODES
+ *
+ * @return A valid device handle on success, else ::MBG_INVALID_DEV_HANDLE
+ *
+ * @ingroup mbgdevio_open_fncs
+ * @see ::mbg_close_device
+ * @see @ref mbgdevio_open_fncs
+ * @see ::MBG_DEV_NAME
+ * @see ::MBG_MATCH_MODES
+ */
+ _MBG_API_ATTR MBG_DEV_HANDLE _MBG_API mbg_open_device_by_name( const char *srch_name, int selection_mode ) ;
- @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 ) ;
+ /**
+ * @brief Close a device handle and set the handle value to ::MBG_INVALID_DEV_HANDLE
+ *
+ * @param[in,out] dev_handle Pointer to a Meinberg device handle
+ *
+ * @see @ref mbgdevio_open_fncs
+ */
+ _MBG_API_ATTR void _MBG_API mbg_close_device( MBG_DEV_HANDLE *dev_handle ) ;
/**
- 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.
+ * @brief Read information about the driver handling a given device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::PCPS_DRVR_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_drvr_info( MBG_DEV_HANDLE dh, PCPS_DRVR_INFO *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::IRIG_SETTINGS structure to be written
+ /**
+ * @brief Read detailed device information
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] *p A ::PCPS_DEV structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_device_info( MBG_DEV_HANDLE dh, PCPS_DEV *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read the current state of the on-board ::PCPS_STATUS_PORT
+ *
+ * This function is useful to read the device's status port which
+ * also includes the ::PCPS_ST_MOD bit reflecting the time code
+ * modulation of long wave receivers.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::PCPS_STATUS_PORT value to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see @ref group_status_port "bitmask" //### TODO check syntax
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_status_port( MBG_DEV_HANDLE dh, PCPS_STATUS_PORT *p ) ;
- @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 ) ;
+ /* (Intentionally excluded from Doxygen)
+ * Generic read function which writes a command code to a 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.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd Can be any @ref PCPS_CMD_CODES "command code" supported by the device
+ * @param[out] p Pointer to a buffer to be filled up
+ * @param[in] size Size of the output buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 ) ;
- /**
- Check if a specific device supports the mbg_get_irig_ctrl_bits() call.
+ /* (Intentionally excluded from Doxygen)
+ * Generic read function which writes a GPS command code to a device
+ * and reads a number of data bytes back into a generic buffer.
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[out] p Pointer to a buffer to be filled up
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+ /* (Intentionally excluded from Doxygen)
+ * Generic write function which writes a command code plus an
+ * associated number of data bytes to a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[in] p Pointer to a buffer of data to be written
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /* (Intentionally excluded from Doxygen)
+ * Generic write function which writes a GPS command code plus an
+ * associated number of data bytes to a device.
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This is for debugging purposes only!
+ * The specialized API calls should be used preferably.
+ * Not all devices support each of the ::PC_GPS_COMMANDS.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] cmd One of the ::PCPS_CMD_CODES supported by the device.
+ * @param[in] p Pointer to a buffer of data to be written
+ * @param[in] size Size of the buffer, has to match the expected data size associated with cmd
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 ) ;
- @see mbg_get_irig_ctrl_bits()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh, int *p ) ;
+ /* (Intentionally excluded from Doxygen)
+ * Write and/or read generic data to/from a device.
+ * The function ::mbg_chk_dev_has_generic_io checks
+ * whether this call is supported by a device.
+ *
+ * <b>Warning</b>: This call is for debugging purposes and internal use only!
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 ::MBG_IRIG_CTRL_BITS type which contains the control function
- bits of the latest IRIG input frame. Those bits may carry some
- well-known information, as in the IEEE1344 code, but may also contain
- some customized information, depending on the IRIG frame type and
- the configuration of the IRIG generator. So these bits are returned
- as-is and must be interpreted by the application.
- The macro _pcps_has_irig_ctrl_bits() or the API call mbg_dev_has_irig_ctrl_bits()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_IRIG_CTRL_BITS type to be filled up
+ * @brief 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) only.
+ *
+ * This call is supported by any device manufactured by Meinberg.
+ * However, for higher accuracy and resolution the @ref mbgdevio_hr_time_fncs or
+ * the @ref mbgdevio_fast_timestamp_fncs group of calls should be used preferably,
+ * if supported by the device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @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 ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Set the device's on-board clock to a given date and time.
+ *
+ * The macro ::_pcps_can_set_time checks whether
+ * this call is supported by a device.
+ *
+ * @todo Provide an API function replacing ::_pcps_can_set_time.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_STIME structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_time( MBG_DEV_HANDLE dh, const PCPS_STIME *p ) ;
- @see mbg_dev_has_irig_ctrl_bits()
-*/
- _MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh, MBG_IRIG_CTRL_BITS *p ) ;
+ /**
+ * @brief Read the time when the device has last recently synchronized
+ *
+ * Fills a ::PCPS_TIME structure with the date/time/status reporting
+ * when the device was synchronized the last time to its time source,
+ * e.g. the DCF77 signal, the GPS satellites, or similar.
+ *
+ * The macro ::_pcps_has_sync_time checks whether
+ * this call is supported by a device.
+ *
+ * <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 set".
+ *
+ * @todo Provide an API function replacing ::_pcps_has_sync_time.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_sync_time( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
/**
- Check if a specific device supports the mbg_get_raw_irig_data() call.
+ * @brief Wait until the next second change, then return current time
+ *
+ * Returns time in 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. The accuracy of this call is limited
+ * to a few milliseconds.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @see ::mbg_get_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_time_sec_change( MBG_DEV_HANDLE dh, PCPS_TIME *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+ /**
+ * @brief Read the card's current time with high resolution, including status
+ *
+ * Fills up a ::PCPS_HR_TIME (High Resolution time) structure containing
+ * the current %UTC time (seconds since 1970), %UTC offset, and status.
+ *
+ * The API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by a device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_hr_time( MBG_DEV_HANDLE dh, PCPS_HR_TIME *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /* (Intentionally excluded from Doxygen )
+ * Write a high resolution time stamp ::PCPS_TIME_STAMP to a device
+ * to configure a %UTC time when the clock shall generate an event.
+ * The API call ::mbg_chk_dev_has_event_time checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This is only supported by some special firmware.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TIME_STAMP structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_event_time
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_event_time( MBG_DEV_HANDLE dh, const PCPS_TIME_STAMP *p ) ;
- @see mbg_get_raw_irig_data()
- @see mbg_get_raw_irig_data_on_sec_change()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_raw_irig_data( MBG_DEV_HANDLE dh, int *p ) ;
+ /**
+ * @brief Read the serial port configuration from an old type of device
+ *
+ * @deprecated Direct usage of this function is deprecated. The generic
+ * API function ::mbg_get_serial_settings should be used instead
+ * which fully supports the capabilities of current devices.
+ *
+ * The macro ::_pcps_has_serial checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_SERIAL structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_serial( MBG_DEV_HANDLE dh, PCPS_SERIAL *p ) ;
/**
- Read a ::MBG_RAW_IRIG_DATA type which contains all data
- bits of the latest IRIG input frame.
- The macro _pcps_has_raw_irig_data() or the API call mbg_dev_has_raw_irig_data()
- check whether this call is supported by a specific card.
+ * @brief Write the serial port configuration to an old type of device
+ *
+ * @deprecated Direct usage of this function is deprecated. The generic
+ * API function ::mbg_save_serial_settings should be used instead
+ * which fully supports the capabilities of current devices.
+ *
+ * The macro ::_pcps_has_serial checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_SERIAL structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_serial( MBG_DEV_HANDLE dh, const PCPS_SERIAL *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
+ /**
+ * @brief Read time zone/daylight saving configuration code from a device.
+ *
+ * The APIs using ::TZCODE are only supported by some simpler cards
+ * and allow just a very basic configuration.
+ *
+ * The API call ::mbg_chk_dev_has_tzcode checks whether
+ * this call is supported by a device.
+ *
+ * Other devices 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TZCODE structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_tzcode
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_get_gps_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_tzcode( MBG_DEV_HANDLE dh, PCPS_TZCODE *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Write time zone/daylight saving configuration code to a device.
+ *
+ * The APIs using ::TZCODE are only supported by some simpler cards
+ * and allow just a very basic configuration.
+ *
+ * The API call ::mbg_chk_dev_has_tzcode checks whether
+ * this call is supported by a device.
+ *
+ * Other devices 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TZCODE structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_tzcode
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_set_gps_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_tzcode( MBG_DEV_HANDLE dh, const PCPS_TZCODE *p ) ;
- @see mbg_dev_has_raw_irig_data()
- @see mbg_get_raw_irig_data_on_sec_change()
-*/
- _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ;
+ /**
+ * @brief Read time zone/daylight saving parameters from a device.
+ *
+ * This function fills up a ::PCPS_TZDL structure which supports a more
+ * detailed configuration of time zone and daylight saving than the ::TZCODE
+ * structure.
+ *
+ * The API call ::mbg_chk_dev_has_pcps_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * Other devices may support the ::mbg_get_tzcode or ::mbg_get_gps_tzdl
+ * calls instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TZDL structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_set_pcps_tzdl
+ * @see ::mbg_get_tzcode
+ * @see ::mbg_get_gps_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_pcps_tzdl( MBG_DEV_HANDLE dh, PCPS_TZDL *p ) ;
/**
- Read a ::MBG_RAW_IRIG_DATA type just after a second change which contains all data
- bits of the latest IRIG input frame.
- The macro _pcps_has_raw_irig_data() or the API call mbg_dev_has_raw_irig_data()
- check whether this call is supported by a specific card.
+ * @brief Write time zone/daylight saving parameters to a device.
+ *
+ * This function passes a ::PCPS_TZDL structure to a device which supports
+ * a more detailed configuration of time zone and daylight saving than the
+ * ::TZCODE structure.
+ *
+ * The API call ::mbg_chk_dev_has_pcps_tzdl checks whether
+ * this call is supported by a device.
+ * Other cards may support the ::mbg_set_tzcode or ::mbg_set_gps_tzdl
+ * calls instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PCPS_TZDL structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pcps_tzdl
+ * @see ::mbg_get_pcps_tzdl
+ * @see ::mbg_set_tzcode
+ * @see ::mbg_set_gps_tzdl
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_pcps_tzdl( MBG_DEV_HANDLE dh, const PCPS_TZDL *p ) ;
- <b>Note:</b> The mbg_get_time_sec_change() function called by this function is
- supported under Windows only, so this function can also only be used under Windows.
+ /**
+ * @brief Read the %UTC offset configuration of the reference time from a device
+ *
+ * This parameter is used to specify the %UTC offset of an incoming
+ * reference time signal if a kind of time signal e.g. an IRIG input
+ * signal) does not provide this information.
+ *
+ * The API call ::mbg_chk_dev_has_ref_offs checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_REF_OFFS value to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ref_offs
+ * @see ::mbg_set_ref_offs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_ref_offs( MBG_DEV_HANDLE dh, MBG_REF_OFFS *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
+ /**
+ * @brief Write the %UTC offset configuration of the reference time to a device.
+ *
+ * This parameter is used to specify the %UTC offset of an incoming
+ * reference time signal if a kind of time signal e.g. an IRIG input
+ * signal) does not provide this information.
+ *
+ * The API call ::mbg_chk_dev_has_ref_offs checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::MBG_REF_OFFS value to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ref_offs
+ * @see ::mbg_get_ref_offs
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_ref_offs( MBG_DEV_HANDLE dh, const MBG_REF_OFFS *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief 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 API call ::mbg_chk_dev_has_opt_flags checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_OPT_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 ) ;
- @see mbg_dev_has_raw_irig_data()
- @see mbg_get_raw_irig_data()
-*/
- _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data_on_sec_change( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ;
+ /**
+ * @brief Write a ::MBG_OPT_SETTINGS structure containing optional device settings.
+ *
+ * The API call ::mbg_chk_dev_has_opt_flags checks whether
+ * this call is supported by a device.
+ *
+ * ::mbg_get_opt_info should be called first to check which of
+ * the specified flags is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_OPT_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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 ) ;
/**
- Check if a specific device supports the mbg_get_irig_time() call.
+ * @brief Read the current IRIG input settings plus capabilities
+ *
+ * @deprecated Calling this function directly is deprecated. The function
+ * ::mbg_get_all_irig_rx_info should be used instead which also reads some
+ * other associated parameters affecting the behaviour of the IRIG input.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] *p An ::IRIG_INFO structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_all_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_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 ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+ /**
+ * @brief Write an ::IRIG_SETTINGS structure to a device to configure an IRIG input.
+ *
+ * @deprecated Calling this function directly is deprecated. The function
+ * ::mbg_save_all_irig_rx_settings should be used instead which also writes some
+ * other associated parameters affecting the behaviour of the IRIG input.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ * ::mbg_get_irig_rx_info should be called first to determine
+ * the possible settings supported by the device's IRIG input.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::IRIG_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_all_irig_rx_settings
+ * @see ::mbg_get_irig_rx_info
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_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 ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read all IRIG input configuration information from a device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] pdev Pointer to the device's ::PCPS_DEV structure //### TODO Make this obsolete
+ * @param[in] p_irig_info Pointer to a ::IRIG_SETTINGS structure to be written
+ * @param[in] p_ref_offs Pointer to a ::MBG_REF_OFFS structure to be written
+ * @param[in] p_opt_info Pointer to a ::MBG_OPT_SETTINGS structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_all_irig_rx_settings
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_set_ref_offs
+ * @see ::mbg_set_opt_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_all_irig_rx_info( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, IRIG_INFO *p_irig_info, MBG_REF_OFFS *p_ref_offs, MBG_OPT_INFO *p_opt_info ) ;
- @see mbg_get_irig_time()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_irig_time( MBG_DEV_HANDLE dh, int *p ) ;
+ /**
+ * @brief Write all IRIG input configuration settings to a device.
+ *
+ * The API call ::mbg_chk_dev_is_tcr checks whether
+ * this call is supported by a device.
+ * ::mbg_get_all_irig_rx_info should be called before to determine
+ * the possible settings supported by the IRIG input.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] pdev Pointer to the device's ::PCPS_DEV structure //### TODO Make this obsolete
+ * @param[out] p_irig_settings Pointer to a ::IRIG_SETTINGS structure to be written
+ * @param[out] p_ref_offs Pointer to a ::MBG_REF_OFFS structure to be written
+ * @param[out] p_opt_settings Pointer to a ::MBG_OPT_SETTINGS structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_all_irig_rx_info
+ * @see ::mbg_set_irig_rx_settings
+ * @see ::mbg_set_ref_offs
+ * @see ::mbg_set_opt_settings
+ */
+ _MBG_API_ATTR int _MBG_API mbg_save_all_irig_rx_settings( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const IRIG_SETTINGS *p_irig_settings, const MBG_REF_OFFS *p_ref_offs, const MBG_OPT_SETTINGS *p_opt_settings ) ;
/**
- Read a ::PCPS_IRIG_TIME type which returns the raw IRIG day-of-year number
- and time decoded from the latest IRIG input frame. If the configured IRIG code
- also contains the year number then the year number is also returned, otherwise
- the returned year number is 0xFF.
- The macro _pcps_has_irig_time() or the API call mbg_dev_has_irig_time()
- check whether this call is supported by a specific card.
+ * @brief Read the control function bits received from an incoming IRIG signal.
+ *
+ * This function fills an ::MBG_IRIG_CTRL_BITS structure with the control function
+ * bits decoded from the incoming IRIG signal.
+ *
+ * The meaning of these bits depends on the type of IRIG code frame format.
+ *
+ * In some IRIG formats these bits provide some well-known information which can
+ * also be evaluated by the device. For example, in IEEE 1344 or IEEE C37.118 code
+ * the control function bits are used to provide the year number, UTC offset,
+ * DST status, leap second warning, etc.
+ *
+ * For most IRIG code formats, however, these bits are reserved, i.e. not used
+ * at all, or application defined, depending on the configuration of the IRIG
+ * generator providing the IRIG signal.
+ *
+ * In the latter case the application has to evaluate the received control function
+ * bits and can use this function to retrieve these bits from the receiver device.
+ *
+ * The API call ::mbg_chk_dev_has_irig_ctrl_bits checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_IRIG_CTRL_BITS type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_irig_ctrl_bits
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh, MBG_IRIG_CTRL_BITS *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_IRIG_TIME type to be filled up
+ /**
+ * @brief Read raw IRIG data from an IRIG receiver.
+ *
+ * This function reads an ::MBG_RAW_IRIG_DATA structure with the raw data bits received
+ * from the incoming IRIG signal. This enables an application itself to decode the
+ * information provided by the IRIG signal.
+ *
+ * The API call ::mbg_chk_dev_has_raw_irig_data checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ * @see ::mbg_get_raw_irig_data_on_sec_change
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Wait for second changeover then read raw IRIG data from an IRIG receiver.
+ *
+ * This function waits until the second of the device's on-board time rolls over,
+ * and then reads the last recent raw IRIG data from the device.
+ *
+ * The API call ::mbg_chk_dev_has_raw_irig_data checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> The ::mbg_get_time_sec_change function called
+ * by this function is supported under Windows only, so this function
+ * can also be used under Windows only.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_RAW_IRIG_DATA type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_raw_irig_data
+ * @see ::mbg_get_raw_irig_data
+ * @see ::mbg_get_time_sec_change
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data_on_sec_change( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ;
- @see mbg_dev_has_irig_time()
-*/
+ /**
+ * @brief Read the IRIG time and day-of-year number from an IRIG receiver.
+ *
+ * Reads a ::PCPS_IRIG_TIME structure with the raw IRIG day-of-year number
+ * and time decoded from the latest IRIG input frame. If the configured IRIG code
+ * also contains the year number then the year number is also returned, otherwise
+ * the returned year number is 0xFF.
+ *
+ * The API call ::mbg_chk_dev_has_irig_time checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_IRIG_TIME type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_irig_time
+ */
_MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh, PCPS_IRIG_TIME *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()
- */
+ * @brief Clear a device's on-board time capture FIFO buffer.
+ *
+ * The API call ::mbg_chk_dev_can_clr_ucap_buff checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
- */
+ * @brief Read information on a device's event capture buffer.
+ *
+ * Reads a ::PCPS_UCAP_ENTRIES structure with the number of user capture
+ * events actually stored in the FIFO buffer, and the maximum number of
+ * events that can be held by the buffer.
+ *
+ * The API call ::mbg_chk_dev_has_ucap checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_UCAP_ENTRIES structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
- */
+ * @brief Retrieve a single time capture event from the on-board FIFO buffer
+ *
+ * The capture event is returned in a ::PCPS_HR_TIME structure. The oldest entry
+ * in 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 API call ::mbg_chk_dev_has_ucap checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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
- */
+ * @brief Read the card's time zone/daylight saving parameters
+ *
+ * This function returns the time zone/daylight saving parameters
+ * in a ::TZDL structure.
+ *
+ * The API call ::mbg_chk_dev_has_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TZDL structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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
- */
+ * @brief Write the card's time zone/daylight saving parameters.
+ *
+ * This function writes the time zone/daylight saving parameters
+ * in a ::TZDL structure to a device.
+ *
+ * The API call ::mbg_chk_dev_has_tzdl checks whether
+ * this call is supported by a device.
+ *
+ * <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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TZDL structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
- */
+ * @brief Retrieve the software revision of a GPS receiver
+ *
+ * @deprecated This function is deprecated.
+ *
+ * This function is deprecated, but still supported
+ * for compatibility with older GPS cards. Normally
+ * the software revision is part of the ::RECEIVER_INFO
+ * structure. See ::mbg_setup_receiver_info which takes
+ * care of the different options.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SW_REV structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_chk_dev_is_gps
+ */
_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.
-*/
+ * @brief Retrieve the status of the battery buffered GPS variables.
+ *
+ * GPS receivers require some navigational data set to be available
+ * to be able to decode position and time accurately. This data set
+ * is transmitted periodically by the satellites, so it can
+ * simply be collected if it's not available.
+ *
+ * The ::BVAR_STAT type reports which parts of the data set are
+ * available in the receiver, and which are not.
+ *
+ * If the available data set is not complete then the receiver
+ * stays in COLD BOOT mode until all data have been received
+ * and thus all data sets are valid.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::BVAR_STAT structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_is_gps
+ * @see ::BVAR_FLAGS
+ */
_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.
-*/
+ * @brief Read the current board time using a ::TTM structure
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This API call is pretty slow, so ::mbg_get_hr_time or
+ * ::mbg_get_fast_hr_timestamp or associated calls should be used preferably.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TTM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_fast_hr_timestamp
+ */
_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.
-*/
+ * @brief Set the time on a GPS receiver device
+ *
+ * Write a ::TTM structure to a GPS receiver in order to set
+ * the on-board date and time. Date and time must be local time
+ * according to the device's on-board time zone configuration
+ * (::TZDL).
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TTM structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_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()
-*/
+ * @brief Read a ::PORT_PARM structure with a device's serial port configuration.
+ *
+ * @deprecated This function is deprecated, use ::mbg_get_serial_settings preferably.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This function is deprecated since it is only
+ * supported by a certain class of devices and can handle only
+ * up to 2 serial ports. The generic function ::mbg_get_serial_settings
+ * should be used instead.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PORT_PARM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Write a ::PORT_PARM structure to configure the on-board serial ports.
+ *
+ * @deprecated This function is deprecated, use ::mbg_save_serial_settings preferably.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> This function is deprecated 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_PARM structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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.
-*/
+ * @brief Read an ::ANT_INFO structure to retrieve an extended GPS antenna status.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <b>Note:</b> Normally the current antenna connection status can also be
+ * determined by evaluation of the ::PCPS_TIME::signal or ::PCPS_HR_TIME::signal
+ * fields. The "disconnected" status reported by ::ANT_INFO disappears only if
+ * the antenna has been reconnected <b>and</b> the receiver has synchronized
+ * to the GPS satellites again.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::ANT_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
_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()
-*/
+ * @brief Read a time capture event from the on-board FIFO buffer using a ::TTM structure
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * <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 device. Anyway, this call is still supported for compatibility
+ * with older devices which don't support ::mbg_get_ucap_event.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TTM structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Read the ::ENABLE_FLAGS structure controlling when outputs are to be enabled
+ *
+ * The ::ENABLE_FLAGS structure controls whether certain signal outputs
+ * are to be enabled immediately after the device's power-up, or only
+ * after the device has synchronized to its input signal.
+ *
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Not all of the input signals specified for the
+ * ::ENABLE_FLAGS structure can be modified individually.
+ * See ::ENABLE_FLAGS_CODES.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::ENABLE_FLAGS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::ENABLE_FLAGS
+ * @see ::ENABLE_FLAGS_CODES
+ * @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()
-*/
+ * @brief Write an ;;ENABLE_FLAGS structure to configure when outputs shall be enabled.
+ *
+ * The ::ENABLE_FLAGS structure controls whether certain signal outputs
+ * are to be enabled immediately after the device's power-up, or only
+ * after the device has synchronized to its input signal.
+ *
+ * The function ::mbg_chk_dev_has_gps_data can be used to check
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Not all of the input signals specified for the
+ * ::ENABLE_FLAGS structure can be modified individually.
+ * See ::ENABLE_FLAGS_CODES.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ENABLE_FLAGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::ENABLE_FLAGS
+ * @see ::ENABLE_FLAGS_CODES
+ * @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
-*/
+ * @brief Read the extended GPS receiver status from a device.
+ *
+ * The ::STAT_INFO structure reports the status of the GPS receiver,
+ * including mode of operation and number of visible/usable satellites.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::STAT_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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
-*/
+ * @brief Send one of the ::PC_GPS_COMMANDS to a GPS receiver device
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::GPS_CMD
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::PC_GPS_COMMANDS
+ */
_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()
-*/
+ * @brief Read the current geographic position from a GPS device.
+ *
+ * The returned ::POS structure contains the current position in
+ * ECEF (Earth Centered, Earth Fixed) kartesian coordinates, and in
+ * geographic coordinates with different formats, using the WGS84
+ * geographic datum.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::POS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Set the GPS receiver position using ::XYZ coordinates
+ *
+ * The structure ::XYZ must specify the new position in ECEF
+ * (Earth Centered, Earth Fixed) kartesian coordinates.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Position in ::XYZ format to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Set the GPS receiver position using ::LLA coordinates
+ *
+ * The structure ::LLA must specify the new position as longitude,
+ * latitude, and altitude, using the WGS84 geographic datum.
+ *
+ * The API call ::mbg_chk_dev_is_gps checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Position in ::LLA format to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Read the configured antenna cable length from a device
+ *
+ * The antenna cable length parameter is used by GPS/GNSS receivers
+ * to compensate the propagation delay of the RF signal over the antenna
+ * cable, which is about 5 ns/m.
+ *
+ * The API call ::mbg_chk_dev_has_cab_len checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::ANT_CABLE_LEN structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
-*/
+ * @brief Write the GPS antenna cable length configuration to a device.
+ *
+ * The antenna cable length parameter is used by GPS/GNSS receivers
+ * to compensate the propagation delay of the RF signal over the antenna
+ * cable, which is about 5 ns/m.
+ *
+ * The API call ::mbg_chk_dev_has_cab_len checks whether
+ * this call is supported by a device.
+ *
+ * @note Different devices may accept different maximum values, so the
+ * written value should be re-read using ::mbg_get_gps_ant_cable_len
+ * to check if the parameter has been accepted.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::ANT_CABLE_LEN structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
-*/
+ * @brief Read the ::RECEIVER_INFO structure from a device
+ *
+ * The API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> Applications should call ::mbg_setup_receiver_info
+ * preferably, which also sets up a basic ::RECEIVER_INFO structure
+ * for devices which don't provide that structure by themselves.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::RECEIVER_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_setup_receiver_info
+ * @see ::mbg_chk_dev_has_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 ) ;
+ * @brief Read a ::STR_TYPE_INFO_IDX array of supported string types.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be passed to this function.
+ *
+ * <b>Note:</b> The function ::mbg_get_serial_settings should be used preferably
+ * to get retrieve the current port settings and configuration options.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] stii Pointer to a an array of string type information to be filled up.
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ * @see ::mbg_get_gps_all_port_info
+ * @see ::mbg_setup_receiver_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_str_type_info( MBG_DEV_HANDLE dh, STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ;
/**
- 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 ) ;
+ * @brief Read a ::PORT_INFO_IDX array of supported serial port configurations.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be passed to this function.
+ *
+ * <b>Note:</b> The function ::mbg_get_serial_settings should be used preferably
+ * to get retrieve the current port settings and configuration options.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of port configuration information to be filled up.
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_serial_settings
+ * @see ::mbg_get_gps_all_str_type_info
+ * @see ::mbg_setup_receiver_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_port_info( MBG_DEV_HANDLE dh, PORT_INFO_IDX pii[], const RECEIVER_INFO *p_ri ) ;
/**
- 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 ) ;
+ * @brief Write the configuration for a single serial port to a device.
+ *
+ * The ::PORT_SETTINGS_IDX structure 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 API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> The function ::mbg_save_serial_settings should be used preferably
+ * to write new port configuration to the board.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_SETTINGS_IDX structure to be written
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ * @see ::mbg_set_gps_port_settings
+ * @see ::mbg_chk_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 ) ;
/**
- 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 ) ;
+ * @brief Write the configuration for a single serial port to a device.
+ *
+ * The ::PORT_SETTINGS structure does not contain the port index, so the
+ * the port index must be given separately. Except for the parameter types
+ * this call is equivalent to ::mbg_set_gps_port_settings_idx.
+ *
+ * The API call ::mbg_chk_dev_has_receiver_info checks
+ * whether this call is supported by a device.
+ *
+ * <b>Note:</b> The function ::mbg_save_serial_settings should be used preferably
+ * to write new port configuration to the board.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::PORT_SETTINGS structure to be written.
+ * @param[in] idx Index of the serial port to be configured (starting from 0).
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_save_serial_settings
+ * @see ::mbg_set_gps_port_settings_idx
+ * @see ::mbg_chk_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 ) ;
/**
- 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 ) ;
+ * @brief 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.
+ *
+ * Optionally, the function ::mbg_get_device_info may have been called
+ * before, and the returned ::PCPS_DEV structure can be passed to this
+ * function.
+ *
+ * If a NULL pointer is passed instead, the device info is retrieved
+ * directly from the device, using the device handle.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p_dev Optional pointer to a ::PCPS_DEV structure, may be NULL.
+ * @param[out] p Pointer to a ::RECEIVER_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_device_info
+ * @see ::mbg_chk_dev_has_receiver_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_setup_receiver_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, RECEIVER_INFO *p ) ;
/**
- 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()
-*/
+ * @brief Read the version code of the on-board PCI/PCIe interface ASIC.
+ *
+ * The API call ::mbg_chk_dev_has_asic_version checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCI_ASIC_VERSION type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
-*/
+ * @brief Read the features of the on-board PCI/PCIe interface ASIC
+ *
+ * The API call ::mbg_chk_dev_has_asic_features checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCI_ASIC_FEATURES type to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_asic_features
+ */
_MBG_API_ATTR int _MBG_API mbg_get_asic_features( MBG_DEV_HANDLE dh, PCI_ASIC_FEATURES *p ) ;
/**
- Check if a specific device supports configurable time scales.
-
- By default the cards return UTC and/or local time. However, some cards
- can be configured to return pure GPS time or TAI instead.
-
- @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_time_scale_info()
- @see mbg_set_time_scale_settings()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_time_scale( MBG_DEV_HANDLE dh, int *p ) ;
-
- /**
- Read a ::MBG_TIME_SCALE_INFO structure from a card telling which time scales
- are supported by a card, and the current settings of the card.
-
- The macro _pcps_has_time_scale() or the API call mbg_dev_has_time_scale()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_time_scale().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_SCALE_INFO structure to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_set_time_scale_settings()
- @see mbg_dev_has_time_scale()
-*/
+ * @brief Read the current time scale settings and which time scales are supported
+ *
+ * The ::MBG_TIME_SCALE_INFO structure tells which time scale settings are supported
+ * by a device, and which time scale is currently configured.
+ *
+ * The API call ::mbg_chk_dev_has_time_scale checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_time_scale.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_SCALE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_time_scale_settings
+ * @see ::mbg_chk_dev_has_time_scale
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_scale_info( MBG_DEV_HANDLE dh, MBG_TIME_SCALE_INFO *p ) ;
/**
- Write a ::MBG_TIME_SCALE_SETTINGS structure to a card which determines
- which time scale shall be represented by time stamps read from the card.
-
- The macro _pcps_has_time_scale() or the API call mbg_dev_has_time_scale()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_time_scale().
-
- The function mbg_get_time_scale_info() should have been called before
- in order to determine which time scales are supported by the card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_SCALE_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_get_time_scale_info()
- @see mbg_dev_has_time_scale()
-*/
- _MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, MBG_TIME_SCALE_SETTINGS *p ) ;
-
- /**
- Check if a specific device supports reading/writing a GPS UTC parameter
- set via the PC bus (reading/writing these parameters via the serial port
- is supported by all GPS devices).
-
- The UTC parameters are normally received from the satellites' broadcasts
- and contain the current time offset between GPT time and UTC, plus information
- on a pending leap second.
-
- It may be useful to overwrite them to do some tests, or for applications
- where a card is freewheeling.
-
- @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_utc_parm()
- @see mbg_set_utc_parm()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_utc_parm( MBG_DEV_HANDLE dh, int *p ) ;
+ * @brief Write the time scale configuration to a device
+ *
+ * The ::MBG_TIME_SCALE_SETTINGS structure determines which time scale
+ * is to be used for the time stamps which can be read from a device.
+ *
+ * The API call ::mbg_chk_dev_has_time_scale checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_time_scale.
+ *
+ * The function ::mbg_get_time_scale_info should have been called before
+ * in order to determine which time scales are supported by the card.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::MBG_TIME_SCALE_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_time_scale_info
+ * @see ::mbg_chk_dev_has_time_scale
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_time_scale_settings( MBG_DEV_HANDLE dh, const MBG_TIME_SCALE_SETTINGS *p ) ;
/**
- Read a ::UTC structure from a card.
-
- The macro _pcps_has_utc_parm() or the API call mbg_dev_has_utc_parm()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_utc_parm().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::UTC structure to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_utc_parm()
- @see mbg_set_utc_parm()
-*/
+ * @brief Read a ::UTC parameter structure from a device
+ *
+ * The API call ::mbg_chk_dev_has_utc_parm checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_has_utc_parm.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::UTC structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_utc_parm
+ * @see ::mbg_set_utc_parm
+ */
_MBG_API_ATTR int _MBG_API mbg_get_utc_parm( MBG_DEV_HANDLE dh, UTC *p ) ;
/**
- Write a ::UTC structure to a card.
-
- This should only be done for testing, or if a card is operated in
- freewheeling mode. If the card receives any satellites the settings
- written to the board are overwritten by the parameters broadcasted
- by the satellites.
-
- The macro _pcps_has_utc_parm() or the API call mbg_dev_has_utc_parm()
- check whether this call is supported by a specific card.
- See also the notes for mbg_dev_has_utc_parm().
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a valid ::UTC structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_utc_parm()
- @see mbg_get_utc_parm()
-*/
- _MBG_API_ATTR int _MBG_API mbg_set_utc_parm( MBG_DEV_HANDLE dh, UTC *p ) ;
+ * @brief Write a ::UTC parameter structure to a device.
+ *
+ * This should only be done for testing, or if a card is operated in
+ * freewheeling mode. If the receiver is tracking any satellites then the settings
+ * written to the device are overwritten by the parameters broadcast
+ * by the satellites.
+ *
+ * The API call ::mbg_chk_dev_has_utc_parm checks whether
+ * this call is supported by a device.
+ *
+ * See also the notes for mbg_chk_dev_has_utc_parm.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a valid ::UTC structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_utc_parm
+ * @see ::mbg_get_utc_parm
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_utc_parm( MBG_DEV_HANDLE dh, const UTC *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()
-*/
+ * @brief Read the current time plus the associated PC cycles from a device.
+ *
+ * The ::PCPS_TIME_CYCLES structure contains a ::PCPS_TIME structure
+ * and a PC cycles 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_cycles call should be used preferably if supported by
+ * the device since that call provides much better accuracy than this one.
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_CYCLES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_legacy_time_fncs
+ * @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()
-*/
+ * @brief Read the current high resolution time plus the associated PC cycles from a device.
+ *
+ * The returned ::PCPS_HR_TIME_CYCLES structure contains a ::PCPS_HR_TIME
+ * structure and a PC cycles 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 API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by the device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME_CYCLES structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
_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()
-*/
+ * @brief Read the current high resolution time, and compensate the call's latency.
+ *
+ * Read a ::PCPS_HR_TIME structure plus cycles 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 API call ::mbg_chk_dev_has_hr_time checks whether
+ * this call is supported by the device.
+ *
+ * For details see @ref ::mbgdevio_hr_time_fncs
+ *
+ * The cycles counter value corresponds to a value returned by QueryPerformanceCounter()
+ * under Windows, and get_cycles() under Linux. On operating systems or targets which don't
+ * provide a cycles counter the returned cycles value is always 0.
+ *
+ * Applications should first pick up their own cycles counter value and then call
+ * this function. The difference of the cycles counter values corresponds to the
+ * latency of the call in units of the cycles counter clock frequency, e.g as reported
+ * by QueryPerformanceFrequency() under Windows.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_HR_TIME structure to be filled up
+ * @param[out] hns_latency Optional pointer to an int32_t value to return
+ * the latency in 100ns units, or NULL, if not used.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_hr_time_fncs
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_hr_time
+ * @see ::mbg_get_hr_time_cycles
+ * @see ::mbg_get_hr_time_comp
+ * @see @ref mbgdevio_hr_time_fncs
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ * @see @ref mbgdevio_legacy_time_fncs
+ */
_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
-*/
+ * @brief Read the current IRIG output settings plus the supported settings.
+ *
+ * The returned ::IRIG_INFO structure contains the configuration of an IRIG output
+ * plus the possible settings supported by that output.
+ *
+ * The API call ::mbg_chk_dev_has_irig_tx checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to an ::IRIG_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_irig_tx_settings
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_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
-*/
+ * @brief Write an ::IRIG_SETTINGS structure to a device to configure the IRIG output
+ *
+ * The API call ::mbg_chk_dev_has_irig_tx checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to an ::IRIG_INFO structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_irig_tx_info
+ * @see ::mbg_chk_dev_has_irig_tx
+ * @see ::mbg_chk_dev_is_tcr
+ * @see ::mbg_chk_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
-*/
+ * @brief Read the current frequency synthesizer settings from a device
+ *
+ * Read a ::SYNTH structure containing the configuration of an optional
+ * on-board programmable frequency synthesizer.
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SYNTH structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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
-*/
+ * @brief Write frequency synthesizer configuration settings to a device
+ *
+ * Write a ::SYNTH structure containing the configuration of an optional
+ * on-board programmable frequency synthesizer.
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::SYNTH structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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
-*/
+ * @brief Read the current status of the on-board frequency synthesizer
+ *
+ * The API call ::mbg_chk_dev_has_synth checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::SYNTH_STATE structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_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()
- @see mbg_get_fast_hr_timestamp()
-*/
- _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()
- @see mbg_get_fast_hr_timestamp()
-*/
+ * @brief Read a high resolution ::PCPS_TIME_STAMP_CYCLES structure via memory mapped access.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP_CYCLES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_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_cycles()
- @see mbg_get_fast_hr_timestamp()
-*/
+ * @brief Read a high resolution timestamp and compensate the latency of the call
+ *
+ * The retrieved ::PCPS_TIME_STAMP is read from memory mapped registers,
+ * and timestamp is compensated for the call's latency before it is returned.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP structure to be filled up
+ * @param[out] hns_latency Optionally receives the latency in hectonanoseconds //### TODO Check if hns
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see ::mbg_get_fast_hr_timestamp
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP *p, int32_t *hns_latency ) ;
/**
- Read a high resolution ::PCPS_TIME_STAMP structure via memory mapped access.
-
- This function does not return or evaluate a cycles count, so the latency
- of the call can not be determined. However, depending on the timer hardware
- used as cycles counter it may take quite some time to read the cycles count
- on some hardware architectures, so this call can be used to yield lower
- latencies, under the restriction to be unable to determine the exact latency.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PCPS_TIME_STAMP 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()
- @see mbg_get_fast_hr_timestamp_cycles()
-*/
+ * @brief Read a high resolution ::PCPS_TIME_STAMP structure via memory mapped access
+ *
+ * This function does not return or evaluate a cycles count, so the latency
+ * of the call can not be determined. However, depending on the timer hardware
+ * used as cycles counter it may take quite some time to read the cycles count
+ * on some hardware architectures, so this call can be used to yield lower
+ * latencies, under the restriction to be unable to determine the exact latency.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_TIME_STAMP structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup mbgdevio_fast_timestamp_fncs
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_fast_hr_timestamp_comp
+ * @see ::mbg_get_fast_hr_timestamp_cycles
+ * @see @ref mbgdevio_fast_timestamp_fncs
+ */
_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP *p ) ;
/**
- 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()
-*/
+ * @brief Read current configuraton and features provided by the programmable pulse outputs.
+ *
+ * Read a ::POUT_INFO_IDX array of current settings and configuration
+ * options of the device's programmable pulse outputs.
+ *
+ * A valid ::RECEIVER_INFO associated with the device
+ * has to be 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of ::POUT_INFO_IDX structures to be filled up
+ * @param[in] p_ri Pointer to the ::RECEIVER_INFO associated with the device //### TODO Make this obsolete
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Write the configuration for a single programmable pulse output
+ *
+ * The ::POUT_SETTINGS_IDX structure 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::POUT_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
-*/
+ * @brief Write the configuration for a single programmable pulse output
+ *
+ * The ::POUT_SETTINGS structure does not contain the index of the
+ * programmable output to be configured, so the index must explicitly
+ * be passed to this function. 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[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::POUT_SETTINGS structure to be written.
+ * @param[in] idx Index of the programmable pulse output to be configured (starting from 0 ).
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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.
- */
+ * @brief Read a device's IRQ status information.
+ *
+ * IRQ status information includes flags indicating whether IRQs are
+ * actually enabled, and whether IRQ support by a card is possibly
+ * unsafe due to the firmware and interface chip version.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PCPS_IRQ_STAT_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see @ref PCPS_IRQ_STAT_INFO_DEFS
+ */
_MBG_API_ATTR int _MBG_API mbg_get_irq_stat_info( MBG_DEV_HANDLE dh, PCPS_IRQ_STAT_INFO *p ) ;
/**
- Check if a specific device provides simple LAN interface API 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_lan_if_info()
- @see mbg_get_ip4_state()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_lan_intf( MBG_DEV_HANDLE dh, int *p ) ;
-
- /**
- Read LAN interface information from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::LAN_IF_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_ip4_state()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN interface information from a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::LAN_IF_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_lan_if_info( MBG_DEV_HANDLE dh, LAN_IF_INFO *p ) ;
/**
- Read LAN IPv4 state from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::IP4_SETTINGS variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_settings()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN IPv4 state from a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::IP4_SETTINGS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ip4_state( MBG_DEV_HANDLE dh, IP4_SETTINGS *p ) ;
/**
- Read LAN IPv4 settings from a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::IP4_SETTINGS variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_state()
- @see mbg_set_ip4_settings()
- */
+ * @brief Read LAN IPv4 settings from a device.
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::IP4_SETTINGS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_state
+ * @see ::mbg_set_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ip4_settings( MBG_DEV_HANDLE dh, IP4_SETTINGS *p ) ;
/**
- Write LAN IPv4 settings to a card which supports this.
- The macro _pcps_has_lan_intf() or the API call mbg_dev_has_lan_intf()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::IP4_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_lan_intf()
- @see mbg_get_lan_if_info()
- @see mbg_get_ip4_settings()
-*/
+ * @brief Write LAN IPv4 settings to a device
+ *
+ * The API call ::mbg_chk_dev_has_lan_intf checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::IP4_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_lan_intf
+ * @see ::mbg_get_lan_if_info
+ * @see ::mbg_get_ip4_settings
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ip4_settings( MBG_DEV_HANDLE dh, const IP4_SETTINGS *p ) ;
/**
- Check if a specific device provides PTP configuration/status 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_ptp_state()
- @see mbg_get_ptp_cfg_info()
- @see mbg_set_ptp_cfg_settings()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_ptp( MBG_DEV_HANDLE dh, int *p ) ;
-
- /**
- Check if a specific device provides PTP Unicast feature/configuration.
-
- @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_ptp_state()
- @see mbg_get_ptp_uc_master_cfg_limits()
- @see mbg_get_all_ptp_uc_master_info()
- @see mbg_set_ptp_unicast_cfg_settings()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_ptp_unicast( MBG_DEV_HANDLE dh, int *p ) ;
-
- /**
- Read PTP/IEEE1588 status from a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_cfg_info()
- @see mbg_set_ptp_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 status from a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_STATE variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_state( MBG_DEV_HANDLE dh, PTP_STATE *p ) ;
/**
- Read PTP/IEEE1588 config info and current settings from a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_state()
- @see mbg_set_ptp_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 config info and current settings from a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_CFG_INFO variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_set_ptp_cfg_settings
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_cfg_info( MBG_DEV_HANDLE dh, PTP_CFG_INFO *p ) ;
/**
- Write PTP/IEEE1588 configuration settings to a card which supports this.
- The macro _pcps_has_ptp() or the API call mbg_dev_has_ptp()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::PTP_CFG_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp()
- @see mbg_get_ptp_state()
- @see mbg_get_ptp_cfg_info()
-*/
+ * @brief Write PTP/IEEE1588 configuration settings to a device.
+ *
+ * The API call ::mbg_chk_dev_has_ptp checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::PTP_CFG_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_state
+ * @see ::mbg_get_ptp_cfg_info
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ptp_cfg_settings( MBG_DEV_HANDLE dh, const PTP_CFG_SETTINGS *p ) ;
/**
- Read PTP/IEEE1588 unicast config info and current settings from a card which supports this.
- The macro _pcps_has_ri_ptp_unicast() or the API call mbg_dev_has_ptp_unicast()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::PTP_UNICAST_CFG_INFO variable to be filled up
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp_unicast()
- @see mbg_set_ptp_unicast_cfg_settings()
- */
+ * @brief Read PTP/IEEE1588 unicast master configuration limits from a device.
+ *
+ * The API call ::mbg_chk_dev_has_ptp_unicast checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::PTP_UC_MASTER_CFG_LIMITS variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_get_ptp_uc_master_cfg_limits( MBG_DEV_HANDLE dh, PTP_UC_MASTER_CFG_LIMITS *p ) ;
/**
- Read a ::IOCTL_SET_PTP_UNICAST_CFG_SETTINGS 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 ::PTP_UC_MASTER_INFO_IDX structures to be filled up
- @param p_umsl Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure returned by mbg_get_ptp_uc_master_cfg_limits()
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see //##++++++++++++++++++++++
- @see
- @see
-*/
+ * @brief Read PTP Unicast master settings and configuration options.
+ *
+ * The array passed to this function to receive the returned data
+ * must be able to hold at least ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master elements.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] pii Pointer to a an array of ::PTP_UC_MASTER_INFO_IDX structures to be filled up.
+ * @param[in] p_umsl Pointer to a ::PTP_UC_MASTER_CFG_LIMITS structure returned by ::mbg_get_ptp_uc_master_cfg_limits
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_set_ptp_uc_master_settings_idx
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_get_all_ptp_uc_master_info( MBG_DEV_HANDLE dh, PTP_UC_MASTER_INFO_IDX pii[], const PTP_UC_MASTER_CFG_LIMITS *p_umsl ) ;
/**
- Write PTP/IEEE1588 unicast configuration settings to a card which supports this.
- The macro _pcps_has_ri_ptp_unicast() or the API call mbg_dev_has_ptp_unicast()
- check whether this call is supported by a specific card.
-
- @param dh Valid handle to a Meinberg device.
- @param *p ::PTP_UNICAST_CFG_SETTINGS structure to be written
-
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
-
- @see mbg_dev_has_ptp_unicast()
- @see mbg_get_ptp_state()
- @see mbg_get_ptp_cfg_info()
- @see mbg_get_ptp_unicast_cfg_info()
-*/
+ * @brief Write PTP/IEEE1588 unicast configuration settings to a device
+ *
+ * The API call ::mbg_chk_dev_has_ptp_unicast checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p ::PTP_UC_MASTER_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_ptp_unicast
+ * @see ::mbg_get_all_ptp_cfg_info
+ * @see ::mbg_get_ptp_uc_master_cfg_limits
+ * @see ::mbg_get_all_ptp_uc_master_info
+ * @see ::mbg_get_ptp_state
+ */
_MBG_API_ATTR int _MBG_API mbg_set_ptp_uc_master_settings_idx( MBG_DEV_HANDLE dh, const PTP_UC_MASTER_SETTINGS_IDX *p ) ;
/**
- Read system time and card time from the kernel driver. The kernel
- driver reads the current system time plus a HR time structure from
- a card immediately after each other. The returned info structure also
- contains some cycles counts to be able to determine the execution times
- required to read those time stamps.
-
- The advantage of this call compared to mbg_get_time_info_tstamp() is
- that this call also returns the card's status. On the other hand, reading
- the HR time from the card may block e.g. if another application accesses
- the board.
-
- This call makes a mbg_get_hr_time_cycles() call internally so the macro
- _pcps_has_hr_time() or the API call mbg_dev_has_hr_time() can be
- used to check whether this call is supported with a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_INFO_HRT variable 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_info_tstamp()
- */
+ * @brief Read both system time and associated device time from the kernel driver
+ *
+ * The kernel driver reads the current system time plus a HR time structure
+ * from a card immediately after each other. The returned info structure also
+ * contains some cycles counts to be able to determine the execution times
+ * required to read those time stamps.
+ *
+ * The advantage of this call compared to ::mbg_get_time_info_tstamp is
+ * that this call also returns the card's status. On the other hand, reading
+ * the HR time from the card may block e.g. if another application accesses
+ * the board.
+ *
+ * This call makes a ::mbg_get_hr_time_cycles call internally so the API call
+ * ::mbg_chk_dev_has_hr_time can be used to check whether this call is supported
+ * by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_INFO_HRT structure to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_hr_time
+ * @see ::mbg_get_time_info_tstamp
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_info_hrt( MBG_DEV_HANDLE dh, MBG_TIME_INFO_HRT *p ) ;
/**
- This call is similar to mbg_get_time_info_hrt() except that a
- mbg_get_fast_hr_timestamp_cycles() call is made internally, so the macro
- _pcps_has_fast_hr_timestamp() or the API call mbg_dev_has_fast_hr_timestamp()
- can be used to check whether this call is supported with a specific card.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::MBG_TIME_INFO_TSTAMP variable 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_time_info_hrt()
- */
+ * @brief Read both system time and associated device timestamp from the kernel driver
+ *
+ * This call is similar to ::mbg_get_time_info_hrt except that a
+ * ::mbg_get_fast_hr_timestamp_cycles call is made internally, so
+ * the API call ::mbg_chk_dev_has_fast_hr_timestamp can be used to check whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_TIME_INFO_TSTAMP structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_fast_hr_timestamp
+ * @see ::mbg_get_time_info_hrt
+ */
_MBG_API_ATTR int _MBG_API mbg_get_time_info_tstamp( MBG_DEV_HANDLE dh, MBG_TIME_INFO_TSTAMP *p ) ;
/**
- Check if a specific device supports demodulation of the DCF77 PZF code.
-
- @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_corr_info()
- @see mbg_dev_has_tr_distance()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_pzf( MBG_DEV_HANDLE dh, int *p ) ;
+ * @brief Read PZF correlation info from a device
+ *
+ * The API call ::mbg_chk_dev_has_corr_info checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::CORR_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_corr_info
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_corr_info( MBG_DEV_HANDLE dh, CORR_INFO *p ) ;
/**
- Check if a specific device supports reading correlation info.
-
- @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_pzf()
- @see mbg_get_corr_info()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_corr_info( MBG_DEV_HANDLE dh, int *p ) ;
+ * @brief Read configurable "distance from transmitter" parameter from a device
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * The API call ::mbg_chk_dev_has_tr_distance checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::TR_DISTANCE variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_set_tr_distance
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_tr_distance( MBG_DEV_HANDLE dh, TR_DISTANCE *p ) ;
/**
- Check if a specific device supports configurable distance from transmitter
- used to compensate RF propagation delay.
-
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to an int which is set 0 or != 0 unless the call fails.
+ * @brief Write configurable "distance from transmitter" parameter to a device.
+ *
+ * The distance from transmitter parameter is used to compensate
+ * the RF propagation delay, mostly with long wave receivers.
+ *
+ * The API call ::mbg_chk_dev_has_tr_distance checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::TR_DISTANCE variable to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_pzf
+ * @see ::mbg_chk_dev_has_tr_distance
+ * @see ::mbg_get_tr_distance
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_tr_distance( MBG_DEV_HANDLE dh, const TR_DISTANCE *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read a debug status word from a device
+ *
+ * This is mainly supported by IRIG timecode receiver cards, and the status
+ * word is intended to provide more detailed information why a card might not
+ * synchronize to the incoming timecode signal.
+ *
+ * See ::MBG_DEBUG_STATUS and related definitions for details.
+ *
+ * The API call ::mbg_chk_dev_has_debug_status checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_DEBUG_STATUS variable to be filled up
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_debug_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_debug_status( MBG_DEV_HANDLE dh, MBG_DEBUG_STATUS *p ) ;
- @see mbg_dev_has_pzf()
- @see mbg_get_tr_distance()
- @see mbg_set_tr_distance()
-*/
- _MBG_API_ATTR int _MBG_API mbg_dev_has_tr_distance( MBG_DEV_HANDLE dh, int *p ) ;
+ /**
+ * @brief Clear the device's on-board event log
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+ _MBG_API_ATTR int _MBG_API mbg_clr_evt_log( MBG_DEV_HANDLE dh ) ;
/**
- Read PZF correlation info from a card which supports this.
- The macro _pcps_has_corr_info() or the API call mbg_dev_has_corr_info()
- check whether this call is supported by a specific card.
+ * @brief Read details about a device's on-board event log buffer
+ *
+ * The returned ::MBG_NUM_EVT_LOG_ENTRIES structure tells how many
+ * event log entries can be saved on the board, and how many entries
+ * actually have been saved.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_NUM_EVT_LOG_ENTRIES variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_first_evt_log_entry
+ * @see ::mbg_get_next_evt_log_entry
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_num_evt_log_entries( MBG_DEV_HANDLE dh, MBG_NUM_EVT_LOG_ENTRIES *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::CORR_INFO variable to be filled up
+ /**
+ * @brief Read the first (oldest) event log entry from a device
+ *
+ * @note Subsequent reads should be made using ::mbg_get_next_evt_log_entry.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * If no (more) event log entry is available on the device then
+ * the returned MBG_EVT_LOG_ENTRY::code is MBG_EVT_ID_NONE.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_EVT_LOG_ENTRY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_next_evt_log_entry
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_first_evt_log_entry( MBG_DEV_HANDLE dh, MBG_EVT_LOG_ENTRY *p ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read the next event log entry from a device
+ *
+ * @note The first read should be made using ::mbg_get_first_evt_log_entry
+ * to set the on-board read index to the oldest entry.
+ *
+ * The API call ::mbg_chk_dev_has_evt_log checks whether
+ * this call is supported by a device.
+ *
+ * If no (more) event log entry is available on the device then
+ * the returned MBG_EVT_LOG_ENTRY::code is MBG_EVT_ID_NONE.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_EVT_LOG_ENTRY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_evt_log
+ * @see ::mbg_clr_evt_log
+ * @see ::mbg_get_num_evt_log_entries
+ * @see ::mbg_get_first_evt_log_entry
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_next_evt_log_entry( MBG_DEV_HANDLE dh, MBG_EVT_LOG_ENTRY *p ) ;
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_corr_info()
- */
- _MBG_API_ATTR int _MBG_API mbg_get_corr_info( MBG_DEV_HANDLE dh, CORR_INFO *p ) ;
+ /**
+ * @brief Read the current GNSS mode info including current settings
+ *
+ * The ::MBG_GNSS_MODE_INFO structure tells which GNSS systems are supported
+ * by a device, and also includes the settings currently in effect.
+ *
+ * The API call ::mbg_chk_dev_is_gnss can be used to check whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_is_gnss.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p_mi Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ * @see ::mbg_chk_dev_is_gnss
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_gnss_mode_info( MBG_DEV_HANDLE dh, MBG_GNSS_MODE_INFO *p_mi ) ;
/**
- Read configurable "distance from transmitter" parameter from a card
- which supports this. The parameter is used to compensate the RF signal
- propagation delay.
- The macro _pcps_has_tr_distance() or the API call mbg_dev_has_tr_distance()
- check whether this call is supported by a specific card.
+ * @brief Write the GNSS mode configuration to a device
+ *
+ * The ::MBG_GNSS_MODE_SETTINGS structure determines the GNSS settings
+ * for a device, e.g. which satellite systems have to be used.
+ *
+ * The function ::mbg_get_gps_gnss_mode_info should have been called before
+ * to determine which GNSS settings are supported by the device.
+ *
+ * The API call ::mbg_chk_dev_is_gnss can be used to check whether
+ * this call is supported by a device.
+ *
+ * See also the notes for ::mbg_chk_dev_is_gnss.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p_ms Pointer to a ::MBG_GNSS_MODE_SETTINGS structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_get_gps_all_gnss_sat_info
+ * @see ::mbg_chk_dev_is_gnss
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_gnss_mode_settings( MBG_DEV_HANDLE dh, const MBG_GNSS_MODE_SETTINGS *p_ms ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::TR_DISTANCE variable to be filled up
+ /**
+ * @brief Read a ::GNSS_SAT_INFO_IDX array of satellite status information
+ *
+ * The function ::mbg_get_gps_gnss_mode_info must have been called before,
+ * and the returned ::MBG_GNSS_MODE_INFO structure be passed to this function.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gsii Pointer to a an array of satellite info structures to be filled up.
+ * @param[in] p_mi Pointer to a ::MBG_GNSS_MODE_INFO structure returned by ::mbg_get_gps_gnss_mode_info.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_get_gps_gnss_mode_info
+ * @see ::mbg_set_gps_gnss_mode_settings
+ * @see ::mbg_chk_dev_is_gnss
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_gnss_sat_info( MBG_DEV_HANDLE dh, GNSS_SAT_INFO_IDX gsii[], const MBG_GNSS_MODE_INFO *p_mi ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read common GPIO configuration limits
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::MBG_GPIO_CFG_LIMITS structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gpio_cfg_limits( MBG_DEV_HANDLE dh, MBG_GPIO_CFG_LIMITS *p ) ;
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_tr_distance()
- @see mbg_set_tr_distance()
- */
- _MBG_API_ATTR int _MBG_API mbg_get_tr_distance( MBG_DEV_HANDLE dh, TR_DISTANCE *p ) ;
+ /**
+ * @brief Get all GPIO settings and capabilities.
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gii An array of ::MBG_GPIO_STATUS_IDX structures to be filled up.
+ * @param[in] p_gcl Pointer to a ::MBG_GPIO_CFG_LIMITS structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_gpio_info( MBG_DEV_HANDLE dh, MBG_GPIO_INFO_IDX gii[], const MBG_GPIO_CFG_LIMITS *p_gcl ) ;
/**
- Write configurable "distance from transmitter" parameter to a card
- which supports this. The parameter is used to compensate the RF signal
- propagation delay.
- The macro _pcps_has_tr_distance() or the API call mbg_dev_has_tr_distance()
- check whether this call is supported by a specific card.
+ * @brief Write the configuration for a single GPIO port to a device
+ *
+ * The ::MBG_GPIO_SETTINGS_IDX structure contains both the ::MBG_GPIO_SETTINGS
+ * and the port index value.
+ *
+ * The API call ::mbg_chk_dev_has_gpio checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_GPIO_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ * @see ::mbg_get_gps_all_gpio_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_gpio_settings_idx( MBG_DEV_HANDLE dh, const MBG_GPIO_SETTINGS_IDX *p ) ;
- @param dh Valid handle to a Meinberg device
- @param *p Pointer to a ::TR_DISTANCE variable to be written
+ /**
+ * @brief Read the status of all GPIO signal ports
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] gsi An array of ::MBG_GPIO_STATUS_IDX structures to be filled up.
+ * @param[in] p_gcl Pointer to a ::MBG_GPIO_CFG_LIMITS structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_gpio
+ * @see ::mbg_get_gpio_cfg_limits
+ * @see ::mbg_get_gps_all_gpio_info
+ * @see ::mbg_set_gps_gpio_settings_idx
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_gpio_status( MBG_DEV_HANDLE dh, MBG_GPIO_STATUS_IDX gsi[], const MBG_GPIO_CFG_LIMITS *p_gcl ) ;
- @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ /**
+ * @brief Read ::XMULTI_REF_INSTANCES
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p A ::XMULTI_REF_INSTANCES structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_xmr_instances( MBG_DEV_HANDLE dh, XMULTI_REF_INSTANCES *p ) ;
- @see mbg_dev_has_pzf()
- @see mbg_dev_has_tr_distance()
- @see mbg_get_tr_distance()
- */
- _MBG_API_ATTR int _MBG_API mbg_set_tr_distance( MBG_DEV_HANDLE dh, const TR_DISTANCE *p ) ;
+ /**
+ * @brief Read the status of all XMR sources
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] xmrsi An array of ::XMULTI_REF_STATUS_IDX structures to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_xmr_status( MBG_DEV_HANDLE dh, XMULTI_REF_STATUS_IDX xmrsi[], const XMULTI_REF_INSTANCES *p_xmri ) ;
/**
- Read the CPU affinity of a process, i.e. on which of the available
- CPUs the process can be executed.
+ * @brief Read all XMR settings and capabilities
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] xmrii An array of ::XMULTI_REF_INFO_IDX structures to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_set_gps_xmr_settings_idx
+ * @see ::mbg_get_xmr_holdover_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_gps_all_xmr_info( MBG_DEV_HANDLE dh, XMULTI_REF_INFO_IDX xmrii[], const XMULTI_REF_INSTANCES *p_xmri ) ;
- @param pid The process ID.
- @param *p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ /**
+ * @brief Write a single XMR setting to a device
+ *
+ * The ::XMULTI_REF_SETTINGS_IDX structure contains both the ::XMULTI_REF_SETTINGS
+ * and the index value.
+ *
+ * The API call ::mbg_chk_dev_has_xmr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] p Pointer to a ::XMULTI_REF_SETTINGS_IDX structure to be written.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_get_xmr_holdover_status
+ */
+ _MBG_API_ATTR int _MBG_API mbg_set_gps_xmr_settings_idx( MBG_DEV_HANDLE dh, const XMULTI_REF_SETTINGS_IDX *p ) ;
- @return ::MBG_SUCCESS or error code returned by the system call.
+ /**
+ * @brief Read the current XMR holdover interval from a device
+ *
+ * The API call ::mbg_chk_dev_has_xmr checks whether
+ * this call is supported by a device.
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::XMR_HOLDOVER_INTV structure to be filled up.
+ * @param[in] p_xmri Pointer to a ::XMULTI_REF_INSTANCES structure read before.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @see ::mbg_chk_dev_has_xmr
+ * @see ::mbg_get_xmr_instances
+ * @see ::mbg_get_gps_all_xmr_status
+ * @see ::mbg_get_gps_all_xmr_info
+ * @see ::mbg_set_gps_xmr_settings_idx
+ */
+ _MBG_API_ATTR int _MBG_API mbg_get_xmr_holdover_status( MBG_DEV_HANDLE dh, XMR_HOLDOVER_STATUS *p, const XMULTI_REF_INSTANCES *p_xmri ) ;
- @see mbg_set_process_affinity()
- @see mbg_set_current_process_affinity_to_cpu()
- */
+ /**
+ * @brief Read the CPU affinity of a process
+ *
+ * This means on which of the available CPUs or CPU cores
+ * a process may be executed.
+ *
+ * @param[in] pid The process ID.
+ * @param[out] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
- */
+ * @brief Set the CPU affinity of a process.
+ *
+ * This determines on which of the available CPUs
+ * or CPU cores the process is allowed to be executed.
+ *
+ * @param[in] pid The process ID.
+ * @param[out] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 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()
- */
+ * @brief Set the CPU affinity of a process for a single CPU only
+ *
+ * This means the process may only be executed on that single CPU.
+ *
+ * @param[in] cpu_num The number of the CPU.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 ) ;
+ * @brief Create a new execution thread for the current process.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in] p_ti Pointer to a ::MBG_THREAD_INFO structure to be filled up.
+ * @param[in] fnc The name of the thread function to be started.
+ * @param[in] arg A generic argument passed to the thread function.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 fnc, 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()
- */
+ * @brief 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 that support threads.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
- */
+ * @brief Let the current thread sleep for a certain interval
+ *
+ * The sleep is interrupted if a signal is received indicating
+ * the thread should terminate.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ * @param[in] sleep_ms The number of milliseconds to sleep
+ *
+ * @return MBG_SUCCESS if the sleep interval has expired normally,
+ * MBG_ERR_INTR if a signal to terminate has been received,
+ * or one of the other @ref MBG_ERROR_CODES
+ *
+ * @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()
- */
+ * @brief Set the CPU affinity of a single thread
+ *
+ * This determines on which of the available CPUs the thread
+ * is allowed to be executed.
+ *
+ * This function is only implemented for targets that support thread affinity.
+ *
+ * @param[in,out] p_ti Pointer to a ::MBG_THREAD_INFO structure associated with the thread.
+ * @param[in] p Pointer to a ::MBG_CPU_SET variable which contains a mask of CPUs.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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()
- */
+ * @brief Set up a ::MBG_POLL_THREAD_INFO structure and start a new thread
+ *
+ * The new thread runs a function which periodically reads
+ * a time stamp / cycles pair from a device.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ * @param[in] dh the Handle of the device to be polled.
+ * @param[in] freq_hz The initial cycles frequency, if known, in Hz.
+ * @param[in] 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_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()
- */
+ * @brief Stop a polling thread started by ::mbg_xhrt_poll_thread_create
+ *
+ * This call also releases all associated resources.
+ *
+ * @param[in,out] p_pti Pointer to a ::MBG_POLL_THREAD_INFO structure.
+ *
+ * @return The result of ::mbg_thread_stop.
+ *
+ * @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()
- */
+ * @brief Retrieve an extrapolated time stamp in ::PCPS_HR_TIME format
+ *
+ * The time stamp 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 @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_hrt Pointer to a ::PCPS_HR_TIME structure to be filled up.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_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()
- */
+ * @brief Retrieve an extrapolated time stamp in FILETIME format
+ *
+ * The time stamp 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 @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * Since FILETIME is a Windows-specific type this function is only
+ * implemented under Windows.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_ft Pointer to a FILETIME structure to be filled up.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_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()
- */
+ * @brief Retrieve the frequency of the system's cycles counter
+ *
+ * The frequency is determined by the device polling thread.
+ * See @ref mbg_xhrt_poll_group for details and limitations.
+ *
+ * This function is only implemented for targets that support threads.
+ *
+ * @param[in,out] p Pointer to a ::MBG_XHRT_INFO structure used to retrieve data from the polling thread.
+ * @param[out] p_freq_hz Pointer to a ::MBG_PC_CYCLES_FREQUENCY variable in which the frequency is returned.
+ *
+ * @return The return code from the API call used by the polling thread
+ * to read the time from the device, usually ::mbg_get_hr_time_cycles,
+ * so ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES.
+ *
+ * @ingroup mbg_xhrt_poll_group
+ * @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
+ * @see @ref mbg_xhrt_poll_group
+ */
_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.
+ * @brief Retrieve the system's default cycles counter frequency from the kernel driver
+ *
+ * This API call can be used on systems which don't provide this information in user space.
+ *
+ * @param[in] dh Handle of the device to which the IOCTL call is sent.
+ * @param[out] p Pointer of a ::MBG_PC_CYCLES_FREQUENCY variable to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @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 ) ;
- @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.
+ /**
+ * @brief Retrieve the system's default cycles counter frequency
+ *
+ * @note This may not be supported on all target platforms, in which case the
+ * returned frequency is 0 and the ::mbg_get_default_cycles_frequency_from_dev
+ * call should be used instead.
+ *
+ * @return the default cycles counter frequency in Hz, or 0 if the value is not available.
+ *
+ * @see ::mbg_get_default_cycles_frequency_from_dev
+ */
+ _MBG_API_ATTR MBG_PC_CYCLES_FREQUENCY _MBG_API mbg_get_default_cycles_frequency( void ) ;
- @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 ) ;
+/* ----- function prototypes end ----- */
- /**
- Retrieve the default system's cycles counter frequency.
- @note This may not be supported on all target platforms, in which case the
- returned frequency is 0 and the mbg_get_default_cycles_frequency_from_dev()
- call should be used.
+#if defined( MBG_TGT_WIN32 )
- @return the default cycles counter frequency in Hz, or 0 if the value is not available.
+static __mbg_inline
+MBGDEVIO_RET_VAL do_mbg_ioctl( MBG_DEV_HANDLE dh, int ioctl_code,
+ const void *in_p, int in_sz, void *out_p, int out_sz )
+{
+ DWORD ReturnedLength;
- @see mbg_get_default_cycles_frequency_from_dev()
-*/
- _MBG_API_ATTR MBG_PC_CYCLES_FREQUENCY _MBG_API mbg_get_default_cycles_frequency( void ) ;
+ if ( !DeviceIoControl( dh, ioctl_code,
+ (LPVOID) in_p, in_sz, out_p, out_sz,
+ &ReturnedLength,
+ NULL
+ ) )
+ {
+ DWORD rc = GetLastError(); // FIXME
+ #if 0 //### TODO
+ // We can't call mbgsvctl_log_mbgdevio_error() here (for now).
+ // Is is defined in mbgsvctl.h, and including mbgsvctl.h here,
+ // or copying the prototype here results in DLL import/export
+ // mismatch errors.
-/* ----- function prototypes end ----- */
+ // do not report a USB device timeout error
+ if ( rc != MBG_ERR_USB_ACCESS )
+ mbgsvctl_log_mbgdevio_error( ioctl_code, rc );
+ #endif
-#ifdef __cplusplus
-}
-#endif
+ return rc;
+ }
+ return MBG_SUCCESS;
-#if defined( MBG_TGT_WIN32 )
+} // do_mbg_ioctl
#define _do_mbg_ioctl( _dh, _ioctl, _p, _in_sz, _out_sz ) \
do_mbg_ioctl( _dh, _ioctl, (LPVOID) _p, _in_sz, (LPVOID) _p, _out_sz )
-#elif defined( MBG_TGT_UNIX )
+#elif defined( MBG_HAS_POSIX_IOCTL )
+
+ // In case of an error ioctl returns -1, and errno has been set to a *positive*
+ // error number according to negative Meinberg error codes, so we need to return
+ // -errno in case of an error to pass the original negative Meinberg error code.
+
+ static __mbg_inline
+ MBGDEVIO_RET_VAL do_mbg_ioctl( MBG_DEV_HANDLE dh, unsigned long ioctl_code, const void *p )
+ {
+ int rc = ioctl( dh, ioctl_code, (void *) p );
+
+ if ( rc == -1 ) // error
+ {
+ rc = -errno;
+ #if DEBUG_IOCTL
+ fprintf( stderr, "IOCTL 0x%08lX error: %s (rc: %i)\n",
+ (ulong) ioctl_code, mbg_strerror( rc ), rc );
+ #endif
+ }
+
+ return rc;
+ }
#define _do_mbg_ioctl( _dh, _ioctl, _p, _in_sz, _out_sz ) \
- ioctl( _dh, _ioctl, _p )
+ do_mbg_ioctl( _dh, _ioctl, _p )
#endif
@@ -3219,21 +5434,42 @@ extern "C" {
// The code below depends on whether the target device is accessed via
// IOCTLs to a device driver, or the hardware is accessed directly.
-#if defined( _MBGIOCTL_H ) // using IOCTL to access device driver
-
+#if defined( MBG_USE_KERNEL_DRIVER ) // using IOCTL to access device driver
+
+ /**
+ * @brief Send a generic IOCTL command to the driver.
+ *
+ * @param dh Valid handle to a Meinberg device
+ * @param info Additional information for the kernel driver depending on
+ * the IOCTL code, i.e. the low level function to be called: <br>
+ * one of the PCPS_... commands with IOCTL_PCPS_GENERIC_{READ|WRITE}<br>
+ * one of the PC_GPS_... commands with IOCTL_PCPS_GENERIC_{READ|WRITE}_GPS<br>
+ * one of the PCPS_GEN_IO_... enumeration codes with IOCTL_PCPS_GENERIC_IO
+ * @param ioctl_code One of the IOCTL_GENERIC_... codes telling the kernel driver
+ * which low level function to use, e.g. normal read or write,
+ * large (GPS) data read or write, or generic I/O.
+ * @param in_p Pointer to an input buffer passed to the driver, can be NULL
+ * @param in_sz Size of the input buffer, can be 0 if no buffer is used
+ * @param out_p Pointer to an output buffer passed to the driver, can be NULL
+ * @param out_sz Size of the output buffer, can be 0 if no buffer is used
+ *
+ * @return ::MBG_SUCCESS or error code returned by device I/O control function.
+ */
static __mbg_inline
int mbgdevio_do_gen_io( MBG_DEV_HANDLE dh, int info, unsigned int ioctl_code,
const void *in_p, int in_sz,
void *out_p, int out_sz )
{
- _mbgdevio_vars();
-
- #if _MBG_SUPP_VAR_ACC_SIZE
- info; // avoid "unused" warning
+ MBGDEVIO_RET_VAL rc;
- rc = do_mbg_ioctl( dh, ioctl_code, in_p, in_sz, out_p, out_sz ); //##++++ in_p / out_p vs. _do_mbg_ioctl()
+ // Generic IOCTL calls always need to pass some info beside
+ // the I/O buffers down to the driver, which usually is
+ // the command code for the device.
+ // Thus we must always use one of the control structures
+ // IOCTL_GENERIC_REQ or IOCTL_GENERIC_BUFFER, whichever
+ // is appropriate for the target OS.
- #elif USE_IOCTL_GENERIC_REQ
+ #if USE_IOCTL_GENERIC_REQ
IOCTL_GENERIC_REQ req = { 0 };
@@ -3254,7 +5490,7 @@ extern "C" {
p_buff = (IOCTL_GENERIC_BUFFER *) malloc( buff_size );
if ( p_buff == NULL )
- return _mbg_err_to_os( MBG_ERR_NO_MEM );
+ return MBG_ERR_NO_MEM;
p_buff->ctl.info = info;
p_buff->ctl.data_size_in = in_sz;
@@ -3274,7 +5510,7 @@ extern "C" {
#endif
- return _mbgdevio_ret_val;
+ return _mbgdevio_cnv_ret_val( rc );
} // mbgdevio_do_gen_io
@@ -3301,8 +5537,10 @@ extern "C" {
#define _mbgdevio_write_cmd( _dh, _cmd, _ioctl ) \
_do_mbgdevio_write( _dh, _cmd, _ioctl, NULL, 0 )
+ #define _mbgdevio_read_gps _do_mbgdevio_read
#define _mbgdevio_read_gps_var _mbgdevio_read_var
+ #define _mbgdevio_write_gps _do_mbgdevio_write
#define _mbgdevio_write_gps_var _mbgdevio_write_var
@@ -3324,10 +5562,10 @@ extern "C" {
#else // accessing hardware device directly
- #define _mbgdevio_chk_cond( _cond ) \
- { \
- if ( !(_cond) ) \
- return _mbg_err_to_os( MBG_ERR_NOT_SUPP_BY_DEV ); \
+ #define _mbgdevio_chk_cond( _cond ) \
+ { \
+ if ( !(_cond) ) \
+ return MBG_ERR_NOT_SUPP_BY_DEV; \
}
#define _mbgdevio_read( _dh, _cmd, _ioctl, _p, _sz ) \
@@ -3408,38 +5646,52 @@ extern "C" {
-#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_POSIX )
+
+// NOTE
+// For some reason the code below causes an internal compiler error
+// with Borland C++Builder 5.0 release builds. Since we don't need
+// this function in the BC5 projects anyway we simply exclude it
+// from build.
+
+#if !defined( __BORLANDC__ )
static __mbg_inline
void mbg_chk_tstamp64_leap_sec( uint64_t *tstamp64, PCPS_TIME_STATUS_X *status )
{
if ( *status & ( PCPS_LS_ANN | PCPS_LS_ENB ) )
{
- time_t t = (uint32_t) ( *tstamp64 >> 32 );
- struct tm tm = *gmtime( &t );
+ struct tm tm = { 0 };
+ time_t t = cvt_to_time_t( (uint32_t) ( (*tstamp64) >> 32 ) );
+ int rc = mbg_gmtime( &tm, &t );
- // Handle leap second and status
- if ( tm.tm_hour == 0 && tm.tm_min == 0 && tm.tm_sec == 0 )
+ if ( mbg_rc_is_success( rc ) )
{
- if ( *status & PCPS_LS_ANN )
+ // Handle leap second and status
+ if ( tm.tm_hour == 0 && tm.tm_min == 0 && tm.tm_sec == 0 )
{
- // Set leap second enabled flag on rollover to the leap second and clear announce flag
- *status &= ~PCPS_LS_ANN;
- *status |= PCPS_LS_ENB;
-
- // Decrement interpolated second to avoid automated overflow during the leap second.
- // Second 59 appears for the second time.
- *tstamp64 -= PCPS_HRT_BIN_FRAC_SCALE;
+ if ( *status & PCPS_LS_ANN )
+ {
+ // Set leap second enabled flag on rollover to the leap second and clear announce flag
+ *status &= ~PCPS_LS_ANN;
+ *status |= PCPS_LS_ENB;
+
+ // Decrement interpolated second to avoid automated overflow during the leap second.
+ // Second 59 appears for the second time.
+ *tstamp64 -= MBG_FRAC32_UNITS_PER_SEC;
+ }
+ else
+ if ( *status & PCPS_LS_ENB ) // Clear bits when leap second expires and 0:00:00 UTC is reached
+ *status &= ~( PCPS_LS_ANN | PCPS_LS_ENB );
}
- else
- if ( *status & PCPS_LS_ENB ) // Clear bits when leap second expires and 0:00:00 UTC is reached
- *status &= ~( PCPS_LS_ANN | PCPS_LS_ENB );
}
}
} // mbg_chk_tstamp64_leap_sec
-#endif // defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+#endif // !defined( __BORLANDC__ )
+
+#endif // defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_POSIX )
@@ -3475,6 +5727,10 @@ void uint64_to_pcps_time_stamp( PCPS_TIME_STAMP *ts, uint64_t n )
#endif
+#ifdef __cplusplus
+}
+#endif
+
#if defined( _USING_BYTE_ALIGNMENT )
#pragma pack() // set default alignment
#undef _USING_BYTE_ALIGNMENT
@@ -3484,6 +5740,7 @@ void uint64_to_pcps_time_stamp( PCPS_TIME_STAMP *ts, uint64_t n )
#undef _ext
+#undef _DO_INIT
#endif /* _MBGDEVIO_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.c b/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.c
new file mode 100755
index 0000000..ffd4bb8
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.c
@@ -0,0 +1,793 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgerror.c 1.3 2017/07/05 09:20:07 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg Library to communicate with USB devices from user space
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgerror.c $
+ * Revision 1.3 2017/07/05 09:20:07 martin
+ * Fixed a bug where POSIX error ENODEV wasn't mapped at all, but
+ * EXDEV was instead translated erraneously to MBG_ERR_NO_DEV.
+ * Mapped POSIX error ENOSPC to MBG_ERR_NO_SPACE, and EFAULT
+ * to MBG_ERR_INV_PARM.
+ * Mapped Windows WSA error codes WSAEFAULT and WSAEINVAL
+ * to MBG_ERR_INV_PARM.
+ * Renamed mbg_ioctl_err() to mbg_cond_err_msg().
+ * New function mbg_cond_err_msg_info() which takes an optional
+ * info string which is printed if the error code to be checked
+ * is MBG_ERR_NOT_SUPP_BY_DEV.
+ * Fixed build in Windows kernel mode.
+ * Fixed syntax error in CVI-specific code.
+ * Quieted some compiler warnings.
+ * Revision 1.2 2016/08/05 12:25:44Z martin
+ * Added some functions.
+ * Revision 1.1 2014/03/07 12:08:14 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _MBGERROR
+ #include <mbgerror.h>
+#undef _MBGERROR
+
+#include <mbg_tgt.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined( MBG_TGT_POSIX ) || \
+ defined( MBG_TGT_WIN32 ) || \
+ defined( MBG_TGT_DOS )
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+#else
+ #define _MBG_TGT_HAS_POSIX_ERRNO 0
+#endif
+
+#if _MBG_TGT_HAS_POSIX_ERRNO
+ #include <errno.h>
+#endif
+
+#if defined( MBG_TGT_DOS )
+ #include <stddef.h>
+#endif
+
+#if defined( MBG_TGT_POSIX )
+ #include <netdb.h>
+#endif
+
+#if defined(USE_MBG_ZLIB)
+ #include <zlib.h>
+#endif
+
+
+typedef struct
+{
+ int orig_errno;
+ int mbg_errno;
+
+} ERRNO_CNV_ENTRY;
+
+
+
+#if _MBG_TGT_HAS_POSIX_ERRNO
+
+static ERRNO_CNV_ENTRY posix_errno_table[] =
+{
+ // POSIX codes taken from Linux asm-generic/errno.h
+ { EPERM, MBG_ERR_PERM }, // 1, Operation not permitted
+ { ENOENT, MBG_ERR_NO_ENTITY }, // 2, No such file or directory
+ // { ESRCH, }, // 3, No such process
+ { EINTR, MBG_ERR_INTR }, // 4, Interrupted system call
+ { EIO, MBG_ERR_IO }, // 5, I/O error
+ { ENXIO, MBG_ERR_NOT_FOUND }, // 6, No such device or address
+ // { E2BIG, }, // 7, Argument list too long
+ // { ENOEXEC, }, // 8, Exec format error
+ // { EBADF, }, // 9, Bad file number
+ // { ECHILD, }, // 10, No child processes
+ // { EAGAIN, }, // 11, Try again
+ { ENOMEM, MBG_ERR_NO_MEM }, // 12, Out of memory
+ { EACCES, MBG_ERR_ACCESS }, // 13, Permission denied
+ { EFAULT, MBG_ERR_INV_PARM }, // 14, Bad address, e.g. invalid pointer
+ // { ENOTBLK, }, // 15, Block device required
+ { EBUSY, MBG_ERR_BUSY }, // 16, Device or resource busy
+ { EEXIST, MBG_ERR_EXIST }, // 17, File exists
+ // { EXDEV, }, // 18, Cross-device link
+ { ENODEV, MBG_ERR_NO_DEV }, // 19, No such device
+ // { ENOTDIR, }, // 20, Not a directory
+ // { EISDIR, }, // 21, Is a directory
+ { EINVAL, MBG_ERR_INV_PARM }, // 22, Invalid argument
+ // { ENFILE, }, // 23, File table overflow
+ // { EMFILE, }, // 24, Too many open files
+ // { ENOTTY, }, // 25, Not a typewriter
+ // { ETXTBSY, }, // 26, Text file busy
+ // { EFBIG, }, // 27, File too large
+ { ENOSPC, MBG_ERR_NO_SPACE }, // 28, No space left on device
+ { ESPIPE, MBG_ERR_PIPE }, // 29, Illegal seek
+ // { EROFS, }, // 30, Read-only file system
+ // { EMLINK, }, // 31, Too many links
+ // { EPIPE, }, // 32, Broken pipe
+ // { EDOM, }, // 33, Math argument out of domain of func
+ { ERANGE, MBG_ERR_RANGE }, // 34, Math result not representable
+#if defined( EOVERFLOW )
+ { EOVERFLOW, MBG_ERR_OVERFLOW }, // 75, Value too large for defined data type
+#endif
+#if defined( ENOTSOCK )
+ { ENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 88, Socket operation on non-socket
+#endif
+#if defined( ECONNRESET )
+ { ECONNRESET, MBG_ERR_CONN_RESET }, // 104, Connection reset by peer
+#endif
+ { 0, 0 } // end-of-table identifier
+
+}; // posix_errno_table
+
+#endif // _MBG_TGT_HAS_POSIX_ERRNO
+
+
+
+#if defined( MBG_TGT_POSIX )
+
+static ERRNO_CNV_ENTRY posix_h_errno_table[] =
+{
+ // POSIX codes taken from Linux netdb.h
+ { HOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // The specified host is unknown
+ // { NO_ADDRESS, }, // Usually same numeric value as NO_DATA
+ // { NO_DATA, }, // The requested name is valid but does not have an IP address
+ // { NO_RECOVERY, }, // A nonrecoverable name server error occurred
+ // { TRY_AGAIN, }, // A temporary error occurred on an authoritative name server. Try again later.
+ { 0, 0 } // end-of-table identifier
+
+}; // posix_h_errno_table
+
+#endif // defined( MBG_TGT_POSIX )
+
+
+
+#if defined( MBG_TGT_CVI )
+
+static ERRNO_CNV_ENTRY cvi_rs232_error_table[] =
+{
+ // { kRS_UnknownSysError, }, // Unknown system error.
+ // { kRS_InvalidPortNum, }, // In valid port number.
+ // { kRS_PortNotOpen, }, // Port is not open.
+ // { kRS_UnknownIOError, }, // Unknown I/O error.
+ // { kRS_InternalError, }, // Unexpected internal error.
+ // { kRS_NoPortFound, }, // No serial port found.
+ // { kRS_CanNotOpenPort, }, // Cannot open port.
+ // { kRS_NullPointerPassed, }, // A NULL pointer was passed when a non-NULL pointer was expected.
+ // { kRS_OutOfMemory, }, // Out of memory.
+ // { kRS_OutOfSystemResources, }, // Unable to allocate system resources.
+ // { kRS_InvalidParameter, }, // Invalid parameter.
+ // { kRS_InvalidBaudRate, }, // Invalid baud rate.
+ // { kRS_InvalidParity, }, // Invalid parity.
+ // { kRS_InvalidDataBits, }, // Invalid number of data bits.
+ // { kRS_InvalidStopBits, }, // Invalid number of stop bits.
+ // { kRS_BadFileHandle, }, // Bad file handle.
+ // { kRS_FileIOError, }, // File I/O error.
+ // { kRS_InvalidCount, }, // Invalid count; must be greater than or equal to 0.
+ // { kRS_InvalidIntLevel, }, // Invalid interrupt level.
+ // { kRS_IOTimeOut, }, // I/O operation timed out.
+ // { kRS_InvalidBreakTime, }, // Break time must be a positive value.
+ // { kRS_InvalidInQSize, }, // Requested input queue size must be 0 or greater.
+ // { kRS_InvalidOutQSize, }, // Requested output queue size must be 0 or greater.
+ // { kRS_GeneralIOFailure, }, // General I/O error.
+ // { kRS_InvalidBufferPointer, }, // Buffer parameter is NULL.
+ // { kRS_VISALibrariesMissing, }, // A necessary run-time library could not be found or loaded.
+ // { kRS_NoAckReceived, }, // Packet was sent, but no acknowledgment was received.
+ // { kRS_MaxRetriesBeforeSend, }, // Packet was not sent within retry limit.
+ // { kRS_MaxRetriesBeforeReceived, }, // Packet was not received within retry limit.
+ // { kRS_UnexpectedEOT, }, // End of transmission character encountered when start of data character expected.
+ // { kRS_CanNotReadPackNum, }, // Unable to read packet number.
+ // { kRS_InconsistentPackNum, }, // Inconsistent packet number.
+ // { kRS_CanNotReadPackData, }, // Unable to read packet data.
+ // { kRS_CanNotReadCheckSum, }, // Unable to read checksum.
+ // { kRS_CheckSumError, }, // Checksum received did not match computed checksum.
+ // { kRS_PackSizeGTInQ, }, // Packet size exceeds input queue size.
+ // { kRS_OpenFileError, }, // Error opening file.
+ // { kRS_ReadFileError, }, // Error reading file.
+ // { kRS_NoInitNegAck, }, // Did not receive initial negative acknowledgment character.
+ // { kRS_NoAckAfterEOT, }, // Did not receive acknowledgment after end of transmission character was sent.
+ // { kRS_WriteFileError, }, // Error writing to file.
+ // { kRS_NoSOHorEOT, }, // Did not receive either a start of data or end of transmission character when expected.
+ // { kRS_TransferCancelled, }, // Transfer was canceled because CAN ASCII character was received.
+ // { kRS_InvalidStartDelay, }, // Invalid start delay.
+ // { kRS_InvalidMaxTries, }, // Invalid maximum number of retries.
+ // { kRS_InvalidWaitPeriod, }, // Invalid wait period.
+ // { kRS_InvalidPacketSize, }, // Invalid packet size.
+ // { kRS_CanNotReadCRC, }, // Unable to read Cyclical Redundancy Check.
+ // { kRS_CRCError, }, // Cyclical Redundancy Check error.
+ { 0, 0 } // end-of-table identifier
+
+}; // cvi_rs232_error_table
+
+#endif // defined( MBG_TGT_CVI )
+
+
+
+#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_KERNEL )
+
+static ERRNO_CNV_ENTRY win32_error_table[] =
+{
+ // Windows System Error Codes (0-499)
+ { ERROR_INVALID_PARAMETER, MBG_ERR_INV_PARM },
+
+ // Windows System Error Codes (1300-1699)
+ { ERROR_ACCESS_DENIED, MBG_ERR_ACCESS }, //
+ { ERROR_PRIVILEGE_NOT_HELD, MBG_ERR_PERM }, //
+ { ERROR_INVALID_HANDLE, MBG_ERR_INV_HANDLE }, //
+ { ERROR_NOT_ENOUGH_MEMORY, MBG_ERR_NO_MEM }, //
+ { ERROR_OUTOFMEMORY, MBG_ERR_NO_MEM }, //
+ // { ERROR_WRITE_PROTECT, }, //
+ // { ERROR_BAD_UNIT, }, //
+ // { ERROR_NOT_READY, }, //
+ // { ERROR_WRITE_FAULT, }, //
+ // { ERROR_READ_FAULT, }, //
+ // { ERROR_GEN_FAILURE, }, //
+ // { ERROR_SHARING_VIOLATION, }, //
+ // { ERROR_LOCK_VIOLATION, }, //
+ // { ERROR_NOT_SUPPORTED, }, //
+ // { ERROR_DUP_NAME, }, //
+ // { ERROR_BAD_DEV_TYPE, }, //
+ // { ERROR_BUFFER_OVERFLOW, }, //
+ { ERROR_BUSY, MBG_ERR_BUSY }, //
+ // { ERROR_NOACCESS, }, //
+ { 0, 0 } // end-of-table identifier
+
+}; // win32_error_table
+
+
+
+static ERRNO_CNV_ENTRY win32_wsa_err_table[] =
+{
+ { WSAEINTR, MBG_ERR_INTR }, // 10004L A blocking operation was interrupted by a call to WSACancelBlockingCall.
+ // { WSAEBADF // 10009L The file handle supplied is not valid.
+ // { WSAEACCES // 10013L An attempt was made to access a socket in a way forbidden by its access permissions.
+ { WSAEFAULT, MBG_ERR_INV_PARM }, // 10014L The system detected an invalid pointer address in attempting to use a pointer argument in a call.
+ { WSAEINVAL, MBG_ERR_INV_PARM }, // 10022L An invalid argument was supplied.
+ // { WSAEMFILE // 10024L Too many open sockets.
+ // { WSAEWOULDBLOCK // 10035L A non-blocking socket operation could not be completed immediately.
+ // { WSAEINPROGRESS // 10036L A blocking operation is currently executing.
+ // { WSAEALREADY // 10037L An operation was attempted on a non-blocking socket that already had an operation in progress.
+ { WSAENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 10038L An operation was attempted on something that is not a socket.
+ // { WSAEDESTADDRREQ // 10039L A required address was omitted from an operation on a socket.
+ // { WSAEMSGSIZE // 10040L A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.
+ // { WSAEPROTOTYPE // 10041L A protocol was specified in the socket function call that does not support the semantics of the socket type requested.
+ // { WSAENOPROTOOPT // 10042L An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call.
+ // { WSAEPROTONOSUPPORT // 10043L The requested protocol has not been configured into the system, or no implementation for it exists.
+ // { WSAESOCKTNOSUPPORT // 10044L The support for the specified socket type does not exist in this address family.
+ // { WSAEOPNOTSUPP // 10045L The attempted operation is not supported for the type of object referenced.
+ // { WSAEPFNOSUPPORT // 10046L The protocol family has not been configured into the system or no implementation for it exists.
+ // { WSAEAFNOSUPPORT // 10047L An address incompatible with the requested protocol was used.
+ // { WSAEADDRINUSE // 10048L Only one usage of each socket address (protocol/network address/port) is normally permitted.
+ // { WSAEADDRNOTAVAIL // 10049L The requested address is not valid in its context.
+ // { WSAENETDOWN // 10050L A socket operation encountered a dead network.
+ // { WSAENETUNREACH // 10051L A socket operation was attempted to an unreachable network.
+ // { WSAENETRESET // 10052L The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.
+ // { WSAECONNABORTED // 10053L An established connection was aborted by the software in your host machine.
+ { WSAECONNRESET, MBG_ERR_CONN_RESET }, // 10054L An existing connection was forcibly closed by the remote host.
+ // { WSAENOBUFS // 10055L An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
+ // { WSAEISCONN // 10056L A connect request was made on an already connected socket.
+ // { WSAENOTCONN // 10057L A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.
+ // { WSAESHUTDOWN // 10058L A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call.
+ // { WSAETOOMANYREFS // 10059L Too many references to some kernel object.
+ // { WSAETIMEDOUT // 10060L A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
+ // { WSAECONNREFUSED // 10061L No connection could be made because the target machine actively refused it.
+ // { WSAELOOP // 10062L Cannot translate name.
+ // { WSAENAMETOOLONG // 10063L Name component or name was too long.
+ // { WSAEHOSTDOWN // 10064L A socket operation failed because the destination host was down.
+ // { WSAEHOSTUNREACH // 10065L A socket operation was attempted to an unreachable host.
+ // { WSAENOTEMPTY // 10066L Cannot remove a directory that is not empty.
+ // { WSAEPROCLIM // 10067L A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously.
+ // { WSAEUSERS // 10068L Ran out of quota.
+ // { WSAEDQUOT // 10069L Ran out of disk quota.
+ // { WSAESTALE // 10070L File handle reference is no longer available.
+ // { WSAEREMOTE // 10071L Item is not available locally.
+ // { WSASYSNOTREADY // 10091L WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable.
+ // { WSAVERNOTSUPPORTED // 10092L The Windows Sockets version requested is not supported.
+ { WSANOTINITIALISED, MBG_ERR_SOCK_INIT }, // 10093L Either the application has not called WSAStartup, or WSAStartup failed.
+ // { WSAEDISCON // 10101L Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence.
+ // { WSAENOMORE // 10102L No more results can be returned by WSALookupServiceNext.
+ // { WSAECANCELLED // 10103L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled.
+ // { WSAEINVALIDPROCTABLE // 10104L The procedure call table is invalid.
+ // { WSAEINVALIDPROVIDER // 10105L The requested service provider is invalid.
+ // { WSAEPROVIDERFAILEDINIT // 10106L The requested service provider could not be loaded or initialized.
+ // { WSASYSCALLFAILURE // 10107L A system call that should never fail has failed.
+ // { WSASERVICE_NOT_FOUND // 10108L No such service is known. The service cannot be found in the specified name space.
+ // { WSATYPE_NOT_FOUND // 10109L The specified class was not found.
+ // { WSA_E_NO_MORE // 10110L No more results can be returned by WSALookupServiceNext.
+ // { WSA_E_CANCELLED // 10111L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled.
+ // { WSAEREFUSED // 10112L A database query failed because it was actively refused.
+ { WSAHOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // 11001L No such host is known.
+ // { WSATRY_AGAIN // 11002L This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server.
+ // { WSANO_RECOVERY // 11003L A non-recoverable error occurred during a database lookup.
+ // { WSANO_DATA // 11004L The requested name is valid, but no data of the requested type was found.
+ { 0, 0 } // end-of-table identifier
+
+}; // win32_wsa_err_table
+
+#endif // defined( MBG_TGT_WIN32 )
+
+
+
+/**
+ * @brief Lookup some error code in a conversion table
+ *
+ * @param[in] orig_errno
+ * @param[in] tbl
+ *
+ * @return @ref MBG_ERROR_CODES associated with the original error code,
+ * or ::MBG_ERR_UNSPEC if origianl code not found in table.
+ */
+static /*HDR*/
+int lookup_mbg_errno( int orig_errno, const ERRNO_CNV_ENTRY tbl[] )
+{
+ const ERRNO_CNV_ENTRY *p;
+
+ for ( p = tbl; p->orig_errno || p->mbg_errno; p++ )
+ if ( p->orig_errno == orig_errno )
+ return p->mbg_errno;
+
+ return MBG_ERR_UNSPEC;
+
+} // lookup_mbg_errno
+
+
+
+/*HDR*/
+/**
+ * @brief Return an error string associated with the @ref MBG_ERROR_CODES
+ *
+ * @param[in] mbg_errno One of the @ref MBG_ERROR_CODES
+ *
+ * @return A constant string describing the error, or NULL for unknown error codes
+ */
+const char *mbg_strerror( int mbg_errno )
+{
+ static const MBG_CODE_NAME_TABLE_ENTRY tbl[] = MBG_ERR_NAMES_ENG;
+
+ const MBG_CODE_NAME_TABLE_ENTRY *p;
+
+ for ( p = tbl; p->name; p++ )
+ {
+ if ( mbg_errno == p->code )
+ return p->name;
+ }
+
+
+ return "Unknown error";
+
+} // mbg_strerror
+
+
+
+#if !( defined( MBG_TGT_WIN32 ) && defined( MBG_TGT_KERNEL ) ) // not supported in Windows kernel mode
+
+/*HDR*/
+/**
+ * @brief Check if a value is an error code and print an associated error message
+ *
+ * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES
+ * @param[in] what A string indicated what failed
+ *
+ * @return true if rc represented an error code, and a message has been printed, else false
+ */
+bool mbg_cond_err_msg( int rc, const char *what )
+{
+ return mbg_cond_err_msg_info( rc, what, NULL );
+
+} // mbg_cond_err_msg
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a value is an general or a "not supported" error code and print an associated message
+ *
+ * If rc contains an error code then an error message is printed, and true is returned.
+ *
+ * If the optional parameter string info2 is not NULL then it should contain
+ * the name of a feature which has been tested before. In this case, if the error
+ * code is the specific error ::MBG_ERR_NOT_SUPP_BY_DEV then a "not supported" message
+ * is printed using info2.
+ *
+ * If info2 is NULL, or the error code is not ::MBG_ERR_NOT_SUPP_BY_DEV then the standard
+ * error message is printed anyway.
+ *
+ * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES
+ * @param[in] what A string indicated what failed
+ * @param[in] info An optional informational string telling what is not supported (may be NULL).
+ *
+ * @return true if rc represented an error code, and a message has been printed, else false
+ */
+bool mbg_cond_err_msg_info( int rc, const char *what, const char *info )
+{
+ if ( mbg_rc_is_error( rc ) )
+ {
+ if ( info && ( rc == MBG_ERR_NOT_SUPP_BY_DEV ) )
+ fprintf( stderr, "This device does not %s.\n", info );
+ else
+ fprintf( stderr, "** %s failed: %s (rc: %i)\n", what, mbg_strerror( rc ), rc );
+
+ return true;
+ }
+
+ return false;
+
+} // mbg_cond_err_msg_info
+
+#endif // !( defined( MBG_TGT_WIN32 ) && defined( MBG_TGT_KERNEL ) )
+
+
+
+#if defined( MBG_TGT_CVI )
+
+/*HDR*/
+/**
+ * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] cvi_rc An error code returned by a CVI RS-232 library function
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ *
+ * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/
+ */
+int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s, CVI RS-232 rc: %i\n", info, cvi_rc );
+ #else
+ (void) info; // avoid compiler warning
+ #endif
+
+ return ( cvi_rc < 0 ) ? lookup_mbg_errno( cvi_rc, cvi_rs232_error_table ) : MBG_SUCCESS;
+
+} // mbg_cvi_rs232_error_to_mbg
+
+#endif
+
+
+
+#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_KERNEL )
+
+/*HDR*/
+/**
+ * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] last_err A Windows non-socket API error code as returned by GetLastError()
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) last_err );
+ #else
+ (void) info; // avoid compiler warning
+ #endif
+
+ return ( last_err == ERROR_SUCCESS ) ? MBG_SUCCESS : lookup_mbg_errno( last_err, win32_error_table );
+
+} // mbg_win32_last_err_to_mbg
+
+
+
+/*HDR*/
+/**
+ * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] wsa_err A Windows socket API error code as returned by WSAGetLastError()
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) wsa_err );
+ #else
+ (void) info; // avoid compiler warning
+ #endif
+
+ // The WSA error code is only retrieved after an error has occurred, so
+ // we don't need care for the success case here.
+ return lookup_mbg_errno( wsa_err, win32_wsa_err_table );
+
+} // mbg_win32_wsa_err_to_mbg
+
+#endif // defined( MBG_TGT_WIN32 )
+
+
+
+#if _MBG_TGT_HAS_POSIX_ERRNO
+
+/*HDR*/
+/**
+ * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] posix_errno A POSIX error code as usually defined in errno.h
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_posix_errno_to_mbg( int posix_errno, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s: %s (errno: %i)\n", info,
+ strerror( posix_errno ), posix_errno );
+ #else
+ (void) info; // avoid compiler warning
+ #endif
+
+ return lookup_mbg_errno( posix_errno, posix_errno_table );
+
+} // mbg_posix_errno_to_mbg
+
+#endif // _MBG_TGT_HAS_POSIX_ERRNO
+
+
+
+#if defined( MBG_TGT_POSIX )
+
+/*HDR*/
+/**
+ * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * This function is specific to translate error codes returned by
+ * gethostbyname() and gethostbyaddr(). In case of error these functions
+ * don't set errno but h_errno to a specific value.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param[in] posix_h_errno An error code as usually defined in netdb.h
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info )
+{
+ #if DEBUG
+ if ( info )
+ fprintf( stderr, "%s: %s (h_errno: %i)\n", info,
+ hstrerror( posix_h_errno ), posix_h_errno );
+ #else
+ (void) info; // avoid compiler warning
+ #endif
+
+ return lookup_mbg_errno( posix_h_errno, posix_h_errno_table );
+
+} // mbg_posix_h_errno_to_mbg
+
+#endif // defined( MBG_TGT_POSIX )
+
+
+
+/*HDR*/
+/**
+ * @brief Get and translate last error after non-socket function call
+ *
+ * Retrieve the "last error" code after a non-socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError(), whereas the "last error"
+ * code from non-socket POSIX-like functions has to be retrieved
+ * by calling GetLastError().
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_last_error( const char *info )
+{
+ #if defined( MBG_TGT_WIN32 )
+
+ #if !defined( MBG_TGT_KERNEL )
+ // Under Windows the "last error" code after a non-socket function
+ // has to be retrieved by calling GetLastError(), whereas
+ // the "last error" code from POSIX-like socket functions
+ // is retrieved by calling WSAGetLastError().
+ return mbg_win32_last_err_to_mbg( GetLastError(), info );
+ #else
+ return MBG_ERR_GENERIC;
+ #endif
+
+ #elif defined( MBG_TGT_POSIX )
+
+ // On POSIX systems the "last error" code is always stored in errno.
+ return mbg_posix_errno_to_mbg( errno, info );
+
+ #else
+
+ // ### TODO #error This function is not supported for this target.
+ return mbg_posix_errno_to_mbg( errno, info );
+
+ #endif
+
+} // mbg_get_last_error
+
+
+
+#if !defined( MBG_TGT_DOS )
+
+/*HDR*/
+/**
+ * @brief Get and translate last error after socket function call
+ *
+ * Retrieve the "last error" code after a socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError, whereas the "last error"
+ * code from non-socket POSIX-like functions is stored in errno as usual.
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_last_socket_error( const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #if !defined( MBG_TGT_KERNEL )
+ // Under Windows the "last error" code after a socket function
+ // has to be retrieved by calling WSAGetLastError, whereas
+ // the "last error" code from non-socket POSIX-like functions
+ // is stored in errno as usual.
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+ #else
+ return MBG_ERR_GENERIC;
+ #endif
+
+ #elif defined( MBG_TGT_POSIX )
+
+ // On POSIX systems the "last error" code is always stored in errno.
+ return mbg_posix_errno_to_mbg( errno, info );
+
+ #else
+
+ #error This function is not supported for this target.
+
+ #endif
+
+} // mbg_get_last_socket_error
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve and convert last error after gethostbyname()
+ *
+ * This function is specific to retrieve and translate error codes
+ * returned by gethostbyname() and gethostbyaddr(). In case of error
+ * these functions don't set errno but h_errno on POSIX systems, but
+ * under Windows the error code can be retrieved by WSAGetLastError()
+ * as usual.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_gethostbyname_error( const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #if !defined( MBG_TGT_KERNEL )
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+ #else
+ return MBG_ERR_GENERIC;
+ #endif
+
+ #elif defined( MBG_TGT_POSIX )
+
+ return mbg_posix_h_errno_to_mbg( h_errno, info );
+
+ #else
+
+ #error This function is not supported for this target.
+
+ #endif
+
+} // mbg_get_gethostbyname_error
+
+#endif // !defined( MBG_TGT_DOS )
+
+
+
+#if 0 // not yet finished
+// error handler for getaddressinfo()
+/*
+ * Handle specific error returned by getaddressinfo()
+ */
+ /*HDR*/
+int mbg_gai_error( int rc, const char *info )
+{
+ #if defined( MBG_TGT_CVI )
+
+ #warning This needs to be implemented for CVI
+ return MBG_ERR_UNSPEC;
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
+
+ #elif defined( MBG_TGT_POSIX )
+
+ return mbg_posix_h_errno_to_mbg( h_errno, info );
+
+ #else
+
+ return MBG_ERR_UNSPEC;
+
+ #endif
+
+} // mbg_get_gai_error
+
+#endif
+
+
+
+#if defined( USE_MBG_ZLIB )
+
+/*HDR*/
+/**
+ * @brief Retrieve and convert last zlib internal error code
+ *
+ * @param[in] zlib_error zlib internal error code
+ * @param[in] info An optional informational text string, or NULL
+ * @param[in] msg An optional zlib specific error msg, or NULL.
+ * Struct z_stream contains member msg.
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg )
+{
+ #if DEBUG
+ if ( info && msg )
+ fprintf( stderr, "%s: %s (zlib_error: %d)\n", info,
+ msg, zlib_error );
+ #endif
+
+ switch ( zlib_error )
+ {
+ case Z_ERRNO: return mbg_get_last_error( info );
+ case Z_MEM_ERROR: return MBG_ERR_NO_MEM;
+ /*
+ * All other zlib error codes are not specified any further.
+ * So, it's hard to guess what they mean and we return MBG_UNSPEC so far.
+ */
+ default:
+ return MBG_ERR_UNSPEC;
+ }
+
+} // mbg_zlib_error_to_mbg
+
+#endif // defined( USE_MBG_ZLIB )
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.h
index 714dd45..20a3edc 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgerror.h
@@ -1,8 +1,7 @@
/**************************************************************************
*
- * $Id: mbgerror.h 1.5.1.1 2011/04/20 16:09:19 martin TRASH martin $
- * $Name: $
+ * $Id: mbgerror.h 1.15 2017/07/05 09:27:25 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -12,7 +11,40 @@
*
* -----------------------------------------------------------------------
* $Log: mbgerror.h $
- * Revision 1.5.1.1 2011/04/20 16:09:19 martin
+ * Revision 1.15 2017/07/05 09:27:25 martin
+ * New error code MBG_ERR_PARM_FMT.
+ * Changed message text for MBG_ERR_NO_ENTITY.
+ * Replaced old _mbg_err_to_os() macro by new inline functions
+ * mbg_errno_to_os() and mbg_ret_val_to_os().
+ * Fixed build under Windows.
+ * Updated doxygen comments.
+ * Updated function prototypes.
+ * Revision 1.14 2017/05/10 15:21:39 martin
+ * Tiny cleanup.
+ * Revision 1.13 2017/02/28 15:23:14 gregoire
+ * error code MBG_ERR_INV_IDX added
+ * Revision 1.12 2017/01/10 15:54:56 philipp
+ * Fixed syntax error
+ * Revision 1.11 2017/01/10 14:26:31 philipp
+ * Added error MBG_ERR_NOT_CONFIGURED
+ * Revision 1.10 2016/12/16 12:40:33 thomas-b
+ * Added MBG_ERR_NO_SPACE
+ * Revision 1.9 2016/10/31 17:41:55 martin
+ * New error code MBG_ERR_DATA_FMT.
+ * Revision 1.8 2016/08/05 12:29:20 martin
+ * Re-enabled some symbols which have been commented out.
+ * Added new codes, and initializers for code/string conversion tables.
+ * Updated doxygen comments.
+ * Updated function prorotypes.
+ * Revision 1.7 2014/05/27 13:32:47Z martin
+ * Defined additional common error codes which can be
+ * translated from OS specific codes.
+ * Function prototypes from new module mbgerror.c.
+ * Comments in doxygen style.
+ * Revision 1.6 2012/10/02 18:42:26Z martin
+ * New codes MBG_ERR_N_POUT_EXCEEDS_SUPP and
+ * MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP.
+ * Modified comments for doxygen.
* Revision 1.5 2011/03/31 10:56:17 martin
* Added MBG_ERR_COPY_TO_USER and MBG_ERR_COPY_FROM_USER.
* Revision 1.4 2008/12/05 13:28:50 martin
@@ -36,6 +68,7 @@
/* Other headers to be included */
#include <mbg_tgt.h>
+#include <words.h>
#ifdef _MBGERROR
#define _ext
@@ -47,112 +80,530 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined( MBG_TGT_WIN32 )
+
+ #if !defined( STATUS_SUCCESS ) // not in kernel mode
+ #define STATUS_SUCCESS 0
+ #endif
+
+#endif
+
+
+#if !defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_KERNEL )
+ // A dummy declaration for DWORD to avoid compiler errors.
+ // Also reqired in Windows kernel mode.
+ #define DWORD uint32_t
+#endif
+
+
+
/**
- @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.
-
- @note Attention:
- These error codes below must match exactly the corresponding codes that are evaluated in user space.
- For Windows, they are located in messages.mc/.h in mbgsvctl.dll
-
- @{
-*/
-
-
-#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 */
-#define MBG_ERR_N_POUT_EXCEEDS_SUPP -39 /**< The number of programmable outputs provided by the device
- exceeds the maximum supported by the driver */
+ * @brief Error codes used with Meinberg devices and drivers
+ *
+ * Appropriate error strings can be retrieved via the ::mbg_strerror function.
+ *
+ * @see ::MBG_ERR_NAMES_ENG
+ *
+ * @anchor MBG_RETURN_CODES @{ */
+
+/* ### TODO
+ * Under Windows, some message strings are provided as resources appended
+ * to the mbgctrl DLL, but the codes specified here have to be translated
+ * to Windows-specific error codes before the appropriate resource string
+ * can be retrieved. Actually this is done by taking the absolute number
+ * of an error code and have it or'ed with 0xE0000000 afterwards, e.g.
+ * ::MBG_ERR_GENERIC (-19) will yield Windows code 0xE0000013.
+ * * See ::_mbg_err_to_os
+ */
+
+// NOTE: Some of these codes have to match codes which are defined in pcpsdefs.h
+// and returned by the firmware of bus-level devices, so the definitions
+// must *not* be renumbered.
+
+#define MBG_SUCCESS 0 ///< no error, has to match ::PCPS_SUCCESS
+
+ /** @anchor MBG_ERROR_CODES @{ */
+
+// Other codes which have to match codes defined in pcpsdefs.h returned by bus-level devices
+#define MBG_ERR_STIME -1 ///< tried to write invalid date/time/status to device, has to match ::PCPS_ERR_STIME
+#define MBG_ERR_CFG -2 ///< tried to write invalid configuration parameters to device, has to match ::PCPS_ERR_CFG (see also ::MBG_ERR_INV_CFG)
+
+
+// Codes returned by low level functions of the bus-level device driver
+#define MBG_ERR_GENERIC -19 ///< generic error
+#define MBG_ERR_TIMEOUT -20 ///< timeout accessing the device
+#define MBG_ERR_FW_ID -21 ///< invalid firmware ID
+#define MBG_ERR_NBYTES -22 ///< the number of parameter bytes passed to the device did not
+ ///< match the number of bytes expected by the device
+
+#define MBG_ERR_INV_TIME -23 ///< the device doesn't have valid time
+#define MBG_ERR_FIFO -24 ///< the data FIFO of a bus-level device is empty, though it shouldn't be
+#define MBG_ERR_NOT_READY -25 ///< bus-level device is temp. unable to respond e.g. during init. after RESET
+#define MBG_ERR_INV_TYPE -26 ///< bus-level device didn't recognize data type
+
+
+// Codes returned by the high level API functions
+#define MBG_ERR_NO_MEM -27 ///< failed to allocate memory
+#define MBG_ERR_CLAIM_RSRC -28 ///< failed to claim port or mem resource
+#define MBG_ERR_DEV_NOT_SUPP -29 ///< specified device type not supported by driver
+#define MBG_ERR_INV_DEV_REQUEST -30 ///< IOCTL call not supported by driver
+#define MBG_ERR_NOT_SUPP_BY_DEV -31 ///< cmd or feature not supported by device
+#define MBG_ERR_USB_ACCESS -32 ///< USB access failed
+#define MBG_ERR_CYCLIC_TIMEOUT -33 ///< cyclic event (IRQ, etc.) didn't occur
+#define MBG_ERR_NOT_SUPP_ON_OS -34 ///< function is not supported under this operating system
+#define MBG_ERR_LIB_NOT_COMPATIBLE -35 ///< installed shared lib. version not compat. with version used at build time
+#define MBG_ERR_N_COM_EXCEEDS_SUPP -36 ///< num. COM ports of the device exceeds max. supp. by driver
+#define MBG_ERR_N_STR_EXCEEDS_SUPP -37 ///< num. string formats of the device exceeds max. supp. by driver
+#define MBG_ERR_IRQ_UNSAFE -38 ///< enabled IRQ of bus-level device is unsafe with this firmware/ASIC version
+#define MBG_ERR_N_POUT_EXCEEDS_SUPP -39 ///< num. prog. outputs of the device exceeds max. supp. by driver
// Legacy codes used with DOS TSRs only:
-#define MBG_ERR_INV_INTNO -40 /**< Invalid interrupt number */
-#define MBG_ERR_NO_DRIVER -41 /**< A driver could not be found */
-#define MBG_ERR_DRV_VERSION -42 /**< The driver is too old */
+#define MBG_ERR_INV_INTNO -40 ///< invalid interrupt number
+#define MBG_ERR_NO_DRIVER -41 ///< a driver could not be found
+#define MBG_ERR_DRV_VERSION -42 ///< the driver is too old
+
+#define MBG_ERR_COPY_TO_USER -43 ///< kernel driver failed to copy data from kernel to user space
+#define MBG_ERR_COPY_FROM_USER -44 ///< kernel driver failed to copy data from use to kernel space
-#define MBG_ERR_COPY_TO_USER -43 /**< kernel driver failed to copy data from kernel to user space */
-#define MBG_ERR_COPY_FROM_USER -44 /**< kernel driver failed to copy data from use to kernel space */
// More codes returned by the driver's high level functions:
+#define MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP -45 ///< num. PTP unicast masters of the device exceeds max. supp. by driver
+#define MBG_ERR_N_GNSS_EXCEEDS_SUPP -46 ///< num. of GNSS systems supp. by device exceeds max. supp. by driver
+#define MBG_ERR_N_GPIO_EXCEEDS_SUPP -47 ///< num. of GPIO ports supp. by device exceeds max. supp. by driver
+#define MBG_ERR_N_XMR_EXCEEDS_SUPP -48 ///< num. of XMR sources supp. by device exceeds max. supp. by driver
+
+#define MBG_ERR_UNSPEC -60 ///< unspecified error
+
+#define MBG_ERR_HDR_CSUM -61 ///< binary protocol header checksum error
+#define MBG_ERR_DATA_CSUM -62 ///< binary protocol data checksum error
+#define MBG_ERR_RCVD_NACK -63 ///< binary protocol received reply msg with a NACK code
+#define MBG_ERR_RCVD_NO_ACK -64 ///< binary protocol received reply msg without expected ACK code //### TODO
+#define MBG_ERR_CONN_TYPE -65 ///< binary protocol no valid/supported connection type specified
+#define MBG_ERR_BYTES_WRITTEN -66 ///< binary protocol failed to write all bytes
+#define MBG_ERR_AUTH -67 ///< binary protocol failed authentication
+
+#define MBG_ERR_SOCK_INIT -68 ///< socket interface not initialized, or failed to initialize
+#define MBG_ERR_INV_SOCK_FD -69 ///< invalid socket when tried to open network socket
+#define MBG_ERR_NOT_A_SOCKET -70 ///< socket descriptor is not a socket
+#define MBG_ERR_NBLOCK_WAIT_SLCT -71 ///< select timed out when waiting for non-blocking network port to become ready
+#define MBG_ERR_NBLOCK_WAIT_WR_FD -72 ///< write fd not set after select when waiting for non-blocking network port to become ready
+
+#define MBG_ERR_IO -73 ///< generic I/O error
+#define MBG_ERR_INV_PARM -74 ///< invalid parameter
+#define MBG_ERR_NO_DEV -75 ///< specified device not found
+#define MBG_ERR_NOT_FOUND -76 ///< specified item not found
+
+#define MBG_ERR_OVERFLOW -77 ///< range or buffer overflow
+#define MBG_ERR_PIPE -78 ///< pipe error
+#define MBG_ERR_INTR -79 ///< interrupted system call
+#define MBG_ERR_ACCESS -80 ///< access denied, e.g. when trying to access a device
+#define MBG_ERR_PERM -81 ///< operation not permitted, e.g. when trying to set the system time
+#define MBG_ERR_BUSY -82 ///< device busy
+#define MBG_ERR_INV_HANDLE -83 ///< invalid file/device handle specified
+
+#define MBG_ERR_XBP_CASC_LVL -84 ///< too many XBP cascading levels
+#define MBG_ERR_ENCRYPT -85 ///< encryption failed
+#define MBG_ERR_DECRYPT -86 ///< decryption failed
+
+#define MBG_ERR_DISCONN -87 ///< connection closed by remote site / host
+#define MBG_ERR_INV_CFG -88 ///< invalid/inconsistent configuration parameters read from device, see also ::MBG_ERR_CFG
+#define MBG_ERR_RANGE -89 ///< input parameter was out of range
+
+#define MBG_ERR_INV_TLV_ANN_BYTES -90 ///< number of announced TLV bytes doesn't match number of transferred bytes
+#define MBG_ERR_INV_TLV_SIZE -91 ///< ### TODO
+#define MBG_ERR_INV_TLV_UID -92 ///< ### TODO
+
+#define MBG_ERR_EXIST -93 ///< file exists
+#define MBG_ERR_DATA_SIZE -94 ///< the received data size toesn't match the expected data size
+#define MBG_ERR_NO_ENTITY -95 ///< no such file or directory
+#define MBG_ERR_ALREADY_ALLOC -96 ///< pointer already allocated when trying to allocate memory
+#define MBG_ERR_HOST_NOT_FOUND -97 ///< host not found
+#define MBG_ERR_CONN_RESET -98 ///< connection reset by peer
+#define MBG_ERR_DATA_FMT -99 ///< invalid data format
+
+#define MBG_ERR_NO_SPACE -100 ///< insufficient disk space left on the device
+#define MBG_ERR_NOT_CONFIGURED -101 ///< configuration option is not active/configured
+#define MBG_ERR_INV_IDX -102 ///< invalid index value used
+
+#define MBG_ERR_PARM_FMT -103 ///< parameter string format error
+
+// NOTE: New codes have to be appended to this list, and the sequence of codes must not
+// be changed. Whenever new codes have been defined, appropriate entries have to be added
+// to the ::MBG_ERR_NAMES_ENG table initializer below, and the Windows-specific message
+// texts specified in messages.mc/.h from which the resources appended to mbgsvctl.dll
+// are generated have to be updated accordingly.
+
+/** @} anchor MBG_ERROR_CODES */
+
+/** @} anchor MBG_RETURN_CODES */
-#define MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP -39 /**< The number of PTP unicast masters supported by the device
- exceeds the maximum supported by the driver */
-/** @} group_error_codes */
-// Depending on the operating system, the codes above have to be converted before
-// they are sent up to user space
-#if defined( MBG_TGT_WIN32 )
- #if !defined( STATUS_SUCCESS ) // not in kernel mode
- #define STATUS_SUCCESS 0
- #endif
+/**
+ * @brief Strings associated with @ref MBG_RETURN_CODES
+ *
+ * @see @ref MBG_RETURN_CODES
+ */
+#define MBG_ERR_NAMES_ENG \
+{ \
+ { MBG_SUCCESS, "Success, no error" }, \
+ { MBG_ERR_STIME, "Invalid date/time for device" }, \
+ { MBG_ERR_CFG, "Invalid configuration parameters for device" }, \
+ { MBG_ERR_GENERIC, "Generic error" }, \
+ { MBG_ERR_TIMEOUT, "Timeout" }, \
+ { MBG_ERR_FW_ID, "Invalid firmware ID" }, \
+ { MBG_ERR_NBYTES, "Unexpected number of data bytes for this API" }, \
+ { MBG_ERR_INV_TIME, "Invalid time passed to device" }, \
+ { MBG_ERR_FIFO, "FIFO unexpectedly empty" }, \
+ { MBG_ERR_NOT_READY, "Device not ready" }, \
+ { MBG_ERR_INV_TYPE, "Unsupported data type" }, \
+ { MBG_ERR_NO_MEM, "Memory allocation error" }, \
+ { MBG_ERR_CLAIM_RSRC, "Faild to claim resources" }, \
+ { MBG_ERR_DEV_NOT_SUPP, "Device not supported" }, \
+ { MBG_ERR_INV_DEV_REQUEST, "Request not supported" }, \
+ { MBG_ERR_NOT_SUPP_BY_DEV, "Not supported by device" }, \
+ { MBG_ERR_USB_ACCESS, "USB access failed" }, \
+ { MBG_ERR_CYCLIC_TIMEOUT, "Cyclic message timeout" }, \
+ { MBG_ERR_NOT_SUPP_ON_OS, "Not supported by OS" }, \
+ { MBG_ERR_LIB_NOT_COMPATIBLE, "Shared lib not compatible" }, \
+ { MBG_ERR_N_COM_EXCEEDS_SUPP, "Num. COM ports exceeds supported" }, \
+ { MBG_ERR_N_STR_EXCEEDS_SUPP, "Num. string formats exceeds supported" }, \
+ { MBG_ERR_IRQ_UNSAFE, "Unsafe IRQ support" }, \
+ { MBG_ERR_N_POUT_EXCEEDS_SUPP, "Num prog. outputs exceeds supported" }, \
+ { MBG_ERR_INV_INTNO, "Invalid interrupt number" }, \
+ { MBG_ERR_NO_DRIVER, "Driver not found" }, \
+ { MBG_ERR_DRV_VERSION, "Driver too old" }, \
+ { MBG_ERR_COPY_TO_USER, "Error copying to user space" }, \
+ { MBG_ERR_COPY_FROM_USER, "Error copying from user space" }, \
+ { MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP, "Num. PTP Unicast masters exceeds supported" }, \
+ { MBG_ERR_N_GNSS_EXCEEDS_SUPP, "Num. GNSS systems exceeds supported" }, \
+ { MBG_ERR_N_GPIO_EXCEEDS_SUPP, "Num. GPIO ports exceeds supported" }, \
+ { MBG_ERR_N_XMR_EXCEEDS_SUPP, "Num. XMR sources exceeds supported" }, \
+ { MBG_ERR_UNSPEC, "Unspecified error" }, \
+ { MBG_ERR_HDR_CSUM, "Header checksum error" }, \
+ { MBG_ERR_DATA_CSUM, "Data checksum error" }, \
+ { MBG_ERR_RCVD_NACK, "Received NACK message" }, \
+ { MBG_ERR_RCVD_NO_ACK, "Didn't receive ACK message" }, \
+ { MBG_ERR_CONN_TYPE, "Invalid I/O connection type" }, \
+ { MBG_ERR_BYTES_WRITTEN, "Failed to write all bytes" }, \
+ { MBG_ERR_AUTH, "Authentication failed" }, \
+ { MBG_ERR_SOCK_INIT, "Failed to initialize socket" }, \
+ { MBG_ERR_INV_SOCK_FD, "Invalid socket descriptor" }, \
+ { MBG_ERR_NOT_A_SOCKET, "Not a socket descriptor" }, \
+ { MBG_ERR_NBLOCK_WAIT_SLCT, "Select timed out waiting for port ready" }, \
+ { MBG_ERR_NBLOCK_WAIT_WR_FD, "Write file descriptor not ready after waiting for port ready" }, \
+ { MBG_ERR_IO, "Generic I/O error" }, \
+ { MBG_ERR_INV_PARM, "Invalid parameter" }, \
+ { MBG_ERR_NO_DEV, "Specified device not found" }, \
+ { MBG_ERR_NOT_FOUND, "Specified item not found" }, \
+ { MBG_ERR_OVERFLOW, "Buffer overflow" }, \
+ { MBG_ERR_PIPE, "Pipe error" }, \
+ { MBG_ERR_INTR, "Interrupted system call" }, \
+ { MBG_ERR_ACCESS, "Access denied" }, \
+ { MBG_ERR_PERM, "Operation not permitted" }, \
+ { MBG_ERR_BUSY, "Device busy" }, \
+ { MBG_ERR_INV_HANDLE, "Invalid handle" }, \
+ { MBG_ERR_XBP_CASC_LVL, "Too many XBP cascading levels" }, \
+ { MBG_ERR_ENCRYPT, "Encryption failed" }, \
+ { MBG_ERR_DECRYPT, "Decryption failed" }, \
+ { MBG_ERR_DISCONN, "Connection closed by remote site/host" }, \
+ { MBG_ERR_INV_CFG, "Invalid/inconsistent configuration read from device" }, \
+ { MBG_ERR_RANGE, "Input parameter was out of range" }, \
+ { MBG_ERR_INV_TLV_ANN_BYTES, "TLV num of transferred bytes differs from num of announced bytes" }, \
+ { MBG_ERR_INV_TLV_SIZE, "MBG_ERR_INV_TLV_SIZE" }, /* ### TODO */ \
+ { MBG_ERR_INV_TLV_UID, "MBG_ERR_INV_TLV_UID" }, /* ### TODO */ \
+ { MBG_ERR_EXIST, "File exists" }, \
+ { MBG_ERR_DATA_SIZE, "Received data size mismatch" }, \
+ { MBG_ERR_NO_ENTITY, "No such file or directory" }, \
+ { MBG_ERR_ALREADY_ALLOC, "Memory already allocated" }, \
+ { MBG_ERR_HOST_NOT_FOUND, "Host not found" }, \
+ { MBG_ERR_CONN_RESET, "Connection reset by peer" }, \
+ { MBG_ERR_DATA_FMT, "Invalid data format" }, \
+ { MBG_ERR_NO_SPACE, "Insufficient disk space" }, \
+ { MBG_ERR_NOT_CONFIGURED, "Configuration is not active and/or configured" }, \
+ { MBG_ERR_INV_IDX, "Invalid or unsupported index value used"}, \
+ { MBG_ERR_PARM_FMT, "Parameter string format error" }, \
+ { 0, NULL } /* end of table */ \
+}
- #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
+#if defined( __mbg_inline )
+static __mbg_inline
+/**
+ * @brief Check if the code returned by a function indicates an error
+ *
+ * @param[in] rc One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_rc_is_success
+ * @see @ref MBG_RETURN_CODES
+ */
+bool mbg_rc_is_error( int rc )
+{
+ // Meinberg error codes are all < 0.
+ return rc < MBG_SUCCESS;
+} // mbg_rc_is_error
-/* function prototypes: */
-#ifdef __cplusplus
-extern "C" {
+static __mbg_inline
+/**
+ * @brief Check if the code returned by a function indicates success
+ *
+ * @param[in] rc One of the @ref MBG_RETURN_CODES
+ *
+ * @see ::mbg_rc_is_error
+ * @see @ref MBG_RETURN_CODES
+ */
+bool mbg_rc_is_success( int rc )
+{
+ // There are functions which don't only return MBG_SUCCESS
+ // on success but some arbitrary positive number, e.g. the
+ // number of bytes sent. So success just means "not an error".
+ return !mbg_rc_is_error( rc );
+
+} // mbg_rc_is_success
+
+#else
+
+ #define mbg_rc_is_error( _rc ) ( (_rc) < MBG_SUCCESS )
+ #define mbg_rc_is_success( _rc ) ( !mbg_rc_is_error( _rc ) )
+
#endif
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Convert one of the @ref MBG_ERROR_CODES to an OS-specific format
+ *
+ * @param[in] err_no One of the @ref MBG_ERROR_CODES.
+ *
+ * @see @ref MBG_ERROR_CODES
+ */
+int mbg_errno_to_os( int err_no )
+{
+ #if defined( MBG_TGT_WIN32 )
+
+ // Windows uses specially encoded numbers
+ return ( -err_no | 0xE0000000L );
+
+ #elif defined( MBG_TGT_BSD )
+
+ return -err_no;
+
+ #else
+
+ return err_no;
+
+ #endif
+
+} // mbg_errno_to_os
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Convert one of the @ref MBG_RETURN_CODES to an OS-specific format
+ *
+ * @param[in] rc One of the @ref MBG_RETURN_CODES.
+ *
+ * @see @ref MBG_RETURN_CODES
+ */
+int mbg_ret_val_to_os( int rc )
+{
+ #if defined( MBG_TGT_WIN32 )
+
+ return mbg_rc_is_error( rc ) ? mbg_errno_to_os( rc ) : STATUS_SUCCESS;
+
+ #elif defined( MBG_TGT_BSD )
+
+ return mbg_rc_is_error( rc ) ? mbg_errno_to_os( rc ) : MBG_SUCCESS;
+
+ #else
+
+ return rc;
+
+ #endif
+
+} // mbg_ret_val_to_os
+
+
+
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
-/* (no header definitions found) */
+ /**
+ * @brief Return an error string associated with the @ref MBG_ERROR_CODES
+ *
+ * @param[in] mbg_errno One of the @ref MBG_ERROR_CODES
+ *
+ * @return A constant string describing the error, or NULL for unknown error codes
+ */
+ const char *mbg_strerror( int mbg_errno ) ;
+
+ /**
+ * @brief Check if a value is an error code and print an associated error message
+ *
+ * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES
+ * @param[in] what A string indicated what failed
+ *
+ * @return true if rc represented an error code, and a message has been printed, else false
+ */
+ bool mbg_cond_err_msg( int rc, const char *what ) ;
+
+ /**
+ * @brief Check if a value is an general or a "not supported" error code and print an associated message
+ *
+ * If rc contains an error code then an error message is printed, and true is returned.
+ *
+ * If the optional parameter string info2 is not NULL then it should contain
+ * the name of a feature which has been tested before. In this case, if the error
+ * code is the specific error ::MBG_ERR_NOT_SUPP_BY_DEV then a "not supported" message
+ * is printed using info2.
+ *
+ * If info2 is NULL, or the error code is not ::MBG_ERR_NOT_SUPP_BY_DEV then the standard
+ * error message is printed anyway.
+ *
+ * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES
+ * @param[in] what A string indicated what failed
+ * @param[in] info An optional informational string telling what is not supported (may be NULL).
+ *
+ * @return true if rc represented an error code, and a message has been printed, else false
+ */
+ bool mbg_cond_err_msg_info( int rc, const char *what, const char *info ) ;
+
+ /**
+ * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] cvi_rc An error code returned by a CVI RS-232 library function
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ *
+ * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/
+ */
+ int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info ) ;
+
+ /**
+ * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] last_err A Windows non-socket API error code as returned by GetLastError()
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info ) ;
+
+ /**
+ * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] wsa_err A Windows socket API error code as returned by WSAGetLastError()
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info ) ;
+
+ /**
+ * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * @param[in] posix_errno A POSIX error code as usually defined in errno.h
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) ;
+
+ /**
+ * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES
+ *
+ * This function is specific to translate error codes returned by
+ * gethostbyname() and gethostbyaddr(). In case of error these functions
+ * don't set errno but h_errno to a specific value.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param[in] posix_h_errno An error code as usually defined in netdb.h
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) ;
+
+ /**
+ * @brief Get and translate last error after non-socket function call
+ *
+ * Retrieve the "last error" code after a non-socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError(), whereas the "last error"
+ * code from non-socket POSIX-like functions has to be retrieved
+ * by calling GetLastError().
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_last_error( const char *info ) ;
+
+ /**
+ * @brief Get and translate last error after socket function call
+ *
+ * Retrieve the "last error" code after a socket function has been called
+ * and translate to one of the @ref MBG_ERROR_CODES.
+ *
+ * On POSIX systems the "last error" code is always stored in errno, but
+ * e.g. under Windows the "last error" code after a socket function
+ * has to be retrieved by calling WSAGetLastError, whereas the "last error"
+ * code from non-socket POSIX-like functions is stored in errno as usual.
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_last_socket_error( const char *info ) ;
+
+ /**
+ * @brief Retrieve and convert last error after gethostbyname()
+ *
+ * This function is specific to retrieve and translate error codes
+ * returned by gethostbyname() and gethostbyaddr(). In case of error
+ * these functions don't set errno but h_errno on POSIX systems, but
+ * under Windows the error code can be retrieved by WSAGetLastError()
+ * as usual.
+ *
+ * The functions gethostbyname() and gethostbyaddr() are obsolete,
+ * and getaddressinfo() should be used preferably.
+ *
+ * @param[in] info An optional informational text string, or NULL
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_gethostbyname_error( const char *info ) ;
+
+ /**
+ * @brief Retrieve and convert last zlib internal error code
+ *
+ * @param[in] zlib_error zlib internal error code
+ * @param[in] info An optional informational text string, or NULL
+ * @param[in] msg An optional zlib specific error msg, or NULL.
+ * Struct z_stream contains member msg.
+ *
+ * @return One of the @ref MBG_ERROR_CODES
+ */
+ int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbggenio.h b/src/external/bsd/meinberg/dist/mbglib/common/mbggenio.h
index 0d6c1ef..4487130 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbggenio.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbggenio.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbggenio.h 1.5.1.3 2011/02/09 17:08:30 martin TRASH $
+ * $Id: mbggenio.h 1.6 2012/10/02 18:43:36 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,11 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: mbggenio.h $
- * Revision 1.5.1.3 2011/02/09 17:08:30 martin
+ * Revision 1.6 2012/10/02 18:43:36 martin
+ * Fixed includes for NetBSD.
* Specify I/O range number when calling port I/O macros
* so they can be used for different ranges under BSD.
- * Revision 1.5.1.2 2011/02/01 12:12:18 martin
- * Revision 1.5.1.1 2011/01/31 17:29:26 martin
* Account for modified resource handling under *BSD.
* Revision 1.5 2008/12/05 13:27:33 martin
* Generally put macro arguments in brackets for evaluation
@@ -72,10 +71,12 @@ extern "C" {
#endif
#elif defined( MBG_TGT_BSD )
-
+ #include <sys/param.h>
#include <sys/types.h>
#include <sys/bus.h>
- #include <machine/bus.h>
+ #if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 599005500
+ #include <machine/bus.h>
+ #endif
#define _mbg_inp8( _d, _i, _p ) ( (uint8_t) bus_space_read_1( ( (_d)->rsrc_info.port[_i].bsd.bst ), \
( (_d)->rsrc_info.port[_i].bsd.bsh ), (_p) ) )
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbggeo.h b/src/external/bsd/meinberg/dist/mbglib/common/mbggeo.h
index 76cf179..ff3165d 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbggeo.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbggeo.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbggeo.h 1.11 2011/06/22 10:18:10 martin TRASH $
+ * $Id: mbggeo.h 1.14 2017/05/10 15:21:40 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,7 @@
*
* Terms used:
*
- * WGS84 world geodetic system of 1984
+ * WGS84 World Geodetic System of 1984
*
* XYZ WGS84 earth centered, earth fixed (ECEF) kartesian
* coordinates
@@ -22,6 +22,13 @@
*
* -----------------------------------------------------------------------
* $Log: mbggeo.h $
+ * Revision 1.14 2017/05/10 15:21:40 martin
+ * Tiny cleanup.
+ * Revision 1.13 2017/01/27 08:57:58 martin
+ * Fixed macro syntax.
+ * Revision 1.12 2016/10/31 16:50:56 martin
+ * Fixed a typo.
+ * Updated doxygen comments.
* Revision 1.11 2011/06/22 10:18:10 martin
* Cleaned up handling of pragma pack().
* Revision 1.10 2008/09/03 14:54:28 martin
@@ -34,7 +41,7 @@
* 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
+ * 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.
@@ -69,106 +76,136 @@
#define _USING_BYTE_ALIGNMENT
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
- Geographic longitude or latitude in [degrees, minutes, seconds]
- longitude East latitude North and positve, South or West angles negative
+ * @brief Geographic longitude or latitude in [degrees, minutes, seconds]
+ *
+ * Longitude East and latitude North are positive angles, South or West
+ * angles are negative.
*/
typedef struct
{
- uint16_t prefix; /**< 'N', 'E', 'S' or 'W' */
- uint16_t deg; /**< [0...90 (lat) or 0...180 (lon)] */
- uint16_t min; /**< [0...59] */
- double sec; /**< [0...59.999] */
+ uint16_t prefix; ///< 'N', 'E', 'S' or 'W'
+ uint16_t deg; ///< [0...90 (lat) or 0...180 (lon)]
+ uint16_t min; ///< [0...59]
+ double sec; ///< [0...59.99999...]
+
} DMS;
-// The corresponding macro _mbg_swab_dms() is defined in gpsdefs.h.
#define _mbg_swab_dms( _p ) \
+do \
{ \
_mbg_swab16( &(_p)->prefix ); \
_mbg_swab16( &(_p)->deg ); \
_mbg_swab16( &(_p)->min ); \
_mbg_swab_double( &(_p)->sec ); \
-}
+} while ( 0 )
+/**
+ * @brief A geographic position represented in different formats
+ */
typedef struct
{
- XYZ xyz; /**< always WGS84 ECEF coordinates */
- LLA lla; /**< depending on the ellipsoid used for reference */
- DMS longitude; /**< longitude in degrees, minutes, seconds */
- DMS latitude; /**< latitude in degrees, minutes, seconds */
- int16_t ellipsoid; /**< ellipsoid used for reference */
+ XYZ xyz; ///< Always WGS84 ECEF coordinates
+ LLA lla; ///< Longitude, latitude and altitude, depending on the ellipsoid used for reference
+ DMS longitude; ///< Longitude broken down to degrees, minutes, seconds
+ DMS latitude; ///< Latitude broken down to degrees, minutes, seconds
+ int16_t ellipsoid; ///< Ellipsoid used for reference, see ::ELLIPSOIDS
+
} POS;
#define _mbg_swab_pos( _p ) \
+do \
{ \
_mbg_swab_xyz( (_p)->xyz ); \
_mbg_swab_lla( (_p)->lla ); \
_mbg_swab_dms( &(_p)->longitude ); \
_mbg_swab_dms( &(_p)->latitude ); \
_mbg_swab16( &(_p)->ellipsoid ); \
-}
+} while ( 0 )
+/**
+ * @brief A structure used internally to compute a geographic position
+ *
+ * Also contains intermediate results useful for the computation.
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
+ CSUM csum; ///< Checksum of the remaining bytes
+ int16_t valid; ///< Indicator if data is valid
- char name[40];
- POS pos; /* the position in WGS84 ECEF coords and LLA */
+ char name[40]; ///< Informational string
+ 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 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 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(). */
+ // 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 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 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 */
+ double e_radius; ///< N
+ double e_radius_alt; ///< N + h
} USER_POS;
+/**
+ * @brief Characteristics of a geographic reference ellipsoid
+ */
typedef struct
{
- CSUM csum; /* checksum of the remaining bytes */
- int16_t valid; /* flag data are valid */
+ CSUM csum; ///< Checksum of the remaining bytes
+ int16_t valid; ///< Indicator if data is valid
char name[40];
- XYZ dxyz; /* offset from the WGS84 ECEF coords */
- double a; /* semi major axis */
- double rcp_f; /* reciproke of flatness */
+ XYZ dxyz; ///< Offset from the WGS84 ECEF coords
+ double a; ///< Semi major axis
+ double rcp_f; ///< Reciproke of flatness
+
+ // The variables below are computed in the init_mbggeo() function:
-/* 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
- double f; /* flatness */
- double b; /* semi minor axis */
- double sqr_e; /* square of numerical eccentricity */
} ELLIPSOID;
-enum { WGS84, BESSEL, N_ELLIPSOIDS };
+/**
+ * @brief An enumeration of known ellipsoids
+ */
+enum ELLIPSOIDS
+{
+ WGS84,
+ BESSEL,
+ N_ELLIPSOIDS
+};
+
_ext ELLIPSOID ellipsoid[N_ELLIPSOIDS]
#ifdef _DO_INIT
@@ -191,15 +228,15 @@ _ext ELLIPSOID ellipsoid[N_ELLIPSOIDS]
;
-/* WGS84 constants used */
+// WGS84 constants used
-_ext double OMEGADOTe /* earth's rotation rate [rad/sec] */
+_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] */
+_ext double mue // Earth's gravitational constant [m^3/sec^2]
#ifdef _DO_INIT
= 3.986005e14
#endif
@@ -249,18 +286,12 @@ _ext double d2r
;
-/* variables for simplifying computations */
+// Variables for simplifying computations
_ext double gps_two_pi;
-_ext double sqrt_mue; /* sqrt( mue ) */
-
-
+_ext double sqrt_mue; // sqrt( mue )
-/* function prototypes: */
-#ifdef __cplusplus
-extern "C" {
-#endif
/* ----- function prototypes begin ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgioctl.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgioctl.h
index 2dfb6a0..54732c1 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgioctl.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgioctl.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgioctl.h 1.24.1.10 2011/07/20 15:49:00 martin TRASH $
+ * $Id: mbgioctl.h 1.27 2017/07/05 09:37:18 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,22 +10,29 @@
*
* -----------------------------------------------------------------------
* $Log: mbgioctl.h $
- * Revision 1.24.1.10 2011/07/20 15:49:00 martin
+ * Revision 1.27 2017/07/05 09:37:18 martin
+ * Definitions to support GPIO ports and XMR.
+ * Support new way to check if specific feature supported.
+ * Moved some IOCTL-related definitions from pcpsdev.h here.
+ * Added some doxygen comments.
+ * Revision 1.26 2013/09/26 08:27:04Z martin
+ * Support GNSS API.
+ * Revision 1.25 2012/10/02 18:45:55 martin
+ * There are some g++ versions which fail to compile source code using
+ * the macros provided by Linux to define IOCTL codes. If only the API
+ * functions are called by an application then the IOCTL codes aren't
+ * required anyway, so we just avoid inclusion of mbgioctl.h.
+ * However, some IOCTL related definitions are required anyway, so
+ * they have been moved to pcpsdev.h which is always included.
+ * Support on-board event logs.
+ * Support debug status.
* Conditionally use older IOCTL request buffer structures.
- * Revision 1.24.1.9 2011/07/19 12:31:59 martin
- * Relaxed required priority level for generic read functions.
- * Revision 1.24.1.8 2011/07/18 10:18:49 martin
- * Revision 1.24.1.7 2011/07/15 14:50:11 martin
- * Revision 1.24.1.6 2011/07/14 14:54:01 martin
* Modified generic IOCTL handling such that for calls requiring variable sizes
* a fixed request block containing input and output buffer pointers and sizes is
* passed down to the kernel driver. This simplifies implementation under *BSD
* and also works for other target systems.
- * Revision 1.24.1.5 2011/07/06 11:19:28 martin
* Support reading CORR_INFO, and reading/writing TR_DISTANCE.
- * Revision 1.24.1.4 2011/06/29 10:52:00 martin
* New code IOCTL_DEV_HAS_PZF.
- * Revision 1.24.1.3 2011/06/21 15:03:29 martin
* Support PTP unicast configuration.
* Changed the names of a few IOCTL codes to follow general naming conventions.
* Added definitions to support privilege level requirements for IOCTLs.
@@ -33,13 +40,9 @@
* Added definitions to set up a table of all known
* IOCTL codes and names.
* Use MBG_TGT_KERNEL instead of _KDD_.
- * Fixed a typo.
- * Revision 1.24.1.2 2011/03/22 11:19:46 martin
* Use IOTYPE 'Z' under *BSD since this means passthrough on NetBSD.
- * Revision 1.24.1.1 2011/02/15 11:21:21 daniel
- * Added ioctls to support PTP unicast configuration
* Revision 1.24 2009/12/15 15:34:59Z daniel
- * Support reading the raw IRIG data bits for firmware versions
+ * Support reading the raw IRIG data bits for firmware versions
* which support this feature.
* Revision 1.23 2009/09/29 15:08:41Z martin
* Support retrieving time discipline info.
@@ -79,23 +82,23 @@
* Added support for programmable pulse outputs.
* Revision 1.12 2005/06/02 10:22:05Z martin
* Added IOCTL code IOCTL_GET_SYNTH_STATE.
- * Added IOCTL codes IOCTL_DEV_HAS_GENERIC_IO,
+ * Added IOCTL codes IOCTL_DEV_HAS_GENERIC_IO,
* IOCTL_PCPS_GENERIC_IO, and IOCTL_GET_SYNTH_STATE.
* Revision 1.11 2005/01/14 10:21:11Z martin
* Added IOCTLs which query device features.
* Revision 1.10 2004/12/09 11:03:36Z martin
* Support configuration of on-board frequency synthesizer.
* Revision 1.9 2004/11/09 12:49:41Z martin
- * Modifications were required in order to be able to configure IRIG
+ * Modifications were required in order to be able to configure IRIG
* settings of cards which provide both IRIG input and output.
- * The existing codes have been renamed with .._RX.. and are used to
- * configure the IRIG receiver (input). New codes have been defined
+ * The existing codes have been renamed with .._RX.. and are used to
+ * configure the IRIG receiver (input). New codes have been defined
* used to configure the IRIG transmitter.
* Renamed IOCTL_GET_GPS_STAT to IOCTL_GET_GPS_BVAR_STAT.
* Use more specific data types than generic types.
* Modified IOCTL codes used for hardware debugging.
* Revision 1.8 2004/09/06 15:46:04Z martin
- * Changed definition of IOCTL codes to support syntax used
+ * Changed definition of IOCTL codes to support syntax used
* with Linux kernel 2.6.x.
* Account for renamed symbols.
* Revision 1.7 2004/04/07 10:08:11 martin
@@ -129,17 +132,57 @@
/* Other headers to be included */
#include <mbg_tgt.h>
+#include <mbgerror.h>
#include <mbggeo.h>
#include <pcpsdev.h>
#include <pci_asic.h>
-#define USE_DEBUG_PORT defined( MBG_ARCH_X86 )
+#if defined( MBG_TGT_LINUX )
+ #include <linux/ioctl.h>
+#endif
-#if defined( MBG_TGT_LINUX )
+#if defined( MBG_TGT_BSD )
+ #include <sys/ioccom.h>
+#endif
- #include <linux/ioctl.h>
+
+#if defined( MBG_TGT_WIN32 )
+
+ #if !defined( MBG_TGT_KERNEL )
+ #include <winioctl.h>
+ #endif
+
+ #if !defined( MBG_TGT_WIN32_NON_PNP )
+ #ifdef _MBGIOCTL
+ #include <initguid.h> // instance the GUID
+ #else
+ #include <guiddef.h> // just define the GUID
+ #endif
+ #endif
+
+#endif
+
+
+
+/* Start of header body */
+
+// We have to use native alignment here!
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined( MBG_ARCH_X86 )
+ #define USE_DEBUG_PORT 1
+#else
+ #define USE_DEBUG_PORT 0
+#endif
+
+
+#if defined( MBG_TGT_LINUX )
// a magic number used to generate IOCTL cmd codes
#define IOTYPE 'M'
@@ -153,8 +196,6 @@
#elif defined( MBG_TGT_BSD )
- #include <sys/ioccom.h>
-
// Under NetBSD 'Z' marks passthrough IOCTLs, under FreeBSD the code
// does not seem to matter, so we use 'Z' anyway.
#define IOTYPE 'Z'
@@ -171,19 +212,6 @@
#define _MBG_SUPP_VAR_ACC_SIZE 1
#endif
- #if !defined( MBG_TGT_KERNEL )
- #include <windows.h>
- #include <winioctl.h>
- #endif
-
- #if !defined( MBG_TGT_WIN32_NON_PNP )
- #ifdef _MBGIOCTL
- #include <initguid.h> // instance the GUID
- #else
- #include <guiddef.h> // just define the GUID
- #endif
- #endif
-
#ifdef DEFINE_GUID // don't break compiles of drivers that
// include this header but don't want the
// GUIDs
@@ -221,18 +249,6 @@
#endif
-#ifdef _MBGIOCTL
- #define _ext
- #define _DO_INIT
-#else
- #define _ext extern
-#endif
-
-
-/* Start of header body */
-
-// We must use native alignment here!
-
// The structure below is used by the IOCTL_PCPS_GENERIC_... calls.
@@ -242,6 +258,11 @@
#endif
#endif
+#if defined( MBG_TGT_WIN32 )
+ // required for 32bit/64 bit compatibility
+ #define USE_IOCTL_GENERIC_REQ 0
+#endif
+
#if !defined( USE_IOCTL_GENERIC_REQ )
#define USE_IOCTL_GENERIC_REQ 1
#endif
@@ -249,9 +270,13 @@
#if USE_IOCTL_GENERIC_REQ
-// This does not yet work properly under Linux/Sparc where the kernel may be 64 bit
-// while user space is 32 bit, which leads to different sizes for pointers and size_t.
-
+/**
+ * @brief A structure used to pass generic IOCTL requests to the kernel driver
+ *
+ * @note This does not work properly under Linux/Sparc where the kernel
+ * may be 64 bit while user space is 32 bit, which leads to different sizes
+ * for pointers, size_t, etc.
+ */
typedef struct
{
ulong info;
@@ -266,18 +291,36 @@ typedef struct
#else
-// The structure below is used by the IOCTL_PCPS_GENERIC_... calls.
+/**
+ * @brief Control structure used for generic IOCTL requests
+ *
+ * Used by the IOCTL_PCPS_GENERIC_... calls.
+ *
+ * @note Is slower, but avoids OS-specific problems occurring
+ * with IOCTL_GENERIC_REQ.
+ */
typedef struct
{
uint32_t info;
uint32_t data_size_in;
uint32_t data_size_out;
+
} IOCTL_GENERIC_CTL;
+
+/**
+ * @brief Data buffer used for generic IOCTL requests
+ *
+ * Used by the IOCTL_PCPS_GENERIC_... calls.
+ *
+ * @note Is slower, but avoids OS-specific problems occurring
+ * with IOCTL_GENERIC_REQ.
+ */
typedef struct
{
IOCTL_GENERIC_CTL ctl;
uint8_t data[1];
+
} IOCTL_GENERIC_BUFFER;
#define _MBG_IOG( _t, _n, _s ) _MBG_IO( _t, _n )
@@ -286,6 +329,27 @@ typedef struct
+/**
+ * @brief Request buffer used to query a device feature
+ */
+typedef struct
+{
+ uint32_t feat_req_type; ///< See ::DEV_FEAT_REQ_TYPES
+ uint32_t feat_num; ///< Number and range depending on ::IOCTL_DEV_FEAT_REQ::feat_req_type value
+
+} IOCTL_DEV_FEAT_REQ;
+
+
+
+/**
+ * @defgroup group_ioctl_codes IOCTL codes used by Meinberg drivers
+ *
+ * @see ::IOCTL_CODES_TABLE
+ *
+ * @anchor IOCTL_CODES
+ *
+ * @{ */
+
// read general driver info, device info, and status port
#define IOCTL_GET_PCPS_DRVR_INFO _MBG_IOR( IOTYPE, 0x00, PCPS_DRVR_INFO )
#define IOCTL_GET_PCPS_DEV _MBG_IOR( IOTYPE, 0x01, PCPS_DEV )
@@ -480,6 +544,35 @@ typedef struct
#define IOCTL_GET_TR_DISTANCE _MBG_IOR( IOTYPE, 0x8C, TR_DISTANCE )
#define IOCTL_SET_TR_DISTANCE _MBG_IOW( IOTYPE, 0x8D, TR_DISTANCE )
+#define IOCTL_DEV_HAS_DEBUG_STATUS _MBG_IOR( IOTYPE, 0x8E, int )
+#define IOCTL_GET_DEBUG_STATUS _MBG_IOR( IOTYPE, 0x8F, MBG_DEBUG_STATUS )
+
+#define IOCTL_DEV_HAS_EVT_LOG _MBG_IOR( IOTYPE, 0x90, int )
+#define IOCTL_CLR_EVT_LOG _MBG_IO( IOTYPE, 0x91 )
+#define IOCTL_GET_NUM_EVT_LOG_ENTRIES _MBG_IOR( IOTYPE, 0x92, MBG_NUM_EVT_LOG_ENTRIES )
+#define IOCTL_GET_FIRST_EVT_LOG_ENTRY _MBG_IOR( IOTYPE, 0x93, MBG_EVT_LOG_ENTRY )
+#define IOCTL_GET_NEXT_EVT_LOG_ENTRY _MBG_IOR( IOTYPE, 0x94, MBG_EVT_LOG_ENTRY )
+
+#define IOCTL_DEV_IS_GNSS _MBG_IOR( IOTYPE, 0x95, int )
+#define IOCTL_GET_GNSS_MODE_INFO _MBG_IOR( IOTYPE, 0x96, MBG_GNSS_MODE_INFO )
+#define IOCTL_SET_GNSS_MODE_SETTINGS _MBG_IOW( IOTYPE, 0x97, MBG_GNSS_MODE_SETTINGS )
+#define IOCTL_GET_ALL_GNSS_SAT_INFO _MBG_IOG( IOTYPE, 0x98, IOCTL_GENERIC_REQ ) // variable size
+
+#define IOCTL_DEV_HAS_GPIO _MBG_IOR( IOTYPE, 0x99, int )
+#define IOCTL_GET_GPIO_CFG_LIMITS _MBG_IOR( IOTYPE, 0x9A, MBG_GPIO_CFG_LIMITS )
+#define IOCTL_GET_ALL_GPIO_INFO _MBG_IOG( IOTYPE, 0x9B, IOCTL_GENERIC_REQ ) // variable size
+#define IOCTL_SET_GPIO_SETTINGS_IDX _MBG_IOW( IOTYPE, 0x9C, MBG_GPIO_SETTINGS_IDX )
+
+#define IOCTL_DEV_HAS_XMR _MBG_IOR( IOTYPE, 0x9D, int )
+#define IOCTL_GET_XMR_INSTANCES _MBG_IOR( IOTYPE, 0x9E, XMULTI_REF_INSTANCES )
+#define IOCTL_GET_ALL_XMR_INFO _MBG_IOG( IOTYPE, 0x9F, IOCTL_GENERIC_REQ ) // variable size
+#define IOCTL_SET_XMR_SETTINGS_IDX _MBG_IOW( IOTYPE, 0xA0, XMULTI_REF_SETTINGS_IDX )
+#define IOCTL_GET_ALL_XMR_STATUS _MBG_IOG( IOTYPE, 0xA1, IOCTL_GENERIC_REQ ) // variable size
+#define IOCTL_GET_XMR_HOLDOVER_STATUS _MBG_IOR( IOTYPE, 0xA2, XMR_HOLDOVER_STATUS )
+
+#define IOCTL_GET_ALL_GPIO_STATUS _MBG_IOG( IOTYPE, 0xA3, IOCTL_GENERIC_REQ ) // variable size
+#define IOCTL_CHK_DEV_FEAT _MBG_IOW( IOTYPE, 0xA4, IOCTL_DEV_FEAT_REQ )
+
// The codes below are subject to changes without notice. They may be supported
// by some kernel drivers, but usage is restricted to Meinberg software development.
// Unrestricted usage may cause system malfunction !!
@@ -489,154 +582,182 @@ typedef struct
#define IOCTL_MBG_DBG_CLR_BIT _MBG_IOW( IOTYPE, 0xF3, uint8_t )
#define IOCTL_MBG_DBG_CLR_ALL _MBG_IO( IOTYPE, 0xF4 )
+/** @} defgroup group_ioctl_codes */
+
/**
* @brief An initializer for a table of IOCTL codes and associated names.
*
- * This can e.g. be assigned to an array of MBG_CODE_NAME_TABLE_ENTRY elements
+ * This can e.g. initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
* and may be helpful when debugging.
+ *
+ * @see @ref IOCTL_CODES
*/
-#define MBG_IOCTL_CODE_TABLE \
-{ \
- { IOCTL_GET_PCPS_DRVR_INFO, "IOCTL_GET_PCPS_DRVR_INFO" }, \
- { IOCTL_GET_PCPS_DEV, "IOCTL_GET_PCPS_DEV" }, \
- { IOCTL_GET_PCPS_STATUS_PORT, "IOCTL_GET_PCPS_STATUS_PORT" }, \
- { IOCTL_PCPS_GENERIC_READ, "IOCTL_PCPS_GENERIC_READ" }, \
- { IOCTL_PCPS_GENERIC_WRITE, "IOCTL_PCPS_GENERIC_WRITE" }, \
- { IOCTL_PCPS_GENERIC_READ_GPS, "IOCTL_PCPS_GENERIC_READ_GPS" }, \
- { IOCTL_PCPS_GENERIC_WRITE_GPS, "IOCTL_PCPS_GENERIC_WRITE_GPS" }, \
- { IOCTL_GET_PCPS_TIME, "IOCTL_GET_PCPS_TIME" }, \
- { IOCTL_SET_PCPS_TIME, "IOCTL_SET_PCPS_TIME" }, \
- { IOCTL_GET_PCPS_SYNC_TIME, "IOCTL_GET_PCPS_SYNC_TIME" }, \
- { IOCTL_GET_PCPS_TIME_SEC_CHANGE, "IOCTL_GET_PCPS_TIME_SEC_CHANGE" }, \
- { IOCTL_GET_PCPS_HR_TIME, "IOCTL_GET_PCPS_HR_TIME" }, \
- { IOCTL_SET_PCPS_EVENT_TIME, "IOCTL_SET_PCPS_EVENT_TIME" }, \
- { IOCTL_GET_PCPS_SERIAL, "IOCTL_GET_PCPS_SERIAL" }, \
- { IOCTL_SET_PCPS_SERIAL, "IOCTL_SET_PCPS_SERIAL" }, \
- { IOCTL_GET_PCPS_TZCODE, "IOCTL_GET_PCPS_TZCODE" }, \
- { IOCTL_SET_PCPS_TZCODE, "IOCTL_SET_PCPS_TZCODE" }, \
- { IOCTL_GET_PCPS_TZDL, "IOCTL_GET_PCPS_TZDL" }, \
- { IOCTL_SET_PCPS_TZDL, "IOCTL_SET_PCPS_TZDL" }, \
- { IOCTL_GET_REF_OFFS, "IOCTL_GET_REF_OFFS" }, \
- { IOCTL_SET_REF_OFFS, "IOCTL_SET_REF_OFFS" }, \
- { IOCTL_GET_MBG_OPT_INFO, "IOCTL_GET_MBG_OPT_INFO" }, \
- { IOCTL_SET_MBG_OPT_SETTINGS, "IOCTL_SET_MBG_OPT_SETTINGS" }, \
- { IOCTL_GET_PCPS_IRIG_RX_INFO, "IOCTL_GET_PCPS_IRIG_RX_INFO" }, \
- { IOCTL_SET_PCPS_IRIG_RX_SETTINGS, "IOCTL_SET_PCPS_IRIG_RX_SETTINGS" }, \
- { IOCTL_PCPS_CLR_UCAP_BUFF, "IOCTL_PCPS_CLR_UCAP_BUFF" }, \
- { IOCTL_GET_PCPS_UCAP_ENTRIES, "IOCTL_GET_PCPS_UCAP_ENTRIES" }, \
- { IOCTL_GET_PCPS_UCAP_EVENT, "IOCTL_GET_PCPS_UCAP_EVENT" }, \
- { IOCTL_GET_GPS_TZDL, "IOCTL_GET_GPS_TZDL" }, \
- { IOCTL_SET_GPS_TZDL, "IOCTL_SET_GPS_TZDL" }, \
- { IOCTL_GET_GPS_SW_REV, "IOCTL_GET_GPS_SW_REV" }, \
- { IOCTL_GET_GPS_BVAR_STAT, "IOCTL_GET_GPS_BVAR_STAT" }, \
- { IOCTL_GET_GPS_TIME, "IOCTL_GET_GPS_TIME" }, \
- { IOCTL_SET_GPS_TIME, "IOCTL_SET_GPS_TIME" }, \
- { IOCTL_GET_GPS_PORT_PARM, "IOCTL_GET_GPS_PORT_PARM" }, \
- { IOCTL_SET_GPS_PORT_PARM, "IOCTL_SET_GPS_PORT_PARM" }, \
- { IOCTL_GET_GPS_ANT_INFO, "IOCTL_GET_GPS_ANT_INFO" }, \
- { IOCTL_GET_GPS_UCAP, "IOCTL_GET_GPS_UCAP" }, \
- { IOCTL_GET_GPS_ENABLE_FLAGS, "IOCTL_GET_GPS_ENABLE_FLAGS" }, \
- { IOCTL_SET_GPS_ENABLE_FLAGS, "IOCTL_SET_GPS_ENABLE_FLAGS" }, \
- { IOCTL_GET_GPS_STAT_INFO, "IOCTL_GET_GPS_STAT_INFO" }, \
- { IOCTL_SET_GPS_CMD, "IOCTL_SET_GPS_CMD" }, \
- { IOCTL_GET_GPS_IDENT, "IOCTL_GET_GPS_IDENT" }, \
- { IOCTL_GET_GPS_POS, "IOCTL_GET_GPS_POS" }, \
- { IOCTL_SET_GPS_POS_XYZ, "IOCTL_SET_GPS_POS_XYZ" }, \
- { IOCTL_SET_GPS_POS_LLA, "IOCTL_SET_GPS_POS_LLA" }, \
- { IOCTL_GET_GPS_ANT_CABLE_LEN, "IOCTL_GET_GPS_ANT_CABLE_LEN" }, \
- { IOCTL_SET_GPS_ANT_CABLE_LEN, "IOCTL_SET_GPS_ANT_CABLE_LEN" }, \
- { IOCTL_GET_GPS_RECEIVER_INFO, "IOCTL_GET_GPS_RECEIVER_INFO" }, \
- { IOCTL_GET_GPS_ALL_STR_TYPE_INFO, "IOCTL_GET_GPS_ALL_STR_TYPE_INFO" }, \
- { IOCTL_GET_GPS_ALL_PORT_INFO, "IOCTL_GET_GPS_ALL_PORT_INFO" }, \
- { IOCTL_SET_GPS_PORT_SETTINGS_IDX, "IOCTL_SET_GPS_PORT_SETTINGS_IDX" }, \
- { IOCTL_GET_PCI_ASIC_VERSION, "IOCTL_GET_PCI_ASIC_VERSION" }, \
- { IOCTL_GET_PCPS_TIME_CYCLES, "IOCTL_GET_PCPS_TIME_CYCLES" }, \
- { IOCTL_GET_PCPS_HR_TIME_CYCLES, "IOCTL_GET_PCPS_HR_TIME_CYCLES" }, \
- { IOCTL_GET_PCPS_IRIG_TX_INFO, "IOCTL_GET_PCPS_IRIG_TX_INFO" }, \
- { IOCTL_SET_PCPS_IRIG_TX_SETTINGS, "IOCTL_SET_PCPS_IRIG_TX_SETTINGS" }, \
- { IOCTL_GET_SYNTH, "IOCTL_GET_SYNTH" }, \
- { IOCTL_SET_SYNTH, "IOCTL_SET_SYNTH" }, \
- { IOCTL_DEV_IS_GPS, "IOCTL_DEV_IS_GPS" }, \
- { IOCTL_DEV_IS_DCF, "IOCTL_DEV_IS_DCF" }, \
- { IOCTL_DEV_IS_IRIG_RX, "IOCTL_DEV_IS_IRIG_RX" }, \
- { IOCTL_DEV_HAS_HR_TIME, "IOCTL_DEV_HAS_HR_TIME" }, \
- { IOCTL_DEV_HAS_CAB_LEN, "IOCTL_DEV_HAS_CAB_LEN" }, \
- { IOCTL_DEV_HAS_TZDL, "IOCTL_DEV_HAS_TZDL" }, \
- { IOCTL_DEV_HAS_PCPS_TZDL, "IOCTL_DEV_HAS_PCPS_TZDL" }, \
- { IOCTL_DEV_HAS_TZCODE, "IOCTL_DEV_HAS_TZCODE" }, \
- { IOCTL_DEV_HAS_TZ, "IOCTL_DEV_HAS_TZ" }, \
- { IOCTL_DEV_HAS_EVENT_TIME, "IOCTL_DEV_HAS_EVENT_TIME" }, \
- { IOCTL_DEV_HAS_RECEIVER_INFO, "IOCTL_DEV_HAS_RECEIVER_INFO" }, \
- { IOCTL_DEV_CAN_CLR_UCAP_BUFF, "IOCTL_DEV_CAN_CLR_UCAP_BUFF" }, \
- { IOCTL_DEV_HAS_UCAP, "IOCTL_DEV_HAS_UCAP" }, \
- { IOCTL_DEV_HAS_IRIG_TX, "IOCTL_DEV_HAS_IRIG_TX" }, \
- { IOCTL_DEV_HAS_SERIAL_HS, "IOCTL_DEV_HAS_SERIAL_HS" }, \
- { IOCTL_DEV_HAS_SIGNAL, "IOCTL_DEV_HAS_SIGNAL" }, \
- { IOCTL_DEV_HAS_MOD, "IOCTL_DEV_HAS_MOD" }, \
- { IOCTL_DEV_HAS_IRIG, "IOCTL_DEV_HAS_IRIG" }, \
- { IOCTL_DEV_HAS_REF_OFFS, "IOCTL_DEV_HAS_REF_OFFS" }, \
- { IOCTL_DEV_HAS_OPT_FLAGS, "IOCTL_DEV_HAS_OPT_FLAGS" }, \
- { IOCTL_DEV_HAS_GPS_DATA, "IOCTL_DEV_HAS_GPS_DATA" }, \
- { IOCTL_DEV_HAS_SYNTH, "IOCTL_DEV_HAS_SYNTH" }, \
- { IOCTL_DEV_HAS_GENERIC_IO, "IOCTL_DEV_HAS_GENERIC_IO" }, \
- { IOCTL_PCPS_GENERIC_IO, "IOCTL_PCPS_GENERIC_IO" }, \
- { IOCTL_GET_SYNTH_STATE, "IOCTL_GET_SYNTH_STATE" }, \
- { IOCTL_GET_GPS_ALL_POUT_INFO, "IOCTL_GET_GPS_ALL_POUT_INFO" }, \
- { IOCTL_SET_GPS_POUT_SETTINGS_IDX, "IOCTL_SET_GPS_POUT_SETTINGS_IDX" }, \
- { IOCTL_GET_MAPPED_MEM_ADDR, "IOCTL_GET_MAPPED_MEM_ADDR" }, \
- { IOCTL_UNMAP_MAPPED_MEM, "IOCTL_UNMAP_MAPPED_MEM" }, \
- { IOCTL_GET_PCI_ASIC_FEATURES, "IOCTL_GET_PCI_ASIC_FEATURES" }, \
- { IOCTL_DEV_HAS_PCI_ASIC_FEATURES, "IOCTL_DEV_HAS_PCI_ASIC_FEATURES" }, \
- { IOCTL_DEV_HAS_PCI_ASIC_VERSION, "IOCTL_DEV_HAS_PCI_ASIC_VERSION" }, \
- { IOCTL_DEV_IS_MSF, "IOCTL_DEV_IS_MSF" }, \
- { IOCTL_DEV_IS_LWR, "IOCTL_DEV_IS_LWR" }, \
- { IOCTL_DEV_IS_WWVB, "IOCTL_DEV_IS_WWVB" }, \
- { IOCTL_GET_IRQ_STAT_INFO, "IOCTL_GET_IRQ_STAT_INFO" }, \
- { IOCTL_GET_CYCLES_FREQUENCY, "IOCTL_GET_CYCLES_FREQUENCY" }, \
- { IOCTL_DEV_HAS_FAST_HR_TIMESTAMP, "IOCTL_DEV_HAS_FAST_HR_TIMESTAMP" }, \
- { IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES, "IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES" }, \
- { IOCTL_GET_FAST_HR_TIMESTAMP, "IOCTL_GET_FAST_HR_TIMESTAMP" }, \
- { IOCTL_DEV_HAS_GPS_TIME_SCALE, "IOCTL_DEV_HAS_GPS_TIME_SCALE" }, \
- { IOCTL_GET_GPS_TIME_SCALE_INFO, "IOCTL_GET_GPS_TIME_SCALE_INFO" }, \
- { IOCTL_SET_GPS_TIME_SCALE_SETTINGS, "IOCTL_SET_GPS_TIME_SCALE_SETTINGS" }, \
- { IOCTL_DEV_HAS_GPS_UTC_PARM, "IOCTL_DEV_HAS_GPS_UTC_PARM" }, \
- { IOCTL_GET_GPS_UTC_PARM, "IOCTL_GET_GPS_UTC_PARM" }, \
- { IOCTL_SET_GPS_UTC_PARM, "IOCTL_SET_GPS_UTC_PARM" }, \
- { IOCTL_DEV_HAS_IRIG_CTRL_BITS, "IOCTL_DEV_HAS_IRIG_CTRL_BITS" }, \
- { IOCTL_GET_IRIG_CTRL_BITS, "IOCTL_GET_IRIG_CTRL_BITS" }, \
- { IOCTL_DEV_HAS_LAN_INTF, "IOCTL_DEV_HAS_LAN_INTF" }, \
- { IOCTL_GET_LAN_IF_INFO, "IOCTL_GET_LAN_IF_INFO" }, \
- { IOCTL_GET_IP4_STATE, "IOCTL_GET_IP4_STATE" }, \
- { IOCTL_GET_IP4_SETTINGS, "IOCTL_GET_IP4_SETTINGS" }, \
- { IOCTL_SET_IP4_SETTINGS, "IOCTL_SET_IP4_SETTINGS" }, \
- { IOCTL_DEV_IS_PTP, "IOCTL_DEV_IS_PTP" }, \
- { IOCTL_DEV_HAS_PTP, "IOCTL_DEV_HAS_PTP" }, \
- { IOCTL_GET_PTP_STATE, "IOCTL_GET_PTP_STATE" }, \
- { IOCTL_GET_PTP_CFG_INFO, "IOCTL_GET_PTP_CFG_INFO" }, \
- { IOCTL_SET_PTP_CFG_SETTINGS, "IOCTL_SET_PTP_CFG_SETTINGS" }, \
- { IOCTL_DEV_HAS_IRIG_TIME, "IOCTL_DEV_HAS_IRIG_TIME" }, \
- { IOCTL_GET_IRIG_TIME, "IOCTL_GET_IRIG_TIME" }, \
- { IOCTL_GET_TIME_INFO_HRT, "IOCTL_GET_TIME_INFO_HRT" }, \
- { IOCTL_GET_TIME_INFO_TSTAMP, "IOCTL_GET_TIME_INFO_TSTAMP" }, \
- { IOCTL_DEV_HAS_RAW_IRIG_DATA, "IOCTL_DEV_HAS_RAW_IRIG_DATA" }, \
- { IOCTL_GET_RAW_IRIG_DATA, "IOCTL_GET_RAW_IRIG_DATA" }, \
- { IOCTL_DEV_HAS_PTP_UNICAST, "IOCTL_DEV_HAS_PTP_UNICAST" }, \
- { IOCTL_PTP_UC_MASTER_CFG_LIMITS, "IOCTL_PTP_UC_MASTER_CFG_LIMITS" }, \
- { IOCTL_GET_ALL_PTP_UC_MASTER_INFO, "IOCTL_GET_ALL_PTP_UC_MASTER_INFO" }, \
- { IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX, "IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX" }, \
- { IOCTL_DEV_HAS_PZF, "IOCTL_DEV_HAS_PZF" }, \
- { IOCTL_DEV_HAS_CORR_INFO, "IOCTL_DEV_HAS_CORR_INFO" }, \
- { IOCTL_DEV_HAS_TR_DISTANCE, "IOCTL_DEV_HAS_TR_DISTANCE" }, \
- { IOCTL_GET_CORR_INFO, "IOCTL_GET_CORR_INFO" }, \
- { IOCTL_GET_TR_DISTANCE, "IOCTL_GET_TR_DISTANCE" }, \
- { IOCTL_SET_TR_DISTANCE, "IOCTL_SET_TR_DISTANCE" }, \
- { IOCTL_MBG_DBG_GET_PORT_ADDR, "IOCTL_MBG_DBG_GET_PORT_ADDR" }, \
- { IOCTL_MBG_DBG_SET_PORT_ADDR, "IOCTL_MBG_DBG_SET_PORT_ADDR" }, \
- { IOCTL_MBG_DBG_SET_BIT, "IOCTL_MBG_DBG_SET_BIT" }, \
- { IOCTL_MBG_DBG_CLR_BIT, "IOCTL_MBG_DBG_CLR_BIT" }, \
- { 0, NULL } \
+#define IOCTL_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_DRVR_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_DEV ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_STATUS_PORT ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_GENERIC_READ ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_GENERIC_WRITE ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_GENERIC_READ_GPS ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_GENERIC_WRITE_GPS ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_TIME ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_SYNC_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_TIME_SEC_CHANGE ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_HR_TIME ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_EVENT_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_SERIAL ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_SERIAL ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_TZCODE ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_TZCODE ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_GET_REF_OFFS ), \
+ _mbg_cn_table_entry( IOCTL_SET_REF_OFFS ), \
+ _mbg_cn_table_entry( IOCTL_GET_MBG_OPT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_MBG_OPT_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_IRIG_RX_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_IRIG_RX_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_CLR_UCAP_BUFF ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_UCAP_ENTRIES ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_UCAP_EVENT ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_SW_REV ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_BVAR_STAT ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_TIME ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_PORT_PARM ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_PORT_PARM ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ANT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_UCAP ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ENABLE_FLAGS ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_ENABLE_FLAGS ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_STAT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_CMD ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_IDENT ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_POS ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_POS_XYZ ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_POS_LLA ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ANT_CABLE_LEN ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_ANT_CABLE_LEN ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_RECEIVER_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ALL_STR_TYPE_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ALL_PORT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_PORT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCI_ASIC_VERSION ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_TIME_CYCLES ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_HR_TIME_CYCLES ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCPS_IRIG_TX_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_PCPS_IRIG_TX_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_GET_SYNTH ), \
+ _mbg_cn_table_entry( IOCTL_SET_SYNTH ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_GPS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_DCF ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_IRIG_RX ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_HR_TIME ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_CAB_LEN ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PCPS_TZDL ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_TZCODE ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_TZ ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_EVENT_TIME ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_RECEIVER_INFO ), \
+ _mbg_cn_table_entry( IOCTL_DEV_CAN_CLR_UCAP_BUFF ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_UCAP ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_IRIG_TX ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_SERIAL_HS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_SIGNAL ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_MOD ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_IRIG ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_REF_OFFS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_OPT_FLAGS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_GPS_DATA ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_SYNTH ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_GENERIC_IO ), \
+ _mbg_cn_table_entry( IOCTL_PCPS_GENERIC_IO ), \
+ _mbg_cn_table_entry( IOCTL_GET_SYNTH_STATE ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_ALL_POUT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_POUT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( IOCTL_GET_MAPPED_MEM_ADDR ), \
+ _mbg_cn_table_entry( IOCTL_UNMAP_MAPPED_MEM ), \
+ _mbg_cn_table_entry( IOCTL_GET_PCI_ASIC_FEATURES ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PCI_ASIC_FEATURES ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PCI_ASIC_VERSION ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_MSF ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_LWR ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_WWVB ), \
+ _mbg_cn_table_entry( IOCTL_GET_IRQ_STAT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_CYCLES_FREQUENCY ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_FAST_HR_TIMESTAMP ), \
+ _mbg_cn_table_entry( IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES ), \
+ _mbg_cn_table_entry( IOCTL_GET_FAST_HR_TIMESTAMP ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_GPS_TIME_SCALE ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_TIME_SCALE_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_TIME_SCALE_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_GPS_UTC_PARM ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPS_UTC_PARM ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPS_UTC_PARM ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_IRIG_CTRL_BITS ), \
+ _mbg_cn_table_entry( IOCTL_GET_IRIG_CTRL_BITS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_LAN_INTF ), \
+ _mbg_cn_table_entry( IOCTL_GET_LAN_IF_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_IP4_STATE ), \
+ _mbg_cn_table_entry( IOCTL_GET_IP4_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_SET_IP4_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_PTP ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PTP ), \
+ _mbg_cn_table_entry( IOCTL_GET_PTP_STATE ), \
+ _mbg_cn_table_entry( IOCTL_GET_PTP_CFG_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_PTP_CFG_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_IRIG_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_IRIG_TIME ), \
+ _mbg_cn_table_entry( IOCTL_GET_TIME_INFO_HRT ), \
+ _mbg_cn_table_entry( IOCTL_GET_TIME_INFO_TSTAMP ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_RAW_IRIG_DATA ), \
+ _mbg_cn_table_entry( IOCTL_GET_RAW_IRIG_DATA ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PTP_UNICAST ), \
+ _mbg_cn_table_entry( IOCTL_PTP_UC_MASTER_CFG_LIMITS ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_PTP_UC_MASTER_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_PZF ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_CORR_INFO ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_TR_DISTANCE ), \
+ _mbg_cn_table_entry( IOCTL_GET_CORR_INFO ), \
+ _mbg_cn_table_entry( IOCTL_GET_TR_DISTANCE ), \
+ _mbg_cn_table_entry( IOCTL_SET_TR_DISTANCE ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_DEBUG_STATUS ), \
+ _mbg_cn_table_entry( IOCTL_GET_DEBUG_STATUS ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_EVT_LOG ), \
+ _mbg_cn_table_entry( IOCTL_CLR_EVT_LOG ), \
+ _mbg_cn_table_entry( IOCTL_GET_NUM_EVT_LOG_ENTRIES ), \
+ _mbg_cn_table_entry( IOCTL_GET_FIRST_EVT_LOG_ENTRY ), \
+ _mbg_cn_table_entry( IOCTL_GET_NEXT_EVT_LOG_ENTRY ), \
+ _mbg_cn_table_entry( IOCTL_DEV_IS_GNSS ), \
+ _mbg_cn_table_entry( IOCTL_GET_GNSS_MODE_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GNSS_MODE_SETTINGS ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_GNSS_SAT_INFO ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_GPIO ), \
+ _mbg_cn_table_entry( IOCTL_GET_GPIO_CFG_LIMITS ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_GPIO_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_GPIO_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( IOCTL_DEV_HAS_XMR ), \
+ _mbg_cn_table_entry( IOCTL_GET_XMR_INSTANCES ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_XMR_INFO ), \
+ _mbg_cn_table_entry( IOCTL_SET_XMR_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_XMR_STATUS ), \
+ _mbg_cn_table_entry( IOCTL_GET_XMR_HOLDOVER_STATUS ), \
+ _mbg_cn_table_entry( IOCTL_GET_ALL_GPIO_STATUS ), \
+ _mbg_cn_table_entry( IOCTL_CHK_DEV_FEAT ), \
+ \
+ _mbg_cn_table_entry( IOCTL_MBG_DBG_GET_PORT_ADDR ), \
+ _mbg_cn_table_entry( IOCTL_MBG_DBG_SET_PORT_ADDR ), \
+ _mbg_cn_table_entry( IOCTL_MBG_DBG_SET_BIT ), \
+ _mbg_cn_table_entry( IOCTL_MBG_DBG_CLR_BIT ), \
+ _mbg_cn_table_end() \
}
@@ -665,7 +786,7 @@ typedef struct
* Implementation should be done in a way which introduces as low
* latency as possible when reading time stamps from a device.
*/
-enum
+enum MBG_REQ_PRIVL
{
MBG_REQ_PRIVL_NONE, //< e.g. read date/time/sync status
MBG_REQ_PRIVL_EXT_STATUS, //< e.g. read receiver position
@@ -736,6 +857,13 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_GET_IP4_STATE:
case IOCTL_GET_PTP_STATE:
case IOCTL_GET_CORR_INFO:
+ case IOCTL_GET_DEBUG_STATUS:
+ case IOCTL_GET_NUM_EVT_LOG_ENTRIES:
+ case IOCTL_GET_FIRST_EVT_LOG_ENTRY:
+ case IOCTL_GET_NEXT_EVT_LOG_ENTRY:
+ #if _MBG_SUPP_VAR_ACC_SIZE
+ case IOCTL_GET_ALL_GNSS_SAT_INFO:
+ #endif
return MBG_REQ_PRIVL_NONE;
// Commands returning device capabilities and features:
@@ -744,6 +872,7 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_DEV_IS_MSF:
case IOCTL_DEV_IS_WWVB:
case IOCTL_DEV_IS_LWR:
+ case IOCTL_DEV_IS_GNSS:
case IOCTL_DEV_IS_IRIG_RX:
case IOCTL_DEV_HAS_HR_TIME:
case IOCTL_DEV_HAS_CAB_LEN:
@@ -780,12 +909,18 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_DEV_HAS_PZF:
case IOCTL_DEV_HAS_CORR_INFO:
case IOCTL_DEV_HAS_TR_DISTANCE:
+ case IOCTL_DEV_HAS_DEBUG_STATUS:
+ case IOCTL_DEV_HAS_EVT_LOG:
+ case IOCTL_DEV_HAS_GPIO:
+ case IOCTL_DEV_HAS_XMR:
+ case IOCTL_CHK_DEV_FEAT:
return MBG_REQ_PRIVL_NONE;
// The next codes are somewhat special since they change something
// on the board but do not affect basic operation:
case IOCTL_PCPS_CLR_UCAP_BUFF:
case IOCTL_SET_PCPS_EVENT_TIME: // supported by some customized firmware only
+ case IOCTL_CLR_EVT_LOG:
return MBG_REQ_PRIVL_NONE;
// Status information which may not be available for everybody:
@@ -825,7 +960,15 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_GET_GPS_ALL_PORT_INFO:
case IOCTL_GET_GPS_ALL_POUT_INFO:
case IOCTL_GET_ALL_PTP_UC_MASTER_INFO:
+ case IOCTL_GET_ALL_GPIO_INFO:
+ case IOCTL_GET_ALL_GPIO_STATUS:
+ case IOCTL_GET_ALL_XMR_STATUS:
+ case IOCTL_GET_ALL_XMR_INFO:
#endif
+ case IOCTL_GET_GNSS_MODE_INFO:
+ case IOCTL_GET_GPIO_CFG_LIMITS:
+ case IOCTL_GET_XMR_INSTANCES:
+ case IOCTL_GET_XMR_HOLDOVER_STATUS:
return MBG_REQ_PRIVL_CFG_READ;
// Writing device configuration:
@@ -847,6 +990,8 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_SET_PTP_CFG_SETTINGS:
case IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX:
case IOCTL_SET_TR_DISTANCE:
+ case IOCTL_SET_GNSS_MODE_SETTINGS:
+ case IOCTL_SET_GPIO_SETTINGS_IDX:
return MBG_REQ_PRIVL_CFG_WRITE;
// Operations which may severely affect system operation:
@@ -857,6 +1002,7 @@ int ioctl_get_required_privilege( ulong ioctl_code )
case IOCTL_SET_GPS_TIME_SCALE_SETTINGS:
case IOCTL_SET_GPS_UTC_PARM:
case IOCTL_SET_GPS_CMD:
+ case IOCTL_SET_XMR_SETTINGS_IDX:
// generic write operations can do anything
case IOCTL_PCPS_GENERIC_WRITE:
case IOCTL_PCPS_GENERIC_WRITE_GPS:
@@ -887,18 +1033,6 @@ int ioctl_get_required_privilege( ulong ioctl_code )
-/* End of header body */
-
-#undef _ext
-#undef _DO_INIT
-
-
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
@@ -913,4 +1047,9 @@ extern "C" {
#endif
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
#endif /* _MBGIOCTL_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgklist.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgklist.h
new file mode 100755
index 0000000..01a3f21
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgklist.h
@@ -0,0 +1,318 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgklist.h 1.3 2017/07/05 09:52:39 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Userspace implementation of Linux Kernel's list.h
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgklist.h $
+ * Revision 1.3 2017/07/05 09:52:39 martin
+ * Safe loop macros added by philipp.
+ * Check if 'typeof' is supported based on the type of compiler.
+ * Reformatted code to conform to standard header file format.
+ * Updated function prototypes.
+ * Revision 1.2 2015/10/06 07:08:45 philipp
+ * Added functions to loop containers of list entries
+ * Revision 1.1 2015/09/09 10:42:27 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBGKLIST_H
+#define _MBGKLIST_H
+
+/* Other headers to be included */
+
+#include <mbg_cof.h>
+
+
+#ifdef _MBGKLIST
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MBG_KLIST_INIT(name) { &(name), &(name) }
+
+#define MBG_KLIST_DECLARE(name) \
+ struct mbg_klist_head name = MBG_KLIST_INIT(name)
+
+#define mbg_klist_for_each(head, pos) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define mbg_klist_for_each_safe(head, pos, n) \
+ for (pos = (head)->next, n = (pos)->next; \
+ pos != (head); \
+ pos = n, n = pos->next)
+
+#define mbg_klist_for_each_rev(head, pos) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+#define mbg_klist_for_each_rev_safe(head, pos, n) \
+ for (pos = (head)->prev, n = (pos)->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+#define mbg_klist_entry(ptr, type, member) \
+ mbg_container_of(ptr, type, member)
+
+#define mbg_klist_first_entry(ptr, type, member) \
+ mbg_klist_entry((ptr)->next, type, member)
+
+#define mbg_klist_last_entry(ptr, type, member) \
+ mbg_klist_entry((ptr)->prev, type, member)
+
+
+
+#if defined( __GNUC__ ) || defined( __clang__ ) // "typeof" supported
+
+#define mbg_klist_next_entry(pos, member) \
+ mbg_klist_entry((pos)->member.next, typeof(*pos), member)
+
+#define mbg_klist_prev_entry(pos, member) \
+ mbg_klist_entry((pos)->member.prev, typeof(*pos), member)
+
+#define mbg_klist_for_each_entry(head, pos, member) \
+ for (pos = mbg_klist_first_entry(head, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = mbg_klist_next_entry(pos, member))
+
+#define mbg_klist_for_each_entry_rev(head, pos, member) \
+ for (pos = mbg_klist_last_entry(head, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = mbg_klist_prev_entry(pos, member))
+
+#define mbg_klist_for_each_entry_safe(head, pos, n, member) \
+ for (pos = mbg_klist_first_entry(head, typeof(*pos), member), \
+ n = mbg_klist_next_entry(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = mbg_klist_next_entry(pos, member))
+
+#define mbg_klist_for_each_entry_rev_safe(head, pos, n, member) \
+ for (pos = mbg_klist_last_entry(head, typeof(*pos), member), \
+ n = mbg_klist_prev_entry(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = mbg_klist_prev_entry(pos, member))
+
+#endif
+
+
+
+struct mbg_klist_head
+{
+ struct mbg_klist_head *prev;
+ struct mbg_klist_head *next;
+};
+
+
+
+static __mbg_inline
+void mbg_klist_init( struct mbg_klist_head *head )
+{
+ head->next = head;
+ head->prev = head;
+}
+
+
+static __mbg_inline
+void __mbg_klist_add_item( struct mbg_klist_head *item, struct mbg_klist_head *prev, struct mbg_klist_head *next )
+{
+ next->prev = item;
+ item->next = next;
+ item->prev = prev;
+ prev->next = item;
+}
+
+
+static __mbg_inline
+void mbg_klist_prepend_item( struct mbg_klist_head *head, struct mbg_klist_head *item )
+{
+ __mbg_klist_add_item( item, head, head->next );
+}
+
+
+static __mbg_inline
+void mbg_klist_append_item( struct mbg_klist_head *head, struct mbg_klist_head *item )
+{
+ __mbg_klist_add_item( item, head->prev, head );
+}
+
+
+static __mbg_inline
+void __mbg_klist_delete_item( struct mbg_klist_head *prev, struct mbg_klist_head *next )
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+
+static __mbg_inline
+void mbg_klist_delete_item( struct mbg_klist_head *item )
+{
+ __mbg_klist_delete_item( item->prev, item->next );
+}
+
+
+static __mbg_inline
+void mbg_klist_delete_item_init( struct mbg_klist_head *item )
+{
+ __mbg_klist_delete_item( item->prev, item->next );
+ mbg_klist_init( item );
+}
+
+
+static __mbg_inline
+void mbg_klist_replace_item( struct mbg_klist_head *old, struct mbg_klist_head *item )
+{
+ item->next = old->next;
+ item->next->prev = item;
+ item->prev = old->prev;
+ item->prev->next = item;
+}
+
+
+static __mbg_inline
+void mbg_klist_replace_item_init( struct mbg_klist_head *old, struct mbg_klist_head *item )
+{
+ mbg_klist_replace_item( old, item );
+ mbg_klist_init( item );
+}
+
+
+static __mbg_inline
+void mbg_klist_move_prepend_item( struct mbg_klist_head *head, struct mbg_klist_head *item )
+{
+ mbg_klist_delete_item( item );
+ mbg_klist_prepend_item( head, item );
+}
+
+
+static __mbg_inline
+void mbg_klist_move_append_item( struct mbg_klist_head *head, struct mbg_klist_head *item )
+{
+ mbg_klist_delete_item( item );
+ mbg_klist_append_item( head, item );
+}
+
+
+static __mbg_inline
+int mbg_klist_is_first( const struct mbg_klist_head *head, const struct mbg_klist_head *item )
+{
+ return ( ( item->prev == head ) ? 1 : 0 );
+}
+
+
+static __mbg_inline
+int mbg_klist_is_last( const struct mbg_klist_head *head, const struct mbg_klist_head *item )
+{
+ return ( ( item->next == head ) ? 1 : 0 );
+}
+
+
+static __mbg_inline
+int mbg_klist_is_empty( const struct mbg_klist_head *head )
+{
+ return ( ( head->next == head ) ? 1 : 0 );
+}
+
+
+static __mbg_inline
+void __mbg_klist_add_list( const struct mbg_klist_head *list, struct mbg_klist_head *prev, struct mbg_klist_head *next )
+{
+ struct mbg_klist_head *first = list->next;
+ struct mbg_klist_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+
+static __mbg_inline
+void mbg_klist_prepend_list( struct mbg_klist_head *head, const struct mbg_klist_head *list )
+{
+ if ( !mbg_klist_is_empty( list ) )
+ __mbg_klist_add_list( list, head, head->next );
+}
+
+
+static __mbg_inline
+void mbg_klist_append_list( struct mbg_klist_head *head, const struct mbg_klist_head *list )
+{
+ if ( !mbg_klist_is_empty( list ) )
+ __mbg_klist_add_list( list, head->prev, head );
+}
+
+
+static __mbg_inline
+void mbg_klist_prepend_list_init( struct mbg_klist_head *head, struct mbg_klist_head *list )
+{
+ if ( !mbg_klist_is_empty( list ) )
+ {
+ __mbg_klist_add_list( list, head, head->next );
+ mbg_klist_init( list );
+ }
+}
+
+
+static __mbg_inline
+void mbg_klist_append_list_init( struct mbg_klist_head *head, struct mbg_klist_head *list )
+{
+ if ( !mbg_klist_is_empty( list ) )
+ {
+ __mbg_klist_add_list( list, head->prev, head );
+ mbg_klist_init( list );
+ }
+}
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Sort a list
+ *
+ * @param[in] priv Private data, opaque to ::mbg_klist_sort, passed to @p cmp
+ * @param[in] head The list to sort
+ * @param[in] cmp The elements comparison function
+ *
+ * This function implements "merge sort", which has O(nlog(n))
+ * complexity.
+ *
+ * The comparison function @p cmp must return a negative value if a
+ * should sort before b, and a positive value if a should sort after
+ * b. If a and b are equivalent, and their original relative
+ * ordering is to be preserved, cmp must return 0.
+ */
+ void mbg_klist_sort( void *priv, struct mbg_klist_head *head, int (*cmp)( void *priv, struct mbg_klist_head *a, struct mbg_klist_head *b ) ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _MBGKLIST_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.c b/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.c
index 3285b73..d6990c1 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgmktm.c 1.1 2006/08/22 08:57:15 martin REL_M $
+ * $Id: mbgmktm.c 1.2 2017/07/05 10:00:29 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,11 @@
*
* -----------------------------------------------------------------------
* $Log: mbgmktm.c $
+ * Revision 1.2 2017/07/05 10:00:29 martin
+ * Let mbg_mktime() fail if year is out of a range which depends on
+ * the size of the 'time_t' type provided by the build environment.
+ * Allow 0 as valid return value for mbg_mktime().
+ * Added some doxygen comments.
* Revision 1.1 2006/08/22 08:57:15 martin
* Former function totalsec() moved here from pcpsmktm.c.
*
@@ -19,7 +24,7 @@
#include <mbgmktm.h>
#undef _MBGMKTM
-#include <sys/types.h>
+#include <assert.h>
static const char Days[12] =
@@ -33,41 +38,56 @@ static int YDays[12] =
};
-/*--------------------------------------------------------------
- * Name: mbg_mktime()
- *
- * Purpose: This function works like the standard mktime()
- * function but does not account for a timezone
- * setting configured for the standard C library.
- * Also, it does not take a structure but a set
- * of variables which makes it more versatile.
- * The accepted variables are in the same ranges
- * as the struct tm members used by mktime().
+
+/*HDR*/
+/**
+ * @brief Compute a linear time_t value from broken down date and time
*
- * Input: int year year - 1900
- * int month months since January, 0..11
- * int day days after 1st, 0..30
- * int hour 0..23
- * int min 0..59
- * int sec 0..59, 60 if leap second
+ * This function works like the standard mktime() function but does not
+ * account for a timezone setting configured for the standard C library.
+ * Also, it does not take a structure but a set of variables which makes
+ * it more versatile. The accepted variables are in the same ranges
+ * as the struct tm members used by mktime().
*
- * Output: --
+ * @param[in] year year number - 1900
+ * @param[in] month months since January, 0..11
+ * @param[in] day days after 1st, 0..30
+ * @param[in] hour 0..23
+ * @param[in] min 0..59
+ * @param[in] sec 0..59, 60 if leap second
*
- * Ret value: seconds since 1970 (Unix time_t format)
- * or -1 if range overflow
- *-------------------------------------------------------------*/
-
-/*HDR*/
-long mbg_mktime( int year, int month, int day,
- int hour, int min, int sec )
+ * @return seconds since 1970-01-01 (Unix time_t format) or ((time_t) -1) if range overflow
+ */
+time_t mbg_mktime( int year, int month, int day,
+ int hour, int min, int sec )
{
int leaps;
long days;
- long secs;
+ time_t secs;
+ // time_t should be at least 4 bytes
+ assert( sizeof( time_t ) >= 4 );
- if ( year < 70 || year > 138 )
- return ( -1 );
+ if ( sizeof( time_t ) == 4 )
+ {
+ // 32 bit *signed* time_t will roll over after 2038-01-19 03:14:07
+ // when the number of seconds reaches 0x7FFFFFFF, so we don't try
+ // conversions for 2038 or later, though 32 bit *unsigned* time_t
+ // may still work after year 2100.
+ if ( year < 70 || year > 137 )
+ goto fail;
+ }
+ else
+ if ( sizeof( time_t ) == 8 )
+ {
+ // 64 bit time_t will work for million years. However, it's not
+ // clear what happes for dates before 1970-01-01T00:00:00 if time_t
+ // is *unsigned*.
+ if ( year < 70 )
+ goto fail;
+ }
+ else
+ goto fail;
min += sec / 60;
sec %= 60; /* Seconds are normalized */
@@ -111,7 +131,14 @@ long mbg_mktime( int year, int month, int day,
secs = days * 86400L + hour * 3600L + min * 60L + sec;
- return( secs > 0 ? secs : -1 );
+ if ( secs < 0 ) // == 0 is valid for 1970-01-01 00:00:00
+ goto fail;
+
+ return secs;
+
+
+fail:
+ return (time_t) -1;
} // mbg_mktime
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.h
index 2aada2a..d7a5473 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgmktm.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgmktm.h 1.1 2006/08/22 08:57:15 martin REL_M $
+ * $Id: mbgmktm.h 1.2 2017/07/05 10:02:42 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: mbgmktm.h $
+ * Revision 1.2 2017/07/05 10:02:42 martin
+ * Include time.h.
+ * Updated function prototypes.
* Revision 1.1 2006/08/22 08:57:15 martin
* Former function totalsec() moved here from pcpsmktm.c.
*
@@ -21,6 +24,9 @@
/* Other headers to be included */
+#include <time.h>
+
+
#ifdef _MBGMKTM
#define _ext
#else
@@ -30,9 +36,6 @@
/* Start of header body */
-
-/* function prototypes: */
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -42,7 +45,26 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
-long mbg_mktime( int year, int month, int day, int hour, int min, int sec ) ;
+ /**
+ * @brief Compute a linear time_t value from broken down date and time
+ *
+ * This function works like the standard mktime() function but does not
+ * account for a timezone setting configured for the standard C library.
+ * Also, it does not take a structure but a set of variables which makes
+ * it more versatile. The accepted variables are in the same ranges
+ * as the struct tm members used by mktime().
+ *
+ * @param[in] year year number - 1900
+ * @param[in] month months since January, 0..11
+ * @param[in] day days after 1st, 0..30
+ * @param[in] hour 0..23
+ * @param[in] min 0..59
+ * @param[in] sec 0..59, 60 if leap second
+ *
+ * @return seconds since 1970-01-01 (Unix time_t format) or ((time_t) -1) if range overflow
+ */
+ time_t mbg_mktime( int year, int month, int day, int hour, int min, int sec ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgmutex.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgmutex.h
index 6ef6f2a..50d7938 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgmutex.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgmutex.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgmutex.h 1.1.1.6 2011/05/31 14:19:55 martin TRASH $
+ * $Id: mbgmutex.h 1.4 2017/07/05 10:05:02 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,17 +11,16 @@
*
* -----------------------------------------------------------------------
* $Log: mbgmutex.h $
- * Revision 1.1.1.6 2011/05/31 14:19:55 martin
- * Revision 1.1.1.5 2011/05/16 17:39:41 martin
+ * Revision 1.4 2017/07/05 10:05:02 martin
+ * windows.h is now included by mbg_tgt.h.
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Revision 1.3 2013/04/11 13:46:58 martin
+ * Use non-specific spinlock function under Windows.
+ * Revision 1.2 2012/03/08 12:19:01Z martin
+ * Fixes for Linux kernel and FreeBSD.
+ * Fixed build under DOS and QNX usinc dummy defines.
* Don't define macros for semaphore destroy functions
* if not required/supported on the target OS.
- * Revision 1.1.1.4 2011/05/06 09:11:16Z martin
- * Fix for DOS.
- * Revision 1.1.1.3 2011/05/04 09:24:18Z martin
- * Revision 1.1.1.2 2011/05/04 08:57:23 martin
- * Fix for FreeBSD.
- * Revision 1.1.1.1 2011/05/03 15:46:06 martin
- * Fix for Linux kernel.
* Revision 1.1 2011/04/15 12:26:59 martin
* Initial revision.
*
@@ -46,6 +45,10 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined( MBG_TGT_KERNEL ) // definitions used in kernel space
#if defined( MBG_TGT_WIN32 ) // Windows kernel space
@@ -53,8 +56,8 @@
typedef KSPIN_LOCK MBG_SPINLOCK;
#define _mbg_spin_lock_init( _spl ) KeInitializeSpinLock( _spl )
// _mbg_spin_lock_destroy is not supported
- #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLockAtDpcLevel( _spl )
- #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLockFromDpcLevel( _spl )
+ #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLock( _spl, &OldIrql )
+ #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLock( _spl, OldIrql )
#define _MBG_SPINLOCK_DEFINED 1
@@ -147,8 +150,6 @@
#if defined( MBG_TGT_WIN32 ) // Windows user space
- #include <windows.h>
-
// definitions used with mutexes
typedef HANDLE MBG_MUTEX;
#define _mbg_mutex_init( _pm ) *(_pm) = CreateMutex( NULL, FALSE, NULL )
@@ -167,7 +168,7 @@
#define _MBG_CRIT_SECT_DEFINED 1
- #elif defined( MBG_TGT_UNIX ) // Unix user space use pthread library
+ #elif defined( MBG_TGT_POSIX ) // Unix user space use pthread library
#include <pthread.h>
@@ -185,7 +186,7 @@
// For critical sections use defaults specified below
- #elif defined( MBG_TGT_DOS )
+ #elif defined( MBG_TGT_DOS ) || defined( MBG_TGT_QNX )
typedef int MBG_MUTEX; // just a dummy declaration
@@ -237,13 +238,6 @@
#endif
-
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgpccyc.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgpccyc.h
index 7a47edf..cc9854a 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgpccyc.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgpccyc.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgpccyc.h 1.1.1.4 2011/07/20 15:58:53 martin TRASH $
+ * $Id: mbgpccyc.h 1.7 2017/05/10 15:21:41 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,12 +10,21 @@
*
* -----------------------------------------------------------------------
* $Log: mbgpccyc.h $
- * Revision 1.1.1.4 2011/07/20 15:58:53 martin
- * Support cycles on IA64 only in kernel space.
- * Revision 1.1.1.3 2011/07/13 09:44:49 martin
- * Moved IA64 includes from pcpsdev.h to mbgpccyc.h.
- * Revision 1.1.1.2 2011/07/06 13:23:36 martin
- * Revision 1.1.1.1 2011/07/05 12:25:08 martin
+ * Revision 1.7 2017/05/10 15:21:41 martin
+ * Tiny cleanup.
+ * Revision 1.6 2016/08/09 16:01:10 martin
+ * Syntax fix.
+ * Revision 1.5 2016/02/17 16:04:18 martin
+ * Include header file missing for FreeBSD.
+ * Revision 1.4 2015/10/19 09:16:45 martin
+ * Fixed some spelling.
+ * Revision 1.3 2014/10/08 13:10:14 martin
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Revision 1.2 2012/03/12 13:45:57 martin
+ * Added cycles support for Linux/IA64, FreeBSD and NetBSD
+ * in kernel space.
+ * Use get_cycles() in Linux kernel mode if no special cycles support
+ * is provided for the given hardware platform.
* Revision 1.1 2011/06/23 15:36:07 martin
* Initial revision.
*
@@ -40,6 +49,7 @@
#if defined( MBG_TGT_FREEBSD )
#if defined( MBG_TGT_KERNEL )
#if defined( MBG_ARCH_X86 )
+ #include <sys/time.h>
#include <machine/clock.h> /* for symbol 'tsc_freq' */
#endif
#endif
@@ -48,7 +58,6 @@
#if defined( MBG_TGT_LINUX )
#if defined( MBG_ARCH_IA64 ) && defined( MBG_TGT_KERNEL )
#include <asm/ia64regs.h>
- #include <asm/intel_intrin.h>
#endif
#endif
@@ -63,13 +72,17 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @brief Generic types to hold PC cycle counter values.
*
* The cycle counter value is usually derived from the PC CPU's TSC or some other
* timer hardware on the mainboard.
*/
-#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_UNIX )
+#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_POSIX )
typedef int64_t MBG_PC_CYCLES;
typedef uint64_t MBG_PC_CYCLES_FREQUENCY;
@@ -106,7 +119,7 @@
// 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 "=A" expression should implicitly 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.
@@ -118,14 +131,14 @@
// 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
+ // A possible workaround could be to mark edx explicitly 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.
+ // implicitly (by "=A") known to be clobbered is also listed
+ // explicitly to be clobbered.
//
// So the code below is a workaround which tells the compiler
- // implicitely that the eax ("=a") and edx ("=d") registers
+ // implicitly that the eax ("=a") and edx ("=d") registers
// are being used and thus clobbered.
union
@@ -153,6 +166,8 @@
static __mbg_inline
void mbg_get_pc_cycles( MBG_PC_CYCLES *p )
{
+#if !defined( OMIT_PC_CYCLES_SUPPORT )
+
#if defined( MBG_TGT_WIN32 )
#if defined( MBG_TGT_KERNEL ) // kernel space
@@ -168,11 +183,6 @@ void mbg_get_pc_cycles( MBG_PC_CYCLES *p )
*p = mbg_rdtscll();
#define MBG_PC_CYCLES_SUPPORTED 1
- #elif defined( MBG_TGT_LINUX ) && defined( MBG_ARCH_SPARC ) && defined( MBG_TGT_KERNEL )
-
- *p = get_cycles();
- #define MBG_PC_CYCLES_SUPPORTED 1
-
#elif defined( MBG_TGT_LINUX ) && defined( MBG_ARCH_IA64 ) && defined( MBG_TGT_KERNEL )
unsigned long result = ia64_getreg( _IA64_REG_AR_ITC );
@@ -189,21 +199,32 @@ void mbg_get_pc_cycles( MBG_PC_CYCLES *p )
#define MBG_PC_CYCLES_SUPPORTED 1
+ #elif defined( MBG_TGT_LINUX ) && defined( MBG_TGT_KERNEL )
+
+ *p = get_cycles();
+ #define MBG_PC_CYCLES_SUPPORTED 1
+
#elif defined( MBG_TGT_FREEBSD ) && defined( MBG_ARCH_X86 )
*p = mbg_rdtscll();
#define MBG_PC_CYCLES_SUPPORTED 1
- #elif defined( MBG_TGT_NETBSD ) && defined ( MBG_TGT_KERNEL )
+ #elif defined( MBG_TGT_NETBSD ) && defined( MBG_TGT_KERNEL )
*p = cpu_counter(); //##++ or cpu_counter_serializing()
#define MBG_PC_CYCLES_SUPPORTED 1
- #else
+ #endif
+
+#endif
+
+
+ #if !defined( MBG_PC_CYCLES_SUPPORTED )
*p = 0;
+ #define MBG_PC_CYCLES_SUPPORTED 0
#endif
@@ -259,7 +280,7 @@ void mbg_get_pc_cycles_frequency( MBG_PC_CYCLES_FREQUENCY *p )
static __mbg_inline
MBG_PC_CYCLES mbg_delta_pc_cycles( const MBG_PC_CYCLES *p1, const MBG_PC_CYCLES *p2 )
{
-#if 0 && !defined( MBG_PC_CYCLES_SUPPORTED ) //##+++++++++++++++++
+#if 0 && !MBG_PC_CYCLES_SUPPORTED
// Cycle counts not supported on this target platform.
// Under SPARC this may even result in bus errors
// due to alignment of the underlying data structures.
@@ -272,12 +293,6 @@ MBG_PC_CYCLES mbg_delta_pc_cycles( const MBG_PC_CYCLES *p1, const MBG_PC_CYCLES
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgsystm.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgsystm.h
new file mode 100755
index 0000000..e481943
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgsystm.h
@@ -0,0 +1,494 @@
+
+/**************************************************************************
+ *
+ * $Id: mbgsystm.h 1.3 2017/07/26 14:26:17 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Generic functions and definitions to deal with the computer's
+ * system time, and prototypes for mbgsystm.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbgsystm.h $
+ * Revision 1.3 2017/07/26 14:26:17 martin
+ * Fixed build for NetBSD.
+ * Revision 1.2 2017/07/04 12:26:57 martin
+ * More detailed control of inclusion of other headers.
+ * Made mbg_delta_sys_time_ms() as inline function here.
+ * Updated function prototypes.
+ * Cleanup.
+ * Revision 1.1 2015/09/15 13:21:00Z martin
+ * Initial revision.
+ * Moved existing code from different modules here.
+ *
+ **************************************************************************/
+
+#ifndef _MBGSYSTM_H
+#define _MBGSYSTM_H
+
+
+/* Other headers to be included */
+
+#include <mbg_tgt.h>
+#include <words.h>
+
+#if defined( MBG_TGT_POSIX )
+
+ #if defined( MBG_TGT_KERNEL )
+
+ #if defined( MBG_TGT_LINUX )
+
+ #define LINUX_KERNEL_HAS_MSLEEP ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 16 ) )
+ #define LINUX_KERNEL_HAS_GETNSTIMEOFDAY ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 22 ) )
+ #define LINUX_KERNEL_HAS_KTIME_H ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 16 ) )
+
+ #if !LINUX_KERNEL_HAS_MSLEEP
+ #include <linux/wait.h>
+ #include <linux/sched.h>
+ #endif
+
+ // We need the prototype for getnstimeofday(). In newer kernels
+ // (e.g. 4.x) this is available via linux/ktime.h, which in turn
+ // includes linux/timekeeping.h, which declares the prototype.
+ #if LINUX_KERNEL_HAS_KTIME_H
+ #include <linux/ktime.h>
+ #endif
+
+ // In older kernel versions the prototype for getnstimeofday()
+ // is declared in linux/time.h, so we include that one anyway.
+ #include <linux/time.h>
+
+ #include <linux/delay.h>
+ #include <linux/jiffies.h>
+
+ #elif defined( MBG_TGT_BSD )
+
+ #if defined( MBG_TGT_FREEBSD )
+ #include <sys/libkern.h>
+ #endif
+
+ #if defined( MBG_TGT_NETBSD )
+ #include <sys/param.h> // mstohz
+ #include <sys/kernel.h> // hz
+ #endif
+
+ #include <sys/time.h>
+
+ #endif
+
+ #else // POSIX user space
+
+ #include <time.h>
+
+ #if defined( MBG_TGT_LINUX )
+ #include <sys/sysinfo.h>
+ #endif
+
+ #endif
+
+#elif defined( MBG_TGT_WIN32 )
+
+ #if defined( MBG_TGT_KERNEL )
+ #include <mbg_w32.h>
+ #endif
+
+ #include <mbgtime.h>
+
+#elif defined( MBG_TGT_DOS )
+
+ #include <dos.h>
+
+#endif
+
+
+#ifdef _MBGSYSTM
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ Define generic types to hold PC cycle counter values and system timestamps.
+ The generic types are defined using native types used by the target operating
+ systems.
+
+ The cycle counter value is usually derived from the PC CPU's TSC or some other
+ timer hardware on the mainboard.
+ */
+#if defined( MBG_TGT_POSIX )
+
+ typedef NANO_TIME_64 MBG_SYS_TIME;
+ typedef int64_t MBG_SYS_UPTIME; // [s]
+
+#elif defined( MBG_TGT_WIN32 )
+
+ typedef LARGE_INTEGER MBG_SYS_TIME;
+ typedef int64_t MBG_SYS_UPTIME; // [s]
+
+#elif defined( MBG_TGT_OS2 )
+
+ typedef uint32_t MBG_SYS_TIME; //## dummy
+ typedef long MBG_SYS_UPTIME; //## dummy
+
+#elif defined( MBG_TGT_DOS )
+
+ typedef uint32_t MBG_SYS_TIME; //## dummy
+ typedef long MBG_SYS_UPTIME; //## dummy
+
+#else // other target OSs which access the hardware directly
+
+ typedef uint32_t MBG_SYS_TIME; //## dummy
+ typedef long MBG_SYS_UPTIME; //## dummy
+
+#endif
+
+//### TODO
+// MBG_SYS_TIME is always read in native machine endianess,
+// so no need to convert endianess.
+#define _mbg_swab_mbg_sys_time( _p ) \
+ _nop_macro_fnc()
+
+
+
+static __mbg_inline
+void mbg_get_sys_time( MBG_SYS_TIME *p )
+{
+ #if defined( MBG_TGT_POSIX )
+
+ #if defined( MBG_TGT_KERNEL ) // kernel space functions even differ for POSIX systems
+
+ #if defined( MBG_TGT_LINUX ) // Linux kernel space
+
+ #if ( LINUX_KERNEL_HAS_GETNSTIMEOFDAY )
+ {
+ // getnstimeofday() supported
+ struct timespec ts;
+
+ getnstimeofday( &ts );
+
+ p->secs = ts.tv_sec;
+ p->nano_secs = ts.tv_nsec;
+ }
+ #else
+ {
+ // getnstimeofday() *not* supported
+ struct timeval tv;
+
+ do_gettimeofday( &tv );
+
+ p->secs = tv.tv_sec;
+ p->nano_secs = tv.tv_usec * 1000;
+ }
+ #endif
+
+ #elif defined( MBG_TGT_BSD ) // BSD kernel space
+ {
+ struct timespec ts;
+
+ nanotime( &ts );
+
+ p->secs = ts.tv_sec;
+ p->nano_secs = ts.tv_nsec;
+ }
+ #endif
+
+ #else // POSIX user space
+ {
+ struct timespec ts;
+
+ #if defined( CLOCK_REALTIME_PRECISE ) // at least available in FreeBSD
+ clock_gettime( CLOCK_REALTIME_PRECISE, &ts );
+ #else
+ clock_gettime( CLOCK_REALTIME, &ts );
+ #endif
+
+ p->secs = ts.tv_sec;
+ p->nano_secs = ts.tv_nsec;
+ }
+ #endif
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #if defined( MBG_TGT_KERNEL ) // Windows kernel space
+ #if defined( MBG_TGT_WIN32_PNP ) && !defined( MBG_TGT_WIN32_PNP_X64 )
+ extern KE_QUERY_SYSTEM_TIME_FNC ke_query_system_time_fnc;
+ ke_query_system_time_fnc( p );
+ #else
+ KeQuerySystemTime( p );
+ #endif
+ #else // Windows user space
+ {
+ FILETIME ft;
+ GetSystemTimeAsFileTime( &ft );
+ p->LowPart = ft.dwLowDateTime;
+ p->HighPart = ft.dwHighDateTime;
+ }
+ #endif
+
+ #else
+
+ *p = 0; // dummy
+
+ #endif
+
+} // mbg_get_sys_time
+
+
+
+static __mbg_inline
+void mbg_get_sys_uptime( MBG_SYS_UPTIME *p )
+{
+ #if defined( MBG_TGT_WIN32 )
+
+ #if defined( MBG_TGT_KERNEL ) // kernel space
+
+ ULONGLONG time_increment = KeQueryTimeIncrement();
+ LARGE_INTEGER tick_count;
+
+ KeQueryTickCount( &tick_count );
+
+ // multiplication by time_increment yields HNS units,
+ // but we need seconds
+ *p = ( tick_count.QuadPart * time_increment ) / HNS_PER_SEC;
+
+ #else // user space
+
+ DWORD tickCount;
+ DWORD timeAdjustment;
+ DWORD timeIncrement;
+ BOOL timeAdjustmentDisabled;
+
+ if ( !GetSystemTimeAdjustment( &timeAdjustment, &timeIncrement, &timeAdjustmentDisabled ) )
+ *p = -1; // failed
+
+ // ATTENTION: This is compatible with older Windows versions, but
+ // the returned tick count wraps around to zero after 49.7 days.
+ // A new GetTickCount64() call is available under Windows Vista and newer,
+ // but the function call had to be imported dynamically since otherwise
+ // programs refused to start under pre-Vista versions due to undefined DLL symbol.
+ tickCount = GetTickCount();
+
+ *p = ( ( (MBG_SYS_UPTIME) tickCount ) * timeIncrement ) / HNS_PER_SEC;
+
+ #endif
+
+ #elif defined( MBG_TGT_LINUX )
+
+ #if defined( MBG_TGT_KERNEL )
+ // getrawmonotonic() can possibly be used for this in newer kernels
+ {
+ // Using a simple 64 bit division may result in a linker error
+ // in kernel mode due to a missing symbol __udivdi3, so we use
+ // a specific inline function do_div().
+ // Also, the jiffies counter is not set to 0 at startup but to
+ // a defined initialization value we need to account for.
+ uint64_t tmp = get_jiffies_64() - INITIAL_JIFFIES;
+ do_div( tmp, HZ );
+ *p = tmp;
+ }
+ #else
+ {
+ struct sysinfo si;
+ int rc = sysinfo( &si );
+ *p = ( rc == 0 ) ? si.uptime : -1;
+ }
+ #endif
+
+ #elif defined( MBG_TGT_BSD )
+
+ #if defined( MBG_TGT_KERNEL )
+ {
+ struct timespec ts;
+ #if 0 //##+++++++
+ {
+ struct bintime bt;
+
+ binuptime( &bt );
+ #if defined( DEBUG )
+ printf( "binuptime: %lli.%09lli\n",
+ (long long) bt.sec,
+ (long long) bt.frac );
+ #endif
+ }
+ #endif
+
+ nanouptime( &ts );
+ #if defined( DEBUG )
+ printf( "nanouptime: %lli.%09lli\n",
+ (long long) ts.tv_sec,
+ (long long) ts.tv_nsec );
+ #endif
+ *p = ts.tv_sec;
+ }
+ #elif defined( MBG_TGT_FREEBSD )
+ {
+ struct timespec ts;
+ // CLOCK_UPTIME_FAST is specific to FreeBSD
+ int rc = clock_gettime( CLOCK_UPTIME_FAST, &ts );
+ *p = ( rc == 0 ) ? ts.tv_sec : -1;
+ }
+ #else // MBG_TGT_NETBSD, ...
+
+ *p = -1; //##++ needs to be implemented
+
+ #endif
+
+ #else
+
+ *p = -1; // not supported
+
+ #endif
+
+} // mbg_get_sys_uptime
+
+
+
+/**
+ * @brief Compute delta between two ::MBG_SYS_TIME times, in milliseconds
+ *
+ * @param[in] t2 the time to be subtracted from
+ * @param[in] t1 The time to be subtracted
+ *
+ * @return The time difference in [milliseconds]
+ */
+static __mbg_inline
+long mbg_delta_sys_time_ms( const MBG_SYS_TIME *t2, const MBG_SYS_TIME *t1 )
+{
+ #if defined( MBG_TGT_POSIX )
+ long dt = ( t2->secs - t1->secs ) * 1000;
+ #if defined ( MBG_TGT_LINUX ) && defined( MBG_TGT_KERNEL )
+ int64_t tmp64 = t2->nano_secs - t1->nano_secs;
+ do_div( tmp64, 1000000 );
+ dt += tmp64;
+ #else
+ dt += ( t2->nano_secs - t1->nano_secs ) / 1000000;
+ #endif
+ return dt;
+ #elif defined( MBG_TGT_WIN32 )
+ return (long) ( ( t2->QuadPart - t1->QuadPart ) / HNS_PER_MS );
+ #else
+ return 0;
+ #endif
+
+} // mbg_delta_sys_time_ms
+
+
+
+static __mbg_inline
+void mbg_sleep_sec( long sec )
+{
+ #if defined( MBG_TGT_POSIX )
+
+ #if defined( MBG_TGT_KERNEL ) // kernel space functions even differ for POSIX systems
+
+ #if defined( MBG_TGT_LINUX ) // Linux kernel space
+
+ // msleep is not defined in older kernels, so we use this
+ // only if it is surely supported.
+ #if LINUX_KERNEL_HAS_MSLEEP
+ msleep( sec * 1000 );
+ #else
+ {
+ DECLARE_WAIT_QUEUE_HEAD( tmp_wait );
+ wait_event_interruptible_timeout( tmp_wait, 0, sec * HZ + 1 );
+ }
+ #endif
+
+ #elif defined( MBG_TGT_FREEBSD )
+
+ struct timeval tv = { 0 };
+ int ticks;
+ tv.tv_sec = sec;
+ ticks = tvtohz( &tv );
+
+ #if defined( DEBUG )
+ printf( "pause: %lli.%06lli (%i ticks)\n",
+ (long long) tv.tv_sec,
+ (long long) tv.tv_usec,
+ ticks );
+ #endif
+
+ pause( "pause", ticks );
+
+ #elif defined( MBG_TGT_NETBSD )
+
+ int timeo = mstohz( sec * 1000 );
+
+ #if defined( DEBUG )
+ printf( "kpause: %i s (%i ticks)\n", sec, timeo );
+ #endif
+
+ kpause( "pause", 1, timeo, NULL );
+
+ #endif
+
+ #else // POSIX user space
+
+ sleep( sec );
+
+ #endif
+
+ #elif defined( MBG_TGT_WIN32 )
+
+ #if defined( MBG_TGT_KERNEL ) // kernel space
+
+ LARGE_INTEGER delay;
+
+ // we need to pass a negative value to KeDelayExecutionThread()
+ // since the given time is a relative time interval, not absolute
+ // time. See the API docs for KeDelayExecutionThread().
+ delay.QuadPart = - ((LONGLONG) sec * HNS_PER_SEC);
+
+ KeDelayExecutionThread( KernelMode, FALSE, &delay );
+
+ #else // user space
+
+ // Sleep() expects milliseconds
+ Sleep( sec * 1000 );
+
+ #endif
+
+ #elif defined( MBG_TGT_DOS )
+
+ delay( (unsigned) ( sec * 1000 ) );
+
+ #else
+
+ // This needs to be implemented for the target OS
+ // and thus will probably yield a linker error.
+ do_sleep_sec( sec );
+
+ #endif
+
+} // mbg_sleep_sec
+
+
+
+/* ----- 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 /* _MBGSYSTM_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgtime.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgtime.h
index ba6900f..847cb88 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgtime.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgtime.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgtime.h 1.17.1.6 2011/05/06 09:03:12 martin TRASH $
+ * $Id: mbgtime.h 1.24 2017/07/04 14:02:25 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,15 +10,32 @@
*
* -----------------------------------------------------------------------
* $Log: mbgtime.h $
- * Revision 1.17.1.6 2011/05/06 09:03:12 martin
- * Fix for DOS.
- * Revision 1.17.1.5 2011/05/06 08:07:58Z daniel
- * include <time.h> for WIN32 target and firmware only
- * Revision 1.17.1.4 2011/02/09 15:46:48Z martin
- * Revision 1.17.1.3 2011/01/24 17:09:20 martin
- * Fixed build under FreeBSD.
- * Revision 1.17.1.2 2010/08/13 11:57:13 martin
- * Revision 1.17.1.1 2010/08/13 11:39:20Z martin
+ * Revision 1.24 2017/07/04 14:02:25 martin
+ * Made definitions of some constants signed to avoid
+ * signed/unsigned compiler warnings.
+ * Moved some macros and inline functions for fraction
+ * conversion here. They are excluded from build in kernel
+ * mode, though, since some kernels don't support this properly.
+ * Moved some NANO_TIME- and NANO_TIME_64-related inline
+ * functions to new module nanotime.c.
+ * Renamed PCPS_HRT_BIN_FRAC_SCALE to MBG_FRAC32_UNITS_PER_SEC.
+ * Updated function prototypes.
+ * Doxygen stuff.
+ * Revision 1.23 2017/03/16 12:26:13 martin
+ * Updated function prototypes.
+ * Revision 1.22 2017/01/25 13:10:55 gregoire.diehl
+ * nano_time_64_to_double and double_to_nano_time_64 added
+ * Revision 1.21 2016/12/15 17:44:59Z martin
+ * Changed conditions to include time.h.
+ * Fixed spelling.
+ * Removed trailing spaces.
+ * Revision 1.20 2014/05/27 08:09:19 martin
+ * Added NTP_SEC_BIAS.
+ * Revision 1.19 2013/05/22 16:47:01 martin
+ * Added some useful macros.
+ * Revision 1.18 2012/10/02 18:51:11 martin
+ * Include <time.h> for WIN32 target and firmware only
+ * Fixed build under QNX, DOS, and FreeBSD.
* Revision 1.17 2010/08/06 13:03:03 martin
* Removed obsolete code.
* Revision 1.16 2010/07/16 10:22:07Z martin
@@ -65,9 +82,7 @@
#include <gpsdefs.h>
-#if _IS_MBG_FIRMWARE \
- || defined( MBG_TGT_WIN32 ) \
- || defined( MBG_TGT_DOS )
+#if !defined( MBG_TGT_KERNEL ) || defined( MBG_TGT_WIN32 )
#include <time.h>
#endif
@@ -78,6 +93,7 @@ extern "C" {
#ifdef _MBGTIME
#define _ext
+ #define _DO_INIT
#else
#define _ext extern
#endif
@@ -86,13 +102,30 @@ extern "C" {
/* Start of header body */
-// The Unix time_t epoche is usually 1970-01-01 00:00 whereas
-// the GPS epoche is 1980-01-06 00:00, so the difference is 10 years,
-// plus 2 days due to leap years (1972 and 1976), plus the difference
-// of the day-of-month (6 - 1).
-#define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
+/**
+ * @brief GPS epoch bias from ordinary time_t epoch
+ *
+ * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
+ * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years,
+ * plus 2 days due to leap years (1972 and 1976), plus the difference
+ * of the day-of-month (6 - 1), so:<br>
+ *
+ * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS
+ */
+#define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
+
+
+/**
+ * @brief NTP epoch bias from ordinary time_t epoch
+ *
+ * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
+ * the NTP epoch is 1900-01-01 00:00, so the difference is
+ * a constant number of seconds:<br>
+ *
+ * time_t t = ntp_time - ::NTP_SEC_BIAS
+ */
+#define NTP_SEC_BIAS 2208988800UL
-// time_t t = ( gps_week * SECS_PER_WEEK ) + sec_of_week + GPS_SEC_BIAS
// Modified Julian Day (MJD) numbers for some commonly used epochs.
@@ -105,7 +138,7 @@ extern "C" {
// The constant below defines the Windows FILETIME number (100 ns intervals
-// since 1601-01-01) for 1970-01-01, which is usually the epoche for the time_t
+// since 1601-01-01) for 1970-01-01, which is usually the epoch for the time_t
// type used by the standard C library.
#if !defined( FILETIME_1970 )
// FILETIME represents a 64 bit number, so we need to defined the
@@ -174,6 +207,7 @@ typedef struct
clock_t start;
clock_t stop;
short is_set;
+
} TIMEOUT;
@@ -203,77 +237,96 @@ typedef struct
#define MSEC_PER_HOUR ( MSEC_PER_SEC * SECS_PER_HOUR )
#define MSEC_PER_DAY ( MSEC_PER_SEC * SECS_PER_DAY )
-#define NSECS_PER_SEC 1000000000UL
+#define NSECS_PER_SEC 1000000000L
#if !defined( HNS_PER_SEC )
- #define HNS_PER_SEC 10000000UL
+ #define HNS_PER_SEC 10000000L
#endif
#if !defined( HNS_PER_MS )
- #define HNS_PER_MS 10000UL
+ #define HNS_PER_MS 10000L
#endif
+/**
+ * @brief A table with the days of month
+ *
+ * First row is for standard years, second row is
+ * for leap years.
+ *
+ * @see DAYS_OF_MONTH_TABLE_INIT
+ */
+typedef char DAYS_OF_MONTH_TABLE[2][12];
+
+
+/**
+ * @brief An initializer for a ::DAYS_OF_MONTH_TABLE
+ */
+#define DAYS_OF_MONTH_TABLE_INIT \
+{ \
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, \
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } \
+}
+
+
+
_ext TM_GPS dhms;
_ext TM_GPS datum;
_ext const char *short_time_fmt
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= "%2i:%02i"
#endif
;
_ext const char *time_fmt
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= "%2i:%02i:%02i"
#endif
;
_ext const char *long_time_fmt
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= "%2i:%02i:%02i.%02i"
#endif
;
_ext const char *date_fmt
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= "%2i.%02i.%04i"
#endif
;
_ext const char *day_date_fmt
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= "%s, %2i.%02i.%04i"
#endif
;
_ext const char *day_name_eng[]
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }
#endif
;
_ext const char *day_name_ger[]
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }
#endif
;
_ext const TM_GPS init_tm
-#ifdef _MBGTIME
+#ifdef _DO_INIT
= { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 }
#endif
;
-_ext char days_of_month[2][12]
-#ifdef _MBGTIME
- = {
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
- }
+_ext DAYS_OF_MONTH_TABLE days_of_month
+#ifdef _DO_INIT
+ = DAYS_OF_MONTH_TABLE_INIT
#endif
;
@@ -283,34 +336,380 @@ _ext char days_of_month[2][12]
n_days( (_s)->mday, (_s)->month, (_s)->year )
+#define _is_leap_year( _y ) \
+ ( ( ( ( (_y) % 4 ) == 0 ) && ( ( (_y) % 100 ) != 0 ) ) || ( ( (_y) % 400 ) == 0 ) )
+
+
+#define _get_days_of_month( _y, _m ) \
+ days_of_month[ _is_leap_year( _y ) ][_m]
+
+
+
+#if !defined( MBG_TGT_KERNEL )
+
+/**
+ * @brief Data type used for intermediate results on 32 bit multiplications
+ *
+ * We need 64 bits for intermediate integer results to avoid a range overflow
+ * from 32 x 32 bit multiplications. On systems which don't support 64 bit types
+ * we use the "double" type as a workaround.
+ */
+#if defined( MBG_TGT_MISSING_64_BIT_TYPES )
+ #define MBG_FRAC32_CONVERSION_TYPE double
+#else
+ #define MBG_FRAC32_CONVERSION_TYPE int64_t
+#endif
+
+/**
+ * @brief Constant used to convert e.g. ::PCPS_TIME_STAMP::frac values
+ *
+ * Max value of ::PCPS_TIME_STAMP::frac + 1, used for scaling
+ */
+#define MBG_FRAC32_UNITS_PER_SEC ( (MBG_FRAC32_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000
+
+
+
+/**
+ * @brief Convert a 16 bit binary fraction to a scaled decimal
+ *
+ * @param[in] bin The binary fraction
+ * @param[in] scale The scale factor
+ *
+ * @return The calculated number
+ *
+ * @see ::dec_frac_to_bin_frac_16
+ * @see ::dec_frac_to_bin_frac_32
+ * @see ::bin_frac_32_to_dec_frac
+ * @see ::frac_sec_from_bin
+ */
+static __mbg_inline
+uint32_t bin_frac_16_to_dec_frac( uint16_t bin, uint32_t scale )
+{
+ return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale
+ / 0x10000UL );
+
+} // bin_frac_16_to_dec_frac
+
+
+
+/**
+ * @brief Convert a 32 bit binary fraction to a scaled decimal
+ *
+ * @param[in] bin The binary fraction
+ * @param[in] scale The scale factor
+ *
+ * @return The calculated number
+ *
+ * @see ::dec_frac_to_bin_frac_32
+ * @see ::dec_frac_to_bin_frac_16
+ * @see ::bin_frac_16_to_dec_frac
+ */
+static __mbg_inline
+uint32_t bin_frac_32_to_dec_frac( uint32_t bin, uint32_t scale )
+{
+ return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale
+ / MBG_FRAC32_UNITS_PER_SEC );
+
+} // bin_frac_32_to_dec_frac
+
+
+
+#if !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+// On targets which don't provide 64 bit data types
+// MBG_FRAC32_CONVERSION_TYPE is defined as double,
+// in which case the ">> 1" operation in the 2 functions
+// below yields an "invalid use of floating point" error.
+// This could probably be fixed by a different way of
+// casting, at least for a partial expression.
+
+static __mbg_inline
+uint16_t dec_frac_to_bin_frac_16( uint32_t dec, uint32_t scale )
+{
+ return (uint16_t) ( ( ( (MBG_FRAC32_CONVERSION_TYPE) dec * 0x20000 / scale ) + 1 ) >> 1 );
+
+} // dec_frac_to_bin_frac_16
+
+
+static __mbg_inline
+uint32_t dec_frac_to_bin_frac_32( uint32_t dec, uint32_t scale )
+{
+ return (uint32_t) ( ( ( (MBG_FRAC32_CONVERSION_TYPE) dec * MBG_FRAC32_UNITS_PER_SEC * 2 / scale ) + 1 ) >> 1 );
+
+} // dec_frac_to_bin_frac_32
+
+#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+
+
+#define bin_frac_32_to_msec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000L )
+#define bin_frac_32_to_usec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000L )
+#define bin_frac_32_to_nsec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000000L )
+#define bin_frac_16_to_msec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000L )
+#define bin_frac_16_to_usec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000L )
+#define bin_frac_16_to_nsec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000000L )
+
+
+#define msec_to_bin_frac_32( _msec ) dec_frac_to_bin_frac_32( (_msec), 1000L )
+#define usec_to_bin_frac_32( _usec ) dec_frac_to_bin_frac_32( (_usec), 1000000L )
+#define nsec_to_bin_frac_32( _nsec ) dec_frac_to_bin_frac_32( (_nsec), 1000000000L )
+#define msec_to_bin_frac_16( _msec ) dec_frac_to_bin_frac_16( (_msec), 1000L )
+#define usec_to_bin_frac_16( _usec ) dec_frac_to_bin_frac_16( (_usec), 1000000L )
+#define nsec_to_bin_frac_16( _nsec ) dec_frac_to_bin_frac_16( (_nsec), 1000000000L )
+
+
+
+/**
+ * @brief Convert a binary fraction to a scaled decimal
+ *
+ * Convert a binary fraction (e.g. of a second, as in ::PCPS_TIME_STAMP::frac)
+ * to a decimal fraction, using a specified scale factor.
+ *
+ * @deprecated This function is deprecated, use ::bin_frac_32_to_dec_frac preferably.
+ *
+ * @param[in] b The binary fraction
+ * @param[in] scale The scale factor
+ *
+ * @return The calculated number
+ *
+ * @see ::bin_frac_32_to_dec_frac
+ */
+static __mbg_inline
+uint32_t _DEPRECATED_BY( "bin_frac_32_to_dec_frac" ) frac_sec_from_bin( uint32_t b, uint32_t scale )
+{
+ return bin_frac_32_to_dec_frac( b, scale );
+
+} // frac_sec_from_bin
+
+
+
+/**
+ * @brief Convert a binary fraction to "double" fractions
+ *
+ * Convert a binary fraction (e.g. of a second, as in ::PCPS_TIME_STAMP::frac)
+ * to a "double" with the units of seconds.<br>
+ * E.g. a 0xFFFFFFFF fraction yields 0.9999999999....
+ *
+ * @note Excluded from build for kernel drivers which usually
+ * don't support floating point operations.
+ *
+ * @param[in] b The binary fraction
+ *
+ * @return The calculated fraction
+ *
+ * @see ::MBG_FRAC32_UNITS_PER_SEC
+ */
+static __mbg_inline
+double dfrac_sec_from_bin( uint32_t b )
+{
+ return (double) b / (double) MBG_FRAC32_UNITS_PER_SEC;
+
+} // dfrac_sec_from_bin
+
+#endif // !defined( MBG_TGT_KERNEL )
+
+
+
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
+ /**
+ * @brief Set a timeout object to specified interval
+ *
+ * @param[out] t The timeout object
+ * @param[in] clk The current time, in clock_t ticks
+ * @param[in] interval The interval until expiration, in clock_t ticks
+ */
void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ;
+
+ /**
+ * @brief Stretch a timeout specified in given timeout object
+ *
+ * @param[in,out] t The timeout object
+ * @param[in] interval The interval until expiration, in clock_t ticks
+ */
void stretch_timeout( TIMEOUT *t, clock_t interval ) ;
+
+ /**
+ * @brief Check if a timeout object has expired
+ *
+ * @param[in] t The timeout object
+ * @param[in] clk The current time, in clock_t ticks
+ *
+ * @return 1 if timeout expired, else 0
+ */
bit check_timeout( TIMEOUT *t, clock_t clk ) ;
- int err_tm( TM_GPS *tm ) ;
+
+ /**
+ * @brief Check if a ::TM_GPS structure contains a valid date and time
+ *
+ * @param[in] tm The date/time structure to be checked
+ *
+ * @return 0 if date/time is valid, else a negative number indicating
+ * which field was found invalid
+ */
+ int err_tm( const TM_GPS *tm ) ;
+
+ /**
+ * @brief Set the time in a ::TM_GPS structure to 00:00:00.000
+ *
+ * @param[in,out] tm The date/time structure to be set
+ *
+ * @return Pointer to the ::TM_GPS structure that has been passed
+ */
TM_GPS *clear_time( TM_GPS *tm ) ;
+
+ /**
+ * @brief Convert second-of-week to day-of-week and time-of-day
+ *
+ * @param[in] wsec The second-of-week number to be converted
+ * @param[out] tm Address of a ::TM_GPS structure which takes the computed results
+ *
+ * @return Pointer to the ::TM_GPS structure that has been passed
+ *
+ * @see ::tm_to_wsec
+ */
TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ;
- long tm_to_wsec( TM_GPS *tm ) ;
+
+ /**
+ * @brief Compute second-of-week from day-of-week and time-of-day
+ *
+ * @todo Specify input / output ranges
+ *
+ * @param[in] tm Address of a ::TM_GPS structure providing day-of-week and time-of-day
+ *
+ * @return The computed second-of-week number
+ *
+ * @see ::wsec_to_tm
+ */
+ long tm_to_wsec( const TM_GPS *tm ) ;
+
+ /**
+ * @brief Check if a specific year is a leap year
+ *
+ * @param[in] y The full year number
+ *
+ * @return != 0 if the year is a leap year, else 0
+ */
int is_leap_year( int y ) ;
+
+ /**
+ * @brief Compute the day-of-year from a given date
+ *
+ * @param[in] day The day-of-month
+ * @param[in] month The month
+ * @param[in] year The full year number
+ *
+ * @return The computed day-of-year
+ */
int day_of_year( int day, int month, int year ) ;
+
+ /**
+ * @brief Compute a date from a given year and day-of-year
+ *
+ * @param[in] year The full year number
+ * @param[in] day_num Number of days from the beginning of that year, may be negative
+ * @param[out] tm Address of a ::TM_GPS structure which takes the computed results
+ */
void date_of_year ( int year, int day_num, TM_GPS *tm ) ;
+
+ /**
+ * @brief Compute day-of-week from a given date
+ *
+ * @todo Specify range of returned day-of-week. Should we just call n_days()?
+ *
+ * @param[in] day The day-of-month
+ * @param[in] month The month
+ * @param[in] year The full year number
+ *
+ * @return The computed day-of-week
+ *
+ * @see ::n_days
+ */
int day_of_week( int day, int month, int year ) ;
+
+ /**
+ * @brief Update a year number by a number of days, accounting for leap years
+ *
+ * @param[in] day_num The number of days to evaluate
+ * @param[in] year The year number to start with
+ *
+ * @return The computed year number
+ */
int days_to_years( long *day_num, int year ) ;
+
+ /**
+ * @brief Compute number of days after Jan 1, 0000 for a given date
+ *
+ * @param[in] mday The day-of-month
+ * @param[in] month The month
+ * @param[in] year The full year number
+ *
+ * @return The computed number of days
+ *
+ * @see ::day_of_week
+ */
long n_days( ushort mday, ushort month, ushort year ) ;
- double nano_time_to_double( const NANO_TIME *p ) ;
- void double_to_nano_time( NANO_TIME *p, double d ) ;
+
+ /**
+ * @brief Print time with hours, minutes, seconds to a string
+ *
+ * @param[out] s Address of a string buffer to be filled
+ * @param[in] tm Address of a ::TM_GPS structure providing date and time
+ */
int sprint_time( char *s, const TM_GPS *tm ) ;
- int sprint_short_time( char *s, TM_GPS *time ) ;
+
+ /**
+ * @brief Print time with hours, minutes to a string
+ *
+ * @param[out] s Address of a string buffer to be filled
+ * @param[in] tm Address of a ::TM_GPS structure providing date and time
+ */
+ int sprint_short_time( char *s, const TM_GPS *tm ) ;
+
+ /**
+ * @brief Print date to a string
+ *
+ * @param[out] s Address of a string buffer to be filled
+ * @param[in] tm Address of a ::TM_GPS structure providing date and time
+ */
int sprint_date( char *s, const TM_GPS *tm ) ;
+
+ /**
+ * @brief Print day-of-week and date to a string
+ *
+ * @param[out] s Address of a string buffer to be filled
+ * @param[in] tm Address of a ::TM_GPS structure providing date and time
+ */
int sprint_day_date( char *s, const TM_GPS *tm ) ;
+
+ /**
+ * @brief Print day-of-week, date and time to a string
+ *
+ * @param[out] s Address of a string buffer to be filled
+ * @param[in] tm Address of a ::TM_GPS structure providing date and time
+ */
int sprint_tm( char *s, const TM_GPS *tm ) ;
- void sscan_time( char *s, TM_GPS *tm ) ;
+
+ /**
+ * @brief Extract a time from a string
+ *
+ * @param[in] s A time string in format hh:mm:ss
+ * @param[out] tm Address of a ::TM_GPS structure which takes the extracted time
+ */
+ void sscan_time( const char *s, TM_GPS *tm ) ;
+
+ /**
+ * @brief Extract a date from a string
+ *
+ * @param[in] s A date string in format dd.mm. or dd.mm.yyyy
+ * @param[out] tm Address of a ::TM_GPS structure which takes the extracted date
+ */
void sscan_date( char *s, TM_GPS *tm ) ;
+
/* ----- function prototypes end ----- */
@@ -318,6 +717,7 @@ _ext char days_of_month[2][12]
#undef _ext
+#undef _DO_INIT
#ifdef __cplusplus
}
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.c b/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.c
index 1a4156e..e588485 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgutil.c 1.5.2.1 2010/07/15 13:06:59 martin TEST $
+ * $Id: mbgutil.c 1.7 2017/07/05 16:40:35 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,17 @@
*
* -----------------------------------------------------------------------
* $Log: mbgutil.c $
- * Revision 1.5.2.1 2010/07/15 13:06:59 martin
+ * Revision 1.7 2017/07/05 16:40:35 martin
+ * Use functions from new module timeutil.
+ * Use safe string functions from str_util.c.
+ * Quieted some compiler warninges.
+ * Account for frac_sec_from_bin() obsoleted by bin_frac_32_to_dec_frac().
+ * Account for renamed library symbols.
+ * Added doxygen comments.
+ * Revision 1.6 2012/10/15 13:12:17 martin
+ * Fixed build under DOS.
+ * Fixed format/type mismatch when printing UTC offset.
+ * Fixed generation of firmware and ASIC version string.
* Revision 1.5 2009/03/19 09:09:55Z daniel
* Fixed ambiguous syntax in mbg_str_dev_name().
* Support TAI and GPS time scales in mbg_str_pcps_hr_tstamp_loc().
@@ -32,13 +42,17 @@
#include <mbgutil.h>
#undef _MBGUTIL
+#include <cfg_hlp.h>
+#include <mbgerror.h>
#include <pcpsutil.h>
-#include <pcpslstr.h>
-//#include <gpsutils.h>
+#include <charcode.h>
#include <pcpsdev.h>
+#include <str_util.h>
+#include <qsdefs.h>
#include <stdio.h>
#include <time.h>
+#include <limits.h>
// required at least for Linux:
#include <stdarg.h>
@@ -58,32 +72,18 @@ static int mbg_date_time_dist = 2;
static int mbg_pos_dist = 2;
static uint16_t mbg_year_lim = 1980;
-
-
-#if defined( MBG_TGT_WIN32 )
- #define mbg_vsnprintf _vsnprintf
-#else
- #define mbg_vsnprintf vsnprintf
-#endif
-
-
-#if defined( MBG_TGT_DOS )
-
-static /*HDR*/
-int vsnprintf( char *s, int max_len, const char *fmt, va_list arg_list )
-{
- return vsprintf( s, fmt, arg_list );
-
-} // vsnprintf
-
-#endif
+static const char str_inv_cnv[] = "(invalid conversion)";
/*HDR*/
+/**
+ * @brief Get the DLL/shared library's version code
+ *
+ * @return The version code at which the library was built
+ */
_MBG_API_ATTR int _MBG_API mbgutil_get_version( void )
{
-
return MBGUTIL_VERSION;
} // mbgutil_get_version
@@ -91,70 +91,99 @@ _MBG_API_ATTR int _MBG_API mbgutil_get_version( void )
/*HDR*/
+/**
+ * @brief Check the DLL/shared library's compatibility
+ *
+ * @param[in] header_version Version code defined in the header file when the application is built
+ *
+ * @return ::MBG_SUCCESS if compatible, else ::MBG_ERR_LIB_NOT_COMPATIBLE
+ */
_MBG_API_ATTR int _MBG_API mbgutil_check_version( int header_version )
{
if ( header_version >= MBGUTIL_COMPAT_VERSION )
- return PCPS_SUCCESS;
+ return MBG_SUCCESS;
- return -1;
+ return MBG_ERR_LIB_NOT_COMPATIBLE;
} // mbgutil_check_version
-// We have our own version of snprintf() since under Windows
-// _snprintf(), returns -1 and does not write a terminating 0
-// if the output exceeds the buffer size.
-//
-// This function terminates the output string properly. However,
-// the maximum return value is (max_len - 1), so the function
-// can not be used to determine the buffer size that would be
-// required for an untruncated string.
-
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... )
+/**
+ * @brief A portable, safe implementation of snprintf()
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ * For a detailed description see ::vsnprintf_safe
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ... Variable argument list according to the format string
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ */
+_MBG_API_ATTR int __attribute__( ( format( printf, 3, 4 ) ) )
+_MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... )
{
- int n;
-
+ size_t n;
va_list ap;
- va_start( ap, fmt );
-
- n = mbg_vsnprintf( s, max_len, fmt, ap );
-
- va_end( ap );
-
-
- #if defined( MBG_TGT_WIN32 )
+ // TODO: size_t can be larger than int, so what happens if
+ // a very long string is written to the buffer and the number
+ // of bytes written exceeds MAXINT, in which case the number
+ // can't be returned?
- // Terminate the output string properly under Windows.
- // For other targets assume the POSIX version is available.
- if ( n < 0 || n >= (int) max_len )
- {
- n = max_len - 1;
- s[n] = 0;
- }
+ va_start( ap, fmt );
- #endif
+ n = vsnprintf_safe( s, max_len, fmt, ap );
+ va_end( ap );
- return n;
+ return _int_from_size_t( n );
} // mbg_snprintf
/*HDR*/
+/**
+ * @brief A portable, safe implementation of strncpy()
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the destination string buffer
+ * @param[in] max_len Size of the destination string buffer
+ * @param[in] src Pointer to the source string buffer
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_strncpy( char *s, size_t max_len, const char *src )
{
- //##++ This could be coded more efficiently
- return mbg_snprintf( s, max_len, "%s", src );
+ size_t n = sn_cpy_str_safe( s, max_len, src );
+
+ return _int_from_size_t( n );
} // mbg_strncpy
/*HDR*/
+/**
+ * @brief Write a character multiple times to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] c The character to write to the output buffer
+ * @param[in] n The number of characters to write to the output buffer
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_strchar( char *s, size_t max_len, char c, size_t n )
{
size_t i;
@@ -166,251 +195,542 @@ _MBG_API_ATTR int _MBG_API mbg_strchar( char *s, size_t max_len, char c, size_t
if ( i >= max_len )
break;
+ if ( i >= ( INT_MAX - 1 ) )
+ break;
+
s[i] = c;
}
s[i] = 0;
- return i;
+ return (int) i;
} // mbg_strchar
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len,
+/**
+ * @brief Write a short date string "dd.mm." to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] mday Day-of-month number, 1..31
+ * @param[in] month Month number, 1..12
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len,
int mday, int month )
{
- return mbg_snprintf( s, max_len, "%02u.%02u.", mday, month );
-
+ size_t n = snprintf_safe( s, max_len, "%02u.%02u.", mday, month );
+
+ return _int_from_size_t( n );
+
} // mbg_str_date_short
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len,
+/**
+ * @brief Write a date string "dd.mm.yyyy" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] mday Day-of-month number, 1..31
+ * @param[in] month Month number, 1..12
+ * @param[in] year Year number
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len,
int mday, int month, int year )
{
- int n = mbg_str_date_short( s, max_len, mday, month );
- n += mbg_snprintf( s + n, max_len - n, "%04u",
- ( year < 256 ) ?
- pcps_exp_year( (uint8_t) year, mbg_year_lim ) :
- year
- );
- return n;
+ size_t n = mbg_str_date_short( s, max_len, mday, month );
+
+ n += snprintf_safe( &s[n], max_len - n, "%04u",
+ ( year < 256 ) ?
+ pcps_exp_year( (uint8_t) year, mbg_year_lim ) :
+ year );
+
+ return _int_from_size_t( n );
} // mbg_str_date
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len,
+/**
+ * @brief Write a short time string "hh:mm" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len,
int hour, int min )
{
- return mbg_snprintf( s, max_len, "%2u:%02u", hour, min );
+ size_t n = snprintf_safe( s, max_len, "%2u:%02u", hour, min );
+
+ return _int_from_size_t( n );
} // mbg_str_time_short
/*HDR*/
+/**
+ * @brief Write a time string "hh:mm:ss" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ * @param[in] sec Seconds number, 0..59, or 60 in case of leap second
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_time( char *s, int max_len,
int hour, int min, int sec )
{
- int n = mbg_str_time_short( s, max_len, hour, min );
+ size_t n = mbg_str_time_short( s, max_len, hour, min );
- n += mbg_snprintf( s + n, max_len - n, ":%02u", sec );
+ n += snprintf_safe( &s[n], max_len - n, ":%02u", sec );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_time
/*HDR*/
+/**
+ * @brief Write a long time string "hh:mm:ss.cc" to a string buffer
+ *
+ * Include 100ths of seconds.
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ * @param[in] sec Seconds number, 0..59, or 60 in case of leap second
+ * @param[in] sec100 Hundreths of seconds, 0..99
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_time_long( char *s, int max_len,
int hour, int min, int sec, int sec100 )
{
- int n = mbg_str_time( s, max_len, hour, min, sec );
+ size_t n = mbg_str_time( s, max_len, hour, min, sec );
- n += mbg_snprintf( s + n, max_len - n, ".%02u", sec100 );
+ n += snprintf_safe( &s[n], max_len - n, ".%02u", sec100 );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_time_long
/*HDR*/
+/**
+ * @brief Write a full date and time string to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::TM_GPS structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_tm_gps_date_time( char *s, int max_len,
const TM_GPS *pt )
{
- int n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, pt->hour, pt->min, pt->sec );
+ size_t n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_time( &s[n], max_len - _int_from_size_t( n ), pt->hour, pt->min, pt->sec );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_tm_gps_date_time
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len,
+/**
+ * @brief Write the short date given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_date_short( s, max_len, pt->mday, pt->month );
+ size_t n = mbg_str_date_short( s, max_len, pt->mday, pt->month );
+
+ return _int_from_size_t( n );
} // mbg_str_pcps_date_short
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len,
+/**
+ * @brief Write the date given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+ size_t n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+
+ return _int_from_size_t( n );
} // mbg_str_pcps_date
/*HDR*/
+/**
+ * @brief Write the short time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time_short( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time_short( s, max_len, pt->hour, pt->min );
+ size_t n = mbg_str_time_short( s, max_len, pt->hour, pt->min );
+
+ return _int_from_size_t( n );
} // mbg_str_pcps_time_short
/*HDR*/
+/**
+ * @brief Write the time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time( s, max_len, pt->hour, pt->min, pt->sec );
+ size_t n = mbg_str_time( s, max_len, pt->hour, pt->min, pt->sec );
+
+ return _int_from_size_t( n );
} // mbg_str_pcps_time
/*HDR*/
+/**
+ * @brief Write the time including sec100ths given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time_long( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time_long( s, max_len, pt->hour, pt->min, pt->sec, pt->sec100 );
+ size_t n = mbg_str_time_long( s, max_len, pt->hour, pt->min, pt->sec, pt->sec100 );
+
+ return _int_from_size_t( n );
} // mbg_str_pcps_time_long
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len,
- const PCPS_TIME *pt,
+/**
+ * @brief Write date and time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ * @param[in] tz_str Optional time zone string to be appended, currently not used, may be NULL
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len,
+ const PCPS_TIME *pt,
const char *tz_str )
{
- int n = mbg_str_pcps_date( s, max_len, pt );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_pcps_time( s + n, max_len - n, pt );
+ size_t n = mbg_str_pcps_date( s, max_len, pt );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_pcps_time( &s[n], max_len - _int_from_size_t( n ), pt );
+ // FIXME Use tz_str ?
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_pcps_date_time
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len,
+/**
+ * @brief Write date derived from seconds-since-epoch to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] sec Number of seconds since the epoch to be converted to date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len,
uint32_t sec )
{
- time_t t = sec;
- struct tm tm = *gmtime( &t );
- return mbg_str_date( s, max_len, tm.tm_mday, tm.tm_mon + 1, tm.tm_year );
+ struct tm tm = { 0 };
+ time_t t = cvt_to_time_t( sec );
+ int rc = mbg_gmtime( &tm, &t );
+
+ return mbg_rc_is_success( rc ) ?
+ mbg_str_date( s, max_len, tm.tm_mday, tm.tm_mon + 1, tm.tm_year ) :
+ sn_cpy_str_safe( s, max_len, str_inv_cnv );
} // mbg_str_pcps_hr_date
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len,
+/**
+ * @brief Write time derived from seconds-since-epoch to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] sec Number of seconds since the epoch to be converted to date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len,
uint32_t sec )
{
- time_t t = sec;
- struct tm tm = *gmtime( &t );
- return mbg_str_time( s, max_len, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ struct tm tm = { 0 };
+ time_t t = cvt_to_time_t( sec );
+ int rc = mbg_gmtime( &tm, &t );
+
+ return mbg_rc_is_success( rc ) ?
+ mbg_str_time( s, max_len, tm.tm_hour, tm.tm_min, tm.tm_sec ) :
+ sn_cpy_str_safe( s, max_len, str_inv_cnv );
} // mbg_str_pcps_hr_time
+static /*HDR*/
+/* (explicitly excluded from Doxygen)
+ * @brief Write UTC date and time given as ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] p_t Pointer to a time_t variable providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+int do_str_pcps_hr_date_time( char *s, int max_len, const time_t *p_t )
+{
+ struct tm tm = { 0 };
+ int n = 0;
+ int rc = mbg_gmtime( &tm, p_t );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_time( &s[n], max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ }
+ else
+ n = sn_cpy_str_safe( s, max_len, str_inv_cnv );
+
+ return n;
+
+} // do_str_pcps_hr_date_time
+
+
+
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len,
+/**
+ * @brief Write UTC date and time given as ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- time_t t = pt->tstamp.sec;
- struct tm tm = *gmtime( &t );
- int n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ time_t t = cvt_to_time_t( pt->tstamp.sec );
- return n;
+ return do_str_pcps_hr_date_time( s, max_len, &t );
} // mbg_str_pcps_hr_date_time_utc
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len,
+/**
+ * @brief Write local date and time given as ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- time_t t = pt->tstamp.sec + pt->utc_offs;
- struct tm tm = *gmtime( &t );
- int n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ long l = (long) pt->tstamp.sec + pt->utc_offs;
+ time_t t = cvt_to_time_t( l );
- return n;
+ return do_str_pcps_hr_date_time( s, max_len, &t );
} // mbg_str_pcps_hr_date_time_loc
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len,
+/**
+ * @brief Print binary ::PCPS_FRAC_32 fractions in decimal to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] frac Binary fractions of a second in ::PCPS_FRAC_32 format
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len,
uint32_t frac )
{
- return mbg_snprintf( s, max_len, PCPS_HRT_FRAC_SCALE_FMT,
- frac_sec_from_bin( frac, PCPS_HRT_FRAC_SCALE ) );
+ size_t n = snprintf_safe( s, max_len, PCPS_HRT_FRAC_SCALE_FMT,
+ (ulong) bin_frac_32_to_dec_frac( frac, PCPS_HRT_FRAC_SCALE ) );
+ return _int_from_size_t( n );
} // mbg_str_pcps_hr_time_frac
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_offs( char *s, int max_len,
+/**
+ * @brief Print the UTC offset from a ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The output format is sign - hours - minutes, e.g. "+01:45h".
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date, and UTC offset
+ * @param[in] info An informational text to be prepended
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_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 )
{
- int n = mbg_snprintf( s, max_len, "%s", info );
+ size_t n = snprintf_safe( s, max_len, "%s", info );
if ( pt->utc_offs )
{
ldiv_t ldt = ldiv( labs( pt->utc_offs ) / 60, 60 );
- n += mbg_snprintf( s + n, max_len - n, "%c%02u:%02uh",
- ( pt->utc_offs < 0 ) ? '-' : '+',
- ldt.quot, ldt.rem );
+ n += snprintf_safe( &s[n], max_len - n, "%c%02lu:%02luh",
+ ( pt->utc_offs < 0 ) ? '-' : '+',
+ ldt.quot, ldt.rem );
}
- return n;
+ return _int_from_size_t( n );
} // mbg_str_pcps_hr_time_offs
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
+/**
+ * @brief Write a high resolution UTC time stamp including fractions to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
int n = mbg_str_pcps_hr_date_time_utc( s, max_len, pt );
@@ -418,7 +738,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
if ( n < ( max_len - 1 ) )
{
s[n++] = '.';
- n += mbg_str_pcps_hr_time_frac( s + n, max_len - n, pt->tstamp.frac );
+ n += mbg_str_pcps_hr_time_frac( &s[n], max_len - n, pt->tstamp.frac );
}
return n;
@@ -428,7 +748,18 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
+/**
+ * @brief Write a high resolution local time stamp including fractions to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
int n = mbg_str_pcps_hr_date_time_loc( s, max_len, pt );
@@ -436,7 +767,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
if ( n < ( max_len - 1 ) )
{
s[n++] = '.';
- n += mbg_str_pcps_hr_time_frac( s + n, max_len - n, pt->tstamp.frac );
+ n += mbg_str_pcps_hr_time_frac( &s[n], max_len - n, pt->tstamp.frac );
}
if ( n < ( max_len - 1 ) )
@@ -450,7 +781,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
cp = "GPS";
s[n++] = ' ';
- n += mbg_str_pcps_hr_time_offs( s + n, max_len - n, pt, cp );
+ n += mbg_str_pcps_hr_time_offs( &s[n], max_len - n, pt, cp );
}
return n;
@@ -460,69 +791,138 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len,
+/**
+ * @brief Write a raw high resolution time stamp to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len,
const PCPS_TIME_STAMP *pt )
{
- return mbg_snprintf( s, max_len, "%08lX.%08lX", pt->sec, pt->frac );
+ size_t n = snprintf_safe( s, max_len, "%08lX.%08lX", (ulong) pt->sec, (ulong) pt->frac );
+ return _int_from_size_t( n );
} // mbg_str_pcps_tstamp_raw
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len,
+/**
+ * @brief Write a raw high resolution time stamp plus converted local time to a string buffer
+ *
+ * The output string also has the time status code appended as hex number.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- int n = mbg_str_pcps_tstamp_raw( s, max_len, &pt->tstamp );
- n += mbg_str_pcps_hr_time_offs( s + n, max_len - n, pt, ", Loc: " );
- n += mbg_snprintf( s + n, max_len - n, ", st: 0x%04X", pt->status );
+ size_t n = mbg_str_pcps_tstamp_raw( s, max_len, &pt->tstamp );
+ n += mbg_str_pcps_hr_time_offs( &s[n], max_len - _int_from_size_t( n ), pt, ", Loc: " );
+ n += snprintf_safe( &s[n], max_len - n, ", st: 0x%04X", pt->status );
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_pcps_hr_time_raw
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len,
+/**
+ * @brief Write time capture / user capture time stamp to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure containing a user capture event
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- int n = mbg_snprintf( s, max_len, "CAP%u: ", pt->signal );
- n += mbg_str_pcps_hr_tstamp_loc( s + n, max_len - n, pt );
+ size_t n = snprintf_safe( s, max_len, "CAP%u: ", pt->signal );
+ n += mbg_str_pcps_hr_tstamp_loc( &s[n], max_len - _int_from_size_t( n ), pt );
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_ucap
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len,
+/**
+ * @brief Write a geographic coordinate in degrees - minutes - seconds to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pdms Pointer to a ::DMS structure containing the coordinate
+ * @param[in] prec Number of digits of the geographic seconds after the decimal separator
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len,
const DMS *pdms, int prec )
{
- return mbg_snprintf( s, max_len, "%c %i" DEG "%02i'%02.*f\"",
- pdms->prefix,
- pdms->deg,
- pdms->min,
- prec,
- pdms->sec
- );
+ size_t n = snprintf_safe( s, max_len, "%c %i" DEG "%02i'%02.*f\"",
+ pdms->prefix, pdms->deg, pdms->min,
+ prec, pdms->sec );
+ return _int_from_size_t( n );
} // mbg_str_pos_dms
/*HDR*/
+/**
+ * @brief Write a position's altitude parameter to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] alt The altitude parameter, in meters
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pos_alt( char *s, int max_len, double alt )
{
- return mbg_snprintf( s, max_len, "%.0fm", alt );
+ size_t n = snprintf_safe( s, max_len, "%.0fm", alt );
+ return _int_from_size_t( n );
} // mbg_str_pos_alt
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
+/**
+ * @brief Write geographic coordinates to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] ppos Pointer to a ::POS structure containing the coordinates
+ * @param[in] prec Number of digits of the geographic seconds after the decimal separator
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
const POS *ppos, int prec )
{
int n;
@@ -530,15 +930,15 @@ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
if ( ppos->lla[LON] || ppos->lla[LAT] || ppos->lla[ALT] )
{
n = mbg_str_pos_dms( s, max_len, &ppos->latitude, prec );
- n += mbg_strchar( s + n, max_len - n, ',', 1 );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_pos_dist );
- n += mbg_str_pos_dms( s + n, max_len - n, &ppos->longitude, prec );
- n += mbg_strchar( s + n, max_len - n, ',', 1 );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_pos_dist );
- n += mbg_str_pos_alt( s + n, max_len - n, ppos->lla[ALT] );
+ n += mbg_strchar( &s[n], max_len - n, ',', 1 );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_pos_dist );
+ n += mbg_str_pos_dms( &s[n], max_len - n, &ppos->longitude, prec );
+ n += mbg_strchar( &s[n], max_len - n, ',', 1 );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_pos_dist );
+ n += mbg_str_pos_alt( &s[n], max_len - n, ppos->lla[ALT] );
}
else
- n = mbg_strncpy( s, max_len, "N/A" );
+ n = mbg_strncpy( s, max_len, str_not_avail );
return n;
@@ -547,53 +947,94 @@ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
/*HDR*/
-_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 )
+/**
+ * @brief Write device info to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] short_name Short device name, e.g. in ::MBG_DEV_NAME format
+ * @param[in] fw_rev_num The firmware revision number
+ * @param[in] asic_ver_num The ASIC version number
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+_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_ver_num )
{
- #define HW_NAME_SZ PCPS_CLOCK_NAME_SZ+PCPS_SN_SIZE+1
-
- char model_code[HW_NAME_SZ];
- PCPS_SN_STR sernum;
+ MBG_DEV_NAME dev_name = { 0 };
+ PCPS_SN_STR sernum = { 0 };
unsigned int i = 0;
- int n = 0;
+ size_t n = 0;
+ size_t l = strlen( short_name );
- memset( model_code, 0, sizeof( model_code ) );
- memset( sernum, 0, sizeof( sernum ) );
-
- if ( strlen( short_name ) > 0 )
+ if ( l > 0 )
{
- if ( strstr( short_name, "COM") )
- return mbg_snprintf(s, max_len,"%s", short_name);
+ // For a serial port string specifies we just
+ // copy the short_name.
+ if ( device_id_is_serial( short_name ) )
+ {
+ n = sn_cpy_str_safe( s, max_len, short_name );
+ goto out;
+ }
- for ( i = 0; ( i < HW_NAME_SZ ) && ( i < strlen( short_name ) ); i++ )
+ // If the short_name has more than sizeof( dev_name ) characters
+ // then we have to reduce the maximum length.
+ // For a bus level device the short_name usually consists of
+ // the model name, followed by an underscore '_', followed
+ // by the serial number, e.g. "PZF180PEX_046411000030".
+ // See ::MBG_DEV_NAME.
+ if ( l > sizeof( dev_name ) )
+ l = sizeof( dev_name );
+
+ for ( i = 0; i < l; i++ )
{
if ( short_name[i] == '_' )
{
i++;
break;
}
- model_code[i] = short_name[i];
+
+ dev_name[i] = short_name[i];
}
- strncpy( sernum, &short_name[i], PCPS_SN_SIZE-1 );
- if ( sernum[12] == ' ' )
- sernum[12] = '\0';
+ strncpy_safe( sernum, &short_name[i], sizeof( sernum ) );
+
+ //### TODO
+ // Legal serial numbers have MBG_GRP_SERNUM_LEN characters, which is
+ // less than the maximum length of a PCPS_SN_STR type string.
+ // Do we really have to check and truncate the PCPS_SN_STR sernum?
+ if ( sernum[MBG_GRP_SERNUM_LEN] == ' ' )
+ sernum[MBG_GRP_SERNUM_LEN] = '\0';
}
- n = mbg_snprintf( s, max_len, "%s, S/N %s", model_code, sernum );
+ n = snprintf_safe( s, max_len, "%s, S/N %s", dev_name, sernum );
- if ( fw_rev_num > 0 )
- n += mbg_snprintf( &s[n], max_len," (FW v%X.%02X", fw_rev_num>>8, fw_rev_num & 0x00FF );
+ if ( fw_rev_num || asic_ver_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, " (" );
- if ( asic_version_num > 0 )
+ if ( fw_rev_num )
{
- mbg_snprintf( &s[n], max_len," / ASIC v%X.%02X)", _convert_asic_version_number( asic_version_num ) >> 8,
- ( _convert_asic_version_number( asic_version_num ) ) & 0xFF );
+ n += snprintf_safe( &s[n], max_len - n, "FW v%X.%02X",
+ fw_rev_num >> 8, fw_rev_num & 0xFF );
+ // Append a separator if ASIC version will follow.
+ if ( asic_ver_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, " / " );
}
- else
- mbg_snprintf( &s[n], max_len,")" );
- return strlen(s);
+ if ( asic_ver_num )
+ {
+ n += snprintf_safe( &s[n], max_len - n, "ASIC v%d.%02d",
+ _convert_asic_version_number( asic_ver_num ) >> 8,
+ _convert_asic_version_number( asic_ver_num ) & 0xFF );
+ }
+
+ if ( fw_rev_num || asic_ver_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, ")" );
+
+out:
+ return _int_from_size_t( n );
} // mbg_str_dev_name
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.h b/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.h
index 761db23..bc29f36 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/mbgutil.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgutil.h 1.16.1.2 2011/06/22 10:21:57 martin TRASH $
+ * $Id: mbgutil.h 1.18 2017/07/05 16:44:35 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,10 +10,14 @@
*
* -----------------------------------------------------------------------
* $Log: mbgutil.h $
- * Revision 1.16.1.2 2011/06/22 10:21:57 martin
- * Cleaned up handling of pragma pack().
- * Revision 1.16.1.1 2011/02/09 15:27:23 martin
+ * Revision 1.18 2017/07/05 16:44:35 martin
+ * New version code 0x0400, compatibility version still 0x0110.
+ * Include timeutil.h.
+ * windows.h is now included in mbg_tgt.h.
+ * Updated function prototypes.
+ * Revision 1.17 2012/10/15 10:08:32 martin
* Include stdlib.h.
+ * Cleaned up handling of pragma pack().
* Revision 1.16 2009/08/14 10:11:53Z daniel
* New version code 306, compatibility version still 110.
* Revision 1.15 2009/06/09 08:57:47Z daniel
@@ -56,6 +60,7 @@
/* Other headers to be included */
#include <mbg_tgt.h>
+#include <timeutil.h>
#include <use_pack.h>
#include <pcpsdefs.h>
#include <mbggeo.h>
@@ -64,14 +69,13 @@
#include <stdlib.h>
-#define MBGUTIL_VERSION 0x0306
+#define MBGUTIL_VERSION 0x0400
#define MBGUTIL_COMPAT_VERSION 0x0110
#if defined( MBG_TGT_WIN32 )
- #include <windows.h>
#elif defined( MBG_TGT_LINUX )
@@ -104,24 +108,11 @@
#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 ) \
@@ -133,38 +124,449 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
+ /**
+ * @brief Get the DLL/shared library's version code
+ *
+ * @return The version code at which the library was built
+ */
_MBG_API_ATTR int _MBG_API mbgutil_get_version( void ) ;
+
+ /**
+ * @brief Check the DLL/shared library's compatibility
+ *
+ * @param[in] header_version Version code defined in the header file when the application is built
+ *
+ * @return ::MBG_SUCCESS if compatible, else ::MBG_ERR_LIB_NOT_COMPATIBLE
+ */
_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, ... ) ;
+
+ /**
+ * @brief A portable, safe implementation of snprintf()
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ * For a detailed description see ::vsnprintf_safe
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ... Variable argument list according to the format string
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ */
+ _MBG_API_ATTR int __attribute__( ( format( printf, 3, 4 ) ) ) _MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... ) ;
+
+ /**
+ * @brief A portable, safe implementation of strncpy()
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the destination string buffer
+ * @param[in] max_len Size of the destination string buffer
+ * @param[in] src Pointer to the source string buffer
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_strncpy( char *s, size_t max_len, const char *src ) ;
+
+ /**
+ * @brief Write a character multiple times to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] c The character to write to the output buffer
+ * @param[in] n The number of characters to write to the output buffer
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_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 ) ;
+
+ /**
+ * @brief Write a short date string "dd.mm." to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] mday Day-of-month number, 1..31
+ * @param[in] month Month number, 1..12
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len, int mday, int month ) ;
+
+ /**
+ * @brief Write a date string "dd.mm.yyyy" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] mday Day-of-month number, 1..31
+ * @param[in] month Month number, 1..12
+ * @param[in] year Year number
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len, int mday, int month, int year ) ;
+
+ /**
+ * @brief Write a short time string "hh:mm" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len, int hour, int min ) ;
+
+ /**
+ * @brief Write a time string "hh:mm:ss" to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ * @param[in] sec Seconds number, 0..59, or 60 in case of leap second
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_time( char *s, int max_len, int hour, int min, int sec ) ;
+
+ /**
+ * @brief Write a long time string "hh:mm:ss.cc" to a string buffer
+ *
+ * Include 100ths of seconds.
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] hour Hours number, 0..23
+ * @param[in] min Minutes number, 0..59
+ * @param[in] sec Seconds number, 0..59, or 60 in case of leap second
+ * @param[in] sec100 Hundreths of seconds, 0..99
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_time_long( char *s, int max_len, int hour, int min, int sec, int sec100 ) ;
+
+ /**
+ * @brief Write a full date and time string to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::TM_GPS structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_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 ) ;
+
+ /**
+ * @brief Write the short date given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len, const PCPS_TIME *pt ) ;
+
+ /**
+ * @brief Write the date given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len, const PCPS_TIME *pt ) ;
+
+ /**
+ * @brief Write the short time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time_short( char *s, int max_len, const PCPS_TIME *pt ) ;
+
+ /**
+ * @brief Write the time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time( char *s, int max_len, const PCPS_TIME *pt ) ;
+
+ /**
+ * @brief Write the time including sec100ths given as ::PCPS_TIME structure to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_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 ) ;
+
+ /**
+ * @brief Write date and time given as ::PCPS_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_TIME structure providing date and time
+ * @param[in] tz_str Optional time zone string to be appended, currently not used, may be NULL
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len, const PCPS_TIME *pt, const char *tz_str ) ;
+
+ /**
+ * @brief Write date derived from seconds-since-epoch to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] sec Number of seconds since the epoch to be converted to date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len, uint32_t sec ) ;
+
+ /**
+ * @brief Write time derived from seconds-since-epoch to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] sec Number of seconds since the epoch to be converted to date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len, uint32_t sec ) ;
+
+ /**
+ * @brief Write UTC date and time given as ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Write local date and time given as ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The number of space characters between date and time
+ * is determined by the global variable ::mbg_date_time_dist.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Print binary ::PCPS_FRAC_32 fractions in decimal to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] frac Binary fractions of a second in ::PCPS_FRAC_32 format
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len, uint32_t frac ) ;
+
+ /**
+ * @brief Print the UTC offset from a ::PCPS_HR_TIME structure to a string buffer
+ *
+ * The output format is sign - hours - minutes, e.g. "+01:45h".
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date, and UTC offset
+ * @param[in] info An informational text to be prepended
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _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 ) ;
+
+ /**
+ * @brief Write a high resolution UTC time stamp including fractions to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Write a high resolution local time stamp including fractions to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Write a raw high resolution time stamp to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len, const PCPS_TIME_STAMP *pt ) ;
+
+ /**
+ * @brief Write a raw high resolution time stamp plus converted local time to a string buffer
+ *
+ * The output string also has the time status code appended as hex number.
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure providing date and time
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Write time capture / user capture time stamp to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pt Pointer to a ::PCPS_HR_TIME structure containing a user capture event
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len, const PCPS_HR_TIME *pt ) ;
+
+ /**
+ * @brief Write a geographic coordinate in degrees - minutes - seconds to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] pdms Pointer to a ::DMS structure containing the coordinate
+ * @param[in] prec Number of digits of the geographic seconds after the decimal separator
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len, const DMS *pdms, int prec ) ;
+
+ /**
+ * @brief Write a position's altitude parameter to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] alt The altitude parameter, in meters
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_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 ) ;
+
+ /**
+ * @brief Write geographic coordinates to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] ppos Pointer to a ::POS structure containing the coordinates
+ * @param[in] prec Number of digits of the geographic seconds after the decimal separator
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len, const POS *ppos, int prec ) ;
+
+ /**
+ * @brief Write device info to a string buffer
+ *
+ * The output string buffer is in any case properly terminated by 0.
+ *
+ * @param[out] s Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer
+ * @param[in] short_name Short device name, e.g. in ::MBG_DEV_NAME format
+ * @param[in] fw_rev_num The firmware revision number
+ * @param[in] asic_ver_num The ASIC version number
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
+ _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_ver_num ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/myutil.h b/src/external/bsd/meinberg/dist/mbglib/common/myutil.h
index 7e6b901..aad15f1 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/myutil.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/myutil.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: myutil.h 1.14 2011/02/16 14:02:35 martin REL_M $
+ * $Id: myutil.h 1.20 2017/03/22 15:09:03 andre.hartmann REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,18 @@
*
* -----------------------------------------------------------------------
* $Log: myutil.h $
+ * Revision 1.20 2017/03/22 15:09:03 andre.hartmann
+ * added macros for lin. interpolation
+ * Revision 1.19 2017/01/27 12:24:08Z martin
+ * Moved STRINGIFY() macro to words.h.
+ * Revision 1.18 2014/10/20 12:30:38 martin
+ * Moved macro _isdigit() to words.h.
+ * Revision 1.17 2014/07/15 06:19:48Z andre
+ * added function _sgn( _x ), returns sign of _x
+ * Revision 1.16 2013/12/16 13:32:57Z martin
+ * Don't redefine MIN and MAX.
+ * Revision 1.15 2012/10/02 18:51:52 martin
+ * Updated handling of pragma pack().
* Revision 1.14 2011/02/16 14:02:35 martin
* Added STRINGIFY() macro.
* Revision 1.13 2010/12/13 15:59:39 martin
@@ -66,26 +78,12 @@
/* Start of header body */
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
#endif
-// The two macros below can be used to define a constant string on the
-// compiler's command line, e.g. like -DVERSION_STRING="v1.0 BETA".
-// Source code like
-// const char version_string[] = VERSION_STRING;
-// may not work for every compiler since the double quotes
-// in VERSION_STRING may be removed when the definition is evaluated.
-// A proper solution is to use the STRINGIFY() macro below:
-// const char version_string[] = STRINGIFY( VERSION_STRING );
-// The XSTRINGIFY() macro is simply a helper macro which should not
-// be used alone.
-#define STRINGIFY(x) XSTRINGIFY(x)
-#define XSTRINGIFY(x) #x
-
-
-
#if MBG_TGT_HAS_64BIT_TYPES
#define _frac( _x ) ( ( (_x) == 0.0 ) ? 0.0 : ( (_x) - (double) ( (int64_t) (_x) ) ) )
#else
@@ -93,12 +91,16 @@
#endif
-#define _isdigit( _c ) ( (_c) >= '0' && (_c) <= '9' )
-
#define _eos( _s ) ( &(_s)[strlen( _s )] )
-#define MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) )
-#define MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) )
+#if !defined( MIN )
+ #define MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) )
+#endif
+
+#if !defined( MAX )
+ #define MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) )
+#endif
+
#define SWAP( _x, _y ) { temp = (_x); (_x) = (_y); (_y) = temp; }
#define SQR( _x ) ( (_x) * (_x) )
@@ -157,6 +159,14 @@ typedef union
#define _is_supported( _i, _msk ) \
( ( (_msk) & _idx_bit( _i ) ) != 0 )
+// return the sign of a number
+#define _sgn( _x ) ( ( ( _x ) < 0 ) ? -1 : 1 )
+
+
+// macro for linear interpolation y = _m * x + _b between two points ( X1; Y1 ), ( X2; Y2 )
+#define _m( _Y1, _X1, _Y2, _X2 ) ( ( _Y2 -_Y1 ) / ( _X2 -_X1 ) )
+#define _b( _Y1, _X1, _Y2, _X2 ) ( ( ( _Y1 * _X2 ) - ( _Y2 * _X1 ) ) / ( _X2 -_X1 ) )
+
/*
* The macro below copies a string, taking care not to
@@ -208,8 +218,9 @@ extern "C" {
#endif
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
#endif
/* End of header body */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/nanotime.c b/src/external/bsd/meinberg/dist/mbglib/common/nanotime.c
new file mode 100755
index 0000000..43cf863
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/nanotime.c
@@ -0,0 +1,312 @@
+
+/**************************************************************************
+ *
+ * $Id: nanotime.c 1.2 2017/06/12 13:54:04 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg Library module providing functions to handle NANO_TIME
+ * and NANO_TIME_64.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: nanotime.c $
+ * Revision 1.2 2017/06/12 13:54:04 martin
+ * Fixed build under Windows.
+ * Revision 1.1 2017/06/12 08:49:09Z martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _NANOTIME
+ #include <nanotime.h>
+#undef _NANOTIME
+
+#include <mbgtime.h>
+#include <str_util.h>
+
+#include <stdlib.h>
+
+
+// At least MSVC++ 9.0 / Visual Studio 2008 or older
+// doesn't provide strtoll()
+#if defined( _MSC_VER ) && ( _MSC_VER <= 1500 )
+ #define strtoll _strtoi64
+#endif
+
+
+/*HDR*/
+/**
+ * @brief Convert a ::NANO_TIME time to double
+ *
+ * @param[in] p Address of a ::NANO_TIME structure to be converted
+ *
+ * @return The computed number of seconds with fractions, as double
+ *
+ * @see ::double_to_nano_time
+ */
+double nano_time_to_double( const NANO_TIME *p )
+{
+ double d = p->secs;
+
+ d += ( (double) p->nano_secs ) / 1e9;
+
+ return d;
+
+} // nano_time_to_double
+
+
+
+/*HDR*/
+/**
+ * @brief Setup a ::NANO_TIME structure from a time provided as double
+ *
+ * @param[out] p Address of a ::NANO_TIME structure to be set up
+ * @param[in] d The time to be converted, in seconds with fractions, as double
+ *
+ * @see ::nano_time_to_double
+ */
+void double_to_nano_time( NANO_TIME *p, double d )
+{
+ p->secs = (int32_t) d;
+
+ d -= (double) p->secs;
+
+ p->nano_secs = (int32_t) ( d * 1e9 );
+
+} // double_to_nano_time
+
+
+
+/*HDR*/
+/**
+ * @brief Print nano time into string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] nt The ::NANO_TIME to be printed
+ */
+size_t snprint_nano_time( char *s, size_t max_len, const NANO_TIME *nt )
+{
+ size_t n = snprintf_safe( s, max_len, "%c%li.%09li",
+ _nano_time_negative( nt ) ? '-' : '+',
+ labs( (long) nt->secs ),
+ labs( (long) nt->nano_secs ) );
+ return n;
+
+} // snprint_nano_time
+
+
+
+#if !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+/*HDR*/
+/**
+ * @brief Normalize a ::NANO_TIME_64 time
+ *
+ * After normalization, the following can be assumed:<br>
+ * - nano_secs is in the range [-10^9 + 1, 10^9 - 1]<br>
+ * - if secs is not 0, secs and nano_secs have the same sign
+ *
+ * @param[in,out] nt The ::NANO_TIME_64 to be normalized
+ */
+void normalize_nano_time_64( NANO_TIME_64 *nt )
+{
+ int64_t additional_secs;
+
+ // Step 1: Make sure nano seconds are in the interval [-10^9 + 1, 10^9 - 1]
+ additional_secs = nt->nano_secs / NSECS_PER_SEC;
+ nt->nano_secs -= additional_secs * NSECS_PER_SEC;
+ nt->secs += additional_secs;
+
+ // Step 2: Make sure seconds and nanoseconds have same sign if seconds is not 0
+ if ( nt->secs > 0 && nt->nano_secs < 0 )
+ {
+ nt->secs -= 1;
+ nt->nano_secs += NSECS_PER_SEC;
+ }
+ else if ( nt->secs < 0 && nt->nano_secs > 0 )
+ {
+ nt->secs += 1;
+ nt->nano_secs -= NSECS_PER_SEC;
+ }
+
+} // normalize_nano_time_64
+
+
+
+/*HDR*/
+/**
+ * @brief Convert a ::NANO_TIME_64 time to double
+ *
+ * @param[in] p Address of a ::NANO_TIME_64 structure to be converted
+ *
+ * @return The computed number of seconds with fractions, as double
+ *
+ * @see ::double_to_nano_time_64
+ */
+double nano_time_64_to_double( const NANO_TIME_64 *p )
+{
+ double d = (double) p->secs;
+
+ d += ( (double) p->nano_secs ) / 1e9;
+
+ return d;
+
+} // nano_time_64_to_double
+
+
+
+/*HDR*/
+/**
+ * @brief Setup a ::NANO_TIME_64 structure from a time as double
+ *
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ * @param[in] d The time to be converted, in seconds with fractions, as double
+ *
+ * @see ::nano_time_64_to_double
+ */
+void double_to_nano_time_64( NANO_TIME_64 *p, double d )
+{
+ p->secs = (int32_t) d;
+
+ d -= (double) p->secs;
+
+ p->nano_secs = (int32_t) ( d * 1e9 );
+
+} // double_to_nano_time_64
+
+
+
+/*HDR*/
+/**
+ * @brief Print a normalized ::NANO_TIME_64 into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] nt The ::NANO_TIME_64 to be printed
+ */
+size_t snprint_nano_time_64( char *s, size_t max_len, const NANO_TIME_64 *nt )
+{
+ size_t n = snprintf_safe( s, max_len, "%c%" PRId64 ".%09" PRId64,
+ _nano_time_negative( nt ) ? '-' : '+',
+ _abs64( nt->secs ),
+ _abs64( nt->nano_secs ) );
+ return n;
+
+} // snprint_nano_time_64
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Generic function to set up a ::NANO_TIME_64 structure from a string
+ *
+ * @param[in] s A string with a time in seconds, with fractions separated by decimal point
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ * @param[in] base The base of the conversion, i.e. 10 for a string with decimal numbers, or 16 for a hex string
+ * @param[in] frac_digits The number of fractions required to represent 1 nanosecond, e.g.
+ * 9 for a decimal string like 0.000000001, or
+ * TODO for a hex string like 0x00000000.00000000
+ */
+void str_to_nano_time_64( const char *s, NANO_TIME_64 *p, int base, int frac_digits )
+{
+ char *cp = NULL;
+
+ p->secs = strtoll( s, &cp, base );
+
+ if ( *cp == '.' ) // fractions may follow
+ {
+ char *ep = NULL;
+
+ cp++; // skip '.'
+
+ p->nano_secs = strtoll( cp, &ep, base );
+
+ if ( p->nano_secs ) // only if fractions not 0
+ {
+ int l = ep - cp;
+
+ while ( l < frac_digits )
+ {
+ p->nano_secs *= base;
+ l++;
+ }
+
+ while ( l > frac_digits )
+ {
+ p->nano_secs /= base;
+ l--;
+ }
+
+ if ( p->secs < 0 )
+ p->nano_secs = -p->nano_secs;
+ }
+ }
+
+} // str_to_nano_time_64
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Generic function to divide ::NANO_TIME_64 value
+ *
+ * @param[in,out] p Address of a ::NANO_TIME_64 structure to be divided
+ * @param[in] div The number by which to divide
+ * @param[in] mul The complementary number to div, i.e. mul = 1000000000 / div
+ */
+void div_nano_time_64( NANO_TIME_64 *p, long div, long mul )
+{
+ // At least MSVC++ 9.0 / Visual Studio 2008 or older
+ // doesn't provide lldiv_t and lldiv().
+ #if defined( _MSC_VER ) && ( _MSC_VER <= 1500 ) //### TODO: Test this code
+ int64_t rem = p->secs % div;
+ p->secs /= div;
+ p->nano_secs = ( rem * mul ) + ( p->nano_secs / div );
+ #else
+ lldiv_t lldt = lldiv( p->secs, div );
+ p->secs = lldt.quot;
+ p->nano_secs = ( lldt.rem * mul ) + ( p->nano_secs / div );
+ #endif
+
+} // div_nano_time_64
+
+
+
+/*HDR*/
+/**
+ * @brief Set up a ::NANO_TIME_64 structure from a string with a time in seconds and fractions
+ *
+ * @param[in] s A string with a time in seconds, with fractions separated by decimal point
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ */
+void str_s_to_nano_time_64( const char *s, NANO_TIME_64 *p )
+{
+ str_to_nano_time_64( s, p, 10, 9 );
+
+} // str_s_to_nano_time_64
+
+
+
+/*HDR*/
+/**
+ * @brief Set up a ::NANO_TIME_64 structure from a string with a time in milliseconds and fractions
+ *
+ * @param[in] s A string with a time in milliseconds, with fractions separated by decimal point
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ */
+void str_ms_to_nano_time_64( const char *s, NANO_TIME_64 *p )
+{
+ // First do the same conversion as for a string representing seconds
+ str_s_to_nano_time_64( s, p );
+
+ // Now we have the value in milliseconds
+ // Divide by 1000 to get seconds
+ div_nano_time_64( p, 1000, 1000000UL );
+
+} // str_ms_to_nano_time_64
+
+#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES )
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/nanotime.h b/src/external/bsd/meinberg/dist/mbglib/common/nanotime.h
new file mode 100755
index 0000000..85963a6
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/nanotime.h
@@ -0,0 +1,148 @@
+
+/**************************************************************************
+ *
+ * $Id: nanotime.h 1.1 2017/06/12 08:49:09 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for nanotime.c
+ *
+ * -----------------------------------------------------------------------
+ * $Log: nanotime.h $
+ * Revision 1.1 2017/06/12 08:49:09 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _NANOTIME_H
+#define _NANOTIME_H
+
+/* Other headers to be included */
+
+#include <words.h> // implicitly includes mbg_tgt.h, if required,
+ // and defines some basic structures
+
+#ifdef _NANOTIME
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Convert a ::NANO_TIME time to double
+ *
+ * @param[in] p Address of a ::NANO_TIME structure to be converted
+ *
+ * @return The computed number of seconds with fractions, as double
+ *
+ * @see ::double_to_nano_time
+ */
+ double nano_time_to_double( const NANO_TIME *p ) ;
+
+ /**
+ * @brief Setup a ::NANO_TIME structure from a time provided as double
+ *
+ * @param[out] p Address of a ::NANO_TIME structure to be set up
+ * @param[in] d The time to be converted, in seconds with fractions, as double
+ *
+ * @see ::nano_time_to_double
+ */
+ void double_to_nano_time( NANO_TIME *p, double d ) ;
+
+ /**
+ * @brief Print nano time into string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] nt The ::NANO_TIME to be printed
+ */
+ size_t snprint_nano_time( char *s, size_t max_len, const NANO_TIME *nt ) ;
+
+ /**
+ * @brief Normalize a ::NANO_TIME_64 time
+ *
+ * After normalization, the following can be assumed:<br>
+ * - nano_secs is in the range [-10^9 + 1, 10^9 - 1]<br>
+ * - if secs is not 0, secs and nano_secs have the same sign
+ *
+ * @param[in,out] nt The ::NANO_TIME_64 to be normalized
+ */
+ void normalize_nano_time_64( NANO_TIME_64 *nt ) ;
+
+ /**
+ * @brief Convert a ::NANO_TIME_64 time to double
+ *
+ * @param[in] p Address of a ::NANO_TIME_64 structure to be converted
+ *
+ * @return The computed number of seconds with fractions, as double
+ *
+ * @see ::double_to_nano_time_64
+ */
+ double nano_time_64_to_double( const NANO_TIME_64 *p ) ;
+
+ /**
+ * @brief Setup a ::NANO_TIME_64 structure from a time as double
+ *
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ * @param[in] d The time to be converted, in seconds with fractions, as double
+ *
+ * @see ::nano_time_64_to_double
+ */
+ void double_to_nano_time_64( NANO_TIME_64 *p, double d ) ;
+
+ /**
+ * @brief Print a normalized ::NANO_TIME_64 into a string buffer
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] nt The ::NANO_TIME_64 to be printed
+ */
+ size_t snprint_nano_time_64( char *s, size_t max_len, const NANO_TIME_64 *nt ) ;
+
+ /**
+ * @brief Set up a ::NANO_TIME_64 structure from a string with a time in seconds and fractions
+ *
+ * @param[in] s A string with a time in seconds, with fractions separated by decimal point
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ */
+ void str_s_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;
+
+ /**
+ * @brief Set up a ::NANO_TIME_64 structure from a string with a time in milliseconds and fractions
+ *
+ * @param[in] s A string with a time in milliseconds, with fractions separated by decimal point
+ * @param[out] p Address of a ::NANO_TIME_64 structure to be set up
+ */
+ void str_ms_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _NANOTIME_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.c b/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.c
new file mode 100755
index 0000000..4be1d30
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.c
@@ -0,0 +1,93 @@
+
+/**************************************************************************
+ *
+ * $Id: ntp_shm.c 1.2 2017/07/05 16:49:00 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * NTP shared memory support functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: ntp_shm.c $
+ * Revision 1.2 2017/07/05 16:49:00 martin
+ * Patch submitted by <juergen.perlinger@t-online.de>:
+ * Support number of the first SHM unit to use.
+ * This intentionally changes the prototype for ntpshm_init().
+ * Revision 1.1 2012/05/29 09:54:15 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _NTP_SHM
+ #include <ntp_shm.h>
+#undef _NTP_SHM
+
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+
+
+
+/*HDR*/
+struct shmTime *getShmTime( int unit )
+{
+ struct shmTime *p;
+
+ int shmid = shmget( (key_t) ( NTPD_BASE + unit ),
+ sizeof( struct shmTime ), IPC_CREAT | 0644 );
+
+ if ( shmid == -1 )
+ {
+ syslog( LOG_ERR, "shmget %i failed: %s", unit, strerror( errno ) );
+ return NULL;
+ }
+
+
+ p = (struct shmTime *) shmat( shmid, 0, 0 );
+
+ if ( (long) p == -1L )
+ {
+ syslog( LOG_ERR, "shmat %i failed: %s", unit, strerror( errno ) );
+ return NULL;
+ }
+
+ return p;
+
+} // getShmTime
+
+
+
+/*HDR*/
+int ntpshm_init( struct shmTime **shmTime, int n_units, int n_unit0 )
+{
+ int i;
+ int ret_val = 0;
+
+ for ( i = 0; i < n_units; i++ )
+ {
+ int u = i + n_unit0;
+ struct shmTime *p = getShmTime( u );
+ shmTime[i] = p;
+
+ if ( p == NULL )
+ {
+ syslog( LOG_WARNING, "** Failed to initialize NTP SHM unit %i", u );
+ ret_val = -1;
+ continue;
+ }
+
+ memset( p, 0, sizeof( *p ) );
+
+ p->mode = 1;
+ p->precision = -5; /* initially 0.5 sec */
+ p->nsamples = 3; /* stages of median filter */
+
+ syslog( LOG_INFO, "NTP SHM unit %i initialized successfully", u );
+ }
+
+ return ret_val;
+
+} // ntpshm_init
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.h b/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.h
new file mode 100755
index 0000000..2cefc00
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ntp_shm.h
@@ -0,0 +1,151 @@
+
+/**************************************************************************
+ *
+ * $Id: ntp_shm.h 1.3 2017/07/05 16:52:25 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for ntp_shm.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: ntp_shm.h $
+ * Revision 1.3 2017/07/05 16:52:25 martin
+ * Defined MAX_SHM_UNIT_OFFSET.
+ * Doxygen changes and fixes.
+ * Updated function prototypes.
+ * Revision 1.2 2013/01/02 10:23:41 daniel
+ * Added nsec support
+ * Revision 1.1 2012/05/29 09:54:15 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _NTP_SHM_H
+#define _NTP_SHM_H
+
+
+/* Other headers to be included */
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+
+#ifdef _NTP_SHM
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if 0 && defined( _USE_PACK ) // use default alignment
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup group_ntp_defs NTP interface definitions
+ *
+ * @note These definitions have been copied from the NTP source code (http://www.ntp.org)
+ *
+ * @{ */
+
+/**
+ * @brief Structure of NTP's shared memory segment
+ */
+struct shmTime
+{
+ int mode; /* 0 - if valid set
+ * use values,
+ * clear valid
+ * 1 - if valid set
+ * if count before and after read of
+ * values is equal,
+ * use values
+ * clear valid
+ */
+ int count;
+ time_t clockTimeStampSec; /* external clock */
+ int clockTimeStampUSec; /* external clock */
+ time_t receiveTimeStampSec; /* internal clock, when external value was received */
+ int receiveTimeStampUSec; /* internal clock, when external value was received */
+ int leap; ///< see @ref NTP_LEAP_BITS
+ int precision;
+ int nsamples;
+ int valid;
+ unsigned clockTimeStampNSec; /* unsigned ns timestamps */
+ unsigned receiveTimeStampNSec;
+ int dummy[8];
+};
+
+/**
+ * @defgroup NTP_LEAP_BITS NTP Leap Bits
+ *
+ * @note This describes NTP leap bits
+ *
+ * @{ */
+
+#define LEAP_NOWARNING 0x0 /**< normal, no leap second warning */
+#define LEAP_ADDSECOND 0x1 /**< last minute of day has 61 seconds */
+#define LEAP_DELSECOND 0x2 /**< last minute of day has 59 seconds */
+#define LEAP_NOTINSYNC 0x3 /**< overload, clock is free running */
+
+/** @} defgroup NTP_LEAP_BITS */
+
+
+/**
+ * @brief Number of units (refclocks) supported by the SMH segment
+ */
+#define MAX_SHM_REFCLOCKS 4
+
+
+/**
+ * @brief Max. Number of SHM unit offset
+ */
+#define MAX_SHM_UNIT_OFFSET 128
+
+
+/**
+ * @brief Basic SHM unit identifier (unit 0)
+ */
+#define NTPD_BASE 0x4e545030 ///< "NTP0"
+
+/** @} defgroup group_ntp_defs */
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ struct shmTime *getShmTime( int unit ) ;
+ int ntpshm_init( struct shmTime **shmTime, int n_units, int n_unit0 ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _NTP_SHM_H */
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/parmgps.c b/src/external/bsd/meinberg/dist/mbglib/common/parmgps.c
deleted file mode 100755
index 44e620b..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/common/parmgps.c
+++ /dev/null
@@ -1,242 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: parmgps.c 1.5 2008/10/21 10:47:26 martin REL_M $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * Functions to handle/convert Meinberg GPS specific parameters.
- *
- * -----------------------------------------------------------------------
- * $Log: parmgps.c $
- * Revision 1.5 2008/10/21 10:47:26 martin
- * Renamed check_port_info() to check_valid_port_info()
- * to avoid naming conflicts.
- * Revision 1.4 2008/09/15 14:11:25 martin
- * New function check_port_info() which returns a bit mask indicating
- * which fields of a PORT_SETTINGS structure are not valid.
- * This is based on code taken from valid_port_info(), which now calls
- * check_port_info() and returns a value compatible to the earlier version.
- * Revision 1.3 2004/11/09 14:21:36 martin
- * Redefined some data types using C99 fixed-size definitions.
- * Revision 1.2 2002/02/19 13:30:23Z MARTIN
- * Bug fix in port_settings_from_port_parm_mode().
- * Revision 1.1 2002/01/30 10:30:26 MARTIN
- * Initial revision
- *
- **************************************************************************/
-
-#define _PARMGPS
- #include <parmgps.h>
-#undef _PARMGPS
-
-#include <myutil.h>
-#include <string.h>
-
-
-
-/*HDR*/
-int get_str_idx( const char *search,
- const char *str_table[],
- int n_entries )
-{
- int i;
-
- for ( i = 0; i < n_entries; i++ )
- if ( strcmp( search, str_table[i] ) == 0 )
- return i;
-
- return -1;
-
-} // get_str_idx
-
-
-
-/*HDR*/
-int get_baud_rate_idx( BAUD_RATE baud_rate )
-{
- int i;
-
- for ( i = 0; i < N_MBG_BAUD_RATES; i++ )
- if ( baud_rate == mbg_baud_rate[i] )
- return i;
-
- return -1;
-
-} // get_baud_rate_idx
-
-
-
-/*HDR*/
-int get_framing_idx( const char *framing )
-{
- return get_str_idx( framing, mbg_framing_str, N_MBG_FRAMINGS );
-
-} // get_framing_idx
-
-
-
-/*HDR*/
-void port_settings_from_port_parm_mode(
- PORT_SETTINGS *p_ps,
- uint8_t pp_mode,
- int str_type_cap
- )
-{
- if ( pp_mode >= STR_UCAP )
- {
- p_ps->str_type = str_type_cap;
- p_ps->mode = ( pp_mode == STR_UCAP ) ? STR_AUTO : STR_ON_REQ;
- }
- else
- {
- p_ps->str_type = 0;
- p_ps->mode = pp_mode;
- }
-
-} // port_settings_from_port_parm_mode
-
-
-
-/*HDR*/
-void port_parm_mode_from_port_settings(
- uint8_t *pp_mode,
- const PORT_SETTINGS *p_ps,
- int str_type_cap
- )
-{
- if ( p_ps->str_type == str_type_cap )
- *pp_mode = ( p_ps->mode == STR_ON_REQ ) ? STR_UCAP_REQ : STR_UCAP;
- else
- *pp_mode = p_ps->mode;
-
-} // port_parm_mode_from_port_settings
-
-
-
-/*HDR*/
-void port_settings_from_port_parm(
- PORT_SETTINGS *p_ps,
- int port_num,
- const PORT_PARM *p_pp,
- int cap_str_idx
-)
-{
- p_ps->parm = p_pp->com[port_num];
-
- port_settings_from_port_parm_mode( p_ps, p_pp->mode[port_num],
- cap_str_idx );
-
-} // port_info_from_port_parm
-
-
-
-/*HDR*/
-void port_parm_from_port_settings(
- PORT_PARM *p_pp,
- int port_num,
- const PORT_SETTINGS *p_ps,
- int cap_str_idx
-)
-{
- p_pp->com[port_num] = p_ps->parm;
-
- port_parm_mode_from_port_settings( &p_pp->mode[port_num],
- p_ps, cap_str_idx );
-
-} // port_parm_from_port_settings
-
-
-
-/*HDR*/
-int check_valid_port_info( const PORT_INFO *p_pi,
- const STR_TYPE_INFO_IDX str_type_info_idx[],
- int n_str_type )
-
-{
- const PORT_SETTINGS *p_ps = &p_pi->port_settings;
- int idx;
- int flags = 0;
-
-
- if ( p_pi->supp_baud_rates & ~_mask( N_MBG_BAUD_RATES ) )
- flags |= MBG_PS_MSK_BAUD_RATE_OVR_SW; // dev. supports more baud rates than driver
-
- idx = get_baud_rate_idx( p_ps->parm.baud_rate );
-
- if ( !_inrange( idx, 0, N_MBG_BAUD_RATES ) ||
- !_is_supported( idx, p_pi->supp_baud_rates ) )
- flags |= MBG_PS_MSK_BAUD_RATE;
-
-
- if ( p_pi->supp_framings & ~_mask( N_MBG_FRAMINGS ) )
- flags |= MBG_PS_MSK_FRAMING_OVR_SW; // dev. supports more framings than driver
-
- idx = get_framing_idx( p_ps->parm.framing );
-
- if ( !_inrange( idx, 0, N_MBG_FRAMINGS ) ||
- !_is_supported( idx, p_pi->supp_framings ) )
- flags |= MBG_PS_MSK_FRAMING;
-
-
- if ( p_ps->parm.handshake >= N_COM_HS )
- flags |= MBG_PS_MSK_HS_OVR_SW; // handshake index exceeds max.
-
- if ( p_ps->parm.handshake != HS_NONE ) // currently no device supports any handshake
- flags |= MBG_PS_MSK_HS; // handshake mode not supp. by dev.
-
-
- if ( p_pi->supp_str_types & ~_mask( n_str_type ) )
- flags |= MBG_PS_MSK_STR_TYPE_OVR_SW; // firmware error: more string types supported than reported
-
- idx = p_ps->str_type;
-
- if ( idx >= n_str_type )
- flags |= MBG_PS_MSK_STR_TYPE_OVR_DEV; // string type index exceeds max.
- else
- {
- if ( !_is_supported( idx, p_pi->supp_str_types ) )
- flags |= MBG_PS_MSK_STR_TYPE; // string type not supported by this port
- else
- {
- // Use the str_type index to get the supported output mode mask
- // from the string type info table. This is required to check
- // whether the selected mode is supported by the selected
- // string type.
- ulong supp_modes = str_type_info_idx[idx].str_type_info.supp_modes;
-
- if ( supp_modes & ~_mask( N_STR_MODE ) )
- flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // dev. supports more string modes than driver
-
- idx = p_ps->mode;
-
- if ( idx >= N_STR_MODE ) // mode is always >= 0
- flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // string mode index exceeds max.
- else
- if ( !_is_supported( idx, supp_modes ) )
- flags |= MBG_PS_MSK_STR_MODE; // string mode not supp. by this string type and port
- }
- }
-
-
- if ( p_ps->flags != 0 ) /* currently always 0 */
- flags |= MBG_PS_MSK_FLAGS_OVR_SW | MBG_PS_MSK_FLAGS;
-
-
- return flags;
-
-} // check_valid_port_info
-
-
-
-/*HDR*/
-int valid_port_info( const PORT_INFO *p_pi,
- const STR_TYPE_INFO_IDX str_type_info_idx[],
- int n_str_type )
-{
- return check_valid_port_info( p_pi, str_type_info_idx, n_str_type ) == 0;
-
-} // valid_port_info
-
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/parmgps.h b/src/external/bsd/meinberg/dist/mbglib/common/parmgps.h
deleted file mode 100755
index 46d28fc..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/common/parmgps.h
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: parmgps.h 1.7 2011/02/16 10:12:13 martin TEST $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * Definitions and prototypes for parmgps.c.
- *
- * -----------------------------------------------------------------------
- * $Log: parmgps.h $
- * Revision 1.7 2011/02/16 10:12:13 martin
- * Fixed macro syntax for _setup_default_receiver_info_gps().
- * Revision 1.6 2008/10/21 10:41:09Z martin
- * Renamed check_port_info() to check_valid_port_info()
- * to avoid naming conflicts.
- * Revision 1.5 2008/09/10 16:22:32 martin
- * Updated function prototypes.
- * Revision 1.4 2004/11/09 14:22:34 martin
- * Updated function prototypes.
- * Revision 1.3 2004/05/19 07:50:16Z martin
- * Use symbolic constant as initializer.
- * Revision 1.2 2004/04/14 09:21:23Z martin
- * Pack structures 1 byte aligned.
- * Revision 1.1 2002/01/30 10:33:38Z MARTIN
- * Initial revision
- *
- **************************************************************************/
-
-#ifndef _PARMGPS_H
-#define _PARMGPS_H
-
-
-/* Other headers to be included */
-
-#include <gpsdefs.h>
-#include <use_pack.h>
-
-
-#ifdef _PARMGPS
- #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
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define DEFAULT_N_STR_TYPE_GPS 2
-
-#define DEFAULT_SUPP_STR_TYPES_GPS \
- ( ( 1UL << DEFAULT_N_STR_TYPE_GPS ) - 1 )
-
-
-/*
- * The macro below can be used to initialize a
- * RECEIVER_INFO structure for old GPS receiver models
- * which don't supply that structure.
- *
- * Parameters: (RECEIVER_INFO *) _p
- */
-#define _setup_default_receiver_info_gps( _p ) \
-do \
-{ \
- memset( (_p), 0, sizeof( *(_p) ) ); \
- \
- (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \
- (_p)->n_ucaps = 2; \
- (_p)->n_com_ports = DEFAULT_N_COM; \
- (_p)->n_str_type = DEFAULT_N_STR_TYPE_GPS; \
-} while ( 0 )
-
-
-_ext BAUD_RATE mbg_baud_rate[N_MBG_BAUD_RATES]
-#ifdef _DO_INIT
- = MBG_BAUD_RATES
-#endif
-;
-
-_ext const char *mbg_baud_str[N_MBG_BAUD_RATES]
-#ifdef _DO_INIT
- = MBG_BAUD_STRS
-#endif
-;
-
-_ext const char *mbg_framing_str[N_MBG_FRAMINGS]
-#ifdef _DO_INIT
- = MBG_FRAMING_STRS
-#endif
-;
-
-
-/* ----- function prototypes begin ----- */
-
-/* This section was generated automatically */
-/* by MAKEHDR, do not remove the comments. */
-
- int get_str_idx( const char *search, const char *str_table[], int n_entries ) ;
- int get_baud_rate_idx( BAUD_RATE baud_rate ) ;
- int get_framing_idx( const char *framing ) ;
- void port_settings_from_port_parm_mode( PORT_SETTINGS *p_ps, uint8_t pp_mode, int str_type_cap ) ;
- void port_parm_mode_from_port_settings( uint8_t *pp_mode, const PORT_SETTINGS *p_ps, int str_type_cap ) ;
- void port_settings_from_port_parm( PORT_SETTINGS *p_ps, int port_num, const PORT_PARM *p_pp, int cap_str_idx ) ;
- void port_parm_from_port_settings( PORT_PARM *p_pp, int port_num, const PORT_SETTINGS *p_ps, int cap_str_idx ) ;
- int check_valid_port_info( const PORT_INFO *p, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ;
- int valid_port_info( const PORT_INFO *p, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ;
-
-/* ----- 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 /* _PARMGPS_H */
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.c b/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.c
deleted file mode 100755
index cd02754..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.c
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: parmpcps.c 1.4 2004/11/09 14:24:15 martin REL_M $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * Functions to handle/convert parameters used by Meinberg plug-in
- * radio clocks.
- *
- * -----------------------------------------------------------------------
- * $Log: parmpcps.c $
- * Revision 1.4 2004/11/09 14:24:15 martin
- * Redefined interface data types using C99 fixed-size definitions.
- * Revision 1.3 2003/04/17 10:43:35Z martin
- * Moved some definitions to parmpcps.h.
- * Removed some functions which are now in mbgdevio.c.
- * Revision 1.2 2002/03/25 09:03:43Z MARTIN
- * Fixed a bug where the wrong framing was configured for DCF77 clocks.
- * Revision 1.1 2002/02/19 14:00:19 MARTIN
- * Initial revision
- *
- **************************************************************************/
-
-#define _PARMPCPS
- #include <parmpcps.h>
-#undef _PARMPCPS
-
-#include <parmgps.h>
-#include <pcpsutil.h>
-#include <myutil.h>
-
-#include <string.h>
-
-
-static const int pcps_to_mbg_framing_tbl[N_PCPS_FR_DCF] =
-{
- MBG_FRAMING_8N1,
- MBG_FRAMING_7E2,
- MBG_FRAMING_8N2,
- MBG_FRAMING_8E1
-};
-
-
-
-/*HDR*/
-void port_info_from_pcps_serial(
- PORT_INFO_IDX *p_pii,
- PCPS_SERIAL pcps_serial,
- uint32_t supp_baud_rates
-)
-{
- PCPS_SER_PACK ser_pack;
- PORT_INFO *p_pi;
- PORT_SETTINGS *p_ps;
-
- ser_pack.pack = pcps_serial;
- pcps_unpack_serial( &ser_pack );
-
- p_pi = &p_pii[0].port_info;
- p_ps = &p_pi->port_settings;
-
- p_ps->parm.baud_rate = mbg_baud_rate[ser_pack.baud];
-
- _strncpy_0( p_ps->parm.framing,
- mbg_framing_str[pcps_to_mbg_framing_tbl[ser_pack.frame]] );
-
- p_ps->parm.handshake = HS_NONE;
-
- p_ps->str_type = 0;
- p_ps->mode = ser_pack.mode;
-
- p_pi->supp_baud_rates = supp_baud_rates;
- p_pi->supp_framings = DEFAULT_FRAMINGS_DCF;
- p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_DCF;
-
-} // port_info_from_pcps_serial
-
-
-/*HDR*/
-void pcps_serial_from_port_info(
- PCPS_SERIAL *p,
- const PORT_INFO_IDX *p_pii
-)
-{
- PCPS_SER_PACK ser_pack;
- const PORT_INFO *p_pi = &p_pii[0].port_info;
- const PORT_SETTINGS *p_ps = &p_pi->port_settings;
- int framing_idx = get_framing_idx( p_ps->parm.framing );
- int i;
-
-
- ser_pack.baud = get_baud_rate_idx( p_ps->parm.baud_rate );
-
- // Translate the common framing index to the corresponding
- // number used with the old PCPS_SERIAL parameter.
- // This should always return a valid result since the
- // framing index is expected to be selected from
- // supported framings.
- for ( i = 0; i < N_PCPS_FR_DCF; i++ )
- if ( pcps_to_mbg_framing_tbl[i] == framing_idx )
- break;
-
- ser_pack.frame = i;
-
- ser_pack.mode = p_ps->mode;
-
- pcps_pack_serial( &ser_pack );
-
- *p = ser_pack.pack;
-
-} // pcps_serial_from_port_info
-
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.h b/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.h
deleted file mode 100755
index 7095d48..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/common/parmpcps.h
+++ /dev/null
@@ -1,159 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: parmpcps.h 1.7 2011/04/01 10:30:51 martin REL_M $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * Definitions and prototypes for parmpcps.c.
- *
- * -----------------------------------------------------------------------
- * $Log: parmpcps.h $
- * Revision 1.7 2011/04/01 10:30:51 martin
- * Fixed macro syntax for _setup_default_receiver_info_dcf().
- * Revision 1.6 2011/02/16 10:13:12 martin
- * Fixed macro syntax for _setup_default_receiver_info_pcps().
- * Revision 1.5 2004/11/09 14:24:58Z martin
- * Updated function prototypes.
- * Revision 1.4 2004/05/19 07:52:25Z martin
- * Fixed macro setting default number of string types.
- * Revision 1.3 2004/04/14 09:21:44Z martin
- * Pack structures 1 byte aligned.
- * Revision 1.2 2003/04/17 10:42:46Z martin
- * Moved typedef RECEIVER_PORT_CFG to pcpsdev.h.
- * Moved some definitions from parmpcps.c here.
- * Removed some global variables.
- * Updated function prototypes.
- * Revision 1.1 2002/02/19 14:00:19Z MARTIN
- * Initial revision
- *
- **************************************************************************/
-
-#ifndef _PARMPCPS_H
-#define _PARMPCPS_H
-
-/* Other headers to be included */
-
-#include <pcpsdev.h>
-#include <use_pack.h>
-
-
-#ifdef _PARMPCPS
- #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
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define DEFAULT_BAUD_RATES_DCF \
-( \
- MBG_PORT_HAS_300 | \
- MBG_PORT_HAS_600 | \
- MBG_PORT_HAS_1200 | \
- MBG_PORT_HAS_2400 | \
- MBG_PORT_HAS_4800 | \
- MBG_PORT_HAS_9600 \
-)
-
-#define DEFAULT_BAUD_RATES_DCF_HS \
-( \
- 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 | \
- MBG_PORT_HAS_38400 \
-)
-
-
-#define DEFAULT_FRAMINGS_DCF \
-( \
- MBG_PORT_HAS_7E2 | \
- MBG_PORT_HAS_8N1 | \
- MBG_PORT_HAS_8N2 | \
- MBG_PORT_HAS_8E1 \
-)
-
-
-#define DEFAULT_N_STR_TYPE_DCF 1
-
-#define DEFAULT_SUPP_STR_TYPES_DCF \
- ( ( 1UL << DEFAULT_N_STR_TYPE_DCF ) - 1 )
-
-
-/*
- * The macro below can be used to initialize a
- * RECEIVER_INFO structure for DCF77 receivers
- * which don't supply that structure.
- *
- * Parameters: (RECEIVER_INFO *) _p
- */
-#define _setup_default_receiver_info_dcf( _p, _pdev ) \
-do \
-{ \
- memset( (_p), 0, sizeof( *(_p) ) ); \
- \
- (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \
- (_p)->n_ucaps = 0; \
- (_p)->n_com_ports = _pcps_has_serial( _pdev ) ? 1 : 0; \
- (_p)->n_str_type = ( (_p)->n_com_ports != 0 ) ? \
- DEFAULT_N_STR_TYPE_DCF : 0; \
-} while ( 0 )
-
-
-#define DEFAULT_MAX_STR_TYPE 2 //##++ DEFAULT_N_STR_TYPE_GPS
-
-_ext STR_TYPE_INFO default_str_type_info[DEFAULT_MAX_STR_TYPE]
-#ifdef _DO_INIT
- = {
- { DEFAULT_STR_MODES, "Default Time String", "Time", 0 },
- { DEFAULT_STR_MODES_UCAP, "Capture String", "Cap", 0 }
- }
-#endif
-;
-
-
-
-/* ----- function prototypes begin ----- */
-
-/* This section was generated automatically */
-/* by MAKEHDR, do not remove the comments. */
-
- void port_info_from_pcps_serial( PORT_INFO_IDX *p_pii, PCPS_SERIAL pcps_serial, uint32_t supp_baud_rates ) ;
- void pcps_serial_from_port_info( PCPS_SERIAL *p, const PORT_INFO_IDX *p_pii ) ;
-
-/* ----- 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 /* _PARMPCPS_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pci.h b/src/external/bsd/meinberg/dist/mbglib/common/pci.h
index fc8abb5..8f0a644 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pci.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pci.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pci.h 1.9 2008/01/30 13:42:29 martin REL_M $
+ * $Id: pci.h 1.10 2017/05/10 15:24:21 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,8 @@
*
* -----------------------------------------------------------------------
* $Log: pci.h $
+ * Revision 1.10 2017/05/10 15:24:21 martin
+ * Tiny cleanup.
* Revision 1.9 2008/01/30 13:42:29 martin
* Code cleanup to support different build environments properly.
* Revision 1.8 2006/07/11 08:59:00Z martin
@@ -67,7 +69,6 @@
#endif
-
#ifdef _PCI
#define _ext
#else
@@ -77,6 +78,10 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if !defined( pci_fnc_init )
#define pci_fnc_init() 0
#endif
@@ -132,16 +137,6 @@
#endif // defined( MBG_PCI_MACROS_MAP_GENERIC )
-/* End of header body */
-
-#undef _ext
-
-
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
/* ----- function prototypes begin ----- */
@@ -157,6 +152,10 @@ extern "C" {
#endif
+/* End of header body */
+
+#undef _ext
+
#endif /* _PCI_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pci_asic.h b/src/external/bsd/meinberg/dist/mbglib/common/pci_asic.h
index cc859f4..3bbba03 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pci_asic.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pci_asic.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pci_asic.h 1.20 2011/06/30 13:52:26 martin REL_M $
+ * $Id: pci_asic.h 1.29 2017/07/04 14:18:03 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,26 @@
*
* -----------------------------------------------------------------------
* $Log: pci_asic.h $
- * Revision 1.20 2011/06/30 13:52:26 martin
+ * Revision 1.29 2017/07/04 14:18:03 martin
+ * Updated minor version for PTP270PEX.
+ * Revision 1.28 2017/05/10 15:24:21 martin
+ * Tiny cleanup.
+ * Revision 1.27 2017/04/25 11:36:30 martin
+ * Renamed GRC181PEX to GNS181PEX.
+ * Revision 1.26 2016/09/15 14:55:02 martin
+ * Support GRC181PEX.
+ * Added doxgen comments.
+ * Revision 1.25 2014/10/17 11:38:39 martin
+ * Updated version info for GPS180PEX.
+ * Revision 1.24 2013/10/01 15:29:39 martin
+ * Updated version info for PTP270PEX.
+ * Revision 1.23 2013/06/26 15:57:07Z martin
+ * Support GLN180PEX.
+ * Revision 1.22 2011/10/05 09:46:12 martin
+ * Updated version info for GPS180PEX.
+ * Revision 1.21 2011/09/13 07:36:21Z martin
+ * Updated version info for GPS180PEX.
+ * Revision 1.20 2011/06/30 13:52:26Z martin
* Updated version info for GPS180PEX.
* Revision 1.19 2011/06/29 08:58:32Z martin
* Support PZF180PEX.
@@ -32,7 +51,7 @@
* 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
+ * 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
@@ -58,7 +77,7 @@
* 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
+ * 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.
@@ -92,77 +111,145 @@
#define _USING_BYTE_ALIGNMENT
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Set of PCI ASIC registers which are writeable once after power-up
+ **/
typedef struct
{
uint32_t cfg_class_rev_id;
uint16_t cfg_badr_0;
uint16_t cfg_dev_id;
+
} PCI_ASIC_CFG;
+/**
+ * @brief A PCI ASIC register as 32, 16, or 8 bit accessible union
+ */
typedef union
{
uint32_t ul;
uint16_t us[2];
uint8_t b[4];
+
} PCI_ASIC_REG;
+
+/**
+ * @brief A data type to hold the PCI ASIC version code
+ */
typedef uint32_t PCI_ASIC_VERSION;
+
#define _mbg_swab_asic_version( _p ) _mbg_swab32( _p )
+
+
+/**
+ * @brief A data type to hold the PCI ASIC feature flags mask
+ *
+ * @see @ref PCI_ASIC_FEATURE_MASKS
+ */
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
+/**
+ * @brief Bit masks used with ::PCI_ASIC_FEATURES
+ *
+ * @see ::PCI_ASIC_FEATURES
+ *
+ * @anchor PCI_ASIC_FEATURE_MASKS @{ */
+
+#define PCI_ASIC_HAS_MM_IO 0x0001 ///< The device supports memory mapped I/O
+#define PCI_ASIC_HAS_PGMB_IRQ 0x0002 ///< The device supports programmable interrupts (yet not used)
+
+/** @} anchor PCI_ASIC_FEATURE_MASKS */
+
+
+
+/**
+ * @brief The addon-data part of a PCI ASIC
+ */
typedef union
{
uint32_t ul[4];
uint16_t us[8];
uint8_t b[16];
+
} PCI_ASIC_ADDON_DATA;
+
+/**
+ * @brief Register layout of a PCI ASIC
+ */
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_CFG cfg; ///< Registers which are writeable from add-on once after power-up
+ PCI_ASIC_VERSION raw_version; ///< Raw version code
+ PCI_ASIC_FEATURES features; ///< PCI ASIC feature mask, see @ref PCI_ASIC_FEATURE_MASKS
+ PCI_ASIC_REG status_port; ///< The status port register
+ PCI_ASIC_REG control_status; ///< See @ref PCI_ASIC_CONTROL_STATUS_MASKS
+ PCI_ASIC_REG pci_data; ///< Register used to pass byte from PCI bus to add-on side
+ PCI_ASIC_REG reserved_1; ///< Currently not implemented / used
+
+ PCI_ASIC_ADDON_DATA addon_data; ///< Register set used to return data from add-on to PCI bus
+ PCI_ASIC_ADDON_DATA reserved_2; ///< Currently not implemented / used
+
} 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.
+/**
+ * @brief Bit masks used with ::PCI_ASIC::control_status
+ *
+ * @see ::PCI_ASIC
+ *
+ * @anchor PCI_ASIC_CONTROL_STATUS_MASKS @{ */
+
+/**
+ * @brief Add-on IRQ flag
+ *
+ * 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.
+/**
+ * @brief PCI IRQ flag
+ *
+ * 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
+// NOTE All other bits are reserved for future use.
+
+/** @} anchor PCI_ASIC_CONTROL_STATUS_MASKS */
-// The ASIC's address decoder always decodes 8 bits, so
-// each device must request at least that number of
-// addresses from the PCI BIOS:
+
+
+/**
+ * @brief PCI address range
+ *
+ * The ASIC's address decoder always decodes 8 bits, so
+ * each device must request at least this number of
+ * addresses from the PCI BIOS.
+ */
#define PCI_ASIC_ADDR_RANGE 0x100U
@@ -221,34 +308,42 @@ typedef struct
_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:
-*/
+
+/**
+ * @brief Version number conversion macro
+ *
+ * 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.
+ *
+ * This macro 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 */
-
+/**
+ * @brief Extract the major part of an ASIC version number
+ */
#define _pcps_asic_version_major( _v ) \
( ( (_v) >> 8 ) & 0xFF )
+
+/**
+ * @brief Extract the minor part of an ASIC version number
+ */
#define _pcps_asic_version_minor( _v ) \
( (_v) & 0xFF )
-/*
- * Macros to check whether a version number is correct
- * and matches a required minimum version
+
+/**
+ * @brief Check whether a version number is correct and matches a required minimum version
*/
#define _pcps_asic_version_greater_equal( _v, _v_major, _v_minor ) \
( \
@@ -257,69 +352,86 @@ typedef struct
)
-/*
- 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
+
+/**
+ * @brief ASIC major version numbers
+ *
+ * @see @ref PCI_ASIC_MINOR_VERSION_NUMBERS
+ */
+enum PCI_ASIC_MAJOR_VERSION_NUMBERS
{
- 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 PEX511
- 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
- PCI_ASIC_MAJOR_GPS180PEX, // PEX EPLD for GPS180PEX
- PCI_ASIC_MAJOR_TCR180PEX, // PEX EPLD for TCR180PEX
- PCI_ASIC_MAJOR_PZF180PEX, // PEX EPLD for PZF180PEX
- N_PCI_ASIC_MAJOR // the number of known codes
+ 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 PEX511
+ 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
+ PCI_ASIC_MAJOR_GPS180PEX, ///< PEX EPLD for GPS180PEX/GPS180AMC
+ PCI_ASIC_MAJOR_TCR180PEX, ///< PEX EPLD for TCR180PEX
+ PCI_ASIC_MAJOR_PZF180PEX, ///< PEX EPLD for PZF180PEX
+ PCI_ASIC_MAJOR_GLN180PEX, ///< PEX EPLD for GLN180PEX
+ PCI_ASIC_MAJOR_GNS181PEX, ///< PEX EPLD for GNS181PEX
+ 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:
-*/
+
+
+/**
+ * @brief ASIC minor version definitions
+ *
+ * The minor number increases when a new EPLD image is released.
+ * At least EPLD images with the defined "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.
+ *
+ * @see ::PCI_ASIC_MAJOR_VERSION_NUMBERS
+ *
+ * @anchor PCI_ASIC_MINOR_VERSION_NUMBERS @{ */
+
#define PCI_ASIC_CURRENT_MINOR_PEX511 0x04
#define PCI_ASIC_REQUIRED_MINOR_PEX511 0x03
-#define PCI_ASIC_FIX_HRT_MINOR_PEX511 0x04 // increases HRT accuracy
-#define PCI_ASIC_FIX_IRQ_MINOR_PEX511 0x03 // fixes IRQ problem
-#define PCI_ASIC_HR_TIME_MINOR_PEX511 0x02 // supports HR time with PEX511
+#define PCI_ASIC_FIX_HRT_MINOR_PEX511 0x04 // Increases HRT accuracy
+#define PCI_ASIC_FIX_IRQ_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 0x05
#define PCI_ASIC_REQUIRED_MINOR_GPS170PEX 0x03
-#define PCI_ASIC_ENH_HRT_MINOR_GPS170PEX 0x05 // enhanced MM HRT accuracy
-#define PCI_ASIC_FIX_HRT_MINOR_GPS170PEX 0x04 // increases MM HRT accuracy
-#define PCI_ASIC_FIX_IRQ_MINOR_GPS170PEX 0x03 // fixes IRQ problem
+#define PCI_ASIC_ENH_HRT_MINOR_GPS170PEX 0x05 // Enhanced MM HRT accuracy
+#define PCI_ASIC_FIX_HRT_MINOR_GPS170PEX 0x04 // Increases MM HRT accuracy
+#define PCI_ASIC_FIX_IRQ_MINOR_GPS170PEX 0x03 // Fixes IRQ problem
#define PCI_ASIC_CURRENT_MINOR_TCR511PEX 0x04
#define PCI_ASIC_REQUIRED_MINOR_TCR511PEX 0x03
// 0x04 // EPLD sources shared with PEX511 0x04
-#define PCI_ASIC_FIX_IRQ_MINOR_TCR511PEX 0x03 // fixes IRQ problem, increases HRT accuracy
+#define PCI_ASIC_FIX_IRQ_MINOR_TCR511PEX 0x03 // Fixes IRQ problem, increases HRT accuracy
-#define PCI_ASIC_CURRENT_MINOR_PTP270PEX 0x02
+#define PCI_ASIC_CURRENT_MINOR_PTP270PEX 0x06
#define PCI_ASIC_REQUIRED_MINOR_PTP270PEX 0x01
-// 0x02 // increased accuracy of IRIG DCLS slopes
-// 0x01 // supports inversion of ucap slopes
+// 0x06 // Supports 1 PPS pulse shift
+// 0x05 // ...
+// 0x04 // ...
+// 0x03 // ...
+// 0x02 // Increased accuracy of IRIG DCLS slopes
+// 0x01 // Supports inversion of ucap slopes
#define PCI_ASIC_CURRENT_MINOR_FRC511PEX 0x01
#define PCI_ASIC_REQUIRED_MINOR_FRC511PEX 0x01
#define PCI_ASIC_CURRENT_MINOR_TCR170PEX 0x03
#define PCI_ASIC_REQUIRED_MINOR_TCR170PEX 0x02
-#define PCI_ASIC_FIX_EE_ACCESS_TCR170PEX 0x02 // fixes EE access problem after reset
-#define PCI_ASIC_FIX_FO_IN_LEVEL_TCR170PEX 0x03 // correct polarity for fiber optic input
+#define PCI_ASIC_FIX_EE_ACCESS_TCR170PEX 0x02 // Fixes EE access problem after reset
+#define PCI_ASIC_FIX_FO_IN_LEVEL_TCR170PEX 0x03 // Correct polarity for fiber optic input
-#define PCI_ASIC_CURRENT_MINOR_GPS180PEX 0x03
+#define PCI_ASIC_CURRENT_MINOR_GPS180PEX 0x06
#define PCI_ASIC_REQUIRED_MINOR_GPS180PEX 0x01
-// 0x01 // updated VHDL compiler and associated PCI primitives
+// 0x01 // Updated VHDL compiler and associated PCI primitives
// 0x02 // I/O using 3.3V LVTTL
// 0x03 // GPS TIC pulse len now 1 sample clock
+// 0x04 // Enabled PCI IRQ line which had unintentionally been disabled earlier
+// 0x05 // Increased accuracy of synthesizer output
+// 0x06 // T0 AUX Capture used by firmware v2.0x
#define PCI_ASIC_CURRENT_MINOR_TCR180PEX 0x00
#define PCI_ASIC_REQUIRED_MINOR_TCR180PEX 0x00
@@ -327,15 +439,38 @@ enum
#define PCI_ASIC_CURRENT_MINOR_PZF180PEX 0x00
#define PCI_ASIC_REQUIRED_MINOR_PZF180PEX 0x00
+#define PCI_ASIC_CURRENT_MINOR_GLN180PEX 0x00
+#define PCI_ASIC_REQUIRED_MINOR_GLN180PEX 0x00
+
+#define PCI_ASIC_CURRENT_MINOR_GNS181PEX 0x00
+#define PCI_ASIC_REQUIRED_MINOR_GNS181PEX 0x00
+
+/** @} anchor PCI_ASIC_MINOR_VERSION_NUMBERS */
+
+
+/**
+ * @brief A structure holding version information for a specific device
+ *
+ * @see ::DEFAULT_PCI_ASIC_VERSION_INFO_TABLE
+ */
typedef struct
{
unsigned int dev_type_num;
unsigned int major;
unsigned int current_minor;
unsigned int required_minor;
+
} PCI_ASIC_VERSION_INFO;
+
+/**
+ * @brief An initializer for a table of ASIC version information for all known devices
+ *
+ * @note GPS180AMC uses the same ASIC as GPS180PEX
+ *
+ * @see ::PCI_ASIC_VERSION_INFO
+ */
#define DEFAULT_PCI_ASIC_VERSION_INFO_TABLE \
{ \
{ PCPS_TYPE_PEX511, PCI_ASIC_MAJOR_PEX511, PCI_ASIC_CURRENT_MINOR_PEX511, PCI_ASIC_REQUIRED_MINOR_PEX511 }, \
@@ -347,16 +482,13 @@ typedef struct
{ PCPS_TYPE_GPS180PEX, PCI_ASIC_MAJOR_GPS180PEX, PCI_ASIC_CURRENT_MINOR_GPS180PEX, PCI_ASIC_REQUIRED_MINOR_GPS180PEX }, \
{ PCPS_TYPE_TCR180PEX, PCI_ASIC_MAJOR_TCR180PEX, PCI_ASIC_CURRENT_MINOR_TCR180PEX, PCI_ASIC_REQUIRED_MINOR_TCR180PEX }, \
{ PCPS_TYPE_PZF180PEX, PCI_ASIC_MAJOR_PZF180PEX, PCI_ASIC_CURRENT_MINOR_PZF180PEX, PCI_ASIC_REQUIRED_MINOR_PZF180PEX }, \
+ { PCPS_TYPE_GLN180PEX, PCI_ASIC_MAJOR_GLN180PEX, PCI_ASIC_CURRENT_MINOR_GLN180PEX, PCI_ASIC_REQUIRED_MINOR_GLN180PEX }, \
+ { PCPS_TYPE_GPS180AMC, PCI_ASIC_MAJOR_GPS180PEX, PCI_ASIC_CURRENT_MINOR_GPS180PEX, PCI_ASIC_REQUIRED_MINOR_GPS180PEX }, \
+ { PCPS_TYPE_GNS181PEX, PCI_ASIC_MAJOR_GNS181PEX, PCI_ASIC_CURRENT_MINOR_GNS181PEX, PCI_ASIC_REQUIRED_MINOR_GNS181PEX }, \
{ 0 } \
}
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
@@ -382,4 +514,3 @@ extern "C" {
#undef _DO_INIT
#endif /* _PCI_ASIC_H */
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcidefs.h b/src/external/bsd/meinberg/dist/mbglib/common/pcidefs.h
index ed365d2..83c503d 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcidefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcidefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcidefs.h 1.7 2008/06/09 10:43:09 martin REL_M $
+ * $Id: pcidefs.h 1.9 2017/05/10 15:24:15 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,13 @@
*
* -----------------------------------------------------------------------
* $Log: pcidefs.h $
- * Revision 1.7 2008/06/09 10:43:09 martin
+ * Revision 1.9 2017/05/10 15:24:15 martin
+ * Tiny cleanup.
+ * Revision 1.8 2013/09/26 09:26:34 martin
+ * Added num of addr regs for PCI CFG header type 0x01.
+ * Re-ordered definition of PCI vendor IDs based on numerical code.
+ * Added some PCI vendor IDs.
+ * Revision 1.7 2008/06/09 10:43:09Z martin
* Added PCI_CMD_ENB_MEM_ACC code.
* Revision 1.6 2005/09/19 13:06:15Z martin
* Added definition for number of base address registers.
@@ -43,6 +49,9 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
// Available PCI subfunction codes depend on the operating system
// so they are defined in the associated headers.
@@ -170,7 +179,8 @@ typedef struct
#define PCI_CS_MIN_GNT 0x3E
#define PCI_CS_MAX_LAT 0x3F
-#define PCI_CS_N_BASE_ADDRESS 6 /* max number of address spaces */
+#define PCI_CS_N_BASE_ADDRESS 6 /* num of badr regs for header type 0x00 */
+#define PCI_CS_N_BASE_ADDRESS_01 2 /* num of badr regs for header type 0x01 */
#define PCI_CMD_ENB_IO_ACC 0x01
@@ -213,39 +223,45 @@ typedef struct
-// some known vendor IDs, in alphabetical order:
+// some known vendor IDs, in numerical order:
-#define PCI_VENDOR_3COM 0x10B7
-#define PCI_VENDOR_ADAPTEC_1 0x9004
-#define PCI_VENDOR_ADAPTEC_2 0x9005
-#define PCI_VENDOR_AMCC 0x10E8
-#define PCI_VENDOR_AMD 0x1022
#define PCI_VENDOR_ASUS 0x1000
+#define PCI_VENDOR_ATI 0x1002
#define PCI_VENDOR_CIRRUS_LOGIC 0x1013
-#define PCI_VENDOR_ELSA 0x5333
#define PCI_VENDOR_IBM 0x1014
-#define PCI_VENDOR_INTEL 0x8086
+#define PCI_VENDOR_AMD 0x1022
#define PCI_VENDOR_MATROX 0x102B
+#define PCI_VENDOR_NEC 0x1033
+#define PCI_VENDOR_TEXAS_INSTR 0x104C
+#define PCI_VENDOR_PLX 0x10B5
+#define PCI_VENDOR_3COM 0x10B7
+#define PCI_VENDOR_AMCC 0x10E8
+#define PCI_VENDOR_REALTEK 0x10EC
#define PCI_VENDOR_MEINBERG 0x1360
+#define PCI_VENDOR_JMICRON 0x197B
+#define PCI_VENDOR_ELSA 0x5333
+#define PCI_VENDOR_INTEL 0x8086
+#define PCI_VENDOR_ADAPTEC_1 0x9004
+#define PCI_VENDOR_ADAPTEC_2 0x9005
-/* End of header body */
-#undef _ext
+/* ----- function prototypes begin ----- */
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+/* (no header definitions found) */
-/* function prototypes: */
+/* ----- function prototypes end ----- */
#ifdef __cplusplus
-extern "C" {
+}
#endif
-// currently none
-#ifdef __cplusplus
-}
-#endif
+/* End of header body */
+#undef _ext
#endif /* _PCIDEFS_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdefs.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdefs.h
index e29d384..d3fcf99 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsdefs.h 1.46.1.11 2011/07/18 10:19:28 martin TRASH $
+ * $Id: pcpsdefs.h 1.62 2017/07/04 16:24:53 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,36 +10,63 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsdefs.h $
- * Revision 1.46.1.11 2011/07/18 10:19:28 martin
- * Added an initializer for a table of GPS command code/names.
- * Revision 1.46.1.10 2011/07/06 11:21:38 martin
- * Added commands to read CORR_INFO, and read/write TR_DISTANCE.
- * Added swab macros for CORR_INFO and TR_DISTANCE.
- * Modified some comments.
- * Revision 1.46.1.9 2011/07/05 08:27:00 martin
- * Comments only.
- * Revision 1.46.1.8 2011/07/04 15:27:52 martin
+ * Revision 1.62 2017/07/04 16:24:53 martin
+ * Moved definitions PCPS_HRT_FRAC_SCALE and PCPS_HRT_FRAC_SCALE_FMT
+ * back here.
+ * New types PCPS_SECONDS and PCPS_FRAC_32.
+ * Fixed typo, wording, and doxygen comments.
+ * Revision 1.61 2017/04/25 11:38:38 martin
+ * Renamed GRC181PEX to GNS181PEX.
+ * Revision 1.60 2017/03/17 12:00:05 martin
+ * Moved definitions of PCPS_HRT_FRAC_CONVERSION_TYPE,
+ * PCPS_HRT_BIN_FRAC_SCALE, and PCPS_HRT_FRAC_SCALE_FMT
+ * to cfg_hlp.h.
+ * Revision 1.59 2017/01/27 08:11:19 martin
+ * Fixed macro syntax.
+ * Revision 1.58 2016/11/08 16:42:52 martin
+ * New GPS cmd codes PC_GPS_XFEATURE_BUFFER and PC_GPS_TLV_INFO.
+ * Revision 1.57 2016/11/08 16:40:39 martin
+ * Doxygen cleanup.
+ * Revision 1.56 2016/10/26 13:22:41 martin
+ * Added definitions for GRC181PEX.
+ * New symbol IRIG_TIME_UNKNOWN_YEAR.
+ * Removed trailing spaces.
+ * Updated doxygen comments.
+ * Revision 1.55 2014/07/17 10:52:24 martin
+ * Increased safety of firmware builds.
+ * Revision 1.54 2014/07/17 09:54:19 martin
+ * New command codes PC_GPS_XMR_HOLDOVER_STATUS
+ * and PC_GPS_ALL_GPIO_STATUS.
+ * Huge update and cleanup on doxygen comments.
+ * Revision 1.53 2014/05/27 10:13:20 martin
+ * Support GPS180AMC.
+ * Moved some signal constant definitions to pcpsdefs.h.
+ * Simplified declaration of code/name tables.
+ * Huge rework of comments in doxygen format.
+ * Revision 1.52 2013/09/26 09:02:52Z martin
+ * Support GNSS API.
+ * Updated doxygen comments.
+ * Revision 1.51 2013/06/25 09:51:39 martin
+ * Support GLN180PEX.
+ * Revision 1.50 2013/01/30 15:59:54 martin
+ * Updated and fixed some doxygen comments.
+ * Revision 1.49 2012/10/02 18:53:02 martin
+ * Added structure PCPS_TIME_STATUS_X_MASKS.
+ * Added initializer for command names, useful for debugging.
+ * Revision 1.48 2011/11/25 15:02:28 martin
+ * Support on-board event logs.
+ * Revision 1.47 2011/11/25 10:22:44 martin
+ * Modified handling of pragma pack().
* Made command group codes obsolete. They are still supported
* when building firmware, though.
- * Revision 1.46.1.7 2011/07/04 14:53:46 martin
- * Added definitions MBG_PCPS_FMT_STATUS and PCPS_SYNC_PZF.
- * Modified some comments.
- * Revision 1.46.1.6 2011/06/29 14:08:28 martin
- * Updated some comments.
- * Revision 1.46.1.5 2011/06/29 09:10:25 martin
- * Renamed PZF600PEX to PZF180PEX.
- * Revision 1.46.1.4 2011/06/21 13:45:14 martin
- * Support PZF600PEX.
- * Renamed *_GPIO_CFG_INFO to *_GPIO_CFG_LIMITS
- * to follow common naming conventions.
* Support PTP unicast configuration.
- * Modified handling of pragma pack().
- * Revision 1.46.1.3 2011/04/18 13:29:39 martin
- * Doxygen changes.
- * Revision 1.46.1.2 2011/04/07 15:56:25 martin
* Support GPIO configuration.
- * Revision 1.46.1.1 2011/02/15 10:55:28 daniel
- * New command PC_GPS_PTP_UNICAST_CFG
+ * Support PZF180PEX.
+ * Added commands to read CORR_INFO, read/write TR_DISTANCE,
+ * PCPS_SYNC_PZF status, and associated structures.
+ * Added an initializer for a table of GPS command code/names.
+ * Added definitions MBG_PCPS_FMT_STATUS.
+ * Updated some comments.
* Revision 1.46 2011/01/13 11:44:29Z martin
* Moved status port register definitions here.
* Revision 1.45 2010/09/06 07:36:24 martin
@@ -81,12 +108,12 @@
* Added new REF type PCPS_REF_MSF.
* Revision 1.35 2008/01/17 09:18:46Z daniel
* Made comments compatible for doxygen parser.
- * No sourcecode changes.
+ * No sourcecode changes.
* Revision 1.34 2007/07/17 08:22:47Z martin
* Added support for TCR511PEX and GPS170PEX.
* Revision 1.33 2007/05/20 21:39:51Z martin
* Added support for PEX511.
- * Added PCPS_GET_STATUS_PORT cmd code for devices
+ * Added PCPS_GET_STATUS_PORT cmd code for devices
* that do not support a hardware status port.
* Revision 1.32 2007/03/29 12:57:32Z martin
* Renamed some TZCODE numbers for unique naming conventions.
@@ -118,14 +145,14 @@
* Support configuration of on-board frequency synthesizer.
* Revision 1.21 2004/11/09 12:55:32Z martin
* Redefined interface data types using C99 fixed-size definitions.
- * Added workaround macros for some structure sizes because the C166
- * compiler always reports an even structure size even if the structure
- * size is in fact odd, which might lead to different sizes in C166 and
+ * Added workaround macros for some structure sizes because the C166
+ * compiler always reports an even structure size even if the structure
+ * size is in fact odd, which might lead to different sizes in C166 and
* other environments.
- * Modifications were required in order to be able to configure IRIG
+ * Modifications were required in order to be able to configure IRIG
* settings of cards which provide both IRIG input and output.
- * The existing codes have been renamed with .._RX.. and are used to
- * configure the IRIG receiver (input). New codes have been defined
+ * The existing codes have been renamed with .._RX.. and are used to
+ * configure the IRIG receiver (input). New codes have been defined
* used to configure the IRIG transmitter.
* Renamed PC_GPS_STAT to PC_GPS_BVAR_STAT.
* Use more specific data types than generic types.
@@ -143,12 +170,12 @@
* fill level.
* Revision 1.16 2003/04/03 10:48:53 martin
* Support for PCI510, GPS169PCI, and TCR510PCI.
- * New codes PCPS_GET_REF_OFFS, PCPS_SET_REF_OFFS
+ * New codes PCPS_GET_REF_OFFS, PCPS_SET_REF_OFFS
* and related structures.
* New codes PCPS_GET_OPT_INFO, PCPS_SET_OPT_SETTINGS
* and related structures.
* New codes PCPS_GET_IRIG_INFO, PCPS_SET_IRIG_SETTINGS.
- * Preliminary PCPS_TZDL structure and cmd codes
+ * Preliminary PCPS_TZDL structure and cmd codes
* to read/write that structure.
* Revision 1.15 2002/08/08 13:24:03 MARTIN
* Moved definition of ref time sources here.
@@ -212,8 +239,8 @@
* Changes before put under RCS control:
*
* Revision 1.5 2000/03/24
- * Introduced PCPS_GIVE_SERNUM
- * Cleaned up for definitions for serial parameter byte
+ * Introduced PCPS_GIVE_SERNUM.
+ * Cleaned up for definitions for serial parameter byte.
* Reviewed and updated comments.
*
* 1998/07/22
@@ -222,7 +249,7 @@
* Reviewed and updated comments.
*
* 1997/06/12
- * GPS definitions added.
+ * Added GPS definitions.
*
* 1996/01/25
* PCPS_TIME redefined from an array of bytes to a structure.
@@ -238,6 +265,13 @@
#include <words.h>
#include <use_pack.h>
+#ifndef _USE_PCPSPRIV
+ #define _USE_PCPSPRIV _IS_MBG_FIRMWARE
+#endif
+
+#if _USE_PCPSPRIV
+ #include <pcpspriv.h>
+#endif
/* Start of header body */
@@ -250,25 +284,30 @@
/**
* @brief Enumeration of the ref time signal sources used by Meinberg devices
*/
-enum
+enum PCPS_REF_TYPES
{
- PCPS_REF_NONE, /**< (unknown or not defined) */
- PCPS_REF_DCF, /**< see http://www.meinberg.de/english/info/dcf77.htm */
- PCPS_REF_GPS, /**< see http://www.meinberg.de/english/info/gps.htm */
- PCPS_REF_IRIG, /**< see http://www.meinberg.de/english/info/irig.htm */
- PCPS_REF_MSF, /**< MSF Receiver (UK) */
- PCPS_REF_PTP, /**< PTP/IEEE1588 network protocol */
- PCPS_REF_FRC, /**< Free Running Clock */
- PCPS_REF_WWVB, /**< WWVB Receiver (US) */
- PCPS_REF_JJY, /**< JJY Receiver (Japan) */
- N_PCPS_REF /**< number of valid ref time sources */
+ PCPS_REF_NONE, ///< unknown, or not defined
+ PCPS_REF_DCF, ///< DCF77 long wave signal (Germany), see http://www.meinberg.de/english/info/dcf77.htm
+ PCPS_REF_GPS, ///< GPS satellite system, see http://www.meinberg.de/english/info/gps.htm
+ PCPS_REF_IRIG, ///< IRIG or similar time code, see http://www.meinberg.de/english/info/irig.htm
+ PCPS_REF_MSF, ///< MSF long wave signal (UK)
+ PCPS_REF_PTP, ///< PTP/IEEE1588 network protocol
+ PCPS_REF_FRC, ///< Free Running Clock
+ PCPS_REF_WWVB, ///< WWVB long wave signal (U.S.)
+ PCPS_REF_JJY, ///< JJY long wave signal (Japan)
+ N_PCPS_REF ///< number of defined ref time sources
};
-/* Initializers for the reference source names */
+/**
+ * @defgroup group_pcps_ref_type_names Reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ *
+ * @{ */
-#define PCPS_REF_NAME_NONE_ENG "unknown"
-#define PCPS_REF_NAME_NONE_GER "nicht bekannt"
+#define PCPS_REF_NAME_NONE_ENG "unknown"
+#define PCPS_REF_NAME_NONE_GER "nicht bekannt"
#define PCPS_REF_NAME_DCF "DCF77"
#define PCPS_REF_NAME_GPS "GPS"
#define PCPS_REF_NAME_IRIG "IRIG"
@@ -278,7 +317,14 @@ enum
#define PCPS_REF_NAME_WWVB "WWVB"
#define PCPS_REF_NAME_JJY "JJY"
+/** @} @defgroup group_pcps_ref_type_names */
+
+/**
+ * @brief Initializer for an array of English reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ */
#define PCPS_REF_NAMES_ENG \
{ \
PCPS_REF_NAME_NONE_ENG, \
@@ -293,6 +339,11 @@ enum
}
+/**
+ * @brief Initializer for a multi-language array of reference type names
+ *
+ * @see ::PCPS_REF_TYPES
+ */
#define PCPS_REF_NAMES_LSTR \
{ \
{ PCPS_REF_NAME_NONE_ENG, PCPS_REF_NAME_NONE_GER }, \
@@ -309,14 +360,23 @@ enum
/**
- * @brief Meinberg PCI vendor ID (assigned by PCI SIG)
+ * @brief Meinberg PCI vendor ID (assigned by the PCI SIG)
+ *
+ * @see @ref MEINBERG_PCI_DEVICE_IDS
*/
#define PCI_VENDOR_MEINBERG 0x1360
-/* PCI device ID numbers (assigned by Meinberg) *
- * High byte: type of ref time source
- * Low Byte: enumeration of device types
- */
+
+/**
+ * @brief PCI device IDs assigned by Meinberg
+ *
+ * High byte: type of ref time source, see ::PCPS_REF_TYPES
+ * Low Byte: enumeration of device types
+ *
+ * @see ::PCI_VENDOR_MEINBERG
+ *
+ * @anchor MEINBERG_PCI_DEVICE_IDS @{ */
+
#define PCI_DEV_PCI32 ( ( PCPS_REF_DCF << 8 ) | 0x01 )
#define PCI_DEV_PCI509 ( ( PCPS_REF_DCF << 8 ) | 0x02 )
#define PCI_DEV_PCI510 ( ( PCPS_REF_DCF << 8 ) | 0x03 )
@@ -330,6 +390,9 @@ enum
#define PCI_DEV_GPS170PCI ( ( PCPS_REF_GPS << 8 ) | 0x04 )
#define PCI_DEV_GPS170PEX ( ( PCPS_REF_GPS << 8 ) | 0x05 )
#define PCI_DEV_GPS180PEX ( ( PCPS_REF_GPS << 8 ) | 0x06 )
+#define PCI_DEV_GLN180PEX ( ( PCPS_REF_GPS << 8 ) | 0x07 )
+#define PCI_DEV_GPS180AMC ( ( PCPS_REF_GPS << 8 ) | 0x08 )
+#define PCI_DEV_GNS181PEX ( ( PCPS_REF_GPS << 8 ) | 0x09 )
#define PCI_DEV_TCR510PCI ( ( PCPS_REF_IRIG << 8 ) | 0x01 )
#define PCI_DEV_TCR167PCI ( ( PCPS_REF_IRIG << 8 ) | 0x02 )
@@ -342,37 +405,56 @@ enum
#define PCI_DEV_FRC511PEX ( ( PCPS_REF_FRC << 8 ) | 0x01 )
+/** @} anchor MEINBERG_PCI_DEVICE_IDS */
-// definitions used for the status port register
-// (not to be intermixed with PCPS_TIME_STATUS)
-typedef uint8_t PCPS_STATUS_PORT; /**< see @ref group_status_port "Bitmask" */
/**
- * @defgroup group_status_port Bit masks of PCPS_STATUS_PORT
+ * @defgroup group_status_port Definitions used with the status port
*
- * Bit definitions used with the #PCPS_STATUS_PORT register.
+ * The status port register on bus-level cards reflects some hardware
+ * signals (e.g. DCF-77 modulation), and flags used for communication
+ * with the card (e.g. the BUSY flag, ::PCPS_ST_BUSY).
+ *
+ * @note Must not be confused with ::PCPS_TIME_STATUS which returns
+ * the synchronization status and associated information
+ *
+ * @{ */
+
+/**
+ * @brief Type of the status register port
+ */
+typedef uint8_t PCPS_STATUS_PORT; ///< see @ref PCPS_STATUS_PORT_BIT_MASKS
+
+
+/**
+ * @brief Bit masks used with ::PCPS_STATUS_PORT
*
- * The flags #PCPS_ST_SEC and #PCPS_ST_MIN are cleared whenever the clock
- * is read, so they are not very reliable in multitasking environments.
+ * The flags ::PCPS_ST_SEC and ::PCPS_ST_MIN are cleared whenever the clock
+ * is read, so they are not very reliable in multitasking environments
+ * and thus should be considered as deprecated.
*
- * @note The PCPS_ST_IRQF flag originates from old ISA cards.
+ * The ::PCPS_ST_IRQF flag was used with old ISA cards to check
+ * if the device has generated an IRQ.
* Some PCI cards also support this, but in case of PCI cards the
* associated flag of the PCI interface chip should be checked to see
- * if a certain card has generated an IRQ on the PC bus.
+ * if a particular card has generated an IRQ on the PC bus.
*
- * The macro _pcps_ddev_has_gen_irq() cares about this and should be used
+ * The macro ::_pcps_ddev_has_gen_irq cares about this and should be used
* to determine in a portable way whether a card has generated an IRQ.
*
- * @{ */
+ * @anchor PCPS_STATUS_PORT_BIT_MASKS @{ */
+
+#define PCPS_ST_BUSY 0x01 ///< the clock is busy filling the output FIFO
+#define PCPS_ST_IRQF 0x02 ///< the clock has generated an IRQ on the PC bus (ISA cards only)
+#define PCPS_ST_MOD 0x20 ///< the raw demodulated DCF77 signal
+#define PCPS_ST_SEC 0x40 ///< seconds have changed since last reading
+#define PCPS_ST_MIN 0x80 ///< minutes have changed since last reading
+
+/** @} anchor PCPS_STATUS_PORT_BIT_MASKS */
-#define PCPS_ST_BUSY 0x01 /**< the clock is busy filling the output FIFO */
-#define PCPS_ST_IRQF 0x02 /**< the clock has generated an IRQ on the PC bus (ISA only)*/
-#define PCPS_ST_MOD 0x20 /**< the raw demodulated DCF77 signal */
-#define PCPS_ST_SEC 0x40 /**< seconds have changed since last reading */
-#define PCPS_ST_MIN 0x80 /**< minutes have changed since last reading */
+/** @} defgroup group_status_port */
-/** @} group_status_port */
/**
* A format string to be used with snprintb() which is available on some Unix
@@ -384,615 +466,709 @@ typedef uint8_t PCPS_STATUS_PORT; /**< see @ref group_status_port "Bitmask" */
-/** @defgroup group_cmd_bytes Command bytes used to access the device
-
- The commands described below are used to access computer peripherals
- manufactured by Meinberg.
-
- The header files pcpsdev.h and pcpsdrvr.h contain macros which can be
- used to check if a detected device supports a certain feature or command.
- If checking is required then the name of the macro is given in the
- comments below.
-
- Some commands expect parameters to be passed to the board. In that
- case, the board returns the number of parameter bytes expected when
- the command code is passed. Every parameter byte has to be supplied
- to the board exactly like a command byte.
- Refer to function pcps_write_data() and the macro _pcps_write_var()
- for details.
-
-
- - #PCPS_GIVE_TIME<br>
- Return a PCPS_TIME structure with current date,
- time and status. Supported by all clocks.
-
- - #PCPS_GIVE_TIME_NOCLEAR<br>
- Same as #PCPS_GIVE_TIME but the bits #PCPS_ST_SEC
- and #PCPS_ST_MIN (see pcpsdev.h) of the status
- port are not cleared.
- Supported by all clocks except PC31/PS31 with
- firmware version older than v3.0.
- This is mainly used by the DOS TSR and should
- not be used in other environments.
-
- - #PCPS_GIVE_SYNC_TIME<br>
- Return a ::PCPS_TIME structure with date and time
- of last synchronization of the clock or
- the last time set via the interface.
- _pcps_has_sync_time() checks whether supported.
-
- - #PCPS_GIVE_HR_TIME<br>
- Return a PCPS_HR_TIME structure with current
- date, time and status. This command should be
- used to read the clock with higher resolution.
- _pcps_has_hr_time() checks whether supported.
-
- - #PCPS_GIVE_IRIG_TIME<br>
- Return a PCPS_IRIG_TIME structure with day-of-year,
- time and status as decoded from the IRIG signal.
- _pcps_has_irig_time() checks whether supported.
-
- - #PCPS_SET_TIME<br>
- Set the board date, time and status. This
- command expects sizeof( ::PCPS_STIME ) parameter
- bytes.
- _pcps_can_set_time() checks whether supported.
-
- - #PCPS_SET_EVENT_TIME<br>
- Send a high resolution time stamp to the clock to
- configure a UTC time when the clock shall generate
- some event. This command expects a PCPS_TIME_STAMP
- parameter.
- _pcps_has_event_time() checks whether supported.
- (requires custom GPS CERN firmware)
-
- - #PCPS_IRQ_NONE<br>
- Disable the board's hardware IRQ<br>
- - #PCPS_IRQ_1_SEC<br>
- Enable hardware IRQs once per second<br>
- - #PCPS_IRQ_1_MIN<br>
- Enable hardware IRQs once per minute<br>
- - #PCPS_IRQ_10_MIN<br>
- Enable hardware IRQs once per 10 minutes<br>
- - #PCPS_IRQ_30_MIN<br>
- Enable hardware IRQs once per 30 minutes<br>
-
- - #PCPS_GET_SERIAL<br>
- #PCPS_SET_SERIAL<br>
- These commands read or set the configuration
- of a clock's serial port COM0. The commands
- expect PCPS_SERIAL_BYTES parameter bytes and
- should be used preferably with the DCF77
- clocks which have only one COM port.
- _pcps_has_serial() checks whether supported.
- Recent GPS clocks' COM ports should be cfg'd
- using the structures RECEIVER_INFO, PORT_INFO,
- and STR_TYPE_INFO.
- _pcps_has_receiver_info() checks whether
- these are supported. If they are not, then
- the code #PC_GPS_PORT_PARM together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands should be used.
-
- - #PCPS_GET_TZCODE<br>
- #PCPS_SET_TZCODE<br>
- These commands read or set a DCF77 clock's
- time zone code and should be used preferably
- with the newer DCF77 clocks which have limited
- support of different time zones.
- _pcps_has_tzcode() checks whether supported.
- A GPS clock's time zone must be cfg'd using
- the code #PC_GPS_TZDL together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands.
-
- - #PCPS_GET_PCPS_TZDL<br>
- #PCPS_SET_PCPS_TZDL<br>
- These commands read or set a DCF77 clock's
- time zone / daylight saving configuration.
- _pcps_has_pcps_tzdl() checks whether supported.
- A GPS clock's time zone must be cfg'd using
- the code #PC_GPS_TZDL together with the
- #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA
- commands.
-
- - #PCPS_GET_REF_OFFS<br>
- #PCPS_SET_REF_OFFS<br>
- These commands can be used to configure the
- reference time offset from UTC for clocks
- which can't determine the offset automatically,
- e.g. from an IRIG input signal.
- _pcps_has_ref_offs() checks whether supported.
-
- - #PCPS_GET_OPT_INFO<br>
- #PCPS_SET_OPT_SETTINGS<br>
- These commands can be used to configure some
- optional settings, controlled by flags.
- When reading, the clock returns a MBG_OPT_INFO
- structure which contains the supported values,
- plus the current settings.
- When writing, clocks accepts a MBG_OPT_SETTINGS
- structure only which contain the desired settings
- of the supported flags only.
- _pcps_has_opt_flags() checks whether supported.
-
- - #PCPS_GET_IRIG_RX_INFO<br>
- #PCPS_SET_IRIG_RX_SETTINGS<br>
- #PCPS_GET_IRIG_TX_INFO<br>
- #PCPS_SET_IRIG_TX_SETTINGS<br>
- These commands can be used to configure IRIG
- inputs and outputs.<br>
- When reading, the clock returns an IRIG_INFO
- structure which contains the supported values,
- plus the current settings.<br>
- When writing, clocks accepts an IRIG_SETTINGS
- structure only which contain the desired settings
- only. _pcps_is_irig_rx() and _pcps_is_irig_tx()
- check whether supported.
-
- - #PCPS_GET_IRIG_CTRL_BITS<br>
- This command can be used to retrieve the control function
- bits of the latest IRIG input frame. Those bits may carry
- some well-known information as in the IEEE1344 code, but
- may also contain some customized information, depending on
- the IRIG frame type and the configuration of the IRIG generator.
- So these bits are returned as-is and must be interpreted
- by the application.
- _pcps_has_irig_ctrl_bits() checks whether supported.
-
- - #PCPS_GET_SYNTH<br>
- #PCPS_SET_SYNTH<br>
- #PCPS_GET_SYNTH_STATE<br>
- These commands can be used to configure an on-board
- frequency synthesizer and query the synthesizer
- status. The commands are only supported if the board
- supports the RECEIVER_INFO structure and the flag
- #GPS_HAS_SYNTH is set in the RECEIVER_INFO::features.
- _pcps_has_synth() checks whether supported.
- The structures SYNTH and SYNTH_STATE used with these
- commands are defined in gpsdefs.h.
-
- - #PCPS_GIVE_FW_ID_1<br>
- #PCPS_GIVE_FW_ID_2<br>
- Returns the first/second block of PCPS_FIFO_SIZE
- characters of the firmware ID string. These
- commands can be used to check if the board
- responds properly. This is done by the clock
- detection functions.
-
- - #PCPS_GIVE_SERNUM<br>
- Returns PCPS_FIFO_SIZE characters of the
- clock's serial number.
- _pcps_has_sernum() checks whether supported.
-
- - #PCPS_GENERIC_IO<br>
- Generic I/O read and write. Can be used to query
- specific data, e.g. a selected element of an array.
- _pcps_has_generic_io() checks whether supported.
-
- - #PCPS_GET_DEBUG_STATUS<br>
- This command reads a MBG_DEBUG_STATUS structure
- which represents the internal status of the
- IRIG decoder and some additional debug info.
- _pcps_has_debug_status() checks whether supported.
-
- - #PCPS_READ_GPS_DATA<br>
- #PCPS_WRITE_GPS_DATA<br>
- These commands are used by the functions
- pcps_read_gps_data() and pcps_write_gps_data()
- to read or write large data structures to
- Meinberg GPS plug-in clocks.
- _pcps_is_gps() checks whether supported.
-
- - #PCPS_CLR_UCAP_BUFF<br>
- Clear a clock's time capture buffer.
- _pcps_can_clr_ucap_buff() checks whether
- supported.
-
- - #PCPS_GIVE_UCAP_ENTRIES<br>
- Read a PCPS_UCAP_ENTRIES structure which
- reports the max number of entries and the
- currently used number of entries in the
- user capture buffer.
- _pcps_has_ucap() checks whether supported.
-
- - #PCPS_GIVE_UCAP_EVENT<br>
- Read capture events using a PCPS_HR_TIME
- structure. This is faster than reading using the
- GPS command #PC_GPS_UCAP. If no capture event is
- available then the structure is filled with 0s.
- _pcps_has_ucap() checks whether supported.
-
- - #PCPS_GET_CORR_INFO<br>
- Read PZF correlation info using a CORR_INFO
- structure.
- _pcps_has_pzf() checks whether supported.
-
- - #PCPS_GET_TR_DISTANCE<br>
- #PCPS_SET_TR_DISTANCE<br>
- Read or write distance from the RF transmitter.
- This is used to compensate the RF propagation delay
- for PZF receivers.
- _pcps_has_tr_distance() checks whether supported.
-
- - #PCPS_FORCE_RESET<br>
- Resets the microprocessor on the device. This is
- for special test scenarios only and should not be
- used by standard applications since this may lock up
- the PC.
-
- The command codes listed above are defined below. The commands are
- grouped for bytes having the same high nibble:
-
- @{ */
-
-
-#if _IS_MBG_FIRMWARE //##++
-
-// These group codes are obsolete and should be removed.
-// The explicite command codes defined below should be used instead.
-#define PCPS_GIVE_TIME_GROUP 0x00
-#define PCPS_SET_TIME_GROUP 0x10
-#define PCPS_IRQ_GROUP 0x20
-#define PCPS_CFG_GROUP 0x30
-#define PCPS_GIVE_DATA_GROUP 0x40
-#define PCPS_GPS_DATA_GROUP 0x50
-#define PCPS_CTRL_GROUP 0x60
-#define PCPS_CFG2_GROUP 0x70
-
-#endif
+/**
+ * @brief Command codes used to communicate with bus level devices
+ *
+ * These commands are used for low level access to bus-level devices
+ * manufactured by Meinberg.
+ *
+ * Applications should instead use the API functions declared in mbgdevio.h.
+ *
+ * The header files pcpsdev.h and pcpsdrvr.h contain macros which can be
+ * used to check if a detected device supports a certain feature or command.
+ * If checking is required then the name of the macro is given in the
+ * comments associated with the command codes.
+ *
+ * Some commands expect parameters to be passed to the board. In that
+ * case, the board returns the number of parameter bytes expected when
+ * the command code is passed. Every parameter byte has to be supplied
+ * to the board exactly like a command byte.
+ *
+ * Refer to function ::pcps_write and the macro ::_pcps_write_var
+ * for details.
+ *
+ * - ::PCPS_GIVE_TIME<br>
+ * Return a ::PCPS_TIME structure with current date,
+ * time and status. Supported by all clocks.
+ *
+ * - ::PCPS_GIVE_TIME_NOCLEAR<br>
+ * Same as ::PCPS_GIVE_TIME but the bits ::PCPS_ST_SEC
+ * and ::PCPS_ST_MIN of the status port are not cleared.
+ * Supported by all clocks except PC31/PS31 with
+ * firmware version older than v3.0.
+ * This is mainly used by the DOS TSR and should
+ * not be used in other environments.
+ *
+ * - ::PCPS_GIVE_SYNC_TIME<br>
+ * Return a ::PCPS_TIME structure with date and time
+ * of last synchronization of the clock or
+ * the last time set via the interface.
+ * ::_pcps_has_sync_time checks whether supported.
+ *
+ * - ::PCPS_GIVE_HR_TIME<br>
+ * Return a ::PCPS_HR_TIME structure with current
+ * date, time and status. This command should be
+ * used to read the clock with higher resolution.
+ * ::_pcps_has_hr_time checks whether supported.
+ *
+ * - ::PCPS_GIVE_IRIG_TIME<br>
+ * Return a ::PCPS_IRIG_TIME structure with day-of-year,
+ * time and status as decoded from the IRIG signal.
+ * ::_pcps_has_irig_time checks whether supported.
+ *
+ * - ::PCPS_SET_TIME<br>
+ * Set the board date, time and status. This command
+ * expects sizeof( ::PCPS_STIME ) parameter bytes.
+ * ::_pcps_can_set_time checks whether supported.
+ *
+ * - ::PCPS_SET_EVENT_TIME<br>
+ * Send a high resolution time stamp to the clock to
+ * configure a %UTC time when the clock shall generate
+ * some event. This command expects a ::PCPS_TIME_STAMP
+ * parameter.
+ * ::_pcps_has_event_time checks whether supported.
+ * (requires custom GPS CERN firmware)
+ *
+ * - ::PCPS_IRQ_NONE<br>
+ * Disable the card's hardware IRQ<br>
+ * - ::PCPS_IRQ_1_SEC<br>
+ * Enable hardware IRQs once per second<br>
+ * - ::PCPS_IRQ_1_MIN<br>
+ * Enable hardware IRQs once per minute (deprecated)<br>
+ * - ::PCPS_IRQ_10_MIN<br>
+ * Enable hardware IRQs once per 10 minutes (deprecated)<br>
+ * - ::PCPS_IRQ_30_MIN<br>
+ * Enable hardware IRQs once per 30 minutes (deprecated)<br>
+ *
+ * - ::PCPS_GET_SERIAL<br>
+ * ::PCPS_SET_SERIAL<br>
+ * Deprecated. Read or write the configuration of a card's
+ * serial port COM0 in ::PCPS_SERIAL format.
+ * ::_pcps_has_serial checks whether supported.
+ * Newer cards should be configured using the structures ::RECEIVER_INFO,
+ * ::PORT_INFO, and STR_TYPE_INFO.
+ * ::_pcps_has_receiver_info checks whether these are supported.
+ *
+ * - ::PCPS_GET_TZCODE<br>
+ * ::PCPS_SET_TZCODE<br>
+ * These commands read or set a DCF77 clock's
+ * time zone code and should be used preferably
+ * with older DCF77 receivers which have limited
+ * support of different time zones.
+ * ::_pcps_has_tzcode checks whether supported.
+ * Most newer devices support the ::TZDL structure which can be
+ * read or written using ::PC_GPS_TZDL.
+ *
+ * - ::PCPS_GET_PCPS_TZDL<br>
+ * ::PCPS_SET_PCPS_TZDL<br>
+ * Read or write time zone / daylight saving information
+ * in ::PCPS_TZDL format.
+ * ::_pcps_has_pcps_tzdl checks whether supported.
+ *
+ * - ::PCPS_GET_REF_OFFS<br>
+ * ::PCPS_SET_REF_OFFS<br>
+ * These commands can be used to configure the
+ * reference time offset from %UTC for clocks
+ * which can't determine the offset automatically,
+ * e.g. from an IRIG input signal.
+ * ::_pcps_has_ref_offs checks whether supported.
+ *
+ * - ::PCPS_GET_OPT_INFO<br>
+ * ::PCPS_SET_OPT_SETTINGS<br>
+ * These commands can be used to configure some
+ * optional settings, controlled by flags.
+ * When reading, the clock returns a ::MBG_OPT_INFO
+ * structure which contains the supported values,
+ * plus the current settings.
+ * When writing, clocks accepts a ::MBG_OPT_SETTINGS
+ * structure only which contain the desired settings
+ * of the supported flags only.
+ * ::_pcps_has_opt_flags checks whether supported.
+ *
+ * - ::PCPS_GET_IRIG_RX_INFO<br>
+ * ::PCPS_SET_IRIG_RX_SETTINGS<br>
+ * ::PCPS_GET_IRIG_TX_INFO<br>
+ * ::PCPS_SET_IRIG_TX_SETTINGS<br>
+ * These commands can be used to configure IRIG
+ * inputs and outputs.<br>
+ * When reading, the clock returns an ::IRIG_INFO
+ * structure which contains the supported values,
+ * plus the current settings.<br>
+ * When writing, clocks accepts an ::IRIG_SETTINGS
+ * structure only which contain the desired settings
+ * only. ::_pcps_is_irig_rx and ::_pcps_has_irig_tx
+ * check whether supported.
+ *
+ * - ::PCPS_GET_IRIG_CTRL_BITS<br>
+ * This command can be used to retrieve the control function
+ * bits of the latest IRIG input frame. Those bits may carry
+ * some well-known information as in the IEEE 1344 code, but
+ * may also contain some customized information, depending on
+ * the IRIG frame type and the configuration of the IRIG generator.
+ * So these bits are returned as-is and must be interpreted
+ * by the application.
+ * ::_pcps_has_irig_ctrl_bits checks whether supported.
+ *
+ * - ::PCPS_GET_SYNTH<br>
+ * ::PCPS_SET_SYNTH<br>
+ * ::PCPS_GET_SYNTH_STATE<br>
+ * These commands can be used to configure an on-board
+ * frequency synthesizer and query the synthesizer
+ * status. The commands are only supported if the board
+ * supports the ::RECEIVER_INFO structure and the flag
+ * #GPS_HAS_SYNTH is set in the ::RECEIVER_INFO::features.
+ * ::_pcps_has_synth checks whether supported.
+ * The structures ::SYNTH and ::SYNTH_STATE used with these
+ * commands are defined in gpsdefs.h.
+ *
+ * - ::PCPS_GIVE_FW_ID_1<br>
+ * ::PCPS_GIVE_FW_ID_2<br>
+ * Returns the first/second block of ::PCPS_FIFO_SIZE
+ * characters of the firmware ID string. These
+ * commands can be used to check if the board
+ * responds properly. This is done by the clock
+ * detection functions.
+ *
+ * - ::PCPS_GIVE_SERNUM<br>
+ * Returns ::PCPS_FIFO_SIZE characters of the
+ * clock's serial number.
+ * ::_pcps_has_sernum checks whether supported.
+ *
+ * - ::PCPS_GENERIC_IO<br>
+ * Generic I/O read and write. Can be used to query
+ * specific data, e.g. a selected element of an array.
+ * ::_pcps_has_generic_io checks whether supported.
+ *
+ * - ::PCPS_GET_DEBUG_STATUS<br>
+ * This command reads an ::MBG_DEBUG_STATUS structure
+ * which represents the internal status of the
+ * IRIG decoder and some additional debug info.
+ * ::_pcps_has_debug_status checks whether supported.
+ *
+ * - ::PCPS_READ_GPS_DATA<br>
+ * ::PCPS_WRITE_GPS_DATA<br>
+ * These commands are used by the functions
+ * ::pcps_read_gps and ::pcps_write_gps
+ * to read or write large data structures to
+ * Meinberg GPS plug-in clocks.
+ * ::_pcps_is_gps checks whether supported.
+ *
+ * - ::PCPS_CLR_UCAP_BUFF<br>
+ * Clear a clock's time capture buffer.
+ * ::_pcps_can_clr_ucap_buff checks whether
+ * supported.
+ *
+ * - ::PCPS_GIVE_UCAP_ENTRIES<br>
+ * Read a ::PCPS_UCAP_ENTRIES structure which
+ * reports the max number of entries and the
+ * currently used number of entries in the
+ * user capture buffer.
+ * ::_pcps_has_ucap checks whether supported.
+ *
+ * - ::PCPS_GIVE_UCAP_EVENT<br>
+ * Read capture events using a PCPS_HR_TIME
+ * structure. This is faster than reading using the
+ * GPS command ::PC_GPS_UCAP. If no capture event is
+ * available then the returned structure is all 0.
+ * ::_pcps_has_ucap checks whether supported.
+ *
+ * - ::PCPS_GET_CORR_INFO<br>
+ * Read PZF correlation info using a ::CORR_INFO
+ * structure.
+ * ::_pcps_has_pzf checks whether supported.
+ *
+ * - ::PCPS_GET_TR_DISTANCE<br>
+ * ::PCPS_SET_TR_DISTANCE<br>
+ * Read or write distance from the RF transmitter.
+ * This is used to compensate the RF propagation delay
+ * for PZF receivers.
+ * ::_pcps_has_tr_distance checks whether supported.
+ *
+ * - ::PCPS_CLR_EVT_LOG<br>
+ * Clear on-board event log.
+ * ::_pcps_has_evt_log checks whether supported.
+ *
+ * - ::PCPS_NUM_EVT_LOG_ENTRIES<br>
+ * Read max. number of num event log entries which can
+ * be saved on the board, and how many entries have currently
+ * been saved.
+ * ::_pcps_has_evt_log checks whether supported.
+ *
+ * - ::PCPS_FIRST_EVT_LOG_ENTRY<br>
+ * ::PCPS_NEXT_EVT_LOG_ENTRY<br>
+ * Read first (oldest) or next event log entry.
+ * ::_pcps_has_evt_log checks whether supported.
+ *
+ * - ::PCPS_FORCE_RESET<br>
+ * Resets the card's hardware. This may lock up the computer
+ * and thus should only be used by very specific applications.
+ *
+ * @anchor PCPS_CMD_CODES @{ */
+#define PCPS_GIVE_TIME 0x00 ///< (r-) Read current time in ::PCPS_TIME format
+#define PCPS_GIVE_TIME_NOCLEAR 0x01 ///< (r-) Read current time in ::PCPS_TIME format, don't clear sec and min flags (deprecated)
+#define PCPS_GIVE_SYNC_TIME 0x02 ///< (r-) Read last sync time as ::PCPS_TIME, only if ::_pcps_has_sync_time
+#define PCPS_GIVE_HR_TIME 0x03 ///< (r-) Read high res. time as ::PCPS_HR_TIME, only if ::_pcps_has_hr_time
+#define PCPS_GIVE_IRIG_TIME 0x04 ///< (r-) Read raw IRIG time as ::PCPS_IRIG_TIME, only if ::_pcps_has_irig_time
+#define PCPS_SET_TIME 0x10 ///< (-w) Set on-board time, see ::PCPS_STIME. Returns ::MBG_ERR_STIME on error.
-#define PCPS_GIVE_TIME 0x00
-#define PCPS_GIVE_TIME_NOCLEAR 0x01
-#define PCPS_GIVE_SYNC_TIME 0x02 // only supported if _pcps_has_sync_time()
-#define PCPS_GIVE_HR_TIME 0x03 // only supported if _pcps_has_hr_time()
-#define PCPS_GIVE_IRIG_TIME 0x04 // only supported if _pcps_has_irig_time()
+#define PCPS_SET_EVENT_TIME 0x14 ///< (-w) Write event time as ::PCPS_TIME_STAMP, only if ::_pcps_has_event_time
-#define PCPS_SET_TIME 0x10
-/* on error, return PCPS_ERR_STIME */
+#define PCPS_IRQ_NONE 0x20 ///< (-w) Disable IRQs
+#define PCPS_IRQ_1_SEC 0x21 ///< (-w) Enable IRQ per 1 second
+#define PCPS_IRQ_1_MIN 0x22 ///< (-w) Enable IRQ per 1 minute (deprecated)
+#define PCPS_IRQ_10_MIN 0x24 ///< (-w) Enable IRQ per 10 minutes (deprecated)
+#define PCPS_IRQ_30_MIN 0x28 ///< (-w) Enable IRQ per 10 minutes (deprecated)
-/* Attention: The code below can be used EXCLUSIVELY */
-/* with a GPS167PCI with customized CERN firmware !! */
-/* _pcps_has_event_time() checks whether supported. */
-#define PCPS_SET_EVENT_TIME 0x14
+#define PCPS_GET_SERIAL 0x30 ///< (r-) Read serial settings as ::PCPS_SERIAL, deprecated by ::PC_GPS_ALL_PORT_INFO
+#define PCPS_SET_SERIAL 0x31 ///< (-w) Write serial settings as ::PCPS_SERIAL, deprecated by ::PC_GPS_PORT_SETTINGS_IDX, returns ::MBG_ERR_CFG on error
-#define PCPS_IRQ_NONE 0x20
-#define PCPS_IRQ_1_SEC 0x21
-#define PCPS_IRQ_1_MIN 0x22
-#define PCPS_IRQ_10_MIN 0x24
-#define PCPS_IRQ_30_MIN 0x28
+#define PCPS_GET_TZCODE 0x32 ///< (r-) Read ::PCPS_TZCODE, only if ::_pcps_has_tzcode
+#define PCPS_SET_TZCODE 0x33 ///< (-w) Write ::PCPS_TZCODE, only if ::_pcps_has_tzcode, returns ::MBG_ERR_CFG on error
-#define PCPS_GET_SERIAL 0x30
-#define PCPS_SET_SERIAL 0x31
-/* on error, return PCPS_ERR_CFG */
+#define PCPS_GET_PCPS_TZDL 0x34 ///< (r-) Read ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl
+#define PCPS_SET_PCPS_TZDL 0x35 ///< (-w) Write ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl, returns ::MBG_ERR_CFG on error
-typedef uint8_t PCPS_SERIAL;
+#define PCPS_GET_REF_OFFS 0x36 ///< (r-) Read ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs
+#define PCPS_SET_REF_OFFS 0x37 ///< (-w) Write ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs, returns ::MBG_ERR_CFG on error
+#define PCPS_GET_OPT_INFO 0x38 ///< (r-) Read ::MBG_OPT_INFO, only if ::_pcps_has_opt_flags
+#define PCPS_SET_OPT_SETTINGS 0x39 ///< (-w) Write ::MBG_OPT_SETTINGS, only if ::_pcps_has_opt_flags, returns ::MBG_ERR_CFG on error
-#define PCPS_GET_TZCODE 0x32
-#define PCPS_SET_TZCODE 0x33
-/* on error, return PCPS_ERR_CFG */
+#define PCPS_GET_IRIG_RX_INFO 0x3A ///< (r-) Read ::IRIG_INFO, only if ::_pcps_is_irig_rx
+#define PCPS_SET_IRIG_RX_SETTINGS 0x3B ///< (-w) Write ::IRIG_SETTINGS, only if ::_pcps_is_irig_rx, returns ::MBG_ERR_CFG on error
-typedef uint8_t PCPS_TZCODE;
+#define PCPS_GET_IRIG_TX_INFO 0x3C ///< (r-) Read ::IRIG_INFO, only if ::_pcps_has_irig_tx
+#define PCPS_SET_IRIG_TX_SETTINGS 0x3D ///< (-w) Write ::IRIG_SETTINGS, only if ::_pcps_has_irig_tx, returns ::MBG_ERR_CFG on error
-/* the following codes are used with the PCPS_TZCODE parameter: */
-enum
-{
- PCPS_TZCODE_CET_CEST, /* default as broadcasted by DCF77 (UTC+1h/UTC+2h) */
- PCPS_TZCODE_CET, /* always CET (UTC+1h), discard DST */
- PCPS_TZCODE_UTC, /* always UTC */
- PCPS_TZCODE_EET_EEST, /* East European Time, CET/CEST + 1h */
- N_PCPS_TZCODE /* the number of valid codes */
-};
+#define PCPS_GET_SYNTH 0x3E ///< (r-) Read ::SYNTH, only if ::_pcps_has_synth
+#define PCPS_SET_SYNTH 0x3F ///< (-w) Write ::SYNTH, only if ::_pcps_has_synth, returns ::MBG_ERR_CFG on error
-/* the definitions below are for compatibily only: */
-#define PCPS_TZCODE_MEZMESZ PCPS_TZCODE_CET_CEST
-#define PCPS_TZCODE_MEZ PCPS_TZCODE_CET
-#define PCPS_TZCODE_OEZ PCPS_TZCODE_EET_EEST
+#define PCPS_GIVE_FW_ID_1 0x40 ///< (r-) Read first ::PCPS_FIFO_SIZE chars of firmware ID
+#define PCPS_GIVE_FW_ID_2 0x41 ///< (r-) Read last ::PCPS_FIFO_SIZE chars of firmware ID
+#define PCPS_GIVE_SERNUM 0x42 ///< (r-) Read serial number as ::PCPS_SN_STR, only if ::_pcps_has_sernum
+#define PCPS_GENERIC_IO 0x43 ///< (rw) See ::pcps_generic_io or ::_mbgdevio_gen_io
+#define PCPS_GET_SYNTH_STATE 0x44 ///< (r-) Read ::SYNTH_STATE, only if ::_pcps_has_synth
+#define PCPS_GET_IRIG_CTRL_BITS 0x45 ///< (r-) Read ::MBG_IRIG_CTRL_BITS, only if ::_pcps_has_irig_ctrl_bits
+#define PCPS_GET_RAW_IRIG_DATA 0x46 ///< (r-) Read ::MBG_RAW_IRIG_DATA, only if ::_pcps_has_raw_irig_data
+#define PCPS_GET_STATUS_PORT 0x4B ///< (r-) Read ::PCPS_STATUS_PORT
+#define PCPS_GET_DEBUG_STATUS 0x4C ///< (r-) Read ::MBG_DEBUG_STATUS, only if ::_pcps_has_debug_status
-#define PCPS_GET_PCPS_TZDL 0x34
-#define PCPS_SET_PCPS_TZDL 0x35
-/* on error, return PCPS_ERR_CFG */
+/// @note Command codes 0x4D, 0x4E, and 0x4F are reserved.
+#define PCPS_READ_GPS_DATA 0x50 ///< (r-) Read large data structure, see ::PC_GPS_CMD_CODES
+#define PCPS_WRITE_GPS_DATA 0x51 ///< (-w) Write large data structure, see ::PC_GPS_CMD_CODES
-/**
- * The structures below can be used to configure a clock's
- * time zone/daylight saving setting. This structure is shorter
- * than the TZDL structure used with GPS clocks.
- */
-typedef struct
-{
- // The year_or_wday field below contains the full year number
- // or 0..6 == Sun..Sat if the DL_AUTO_FLAG is set; see below.
- uint16_t year_or_wday;
- uint8_t month;
- uint8_t mday;
- uint8_t hour;
- uint8_t min;
-} PCPS_DL_ONOFF;
+#define PCPS_CLR_UCAP_BUFF 0x60 ///< (-w) No param., clear on-board capture FIFO, only if ::_pcps_has_ucap
+#define PCPS_GIVE_UCAP_ENTRIES 0x61 ///< (r-) Read ::PCPS_UCAP_ENTRIES, only if ::_pcps_has_ucap
+#define PCPS_GIVE_UCAP_EVENT 0x62 ///< (r-) Return oldest event as ::PCPS_HR_TIME, only if ::_pcps_has_ucap
-#define _mbg_swab_pcps_dl_onoff( _p ) \
-{ \
- _mbg_swab16( &(_p)->year_or_wday ); \
-}
+#define PCPS_GET_CORR_INFO 0x63 ///< (r-) Read ::CORR_INFO structure, only if ::_pcps_has_pzf
+#define PCPS_GET_TR_DISTANCE 0x64 ///< (r-) Read ::TR_DISTANCE, only if ::_pcps_has_tr_distance
+#define PCPS_SET_TR_DISTANCE 0x65 ///< (-w) Write ::TR_DISTANCE, only if ::_pcps_has_tr_distance
-/**
- * If the field year_or_wday is or'ed with the constant DL_AUTO_FLAG
- * defined below then this means that start and end of daylight saving
- * time shall be computed automatically for each year. In this case
- * the remaining bits represent the day-of-week after the specified
- * mday/month at which the change shall occur. If that flag is not set
- * then the field contains the full four-digit year number and the
- * mday/month values specify the exact date of that year.
- */
-#define DL_AUTO_FLAG 0x8000 // also defined in gpsdefs.h
+#define PCPS_CLR_EVT_LOG 0x66 ///< (-w) Write clear on-board event log, only if ::_pcps_has_evt_log
+#define PCPS_NUM_EVT_LOG_ENTRIES 0x67 ///< (r-) Read ::MBG_NUM_EVT_LOG_ENTRIES, only if ::_pcps_has_evt_log
+#define PCPS_FIRST_EVT_LOG_ENTRY 0x68 ///< (r-) Read first (oldest) ::MBG_EVT_LOG_ENTRY, only if ::_pcps_has_evt_log
+#define PCPS_NEXT_EVT_LOG_ENTRY 0x69 ///< (r-) Read next ::MBG_EVT_LOG_ENTRY, only if ::_pcps_has_evt_log
-typedef struct
-{
- int16_t offs; /**< offset from UTC to local time [min] */
- int16_t offs_dl; /**< additional offset if DST enabled [min] */
- PCPS_DL_ONOFF tm_on; /**< date/time when daylight saving starts */
- PCPS_DL_ONOFF tm_off; /**< date/time when daylight saving ends */
-} PCPS_TZDL;
+#define PCPS_FORCE_RESET 0x80 ///< (-w) No param., reset the device (deprecated, this can lock up the computer!!)
-#define _mbg_swab_pcps_tzdl( _p ) \
-{ \
- _mbg_swab16( &(_p)->offs ); \
- _mbg_swab16( &(_p)->offs_dl ); \
- _mbg_swab_pcps_dl_onoff( &(_p)->tm_on ); \
- _mbg_swab_pcps_dl_onoff( &(_p)->tm_off ); \
-}
+/// @note Command codes 0xF0 through 0xFF are reserved.
+/** @} anchor PCPS_CMD_CODES */
-#define PCPS_GET_REF_OFFS 0x36
-#define PCPS_SET_REF_OFFS 0x37
-/* on error, return PCPS_ERR_CFG */
-/* The associated type MBG_REF_OFFS is defined in gpsdefs.h. */
+#if _IS_MBG_FIRMWARE
+/**
+ * @brief Deprecated command group codes
+ *
+ * @deprecated These group codes are deprecated.
+ * They should not be used anymore but removed
+ * from existing source code. The explicite command
+ * codes @ref PCPS_CMD_CODES should be used instead.
+ *
+ * @anchor PCPS_CMD_GROUP_CODES @{ */
-#define PCPS_GET_OPT_INFO 0x38
-#define PCPS_SET_OPT_SETTINGS 0x39
-/* on error, return PCPS_ERR_CFG */
+#define PCPS_GIVE_TIME_GROUP 0x00
+#define PCPS_SET_TIME_GROUP 0x10
+#define PCPS_IRQ_GROUP 0x20
+#define PCPS_CFG_GROUP 0x30
+#define PCPS_GIVE_DATA_GROUP 0x40
+#define PCPS_GPS_DATA_GROUP 0x50
+#define PCPS_CTRL_GROUP 0x60
+#define PCPS_CFG2_GROUP 0x70
-/* The associated structures MBG_OPT_INFO and MBG_OPT_SETTINGS
- are defined in gpsdefs.h. */
+/** @} anchor PCPS_CMD_GROUP_CODES */
+#endif // _IS_MBG_FIRMWARE
-#define PCPS_GET_IRIG_RX_INFO 0x3A
-#define PCPS_SET_IRIG_RX_SETTINGS 0x3B
-/* on error, return PCPS_ERR_CFG */
-#define PCPS_GET_IRIG_TX_INFO 0x3C
-#define PCPS_SET_IRIG_TX_SETTINGS 0x3D
-/* on error, return PCPS_ERR_CFG */
-/* The associated structures IRIG_INFO and IRIG_SETTINGS
- are defined in gpsdefs.h. */
+#if !defined( MBG_CMD_TABLE_EXT )
+ #define MBG_CMD_TABLE_EXT _mbg_cn_table_end()
+#endif
+/**
+ * @brief An initializer for a table of code/name entries of non-GPS commands.
+ *
+ * This can e.g. initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
+ * and may be helpful when debugging.
+ *
+ * @see @ref PCPS_CMD_CODES
+ */
+#define PCPS_CMD_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( PCPS_GIVE_TIME ), /* 0x00 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_TIME_NOCLEAR ), /* 0x01 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_SYNC_TIME ), /* 0x02 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_HR_TIME ), /* 0x03 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_IRIG_TIME ), /* 0x04 */ \
+ _mbg_cn_table_entry( PCPS_SET_TIME ), /* 0x10 */ \
+ _mbg_cn_table_entry( PCPS_SET_EVENT_TIME ), /* 0x14 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_NONE ), /* 0x20 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_1_SEC ), /* 0x21 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_1_MIN ), /* 0x22 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_10_MIN ), /* 0x24 */ \
+ _mbg_cn_table_entry( PCPS_IRQ_30_MIN ), /* 0x28 */ \
+ _mbg_cn_table_entry( PCPS_GET_SERIAL ), /* 0x30 */ \
+ _mbg_cn_table_entry( PCPS_SET_SERIAL ), /* 0x31 */ \
+ _mbg_cn_table_entry( PCPS_GET_TZCODE ), /* 0x32 */ \
+ _mbg_cn_table_entry( PCPS_SET_TZCODE ), /* 0x33 */ \
+ _mbg_cn_table_entry( PCPS_GET_PCPS_TZDL ), /* 0x34 */ \
+ _mbg_cn_table_entry( PCPS_SET_PCPS_TZDL ), /* 0x35 */ \
+ _mbg_cn_table_entry( PCPS_GET_REF_OFFS ), /* 0x36 */ \
+ _mbg_cn_table_entry( PCPS_SET_REF_OFFS ), /* 0x37 */ \
+ _mbg_cn_table_entry( PCPS_GET_OPT_INFO ), /* 0x38 */ \
+ _mbg_cn_table_entry( PCPS_SET_OPT_SETTINGS ), /* 0x39 */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_RX_INFO ), /* 0x3A */ \
+ _mbg_cn_table_entry( PCPS_SET_IRIG_RX_SETTINGS ), /* 0x3B */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_TX_INFO ), /* 0x3C */ \
+ _mbg_cn_table_entry( PCPS_SET_IRIG_TX_SETTINGS ), /* 0x3D */ \
+ _mbg_cn_table_entry( PCPS_GET_SYNTH ), /* 0x3E */ \
+ _mbg_cn_table_entry( PCPS_SET_SYNTH ), /* 0x3F */ \
+ _mbg_cn_table_entry( PCPS_GIVE_FW_ID_1 ), /* 0x40 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_FW_ID_2 ), /* 0x41 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_SERNUM ), /* 0x42 */ \
+ _mbg_cn_table_entry( PCPS_GENERIC_IO ), /* 0x43 */ \
+ _mbg_cn_table_entry( PCPS_GET_SYNTH_STATE ), /* 0x44 */ \
+ _mbg_cn_table_entry( PCPS_GET_IRIG_CTRL_BITS ), /* 0x45 */ \
+ _mbg_cn_table_entry( PCPS_GET_RAW_IRIG_DATA ), /* 0x46 */ \
+ _mbg_cn_table_entry( PCPS_GET_STATUS_PORT ), /* 0x4B */ \
+ _mbg_cn_table_entry( PCPS_GET_DEBUG_STATUS ), /* 0x4C */ \
+ _mbg_cn_table_entry( PCPS_READ_GPS_DATA ), /* 0x50 */ \
+ _mbg_cn_table_entry( PCPS_WRITE_GPS_DATA ), /* 0x51 */ \
+ _mbg_cn_table_entry( PCPS_CLR_UCAP_BUFF ), /* 0x60 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_UCAP_ENTRIES ), /* 0x61 */ \
+ _mbg_cn_table_entry( PCPS_GIVE_UCAP_EVENT ), /* 0x62 */ \
+ _mbg_cn_table_entry( PCPS_GET_CORR_INFO ), /* 0x63 */ \
+ _mbg_cn_table_entry( PCPS_GET_TR_DISTANCE ), /* 0x64 */ \
+ _mbg_cn_table_entry( PCPS_SET_TR_DISTANCE ), /* 0x65 */ \
+ _mbg_cn_table_entry( PCPS_CLR_EVT_LOG ), /* 0x66 */ \
+ _mbg_cn_table_entry( PCPS_NUM_EVT_LOG_ENTRIES ), /* 0x67 */ \
+ _mbg_cn_table_entry( PCPS_FIRST_EVT_LOG_ENTRY ), /* 0x68 */ \
+ _mbg_cn_table_entry( PCPS_NEXT_EVT_LOG_ENTRY ), /* 0x69 */ \
+ _mbg_cn_table_entry( PCPS_FORCE_RESET ), /* 0x80 */ \
+ MBG_CMD_TABLE_EXT, \
+ _mbg_cn_table_end() \
+}
-#define PCPS_GET_SYNTH 0x3E
-#define PCPS_SET_SYNTH 0x3F
-/* on error, return PCPS_ERR_CFG */
-/* The associated structure SYNTH is defined in gpsdefs.h. */
+/**
+ * @brief Bus level command return codes
+ *
+ * @deprecated These codes are deprecated and @ref MBG_RETURN_CODES should be used
+ * instead which provide corresponding symbols with same numeric values.
+ *
+ * @anchor PCPS_LEVEL_CMD_RETURN_CODES @{ */
-#define PCPS_GIVE_FW_ID_1 0x40
-#define PCPS_GIVE_FW_ID_2 0x41
-#define PCPS_GIVE_SERNUM 0x42
-#define PCPS_GENERIC_IO 0x43
-#define PCPS_GET_SYNTH_STATE 0x44
-#define PCPS_GET_IRIG_CTRL_BITS 0x45
-#define PCPS_GET_RAW_IRIG_DATA 0x46
+#define PCPS_SUCCESS 0 ///< OK, no error (see ::MBG_SUCCESS)
+#define PCPS_ERR_STIME -1 ///< invalid date/time/status passed (see ::MBG_ERR_STIME)
+#define PCPS_ERR_CFG -2 ///< invalid parms for a cmd writing config parameters (see ::MBG_ERR_CFG)
+/** @} anchor PCPS_LEVEL_CMD_RETURN_CODES */
-#define PCPS_GET_STATUS_PORT 0x4B
-#define PCPS_GET_DEBUG_STATUS 0x4C
-// expects sizeof( MBG_DEBUG_STATUS ) chars
-// Command codes 0x4D, 0x4E, and 0x4F are reserved.
+#if !defined( BITMASK )
+ #define BITMASK( b ) ( ( 1 << b ) - 1 )
+#endif
-#define PCPS_READ_GPS_DATA 0x50
-#define PCPS_WRITE_GPS_DATA 0x51
+/** @brief The size of a bus level device's command/data FIFO */
+#define PCPS_FIFO_SIZE 16
-#define PCPS_CLR_UCAP_BUFF 0x60
-#define PCPS_GIVE_UCAP_ENTRIES 0x61
-#define PCPS_GIVE_UCAP_EVENT 0x62
+/** @brief A data buffer for a bus level device's command/data */
+typedef int8_t PCPS_BUFF[PCPS_FIFO_SIZE];
-typedef struct
-{
- uint32_t used; /**< the number of saved capture events */
- uint32_t max; /**< capture buffer size */
-} PCPS_UCAP_ENTRIES;
-#define _mbg_swab_pcps_ucap_entries( _p ) \
-{ \
- _mbg_swab32( &(_p)->used ); \
- _mbg_swab32( &(_p)->max ); \
-}
+/** @brief The maximum length of an ID string, including terminating 0 */
+#define PCPS_ID_SIZE ( 2 * PCPS_FIFO_SIZE + 1 ) ///< ASCIIZ string
+/** @brief A buffer for an ID string, including terminating 0 */
+typedef char PCPS_ID_STR[PCPS_ID_SIZE];
-#define PCPS_GET_CORR_INFO 0x63 // read CORR_INFO structure, only if _pcps_has_pzf()
-#define PCPS_GET_TR_DISTANCE 0x64 // read TR_DISTANCE, only if _pcps_has_tr_distance()
-#define PCPS_SET_TR_DISTANCE 0x65 // write TR_DISTANCE, only if _pcps_has_tr_distance()
+/** @brief The maximum length of a serial number string, including terminating 0 */
+#define PCPS_SN_SIZE ( PCPS_FIFO_SIZE + 1 ) ///< ASCIIZ string
+/** @brief A buffer for a serial number string, including terminating 0 */
+typedef char PCPS_SN_STR[PCPS_SN_SIZE];
/**
- special -- use with care !
-*/
-#define PCPS_FORCE_RESET 0x80
+ * @brief Seconds since epoch 1970-01-01, usually %UTC scale
+ *
+ * Used with ::PCPS_TIME_STAMP.
+ *
+ * @see ::PCPS_FRAC_32
+ * @see ::PCPS_TIME_STAMP
+ */
+typedef uint32_t PCPS_SECONDS;
-// Command codes 0xF0 through 0xFF are reserved.
+#define _mbg_swab_pcps_seconds( _p ) \
+do \
+{ \
+ _mbg_swab32( _p ); \
+} while ( 0 )
-/** @} group_cmd_bytes */
-/* Codes returned when commands with parameters have been passed */
-/* to the board */
-#define PCPS_SUCCESS 0 /**< OK, no error */
-#define PCPS_ERR_STIME -1 /**< invalid date/time/status passed */
-#define PCPS_ERR_CFG -2 /**< invalid parms for a cmd writing config parameters */
+/**
+ * @brief 32 bit binary fraction of a second
+ *
+ * Used with ::PCPS_TIME_STAMP, e.g.
+ * 0x80000000 == 0.5 s, 0xFFFFFFFF == 0.9999999.. s, etc.
+ * Use ::bin_frac_32_to_dec_frac for conversion.
+ *
+ * @see ::bin_frac_32_to_dec_frac
+ * @see ::PCPS_SECONDS
+ * @see ::PCPS_TIME_STAMP
+ * @see ::PCPS_HRT_FRAC_SCALE
+ * @see ::PCPS_HRT_FRAC_SCALE_FMT
+ */
+typedef uint32_t PCPS_FRAC_32;
+#define _mbg_swab_pcps_frac_32( _p ) \
+do \
+{ \
+ _mbg_swab32( _p ); \
+} while ( 0 )
-#ifndef BITMASK
- #define BITMASK( b ) ( ( 1 << b ) - 1 )
-#endif
+/**
+ * @brief A high resolution time stamp
+ */
+typedef struct
+{
+ PCPS_SECONDS sec; ///< seconds since 1970, usually %UTC scale
+ PCPS_FRAC_32 frac; ///< binary fractions of second, see ::PCPS_FRAC_32
-/** The size of the plug-in card's on-board FIFO */
-#define PCPS_FIFO_SIZE 16
+} PCPS_TIME_STAMP;
-typedef int8_t PCPS_BUFF[PCPS_FIFO_SIZE];
+#define _mbg_swab_pcps_time_stamp( _p ) \
+do \
+{ \
+ _mbg_swab_pcps_seconds( &(_p)->sec ); \
+ _mbg_swab_pcps_frac_32( &(_p)->frac ); \
+} while ( 0 )
-#define PCPS_ID_SIZE ( 2 * PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
-typedef char PCPS_ID_STR[PCPS_ID_SIZE];
+#ifndef PCPS_HRT_FRAC_SCALE
+ /**
+ * @brief Scale to be used to print ::PCPS_TIME_STAMP::frac values
+ *
+ * The function ::frac_sec_from_bin can be used for the conversion.
+ *
+ * @see ::PCPS_HRT_FRAC_SCALE_FMT
+ */
+ #define PCPS_HRT_FRAC_SCALE 10000000UL
+#endif
+
+#ifndef PCPS_HRT_FRAC_SCALE_FMT
+ /**
+ * @brief Format specifier used to print ::PCPS_TIME_STAMP::frac values
+ *
+ * Used to print values scaled with ::frac_sec_from_bin called
+ * with ::PCPS_HRT_FRAC_SCALE.
+ *
+ * @see ::PCPS_HRT_FRAC_SCALE
+ */
+ #define PCPS_HRT_FRAC_SCALE_FMT "%07lu"
+#endif
-#define PCPS_SN_SIZE ( PCPS_FIFO_SIZE + 1 ) /**< ASCIIZ string */
-typedef char PCPS_SN_STR[PCPS_SN_SIZE];
/**
- * The structure has been introduced to be able to handle
- * high resolution time stamps.
+ * @brief Extended status code
+ *
+ * Low byte corresponds to ::PCPS_TIME_STATUS, high byte
+ * contains additional flags.
+ *
+ * @see ::PCPS_TIME_STATUS
+ * @see @ref PCPS_TIME_STATUS_FLAGS
*/
-typedef struct
-{
- uint32_t sec; /**< seconds since 1970 (UTC) */
- uint32_t frac; /**< fractions of second ( 0xFFFFFFFF == 0.9999.. sec) */
-} PCPS_TIME_STAMP;
+typedef uint16_t PCPS_TIME_STATUS_X;
-#define _mbg_swab_pcps_time_stamp( _p ) \
-{ \
- _mbg_swab32( &(_p)->sec ); \
- _mbg_swab32( &(_p)->frac ); \
-}
+#define _mbg_swab_pcps_time_status_x( _p ) _mbg_swab16( _p )
+typedef struct
+{
+ PCPS_TIME_STATUS_X set_mask;
+ PCPS_TIME_STATUS_X clr_mask;
-// Depending on the target environment define a data type
-// which can be used to convert binary fractions without
-// range overflow.
-#if defined( MBG_TGT_UNIX )
- #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
-#elif defined( MBG_TGT_WIN32 )
- #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
-#elif defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
- #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t
-#else
- #define PCPS_HRT_FRAC_CONVERSION_TYPE double
-#endif
+} PCPS_TIME_STATUS_X_MASKS;
-// Max value of PCPS_TIME_STAMP::frac + 1 used for scaling
-#define PCPS_HRT_BIN_FRAC_SCALE ( (PCPS_HRT_FRAC_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000
+#define _mbg_swab_pcps_time_status_x_masks( _p ) \
+do \
+{ \
+ _mbg_swab_pcps_time_status_x( &(_p)->set_mask ); \
+ _mbg_swab_pcps_time_status_x( &(_p)->clr_mask ); \
+} while ( 0 )
-// The scale and format to be used to print the fractions
-// of a second as returned in the PCPS_TIME_STAMP structure.
-// The function frac_sec_from_bin() can be used for
-// the conversion.
-#ifndef PCPS_HRT_FRAC_SCALE
- #define PCPS_HRT_FRAC_SCALE 10000000UL
-#endif
-#ifndef PCPS_HRT_FRAC_SCALE_FMT
- #define PCPS_HRT_FRAC_SCALE_FMT "%07lu"
-#endif
+/**
+ * @brief Definitions used to report a signal strength
+ *
+ * @anchor PCPS_SIG_VAL_DEFS @{ */
+/**
+ * @brief A data type used to report the signal value
+ */
+typedef uint8_t PCPS_SIG_VAL;
+// The following constants are used to draw a signal bar
+// depending on a DCF77 clock's signal value:
+#define PCPS_SIG_BIAS 55
+#define PCPS_SIG_ERR 1
+#define PCPS_SIG_MIN 20
+#define PCPS_SIG_MAX 68
-typedef uint16_t PCPS_TIME_STATUS_X; /**< extended status */
+// These constants are used by non-DCF77 devices to indicate
+// if an input signal is available or not:
+#define PCPS_SIG_LVL_SIG_NOT_AVAIL 0
+#define PCPS_SIG_LVL_SIG_AVAIL 128
+
+/** @} anchor PCPS_SIG_VAL_DEFS */
-#define _mbg_swab_pcps_time_status_x( _p ) _mbg_swab16( _p )
/**
- * The structure has been introduced to be able to read the
- * current time with higher resolution of fractions of seconds and
- * more detailed information on the time zone and status.
- * The structure is returned if the new command #PCPS_GIVE_HR_TIME
- * is written to the board.
- * _pcps_has_hr_time() checks whether supported.
- *
- * Newer GPS boards also accept the #PCPS_GIVE_UCAP_EVENT command
- * to return user capture event times using this format. In this
- * case, the "signal" field contains the number of the capture
- * input line, e.g. 0 or 1.
- * _pcps_has_ucap() checks whether supported.
+ * @brief High resolution time including status and local time offset
+ *
+ * Used to read time with high resolution of fractions of seconds and
+ * more detailed information on the local time offset and status.
+ * Should be prefered over ::PCPS_TIME.
+ *
+ * ::_pcps_has_hr_time checks whether the command ::PCPS_GIVE_TIME is
+ * supported to read a device's current time using this format.
+ *
+ * Newer devices providing time capture input may also accept the
+ * ::PCPS_GIVE_UCAP_EVENT command to read user capture event times
+ * using this format. In this case, the "signal" field contains
+ * the number of the capture input line, e.g. 0 or 1.
+ * ::_pcps_has_ucap checks whether this is supported.
*/
typedef struct
{
- PCPS_TIME_STAMP tstamp; /**< High resolution time stamp (UTC) */
- int32_t utc_offs; /**< UTC offs [sec] (loc_time = UTC + utc_offs) */
- PCPS_TIME_STATUS_X status; /**< status flags as defined below */
- uint8_t signal; /**< for normal time, the relative RF signal level, for ucap, the channel number */
+ PCPS_TIME_STAMP tstamp; ///< High resolution time stamp (%UTC)
+ int32_t utc_offs; ///< %UTC offs [sec] (loc_time = tstamp + utc_offs)
+ PCPS_TIME_STATUS_X status; ///< status bits, see @ref PCPS_TIME_STATUS_FLAGS
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS, or capture input channel number
+
} PCPS_HR_TIME;
#define _mbg_swab_pcps_hr_time( _p ) \
+do \
{ \
_mbg_swab_pcps_time_stamp( &(_p)->tstamp ); \
_mbg_swab32( &(_p)->utc_offs ); \
_mbg_swab_pcps_time_status_x( &(_p)->status ); \
-}
+} while ( 0 )
+/**
+ * @brief Time synchronization status
+ *
+ * Used by legacy API calls. New API calls provide
+ * an extended status word ::PCPS_TIME_STATUS_X.
+ *
+ * @see ::PCPS_TIME_STATUS_FLAGS_COMMON
+ * @see ::PCPS_TIME_STATUS_X
+ */
typedef uint8_t PCPS_TIME_STATUS;
-/**
- The standard structure used to read times from the board.
- The time has a resultion of 10 ms.
-*/
-typedef struct PCPS_TIME_s
+
+
+/**
+ * @brief Local calendar date and time, plus sync status
+ *
+ * This legacy structure is supported by all bus level devices but
+ * has a time resultion of 10 ms only. For more accurate time stamps
+ * the structures ::PCPS_HR_TIME and ::PCPS_TIME_STAMP should be
+ * used preferably.
+ *
+ * @see ::PCPS_HR_TIME
+ * @see ::PCPS_TIME_STAMP
+ * @see ::PCPS_STIME
+ */
+typedef struct
{
- uint8_t sec100; /**< hundredths of seconds, 0..99 */
- uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
- uint8_t min; /**< minutes, 0..59 */
- uint8_t hour; /**< hours, 0..23 */
-
- uint8_t mday; /**< day of month, 0..31 */
- uint8_t wday; /**< day of week, 1..7, 1 = Monday */
- uint8_t month; /**< month, 1..12 */
- uint8_t year; /**< year of the century, 0..99 */
-
- PCPS_TIME_STATUS status; /**< status bits, see below */
- uint8_t signal; /**< relative signal strength, range depends on device type */
- int8_t offs_utc; /**< [hours], 0 if !_pcps_has_utc_offs() */
+ uint8_t sec100; ///< hundredths of seconds, 0..99, 10 ms resolution
+ uint8_t sec; ///< seconds, 0..59, or 60 if leap second
+ uint8_t min; ///< minutes, 0..59
+ uint8_t hour; ///< hours, 0..23
+
+ uint8_t mday; ///< day of month, 0..31
+ uint8_t wday; ///< day of week, 1..7, 1 = Monday
+ uint8_t month; ///< month, 1..12
+ uint8_t year; ///< year of the century, 0..99
+
+ PCPS_TIME_STATUS status; ///< status bits, see ::PCPS_TIME_STATUS_FLAGS_COMMON
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+ int8_t offs_utc; ///< [hours], 0 if not ::_pcps_has_utc_offs
+
} PCPS_TIME;
-/**
- The structure is passed as parameter with the PCPS_SET_TIME cmd
-*/
-typedef struct PCPS_STIME_s
+
+/**
+ * @brief Date time and status used with the ::PCPS_SET_TIME command
+ *
+ * Similar to ::PCPS_TIME, but missing the ::PCPS_TIME::signal
+ * and ::PCPS_TIME::offs_utc fields.
+ *
+ * @see ::PCPS_TIME
+ */
+typedef struct
{
- uint8_t sec100; /**< hundredths of seconds, 0..99 */
- uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
- uint8_t min; /**< minutes, 0..59 */
- uint8_t hour; /**< hours, 0..23 */
+ uint8_t sec100; ///< hundredths of seconds, 0..99, 10 ms resolution
+ uint8_t sec; ///< seconds, 0..59, or 60 if leap second
+ uint8_t min; ///< minutes, 0..59
+ uint8_t hour; ///< hours, 0..23
+
+ uint8_t mday; ///< day of month, 0..31
+ uint8_t wday; ///< day of week, 1..7, 1 = Monday
+ uint8_t month; ///< month, 1..12
+ uint8_t year; ///< year of the century, 0..99
- uint8_t mday; /**< day of month, 0..31 */
- uint8_t wday; /**< day of week, 1..7, 1 = Monday */
- uint8_t month; /**< month, 1..12 */
- uint8_t year; /**< year of the century, 0..99 */
+ PCPS_TIME_STATUS status; ///< status bits, see ::PCPS_TIME_STATUS_FLAGS_COMMON
- PCPS_TIME_STATUS status; /**< status bits, see below */
} PCPS_STIME;
#ifdef _C166
- // This is a workaround to specify some structure sizes. The C166 compiler
- // always reports an even structure size although the structure size may
- // be odd due to the number of bytes. This might lead to errors between
+ // This is a workaround to specify some structure sizes. The C166 compiler
+ // always reports an even structure size although the structure size may
+ // be odd due to the number of bytes. This might lead to errors between
// the C166 and other build environments.
#define sizeof_PCPS_TIME ( sizeof( PCPS_TIME ) - 1 )
#define sizeof_PCPS_STIME ( sizeof( PCPS_STIME ) - 1 )
@@ -1005,129 +1181,174 @@ typedef union
{
PCPS_TIME t;
PCPS_STIME stime;
+
} PCPS_TIME_UNION;
/**
- The structure below can be used to read the raw IRIG time
- from an IRIG receiver card, if the card supports this.
- See the #PCPS_GIVE_IRIG_TIME command.
-
- The granularity of the value in the .frac field depends on
- the update interval of the structure as implementation
- in the firmware. I.e. if the raw IRIG time is updated
- only once per second, the .frac value can always be 0.
-*/
-typedef struct PCPS_IRIG_TIME_s
+ * @brief Raw IRIG time
+ *
+ * Used to read the raw IRIG time from an IRIG receiver card, if the card
+ * supports this. See the ::PCPS_GIVE_IRIG_TIME command.
+ *
+ * The granularity of the value in the ::PCPS_IRIG_TIME::frac field
+ * depends on the update interval at which the structure is updated
+ * by the firmeware. I.e., if the raw IRIG time is updated only
+ * once per second, the ::PCPS_IRIG_TIME::frac value can always be 0.
+ *
+ * @see @ref group_icode
+ * @see ::ICODE_RX_CODES
+ */
+typedef struct
{
- PCPS_TIME_STATUS_X status; /**< status bits, see below */
- int16_t offs_utc; /**< [minutes] */
- uint16_t yday; /**< day of year, 1..365/366 */
- uint16_t frac; /**< fractions of seconds, 0.1 ms units */
- uint8_t sec; /**< seconds, 0..59, or 60 if leap second */
- uint8_t min; /**< minutes, 0..59 */
- uint8_t hour; /**< hours, 0..23 */
- uint8_t year; /**< 2 digit year number, 0xFF if year not supp. by the IRIG code */
- uint8_t signal; /**< relative signal strength, range depends on device type */
- uint8_t reserved; /**< currently not used, always 0 */
+ PCPS_TIME_STATUS_X status; ///< status bits, see @ref PCPS_TIME_STATUS_FLAGS
+ int16_t offs_utc; ///< [minutes], 0 unless supported by the code format, see ::MSK_ICODE_RX_HAS_TZI
+ uint16_t yday; ///< day of year, 1..365/366
+ uint16_t frac; ///< fractions of seconds, 0.1 ms units
+ uint8_t sec; ///< seconds, 0..59, may be 60 for leap second
+ uint8_t min; ///< minutes, 0..59
+ uint8_t hour; ///< hours, 0..23
+ uint8_t year; ///< 2 digit year number, or ::IRIG_TIME_UNKNOWN_YEAR if year not supported
+ ///< by the time code, see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+ uint8_t reserved; ///< currently not used, always 0
+
} PCPS_IRIG_TIME;
#define _mbg_swab_pcps_irig_time( _p ) \
+do \
{ \
_mbg_swab_pcps_time_status_x( &(_p)->status ); \
_mbg_swab16( &(_p)->offs_utc ); \
_mbg_swab16( &(_p)->yday ); \
_mbg_swab16( &(_p)->frac ); \
-}
-
-
+} while ( 0 )
/**
- * Bit masks used with both PCPS_TIME_STATUS and PCPS_TIME_STATUS_X
+ * @brief A constant representing a 2 digit unknown IRIG year number
+ *
+ * Used with ::PCPS_IRIG_TIME::year
*/
-#define PCPS_FREER 0x01 /**< DCF77 clock running on xtal */
- /**< GPS receiver has not verified its position */
-
-#define PCPS_DL_ENB 0x02 /**< daylight saving enabled */
+#define IRIG_TIME_UNKNOWN_YEAR 0xFF
-#define PCPS_SYNCD 0x04 /**< clock has sync'ed at least once after pwr up */
-
-#define PCPS_DL_ANN 0x08 /**< a change in daylight saving is announced */
-
-#define PCPS_UTC 0x10 /**< a special UTC firmware is installed */
-
-#define PCPS_LS_ANN 0x20 /**< leap second announced */
- /**< (requires firmware rev. REV_PCPS_LS_ANN_...) */
-
-#define PCPS_IFTM 0x40 /**< the current time was set via PC */
- /**< (requires firmware rev. REV_PCPS_IFTM_...) */
-
-#define PCPS_INVT 0x80 /**< invalid time because battery was disconn'd */
/**
- * Bit masks used only with PCPS_TIME_STATUS_X
- */
-#define PCPS_LS_ENB 0x0100 /**< current second is leap second */
-#define PCPS_ANT_FAIL 0x0200 /**< antenna failure */
-#define PCPS_LS_ANN_NEG 0x0400 /**< announced leap second is negative */
-#define PCPS_SCALE_GPS 0x0800 /**< time stamp is GPS scale */
-#define PCPS_SCALE_TAI 0x1000 /**< time stamp is TAI scale */
+ * @brief Time status flags
+ *
+ * @anchor PCPS_TIME_STATUS_FLAGS @{ */
/**
- * Bit masks used only with time stamps representing user capture events
+ * @brief Legacy time status flags
+ *
+ * Bit masks used with both ::PCPS_TIME_STATUS and ::PCPS_TIME_STATUS_X
*/
-#define PCPS_UCAP_OVERRUN 0x2000 /**< events interval too short */
-#define PCPS_UCAP_BUFFER_FULL 0x4000 /**< events read too slow */
+enum PCPS_TIME_STATUS_FLAGS_COMMON
+{
+ PCPS_FREER = 0x01, ///< long wave or time code receiver running on xtal, satellite receiver has not verified its position
+ PCPS_DL_ENB = 0x02, ///< daylight saving currently enabled
+ PCPS_SYNCD = 0x04, ///< long wave or time code receiver has sync'ed at least once after pwr up, sat receiver is synchronized
+ PCPS_DL_ANN = 0x08, ///< a change in daylight saving status is announced
+ PCPS_UTC = 0x10, ///< returned time is always %UTC instead of some local time
+ PCPS_LS_ANN = 0x20, ///< leap second announced, for *very* old clocks see ::REV_PCPS_LS_ANN_PC31PS31
+ PCPS_IFTM = 0x40, ///< the current time has been set by an API call, for *very* old clocks see ::REV_PCPS_IFTM_PC31PS31
+ PCPS_INVT = 0x80 ///< invalid time because battery had been disconnected, or absolute time can't be decoded safely
+};
-/**
- * Bit masks used only with time stamps representing the current board time.
- * A DCF77 PZF receiver can set this bit if it is actually synchronized
- * using PZF correlation and thus provides higher accuracy than AM receivers.
- */
-#define PCPS_SYNC_PZF 0x2000 /**< same code as PCPS_UCAP_OVERRUN */
/**
- * Immediately after a clock has been accessed, subsequent accesses
- * are blocked for up to 1.5 msec to give the clock's microprocessor
- * some time to decode the incoming time signal.
- * The flag below is set if a program tries to read the PCPS_HR_TIME
- * during this interval. In this case the read function returns the
- * proper time stamp which is taken if the command byte is written,
- * however, the read function returns with delay.
- * This flag is not supported by all clocks.
+ * @brief Extended time status flags
+ *
+ * Bit masks used with ::PCPS_TIME_STATUS_X only
*/
-#define PCPS_IO_BLOCKED 0x8000
+enum PCPS_TIME_STATUS_FLAGS_EXT
+{
+ PCPS_LS_ENB = 0x0100, ///< current second is leap second
+ PCPS_ANT_FAIL = 0x0200, ///< antenna failure
+ PCPS_LS_ANN_NEG = 0x0400, ///< announced leap second is negative
+ PCPS_SCALE_GPS = 0x0800, ///< time stamp is GPS scale
+ PCPS_SCALE_TAI = 0x1000, ///< time stamp is TAI scale
+
+ PCPS_UCAP_OVERRUN = 0x2000, ///< events interval too short (capture events only)
+ PCPS_UCAP_BUFFER_FULL = 0x4000, ///< events read too slow (capture events only)
+
+ /**
+ * Bit masks used only with time stamps representing the current board time.
+ * A DCF77 PZF receiver can set this bit if it is actually synchronized
+ * using PZF correlation and thus provides higher accuracy than AM receivers.
+ * Same numeric code as ::PCPS_UCAP_OVERRUN
+ */
+ PCPS_SYNC_PZF = 0x2000,
+
+ /**
+ * Immediately after a clock has been accessed, subsequent accesses
+ * may be blocked for up to 1.5 msec to give the clock's microprocessor
+ * some time to decode the incoming time signal.
+ * The flag below is eventually set if a program tries to read ::PCPS_HR_TIME
+ * during this interval. In this case the read function returns the
+ * proper time stamp which is taken if the command byte is written,
+ * however, the read function returns with delay.
+ * This flag is not supported by all clocks.
+ */
+ PCPS_IO_BLOCKED = 0x8000
+};
+
+
/**
* This bit mask can be used to extract the time scale information out
* of a PCPS_TIME_STATUS_X value.
-*/
+ */
#define PCPS_SCALE_MASK ( PCPS_SCALE_TAI | PCPS_SCALE_GPS )
+/** @} anchor PCPS_TIME_STATUS_FLAGS */
+
+
+
+/**
+ * @brief Legacy definitions used to configure a device's serial port
+ *
+ * @deprecated This structure and the associated command codes
+ * are deprecated. ::PORT_SETTINGS, ::PORT_INFO and associated
+ * definitions should be used instead, if supported.
+ *
+ * @anchor PCPS_OLD_SERIAL_CFG @{ */
+
/**
- * Some DCF77 clocks have a serial interface that can be controlled
- * using the commands PCPS_SET_SERIAL and PCPS_GET_SERIAL. Both commands
- * use a parameter byte describing transmission speed, framing and mode
- * of operation. The parameter byte can be build using the constants
- * defined below, by or'ing one of the constants of each group, shifted
- * to the right position. PCPS_GET_SERIAL expects that parameter byte
- * and PCPS_GET_SERIAL returns the current configuration from the board.
- * _pcps_has_serial() checks whether supported.
- * For GPS clocks, please refer to the comments for the PCPS_GET_SERIAL
+ * @brief Configuration information for a device's serial port
+ *
+ * Used with ::PCPS_GET_SERIAL and ::PCPS_SET_SERIAL
+ *
+ * The serial interface on some old DCF77 clocks can be configured
+ * using the commands ::PCPS_SET_SERIAL and ::PCPS_GET_SERIAL.
+ * Both commands use a parameter byte describing transmission speed,
+ * framing and mode of operation. The parameter byte can be assembled
+ * using the constants defined in ::PCPS_BD_CODES, ::PCPS_FR_CODES,
+ * and ::PCPS_MOD_CODES, by or'ing one of the constants of each group,
+ * shifted to the right position. ::PCPS_GET_SERIAL expects that parameter
+ * byte and ::PCPS_GET_SERIAL returns the current configuration from
+ * the board.
+ * ::_pcps_has_serial checks whether supported.
+ * For old GPS clocks refer to the comments for the ::PCPS_GET_SERIAL
* command.
*/
+typedef uint8_t PCPS_SERIAL;
+
/**
- * Baud rate indices. The values below are obsolete and should
- * be replaced by the codes named MBG_BAUD_RATE_... which are
- * defined in gpsdefs.h. The resulting index numbers, however,
- * have not changed.
+ * @brief Deprecated baud rate indices
+ *
+ * @deprecated These values are deprecated.
+ * ::MBG_BAUD_RATE_CODES and associated structures
+ * should be used preferably.
+ *
+ * The sequence of codes matches the sequence
+ * defined in ::MBG_BAUD_RATE_CODES.
*/
-enum
+enum PCPS_BD_CODES
{
PCPS_BD_300,
PCPS_BD_600,
@@ -1136,233 +1357,429 @@ enum
PCPS_BD_4800,
PCPS_BD_9600,
PCPS_BD_19200,
- N_PCPS_BD /* number of codes */
+ N_PCPS_BD ///< number of codes
};
-#define PCPS_BD_BITS 4 /* field with in the cfg byte */
-#define PCPS_BD_SHIFT 0 /* num of bits to shift left */
+#define PCPS_BD_BITS 4 ///< field with in the cfg byte
+#define PCPS_BD_SHIFT 0 ///< num of bits to shift left
-/*
- * Initializers for a table of all baud rate strings
- * and values can be found in gpsdefs.h.
- */
/**
- * Unfortunately, the framing codes below can not simply be
- * replaced by the newer MBG_FRAMING_... definitions since
- * the order of indices does not match.
+ * @brief Deprecated framing code indices
+ *
+ * @deprecated These values are deprecated.
+ * ::MBG_FRAMING_CODES and associated structures
+ * should be used preferably.
+ *
+ * Unfortunately, these framing codes can *not* simply
+ * be replaced by the newer MBG_FRAMING_... definitions
+ * since the order of indices doesn't match.
*/
-enum
+enum PCPS_FR_CODES
{
PCPS_FR_8N1,
PCPS_FR_7E2,
PCPS_FR_8N2,
PCPS_FR_8E1,
- N_PCPS_FR_DCF /* number of valid codes */
+ N_PCPS_FR_DCF ///< number of valid codes
};
-#define PCPS_FR_BITS 2 /* field with in the cfg byte */
-#define PCPS_FR_SHIFT PCPS_BD_BITS /* num of bits to shift left */
+#define PCPS_FR_BITS 2 ///< field with in the cfg byte
+#define PCPS_FR_SHIFT PCPS_BD_BITS ///< num of bits to shift left
+
+
-/*
- * An initializer for a table of framing strings is only defined for
- * the new MBG_FRAMING_... definitions. For editing the serial port
- * configuration, the old codes above should be translated to the new
- * codes to unify handling inside the edit functions.
+/**
+ * @brief Deprecated codes for modes of operation
+ *
+ * @deprecated These values are deprecated.
+ * ::STR_MODES and associated structures
+ * should be used preferably.
+ *
+ * The sequence of codes matches the sequence
+ * defined in ::STR_MODES.
*/
+enum PCPS_MOD_CODES
+{
+ PCPS_MOD_REQ, ///< time string on request '?' only
+ PCPS_MOD_SEC, ///< time string once per second
+ PCPS_MOD_MIN, ///< time string once per minute
+ PCPS_MOD_RSVD, ///< reserved
+ N_PCPS_MOD_DCF ///< number of possible codes
+};
+
+#define PCPS_MOD_BITS 2 ///< field with in the cfg byte
+#define PCPS_MOD_SHIFT ( PCPS_BD_BITS + PCPS_FR_BITS ) ///< num of bits to shift left
-/**
- Modes of operation
+/** @} anchor PCPS_OLD_SERIAL_CFG */
- * Indices for modes of operation. The values below are obsolete
- * and should be replaced by the codes named STR_... which are
- * defined in gpsdefs.h. The resulting index numbers, however,
- * have not changed.
+
+
+/**
+ * @brief Type of variable to hold a TZ code
+ *
+ * This is used with the PCI interface but differs from ::TZCODE
+ * which is used with the binary protocol.
+ *
+ * @see ::TZCODE
+ * @see ::TZCODE_UNION
*/
-enum
+typedef uint8_t PCPS_TZCODE;
+
+
+/**
+ * @brief Enumeration of codes used with PCPS_TZCODE
+ */
+enum PCPS_TZCODES
{
- PCPS_MOD_REQ, /* time string on request '?' only */
- PCPS_MOD_SEC, /* time string once per second */
- PCPS_MOD_MIN, /* time string once per minute */
- PCPS_MOD_RSVD, /* reserved */
- N_PCPS_MOD_DCF /* number of possible codes */
+ PCPS_TZCODE_CET_CEST, ///< default as broadcast by DCF77 (UTC+1h/UTC+2h)
+ PCPS_TZCODE_CET, ///< always CET (UTC+1h), discard DST
+ PCPS_TZCODE_UTC, ///< always %UTC
+ PCPS_TZCODE_EET_EEST, ///< East European Time, CET/CEST + 1h
+ N_PCPS_TZCODE ///< the number of valid codes
};
-#define PCPS_MOD_BITS 2 /* field with in the cfg byte */
-#define PCPS_MOD_SHIFT ( PCPS_BD_BITS + PCPS_FR_BITS )
- /* num of bits to shift left */
+/* the definitions below are for compatibily only: */
+#define PCPS_TZCODE_MEZMESZ PCPS_TZCODE_CET_CEST
+#define PCPS_TZCODE_MEZ PCPS_TZCODE_CET
+#define PCPS_TZCODE_OEZ PCPS_TZCODE_EET_EEST
+
+
+/**
+ * @brief Daylight changeover specification
+ *
+ * Used as member field of ::PCPS_TZDL only. Most devices supporting
+ * conversion to local time support the ::TZDL structure instead.
+ *
+ * @see ::TZDL
+ */
+typedef struct
+{
+ uint16_t year_or_wday; ///< The full year number, or 0..6 == Sun..Sat if the ::DL_AUTO_FLAG is set
+ uint8_t month; ///< [1..12]
+ uint8_t mday; ///< [1..31]
+ uint8_t hour; ///< [0..23]
+ uint8_t min; ///< [0..59]
+
+} PCPS_DL_ONOFF;
+
+#define _mbg_swab_pcps_dl_onoff( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->year_or_wday ); \
+} while ( 0 )
+
+/**
+ * @brief A flag indicating if DST changeovers are to be computed automatically
+ *
+ * If ::PCPS_DL_ONOFF::year_or_wday is or'ed with the constant ::DL_AUTO_FLAG
+ * then start and end of daylight saving time shall be computed automatically
+ * for each year. In this case the remaining bits represent the day-of-week
+ * after the specified mday/month at which the change shall occur.
+ * If that flag is not set then the field contains the full four-digit year number
+ * and the ::PCPS_DL_ONOFF::mday and ::PCPS_DL_ONOFF::month values specify
+ * the exact date of that year. Most devices supporting conversion to local time
+ * support the ::TZDL structure instead.
+ *
+ * @see ::TZDL
+ * @see ::PCPS_TZDL
+ */
+#define DL_AUTO_FLAG 0x8000 // also defined in gpsdefs.h
/**
- * Some definitions used with PZF receivers
+ * @brief Specification of a local time zone
+ *
+ * Most devices supporting conversion to local time support
+ * the ::TZDL structure instead.
+ *
+ * @see ::DL_AUTO_FLAG
+ * @see ::TZDL
*/
+typedef struct
+{
+ int16_t offs; ///< offset from %UTC to local time [min] (local time = %UTC + offs)
+ int16_t offs_dl; ///< additional offset if DST enabled [min] (DST time = local time + offs_dl)
+ PCPS_DL_ONOFF tm_on; ///< date/time when daylight saving starts
+ PCPS_DL_ONOFF tm_off; ///< date/time when daylight saving ends
+
+} PCPS_TZDL;
+
+#define _mbg_swab_pcps_tzdl( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->offs ); \
+ _mbg_swab16( &(_p)->offs_dl ); \
+ _mbg_swab_pcps_dl_onoff( &(_p)->tm_on ); \
+ _mbg_swab_pcps_dl_onoff( &(_p)->tm_off ); \
+} while ( 0 )
+
-/* receiver distance from transmitter [km] */
-typedef uint16_t TR_DISTANCE;
+
+/**
+ * @brief Status of the time capture FIFO buffer
+ *
+ * Only supported if ::RECEIVER_INFO::n_ucaps > 0.
+ */
+typedef struct
+{
+ uint32_t used; ///< the number of saved capture events
+ uint32_t max; ///< capture buffer size
+
+} PCPS_UCAP_ENTRIES;
+
+#define _mbg_swab_pcps_ucap_entries( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->used ); \
+ _mbg_swab32( &(_p)->max ); \
+} while ( 0 )
+
+
+
+/**
+ * @defgroup group_pzf_supp Definitions used with PZF receivers
+ *
+ * @{ */
+
+/**
+ * @brief Receiver distance from transmitter [km]
+ */
+typedef uint16_t TR_DISTANCE; ///< Range may vary with receiver type
#define _mbg_swab_tr_distance( _p ) \
_mbg_swab16( _p )
-
-/* correlation status info */
+/**
+ * @brief PZF correlation status info
+ */
typedef struct
{
- uint8_t val; /**< correlation value, or check count if status == PZF_CORR_CHECK */
- uint8_t status; /**< status codes, see below */
- char corr_dir; /**< space, '<', or '>' */
- uint8_t signal; /**< signal level, may always be 0 for devices which do not support this */
+ uint8_t val; ///< correlation value, or check count if status ==:: PZF_CORR_CHECK
+ uint8_t status; ///< status codes, see ::PZF_CORR_STATES
+ char corr_dir; ///< space, '<', or '>', just for information
+ PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS
+
} CORR_INFO;
#define _mbg_swab_corr_info( _p ) \
_nop_macro_fnc()
-/** Codes used with CORR_INFO::status: */
-enum
+/**
+ * @brief Codes used with ::CORR_INFO::status
+ */
+enum PZF_CORR_STATES
{
- PZF_CORR_RAW, /**< trying raw correlation, combi receivers running in AM mode */
- PZF_CORR_CHECK, /**< raw correlation achieved, doing plausibility checks */
- PZF_CORR_FINE, /**< fine correlation achieved */
+ PZF_CORR_RAW, ///< trying raw correlation, combi receivers running in AM mode
+ PZF_CORR_CHECK, ///< raw correlation achieved, doing plausibility checks
+ PZF_CORR_FINE, ///< fine correlation achieved
N_PZF_CORR_STATE
};
-/** @defgroup group_gps_cmds_bus GPS commands passed via the system bus
+#define PZF_CORR_STATE_NAME_RAW_ENG "Searching"
+#define PZF_CORR_STATE_NAME_CHECK_ENG "Correlating"
+#define PZF_CORR_STATE_NAME_FINE_ENG "Locked"
- This enumeration defines the various types of data that can be read
- from or written to Meinberg bus level devices which support this.
- Access should be done using the functions ::pcps_read_gps_data()
- and ::pcps_write_gps_data() since the size of some of the structures
- exceeds the size of the devices's I/O buffer and must therefore be
- accessed in several portions.
+#define PZF_CORR_STATE_NAME_RAW_GER "suchen"
+#define PZF_CORR_STATE_NAME_CHECK_GER "korrelieren"
+#define PZF_CORR_STATE_NAME_FINE_GER "eingerastet"
- The structures to be used are defined in gpsdefs.h. Not all structures
- are supportet, yet. Check the R/W indicators for details.
- * @{ */
-enum
-{ // R/W data type description
- // system data -----------------------------------------------
- PC_GPS_TZDL = 0, // R/W TZDL time zone / daylight saving
- PC_GPS_SW_REV, // R/- SW_REV software revision
- PC_GPS_BVAR_STAT, // R/- BVAR_STAT status of buffered variables
- PC_GPS_TIME, // R/W TTM curr. time
- PC_GPS_POS_XYZ, // -/W XYZ curr. pos. in ECEF coords
- PC_GPS_POS_LLA, // -/W LLA curr. pos. in geogr. coords
- PC_GPS_PORT_PARM, // R/W PORT_PARM param. of the serial ports
- PC_GPS_ANT_INFO, // R/- ANT_INFO time diff after ant. disconn.
- PC_GPS_UCAP, // R/- TTM user capture
- PC_GPS_ENABLE_FLAGS, // R/W ENABLE_FLAGS controls when to enable outp.
- PC_GPS_STAT_INFO, // R/- GPS_STAT_INFO
- PC_GPS_CMD, // -/W GPS_CMD commands as described below
- PC_GPS_IDENT, // R/- GPS_IDENT serial number
- PC_GPS_POS, // R/- POS position XYZ, LLA, and DMS
- PC_GPS_ANT_CABLE_LEN, // R/W ANT_CABLE_LEN used to compensate delay
- // The codes below are supported by new GPS receiver boards:
- PC_GPS_RECEIVER_INFO, // R/- RECEIVER_INFO rcvr model info
- PC_GPS_ALL_STR_TYPE_INFO, // R/- n*STR_TYPE_INFO_IDX all string types
- PC_GPS_ALL_PORT_INFO, // R/- n*PORT_INFO_IDX all port info
- PC_GPS_PORT_SETTINGS_IDX, // -/W PORT_SETTINGS_IDX port settings only
- PC_GPS_ALL_POUT_INFO, // R/- n*POUT_INFO_IDX all pout info
- PC_GPS_POUT_SETTINGS_IDX, // -/W POUT_SETTINGS_IDX pout settings only
- PC_GPS_TIME_SCALE, // R/W MBG_TIME_SCALE_{SETTINGS|INFO}, only if PCPS_HAS_TIME_SCALE
- PC_GPS_LAN_IF_INFO, // R/- LAN_IF_INFO LAN interface info, only if PCPS_HAS_LAN_INTF
- PC_GPS_IP4_STATE, // R/- IP4_SETTINGS LAN interface state, only if PCPS_HAS_LAN_INTF
- PC_GPS_IP4_SETTINGS, // R/W IP4_SETTINGS LAN interface configuration, only if PCPS_HAS_LAN_INTF
- PC_GPS_PTP_STATE, // R/- PTP_STATE, only if PCPS_HAS_PTP
- PC_GPS_PTP_CFG, // R/W PTP_CFG_{SETTINGS|INFO}, only if PCPS_HAS_PTP
- PC_GPS_PTP_UC_MASTER_CFG_LIMITS, // R/- PTP_UC_MASTER_CFG_LIMITS, only if can be unicast master
- PC_GPS_ALL_PTP_UC_MASTER_INFO, // R/- n*PTP_UC_MASTER_INFO_IDX, only if can be unicast master
- PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, // -/W PTP_UC_MASTER_SETTINGS_IDX, only if can be unicast master
- PC_GPS_GPIO_CFG_LIMITS, // R/- MBG_GPIO_CFG_LIMITS, only if PCPS_HAS_GPIO
- PC_GPS_ALL_GPIO_INFO, // R/- n*MBG_GPIO_INFO, all GPIO info, only if PCPS_HAS_GPIO
- PC_GPS_GPIO_SETTINGS_IDX, // -/W MBG_GPIO_SETTINGS_IDX, GPIO cfg for a specific port, only if PCPS_HAS_GPIO
+#define PZF_CORR_STATE_NAMES_ENG \
+{ \
+ PZF_CORR_STATE_NAME_RAW_ENG, \
+ PZF_CORR_STATE_NAME_CHECK_ENG, \
+ PZF_CORR_STATE_NAME_FINE_ENG \
+}
+
+
+#define PZF_CORR_STATE_NAMES_LSTR \
+{ \
+ { PZF_CORR_STATE_NAME_RAW_ENG, PZF_CORR_STATE_NAME_RAW_GER }, \
+ { PZF_CORR_STATE_NAME_CHECK_ENG, PZF_CORR_STATE_NAME_CHECK_GER }, \
+ { PZF_CORR_STATE_NAME_FINE_ENG, PZF_CORR_STATE_NAME_FINE_GER } \
+}
+
+/** @} defgroup group_pzf_supp */
+
+
+
+/**
+ * @brief GPS Command codes passed via the system bus
+ *
+ * Codes specifying various types of data that can be read from or
+ * written to Meinberg bus level devices which support this.
+ * Access is done using the low level functions ::pcps_read_gps
+ * and ::pcps_write_gps since the size of some of the structures
+ * exceeds the size of the device's I/O buffer and must therefore be
+ * accessed in several blocks.
+ *
+ * Applications should instead use the API functions declared in mbgdevio.h.
+ *
+ * The structures to be used are defined in gpsdefs.h. Not all structures
+ * are supported, yet. Check the r/w indicators for details.
+ *
+ * @see @ref PCPS_CMD_CODES
+ * @see ::PC_GPS_CMD_CODES_TABLE
+ */
+enum PC_GPS_CMD_CODES
+{
+ PC_GPS_TZDL, ///< (r/w) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL
+ PC_GPS_SW_REV, ///< (r/-) ::SW_REV, software revision, deprecated by ::PC_GPS_RECEIVER_INFO
+ PC_GPS_BVAR_STAT, ///< (r/-) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT
+ PC_GPS_TIME, ///< (r/w) ::TTM, current time, deprecated by ::PCPS_GIVE_HR_TIME
+ PC_GPS_POS_XYZ, ///< (-/w) ::XYZ, current position in ECEF coordinates, only if ::GPS_MODEL_HAS_POS_XYZ
+ PC_GPS_POS_LLA, ///< (-/w) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA
+ PC_GPS_PORT_PARM, ///< (r/w) ::PORT_PARM, param. of the serial ports, deprecated by ::PC_GPS_ALL_PORT_INFO
+ PC_GPS_ANT_INFO, ///< (r/-) ::ANT_INFO, time diff at sync. after antenna had been disconn., only if ::GPS_MODEL_HAS_ANT_INFO
+
+ PC_GPS_UCAP, ///< (r/-) ::TTM, user capture events, deprecated by ::PCPS_GIVE_UCAP_EVENT
+ PC_GPS_ENABLE_FLAGS, ///< (r/w) ::ENABLE_FLAGS, when to enable serial, pulses, and synth, only if ::GPS_MODEL_HAS_ENABLE_FLAGS
+ PC_GPS_STAT_INFO, ///< (r/-) ::GPS_STAT_INFO, satellite info, mode of operation, and DAC info, only if ::GPS_MODEL_HAS_STAT_INFO
+ PC_GPS_CMD, ///< (-/w) ::GPS_CMD, send one of the ::PC_GPS_COMMANDS
+ PC_GPS_IDENT, ///< (r/-) ::IDENT, serial number, deprecated by ::PC_GPS_RECEIVER_INFO
+ PC_GPS_POS, ///< (r/-) ::POS, position ::XYZ, ::LLA, and ::DMS combined, only if ::GPS_MODEL_HAS_POS
+ PC_GPS_ANT_CABLE_LEN, ///< (r/w) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LEN
+ PC_GPS_RECEIVER_INFO, ///< (r/-) ::RECEIVER_INFO, rcvr model info, only if ::PCPS_HAS_RECEIVER_INFO
+
+ PC_GPS_ALL_STR_TYPE_INFO, ///< (r/-) n * ::STR_TYPE_INFO_IDX, names and capabilities of all supp. string types, only if ::RECEIVER_INFO::n_str_type > 0
+ PC_GPS_ALL_PORT_INFO, ///< (r/-) n * ::PORT_INFO_IDX, settings and capabilities of all serial ports, only if ::RECEIVER_INFO::n_com_ports > 0
+ PC_GPS_PORT_SETTINGS_IDX, ///< (-/w) ::PORT_SETTINGS_IDX, settings for specified serial port, only if ::RECEIVER_INFO::n_com_ports > 0
+ PC_GPS_ALL_POUT_INFO, ///< (r/-) n * ::POUT_INFO_IDX, all programmable output info
+ PC_GPS_POUT_SETTINGS_IDX, ///< (-/w) ::POUT_SETTINGS_IDX, settings for one programmable output
+ PC_GPS_TIME_SCALE, ///< (r/w) ::MBG_TIME_SCALE_SETTINGS / ::MBG_TIME_SCALE_INFO, only if ::PCPS_HAS_TIME_SCALE
+ PC_GPS_LAN_IF_INFO, ///< (r/-) ::LAN_IF_INFO, LAN interface info, only if ::PCPS_HAS_LAN_INTF
+ PC_GPS_IP4_STATE, ///< (r/-) ::IP4_SETTINGS, LAN interface state, only if ::PCPS_HAS_LAN_INTF
+
+ PC_GPS_IP4_SETTINGS, ///< (r/w) ::IP4_SETTINGS, LAN interface configuration, only if ::PCPS_HAS_LAN_INTF
+ PC_GPS_PTP_STATE, ///< (r/-) ::PTP_STATE, only if ::PCPS_HAS_PTP
+ PC_GPS_PTP_CFG, ///< (r/w) ::PTP_CFG_SETTINGS / ::PTP_CFG_INFO, only if ::PCPS_HAS_PTP
+ PC_GPS_PTP_UC_MASTER_CFG_LIMITS, ///< (r/-) ::PTP_UC_MASTER_CFG_LIMITS, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_ALL_PTP_UC_MASTER_INFO, ///< (r/-) n * ::PTP_UC_MASTER_INFO_IDX, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, ///< (-/w) ::PTP_UC_MASTER_SETTINGS_IDX, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST
+ PC_GPS_GPIO_CFG_LIMITS, ///< (r/-) ::MBG_GPIO_CFG_LIMITS, only if ::GPS_HAS_GPIO
+ PC_GPS_ALL_GPIO_INFO, ///< (r/-) n * ::MBG_GPIO_INFO_IDX, all GPIO info, only if ::GPS_HAS_GPIO
+
+ PC_GPS_GPIO_SETTINGS_IDX, ///< (-/w) ::MBG_GPIO_SETTINGS_IDX, settings for a specific port, only if ::GPS_HAS_GPIO
+ PC_GPS_GNSS_MODE, ///< (r/w) ::MBG_GNSS_MODE_INFO / ::MBG_GNSS_MODE_SETTINGS, only if ::PCPS_IS_GNSS
+ PC_GPS_ALL_GNSS_SAT_INFO, ///< (r/-) n * ::GNSS_SAT_INFO_IDX, satellite info, only if ::PCPS_IS_GNSS
+ PC_GPS_XMR_INSTANCES, ///< (r/-) ::XMULTI_REF_INSTANCES, only if ::GPS_HAS_XMULTI_REF and ::GPS_HAS_XMRS_MULT_INSTC
+ PC_GPS_XMR_SETTINGS_IDX, ///< (-/w) ::XMULTI_REF_SETTINGS_IDX, idx 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_ALL_XMR_INFO, ///< (r/-) n * ::XMULTI_REF_INFO_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_ALL_XMR_STATUS, ///< (r/w) n * ::XMULTI_REF_STATUS_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, one structure on write, only if ::GPS_HAS_XMULTI_REF
+ PC_GPS_XMR_HOLDOVER_STATUS, ///< (r/-) ::XMR_HOLDOVER_STATUS, only if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP
+
+ PC_GPS_ALL_GPIO_STATUS, ///< (r/-) n * ::MBG_GPIO_STATUS_IDX, where n == ::MBG_GPIO_CFG_LIMITS::num_io, only if ::MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP
+ PC_GPS_XFEATURE_BUFFER, ///< (r/-) ::MBG_XFEATURE_BUFFER, only if ::GPS_HAS_XFEATURE
+ PC_GPS_TLV_INFO, ///< (r/-) ::MBG_TLV_INFO, only if ::MBG_XFEATURE_TLV_API
// GPS data
- PC_GPS_CFGH = 0x80, // -/- CFGH SVs' config. and health codes
- PC_GPS_ALM, // -/- SV_ALM one SV's num and almanac
- PC_GPS_EPH, // -/- SV_EPH one SV's num and ephemeris
- PC_GPS_UTC, // R/W UTC UTC corr. param., only if PCPS_HAS_UTC_PARM
- PC_GPS_IONO, // -/- IONO ionospheric corr. param.
- PC_GPS_ASCII_MSG // -/- ASCII_MSG the GPS ASCII message
+ PC_GPS_CFGH = 0x80, ///< (-/-) ::CFGH, SVs' config. and health codes (yet not used)
+ PC_GPS_ALM, ///< (-/-) ::SV_ALM, one SV's num and almanac (yet not used)
+ PC_GPS_EPH, ///< (-/-) ::SV_EPH, one SV's num and ephemeris (yet not used)
+ PC_GPS_UTC, ///< (r/w) ::UTC, %UTC corr. param., only if ::PCPS_HAS_UTC_PARM
+ PC_GPS_IONO, ///< (-/-) ::IONO, ionospheric corr. param. (yet not used)
+ PC_GPS_ASCII_MSG ///< (-/-) ::ASCII_MSG, the GPS ASCII message (yet not used)
};
-/** @} group_gps_cmds_bus */
-
/**
* @brief An initializer for a table of code/name entries of GPS commands.
*
- * This can e.g. be assigned to an array of MBG_CODE_NAME_TABLE_ENTRY elements
+ * This can e.g. be assigned to an array of ::MBG_CODE_NAME_TABLE_ENTRY elements
* and may be helpful when debugging.
+ *
+ * @see ::PC_GPS_CMD_CODES
*/
-#define MBG_PC_GPS_CMD_TABLE \
-{ \
- { PC_GPS_TZDL, "PC_GPS_TZDL" }, \
- { PC_GPS_SW_REV, "PC_GPS_SW_REV" }, \
- { PC_GPS_BVAR_STAT, "PC_GPS_BVAR_STAT" }, \
- { PC_GPS_TIME, "PC_GPS_TIME" }, \
- { PC_GPS_POS_XYZ, "PC_GPS_POS_XYZ" }, \
- { PC_GPS_POS_LLA, "PC_GPS_POS_LLA" }, \
- { PC_GPS_PORT_PARM, "PC_GPS_PORT_PARM" }, \
- { PC_GPS_ANT_INFO, "PC_GPS_ANT_INFO" }, \
- { PC_GPS_UCAP, "PC_GPS_UCAP" }, \
- { PC_GPS_ENABLE_FLAGS, "PC_GPS_ENABLE_FLAGS" }, \
- { PC_GPS_STAT_INFO, "PC_GPS_STAT_INFO" }, \
- { PC_GPS_CMD, "PC_GPS_CMD" }, \
- { PC_GPS_IDENT, "PC_GPS_IDENT" }, \
- { PC_GPS_POS, "PC_GPS_POS" }, \
- { PC_GPS_ANT_CABLE_LEN, "PC_GPS_ANT_CABLE_LEN" }, \
- { PC_GPS_RECEIVER_INFO, "PC_GPS_RECEIVER_INFO" }, \
- { PC_GPS_ALL_STR_TYPE_INFO, "PC_GPS_ALL_STR_TYPE_INFO" }, \
- { PC_GPS_ALL_PORT_INFO, "PC_GPS_ALL_PORT_INFO" }, \
- { PC_GPS_PORT_SETTINGS_IDX, "PC_GPS_PORT_SETTINGS_IDX" }, \
- { PC_GPS_ALL_POUT_INFO, "PC_GPS_ALL_POUT_INFO" }, \
- { PC_GPS_POUT_SETTINGS_IDX, "PC_GPS_POUT_SETTINGS_IDX" }, \
- { PC_GPS_TIME_SCALE, "PC_GPS_TIME_SCALE" }, \
- { PC_GPS_LAN_IF_INFO, "PC_GPS_LAN_IF_INFO" }, \
- { PC_GPS_IP4_STATE, "PC_GPS_IP4_STATE" }, \
- { PC_GPS_IP4_SETTINGS, "PC_GPS_IP4_SETTINGS" }, \
- { PC_GPS_PTP_STATE, "PC_GPS_PTP_STATE" }, \
- { PC_GPS_PTP_CFG, "PC_GPS_PTP_CFG" }, \
- { PC_GPS_PTP_UC_MASTER_CFG_LIMITS, "PC_GPS_PTP_UC_MASTER_CFG_LIMITS" }, \
- { PC_GPS_ALL_PTP_UC_MASTER_INFO, "PC_GPS_ALL_PTP_UC_MASTER_INFO" }, \
- { PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, "PC_GPS_PTP_UC_MASTER_SETTINGS_IDX" }, \
- { PC_GPS_GPIO_CFG_LIMITS, "PC_GPS_GPIO_CFG_LIMITS" }, \
- { PC_GPS_ALL_GPIO_INFO, "PC_GPS_ALL_GPIO_INFO" }, \
- { PC_GPS_GPIO_SETTINGS_IDX, "PC_GPS_GPIO_SETTINGS_IDX" }, \
- { PC_GPS_CFGH, "PC_GPS_CFGH" }, \
- { PC_GPS_ALM, "PC_GPS_ALM" }, \
- { PC_GPS_EPH, "PC_GPS_EPH" }, \
- { PC_GPS_UTC, "PC_GPS_UTC" }, \
- { PC_GPS_IONO, "PC_GPS_IONO" }, \
- { PC_GPS_ASCII_MSG, "PC_GPS_ASCII_MSG" }, \
- { 0, NULL } \
+#define PC_GPS_CMD_CODES_TABLE \
+{ \
+ _mbg_cn_table_entry( PC_GPS_TZDL ), \
+ _mbg_cn_table_entry( PC_GPS_SW_REV ), \
+ _mbg_cn_table_entry( PC_GPS_BVAR_STAT ), \
+ _mbg_cn_table_entry( PC_GPS_TIME ), \
+ _mbg_cn_table_entry( PC_GPS_POS_XYZ ), \
+ _mbg_cn_table_entry( PC_GPS_POS_LLA ), \
+ _mbg_cn_table_entry( PC_GPS_PORT_PARM ), \
+ _mbg_cn_table_entry( PC_GPS_ANT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_UCAP ), \
+ _mbg_cn_table_entry( PC_GPS_ENABLE_FLAGS ), \
+ _mbg_cn_table_entry( PC_GPS_STAT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_CMD ), \
+ _mbg_cn_table_entry( PC_GPS_IDENT ), \
+ _mbg_cn_table_entry( PC_GPS_POS ), \
+ _mbg_cn_table_entry( PC_GPS_ANT_CABLE_LEN ), \
+ _mbg_cn_table_entry( PC_GPS_RECEIVER_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_STR_TYPE_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_PORT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_PORT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_POUT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_POUT_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_TIME_SCALE ), \
+ _mbg_cn_table_entry( PC_GPS_LAN_IF_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_IP4_STATE ), \
+ _mbg_cn_table_entry( PC_GPS_IP4_SETTINGS ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_STATE ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_CFG ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_UC_MASTER_CFG_LIMITS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_PTP_UC_MASTER_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_PTP_UC_MASTER_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_GPIO_CFG_LIMITS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GPIO_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_GPIO_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_GNSS_MODE ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GNSS_SAT_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_INSTANCES ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_SETTINGS_IDX ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_XMR_INFO ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_XMR_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_XMR_HOLDOVER_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_ALL_GPIO_STATUS ), \
+ _mbg_cn_table_entry( PC_GPS_XFEATURE_BUFFER ), \
+ _mbg_cn_table_entry( PC_GPS_TLV_INFO ), \
+ \
+ _mbg_cn_table_entry( PC_GPS_CFGH ), \
+ _mbg_cn_table_entry( PC_GPS_ALM ), \
+ _mbg_cn_table_entry( PC_GPS_EPH ), \
+ _mbg_cn_table_entry( PC_GPS_UTC ), \
+ _mbg_cn_table_entry( PC_GPS_IONO ), \
+ _mbg_cn_table_entry( PC_GPS_ASCII_MSG ), \
+ _mbg_cn_table_end() \
}
-/** codes used with PC_GPS_CMD */
-enum
+/**
+ * @brief Codes used with ::PC_GPS_CMD
+ *
+ * @note These commands should only used with care, in very rare cases!
+ */
+enum PC_GPS_COMMANDS //##++++++++++++++
{
- PC_GPS_CMD_BOOT = 1, /**< force the clock to boot mode */
- PC_GPS_CMD_INIT_SYS, /**< let the clock clear its system variables */
- PC_GPS_CMD_INIT_USER, /**< reset the clock's user parameters to defaults */
- PC_GPS_CMD_INIT_DAC, /**< initialize the oscillator disciplining values */
- N_PC_GPS_CMD /**< no command, just the number of known commands */
+ PC_GPS_CMD_BOOT = 1, ///< force a GPS receiver to boot mode
+ PC_GPS_CMD_INIT_SYS, ///< let the clock clear its system variables
+ PC_GPS_CMD_INIT_USER, ///< reset the clock's user parameters to defaults
+ PC_GPS_CMD_INIT_DAC, ///< initialize the oscillator disciplining values
+ N_PC_GPS_CMD_CODES ///< no command, just the number of known commands
};
-// The type below can be used to store an unambiguous command code.
-// In case of the standard PCPS_... commands the lower byte contains
-// the command code and the upper byte is 0.
-// In case of a GPS command the lower byte contains PCPS_READ_GPS_DATA
-// or PCPS_WRITE_GPS_DATA, as appropriate, and the upper byte contains
-// the associated PC_GPS_... type code.
+/**
+ * @brief A type used to store an unambiguous command code
+ *
+ * In case of the standard @ref PCPS_CMD_CODES the lower byte contains
+ * the command code and the upper byte is 0.
+ * In case of a GPS command the lower byte contains ::PCPS_READ_GPS_DATA
+ * or ::PCPS_WRITE_GPS_DATA, as appropriate, and the upper byte contains
+ * the associated type code from ::PC_GPS_CMD_CODES.
+ *
+ * Used internally by the firmware only.
+ */
typedef uint16_t PCPS_CMD_INFO;
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdev.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdev.h
index 7598a6f..313ccca 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdev.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdev.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsdev.h 1.49.1.52 2011/07/19 10:41:48 martin TRASH $
+ * $Id: pcpsdev.h 1.56.1.1 2017/07/26 14:28:29 martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -17,93 +17,77 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsdev.h $
- * Revision 1.49.1.52 2011/07/19 10:41:48 martin
- * Revision 1.49.1.51 2011/07/14 13:29:14 martin
- * Revision 1.49.1.50 2011/07/13 09:44:53 martin
+ * Revision 1.56.1.1 2017/07/26 14:28:29 martin
+ * Removed includes that are obsolete for NetBSD.
+ * Revision 1.56 2017/07/04 16:31:08 martin
+ * New types PCPS_CLOCK_NAME and MBG_DEV_NAME.
+ * Definitions used with new feature check implementation.
+ * Changed some macros and definitions to clean up
+ * I/O port usage and storage.
+ * Moved some definitions used with IOCTLs to mbgioctl.h.
+ * Revision 1.55 2017/04/25 11:36:40 martin
+ * Renamed GRC181PEX to GNS181PEX.
+ * Revision 1.54 2017/01/27 09:10:57 martin
+ * Support GPS180AMC.
+ * Support GRC181PEX.
+ * Support GPIO ports.
+ * IRIG TX support for GPS180PEX and TCR180PEX only
+ * if GPS_HAS_IRIG_TX flag is set.
+ * New type PCPS_FW_REV_NUM.
+ * Moved some code to new module mbgsystm.h.
+ * Moved NANO_TIME_64 to gpsdefs.h.
+ * Moved inline function num_bits_set() to cfg_hlp.h.
+ * Added macro _ri_addr().
+ * Added macro _pcps_has_ri_xmr().
+ * Fixed macro syntax.
+ * Doxygen stuff.
+ * Removed trailing spaces.
+ * Cleanup.
+ * Revision 1.53 2013/11/08 08:46:00 martin
+ * Doxygen comment updates.
+ * Revision 1.52 2013/09/26 09:06:47Z martin
+ * Support GLN180PEX and GNSS API.
+ * Added inline fnc num_bits_set().
+ * Revision 1.51 2013/01/25 15:44:21 martin
+ * Added inline function setup_hr_time_cycles_from_timestamp_cycles() which sets
+ * up a PCPS_HR_TIME_CYCLES structure from PCPS_TIME_STAMP_CYCLES.
+ * Revision 1.50 2012/10/02 19:00:46 martin
+ * Support GPS180PEX, TCR180PEX, and PZF180PEX.
+ * Support DCF600USB, TCR600USB, MSF600USB, and WVB600USB.
+ * Runtime support for precise time API introduced with Windows 8.
+ * This does not yet for x64 builds.
+ * There are some g++ versions which fail to compile source code using
+ * the macros provided by Linux to define IOCTL codes. If only the API
+ * functions are called by an application then the IOCTL codes aren't
+ * required anyway, so we just avoid inclusion of mbgioctl.h.
+ * However, some IOCTL related definitions are required anyway, so
+ * they have been moved to this file which is always included.
+ * Bug fix: Use negative sign for delay in KeDelayExecutionThread()
+ * Support on-board event logs.
+ * Moved macro _must_do_fw_workaround_20ms() here.
+ * New macro _pcps_has_debug_status().
+ * Added some macros to test if specific stat_info stuff is supported.
+ * Moved some definitions useful for configuration tools to new file cfg_hlp.h.
* Moved IA64 includes from pcpsdev.h to mbgpccyc.h.
- * Revision 1.49.1.49 2011/07/06 13:23:24 martin
- * Revision 1.49.1.48 2011/07/06 11:22:50 martin
* Added macros _pcps_has_corr_info() and _pcps_has_tr_distance().
- * Revision 1.49.1.47 2011/07/05 12:25:19 martin
- * Revision 1.49.1.46 2011/07/04 10:29:44 martin
- * Modified a comment.
- * Revision 1.49.1.45 2011/06/29 14:06:08 martin
- * Added support for TCR600USB, MSF600USB, and WVB600USB.
* Extended bus flag for USB v2 and macro _pcps_is_usb_v2().
* New feature ..._HAS_PZF and macro _pcps_has_pzf().
- * Revision 1.49.1.44 2011/06/29 09:10:26 martin
- * Renamed PZF600PEX to PZF180PEX.
- * Revision 1.49.1.43 2011/06/24 10:26:52 martin
- * Fixed warning under DOS.
- * Revision 1.49.1.42 2011/06/24 08:07:03Z martin
* Moved PC cycles stuff to an new extra header.
- * Revision 1.49.1.41 2011/06/21 15:17:36 martin
- * Fixed build under DOS.
- * Revision 1.49.1.40 2011/06/21 14:23:59Z martin
* Cleaned up handling of pragma pack().
* Introduced generic MBG_SYS_TIME with nanosecond resolution.
* Support struct timespec under Linux, if available.
- * Revision 1.49.1.39 2011/06/01 09:29:09 martin
- * Revision 1.49.1.38 2011/05/31 14:20:54 martin
- * Revision 1.49.1.37 2011/05/16 13:18:38 martin
* Use MBG_TGT_KERNEL instead of _KDD_.
- * Revision 1.49.1.36 2011/05/06 13:47:38Z martin
- * Support PZF600PEX.
- * Revision 1.49.1.35 2011/04/19 15:06:24 martin
* Added PTP unicast master configuration stuff.
- * Revision 1.49.1.34 2011/03/29 14:08:45 martin
* For compatibility use cpu_counter() instead of cpu_counter_serializing() under NetBSD.
- * Revision 1.49.1.33 2011/03/28 09:50:18 martin
- * Modifications for NetBSD from Frank Kardel.
- * Revision 1.49.1.32 2011/03/25 11:09:43 martin
* Optionally support timespec for sys time (USE_TIMESPEC).
- * Started to support NetBSD.
- * Revision 1.49.1.31 2011/02/16 10:10:49 martin
- * Fixed macro syntax for _pcps_time_set_unread().
- * Revision 1.49.1.30 2011/02/15 14:24:56Z martin
- * Revision 1.49.1.29 2011/02/10 13:34:21 martin
- * Revision 1.49.1.28 2011/02/10 13:21:59 martin
- * Revision 1.49.1.27 2011/02/10 12:26:17 martin
- * Revision 1.49.1.26 2011/02/09 15:46:49 martin
- * Revision 1.49.1.25 2011/02/04 14:44:44 martin
- * Revision 1.49.1.24 2011/02/04 10:10:00 martin
- * Revision 1.49.1.23 2011/02/02 12:34:10 martin
- * Revision 1.49.1.22 2011/02/01 17:12:04 martin
- * Revision 1.49.1.21 2011/01/28 13:11:11 martin
- * Preliminary implementation of mbg_get_sys_time for FreeBSD traps.
- * Revision 1.49.1.20 2011/01/28 10:34:37 martin
+ * Support FreeBSD and NetBSD.
* Moved MBG_TGT_SUPP_MEM_ACC definition here.
- * Revision 1.49.1.19 2011/01/26 16:39:05 martin
- * Preliminarily support FreeBSD build.
- * Revision 1.49.1.18 2011/01/24 17:09:51 martin
- * Preliminarily fixed build under FreeBSD.
- * Revision 1.49.1.17 2010/12/14 13:19:58 martin
- * Fixed doxgen comments.
- * Revision 1.49.1.16 2010/12/14 12:20:10 martin
- * Revision 1.49.1.15 2010/11/25 14:54:22 martin
* Moved status port register definitions to pcpsdefs.h.
- * Revision 1.49.1.14 2010/11/11 09:15:38 martin
- * Added definitions to support DCF600USB.
- * Revision 1.49.1.13 2010/09/27 13:09:06 martin
* Features are now defined using enum and bit masks.
* Added initializer for feature names (used for debug).
- * Revision 1.49.1.12 2010/08/25 12:44:42 martin
- * Revision 1.49.1.11 2010/08/20 09:34:41Z martin
* Added macro _pcps_features().
- * Revision 1.49.1.10 2010/08/17 15:34:23 martin
- * Revision 1.49.1.9 2010/08/16 15:41:32 martin
- * Revision 1.49.1.8 2010/08/13 12:14:46 daniel
- * Revision 1.49.1.7 2010/08/13 11:57:54Z martin
- * Revision 1.49.1.6 2010/08/13 11:39:28Z martin
- * Revision 1.49.1.5 2010/08/13 11:19:41 martin
* Implemented portable mbg_get_sys_uptime() and mbg_sleep_sec()
* functions and associated types.
- * Revision 1.49.1.4 2010/08/11 14:32:14 martin
- * Revision 1.49.1.3 2010/08/11 13:47:42 martin
- * Cleanup.
- * Revision 1.49.1.2 2010/07/14 14:50:42 martin
- * Revision 1.49.1.1 2010/06/30 13:17:18 martin
- * Support GPS180PEX and TCR180PEX.
* Revision 1.49 2010/06/30 13:03:48 martin
* Use new preprocessor symbol MBG_ARCH_X86.
* Use ulong port addresses for all platforms but x86.
@@ -135,7 +119,7 @@
* Moved some inline functions dealing with MBG_PC_CYCLES
* from mbgdevio.h here.
* Merged the code from _pcps_get_cycles() and _pcps_get_cycles_frequency()
- * to the mbg_get_pc_cycles...() inline functions which now replace the
+ * to the mbg_get_pc_cycles...() inline functions which now replace the
* _pcps_get_cycles...() macros.
* Fixed cycles code for non-x86 architectures.
* Revision 1.39 2008/12/05 16:24:24Z martin
@@ -146,7 +130,7 @@
* 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
+ * 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.
@@ -166,11 +150,11 @@
* _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.
+ * 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
+ * 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.
@@ -183,15 +167,15 @@
* 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
+ * 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.
+ * 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.
@@ -212,8 +196,8 @@
* 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
+ * 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.
@@ -292,22 +276,21 @@
#include <mbg_tgt.h>
#include <mbgtime.h>
+#include <mbgsystm.h>
#include <mbgpccyc.h>
#include <pcpsdefs.h>
#include <gpsdefs.h>
#include <usbdefs.h>
#include <use_pack.h>
+#if !defined( MBG_TGT_KERNEL )
+ #include <string.h>
+#endif
+
#if defined( MBG_TGT_LINUX )
- #if defined( MBG_TGT_KERNEL )
- #include <linux/delay.h>
- #include <linux/time.h>
- #else
+ #if !defined( MBG_TGT_KERNEL )
#include <unistd.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/sysinfo.h>
#endif
#elif defined( MBG_TGT_FREEBSD )
@@ -315,16 +298,25 @@
#if defined( MBG_TGT_KERNEL )
#include <sys/sysproto.h>
#include <sys/pcpu.h>
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/proc.h>
#else
+ #include <unistd.h>
#include <sys/time.h>
#endif
#elif defined( MBG_TGT_NETBSD )
#if !defined( MBG_TGT_KERNEL )
+ #include <unistd.h>
#include <sys/time.h>
#endif
+#elif defined( MBG_TGT_QNX_NTO )
+
+ #include <unistd.h>
+
#elif defined( MBG_TGT_DOS )
#include <dos.h> // for delay()
@@ -342,55 +334,14 @@
#endif
-#if defined( MBG_TGT_UNIX )
- #define USE_GENERIC_SYS_TIME 1
-#else
- #define USE_GENERIC_SYS_TIME 0
-#endif
-
-
-#if USE_GENERIC_SYS_TIME
-
- typedef struct
- {
- uint64_t sec;
- uint64_t nsec;
- } NANO_TIME_64;
-
- typedef NANO_TIME_64 MBG_SYS_TIME;
-
-#endif
-
-
-
-/**
- Define generic types to hold PC cycle counter values and system timestamps.
- The generic types are defined using native types used by the target operating
- systems.
-
- The cycle counter value is usually derived from the PC CPU's TSC or some other
- timer hardware on the mainboard.
- */
-#if defined( MBG_TGT_WIN32 )
-
- #define MBG_TGT_SUPP_MEM_ACC 1
-
- typedef int64_t MBG_SYS_UPTIME; // [s]
-
- typedef LARGE_INTEGER MBG_SYS_TIME;
-
-#elif defined( MBG_TGT_LINUX )
+#if defined( MBG_TGT_LINUX )
#define MBG_TGT_SUPP_MEM_ACC 1
- typedef int64_t MBG_SYS_UPTIME; // [s]
-
#elif defined( MBG_TGT_BSD )
#define MBG_TGT_SUPP_MEM_ACC 1
- typedef int64_t MBG_SYS_UPTIME; // [s]
-
#if defined( MBG_TGT_NETBSD )
#ifdef __LP64__
#define MBG_MEM_ADDR uint64_t
@@ -399,26 +350,14 @@
#endif
#endif
-#elif defined( MBG_TGT_OS2 )
+#elif defined( MBG_TGT_WIN32 )
- typedef long MBG_SYS_UPTIME; //## dummy
-
- typedef uint32_t MBG_SYS_TIME; //## dummy
+ #define MBG_TGT_SUPP_MEM_ACC 1
#elif defined( MBG_TGT_DOS )
#define MBG_MEM_ADDR uint32_t // 64 bit not supported, nor required.
- typedef long MBG_SYS_UPTIME; //## dummy
-
- typedef uint32_t MBG_SYS_TIME; //## dummy
-
-#else // other target OSs which access the hardware directly
-
- typedef long MBG_SYS_UPTIME; //## dummy
-
- typedef uint32_t MBG_SYS_TIME; //## dummy
-
#endif
@@ -427,283 +366,62 @@
#endif
-// MBG_SYS_TIME is always read in native machine endianess,
-// so no endianess conversion is required.
-#define _mbg_swab_mbg_sys_time( _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 MBG_DBG_DATA;
+typedef uint16_t MBG_DBG_PORT;
/**
- The structure holds a system timestamp in a format depending on the target OS
- plus two cycles counter values which can be taken before and after reading
- the system time. These cycles values can be used to determine the execution
- time required to read the system time.
-
- Limitations of the operating system need to be taken into account,
- e.g. the Windows system time may increase once every ~16 ms only.
- */
+ * @brief System time plus associated cycles counter values
+ *
+ * The structure holds a system timestamp in a format depending on the target OS
+ * plus two cycles counter values which can be taken before and after reading
+ * the system time. These cycles values can be used to determine the execution
+ * time required to read the system time.
+ *
+ * Limitations of the operating system need to be taken into account,
+ * e.g. the Windows system time may increase once every ~16 ms or ~1 ms only,
+ * depending on the Windows version.
+ */
typedef struct
{
- MBG_PC_CYCLES cyc_before; /**< cycles count before sys time is read */
- MBG_PC_CYCLES cyc_after; /**< cycles count after sys time has been read */
- MBG_SYS_TIME sys_time; /**< system time stamp */
+ MBG_PC_CYCLES cyc_before; ///< cycles count before sys time is read
+ MBG_PC_CYCLES cyc_after; ///< cycles count after sys time has been read
+ MBG_SYS_TIME sys_time; ///< system time stamp
+
} MBG_SYS_TIME_CYCLES;
#define _mbg_swab_mbg_sys_time_cycles( _p ) \
+do \
{ \
_mbg_swab_mbg_pc_cycles( &(_p)->cyc_before ); \
_mbg_swab_mbg_pc_cycles( &(_p)->cyc_after ); \
_mbg_swab_mbg_sys_time( &(_p)->sys_time ); \
-}
-
-
-
-
-static __mbg_inline
-void mbg_get_sys_time( MBG_SYS_TIME *p )
-{
- #if defined( MBG_TGT_WIN32 )
-
- #if defined( MBG_TGT_KERNEL ) // kernel space
- KeQuerySystemTime( p );
- #else // user space
- {
- FILETIME ft;
- GetSystemTimeAsFileTime( &ft );
- p->LowPart = ft.dwLowDateTime;
- p->HighPart = ft.dwHighDateTime;
- }
- #endif
-
- #elif defined( MBG_TGT_LINUX )
-
- #if defined( MBG_TGT_KERNEL )
-
- #if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 22 ) ) //##+++++++++++++
- {
- // getnstimeofday() supported
- struct timespec ts;
-
- getnstimeofday( &ts );
-
- p->sec = ts.tv_sec;
- p->nsec = ts.tv_nsec;
- }
- #else
- {
- // getnstimeofday() *not* supported
- struct timeval tv;
-
- do_gettimeofday( &tv );
-
- p->sec = tv.tv_sec;
- p->nsec = tv.tv_usec * 1000;
- }
- #endif
-
- #else // Linux user space
- {
- struct timespec ts;
-
- clock_gettime( CLOCK_REALTIME, &ts );
-
- p->sec = ts.tv_sec;
- p->nsec = ts.tv_nsec;
- }
- #endif
-
- #elif defined( MBG_TGT_BSD )
+} while ( 0 )
- struct timespec ts;
- #if defined( MBG_TGT_KERNEL )
- nanotime( &ts );
- #else
- #if defined( MBG_TGT_FREEBSD )
- clock_gettime( CLOCK_REALTIME_PRECISE, &ts );
- #else // MBG_TGT_NETBSD, ...
- clock_gettime( CLOCK_REALTIME, &ts );
- #endif
- #endif
-
- p->sec = ts.tv_sec;
- p->nsec = ts.tv_nsec;
-
- #else
-
- *p = 0;
-
- #endif
-
-} // mbg_get_sys_time
-
-
-
-static __mbg_inline
-void mbg_get_sys_uptime( MBG_SYS_UPTIME *p )
-{
- #if defined( MBG_TGT_WIN32 )
-
- #if defined( MBG_TGT_KERNEL ) // kernel space
-
- ULONGLONG time_increment = KeQueryTimeIncrement();
- LARGE_INTEGER tick_count;
-
- KeQueryTickCount( &tick_count );
-
- // multiplication by time_increment yields HNS units,
- // but we need seconds
- *p = ( tick_count.QuadPart * time_increment ) / HNS_PER_SEC;
-
- #else // user space
-
- DWORD tickCount;
- DWORD timeAdjustment;
- DWORD timeIncrement;
- BOOL timeAdjustmentDisabled;
-
- if ( !GetSystemTimeAdjustment( &timeAdjustment, &timeIncrement, &timeAdjustmentDisabled ) )
- *p = -1; // failed
-
- // ATTENTION: This is compatible with older Windows versions, but
- // the returned tick count wraps around to zero after 49.7 days.
- // A new GetTickCount64() call is available under Windows Vista and newer,
- // but the function call had to be imported dynamically since otherwise
- // programs refused to start under pre-Vista versions due to undefined DLL symbol.
- tickCount = GetTickCount();
-
- *p = ( ( (MBG_SYS_UPTIME) tickCount ) * timeIncrement ) / HNS_PER_SEC;
-
- #endif
-
- #elif defined( MBG_TGT_LINUX )
-
- #if defined( MBG_TGT_KERNEL )
- {
- // Using a simple 64 bit division may result in a linker error
- // in kernel mode due to a missing symbol __udivdi3, so we use
- // a specific inline function do_div().
- // Also, the jiffies counter is not set to 0 at startup but to
- // a defined initialization value we need to account for.
- uint64_t tmp = get_jiffies_64() - INITIAL_JIFFIES;
- do_div( tmp, HZ );
- *p = tmp;
- }
- #else
- {
- struct sysinfo si;
- int rc = sysinfo( &si );
- *p = ( rc == 0 ) ? si.uptime : -1;
- }
- #endif
-
- #elif defined( MBG_TGT_BSD )
-
- #if defined( MBG_TGT_KERNEL )
- {
- struct timespec ts;
-
- getnanouptime( &ts );
-
- *p = ts.tv_sec;
- }
- #elif defined( MBG_TGT_FREEBSD )
- {
- struct timespec ts;
- // CLOCK_UPTIME_FAST is specific to FreeBSD
- int rc = clock_gettime( CLOCK_UPTIME_FAST, &ts );
- *p = ( rc == 0 ) ? ts.tv_sec : -1;
- }
- #else // MBG_TGT_NETBSD, ...
-
- *p = -1; //##++ needs to be implemented
-
- #endif
-
- #else
-
- *p = -1; // not supported
-
- #endif
-
-} // mbg_get_sys_uptime
-
-
-
-static __mbg_inline
-void mbg_sleep_sec( long sec )
-{
- #if defined( MBG_TGT_WIN32 )
-
- #if defined( MBG_TGT_KERNEL ) // kernel space
- LARGE_INTEGER delay;
-
- // we need to pass a negative value to KeDelayExecutionThread()
- // since the given time is a relative time interval, not absolute
- // time. See the API docs for KeDelayExecutionThread().
- delay.QuadPart = (LONGLONG) sec * HNS_PER_SEC;
-
- KeDelayExecutionThread( KernelMode, FALSE, &delay );
- #else // user space
- // Sleep() expects milliseconds
- Sleep( sec * 1000 );
- #endif
-
- #elif defined( MBG_TGT_LINUX )
-
- #if defined( MBG_TGT_KERNEL )
- // msleep is not defined in older kernels, so we use this
- // only if it is surely supported.
- #if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 16 ) ) //##+++++
- msleep( sec * 1000 );
- #else
- {
- DECLARE_WAIT_QUEUE_HEAD( tmp_wait );
- wait_event_interruptible_timeout( tmp_wait, 0, sec * HZ + 1 );
- }
- #endif
- #else
- sleep( sec );
- #endif
-
- #elif defined( MBG_TGT_BSD )
-
- //##+++++++++++++++++++ needs to be defined
-
- #elif defined( MBG_TGT_DOS )
-
- delay( (unsigned) ( sec * 1000 ) );
-
- #else
-
- // This needs to be implemented for the target OS
- // and thus will probably yield a linker error.
- do_sleep_sec( sec );
-
- #endif
-
-} // mbg_sleep_sec
-
-
-
-#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 MBG_DBG_DATA;
-typedef uint16_t MBG_DBG_PORT;
+/**
+ * @defgroup group_bus_flag_masks BUS flag masks
+ *
+ * @anchor PCPS_BUS_FLAG_MASKS
+ *
+ * @{ */
// 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
+#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
@@ -711,10 +429,10 @@ typedef uint16_t MBG_DBG_PORT;
// 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.
-#define PCPS_BUS_PCI_CHIP_S5920 0x8000 // S5920 PCI interface chip.
-#define PCPS_BUS_PCI_CHIP_ASIC 0x4000 // Meinberg's own PCI interface chip.
-#define PCPS_BUS_PCI_CHIP_PEX8311 0x2000 // PEX8311 PCI Express interface chip
-#define PCPS_BUS_PCI_CHIP_MBGPEX 0x1000 // Meinberg's own PCI Express interface chip
+#define PCPS_BUS_PCI_CHIP_S5920 0x8000 ///< S5920 PCI interface chip.
+#define PCPS_BUS_PCI_CHIP_ASIC 0x4000 ///< Meinberg's own PCI interface chip.
+#define PCPS_BUS_PCI_CHIP_PEX8311 0x2000 ///< PEX8311 PCI Express interface chip
+#define PCPS_BUS_PCI_CHIP_MBGPEX 0x1000 ///< Meinberg's own PCI Express interface chip
// The constants below combine the PCI bus flags:
#define PCPS_BUS_PCI_S5933 ( PCPS_BUS_PCI )
@@ -733,9 +451,13 @@ typedef uint16_t MBG_DBG_PORT;
// The constant below combines the PCI bus flags:
#define PCPS_BUS_USB_V2 ( PCPS_BUS_USB | PCPS_BUS_USB_FLAG_V2 )
+/** @} defgroup group_bus_flag_masks */
+
-/** A list of known radio clocks. */
+/**
+ * @brief A list of known devices
+ */
enum PCPS_TYPES
{
PCPS_TYPE_PC31,
@@ -771,52 +493,72 @@ enum PCPS_TYPES
PCPS_TYPE_TCR600USB,
PCPS_TYPE_MSF600USB,
PCPS_TYPE_WVB600USB,
+ PCPS_TYPE_GLN180PEX,
+ PCPS_TYPE_GPS180AMC,
+ PCPS_TYPE_GNS181PEX,
N_PCPS_DEV_TYPE
};
#define PCPS_CLOCK_NAME_SZ 10 // including terminating 0
+typedef char PCPS_CLOCK_NAME[PCPS_CLOCK_NAME_SZ];
+
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.
- */
+ * @brief Device type specification
+ *
+ * Contains the characteristics of one of the ::PCPS_TYPES.
+ * These specifications are always the same for a particular
+ * type of device 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;
+ uint16_t num; ///< see ::PCPS_TYPES
+ PCPS_CLOCK_NAME name;
+ PCPS_DEV_ID dev_id; ///< see @ref MEINBERG_PCI_DEVICE_IDS and @ref MBG_USB_DEVICE_IDS
+ PCPS_REF_TYPE ref_type; ///< see ::PCPS_REF_TYPES
+ PCPS_BUS_FLAGS bus_flags; ///< see @ref PCPS_BUS_FLAG_MASKS
+} PCPS_DEV_TYPE;
-#if !defined( MBG_TGT_UNIX ) || defined( MBG_ARCH_X86 )
- typedef uint16_t PCPS_PORT_ADDR;
-#else
- typedef uint64_t PCPS_PORT_ADDR;
-#endif
+/**
+ * @brief Legacy I/O address type, see ::PCPS_SHORT_PORT_RSRC
+ */
+typedef uint16_t PCPS_SHORT_PORT_ADDR;
/**
- The structure below describes an I/O port resource
- used by a clock.
-*/
+ * @brief An I/O port resource used by a device
+ *
+ * This structure has originally been used to store information
+ * on an I/O address range.
+ * However, the 16 bits provided by ::PCPS_SHORT_PORT_ADDR may
+ * not be sufficient to hold an address on some target platforms,
+ * so this is only kept to maintain API compatibility when
+ * reporting I/O addresses to user space via ::PCPS_DEV_CFG
+ * and thus ::PCPS_DEV structures.
+ * A different structure is actually being used internally
+ * by the kernel drivers.
+ */
typedef struct
{
- PCPS_PORT_ADDR base;
+ PCPS_SHORT_PORT_ADDR base;
uint16_t num;
-} PCPS_PORT_RSRC;
-/** The max number of I/O port resources used by a clock. */
+} PCPS_SHORT_PORT_RSRC;
+
+
+
+/**
+ * @brief The max. number of I/O port resources used by a clock
+ */
#define N_PCPS_PORT_RSRC 2
@@ -830,61 +572,83 @@ typedef struct
#else
ulong len;
#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 uint32_t PCPS_ERR_FLAGS; ///< see @ref PCPS_ERR_FLAG_MASKS
+typedef uint32_t PCPS_FEATURES; ///< see @ref PCPS_FEATURE_MASKS
typedef uint16_t PCPS_BUS_NUM;
typedef uint16_t PCPS_SLOT_NUM;
+typedef uint16_t PCPS_FW_REV_NUM; ///< firmware revision number, MSB major, LSB minor version
/**
- 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.
-*/
+ * @brief Device information
+ *
+ * Contains variable data which depends on a particular instance
+ * of a device, e.g. the firmware which is currently installed,
+ * the port address which has actually been assigned, etc.
+ */
typedef struct
{
- PCPS_ERR_FLAGS err_flags; /**< See \ref group_err_flags "Error flags" */
+ PCPS_ERR_FLAGS err_flags; ///< See @ref PCPS_ERR_FLAG_MASKS
PCPS_BUS_NUM bus_num;
PCPS_SLOT_NUM slot_num;
- PCPS_PORT_RSRC port[N_PCPS_PORT_RSRC];
- uint16_t status_port;
+ PCPS_SHORT_PORT_RSRC port[N_PCPS_PORT_RSRC];
+ PCPS_SHORT_PORT_ADDR short_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_FW_REV_NUM fw_rev_num;
+ PCPS_FEATURES features; ///< See @ref PCPS_FEATURE_MASKS
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.
- @{
-*/
-enum
+
+
+/**
+ * @brief Possible device initialization error flags
+ *
+ * Used with ::PCPS_DEV_CFG::err_flags
+ *
+ * @see ::PCPS_ERR_FLAGS
+ *
+ * @anchor PCPS_ERR_FLAG_MASKS @{ */
+
+#define PCPS_EF_TIMEOUT 0x00000001 ///< timeout occured
+#define PCPS_EF_INV_FW_ID 0x00000002 ///< invalid firmware ID
+#define PCPS_EF_IO_INIT 0x00000004 ///< I/O interface not initialized
+#define PCPS_EF_IO_CFG 0x00000008 ///< I/O interface not configured
+#define PCPS_EF_IO_ENB 0x00000010 ///< I/O interface not enabled
+#define PCPS_EF_IO_RSRC 0x00000020 ///< I/O resource not registered with resource manager
+
+/** @} anchor PCPS_ERR_FLAG_MASKS */
+
+
+
+/**
+ * @defgroup group_pcps_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.
+ *
+ * @see ::PCPS_FEATURES
+ *
+ * @{ */
+
+/**
+ * @brief Feature bits for bus-level devices
+ *
+ * @see @ref PCPS_FEATURE_MASKS
+ */
+enum PCPS_FEATURE_BITS
{
PCPS_BIT_CAN_SET_TIME,
PCPS_BIT_HAS_SERIAL,
@@ -917,40 +681,59 @@ enum
PCPS_BIT_HAS_FAST_HR_TSTAMP,
PCPS_BIT_HAS_RAW_IRIG_DATA,
PCPS_BIT_HAS_PZF, // can also demodulate DCF77 PZF
+ PCPS_BIT_HAS_EVT_LOG,
+ PCPS_BIT_IS_GNSS, // supports several satellite systems and GNSS API calls
- N_PCPS_FEATURE // must not exceed 32 !!
+ N_PCPS_FEATURE_BITS // must not exceed 32 !!
};
-#define PCPS_CAN_SET_TIME ( 1UL << PCPS_BIT_CAN_SET_TIME )
-#define PCPS_HAS_SERIAL ( 1UL << PCPS_BIT_HAS_SERIAL )
-#define PCPS_HAS_SYNC_TIME ( 1UL << PCPS_BIT_HAS_SYNC_TIME )
-#define PCPS_HAS_TZDL ( 1UL << PCPS_BIT_HAS_TZDL )
-#define PCPS_HAS_IDENT ( 1UL << PCPS_BIT_HAS_IDENT )
-#define PCPS_HAS_UTC_OFFS ( 1UL << PCPS_BIT_HAS_UTC_OFFS )
-#define PCPS_HAS_HR_TIME ( 1UL << PCPS_BIT_HAS_HR_TIME )
-#define PCPS_HAS_SERNUM ( 1UL << PCPS_BIT_HAS_SERNUM )
-#define PCPS_HAS_TZCODE ( 1UL << PCPS_BIT_HAS_TZCODE )
-#define PCPS_HAS_CABLE_LEN ( 1UL << PCPS_BIT_HAS_CABLE_LEN )
-#define PCPS_HAS_EVENT_TIME ( 1UL << PCPS_BIT_HAS_EVENT_TIME )
-#define PCPS_HAS_RECEIVER_INFO ( 1UL << PCPS_BIT_HAS_RECEIVER_INFO )
-#define PCPS_CAN_CLR_UCAP_BUFF ( 1UL << PCPS_BIT_CAN_CLR_UCAP_BUFF )
-#define PCPS_HAS_PCPS_TZDL ( 1UL << PCPS_BIT_HAS_PCPS_TZDL )
-#define PCPS_HAS_UCAP ( 1UL << PCPS_BIT_HAS_UCAP )
-#define PCPS_HAS_IRIG_TX ( 1UL << PCPS_BIT_HAS_IRIG_TX )
-#define PCPS_HAS_GPS_DATA_16 ( 1UL << PCPS_BIT_HAS_GPS_DATA_16 )
-#define PCPS_HAS_SYNTH ( 1UL << PCPS_BIT_HAS_SYNTH )
-#define PCPS_HAS_GENERIC_IO ( 1UL << PCPS_BIT_HAS_GENERIC_IO )
-#define PCPS_HAS_TIME_SCALE ( 1UL << PCPS_BIT_HAS_TIME_SCALE )
-#define PCPS_HAS_UTC_PARM ( 1UL << PCPS_BIT_HAS_UTC_PARM )
-#define PCPS_HAS_IRIG_CTRL_BITS ( 1UL << PCPS_BIT_HAS_IRIG_CTRL_BITS )
-#define PCPS_HAS_LAN_INTF ( 1UL << PCPS_BIT_HAS_LAN_INTF )
-#define PCPS_HAS_PTP ( 1UL << PCPS_BIT_HAS_PTP )
-#define PCPS_HAS_IRIG_TIME ( 1UL << PCPS_BIT_HAS_IRIG_TIME )
-#define PCPS_HAS_FAST_HR_TSTAMP ( 1UL << PCPS_BIT_HAS_FAST_HR_TSTAMP )
-#define PCPS_HAS_RAW_IRIG_DATA ( 1UL << PCPS_BIT_HAS_RAW_IRIG_DATA )
-#define PCPS_HAS_PZF ( 1UL << PCPS_BIT_HAS_PZF )
+/**
+ * @brief Feature bit masks for bus-level devices
+ *
+ * Used with ::PCPS_DEV_CFG::features
+ *
+ * @see ::PCPS_FEATURE_BITS
+ * @see ::PCPS_FEATURES
+ *
+ * @anchor PCPS_FEATURE_MASKS @{ */
+
+#define PCPS_CAN_SET_TIME ( 1UL << PCPS_BIT_CAN_SET_TIME ) ///< see ::PCPS_BIT_CAN_SET_TIME
+#define PCPS_HAS_SERIAL ( 1UL << PCPS_BIT_HAS_SERIAL ) ///< see ::PCPS_BIT_HAS_SERIAL
+#define PCPS_HAS_SYNC_TIME ( 1UL << PCPS_BIT_HAS_SYNC_TIME ) ///< see ::PCPS_BIT_HAS_SYNC_TIME
+#define PCPS_HAS_TZDL ( 1UL << PCPS_BIT_HAS_TZDL ) ///< see ::PCPS_BIT_HAS_TZDL
+#define PCPS_HAS_IDENT ( 1UL << PCPS_BIT_HAS_IDENT ) ///< see ::PCPS_BIT_HAS_IDENT
+#define PCPS_HAS_UTC_OFFS ( 1UL << PCPS_BIT_HAS_UTC_OFFS ) ///< see ::PCPS_BIT_HAS_UTC_OFFS
+#define PCPS_HAS_HR_TIME ( 1UL << PCPS_BIT_HAS_HR_TIME ) ///< see ::PCPS_BIT_HAS_HR_TIME
+#define PCPS_HAS_SERNUM ( 1UL << PCPS_BIT_HAS_SERNUM ) ///< see ::PCPS_BIT_HAS_SERNUM
+
+#define PCPS_HAS_TZCODE ( 1UL << PCPS_BIT_HAS_TZCODE ) ///< see ::PCPS_BIT_HAS_TZCODE
+#define PCPS_HAS_CABLE_LEN ( 1UL << PCPS_BIT_HAS_CABLE_LEN ) ///< see ::PCPS_BIT_HAS_CABLE_LEN
+#define PCPS_HAS_EVENT_TIME ( 1UL << PCPS_BIT_HAS_EVENT_TIME ) ///< see ::PCPS_BIT_HAS_EVENT_TIME
+#define PCPS_HAS_RECEIVER_INFO ( 1UL << PCPS_BIT_HAS_RECEIVER_INFO ) ///< see ::PCPS_BIT_HAS_RECEIVER_INFO
+#define PCPS_CAN_CLR_UCAP_BUFF ( 1UL << PCPS_BIT_CAN_CLR_UCAP_BUFF ) ///< see ::PCPS_BIT_CAN_CLR_UCAP_BUFF
+#define PCPS_HAS_PCPS_TZDL ( 1UL << PCPS_BIT_HAS_PCPS_TZDL ) ///< see ::PCPS_BIT_HAS_PCPS_TZDL
+#define PCPS_HAS_UCAP ( 1UL << PCPS_BIT_HAS_UCAP ) ///< see ::PCPS_BIT_HAS_UCAP
+#define PCPS_HAS_IRIG_TX ( 1UL << PCPS_BIT_HAS_IRIG_TX ) ///< see ::PCPS_BIT_HAS_IRIG_TX
+
+#define PCPS_HAS_GPS_DATA_16 ( 1UL << PCPS_BIT_HAS_GPS_DATA_16 ) ///< see ::PCPS_BIT_HAS_GPS_DATA_16
+#define PCPS_HAS_SYNTH ( 1UL << PCPS_BIT_HAS_SYNTH ) ///< see ::PCPS_BIT_HAS_SYNTH
+#define PCPS_HAS_GENERIC_IO ( 1UL << PCPS_BIT_HAS_GENERIC_IO ) ///< see ::PCPS_BIT_HAS_GENERIC_IO
+#define PCPS_HAS_TIME_SCALE ( 1UL << PCPS_BIT_HAS_TIME_SCALE ) ///< see ::PCPS_BIT_HAS_TIME_SCALE
+#define PCPS_HAS_UTC_PARM ( 1UL << PCPS_BIT_HAS_UTC_PARM ) ///< see ::PCPS_BIT_HAS_UTC_PARM
+#define PCPS_HAS_IRIG_CTRL_BITS ( 1UL << PCPS_BIT_HAS_IRIG_CTRL_BITS ) ///< see ::PCPS_BIT_HAS_IRIG_CTRL_BITS
+#define PCPS_HAS_LAN_INTF ( 1UL << PCPS_BIT_HAS_LAN_INTF ) ///< see ::PCPS_BIT_HAS_LAN_INTF
+#define PCPS_HAS_PTP ( 1UL << PCPS_BIT_HAS_PTP ) ///< see ::PCPS_BIT_HAS_PTP
+
+#define PCPS_HAS_IRIG_TIME ( 1UL << PCPS_BIT_HAS_IRIG_TIME ) ///< see ::PCPS_BIT_HAS_IRIG_TIME
+#define PCPS_HAS_FAST_HR_TSTAMP ( 1UL << PCPS_BIT_HAS_FAST_HR_TSTAMP ) ///< see ::PCPS_BIT_HAS_FAST_HR_TSTAMP
+#define PCPS_HAS_RAW_IRIG_DATA ( 1UL << PCPS_BIT_HAS_RAW_IRIG_DATA ) ///< see ::PCPS_BIT_HAS_RAW_IRIG_DATA
+#define PCPS_HAS_PZF ( 1UL << PCPS_BIT_HAS_PZF ) ///< see ::PCPS_BIT_HAS_PZF
+#define PCPS_HAS_EVT_LOG ( 1UL << PCPS_BIT_HAS_EVT_LOG ) ///< see ::PCPS_BIT_HAS_EVT_LOG
+#define PCPS_IS_GNSS ( 1UL << PCPS_BIT_IS_GNSS ) ///< see ::PCPS_BIT_IS_GNSS
+
+/** @} anchor PCPS_FEATURE_MASKS */
#define PCPS_FEATURE_NAMES \
@@ -981,11 +764,13 @@ enum
"PCPS_HAS_PTP", \
"PCPS_HAS_IRIG_TIME", \
"PCPS_HAS_FAST_HR_TSTAMP", \
- "PCPS_HAS_RAW_IRIG_DATA" \
- "PCPS_HAS_PZF" \
+ "PCPS_HAS_RAW_IRIG_DATA", \
+ "PCPS_HAS_PZF", \
+ "PCPS_HAS_EVT_LOG", \
+ "PCPS_IS_GNSS" \
}
-/** @} */
+/** @} defgroup group_pcps_features */
@@ -1102,13 +887,25 @@ enum
#define PCPS_FEAT_WWVB51USB ( PCPS_FEAT_MSF51USB )
-#define PCPS_FEAT_GPS180PEX ( PCPS_FEAT_GPS170PEX | PCPS_HAS_FAST_HR_TSTAMP )
+#define PCPS_FEAT_GPS180PEX ( ( PCPS_FEAT_GPS170PEX | PCPS_HAS_FAST_HR_TSTAMP ) \
+ & ~PCPS_HAS_IRIG_TX ) ///< IRIG TX only supp. if ::GPS_HAS_IRIG_TX
-#define PCPS_FEAT_TCR180PEX ( PCPS_FEAT_TCR170PEX | PCPS_HAS_FAST_HR_TSTAMP )
+#define PCPS_FEAT_TCR180PEX ( ( PCPS_FEAT_TCR170PEX | PCPS_HAS_FAST_HR_TSTAMP ) \
+ & ~PCPS_HAS_IRIG_TX ) ///< IRIG TX only supp. if ::GPS_HAS_IRIG_TX
#define PCPS_FEAT_DCF600USB ( PCPS_FEAT_USB5131 )
-#define PCPS_FEAT_PZF180PEX ( PCPS_FEAT_PEX511 | PCPS_HAS_PZF )
+#define PCPS_FEAT_PZF180PEX ( PCPS_FEAT_LVL2 \
+ | PCPS_HAS_TZDL \
+ | PCPS_HAS_HR_TIME \
+ | PCPS_HAS_SERNUM \
+ | PCPS_HAS_RECEIVER_INFO \
+ | PCPS_CAN_CLR_UCAP_BUFF \
+ | PCPS_HAS_UCAP \
+ | PCPS_HAS_GPS_DATA_16 \
+ | PCPS_HAS_GENERIC_IO \
+ | PCPS_HAS_UTC_PARM \
+ | PCPS_HAS_PZF )
#define PCPS_FEAT_TCR600USB ( PCPS_FEAT_TCR51USB \
| PCPS_HAS_IRIG_CTRL_BITS \
@@ -1119,6 +916,12 @@ enum
#define PCPS_FEAT_WVB600USB ( PCPS_FEAT_WWVB51USB )
+#define PCPS_FEAT_GLN180PEX ( PCPS_FEAT_GPS180PEX | PCPS_IS_GNSS )
+
+#define PCPS_FEAT_GPS180AMC ( PCPS_FEAT_GPS180PEX )
+
+#define PCPS_FEAT_GNS181PEX ( PCPS_FEAT_GLN180PEX )
+
// Some features of the API used to access Meinberg plug-in devices
// have been implemented starting with the special firmware revision
// numbers defined below.
@@ -1128,12 +931,12 @@ enum
// There are some versions of PCI Express cards out there which do not
-// safely support hardware IRQs. The following firmware versions are required
+// 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
+// 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:
@@ -1158,8 +961,8 @@ enum
#define REV_HAS_IRIG_CTRL_BITS_TCR511PCI 0x0107
#define REV_HAS_IRIG_CTRL_BITS_TCR51USB 0x0106
-/* This board uses the GPS_DATA interface with 16 bit buffer sizes
- instead of the original 8 bit sizes, thus allowing to transfer
+/* 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
@@ -1214,16 +1017,26 @@ enum
/**
- The structure has been defined to pass all
- information on a clock device from a device driver
- to a user program. */
+ * @brief Device info structure
+ *
+ * Used to pass all information on a bus-level device
+ * from a device driver to a user space application.
+ */
typedef struct
{
PCPS_DEV_TYPE type;
PCPS_DEV_CFG cfg;
+
} PCPS_DEV;
+#if 1 || defined( MBG_TGT_KERNEL ) //### FIXME
+ #define _USE_DEV_MACROS 1
+#else
+ #define _USE_DEV_MACROS 0
+#endif
+
+
// The macros below simplify access to the data
// stored in PCPS_DEV structure and should be used
// to extract the desired information.
@@ -1247,6 +1060,7 @@ typedef struct
#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_gnss( _d ) _pcps_has_feature( (_d), PCPS_IS_GNSS )
#define _pcps_is_lwr( _d ) ( _pcps_is_dcf( _d ) || _pcps_is_msf( _d ) || _pcps_is_wwvb( _d ) )
@@ -1270,12 +1084,11 @@ typedef struct
#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_short_port_rsrc( _c, _n ) ( (_c)->port[_n] )
+#define _pcps_short_port_rsrc( _d, _n ) _pcps_cfg_short_port_rsrc( &(_d)->cfg, (_n) )
-#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_short_port_base( _c, _n ) ( _pcps_cfg_short_port_rsrc( (_c), (_n) ).base )
+#define _pcps_short_port_base( _d, _n ) ( _pcps_short_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 )
@@ -1296,12 +1109,18 @@ typedef struct
#define _pcps_clr_err_flags( _d, _msk ) ( _pcps_err_flags( _d ) &= ~(_msk) )
-// Query whether a special feature is supported:
+#if _USE_DEV_MACROS
+
+/// Check whether a special feature is supported
#define _pcps_has_feature( _d, _f ) ( ( (_d)->cfg.features & (_f) ) != 0 )
-// Query whether a special feature is supported according to RECEIVER_INFO:
+/// Check whether a special feature is supported according to ::RECEIVER_INFO
#define _pcps_has_ri_feature( _p_ri, _f ) ( ( (_p_ri)->features & (_f) ) != 0 )
+#define _ri_addr( _p ) &(_p)->xdev_features.receiver_info
+#define _xfeat_addr( _p ) &(_p)->xdev_features.xfeature_buffer
+#define _tlv_info_addr( _p ) &(_p)->xdev_features.tlv_info
+
#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 )
@@ -1397,6 +1216,25 @@ typedef struct
#define _pcps_has_tr_distance( _d ) _pcps_has_pzf( _d )
+#define _pcps_has_evt_log( _d ) _pcps_has_feature( (_d), PCPS_HAS_EVT_LOG )
+
+#define _pcps_has_debug_status( _d ) _pcps_is_irig_rx( _d )
+
+#define _pcps_has_stat_info( _d ) ( _pcps_is_gps( _d ) || _pcps_has_pzf( _d ) )
+
+#define _pcps_has_stat_info_mode( _d ) _pcps_is_gps( _d )
+
+#define _pcps_has_stat_info_svs( _d ) _pcps_is_gps( _d )
+
+#define _pcps_has_ri_gpio( _p_ri ) _pcps_has_ri_feature( (_p_ri), GPS_HAS_GPIO )
+
+// We only report that XMR is supported if all required features are supported.
+#define _pcps_has_ri_xmr( _p_ri ) ( _pcps_has_ri_feature( (_p_ri), GPS_HAS_XMULTI_REF ) && \
+ _pcps_has_ri_feature( (_p_ri), GPS_HAS_XMRS_MULT_INSTC ) )
+//### TODO should also check GPS_MODEL_HAS_XMR_HOLDOVER_INTV, which is a builtin feature flag only
+
+#endif // _USE_DEV_MACROS
+
// There are some versions of IRIG receiver cards which ignore the TFOM code
// of an incoming IRIG signal even if an IRIG code has been configured which
@@ -1404,7 +1242,7 @@ typedef struct
// signal even if the TFOM code reports the IRIG generator is not synchronized.
// The intended behaviour is that the IRIG receiver card changes its status
// to "freewheeling" in this case, unless it has been configured to ignore
-// the TFOM code of the incoming IRIG signal (see the IFLAGS_DISABLE_TFOM flag
+// the TFOM code of the incoming IRIG signal (see the ::IFLAGS_DISABLE_TFOM flag
// defined in gpsdefs.h).
// The macro below can be used to check based on the device info if a specific
@@ -1418,76 +1256,64 @@ typedef struct
// PCI bridge built into the chip. Unfortunately there are some mainboards out there
// which do not handle PCI resources behind this PCI bridge correctly. The symptom is
// usually that both I/O address ranges of these cards get the same base address
-// assigned by the BIOS, and the efeect is that in this case a card is not accessible
+// assigned by the BIOS, and the effect is that in this case a card is not accessible
// properly, since both I/O ranges try to respond to the same I/O addresses.
-// As a consequence data read from the card is usually garbage.
+// As a consequence, data read from the card is usually garbage.
// The only known fix for this is a BIOS update for the mainboard which makes the
// BIOS handle the card's resources properly.
// The macro below can be used to test if both port base addresses assigned to a card
// are identical, and thus the BIOS is probably faulty::
#define _pcps_pci_cfg_err( _d ) \
- ( _pcps_port_base( _d, 1 ) == _pcps_port_base( _d, 0 ) )
+ ( _pcps_is_pci( _d ) && ( _pcps_short_port_base( _d, 1 ) == _pcps_short_port_base( _d, 0 ) ) )
-/**
- 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;
+// There are some versions of GPS PCI firmware which may occasionally return
+// a HR time stamp which is wrong by 20 milliseconds, if the HR time is read
+// right after some GPS data. As a workaround for that bug an application
+// must wait at least 1.5 ms and then just read the PCPS_TIME structure
+// in order to re-initialize the software interface state.
+// This has been fixed in more recent versions of the affected firmware,
+// but this macro can be used to let an application determine whether it
+// must account for this bug with a given card and firmware version.
+#define _must_do_fw_workaround_20ms( _d ) \
+( \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_GPS168PCI && _pcps_fw_rev_num( _d ) < 0x0102 ) || \
+ ( _pcps_type_num( _d ) == PCPS_TYPE_GPS167PCI && _pcps_fw_rev_num( _d ) < 0x0420 ) \
+)
-/*
- * 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:
+/**
+ * @brief Codes used with ::IOCTL_DEV_FEAT_REQ::feat_req_type
*/
-
-// 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
+enum DEV_FEAT_REQ_TYPES
{
- 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];
+ DEV_FEAT_REQ_TYPE_BUILTIN, ///< feat_num field contains one of the ::GPS_BUILTIN_FEATURE_BITS
+ DEV_FEAT_REQ_TYPE_REF_TYPE, ///< feat_num field contains one of the ::PCPS_REF_TYPES
+ DEV_FEAT_REQ_TYPE_PCPS, ///< feat_num field contains one of the ::PCPS_FEATURE_BITS
+ DEV_FEAT_REQ_TYPE_RI, ///< feat_num field contains one of the ::GPS_FEATURE_BITS
+ DEV_FEAT_REQ_TYPE_XFEAT, ///< feat_num field contains one of the ::MBG_XFEATURE_BITS
+ DEV_FEAT_REQ_TYPE_TLV_FEAT, ///< feat_num field contains one of the ::MBG_TLV_FEAT_TYPES
+ N_DEV_FEAT_REQ_TYPES
+};
-/*
- * The definitions and types below are used to collect
- * all configuration parameters of PTP device's unicast
- * master specification:
+/**
+ * @brief Device driver information
+ *
+ * Used to pass info on the device driver to
+ * a user space application.
*/
+typedef struct
+{
+ uint16_t ver_num; ///< the device driver's version number
+ uint16_t n_devs; ///< the number of devices handled by the driver
+ PCPS_ID_STR id_str; ///< the device driver's ID string
-#define MAX_PARM_PTP_UC_MASTER 3
-
-typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO[MAX_PARM_PTP_UC_MASTER];
+} PCPS_DRVR_INFO;
@@ -1500,99 +1326,125 @@ typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO[MAX_PARM_PTP_UC_MASTER];
/**
- The structure is used to read the current time from
- a device, combined with an associated PC cycle counter value
- to compensate program execution time.
- */
+ * @brief Time read from a device plus associated system cycles count
+ *
+ * Contains current time from a device, plus an associated PC
+ * cycles counter value useful to compensate execution time.
+ */
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.
- */
+ * @brief High resolution time stamp plus associated system cycles count
+ *
+ * Contains current high resolution UTC time stamp from a device, plus
+ * an associated PC cycles counter value useful to compensate execution time.
+ */
typedef struct
{
MBG_PC_CYCLES cycles;
- PCPS_TIME_STAMP tstamp; /**< High resolution time stamp (UTC) */
+ PCPS_TIME_STAMP tstamp; ///< High resolution time stamp (%UTC)
+
} PCPS_TIME_STAMP_CYCLES;
#define _mbg_swab_pcps_time_stamp_cycles( _p ) \
+do \
{ \
_mbg_swab_mbg_pc_cycles( &(_p)->cycles ); \
_mbg_swab_pcps_time_stamp( &(_p)->tstamp ); \
-}
+} while ( 0 )
/**
- The structure is used to read the current high resolution time
- from a device, combined with an associated PC cycle counter value
- to compensate program execution time.
- */
+ * @brief High resolution time plus associated system cycles count
+ *
+ * Contains current high resolution %UTC time from a device, including
+ * local time offset and status, plus an associated PC cycles counter value
+ * useful to compensate execution time.
+ */
typedef struct
{
MBG_PC_CYCLES cycles;
PCPS_HR_TIME t;
+
} PCPS_HR_TIME_CYCLES;
#define _mbg_swab_pcps_hr_time_cycles( _p ) \
+do \
{ \
_mbg_swab_mbg_pc_cycles( &(_p)->cycles ); \
_mbg_swab_pcps_hr_time( &(_p)->t ); \
-}
+} while ( 0 )
/**
- The structure below can be used to let the kernel driver read
- the current system time plus the associated HR time from a plugin card
- as close as possibly, and return the results to a user space application
- which can then compute the time difference and latencies.
- This structure also contains the card's status information (e.g. sync status).
- */
+ * @brief High resolution device time, system time, and associated cycles counts
+ *
+ * Used to let the kernel driver read the current system time plus the associated
+ * high resolution time from a bus-level device as close as possible, and return
+ * the results to the caller which can then compute the time difference, taking
+ * into account the latencies determined from the cycles counts.
+ *
+ * This structure also contains the card's status information (e.g. sync status).
+ */
typedef struct
{
- PCPS_HR_TIME_CYCLES ref_hr_time_cycles; /**< HR time read from the card, plus cycles */
- MBG_SYS_TIME_CYCLES sys_time_cycles; /**< system timestamp plus associated cycles */
+ PCPS_HR_TIME_CYCLES ref_hr_time_cycles; ///< HR time read from the card, plus cycles
+ MBG_SYS_TIME_CYCLES sys_time_cycles; ///< system time stamp plus associated cycles
+
} MBG_TIME_INFO_HRT;
#define _mbg_swab_mbg_time_info_hrt( _p ) \
+do \
{ \
_mbg_swab_pcps_hr_time_cycles( &(_p)->ref_hr_time_cycles ); \
_mbg_swab_mbg_sys_time_cycles( &(_p)->sys_time_cycles ); \
-}
+} while ( 0 )
/**
- The structure below can be used to let the kernel driver read
- the current system time plus an associated HR timestamp from a plugin card
- as close as possibly, and return the results to a user space application
- which can then compute the time difference and latencies.
- Since the card's time stamp is usually taken using the fast memory mapped
- access this structure does *not* contain the card's status information
- (e.g. sync status).
- */
+ * @brief High resolution device time stamp, system time, and associated cycles counts
+ *
+ * Used to let the kernel driver read the current system time plus the associated
+ * high resolution time stamp from a bus-level device as close as possible, and return
+ * the results to the caller which can then compute the time difference, taking
+ * into account the latencies determined from the cycles counts.
+ *
+ * Since the card's time stamp is taken from the fast memory mapped registers
+ * this structure does *not* contain the card's status information (e.g. sync status).
+ */
typedef struct
{
- PCPS_TIME_STAMP_CYCLES ref_tstamp_cycles; /**< HR timestamp from the card, plus cycles */
- MBG_SYS_TIME_CYCLES sys_time_cycles; /**< system timestamp plus associated cycles */
+ PCPS_TIME_STAMP_CYCLES ref_tstamp_cycles; ///< HR timestamp from the card, plus cycles
+ MBG_SYS_TIME_CYCLES sys_time_cycles; ///< system timestamp plus associated cycles
+
} MBG_TIME_INFO_TSTAMP;
#define _mbg_swab_mbg_time_info_tstamp( _p ) \
+do \
{ \
_mbg_swab_pcps_time_stamp_cycles( &(_p)->ref_tstamp_cycles ); \
_mbg_swab_mbg_sys_time_cycles( &(_p)->sys_time_cycles ); \
-}
+} while ( 0 )
+/**
+ * @defgroup group_irq_stat_info IRQ status information
+ *
+ * @anchor PCPS_IRQ_STAT_INFO_DEFS
+ *
+ * @{ */
+
typedef uint32_t PCPS_IRQ_STAT_INFO;
// Flags used with PCPS_IRQ_STAT_INFO:
@@ -1602,6 +1454,10 @@ typedef uint32_t PCPS_IRQ_STAT_INFO;
#define PCPS_IRQ_STATE_DANGER ( PCPS_IRQ_STAT_ENABLED | PCPS_IRQ_STAT_UNSAFE )
+/** @} defgroup group_irq_stat_info */
+
+
+
#define _pcps_fw_rev_num_major( _v ) \
( ( (_v) >> 8 ) & 0xFF )
@@ -1614,6 +1470,37 @@ typedef uint32_t PCPS_IRQ_STAT_INFO;
#undef _USING_BYTE_ALIGNMENT
#endif
+
+#if !defined( MBG_TGT_KERNEL )
+
+static __mbg_inline
+void setup_hr_time_cycles_from_timestamp_cycles( PCPS_HR_TIME_CYCLES *p_ht_c,
+ const PCPS_TIME_STAMP_CYCLES *p_ts_c )
+{
+ memset( p_ht_c, 0, sizeof( *p_ht_c ) );
+
+ p_ht_c->t.tstamp = p_ts_c->tstamp;
+ p_ht_c->cycles = p_ts_c->cycles;
+
+} // setup_hr_time_cycles_from_timestamp_cycles
+
+#endif
+
+
+
+/**
+ * @brief A string buffer for a unique device ID
+ *
+ * The unique ID is made up of the device model name
+ * and its serial number, i.e. [model_name]_[serial_number]
+ * E.g.: "GPS170PCI_028210040670"
+ *
+ * @see ::snprint_dev_name
+ */
+typedef char MBG_DEV_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1];
+
+
+
/* End of header body */
#undef _ext
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c
index 4b1856f..fd6df88 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsdrvr.c 1.46.2.48 2011/07/19 12:48:10 martin TRASH $
+ * $Id: pcpsdrvr.c 1.52 2017/07/04 16:45:36 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -25,15 +25,16 @@
* USB v1: USB5131, TCR51USB, MSF51USB, WWVB51USB
* PCI express: PEX511, TCR511PEX, GPS170PEX, PTP270PEX,
* FRC511PEX, TCR170PEX, GPS180PEX, TCR180PEX
- * PZF180PEX
+ * PZF180PEX, GLN180PEX, GPS180AMC, GNS181PEX
* PCI bus 5V/3.3V: PCI510, PCI511, GPS169PCI, GPS170PCI,
* TCR510PCI, TCR167PCI, TCR511PCI
* PCI bus 5V: PCI32, GPS167PCI, PCI509, GPS168PCI
* MCA bus: PS31
* ISA bus: PC31, PC32, GPS167PC
*
- * USB is not supported for some target environments, mainly because
- * those operating systems don't provide full USB support.
+ * USB is not supported for all target environments, eventually
+ * because an operating systems doesn't provide full USB support,
+ * or USB support hasn't yet been implemented.
*
* PCI support is possible in two different ways. The preferred
* functions are compiled in if one of the symbols _PCPS_USE_PCI_PNP
@@ -42,12 +43,12 @@
* If _PCPS_USE_PCI_PNP is != 0 it is assumed that the operating
* system's PCI layer detects a new PCI device and calls a driver's
* add_device()/start_device() function to initialize the device.
- * This new technique is supported with PNP operating systems
- * (e.g. Win98, Win2K, newer Linux versions).
+ * This technique is supported with PNP operating systems
+ * (e.g. Windows versions after NT, Linux, *BSD).
*
* If _PCPS_USE_PCI_BIOS is != 0 the program scans the PCI bus
* during startup to detect and initialize supported PCI devices.
- * This techique is used with non-PNP operating systems.
+ * This techique is used with old non-PNP operating systems.
*
* The symbol _PCPS_USE_RSRCMGR must be defined != 0 to include
* support of resource managers, if necessary.
@@ -56,113 +57,75 @@
* detection (and therefore auto-detection of a MCA clock) is
* supported.
*
- * MCA clocks are accessed using the same low level functions as
- * ISA clocks, so if autodetection of MCA clocks is not supported
- * then a MCA clock's known port number can be passed to
- * pcps_detect_clocks() to let it be treated like an ISA clock.
+ * MCA devices are accessed using the same low level functions as
+ * ISA devices, so if autodetection of MCA clocks is not supported
+ * then a MCA device's known port number can be passed to
+ * pcps_detect_devices() to let it be treated like an ISA device.
*
* -----------------------------------------------------------------------
* $Log: pcpsdrvr.c $
- * Revision 1.46.2.48 2011/07/19 12:48:10 martin
+ * Revision 1.52 2017/07/04 16:45:36 martin
+ * Support GPS180AMC and GNS181PEX.
+ * Renamed some functions: Use _device instead of _clock,
+ * pcps_start_device() is now called pcps_probe_device(), etc.
+ * Runtime support for forcing I/O rather than MM access.
+ * Increase MAX_BOOT_TIME_PTP270PEX from 27 to 40 seconds
+ * to be safe in case a firmware update is applied at startup.
+ * Fixed type of a register address.
+ * Cleaned up I/O port usage.
+ * Older defines N_SUPP_DEV, PCPS_MAX_DDEVS, and MBG_MAX_DEVICES
+ * have been obsoleted by new defines N_SUPP_DEV_BUS, N_SUPP_DEV_EXT,
+ * and N_SUPP_DEV_TOTAL.
+ * Fixed DEBUG build under *BSD.
+ * Added DEBUG code dumping RECEIVER_INFO.
+ * Moved mbg_delta_sys_time_ms() to new module mbgsystm.c.
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Provided a driver name string for debug build on direct-access targets.
+ * Avoid 'redundant redeclaration' warning under FreeBSD 8.2.
+ * Fixed macro definition syntax to avoid clang compiler warnings.
+ * Fixed some other warnings from clang.
+ * Attribute always_inline is now in __mbg_inline.
+ * Conditional USB debug code.
+ * Account for renamed symbols.
+ * Fixed typos, wording, and doxygen comments.
+ * Removed trailing white space.
+ * Revision 1.51 2013/10/01 14:19:03 martin
+ * Support GLN180PEX.
+ * Revision 1.50 2013/03/15 10:01:58 martin
+ * Modified/added some debug messages.
+ * Revision 1.49 2013/03/15 08:35:08 martin
+ * Account for PTP270PEX HW v2 cards which can indicate
+ * when they are ready to be accessed.
+ * Account for unified, renamed PLX symbols.
+ * Revision 1.48 2012/11/05 16:32:02Z martin
+ * Fixed and enhanced some timing DEBUG code.
+ * Rewrote report_uptime().
+ * Revision 1.47 2012/10/15 14:12:08 martin
+ * Support GPS180PEX, TCR180PEX, and PZF180PEX.
+ * Support DCF600USB, TCR600USB, MSF600USB, and WVB600USB.
+ * Support FreeBSD and NetBSD.
+ * Support on-board event log.
+ * If required, wait until PTP270PEX has finished booting.
+ * Use USB micro frame timing conditionally only, yet disabled by default.
+ * Conditional debug code to test PCI access time and/or execution time
+ * of the low level functions.
+ * Always read the serial number directly from the device.
* Unified low level functions and use 16 bit types for buffer sizes.
- * Cleanup.
- * Revision 1.46.2.47 2011/07/11 12:49:44 martin
- * Revision 1.46.2.46 2011/07/11 11:00:42Z martin
- * Modified some debug code.
- * Revision 1.46.2.45 2011/07/05 10:44:22 martin
- * Fixed build errors under Unix.
- * Revision 1.46.2.44 2011/07/05 10:18:59 martin
- * Fixed pcps_start_device() for USBv2 devices.
- * Added warnings in case a device is not handled
- * by chip setup or device feature check.
- * Revision 1.46.2.43 2011/06/29 14:02:49Z martin
- * Renamed PZF600PEX to PZF180PEX.
- * Added support for TCR600USB, MSF600USB, and WVB600USB.
- * Modified low level AMCC read functions for SPARC.
- * Fixed handling of unaligned access for SPARC.
- * Modified DEBUG_IO code.
- * Added some debug messages.
- * Updated some comments.
- * Revision 1.46.2.42 2011/06/21 15:20:56 martin
- * Fixed build under DOS.
- * Revision 1.46.2.41 2011/06/20 16:53:34Z martin
- * account for generic MBG_SYS_TIME with nanosecond resolution.
- * Revision 1.46.2.40 2011/05/16 17:41:11 martin
+ * Added warnings in case a device is not handled by chip setup
+ * or device feature check.
+ * Modified low level AMCC read functions for SPARC to fix unaligned access.
+ * Added debug messages for generic I/O.
* Initialize device semaphores only early at device initializition
* if required, otherwise later, since early initialization can lead
* to a trap e.g. under Windows.
- * Revision 1.46.2.39 2011/05/06 13:47:39Z martin
- * Support PZF600PEX.
- * Revision 1.46.2.38 2011/04/19 15:06:56 martin
- * Fixed build error on bigendian target.
- * Revision 1.46.2.37 2011/04/12 15:28:56 martin
+ * Conditional code to test MM I/O for new PCI cards.
* Use common mutex primitives from mbgmutex.h.
- * Revision 1.46.2.36 2011/04/01 10:38:00 martin
- * Modified mutex/spinlock initialization, and do deinitializaton.
- * Fixed compiler warnings.
- * Revision 1.46.2.35 2011/03/25 11:10:34 martin
* Optionally support timespec for sys time (USE_TIMESPEC).
- * Revision 1.46.2.34 2011/03/22 10:25:57 martin
- * Modifications to support NetBSD.
- * Revision 1.46.2.33 2011/03/21 16:26:03 martin
- * Account for modified _pcps_kfree().
- * Revision 1.46.2.32 2011/02/16 10:14:37 martin
* Set up basic default receiver info for devices which don't
* support this structure.
- * Revision 1.46.2.31 2011/02/15 14:24:57Z martin
- * Revision 1.46.2.30 2011/02/10 09:18:07 martin
- * Revision 1.46.2.29 2011/02/09 17:08:30Z martin
- * Specify I/O range number when calling port I/O macros
- * so they can be used for different ranges under BSD.
- * Revision 1.46.2.28 2011/02/09 16:42:12 martin
- * Revision 1.46.2.27 2011/02/09 15:27:49 martin
- * Revision 1.46.2.26 2011/02/09 14:43:19Z martin
- * Revision 1.46.2.25 2011/02/07 15:47:28 martin
- * Fixed a potential trap in kernel messages.
- * Revision 1.46.2.24 2011/02/04 14:44:45 martin
- * Revision 1.46.2.23 2011/02/01 17:12:04 martin
- * Revision 1.46.2.22 2011/02/01 15:08:34 martin
- * Revision 1.46.2.21 2011/02/01 12:12:18 martin
- * Revision 1.46.2.20 2011/01/31 17:30:28 martin
- * Preliminary virt addr under *BSD.
- * Revision 1.46.2.19 2011/01/28 10:34:06 martin
* Moved MBG_TGT_SUPP_MEM_ACC definition to pcpsdev.h.
- * Revision 1.46.2.18 2011/01/27 15:13:08 martin
- * Added some debug messages in pcps_start_device().
- * Revision 1.46.2.17 2011/01/27 13:39:33 martin
- * Revision 1.46.2.16 2011/01/27 11:01:48 martin
- * Support static device list (no malloc) and use it under FreeBSD.
- * Revision 1.46.2.15 2011/01/26 16:40:14 martin
- * Fixed build under FreeBSD.
- * Revision 1.46.2.14 2011/01/26 11:30:29 martin
- * Fixed PTP270PEX boot delay.
- * Revision 1.46.2.13 2011/01/07 14:00:58 daniel
- * Re-enabled wait period for PTP270PEX
- * Revision 1.46.2.12 2010/11/23 11:07:56Z martin
- * Support memory mapped access under DOS.
- * Revision 1.46.2.11 2010/11/22 14:19:27Z martin
- * Support DCF600USB.
- * Cleanup.
- * Revision 1.46.2.10 2010/10/06 09:24:02 martin
- * Revision 1.46.2.9 2010/09/27 13:09:22Z martin
- * Revision 1.46.2.8 2010/09/21 13:10:15 daniel
- * Check for raw IRIG data support in reciver info.
- * Revision 1.46.2.7 2010/09/02 12:19:24Z martin
* Introduced and use new function check_ri_feature().
* Also detect support for raw IRIG data from RECEIVER_INFO.
- * Added debug code.
- * Sleeping for PTP270PEX if uptime is too low needs to be fixed.
- * Revision 1.46.2.6 2010/08/16 15:41:28 martin
- * Revision 1.46.2.5 2010/08/13 11:56:49 martin
- * Fixed build on WIN32_NON_PNP.
- * Revision 1.46.2.4 2010/08/13 11:20:23Z martin
- * If required, wait until PTP270PEX has finished booting.
- * Revision 1.46.2.3 2010/08/11 13:41:47Z martin
- * Code cleanup.
- * Revision 1.46.2.2 2010/07/14 14:51:56 martin
- * Use direct pointer to memory maopped timestamp.
- * Revision 1.46.2.1 2010/06/30 15:02:12 martin
- * Support GPS180PEX and TCR180PEX.
* Revision 1.46 2009/12/15 14:45:33 daniel
* Account for feature to read the raw IRIG bits.
* Revision 1.45 2009/09/29 07:24:50Z martin
@@ -184,17 +147,17 @@
* Revision 1.38 2009/03/17 15:33:53 martin
* Support reading IRIG control function bits.
* Revision 1.37 2009/03/13 09:17:00Z martin
- * Bug fix: Hadn't checked whether TCR170PEX card provides the
+ * Bug fix: Hadn't checked whether TCR170PEX card provides the
* programmable synthesizer.
- * As a fix moved the code from the body of check_opt_features()
- * into pcps_start_device() so that the check is done for every
+ * As a fix moved the code from the body of check_opt_features()
+ * into pcps_start_device() so that the check is done for every
* type of card.
* Swap receiver_info to make this work on non-x86 architectures.
- * Support configurable time scales, and reading/writing GPS UTC
+ * Support configurable time scales, and reading/writing GPS UTC
* parameters via the PC bus.
* Use mbg_get_pc_cycles() instead of _pcps_get_cycles().
* Revision 1.36 2009/01/13 12:03:57Z martin
- * Generate a separate warning message if the firmware could not
+ * Generate a separate warning message if the firmware could not
* be read from an ISA card.
* Care about "long long" in debug msg.
* Revision 1.35 2008/12/16 14:38:49Z martin
@@ -204,10 +167,10 @@
* Check whether PEX511 and PCI511 support HR time.
* Moved initialization of common spinlocks and mutexes to pcps_start_device().
* Take access cycles count in the low level routines, with interrupts disabled.
- * Cleanup for pcps_read_usb() which is now possible since access cycles count
+ * Cleanup for pcps_read_usb() which is now possible since access cycles count
* is now taken inside the low evel routines.
* Support mapped I/O resources, unaligned access and endianess conversion.
- * Account for ASIC_FEATURES being coded as flags, and account for
+ * Account for ASIC_FEATURES being coded as flags, and account for
* new symbol PCI_ASIC_HAS_MM_IO.
* Account for new MBG_PC_CYCLES type.
* Account for signed irq_num.
@@ -215,8 +178,8 @@
* Use MBG_MEM_ADDR type for memory rather than split high/low types.
* Distinguish device port variables for IRQ handling.
* Preliminarily support USB latency compensation under Win32 PNP targets
- * and account for USB EHCI microframe timing which requires a different
- * latency compensation approach. This is useful if a USB 2.0 hub is connected
+ * and account for USB EHCI microframe timing which requires a different
+ * latency compensation approach. This is useful if a USB 2.0 hub is connected
* between device and host.
* Also read the ASIC version at device initialization.
* pcps_alloc_ddev() does not take a parameter anymore.
@@ -224,9 +187,9 @@
* Revision 1.34 2008/02/27 10:03:02 martin
* Support TCR51USB and MSF51USB.
* Preliminary support for mapped memory access under Windows and Linux.
- * Enabled PCPS_IRQ_1_SEC for USB within WIN32 targets
+ * Enabled PCPS_IRQ_1_SEC for USB within WIN32 targets
* in pcps_start_device().
- * Fixed a bug in pcps_write() where the error code
+ * Fixed a bug in pcps_write() where the error code
* that was returned from a USB device was misinterpreted
* due to a signed/unsigned mismatch (added typecast).
* Removed obsolete function pcps_cleanup_all_devices().
@@ -271,7 +234,7 @@
* OS requirements, in order to avoid naming conflicts.
* Revision 1.26 2006/06/19 15:28:52 martin
* Added support for TCR511PCI.
- * Modified parameters required to detect ISA cards.
+ * Modified parameters required to detect ISA cards.
* The array of port addresses does no more require a 0 address
* as last value.
* Revision 1.25 2006/03/10 11:01:27 martin
@@ -291,8 +254,8 @@
* Revision 1.19 2004/10/14 15:01:24 martin
* Added support for TCR167PCI.
* Revision 1.18 2004/09/06 15:16:57Z martin
- * Support a GPS_DATA interface where sizes are specified
- * by 16 instead of the original 8 bit quantities, thus allowing
+ * 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.
* Conditionally skip assertions under Linux.
* Revision 1.17 2004/04/22 14:47:54 martin
@@ -330,9 +293,9 @@
* Use new header mbg_tgt.h to check the target environment.
* Removed function pcps_sn_str_from_ident(), use new
* function mbg_gps_ident_decode() from identdec.c now.
- * If a PCI clock's interface is not properly configured don't
- * enable the device and set the read function to the new
- * dummy function pcps_read_null() to prevent driver from
+ * If a PCI clock's interface is not properly configured don't
+ * enable the device and set the read function to the new
+ * dummy function pcps_read_null() to prevent driver from
* accessing random ports.
* Revision 1.5 2002/02/01 12:06:12 MARTIN
* Added support for GPS168PCI.
@@ -355,13 +318,12 @@
#include <pcpsdrvr.h>
#undef _PCPSDRVR
-#include <parmpcps.h>
-#include <parmgps.h>
#include <identdec.h>
#include <mbgddmsg.h>
#include <plxdefs.h>
#include <pci_asic.h>
#include <amccdefs.h>
+#include <pcidefs.h>
#if defined( MBG_TGT_WIN32_PNP )
#include <usbdrv.h>
@@ -371,6 +333,8 @@
#elif defined( MBG_TGT_WIN32 )
#include <pcps_ioc.h>
#include <stdio.h>
+#elif defined( MBG_TGT_DOS )
+ #include <mbgplx.h>
#endif
#if !defined( MBG_TGT_LINUX ) && !defined( MBG_TGT_BSD )
@@ -379,7 +343,6 @@
#if defined( MBG_TGT_FREEBSD )
#include <sys/rman.h>
- #include <sys/libkern.h>
#endif
#if _PCPS_USE_MCA
@@ -395,27 +358,109 @@
#endif
-// time required for PTP270PEX to be ready after booting
-#define MAX_BOOT_TIME_PTP270PEX 27 // [s]
+// In NetBSD defining DEBUG to build a debug version of this driver
+// would interfere with DEBUG being defined for the kernel sources,
+// so we need to define MBG_DEBUG instead. For simplicity, we define
+// DEBUG locally in this module if MBG_DEBUG is defined.
+#if defined( MBG_TGT_NETBSD ) && defined( MBG_DEBUG )
+ #undef DEBUG
+ #define DEBUG MBG_DEBUG
+#endif
+
+
+#if !defined( USE_CMD_PTR )
+ #define USE_CMD_PTR 1
+#endif
+#if !defined( DEBUG_ACCESS_TIMING )
+ // test how much cycles it takes to read/write a register on the board
+ #if ( defined( DEBUG ) && ( DEBUG >= 10 ) )
+ #define DEBUG_ACCESS_TIMING 1
+ #else
+ #define DEBUG_ACCESS_TIMING 0
+ #endif
+#endif
+
+#if !defined( DEBUG_IO_TIMING )
+ // test how much cycles it takes for a low level function to execute
+ #if ( defined( DEBUG ) && ( DEBUG >= 10 ) )
+ #define DEBUG_IO_TIMING 1
+ #else
+ #define DEBUG_IO_TIMING 0
+ #endif
+#endif
#if !defined( DEBUG_IO )
- #if defined( MBG_TGT_NETBSD )
- #define DEBUG_IO ( defined( MBG_DEBUG ) && ( MBG_DEBUG >= DEBUG_LVL_IO ) )
+ // debug which bytes are written to or read from the board
+ #if ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_IO ) )
+ #define DEBUG_IO 1
#else
- #define DEBUG_IO ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_IO ) )
+ #define DEBUG_IO 0
#endif
#endif
#if !defined( DEBUG_PORTS )
- #define DEBUG_PORTS ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_PORTS ) )
+ #if ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_PORTS ) )
+ #define DEBUG_PORTS 1
+ #else
+ #define DEBUG_PORTS 0
+ #endif
#endif
#if !defined( DEBUG_SERNUM )
- #define DEBUG_SERNUM ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_SERNUM ) )
+ #if ( defined( DEBUG ) && ( DEBUG >= DEBUG_LVL_SERNUM ) )
+ #define DEBUG_SERNUM 1
+ #else
+ #define DEBUG_SERNUM 0
+ #endif
+#endif
+
+#if !defined( USE_USB_MICRO_FRAMES )
+ #define USE_USB_MICRO_FRAMES 0
#endif
-extern const char pcps_driver_name[];
+
+/**
+ * @brief Max. time required for PTP270PEX v1 card to be ready after power-up.
+ *
+ * The PTP270PEX cards have an on-board Linux system which must have
+ * finished booting before the card can be accessed via the PCI bus.
+ * If the card is accessed earlier then the PCI bus and thus the computer
+ * may hang.
+ *
+ * There are 2 different hardware versions of the PTP270PEX card.
+ * PTP270PEX v2 hardware and firmware can flag via a bit in the PCI
+ * configuration space when the card is ready, so the driver can just
+ * wait until the card has flagged that it's ready.
+ *
+ * However, the PTP270PEX v1 hardware doesn't support this, so the driver
+ * checks the system uptime and waits until it is greater or equal the
+ * maximum time required for a PTP270PEX v1 card to finish booting.
+ *
+ * The nominal time is 27 s, but if a firmware update has been submitted
+ * then the update is applied first, which takes another few seconds.
+ *
+ * @see ::wait_ptp270pex_ready
+ * @see ::report_uptime
+ */
+#define MAX_BOOT_TIME_PTP270PEX 40 // [s]
+
+
+#if defined( MBG_TGT_BSD )
+ // Avoid compiler warnings "redundant redeclaration of ..."
+ // e.g. under FreeBSD 8.2 with gcc 4.2.1.
+ #define AVOID_REDUNDANT_REDECLARATION 1
+#endif
+
+#if defined( MBG_TGT_KERNEL )
+ // Driver name defined by the skeleton driver for the target OS.
+ extern const char pcps_driver_name[];
+#else
+ // No skeleton driver, but we need a string to pass to debug messages.
+ #if DEBUG
+ const char pcps_driver_name[] = "pcpsdrvr";
+ #endif
+#endif
// In some environments special far functions are are neither
@@ -495,120 +540,505 @@ extern const char pcps_driver_name[];
#endif
+#if defined( MBG_TGT_DOS ) || \
+ defined( MBG_TGT_QNX )
+ #define MBG_TGT_HAS_UPTIME 0
+#elif defined( MBG_TGT_FREEBSD )
+ // Under FreeBSD (at least 8.2) the kernel calls to read uptime always
+ // return 1 when this driver is loaded automatically, so the system
+ // locks up if we wait util uptime has reached a certain value.
+ #define MBG_TGT_HAS_UPTIME 0
+#else
+ #define MBG_TGT_HAS_UPTIME 1
+#endif
+
+
+
+/**
+ * @brief A table used to map ::RECEIVER_INFO::features to ::PCPS_DEV_CFG::features
+ *
+ * The enumerated ::GPS_FEATURE_BITS can be used as index
+ * to this table, and the table entry contains a combination
+ * of associated @ref PCPS_FEATURE_MASKS, if there are any.
+ *
+ * @note Devices which support a configurable time scale do also
+ * support reading/writing the GPS %UTC parameters via the PC bus.
+ * This is not explicitly coded in the ::RECEIVER_INFO::features
+ * since the the ::RECEIVER_INFO structure can also be read via
+ * the serial port, and reading/writing the GPS %UTC parameters
+ * via the serial port is supported by all GPS devices anyway.
+ *
+ * @note Devices which support reading ::MBG_RAW_IRIG_DATA via the PC bus
+ * interface also support reading ::PCPS_IRIG_TIME. However, there is
+ * no associated flag in ::RECEIVER_INFO::features since this call
+ * is not supported via the serial interface. Thus we use the
+ * ::GPS_HAS_RAW_IRIG_DATA flag to check both features.
+ *
+ * @see ::GPS_FEATURE_BITS
+ * @see @ref PCPS_FEATURE_MASKS
+ */
+static uint32_t ri_feat_tbl[N_GPS_FEATURE] =
+{
+ 0, ///< see ::GPS_FEAT_PPS
+ 0, ///< see ::GPS_FEAT_PPM
+ PCPS_HAS_SYNTH, ///< see ::GPS_FEAT_SYNTH
+ 0, ///< see ::GPS_FEAT_DCFMARKS
+ PCPS_HAS_IRIG_TX, ///< see ::GPS_FEAT_IRIG_TX
+ 0, ///< see ::GPS_FEAT_IRIG_RX
+ PCPS_HAS_LAN_INTF, ///< see ::GPS_FEAT_LAN_IP4
+ 0, ///< see ::GPS_FEAT_MULTI_REF
+
+ 0, ///< see ::GPS_FEAT_RCV_TIMEOUT
+ 0, ///< see ::GPS_FEAT_IGNORE_LOCK
+ 0, ///< see ::GPS_FEAT_5_MHZ
+ 0, ///< see ::GPS_FEAT_XMULTI_REF
+ 0, ///< see ::GPS_FEAT_OPT_SETTINGS
+ PCPS_HAS_TIME_SCALE | PCPS_HAS_UTC_PARM, ///< see ::GPS_FEAT_TIME_SCALE
+ PCPS_HAS_IRIG_CTRL_BITS, ///< see ::GPS_FEAT_IRIG_CTRL_BITS
+ PCPS_HAS_PTP, ///< see ::GPS_FEAT_PTP
+
+ 0, ///< see ::GPS_FEAT_NAV_ENGINE_SETTINGS
+ PCPS_HAS_IRIG_TIME | PCPS_HAS_RAW_IRIG_DATA, ///< see ::GPS_FEAT_RAW_IRIG_DATA
+ 0, ///< see ::GPS_FEAT_RAW_IRIG_TIME
+ 0, ///< see ::GPS_FEAT_PTP_UNICAST
+ 0, ///< see ::GPS_FEAT_GPIO
+ 0, ///< see ::GPS_FEAT_XMRS_MULT_INSTC
+ 0, ///< see ::GPS_FEAT_10MHZ_DISBD
+ PCPS_HAS_EVT_LOG, ///< see ::GPS_FEAT_EVT_LOG
+
+ 0, ///< see ::GPS_FEAT_IMS
+ 0, ///< see ::GPS_FEAT_HAVEQUICK
+ 0, ///< see ::GPS_FEAT_NTP
+ 0, ///< see ::GPS_FEAT_NET_CFG
+ 0, ///< see ::GPS_FEAT_VST
+ 0, ///< see ::GPS_FEAT_SHS
+ 0 ///< see ::GPS_FEAT_XBP
+};
+
+
+
+#if defined( DEBUG )
+
+/**
+ * @brief A table of name strings associated with ::GPS_FEATURE_BITS
+ */
+static const char *gps_ri_feature_names[N_GPS_FEATURE] = DEFAULT_GPS_FEATURE_NAMES;
+
+/**
+ * @brief A table of name strings associated with ::PCPS_FEATURE_BITS
+ */
+static const char *pcps_feature_names[N_PCPS_FEATURE_BITS] = PCPS_FEATURE_NAMES;
+
+#endif // defined( DEBUG )
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Check if a device is a PTP270PEX card
+ */
+int pcps_ddev_is_ptp270pex( const PCPS_DDEV *pddev )
+{
+ return _pcps_ddev_is_pci( pddev ) &&
+ ( _pcps_ddev_dev_id( pddev ) == PCI_DEV_PTP270PEX );
+
+} // pcps_ddev_is_ptp270pex
+
+
+
+
+#if defined( MBG_TGT_LINUX )
static /*HDR*/
-long mbg_delta_sys_time_ms( const MBG_SYS_TIME *t2, const MBG_SYS_TIME *t1 )
+/**
+ * @brief Read a dword from a PLX PECS register
+ *
+ * @param[in] pNode Device structure
+ * @param[in] reg Number of the register to read
+ * @param[out] pval Pointer to a variable to take the value read from the register
+ *
+ * @return ::PCI_SUCCESS on success, else one of the PCI BIOS error codes
+ */
+int mbg_plx_read_pecs_reg( struct pci_dev *pNode,
+ uint16_t reg, uint32_t *pval )
{
- #if USE_GENERIC_SYS_TIME
- long dt = ( t2->sec - t1->sec ) * 1000;
- #if defined ( MBG_TGT_LINUX ) && defined( MBG_TGT_KERNEL )
- int64_t tmp64 = t2->nsec - t1->nsec;
- do_div( tmp64, 1000000 );
- dt += tmp64;
- #else
- dt += ( t2->nsec - t1->nsec ) / 1000000;
- #endif
- return dt;
+ int rc;
+
+ if ( reg & 0x03 )
+ return PCI_BAD_REGISTER_NUMB;
+
+ if ( reg < 0x1000 )
+ {
+ rc = pci_read_config_dword( pNode, reg, pval );
+ }
+ else
+ {
+ uint32_t mcr_idx_sav = (uint32_t) -1;
+
+ reg -= 0x1000;
+
+ rc = pci_read_config_dword( pNode, PLX_PECS_MAININDEX, &mcr_idx_sav );
+
+ if ( rc != PCI_SUCCESS )
+ goto done;
+
+ rc = pci_write_config_dword( pNode, PLX_PECS_MAININDEX, reg );
+
+ if ( rc != PCI_SUCCESS )
+ goto done;
+
+ rc = pci_read_config_dword( pNode, PLX_PECS_MAINDATA, pval );
+
+ if ( rc != PCI_SUCCESS )
+ goto done;
+
+ rc = pci_write_config_dword( pNode, PLX_PECS_MAININDEX, mcr_idx_sav );
+ }
+
+done:
+ return rc;
+
+} // mbg_plx_read_pecs_reg
+
+#endif
+
+
+
+static /*HDR*/
+/**
+ * @brief Check if a PTP270PEX card can indicate when it's ready
+ *
+ * A PTP270PEX card must be accessed by the driver only
+ * after it has finished booting. Otherwise the host system
+ * may be locked up.
+ *
+ * On HW v2 cards the firmware can indicate when the card is
+ * ready to be accessed, so this can be checked by the driver.
+ * On these cards the on-board GPIO3 pin is hardwired to 0
+ * to indicate this is supported, whereas on older v1 cards
+ * the GPIO3 pin is pulled up to 1.
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @return true if the card can flag "ready"
+ *
+ * @see ::ptp270pex_has_flagged_ready
+ */
+bool ptp270pex_can_flag_ready( const PCPS_DDEV *pddev )
+{
+ // The GPIO3 input level can only be read via a register
+ // which is located inside the PCI configuration space
+ // of the built-in PLX8111 PCIe-to-PCI bridge.
+ //
+ // So we must first locate the PCI bridge associated with our device,
+ // read the PECS_GPIOCTL register and return 1 if the GPIO3 bit
+ // has been pulled down to 0.
+
+ uint32_t reg_val = (uint32_t) -1;
+ int rc = -1;
+
+ #if defined( MBG_TGT_LINUX )
+
+ struct pci_dev *bridge = NULL;
+
+ // search for any PLX PCI bridge device
+ while ( ( bridge = pci_get_device( PCI_VENDOR_ID_PLX,
+ PCI_DEVICE_ID_PLX_8111, bridge ) ) != NULL )
+ {
+ uint8_t uc;
+
+ #if defined( DEBUG )
+ printk( KERN_INFO "%s: Found bridge: %s\n",
+ pcps_driver_name, pci_name( bridge ) );
+ #endif
+
+ // Read the secondary bus number.
+ rc = pci_read_config_byte( bridge, 0x19, &uc );
+
+ if ( ( rc == PCI_SUCCESS ) && ( uc == pddev->dev.cfg.bus_num ) )
+ {
+ #if defined( DEBUG )
+ printk( KERN_INFO "%s: Found bridge associated with device %s\n",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ) );
+ #endif
+ break;
+ }
+ }
+
+ if ( bridge ) // associated PCI bridge has been found
+ {
+ rc = mbg_plx_read_pecs_reg( bridge, PLX_PECS_GPIOCTL, &reg_val );
+
+ #if defined( DEBUG )
+ printk( KERN_INFO "%s: Read cfg dword %04lX: %08lX, rc: %i\n",
+ pcps_driver_name, (ulong) PLX_PECS_GPIOCTL, (ulong) reg_val, rc );
+ #endif
+
+ // The pci_get_device() calls above has increased the use count
+ // for the last device which has been found, so we need to decrease
+ // the use count if we don't need to access the device anymore.
+ // This is done by calling the complementary function.
+ pci_dev_put( bridge );
+ }
+
#elif defined( MBG_TGT_WIN32 )
- return (long) ( ( t2->QuadPart - t1->QuadPart ) / HNS_PER_MS );
+
+ // We don't scan the PCI bus to find the associated bridge device
+ // but just assume the card can flag when it's ready. If the card
+ // actually can't then the driver just waits until the maximum
+ // required uptime has been reached or exceeded, so there's no danger
+ // that the system might lock up.
+ rc = PCI_SUCCESS;
+ reg_val = 0;
+
+ #elif defined( MBG_TGT_DOS )
+
+ PLX_DEVICE_NODE dn_bridge = { 0 };
+
+ rc = mbg_find_plx8311_bridge( pddev->dev.cfg.bus_num, &dn_bridge );
+
+ if ( rc == PCI_SUCCESS )
+ rc = mbg_plx_read_pecs_reg( &dn_bridge, PLX_PECS_GPIOCTL, &reg_val );
+
#else
- return 0;
+
#endif
-} // mbg_delta_sys_time_ms
+ // The device can indicate when it's ready if reg_val
+ // has been read successfully, and the GPIO3 bit is 0.
+ return ( rc == PCI_SUCCESS ) && ( ( reg_val & PLX_PECS_GPIOCTL_GPIO3_DATA ) == 0 );
+
+} // ptp270pex_can_flag_ready
+
+
+
+static /*HDR*/
+/**
+ * @brief Check if a PTP270PEX card indicates it is ready
+ *
+ * A PTP270PEX card must be accessed by the driver only
+ * after it has finished booting. Otherwise the host system
+ * may be locked up.
+ *
+ * On HW v2 cards the firmware can indicate when the card is
+ * ready to be accessed, so the driver can call this function
+ * to check this.
+ *
+ * @note The function ::ptp270pex_can_flag_ready should
+ * have been called before to check if the card actually
+ * supports this.
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @return true if the card has flagged "ready"
+ *
+ * @see ::ptp270pex_can_flag_ready
+ */
+bool ptp270pex_has_flagged_ready( const PCPS_DDEV *pddev )
+{
+ // GPIO pin USERI is pulled down to 0 by the firmware
+ // as soon as the card is ready to be accessed.
+ // With PTP270PEX HW v1 cards this pin is always 1.
+
+ // Read the LCS_CNTRL register and return 1 if the USERI
+ // bit is set.
+
+ PCPS_IO_ADDR_MAPPED cntrl_reg = _pcps_ddev_io_base_mapped( pddev, 1 )
+ + PLX_LCS_CNTRL;
+ uint32_t reg_val = _mbg_inp32_to_cpu( pddev, 0, cntrl_reg );
+
+ return ( reg_val & PLX_LCS_CNTRL_USERI ) == 0;
+
+} // ptp270pex_has_flagged_ready
+#if MBG_TGT_HAS_UPTIME
+
static /*HDR*/
+/**
+ * @brief Report the system uptime
+ *
+ * This is mainly used for debugging, and informational.
+ *
+ * @param[in] p_uptime The system uptime
+ *
+ * @see ::wait_ptp270pex_ready
+ * @see ::MAX_BOOT_TIME_PTP270PEX
+ */
void report_uptime( const MBG_SYS_UPTIME *p_uptime )
{
- #if defined( MBG_TGT_LINUX )
- printk( KERN_INFO "%s: system uptime %llu jiffies -> %llu s, required %u s\n",
- pcps_driver_name, (unsigned long long) ( get_jiffies_64() - INITIAL_JIFFIES ),
- (unsigned long long) *p_uptime, MAX_BOOT_TIME_PTP270PEX );
- #elif defined( MBG_TGT_BSD )
- printf( "%s: system uptime %llu s, required %u s\n",
- pcps_driver_name, (unsigned long long) *p_uptime, MAX_BOOT_TIME_PTP270PEX );
- #elif defined( MBG_TGT_WIN32 )
+ #if defined( MBG_TGT_WIN32 )
+ // Simplified code for Windows since Windows doesn't provide
+ // snprintf() or an equivalent function in kernel mode.
WCHAR wcs_msg[120];
swprintf( wcs_msg, L"system uptime: %I64u s, required %u s",
(int64_t) *p_uptime, MAX_BOOT_TIME_PTP270PEX );
- _evt_msg( GlbDriverObject, wcs_msg );
+ _evt_msg_w( GlbDriverObject, wcs_msg );
+
+ #else
+
+ char ws[120];
+ int l = sizeof( ws );
+ int n = 0;
+
+ n += snprintf( &ws[n], l - n, "%s: system uptime ", pcps_driver_name );
+
+ #if defined( MBG_TGT_LINUX )
+ n += snprintf( &ws[n], l - n, "%llu jiffies -> ",
+ (unsigned long long) ( get_jiffies_64() - INITIAL_JIFFIES ) );
+ #endif
+
+ n += snprintf( &ws[n], l - n, "%llu", (unsigned long long) *p_uptime );
+ n += snprintf( &ws[n], l - n, " s, required %u s", MAX_BOOT_TIME_PTP270PEX );
+
+ if ( *p_uptime < MAX_BOOT_TIME_PTP270PEX )
+ {
+ int waiting = (int) ( MAX_BOOT_TIME_PTP270PEX - *p_uptime );
+ n += snprintf( &ws[n], l - n, ", waiting %i s", waiting );
+ }
+ else
+ n += snprintf( &ws[n], l - n, ", OK." );
+
+ #if defined( MBG_TGT_LINUX )
+ printk( KERN_INFO "%s\n", ws );
+ #elif defined( MBG_TGT_BSD )
+ printf( "%s\n", ws );
+ #endif
+
#endif
} // report_uptime
+#endif // MBG_TGT_HAS_UPTIME
+
static /*HDR*/
-void check_uptime( void )
+/**
+ * @brief Wait until a PTP270PEX card is ready after power-up
+ *
+ * A PTP270PEX card must be accessed by the driver only
+ * after it has finished booting. Otherwise the host system
+ * may be locked up.
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @see ::ptp270pex_can_flag_ready
+ * @see ::ptp270pex_has_flagged_ready
+ * @see ::report_uptime
+ * @see ::MAX_BOOT_TIME_PTP270PEX
+ */
+void wait_ptp270pex_ready( const PCPS_DDEV *pddev )
{
- #if !defined( MBG_TGT_DOS )
- MBG_SYS_TIME t1;
- MBG_SYS_TIME t2;
- MBG_SYS_UPTIME uptime;
- int delayed = 0;
+ MBG_SYS_TIME t1;
+ MBG_SYS_TIME t2;
+ MBG_SYS_UPTIME uptime;
+ int delayed = 0;
+ bool can_flag_ready;
+ int i = 0;
- mbg_get_sys_time( &t1 );
+ // A newer PTP270PEX card (HW v2.0) can indicate if it has
+ // finished booting and thus is ready to be accessed, but
+ // older PTP270PEX cards (HW v1.0) don't support this.
+ can_flag_ready = ptp270pex_can_flag_ready( pddev );
- for (;;)
- {
- mbg_get_sys_uptime( &uptime );
+ mbg_get_sys_time( &t1 );
+
+ for (;;)
+ {
+ mbg_get_sys_uptime( &uptime );
+ #if MBG_TGT_HAS_UPTIME
#if !defined( DEBUG )
- if ( !delayed )
+ if ( delayed )
#endif
report_uptime( &uptime );
+ #endif
- if ( uptime == 0 )
+ if ( can_flag_ready )
+ {
+ if ( ptp270pex_has_flagged_ready( pddev ) )
+ break;
+ }
+ else
+ {
+ // If the card is unable to indicate when it is ready
+ // and the target system doesn't support uptime
+ // then it makes no sense to keep looping and waiting,
+ // so just stop waiting and hope the card is ready.
+ if ( uptime == 0 || uptime == -1 )
break; // assume uptime not supported
+ }
- if ( uptime >= MAX_BOOT_TIME_PTP270PEX )
- break;
+ // If the target system supports uptime then
+ // keep looping until the system uptime exceeds
+ // the max. boot time required by the card.
- mbg_sleep_sec( 1 );
- delayed = 1;
- }
+ if ( uptime >= MAX_BOOT_TIME_PTP270PEX )
+ break;
- if ( delayed )
- {
- long dt;
+ mbg_sleep_sec( 1 );
+ delayed = 1;
- mbg_get_sys_time( &t2 );
+ if ( ++i >= MAX_BOOT_TIME_PTP270PEX )
+ break;
+ }
- dt = mbg_delta_sys_time_ms( &t2, &t1 );
+ if ( delayed )
+ {
+ long dt;
- #if defined( MBG_TGT_LINUX )
- printk( KERN_INFO "PTP270PEX startup delay: %li.%03li s\n",
- dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
- #elif defined( MBG_TGT_BSD )
- printf( "PTP270PEX startup delay: %li.%03li s\n",
- dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
- #elif defined( MBG_TGT_WIN32 )
- {
- WCHAR wcs_msg[128];
- swprintf( wcs_msg, L"PTP270PEX startup delay: %li.%03li s",
+ mbg_get_sys_time( &t2 );
+
+ dt = mbg_delta_sys_time_ms( &t2, &t1 );
+
+ #if defined( MBG_TGT_LINUX )
+ printk( KERN_INFO "PTP270PEX startup delay: %li.%03li s\n",
+ dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
+ #elif defined( MBG_TGT_BSD )
+ printf( "PTP270PEX startup delay: %li.%03li s\n",
+ dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
+ #elif defined( MBG_TGT_WIN32 )
+ {
+ WCHAR wcs_msg[128];
+ swprintf( wcs_msg, L"PTP270PEX startup delay: %li.%03li s",
dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
- _evt_msg( GlbDriverObject, wcs_msg );
- }
- #endif
+ _evt_msg_w( GlbDriverObject, wcs_msg );
}
- #endif
+ #else
+ (void) dt;
+ #endif
+ }
-} // check_uptime
+} // wait_ptp270pex_ready
static /*HDR*/
-int pcps_check_pex_irq_unsafe( PCPS_DDEV *pddev, uint16_t req_fw_ver,
- uint8_t req_asic_ver_major, uint8_t req_asic_ver_minor )
+/**
+ * @brief Check if IRQ usage with a device is unsafe
+ *
+ * A few early PCI Express cards had a problem where usage
+ * of IRQs was unsafe. Firmware upgrades are available to fix this.
+ * See http://www.meinberg.de/english/info/pex-upgrades.htm
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] req_fw_ver Required firmware version
+ * @param[in] req_asic_ver_major Required ASIC major version
+ * @param[in] req_asic_ver_minor Required ASIC major version
+ *
+ * @return true if IRQ operation is unsafe
+ */
+bool pcps_check_pex_irq_unsafe( PCPS_DDEV *pddev, uint16_t req_fw_ver,
+ uint8_t req_asic_ver_major, uint8_t req_asic_ver_minor )
{
- int rc = !_pcps_pex_irq_is_safe( _pcps_ddev_fw_rev_num( pddev ), req_fw_ver,
+ bool b = !_pcps_pex_irq_is_safe( _pcps_ddev_fw_rev_num( pddev ), req_fw_ver,
_pcps_ddev_asic_version( pddev ),
req_asic_ver_major, req_asic_ver_minor );
- if ( rc )
+ if ( b )
{
pddev->irq_stat_info |= PCPS_IRQ_STAT_UNSAFE;
@@ -618,7 +1048,7 @@ int pcps_check_pex_irq_unsafe( PCPS_DDEV *pddev, uint16_t req_fw_ver,
pddev->irq_ack_mask = 0;
}
- return rc;
+ return b;
} // pcps_check_pex_irq_unsafe
@@ -627,26 +1057,49 @@ int pcps_check_pex_irq_unsafe( PCPS_DDEV *pddev, uint16_t req_fw_ver,
#if MBG_TGT_SUPP_MEM_ACC
static __mbg_inline /*HDR*/
+/**
+ * @brief Check if a virtual address has been mapped for a device
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @return true if virtual address has been mapped
+ */
+bool has_mapped_sys_virtual_address( PCPS_DDEV *pddev )
+{
+ return pddev->mm_addr != NULL;
+
+} // has_mapped_sys_virtual_address
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Map a virtual address for a device
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int map_sys_virtual_address( PCPS_DDEV *pddev )
{
pddev->mm_tstamp_addr = NULL; // unless configured below
- #if defined ( MBG_TGT_WIN32 )
+ #if defined( MBG_TGT_WIN32 )
{
PHYSICAL_ADDRESS pAD;
pAD.QuadPart = pddev->rsrc_info.mem[0].start;
pddev->mm_addr = MmMapIoSpace( pAD, sizeof( *pddev->mm_addr ), MmNonCached );
}
- #elif defined ( MBG_TGT_LINUX )
+ #elif defined( MBG_TGT_LINUX )
pddev->mm_addr = ioremap( ( (ulong) pddev->rsrc_info.mem[0].start ), sizeof( *pddev->mm_addr ) );
- #elif defined ( MBG_TGT_FREEBSD )
+ #elif defined( MBG_TGT_FREEBSD )
pddev->mm_addr = rman_get_virtual( pddev->rsrc_info.mem[0].bsd.res );
- #elif defined ( MBG_TGT_NETBSD )
+ #elif defined( MBG_TGT_NETBSD )
pddev->mm_addr = bus_space_vaddr( pddev->rsrc_info.mem[0].bsd.bst, pddev->rsrc_info.mem[0].bsd.bsh );
@@ -657,7 +1110,11 @@ int map_sys_virtual_address( PCPS_DDEV *pddev )
#endif // target specific code
if ( pddev->mm_addr == NULL )
+ {
+ _mbgddmsg_2( MBG_DBG_ERR, "%s: %s Failed to map virtual address",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ) );
return -1;
+ }
if ( _pcps_ddev_is_pci_mbgpex( pddev ) )
pddev->mm_tstamp_addr = &pddev->mm_addr->mbgpex.tstamp;
@@ -665,24 +1122,32 @@ int map_sys_virtual_address( PCPS_DDEV *pddev )
if ( _pcps_ddev_is_pci_pex8311( pddev ) )
pddev->mm_tstamp_addr = &pddev->mm_addr->pex8311.tstamp;
+#if 0 && defined( DEBUG ) // ### TODO
_mbgddmsg_3( MBG_DBG_INIT_DEV, "MM addr: base: 0x%p, tstamp: 0x%p, offs: 0x%02lX",
pddev->mm_addr, pddev->mm_tstamp_addr,
- (ulong) pddev->mm_tstamp_addr - (ulong) pddev->mm_addr );
+ (ulong) ( (uint8_t *) pddev->mm_tstamp_addr - (uint8_t *) pddev->mm_addr ) );
+#endif
- return 0;
+ return MBG_SUCCESS;
} // map_sys_virtual_address
static __mbg_inline /*HDR*/
+/**
+ * @brief Unmap a virtual address for a device, if it has been mapped before
+ *
+ * @param[in] pddev Pointer to the device structure
+ */
void unmap_sys_virtual_address( PCPS_DDEV *pddev )
{
- if ( pddev->mm_addr )
+
+ if ( has_mapped_sys_virtual_address( pddev ) )
{
- #if defined ( MBG_TGT_WIN32 )
+ #if defined( MBG_TGT_WIN32 )
MmUnmapIoSpace( pddev->mm_addr, sizeof( *pddev->mm_addr ) );
- #elif defined ( MBG_TGT_LINUX )
+ #elif defined( MBG_TGT_LINUX )
iounmap( pddev->mm_addr );
#else // DOS, ...
// nothing to do
@@ -698,13 +1163,221 @@ void unmap_sys_virtual_address( PCPS_DDEV *pddev )
+#if ( DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING )
+
+#if ( 1 && defined( MBG_TGT_LINUX ) && defined( MBG_ARCH_X86 ) )
+ #define DEBUG_PRINT_ACCESS_TIMES 1
+#else
+ #define DEBUG_PRINT_ACCESS_TIMES 0
+#endif
+
+
+#if DEBUG_PRINT_ACCESS_TIMES
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Convert TSC cycles to picoseconds
+ *
+ * @note This has not yet been implemented for all target systems.
+ *
+ * A specific cycles frequency has to be provided by the target OS.
+ *
+ * @param[in] cyc The number of TSC cycles
+ *
+ * @return the computed number of picoseconds
+ */
+long long _cyc_to_ps( long long cyc )
+{
+ cyc *= 1000000000UL;
+
+ #if defined( MBG_TGT_LINUX )
+ // The variable cpu_khz is exported by the kernel, and the
+ // do_div() function needs to be used in kernel space
+ // for the division.
+ do_div( cyc, cpu_khz );
+ #else
+ cyc = 0; //### TODO FIXME for different targets
+ #endif
+
+ return cyc;
+}
+
+#endif // DEBUG_PRINT_ACCESS_TIMES
+
+#endif // ( DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING )
+
+
+
+#if DEBUG_ACCESS_TIMING
+
+static uint32_t debug_dummy_var;
+
+static /*HDR*/
+/**
+ * @brief Report access timing for a device
+ *
+ * This is only used for testing.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] info Informational string to be printed
+ * @param[in] t_after_cmd Cycles value taken after command code has been written
+ * @param[in] t_after_reread Cycles value taken after a data word has been re-read
+ */
+void report_access_timing( const PCPS_DDEV *pddev, const char *info,
+ MBG_PC_CYCLES t_after_cmd, MBG_PC_CYCLES t_after_reread )
+{
+ #if defined( MBG_TGT_LINUX )
+ long long delta_cyc_write = t_after_cmd - pddev->acc_cycles;
+ long long delta_cyc_read = t_after_reread - t_after_cmd;
+
+ #if DEBUG_PRINT_ACCESS_TIMES
+ long long delta_t_write = _cyc_to_ps( delta_cyc_write );
+ long long delta_t_read = _cyc_to_ps( delta_cyc_read );
+ #endif
+
+ printk( KERN_INFO "%s %s: %lli/%lli cyc"
+ #if DEBUG_PRINT_ACCESS_TIMES
+ ", %lli/%lli ps @ %lu kHz"
+ #endif
+ "\n",
+ _pcps_ddev_type_name( pddev ), info,
+ delta_cyc_write, delta_cyc_read
+ #if DEBUG_PRINT_ACCESS_TIMES
+ , delta_t_write, delta_t_read, (ulong) cpu_khz
+ #endif
+ );
+ #endif
+
+} // report_access_timing
+
+#endif // DEBUG_ACCESS_TIMING
+
+
+
+#if DEBUG_IO_TIMING
+
+static /*HDR*/
+/**
+ * @brief Report I/O timing for a device
+ *
+ * This is only used for testing.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] info Informational string to be printed
+ * @param[in] cmd The command by tent to the device
+ * @param[in] count The number of bytes read from the device
+ * @param[in] t_after_cmd Cycles value taken after command code has been written
+ * @param[in] t_after_busy Cycles value taken after busy flag was cleard by the device
+ * @param[in] t_done Cycles value taken after bytes have been read
+ */
+void report_io_timing( const PCPS_DDEV *pddev, const char *info,
+ uint8_t cmd, uint16_t count, MBG_PC_CYCLES t_after_cmd,
+ MBG_PC_CYCLES t_after_busy, MBG_PC_CYCLES t_done )
+{
+ #if defined( MBG_TGT_LINUX ) //##++++ TODO support other OSs
+ long long cmd_cycles = t_after_cmd - pddev->acc_cycles;
+ long long busy_cycles = t_after_busy - t_after_cmd;
+ long long read_cycles = t_done - t_after_busy;
+ long long cycles_per_read = 0;
+
+ #if DEBUG_PRINT_ACCESS_TIMES
+ long long cmd_time = _cyc_to_ps( cmd_cycles );
+ long long busy_time = _cyc_to_ps( busy_cycles );
+ long long read_time = _cyc_to_ps( read_cycles );
+ long long time_per_read = 0;
+ #endif
+
+ if ( count )
+ {
+ cycles_per_read = read_cycles;
+ do_div( cycles_per_read, count );
+
+ #if DEBUG_PRINT_ACCESS_TIMES
+ time_per_read = read_time;
+ do_div( time_per_read, count );
+ #endif
+ }
+
+ printk( KERN_INFO "%s %s cmd: 0x%02X (%u bytes), "
+ "write %lli cyc, busy: %lli cyc, read: %lli/%lli cyc"
+ #if DEBUG_PRINT_ACCESS_TIMES
+ ",\n write %lli ps, busy: %lli ps, read: %lli/%lli ps @ %lu kHz"
+ #endif
+ "\n",
+ _pcps_ddev_type_name( pddev ), info, cmd, count,
+ cmd_cycles, busy_cycles, read_cycles, cycles_per_read
+ #if DEBUG_PRINT_ACCESS_TIMES
+ , cmd_time, busy_time, read_time, time_per_read, (ulong) cpu_khz
+ #endif
+ );
+ printk( KERN_ERR "cycles after cmd: %lli, after busy: %lli, when done: %lli\n",
+ (long long) t_after_cmd,
+ (long long) t_after_busy,
+ (long long) t_done );
+
+ #endif
+
+} // report_io_timing
+
+#endif // DEBUG_IO_TIMING
+
+
+
+#if DEBUG_USB_IO
+
+// This is the prototype of the standard usb_bulk_msg() prototype
+// provided by the Linux kernel. We include it here to make sure
+// our debug wrapper function usb_bulk_msg_dbg() has the same
+// prototype, otherwise we'd expect a compiler warning.
+
+int usb_bulk_msg( struct usb_device *usb_dev,
+ unsigned int pipe,
+ void *data,
+ int len,
+ int *actual_length,
+ int timeout );
+
+
+ /*HDR*/ //### TODO Do we need a prototype?
+int usb_bulk_msg_dbg( struct usb_device *usb_dev,
+ unsigned int pipe,
+ void *data,
+ int len,
+ int *actual_length,
+ int timeout )
+{
+ int rc = usb_bulk_msg( usb_dev, pipe, data, len, actual_length, timeout );
+
+ _mbgddmsg_6( MBG_DBG_ERR, "usb_bulk_msg: pipe %u, data %p, len %i, actual_len %i, timeout %i: returned %i",
+ pipe, data, len, *actual_length, timeout, rc );
+
+ return rc;
+
+} // usb_bulk_msg_dbg
+
+#endif // DEBUG_USB_IO
+
+
+
#if defined( __GNUC__ )
// Avoid "no previous prototype" with some gcc versions.
__mbg_inline
-int pcps_wait_busy( PCPS_DDEV *pddev ) __attribute__((always_inline));
+int pcps_wait_busy( PCPS_DDEV *pddev );
#endif
__mbg_inline /*HDR*/
+/**
+ * @brief Wait as long as a device is busy, or until timeout
+ *
+ * Used by the @ref pcps_read_fncs to wait after the command byte has been
+ * written until the requested data has been made available by the device.
+ *
+ * @param[in] pddev Pointer to the device structure
+ *
+ * @return ::MBG_SUCCESS on success, or ::MBG_ERR_TIMEOUT
+ *
+ * @see @ref pcps_read_fncs
+ */
int pcps_wait_busy( PCPS_DDEV *pddev )
{
if ( _pcps_ddev_status_busy( pddev ) )
@@ -740,56 +1413,81 @@ int pcps_wait_busy( PCPS_DDEV *pddev )
#endif
}
- return 0;
+ return MBG_SUCCESS;
} // pcps_wait_busy
-/*--------------------------------------------------------------
- * Name: pcps_read_null()
- * pcps_read_std()
- * pcps_read_amcc_s5933()
- * pcps_read_amcc_s5920()
- * pcps_read_asic()
- * pcps_read_usb()
- *
- * Purpose: These functions are used for low level access
- * to Meinberg plug-in devices. The function
- * to be used depends on the clock's bus type and
- * interface chip.
- *
- * Input: pcfg pointer to the clock's configuration
- * cmd the command code for the board
- * count the number of bytes to be read
- *
- * Output: buffer the bytes that could be read
- *
- * Ret value: MBG_SUCCESS no error
- * MBG_ERR_TIMEOUT board is busy for too long
- *-------------------------------------------------------------*/
+/**
+ * @defgroup pcps_read_fncs Device read functions
+ *
+ * These group of functions is used for low level access to Meinberg
+ * bus-level devices. Which of the function is actually to be used
+ * depends on the device's bus type and interface chip and is determined
+ * by the function ::pcps_probe_device which is called at device startup.
+ *
+ * @see ::pcps_read_null
+ * @see ::pcps_read_std
+ * @see ::pcps_read_amcc_s5933
+ * @see ::pcps_read_amcc_s5920
+ * @see ::pcps_read_asic
+ * @see ::pcps_read_usb
+ *
+ * @{ */
-// The dummy read function below is used if a clock is
-// not properly initialized, in order to avoid I/O access
-// on unspecified ports.
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_null( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+static /*HDR*/
+/**
+ * @brief Dummy read function
+ *
+ * Used if a clock is not properly initialized, in order to
+ * avoid I/O access on unspecified ports.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_null( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
+ // avoid compiler warnings
+ (void) pddev;
+ (void) cmd;
+ (void) buffer;
+ (void) count;
return MBG_ERR_TIMEOUT;
} // pcps_read_null
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_null;
+#endif
-// The function below must be used to access a clock with
-// standard ISA or micro channel bus.
-
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_std( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+static /*HDR*/
+/**
+ * @brief Read function for devices with ISA or micro channel bus
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_std( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
uint8_t FAR *p = (uint8_t FAR *) buffer;
PCPS_IO_ADDR_MAPPED port = _pcps_ddev_io_base_mapped( pddev, 0 );
@@ -825,18 +1523,31 @@ short pcps_read_std( PCPS_DDEV *pddev, uint8_t cmd,
return MBG_SUCCESS;
-} // pcps_read_std
+} // pcps_read_std
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_std;
+#endif
#if _PCPS_USE_PCI
-// The function below must be used to access a clock with
-// PCI bus and AMCC S5933 interface chip.
-
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_amcc_s5933( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+static /*HDR*/
+/**
+ * @brief Read function for devices with AMCC S5933 PCI interface chip
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_amcc_s5933( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
uint8_t FAR *p = (uint8_t FAR *) buffer;
PCPS_IO_ADDR_MAPPED port = _pcps_ddev_io_base_mapped( pddev, 0 );
@@ -886,7 +1597,11 @@ short pcps_read_amcc_s5933( PCPS_DDEV *pddev, uint8_t cmd,
return MBG_SUCCESS;
-} /* pcps_read_amcc_s5933 */
+} // pcps_read_amcc_s5933
+
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_amcc_s5933;
+#endif
#endif /* _PCPS_USE_PCI */
@@ -894,12 +1609,22 @@ short pcps_read_amcc_s5933( PCPS_DDEV *pddev, uint8_t cmd,
#if _PCPS_USE_PCI
-// The function below must be used to access a clock with
-// PCI bus and AMCC S5920 interface chip.
-
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_amcc_s5920( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+static /*HDR*/
+/**
+ * @brief Read function for devices with AMCC S5920 PCI interface chip
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_amcc_s5920( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
uint8_t FAR *p = (uint8_t FAR *) buffer;
PCPS_IO_ADDR_MAPPED data_port = _pcps_ddev_io_base_mapped( pddev, 1 );
@@ -977,19 +1702,35 @@ short pcps_read_amcc_s5920( PCPS_DDEV *pddev, uint8_t cmd,
} // pcps_read_amcc_s5920
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_amcc_s5920;
+#endif
+
#endif /* _PCPS_USE_PCI */
#if _PCPS_USE_PCI
-// The function below must be used to access a clock with
-// PCI bus and Meinberg PCI interface ASIC.
-
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_asic( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+static /*HDR*/
+/**
+ * @brief Read function for devices with Meinberg PCI interface ASIC
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see ::pcps_read_asic_mm
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_asic( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
+ short ret_val = MBG_SUCCESS;
uint8_t FAR *p = (uint8_t FAR *) buffer;
PCPS_IO_ADDR_MAPPED data_port;
PCI_ASIC_REG ar;
@@ -997,18 +1738,42 @@ short pcps_read_asic( PCPS_DDEV *pddev, uint8_t cmd,
int dt_quot;
int dt_rem;
_pcps_irq_flags
+ #if DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING
+ MBG_PC_CYCLES t_after_cmd = 0;
+ #endif
+ #if DEBUG_ACCESS_TIMING
+ MBG_PC_CYCLES t_after_reread = 0;
+ #endif
+
+ #if DEBUG_IO_TIMING
+ MBG_PC_CYCLES t_after_busy = 0;
+ MBG_PC_CYCLES t_done = 0;
+ #endif
#if DEBUG_IO
- _mbgddmsg_3( MBG_DBG_INIT_DEV, "pcps_read_asic: cmd: 0x%02X (0x%08X), cnt: %u",
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "pcps_read_asic: cmd: 0x%02X (0x%08X), cnt: %u",
cmd, _cpu_to_mbg32( cmd ), count );
#endif
_pcps_disb_local_irq_save();
+
+ // get current cycles and write the command byte
mbg_get_pc_cycles( &pddev->acc_cycles );
- // write the command byte
_mbg_outp32( pddev, 0, _pcps_ddev_io_base_mapped( pddev, 0 )
+ offsetof( PCI_ASIC, pci_data ), cmd );
+
+ #if DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_cmd );
+ #endif
+
+ #if DEBUG_ACCESS_TIMING
+ debug_dummy_var = _mbg_inp32_to_cpu( pddev, 0, _pcps_ddev_io_base_mapped( pddev, 0 )
+ + offsetof( PCI_ASIC, addon_data ) );
+ mbg_get_pc_cycles( &t_after_reread );
+ #endif
+
+
_pcps_local_irq_restore();
data_port = _pcps_ddev_io_base_mapped( pddev, 0 )
@@ -1018,9 +1783,19 @@ short pcps_read_asic( PCPS_DDEV *pddev, uint8_t cmd,
// wait until BUSY flag goes low or timeout
if ( pcps_wait_busy( pddev ) < 0 )
- return MBG_ERR_TIMEOUT;
+ {
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_busy );
+ #endif
+ ret_val = MBG_ERR_TIMEOUT;
+ goto done;
+ }
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_busy );
+ #endif
+
// no timeout: read bytes from the board's FIFO
// first read full 32 bit words
@@ -1050,21 +1825,190 @@ short pcps_read_asic( PCPS_DDEV *pddev, uint8_t cmd,
}
}
- return MBG_SUCCESS;
+done:
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_done );
+ report_io_timing( pddev, "ASIC", cmd, count, t_after_cmd, t_after_busy, t_done );
+ #endif
+
+ #if DEBUG_ACCESS_TIMING
+ report_access_timing( pddev, "ASIC wr/rd", t_after_cmd, t_after_reread );
+ #endif
+
+ return ret_val;
} // pcps_read_asic
-#endif /* _PCPS_USE_PCI */
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_asic;
+#endif
+#if _PCPS_USE_MM_IO
-#if _PCPS_USE_USB
+static /*HDR*/
+/**
+ * @brief Read function for devices with Meinberg PCI interface ASIC
+ *
+ * Unlike ::pcps_read_asic and most of the other read functions,
+ * this function accesses the memory mapped registers rather than
+ * the I/O ports, so this is significantly faster.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see ::pcps_read_asic
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_asic_mm( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
+{
+ short ret_val = MBG_SUCCESS;
+ uint8_t FAR *p = (uint8_t FAR *) buffer;
+ volatile uint32_t *p_data_reg;
+ PCI_ASIC_REG ar;
+ int i;
+ int dt_quot;
+ int dt_rem;
+ _pcps_irq_flags
+
+ #if DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING
+ MBG_PC_CYCLES t_after_cmd = 0;
+ #endif
+
+ #if DEBUG_ACCESS_TIMING
+ MBG_PC_CYCLES t_after_reread = 0;
+ #endif
+
+ #if DEBUG_IO_TIMING
+ MBG_PC_CYCLES t_after_busy = 0;
+ MBG_PC_CYCLES t_done = 0;
+ #endif
+
+ #if DEBUG_IO
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "pcps_read_asic_mm: cmd: 0x%02X (0x%08X), cnt: %u",
+ cmd, _cpu_to_mbg32( cmd ), count );
+ #endif
+
+ _pcps_disb_local_irq_save();
+
+ // get current cycles and write the command byte
+ #if USE_CMD_PTR
+ {
+ volatile uint32_t *p_cmd_reg = &pddev->mm_addr->mbgpex.asic.pci_data.ul;
+ mbg_get_pc_cycles( &pddev->acc_cycles );
+ *p_cmd_reg = cmd;
+ }
+ #else
+ mbg_get_pc_cycles( &pddev->acc_cycles );
+ pddev->mm_addr->mbgpex.asic.pci_data.ul = cmd;
+ #endif
+
+ #if DEBUG_ACCESS_TIMING || DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_cmd );
+ #endif
+
+ #if DEBUG_ACCESS_TIMING
+ debug_dummy_var = pddev->mm_addr->mbgpex.asic.pci_data.ul;
+ mbg_get_pc_cycles( &t_after_reread );
+ #endif
+
+ _pcps_local_irq_restore();
+
+ p_data_reg = &pddev->mm_addr->mbgpex.asic.addon_data.ul[0];
+ dt_quot = count / 4;
+ dt_rem = count % 4;
+
+ // wait until BUSY flag goes low or timeout
+ if ( pcps_wait_busy( pddev ) < 0 )
+ {
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_busy );
+ #endif
+ ret_val = MBG_ERR_TIMEOUT;
+ goto done;
+ }
+
+
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_after_busy );
+ #endif
+
+ // no timeout: read bytes from the board's FIFO
-// The function below must be used to access a device connected via USB.
+ // first read full 32 bit words
+ for ( i = 0; i < dt_quot; i++ )
+ {
+ ar.ul = *p_data_reg;
+ #if DEBUG_IO
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "pcps_read_asic_mm: %08X", ar.ul );
+ #endif
+ _mbg_put_unaligned( ar.ul, (uint32_t FAR *) p );
+ p += sizeof( ar.ul );
+ p_data_reg++;
+ }
+
+ // then read the remaining bytes, if required
+ if ( dt_rem )
+ {
+ ar.ul = *p_data_reg;
+
+ for ( i = 0; i < dt_rem; i++ )
+ {
+ #if DEBUG_IO
+ #endif
+
+ *p++ = ar.b[i];
+ }
+ }
+
+done:
+ #if DEBUG_IO_TIMING
+ mbg_get_pc_cycles( &t_done );
+ report_io_timing( pddev, "ASIC MM", cmd, count, t_after_cmd, t_after_busy, t_done );
+ #endif
+
+ #if DEBUG_ACCESS_TIMING
+ report_access_timing( pddev, "ASIC MM wr/rd", t_after_cmd, t_after_reread );
+ #endif
+
+ return ret_val;
+
+} // pcps_read_asic_mm
-static /*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
- void FAR *buffer, uint16_t count )
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_asic_mm;
+#endif
+
+#endif // _PCPS_USE_MM_IO
+
+#endif // _PCPS_USE_PCI
+
+
+
+#if _PCPS_USE_USB
+
+static /*HDR*/
+/**
+ * @brief Read function for USB devices
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[out] buffer A buffer to take the bytes to be read
+ * @param[in] count The number of bytes to be read into the buffer
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ *
+ * @ingroup pcps_read_fncs
+ * @see @ref pcps_read_fncs
+ */
+int pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
+ void FAR *buffer, uint16_t count )
{
int actual_count = 0;
short rc;
@@ -1073,19 +2017,44 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
rc = _pcps_usb_write_var( pddev, &cmd );
- if ( ( rc == MBG_SUCCESS ) && ( count && buffer ) )
+ #if DEBUG_USB_IO
+ if ( rc == 0 )
+ _mbgddmsg_4( MBG_DBG_INFO, "%s: %s _pcps_usb_write_var cmd 0x%02X, %i bytes: succeeded",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ), cmd, actual_count );
+ else
+ _mbgddmsg_5( MBG_DBG_ERR, "%s: %s _pcps_usb_write_var cmd 0x%02X, %i bytes: failed with rc %i",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ), cmd, actual_count, rc );
+ #endif // DEBUG_USB_IO
+
+ if ( ( rc == 0 ) && ( count && buffer ) )
{
#if defined( MBG_TGT_WIN32_PNP )
- int temp_fn1 = frame_number_1;
- int temp_fn2 = frame_number_2;
+ #if USE_USB_MICRO_FRAMES
+ int temp_fn1 = micro_frame_number_1 ? micro_frame_number_1 : frame_number_1;
+ int temp_fn2 = micro_frame_number_2 ? micro_frame_number_2 : frame_number_2;
+ #else
+ int temp_fn1 = frame_number_1;
+ int temp_fn2 = frame_number_2;
+ #endif
+
LARGE_INTEGER UsbPreCount = Count1;
LARGE_INTEGER UsbPostCount = Count2;
#endif
rc = _pcps_usb_read( pddev, buffer, count );
+ #if DEBUG_USB_IO
+ if ( rc == 0 )
+ _mbgddmsg_4( MBG_DBG_INFO, "%s: %s _pcps_usb_read after cmd 0x%02X succeeded, bytes read: %i",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ), cmd, actual_count );
+ else
+ _mbgddmsg_5( MBG_DBG_ERR, "%s: %s _pcps_usb_read after cmd 0x%02X failed after with rc %i, bytes read: %i",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ), cmd, rc, actual_count );
+ #endif // DEBUG_USB_IO
+
#if defined( MBG_TGT_WIN32_PNP )
- if ( cmd == PCPS_GIVE_HR_TIME && rc == PCPS_SUCCESS )
+
+ if ( cmd == PCPS_GIVE_HR_TIME && rc == 0 )
{
ULONGLONG usb_latency_cycles;
ULONGLONG cycles_diff;
@@ -1093,6 +2062,7 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
ULONGLONG frame_length_cycles;
int FrameNumberDiff;
+ #if !USE_USB_MICRO_FRAMES
if ( pddev->usb_20_mode )
{
// USB 2.0 microframe timing.
@@ -1101,6 +2071,7 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
usb_latency_cycles = ( (ULONGLONG) PerfFreq.QuadPart ) / 20000UL; // represents 50 us
}
else
+ #endif
{
// USB 1.1 mode with millisecond timing.
// Compensate latency to millisecond frame boundaries.
@@ -1111,12 +2082,20 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
FrameNumberDiff = temp_fn2 - temp_fn1;
cycles_diff = (ULONGLONG) ( UsbPostCount.QuadPart - UsbPreCount.QuadPart );
- frame_length_cycles = (ULONGLONG) ( (ULONGLONG) PerfFreq.QuadPart ) / 1000UL;
+
+ #if USE_USB_MICRO_FRAMES
+ if ( micro_frame_number_1 > 0 || micro_frame_number_2 > 0 )
+ frame_length_cycles = (ULONGLONG) ( (ULONGLONG) PerfFreq.QuadPart ) / 8000UL;
+ else
+ frame_length_cycles = (ULONGLONG) ( (ULONGLONG) PerfFreq.QuadPart ) / 1000UL;
+ #else
+ frame_length_cycles = (ULONGLONG) ( (ULONGLONG) PerfFreq.QuadPart ) / 1000UL;
+ #endif
if ( ( temp_fn1 == 0 ) && ( temp_fn2 == 0 ) )
{
if ( cycles_diff > frame_length_cycles )
- usb_latency_cycles = cycles_diff - frame_length_cycles;
+ usb_latency_cycles = cycles_diff - frame_length_cycles;
else
usb_latency_cycles = frame_length_cycles - cycles_diff;
}
@@ -1126,7 +2105,7 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
#if defined( DEBUG )
swprintf( pddev->wcs_msg, L"FD %d CD %I64u l %I64u fl %I64u", FrameNumberDiff,
cycles_diff, usb_latency_cycles, frame_length_cycles );
- _dbg_evt_msg( GlbDriverObject, pddev->wcs_msg );
+ _dbg_evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#endif
}
@@ -1139,36 +2118,38 @@ short pcps_read_usb( PCPS_DDEV *pddev, uint8_t cmd,
} // pcps_read_usb
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_usb;
#endif
+#endif // _PCPS_USE_USB
+/** @} defgroup group_pcps_read_fnc */
-/*--------------------------------------------------------------
- * Name: pcps_write()
- *
- * Purpose: Write data to a device.
+
+
+/*HDR*/
+/**
+ * @brief Write data to a device
*
- * Input: pddev pointer to the device information
- * cmd the address of buffer holding the
- * date/time/status information
- * read_fnc function to access the board
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[in] buffer A buffer with data to be written according to the cmd code
+ * @param[in] count The number of bytes to be written according to the cmd code
*
- * Output: --
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
*
- * Ret value: MBG_SUCCESS no error
- * MBG_ERR_TIMEOUT board is busy for too long
- * MBG_ERR_NBYTES the number of parameter bytes
- * did not match the number of
- * data bytes expected
- * MBG_ERR_STIME the date, time or status
- * has been invalid
- *-------------------------------------------------------------*/
-
-/*HDR*/ /* PCPS_WRITE_FNC */
-short pcps_write( PCPS_DDEV *pddev, uint8_t cmd,
- const void FAR *buffer, uint16_t count )
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+int pcps_write( PCPS_DDEV *pddev, uint8_t cmd,
+ const void FAR *buffer, uint16_t count )
{
- short rc;
+ int rc;
#if _PCPS_USE_USB
if ( _pcps_ddev_is_usb( pddev ) )
@@ -1262,46 +2243,59 @@ done:
} // pcps_write
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_WRITE_FNC pcps_write;
+#endif
-/*--------------------------------------------------------------
- * Name: pcps_generic_io()
- *
- * Purpose: Write data to and/or read data from a device.
+
+/*HDR*/
+/**
+ * @brief Generic I/O function
*
- * Input: pddev pointer to the device information
- * cmd the address of buffer holding the
- * date/time/status information
- * read_fnc function to access the board
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] type The type of data to be read/written, see @ref PCPS_CMD_CODES
+ * @param[in] in_buff A buffer with data to be written according to the type code
+ * @param[in] in_cnt The number of bytes to be written according to the type code
+ * @param[out] out_buff A buffer with data to be read according to the type code
+ * @param[in] out_cnt The number of bytes to be read according to the type code
*
- * Output: --
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
*
- * Ret value: MBG_SUCCESS no error
- * MBG_ERR_TIMEOUT board is busy for too long
- * MBG_ERR_NBYTES the number of parameter bytes
- * did not match the number of
- * data bytes expected
- * MBG_ERR_STIME the date, time or status
- * has been invalid
- *-------------------------------------------------------------*/
-
-/*HDR*/
-short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
- const void FAR *in_buff, uint8_t in_cnt,
- void FAR *out_buff, uint8_t out_cnt )
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+int pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
+ const void FAR *in_buff, uint8_t in_cnt,
+ void FAR *out_buff, uint8_t out_cnt )
{
const uint8_t FAR *p;
int i;
- short rc;
+ int rc;
uint8_t tmp_byte;
int8_t data_read[PCPS_FIFO_SIZE];
uint8_t bytes_to_read;
+ #if DEBUG_IO
+ #if defined( MBG_TGT_DOS )
+ #define FP_FMT "%Fp"
+ #else
+ #define FP_FMT "%p"
+ #endif
+ _mbgddmsg_5( MBG_DBG_DETAIL, "pcps_generic_io: type 0x%02X, in_buff: " FP_FMT
+ " (%u), out_buf " FP_FMT " (%u)",
+ type, in_buff, in_cnt, out_buff, out_cnt );
+ #endif
+
// Write the command and read one byte which will contain
// the number of data bytes that must follow.
rc = _pcps_read_var( pddev, PCPS_GENERIC_IO, tmp_byte );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
return rc;
@@ -1310,16 +2304,21 @@ short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
return MBG_ERR_NBYTES;
+ #if DEBUG_IO
+ _mbgddmsg_3( MBG_DBG_DETAIL, "pcps_generic_io: going to write type 0x%02X, in_sz %i, out_sz %i",
+ type, in_cnt, out_cnt );
+ #endif
+
// Write the 3 bytes which are expected:
rc = _pcps_write_byte( pddev, type );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto done;
rc = _pcps_write_byte( pddev, in_cnt );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto done;
@@ -1329,11 +2328,15 @@ short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
{
rc = _pcps_write_byte( pddev, out_cnt );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
goto done;
// Write the input parameters
+ #if DEBUG_IO
+ _mbgddmsg_0( MBG_DBG_DETAIL, "pcps_generic_io: going to write input bytes" );
+ #endif
+
p = (const uint8_t FAR *) in_buff;
tmp_byte = in_cnt - 1;
@@ -1341,7 +2344,7 @@ short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
{
rc = _pcps_write_byte( pddev, *p++ );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
goto done;
}
@@ -1358,8 +2361,8 @@ short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type,
// Write the last byte and read the completion code.
rc = _pcps_read( pddev, tmp_byte, data_read, bytes_to_read );
- if ( out_cnt ) //##++ should do some more plausibility checks
- if ( rc == MBG_SUCCESS )
+ if ( out_cnt ) //### TODO should do some more plausibility checks
+ if ( mbg_rc_is_success( rc ) )
{
_fmemcpy( out_buff, &data_read[2], out_cnt );
}
@@ -1368,41 +2371,39 @@ done:
// If an error code has been returned by the I/O function,
// return that code, otherwise return the completion code
// read from the board.
- return ( rc < 0 ) ? rc : data_read[0];
+ return mbg_rc_is_error( rc ) ? rc : data_read[0];
} // pcps_generic_io
-/*--------------------------------------------------------------
- * Name: pcps_read_gps_block()
- *
- * Purpose: Get a block of data from GPS clock device.
- * This is a local function which is called
- * by pcps_read_gps().
+static /*HDR*/
+/**
+ * @brief Get a block of data from a GPS device
*
- * Input: pddev pointer to the device information
- * data_type the code assigned to the data type
- * buffer_size the size of the buffer
- * block_num the number of the block to read
- * block_size the size of the block to read
+ * This static function is used by ::pcps_read_gps.
*
- * Output: buffer filled with data
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] data_type The code assigned to the dadta type, see @ref PC_GPS_CMD_CODES
+ * @param[out] buffer A buffer with data to be read according to the data_type
+ * @param[in] buffer_size The number of bytes to be read according to the data_type
+ * @param[in] block_num A buffer with data to be written according to the type code
+ * @param[in] block_size The number of bytes to be written according to the type code
*
- * Ret value: MBG_SUCCESS
- * MBG_ERR_TIMEOUT
- * MBG_ERR_NBYTES
- *-------------------------------------------------------------*/
-
-static /*HDR*/
-short pcps_read_gps_block( PCPS_DDEV *pddev,
- uint8_t data_type,
- void FAR *buffer,
- uint16_t buffer_size,
- uint8_t block_num,
- uint8_t block_size )
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
+ */
+int pcps_read_gps_block( PCPS_DDEV *pddev,
+ uint8_t data_type,
+ void FAR *buffer,
+ uint16_t buffer_size,
+ uint8_t block_num,
+ uint8_t block_size )
{
- short rc;
+ int rc;
uint16_t n_bytes;
uint8_t size_n_bytes;
uint8_t uc;
@@ -1429,7 +2430,7 @@ short pcps_read_gps_block( PCPS_DDEV *pddev,
// Write the command, expect to read one byte.
rc = _pcps_read_var( pddev, PCPS_READ_GPS_DATA, uc );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) )
return rc;
if ( uc != 1 ) // The board doesn't expect exactly one more byte
@@ -1459,17 +2460,17 @@ short pcps_read_gps_block( PCPS_DDEV *pddev,
n_bytes = 0;
rc = _pcps_read( pddev, data_type, &n_bytes, size_n_bytes );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) ) // Error ...
return rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
- // Swap n_bytes regardless of whether we have actuall read 1 or 2 bytes.
- // If we have read only 1 byte then the other one is 0.
- n_bytes = _mbg16_to_cpu( n_bytes );
+ // Swap n_bytes regardless of whether we have actually read 1 or 2 bytes.
+ // If we have read only 1 byte then the other one is 0 anyway.
+ n_bytes = _mbg16_to_cpu( n_bytes );
#endif
#if DEBUG_IO
- _mbgddmsg_2( MBG_DBG_DETAIL, "pcps_read_gps_block: board expects data size %u, buffer size %u",
+ _mbgddmsg_2( MBG_DBG_DETAIL, "pcps_read_gps_block: device expects data size %u, buffer size %u",
n_bytes, buffer_size );
#endif
@@ -1489,37 +2490,45 @@ short pcps_read_gps_block( PCPS_DDEV *pddev,
-/*--------------------------------------------------------------
- * Name: pcps_read_gps()
+/*HDR*/
+/**
+ * @brief Read a large data structure from a device
*
- * Purpose: Get a data structure from a GPS clock.
+ * Read data structures which exceed ::PCPS_FIFO_SIZE bytes.
+ * This can't be handled in a single read cycle, and due to
+ * limitations of the device's microprocessor the execution time
+ * can be up to 20 milliseconds, depending on the device type.
+ * This has been introduced with the first GPS devices but is
+ * now in fact also used with non-GPS devices.
*
- * Input: pddev pointer to the device information
- * data_type the code assigned to the data type
- * buffer_size the size of the buffer
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] data_type The code assigned to the dadta type, see @ref PC_GPS_CMD_CODES
+ * @param[out] buffer A buffer with data to be read according to the data_type
+ * @param[in] buffer_size The number of bytes to be read according to the data_type
*
- * Output: buffer filled with data
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
*
- * Ret value: MBG_SUCCESS
- * MBG_ERR_TIMEOUT
- * MBG_ERR_NBYTES
- *-------------------------------------------------------------*/
-
-/*HDR*/ /* PCPS_READ_FNC */
-short pcps_read_gps( PCPS_DDEV *pddev,
- uint8_t data_type,
- void FAR *buffer,
- uint16_t buffer_size )
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+int pcps_read_gps( PCPS_DDEV *pddev,
+ uint8_t data_type,
+ void FAR *buffer,
+ uint16_t buffer_size )
{
uint8_t FAR *p = (uint8_t FAR *) buffer;
- short rc = 0;
+ int rc = 0;
int dt_quot;
int dt_rem;
int block_num;
#if DEBUG_IO
- _mbgddmsg_3( MBG_DBG_DETAIL, "Going to read GPS data, type: %02X, addr: %p, size: %u",
+ _mbgddmsg_3( MBG_DBG_DETAIL, "Going to read GPS data, type: 0x%02X, addr: %p, size: %u",
data_type, buffer, buffer_size );
#endif
@@ -1534,7 +2543,7 @@ short pcps_read_gps( PCPS_DDEV *pddev,
rc = pcps_read_gps_block( pddev, data_type, p, buffer_size,
(uint8_t) block_num, PCPS_FIFO_SIZE );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) ) // Error ...
goto done;
// Move the destination pointer to the next free byte.
@@ -1556,34 +2565,40 @@ done:
} // pcps_read_gps
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_READ_FNC pcps_read_gps;
+#endif
-/*--------------------------------------------------------------
- * Name: pcps_write_gps()
+
+/*HDR*/
+/**
+ * @brief Write a large data structure to a device
*
- * Purpose: Write a data structure to a GPS clock.
+ * This has been introduced with the first GPS devices but is
+ * now in fact also used with non-GPS devices.
*
- * Input: pddev pointer to the device information
- * data_type the code assigned to the data type
- * buffer the data to write
- * buffer_size the size of the buffer
- * read_fnc function to access the board
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] data_type The code assigned to the dadta type, see @ref PC_GPS_CMD_CODES
+ * @param[in] buffer A buffer with data to be written according to the data_type
+ * @param[in] buffer_size The number of bytes to be written according to the data_type
*
- * Output: --
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
*
- * Ret value: MBG_SUCCESS
- * MBG_ERR_TIMEOUT
- * MBG_ERR_NBYTES
- *-------------------------------------------------------------*/
-
-/*HDR*/ /* PCPS_WRITE_FNC */
-short pcps_write_gps( PCPS_DDEV *pddev,
- uint8_t data_type,
- const void FAR *buffer,
- uint16_t buffer_size )
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+int pcps_write_gps( PCPS_DDEV *pddev,
+ uint8_t data_type,
+ const void FAR *buffer,
+ uint16_t buffer_size )
{
const uint8_t FAR *p = (const uint8_t FAR *) buffer;
- short rc;
+ int rc;
short i;
uint16_t n_bytes;
uint8_t size_n_bytes;
@@ -1609,7 +2624,7 @@ short pcps_write_gps( PCPS_DDEV *pddev,
// Write the command, expect to read one byte.
rc = _pcps_read_var( pddev, PCPS_WRITE_GPS_DATA, uc );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) ) // Error ...
return rc;
if ( uc != 1 ) // The board doesn't expect exactly one more byte
@@ -1639,7 +2654,7 @@ short pcps_write_gps( PCPS_DDEV *pddev,
n_bytes = 0;
rc = _pcps_read( pddev, data_type, &n_bytes, size_n_bytes );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) ) // Error ...
return rc;
#if defined( MBG_ARCH_BIG_ENDIAN )
@@ -1649,12 +2664,12 @@ short pcps_write_gps( PCPS_DDEV *pddev,
#endif
#if DEBUG_IO
- _mbgddmsg_2( MBG_DBG_DETAIL, "pcps_write_gps: board expects data size %u, buffer size %u",
+ _mbgddmsg_2( MBG_DBG_DETAIL, "pcps_write_gps: device expects data size %u, buffer size is %u",
n_bytes, buffer_size );
#endif
if ( n_bytes != buffer_size ) // The board doesn't expect the number
- return MBG_ERR_NBYTES; // of bytes we were going to write.
+ return MBG_ERR_NBYTES; // of bytes we were going to write.
// Write all bytes but the last one without reading.
@@ -1664,7 +2679,7 @@ short pcps_write_gps( PCPS_DDEV *pddev,
{
rc = _pcps_write_byte( pddev, *p++ );
- if ( rc != MBG_SUCCESS ) // Error ...
+ if ( mbg_rc_is_error( rc ) ) // Error ...
return rc;
}
@@ -1678,71 +2693,65 @@ short pcps_write_gps( PCPS_DDEV *pddev,
} // pcps_write_gps
+#if !defined( AVOID_REDUNDANT_REDECLARATION )
+ PCPS_WRITE_FNC pcps_write_gps;
+#endif
-/*--------------------------------------------------------------
- * Name: pcps_get_fw_id()
- *
- * Purpose: This function tries to read the firmware ID
- * from the board. It should be used to check
- * if the board is properly installed and can
- * be accessed without problems.
+
+static /*HDR*/
+/**
+ * @brief Read the firmware ID from a device
*
- * Input: pddev pointer to the device information
+ * This is usually done first when probing a device to check if the
+ * device is properly installed and can be accessed without problems.
*
- * Output: fw_id buffer filled with ASCIIZ string
+ * @param[in] pddev Pointer to a device structure
+ * @param[out] fw_id A buffer to be filled withtthe firmware ID
*
- * Ret value: MBG_SUCCESS no error
- * MBG_ERR_TIMEOUT the board is busy for too long
- *-------------------------------------------------------------*/
-
-/*HDR*/
-short pcps_get_fw_id( PCPS_DDEV *pddev, PCPS_ID_STR FAR fw_id )
+ * @return ::MBG_SUCCESS if the the signature was found, or signature was specified, or
+ * ::MBG_ERR_FW_ID if the firmware ID is unknown or invalid
+ */
+int pcps_get_fw_id( PCPS_DDEV *pddev, PCPS_ID_STR FAR fw_id )
{
- short rc;
+ int rc;
+ memset( fw_id, 0, sizeof( PCPS_ID_STR ) ); // sizeof( fw_id ) would yield pointer size only
- // read first part of the firmware ID
+ // read the first part of the firmware ID
rc = _pcps_read( pddev, PCPS_GIVE_FW_ID_1, &fw_id[0], PCPS_FIFO_SIZE );
- if ( rc != MBG_SUCCESS )
- return rc; // may be timeout
+ if ( mbg_rc_is_error( rc ) )
+ goto out;
-
- // read second part of the firmware ID
+ // read the second part of the firmware ID
rc = _pcps_read( pddev, PCPS_GIVE_FW_ID_2, &fw_id[PCPS_FIFO_SIZE], PCPS_FIFO_SIZE );
- if ( rc != MBG_SUCCESS )
- return rc; // may be timeout
-
-
- // terminate the string with 0
-
+ // force termination with 0
fw_id[PCPS_ID_SIZE - 1] = 0;
-
- return MBG_SUCCESS;
+out:
+ return rc;
} // pcps_get_fw_id
-/*--------------------------------------------------------------
- * Name: pcps_check_id()
- *
- * Purpose: Check an ASCIIZ string for a valid signature.
+static /*HDR*/
+/**
+ * @brief Check an ASCIIZ string for a valid signature.
*
- * Input: pddev pointer to the device information
- * ref the reference signature
+ * This function is only used to determine the type of a legacy ISA card.
+ * For PCI and USB devices the type can be determined from the device ID.
*
- * Output: --
+ * @param[in] pddev Pointer to a device structure
+ * @param[in] ref The reference signature, i.e. the expected signature
+ * at the beginning of the device's firmware ID
*
- * Ret value: MBG_SUCCESS no error
- * MBG_ERR_FW_ID the firmware ID is not valid
- *-------------------------------------------------------------*/
-
-/*HDR*/
-short pcps_check_id( PCPS_DDEV *pddev, const char FAR *ref )
+ * @return ::MBG_SUCCESS if a signature was specified and the signature was found, or
+ * ::MBG_ERR_FW_ID if the firmware ID is unknown or invalid
+ */
+int pcps_check_id( PCPS_DDEV *pddev, const char FAR *ref )
{
// check if the first characters of the string match the reference
@@ -1756,38 +2765,36 @@ short pcps_check_id( PCPS_DDEV *pddev, const char FAR *ref )
-/*--------------------------------------------------------------
- * Name: pcps_get_rev_num()
- *
- * Purpose: Get a version number from an ID string.
- *
- * Input: idstr the ID string
+static /*HDR*/
+/**
+ * @brief Retrieve a version number from a firmware ID string
*
- * Output: --
+ * @param[in] idstr The ID string, e.g. a ::PCPS_ID_STR
*
- * Ret value: on success: the version number in hex
- * (e.g. 0x0270 for version 2.7)
- * on error: 0
- *-------------------------------------------------------------*/
-
-/*HDR*/
-short pcps_get_rev_num( char FAR *idstr )
+ * @return A version number in hex format, e.g. 0x0270 for version 2.7,
+ * or 0 if no version number could be found.
+ */
+PCPS_FW_REV_NUM pcps_get_rev_num( char FAR *idstr )
{
+ int len = _fstrlen( idstr );
int i;
- int len = _fstrlen( idstr ) - 2;
- char c;
- uchar rev_num_hi;
- uchar rev_num_lo;
+ if ( len < 2 )
+ goto no_rev_num;
+
+ len -= 2;
for ( i = 0; i < len; i++ )
{
if ( idstr[i + 1] == '.' )
{
- rev_num_hi = idstr[i] & 0x0F;
- rev_num_lo = ( idstr[i + 2] & 0x0F ) << 4;
+ uint8_t rev_num_hi = idstr[i] & 0x0F;
+ uint8_t rev_num_lo = ( idstr[i + 2] & 0x0F ) << 4;
+
+ // If the minor part of the version string has 2 digits
+ // then evaluate the 2nd digit, too.
- c = idstr[i + 3];
+ char c = idstr[i + 3];
if ( c >= '0' && c <= '9' )
rev_num_lo |= c & 0x0F;
@@ -1796,27 +2803,24 @@ short pcps_get_rev_num( char FAR *idstr )
}
}
+no_rev_num:
return 0;
} // pcps_get_rev_num
-/*--------------------------------------------------------------
- * Name: pcps_read_sernum()
- *
- * Purpose: This function tries to read the clock's S/N
- * from the board, if supported by the clock.
+/*HDR*/
+/**
+ * @brief Read the serial number from a device, if supported
*
- * Input: pddev pointer to the device information
+ * If the serial number could be read successfully then it is
+ * stored in one of the sub-structures of pddev.
*
- * Output: pddev sernum field filled with ASCIIZ
+ * @param[in,out] pddev Pointer to a device structure
*
- * Ret value: MBG_SUCCESS no error
- * other error
- *-------------------------------------------------------------*/
-
-/*HDR*/
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_read_sernum( PCPS_DDEV *pddev )
{
char *cp;
@@ -1826,48 +2830,62 @@ int pcps_read_sernum( PCPS_DDEV *pddev )
memset( pddev->dev.cfg.sernum, 0, sizeof( pddev->dev.cfg.sernum ) );
- // There are different ways to read the clock's S/N.
- // Check which way is supported by the clock, and
- // read the S/N.
-
+ // There are different ways to read the clock's S/N. Check which
+ // way is supported, and read the S/N from the device.
+ //
+ // Never just return a previous copy of the serial number which
+ // has been read earlier since the S/N may just have been set
+ // by a configuration API call.
- // The S/N is part of the RECEIVER_INFO structure. If this
- // structure is supported by the device then it should have
- // already been set up, so we can simply copy the serial number.
- if ( _pcps_ddev_has_receiver_info( pddev ) )
+ // Read directly. This is supported by newer devices.
+ if ( _pcps_ddev_has_sernum( pddev ) )
{
#if DEBUG_SERNUM
- _mbgddmsg_0( MBG_DBG_DETAIL, "copying S/N from receiver info" );
+ _mbgddmsg_0( MBG_DBG_DETAIL, "getting S/N via PCPS_GIVE_SERNUM cmd" );
#endif
- strncpy( pddev->dev.cfg.sernum, pddev->ri.sernum,
- sizeof( pddev->dev.cfg.sernum ) );
+ rc = _pcps_read( pddev, PCPS_GIVE_SERNUM, pddev->dev.cfg.sernum, PCPS_FIFO_SIZE );
+
+ if ( mbg_rc_is_error( rc ) )
+ {
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "PCPS read SERNUM %X: rc = %i",
+ _pcps_ddev_dev_id( pddev ), rc );
+ goto fail;
+ }
+
goto check;
}
- // Read directly. This is supported by newer DCF77 clocks.
- if ( _pcps_ddev_has_sernum( pddev ) )
+ // The S/N is part of the RECEIVER_INFO structure,
+ // so use that one, if supported.
+ if ( _pcps_ddev_has_receiver_info( pddev ) )
{
+ RECEIVER_INFO *p_ri = _ri_addr( pddev );
+
#if DEBUG_SERNUM
- _mbgddmsg_0( MBG_DBG_DETAIL, "getting S/N via PCPS_GIVE_SERNUM cmd" );
+ _mbgddmsg_0( MBG_DBG_DETAIL, "getting S/N from receiver info" );
#endif
- rc = _pcps_read( pddev, PCPS_GIVE_SERNUM, pddev->dev.cfg.sernum, PCPS_FIFO_SIZE );
+ rc = _pcps_read_gps_var( pddev, PC_GPS_RECEIVER_INFO, *p_ri );
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
{
- _mbgddmsg_2( MBG_DBG_INIT_DEV, "PCPS read SERNUM %X: rc = %i",
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "PCPS read GPS receiver info %X: rc = %i",
_pcps_ddev_dev_id( pddev ), rc );
goto fail;
}
+ _mbg_swab_receiver_info( p_ri );
+
+ strncpy( pddev->dev.cfg.sernum, p_ri->sernum,
+ sizeof( pddev->dev.cfg.sernum ) );
goto check;
}
// Older GPS clocks store the S/N in an IDENT structure
- // which must be decoded to get the S/N.
+ // which needs to be decoded to get the S/N.
if ( _pcps_ddev_has_ident( pddev ) )
{
static_wc IDENT ident = { { 0 } };
@@ -1882,7 +2900,7 @@ int pcps_read_sernum( PCPS_DDEV *pddev )
assert( sizeof( ident ) < sizeof( pddev->dev.cfg.sernum ) );
#endif
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
{
_mbgddmsg_2( MBG_DBG_INIT_DEV, "PCPS read GPS ident %X: rc = %i",
_pcps_ddev_dev_id( pddev ), rc );
@@ -1899,6 +2917,26 @@ int pcps_read_sernum( PCPS_DDEV *pddev )
#endif
mbg_gps_ident_decode( _pcps_ddev_sernum( pddev ), &ident );
+
+ #if DEBUG_SERNUM
+ _mbgddmsg_1( MBG_DBG_DETAIL, "S/N decoded from ident: %s (raw)",
+ _pcps_ddev_sernum( pddev ) );
+ #endif
+
+ // Some old devices may have non-digits appended
+ // to the S/N string. Truncate such a string.
+ for ( cp = _pcps_ddev_sernum( pddev ); *cp; cp++ )
+ if ( ( *cp < '0' ) || ( *cp > '9' ) )
+ {
+ *cp = 0;
+ break;
+ }
+
+ #if DEBUG_SERNUM
+ _mbgddmsg_1( MBG_DBG_DETAIL, "S/N decoded from ident: %s",
+ _pcps_ddev_sernum( pddev ) );
+ #endif
+
goto check;
}
@@ -1948,7 +2986,7 @@ fail:
fail:
// No valid serial number has been found, though the device
- // should have one. In order to distinguish from devices which
+ // should have one. In order to distinguish from devices which
// don't even support a serial number we return a number of '?'
// rather than "N/A".
memset( pddev->dev.cfg.sernum, '?', 8 );
@@ -1967,7 +3005,14 @@ done:
#if _PCPS_USE_RSRCMGR
-/*HDR*/
+static /*HDR*/
+/**
+ * @brief Try to claim an I/O port resource range
+ *
+ * @param[in,out] pddev The device structure
+ *
+ * @return ::MBG_SUCCESS if the port range could be claimed, else ::MBG_ERR_CLAIM_RSRC
+ */
int pcps_rsrc_claim( PCPS_DDEV *pddev )
{
ushort decode_width;
@@ -1986,38 +3031,40 @@ int pcps_rsrc_claim( PCPS_DDEV *pddev )
PCPS_IO_RSRC *p = &_pcps_ddev_io_rsrc( pddev, i );
ushort rc;
- rc = _rsrc_alloc_ports( &pddev->rsrc, p->base_raw, p->num, decode_width ); //##++
+ rc = _rsrc_alloc_ports( pddev, p->base_raw, p->num, decode_width );
// If the resource manager was unable to alloc the resources
// then the selected range of ports is probably in use
// by another hardware device and/or driver
- if ( rc )
+ if ( mbg_rc_is_error( rc ) )
{
_pcps_ddev_set_err_flags( pddev, PCPS_EF_IO_RSRC );
return MBG_ERR_CLAIM_RSRC;
}
}
- return 0;
+ return MBG_SUCCESS;
} // pcps_rsrc_claim
/*HDR*/
+/**
+ * @brief Release an I/O port resource range that has been claimed before
+ *
+ * @param[in,out] pddev The device structure
+ */
void pcps_rsrc_release( PCPS_DDEV *pddev )
{
int i;
- for ( i = 0; i < N_PCPS_PORT_RSRC; i++ )
+ for ( i = 0; i < pddev->rsrc_info.num_rsrc_io; i++ )
{
- PCPS_PORT_RSRC *p = &_pcps_ddev_port_rsrc( pddev, i );
-
- if ( _pcps_port_rsrc_unused( p ) )
- continue;
+ PCPS_IO_RSRC *p = &_pcps_ddev_io_rsrc( pddev, i );
- // clean up if clock not found
- _rsrc_dealloc_ports( &pddev->rsrc.hResource[i], p->base, p->num );
+ if ( p->base_raw )
+ _rsrc_dealloc_ports( pddev, p->base_raw, p->num );
}
} // pcps_rsrc_release
@@ -2027,6 +3074,11 @@ void pcps_rsrc_release( PCPS_DDEV *pddev )
#if defined( MBG_TGT_OS2 )
static /*HDR*/
+/**
+ * @brief Register a device under OS/2
+ *
+ * @param[in] pddev The device structure
+ */
void pcps_rsrc_register_device( PCPS_DDEV *pddev )
{
#define RSRC_BASE_NAME "RADIOCLK_# Meinberg Radio Clock "
@@ -2091,14 +3143,17 @@ void pcps_rsrc_register_device( PCPS_DDEV *pddev )
*
*-------------------------------------------------------------*/
-/*--------------------------------------------------------------
- * Convert the code read from PS/2 POS to the port base address.
- *-------------------------------------------------------------*/
-
-/*HDR*/
-ushort pcps_port_from_pos( ushort pos )
+static /*HDR*/
+/**
+ * @brief Convert the code read from PS/2 POS to the port base address
+ *
+ * @param[in] pos The POS code to be converted
+ *
+ * @return The decoded I/O port base address
+ */
+uint16_t pcps_port_from_pos( uint16_t pos )
{
- ushort us = ( ( pos & 0x007E ) << 8 ) | 0x0100;
+ uint16_t us = ( ( pos & 0x007E ) << 8 ) | 0x0100;
if ( pos & 0x0001 )
us |= 0x0010;
@@ -2109,14 +3164,17 @@ ushort pcps_port_from_pos( ushort pos )
-/*--------------------------------------------------------------
- * Convert the port base address to a PS/2 POS code.
- *-------------------------------------------------------------*/
-
-/*HDR*/
-uchar pcps_pos_from_port( ushort port )
+static /*HDR*/
+/**
+ * @brief Convert the port base address to a PS/2 POS code
+ *
+ * @param[in] port The I/O port base address to be encoded
+ *
+ * @return The encoded POS code
+ */
+uint8_t pcps_pos_from_port( uint16_t port )
{
- uchar uc;
+ uint8_t uc;
uc = *( ( (uchar *) (&port) ) + 1 ) & 0x7E;
@@ -2131,7 +3189,12 @@ uchar pcps_pos_from_port( ushort port )
static /*HDR*/
-void pcps_detect_mca_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg )
+/**
+ * @brief Detect MCA devices and allocate device info structures
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ */
+void pcps_detect_mca_devices( PCPS_DDEV_ALLOC_FNC *alloc_fnc )
{
short rc;
ushort type_idx;
@@ -2164,7 +3227,7 @@ void pcps_detect_mca_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg )
// New device found, try to add to list.
- pddev = alloc_fnc( alloc_arg );
+ pddev = alloc_fnc();
if ( pddev ) // Setup only if successful.
{
@@ -2175,24 +3238,33 @@ void pcps_detect_mca_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg )
//##++ Should try to read the interrupt line assigned to the clock.
// The standard functions, however, don't use any interrupt.
- pcps_start_device( pddev, 0, slot_num );
+ pcps_probe_device( pddev, 0, slot_num );
}
}
mca_fnc_deinit();
-} // pcps_detect_mca_clocks
+} // pcps_detect_mca_devices
#endif /* _PCPS_USE_MCA */
-// The function below takes a bus flag and device ID to search
-// the table of known devices for a device which matches the
-// given criteria.
-
/*HDR*/
-PCPS_DEV_TYPE *pcps_get_dev_type( int bus_mask, ushort dev_id )
+/**
+ * @brief Lookup a specific device in the device table
+ *
+ * The function below takes a bus flag and device ID to search
+ * the table of known devices for a device which matches the
+ * given criteria.
+ *
+ * @param[in] bus_mask Mask of the bus type to look up, see @ref PCPS_BUS_FLAG_MASKS
+ * @param[in] dev_id The device ID to lookup, see @ref MEINBERG_PCI_DEVICE_IDS
+ * or @ref MBG_USB_DEVICE_IDS, depending on the bus_mask
+ *
+ * @return A pointer to the device table entry, or NULL if no entry found
+ */
+PCPS_DEV_TYPE *pcps_get_dev_type_table_entry( PCPS_BUS_FLAGS bus_mask, PCPS_DEV_ID dev_id )
{
int i;
@@ -2209,11 +3281,16 @@ PCPS_DEV_TYPE *pcps_get_dev_type( int bus_mask, ushort dev_id )
return NULL;
-} // pcps_get_dev_type
+} // pcps_get_dev_type_table_entry
/*HDR*/
+/**
+ * @brief Allocate a device info structure for a device
+ *
+ * @return A pointer to the allocated structure, or NULL if failed
+ */
PCPS_DDEV *pcps_alloc_ddev( void )
{
PCPS_DDEV *pddev;
@@ -2221,7 +3298,7 @@ PCPS_DDEV *pcps_alloc_ddev( void )
#if !_PCPS_STATIC_DEV_LIST
pddev = _pcps_kmalloc( sizeof( *pddev ) );
#else
- if ( n_ddevs >= PCPS_MAX_DDEVS )
+ if ( n_ddevs >= N_SUPP_DEV_BUS )
{
_mbgddmsg_0( MBG_DBG_INIT_DEV,
"Unable to add new device: max count reached" );
@@ -2260,6 +3337,11 @@ PCPS_DDEV *pcps_alloc_ddev( void )
/*HDR*/
+/**
+ * @brief Free a previously allocated device info structure
+ *
+ * @param[in] pddev Pointer to the device structure to be freed
+ */
void pcps_free_ddev( PCPS_DDEV *pddev )
{
if ( pddev )
@@ -2287,16 +3369,33 @@ void pcps_free_ddev( PCPS_DDEV *pddev )
static /*HDR*/
-void rsrc_port_to_cfg_port( PCPS_PORT_RSRC *p_port_rsrc, const PCPS_IO_RSRC *p_io_rsrc )
+/**
+ * @brief Convert a raw I/O base address to a short format
+ *
+ * See notes for ::PCPS_SHORT_PORT_RSRC.
+
+ * @param[out] p_short_port_rsrc Pointer to a variable that takes up the converted address
+ * @param[in] p_io_rsrc Pointer to a variable with the address to be converted
+ */
+void rsrc_port_to_cfg_port( PCPS_SHORT_PORT_RSRC *p_short_port_rsrc, const PCPS_IO_RSRC *p_io_rsrc )
{
- p_port_rsrc->base = (PCPS_PORT_ADDR) p_io_rsrc->base_raw;
- p_port_rsrc->num = p_io_rsrc->num;
+ p_short_port_rsrc->base = (PCPS_SHORT_PORT_ADDR) p_io_rsrc->base_raw;
+ p_short_port_rsrc->num = (uint16_t) p_io_rsrc->num;
} // rsrc_port_to_cfg_port
/*HDR*/
+/**
+ * @brief Add an I/O address range resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] base Base address of the I/O address range
+ * @param[in] num Number of addresses of the I/O address range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_io( PCPS_DDEV *pddev, ulong base, ulong num )
{
PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info;
@@ -2307,7 +3406,7 @@ int pcps_add_rsrc_io( PCPS_DDEV *pddev, ulong base, ulong num )
p->base_mapped = (PCPS_IO_ADDR_MAPPED) _pcps_ioremap( base, num );
p->base_raw = (PCPS_IO_ADDR_RAW) base;
- p->num = (uint16_t) num;
+ p->num = num;
prsrci->num_rsrc_io++;
@@ -2324,6 +3423,15 @@ int pcps_add_rsrc_io( PCPS_DDEV *pddev, ulong base, ulong num )
/*HDR*/
+/**
+ * @brief Add a memory address range resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] start Start address of the memory range
+ * @param[in] len Size of the memory range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_mem( PCPS_DDEV *pddev, MBG_MEM_ADDR start, ulong len )
{
PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info;
@@ -2335,7 +3443,7 @@ int pcps_add_rsrc_mem( PCPS_DDEV *pddev, MBG_MEM_ADDR start, ulong len )
p->len = len;
prsrci->num_rsrc_mem++;
- #if defined( MBG_TGT_UNIX )
+ #if defined( MBG_TGT_POSIX )
_mbgddmsg_3( MBG_DBG_INIT_DEV, "Adding mem rsrc #%i: %08llX(%lu)",
prsrci->num_rsrc_mem, (unsigned long long) start, len );
#else
@@ -2353,6 +3461,14 @@ int pcps_add_rsrc_mem( PCPS_DDEV *pddev, MBG_MEM_ADDR start, ulong len )
/*HDR*/
+/**
+ * @brief Add an IRQ number resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] irq_num Start address of the memory range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_irq( PCPS_DDEV *pddev, int16_t irq_num )
{
PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info;
@@ -2377,10 +3493,20 @@ int pcps_add_rsrc_irq( PCPS_DDEV *pddev, int16_t irq_num )
#if _PCPS_USE_PNP
/*HDR*/
-int pcps_init_ddev( PCPS_DDEV *pddev, int bus_flags, ushort dev_id )
+/**
+ * @brief Initialize an allocated device structure for a specific device
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] bus_mask Mask of the bus type to look up, see @ref PCPS_BUS_FLAG_MASKS
+ * @param[in] dev_id The device ID to lookup, see @ref MEINBERG_PCI_DEVICE_IDS
+ * or @ref MBG_USB_DEVICE_IDS, depending on the bus_mask
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int pcps_init_ddev( PCPS_DDEV *pddev, PCPS_BUS_FLAGS bus_mask, PCPS_DEV_ID dev_id )
{
// First check if we really support the device to be added.
- PCPS_DEV_TYPE *pdt = pcps_get_dev_type( bus_flags, dev_id );
+ PCPS_DEV_TYPE *pdt = pcps_get_dev_type_table_entry( bus_mask, dev_id );
if ( pdt == NULL )
{
@@ -2405,39 +3531,59 @@ int pcps_init_ddev( PCPS_DDEV *pddev, int bus_flags, ushort dev_id )
#if defined( DEBUG )
+
static /*HDR*/
-const char *get_feature_name( PCPS_FEATURES flag )
+/**
+ * @brief Get the name assigned to one of the @ref PCPS_FEATURE_MASKS flags
+ *
+ * @param[in] flag_mask one of the @ref PCPS_FEATURE_MASKS flags
+ *
+ * @return The associated feature name, or "unknown"
+ *
+ * @see @ref PCPS_FEATURE_MASKS
+ */
+const char *get_pcps_feature_name( PCPS_FEATURES flag_mask )
{
- static const char *pcps_feature_names[N_PCPS_FEATURE] = PCPS_FEATURE_NAMES;
-
int i;
- for ( i = 0; i < N_PCPS_FEATURE; i++ )
- if ( ( 1UL << i ) == flag )
+ for ( i = 0; i < N_PCPS_FEATURE_BITS; i++ )
+ if ( ( 1UL << i ) == flag_mask )
return pcps_feature_names[i];
return "unknown";
-} // get_feature_name
+} // get_pcps_feature_name
#endif
static /*HDR*/
+/**
+ * @brief Check the firmware to see if a specific feature is supported
+ *
+ * Some devices provide a specific feature only starting with a specific
+ * firmware version, but the device provides no way to test this, so
+ * the feature flag in the device structure is set if the firmware
+ * has the required version.
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] req_rev_num Revision number required for the feature to be supported
+ * @param[in] flag_mask Flag mask of the feature to be tested
+ */
void check_feature( PCPS_DDEV *pddev, ushort req_rev_num,
- PCPS_FEATURES flag )
+ PCPS_FEATURES flag_mask )
{
int supported = _pcps_ddev_fw_rev_num( pddev ) >= req_rev_num;
if ( supported )
- pddev->dev.cfg.features |= flag;
+ pddev->dev.cfg.features |= flag_mask;
#if defined( DEBUG )
_mbgddmsg_5( MBG_DBG_INIT_DEV, "%s v%03X: feature 0x%08lX (%s) %ssupported",
_pcps_ddev_type_name( pddev ),
_pcps_ddev_fw_rev_num( pddev ),
- (ulong) flag, get_feature_name( flag ),
+ (ulong) flag_mask, get_pcps_feature_name( flag_mask ),
supported ? "" : "not " );
#endif
@@ -2446,31 +3592,196 @@ void check_feature( PCPS_DDEV *pddev, ushort req_rev_num,
static /*HDR*/
-void check_ri_feature( PCPS_DDEV *pddev, const RECEIVER_INFO *p_ri,
- RI_FEATURES ri_flag, PCPS_FEATURES flag )
+/**
+ * @brief Check the receiver info features to see if a specific feature is supported
+ *
+ * Some devices provide a ::RECEIVER_INFO which provides some flags that
+ * can be mapped to the feature flags we use internally, so we scan these features
+ * and update the internal features mask accordingly.
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ */
+void check_ri_features( PCPS_DDEV *pddev )
{
- int supported = ( p_ri->features & ri_flag ) != 0;
+ const RECEIVER_INFO *p_ri = _ri_addr( pddev );
+ int gps_feat_bit;
- if ( supported )
- pddev->dev.cfg.features |= flag;
+ for ( gps_feat_bit = 0; gps_feat_bit < N_GPS_FEATURE; gps_feat_bit++ )
+ {
+ int supported = ( p_ri->features & ( 1UL << gps_feat_bit ) ) != 0;
+ PCPS_FEATURES pcps_flags = ri_feat_tbl[gps_feat_bit];
- #if defined( DEBUG )
- _mbgddmsg_5( MBG_DBG_INIT_DEV, "%s v%03X: feature 0x%08lX (%s) %ssupported according to RECEIVER_INFO",
- _pcps_ddev_type_name( pddev ),
- _pcps_ddev_fw_rev_num( pddev ),
- (ulong) flag, get_feature_name( flag ),
- supported ? "" : "not " );
- #endif
+ if ( supported )
+ {
+ if ( pcps_flags )
+ {
+ pddev->dev.cfg.features |= pcps_flags;
+
+ #if defined( DEBUG )
+ {
+ int i;
+
+ for ( i = 0; i < 8 * sizeof( pcps_flags ); i++ )
+ if ( pcps_flags & ( 1UL << i ) )
+ _mbgddmsg_4( MBG_DBG_INIT_DEV, "%s v%03X: Supported RI feature \"%s\" maps to PCPS feature %s",
+ _pcps_ddev_type_name( pddev ),
+ _pcps_ddev_fw_rev_num( pddev ),
+ gps_ri_feature_names[gps_feat_bit],
+ pcps_feature_names[i] );
+ }
+ #endif
+ }
+ else
+ {
+ #if defined( DEBUG )
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s v%03X: RI feature \"%s\" supported, but no corresponding PCPS feature",
+ _pcps_ddev_type_name( pddev ),
+ _pcps_ddev_fw_rev_num( pddev ),
+ gps_ri_feature_names[gps_feat_bit] );
+ #endif
+ }
+ }
+ else
+ {
+ #if defined( DEBUG )
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s v%03X: RI feature \"%s\" not supported by device",
+ _pcps_ddev_type_name( pddev ),
+ _pcps_ddev_fw_rev_num( pddev ),
+ gps_ri_feature_names[gps_feat_bit] );
+ #endif
+ }
+ }
+
+} // check_ri_features
+
+
+
+/*HDR*/
+/**
+ * @brief Check if a specific feature of a specific feature type is supported
+ *
+ * There are different structures where information can be stored
+ * if a specific feature is supported. All information is set up
+ * when the ::pcps_probe_device function is called to probe and
+ * initialize the device.
+ * This generic low-level function can be called by API functions
+ * to check if a specific feature is supported.
+ *
+ * @param[in] p_ddev Pointer to the device structure
+ * @param[in] feat_req_type See ::DEV_FEAT_REQ_TYPES
+ * @param[in] feat_num Number and range depending on feat_req_type value
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @see ::pcps_probe_device
+ */
+int pcps_chk_dev_feat( PCPS_DDEV *p_ddev, uint32_t feat_req_type, uint32_t feat_num )
+{
+ // NOTE In the code below we currently check if the bit to be tested
+ // is really defined in an enumeration, and return an error if a bit
+ // is tested which is not defined.
+ // Alternatively we could instead just check if the bit number is valid
+ // according to the buffer size.
+
+ switch ( feat_req_type )
+ {
+ case DEV_FEAT_REQ_TYPE_BUILTIN:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: builtin_feat %i/%i",
+ pcps_driver_name, feat_num, N_GPS_BUILTIN_FEATURE_BITS );
+
+ if ( feat_num < N_GPS_BUILTIN_FEATURE_BITS )
+ return _check_feat_supp_bit( p_ddev->builtin_features, feat_num );
-} // check_ri_feature
+ break; // invalid
+
+
+ case DEV_FEAT_REQ_TYPE_REF_TYPE:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: ref_type feat %i/%i",
+ pcps_driver_name, feat_num, N_PCPS_REF );
+
+ if ( feat_num < N_PCPS_REF )
+ return ( feat_num == _pcps_ddev_ref_type( p_ddev ) ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV;
+
+ break; // invalid
+
+
+ case DEV_FEAT_REQ_TYPE_PCPS:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: pcps_feat %i/%i",
+ pcps_driver_name, feat_num, N_PCPS_FEATURE_BITS );
+
+ if ( feat_num < N_PCPS_FEATURE_BITS )
+ return _check_feat_supp_bit( p_ddev->dev.cfg.features, feat_num );
+
+ break; // invalid
+
+
+ case DEV_FEAT_REQ_TYPE_RI:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: ri_feat %i/%i",
+ pcps_driver_name, feat_num, N_GPS_FEATURE );
+
+ if ( feat_num < N_GPS_FEATURE )
+ return _check_feat_supp_bit( p_ddev->xdev_features.receiver_info.features, feat_num );
+
+ break; // invalid
+
+
+
+ case DEV_FEAT_REQ_TYPE_XFEAT:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: x_feat %i/%i",
+ pcps_driver_name, feat_num, N_MBG_XFEATURE );
+
+ if ( feat_num < N_MBG_XFEATURE )
+ return check_feat_supp_byte_array( feat_num, p_ddev->xdev_features.xfeature_buffer.b,
+ sizeof( p_ddev->xdev_features.xfeature_buffer ) );
+ break; // invalid
+
+
+
+ case DEV_FEAT_REQ_TYPE_TLV_FEAT:
+ _mbgddmsg_3( MBG_DBG_DETAIL, "%s: chk_dev_feat: tlv_feat %i/%i",
+ pcps_driver_name, feat_num, N_MBG_TLV_FEAT_TYPES );
+
+ if ( feat_num < N_MBG_TLV_FEAT_TYPES )
+ return check_feat_supp_byte_array( feat_num, p_ddev->xdev_features.tlv_info.supp_tlv_feat.b,
+ sizeof( p_ddev->xdev_features.tlv_info.supp_tlv_feat.b ) );
+ break; // invalid
+ }
+
+ _mbgddmsg_3( MBG_DBG_WARN, "%s: chk_dev_feat: *invalid* request %i:%i",
+ pcps_driver_name, feat_req_type, feat_num );
+
+ return MBG_ERR_INV_PARM;
+
+} // pcps_chk_dev_feat
/*HDR*/
-int pcps_start_device( PCPS_DDEV *pddev,
+/**
+ * @brief Probe if a device is supported, and allocate and setup the device structure
+ *
+ * This function should be called by the probe routines of any
+ * target-specific kernel drivers.
+ * If the device is supported then all specific information including
+ * supported features is read from the device and stored in sub-structures
+ * of the device structure addressed by pdev.
+ *
+ * @param[in,out] pddev Pointer to the device structure which has been initialized and will be set up
+ * @param[in] bus_num The bus number if supported (e.g. PCI), else 0
+ * @param[in] dev_fnc_num The device/function number if supported (e.g. PCI), else 0
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @see ::pcps_cleanup_device
+ * @see ::pcps_chk_dev_feat
+ */
+int pcps_probe_device( PCPS_DDEV *pddev,
PCPS_BUS_NUM bus_num,
PCPS_SLOT_NUM dev_fnc_num )
{
+ RECEIVER_INFO *p_ri = _ri_addr( pddev );
ushort port_rsrc_len[N_PCPS_PORT_RSRC] = { 0 };
int port_ranges_required = 0;
ushort status_port_offs = 0;
@@ -2513,6 +3824,9 @@ int pcps_start_device( PCPS_DDEV *pddev,
#endif
+ // Next we do some setup depending on the interface type
+ // and chip.
+
switch ( _pcps_ddev_bus_flags( pddev ) )
{
#if _PCPS_USE_USB
@@ -2552,7 +3866,7 @@ int pcps_start_device( PCPS_DDEV *pddev,
#error USB endpoint configuration can not be determined for this target.
#endif
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
if ( pddev->n_usb_ep < MBGUSB_MIN_ENDPOINTS_REQUIRED )
{
#if defined( MBG_TGT_LINUX )
@@ -2561,9 +3875,9 @@ int pcps_start_device( PCPS_DDEV *pddev,
#elif defined( MBG_TGT_WIN32_PNP )
swprintf( pddev->wcs_msg, L"device supports only %d endpoints while %d are required",
pddev->n_usb_ep, MBGUSB_MIN_ENDPOINTS_REQUIRED );
- _evt_msg( GlbDriverObject, pddev->wcs_msg );
+ _evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#else
- //##++
+ //##++
#endif
rc = MBG_ERR_GENERIC;
@@ -2584,14 +3898,11 @@ int pcps_start_device( PCPS_DDEV *pddev,
// If access time is below 1 ms then there might be a V2.0 Hub between device and host.
// In this case, you can expect that there is the 125 us microframe timing of USB 2.0.
- if ( ( (ULONGLONG) ( Count2.QuadPart - Count1.QuadPart ) ) < ( (ULONGLONG) PerfFreq.QuadPart ) / 1000UL )
- pddev->usb_20_mode = 1;
- else
- pddev->usb_20_mode = 0;
+ pddev->usb_20_mode = ( (ULONGLONG) ( Count2.QuadPart - Count1.QuadPart ) ) < ( ( (ULONGLONG) PerfFreq.QuadPart ) / 1000UL );
}
#endif
- if ( rc != MBG_SUCCESS )
+ if ( mbg_rc_is_error( rc ) )
{
_pcps_ddev_set_err_flags( pddev, PCPS_EF_IO_INIT );
goto fail;
@@ -2648,22 +3959,30 @@ int pcps_start_device( PCPS_DDEV *pddev,
#elif defined( MBG_TGT_WIN32 )
swprintf( pddev->wcs_msg, L"unhandled bus flags %04X for device %S",
_pcps_ddev_bus_flags( pddev ), _pcps_ddev_type_name( pddev ) );
- _evt_msg( GlbDriverObject, pddev->wcs_msg );
+ _evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#endif
goto fail;
} // switch ( _pcps_ddev_bus_flags( pddev ) )
-
- // check if all required resources have been assigned
- if ( pddev->rsrc_info.num_rsrc_io < port_ranges_required )
+ #if _PCPS_USE_MM_IO
+ if ( !_pcps_ddev_is_pci_mbgpex( pddev ) || force_io_access )
+ #endif
{
- _mbgddmsg_3( MBG_DBG_INIT_DEV, "PCPS start device %X fails: port ranges (%u) less than required (%u)",
- _pcps_ddev_dev_id( pddev ), pddev->rsrc_info.num_rsrc_io, port_ranges_required );
- _pcps_ddev_set_err_flags( pddev, PCPS_EF_IO_INIT );
- goto fail;
+ // check if all required I/O resources have been assigned
+ if ( pddev->rsrc_info.num_rsrc_io < port_ranges_required )
+ {
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "PCPS start device %X fails: port ranges (%u) less than required (%u)",
+ _pcps_ddev_dev_id( pddev ), pddev->rsrc_info.num_rsrc_io, port_ranges_required );
+ _pcps_ddev_set_err_flags( pddev, PCPS_EF_IO_INIT );
+ goto fail;
+ }
}
+ #if _PCPS_USE_MM_IO
+ pddev->use_mm_io = 0; // default, eventually changed later
+ #endif
+
if ( _pcps_ddev_is_pci_mbgpex( pddev ) )
{
pddev->irq_enb_disb_port = _pcps_ddev_io_base_mapped( pddev, 0 )
@@ -2673,12 +3992,48 @@ int pcps_start_device( PCPS_DDEV *pddev,
pddev->irq_ack_port = pddev->irq_enb_disb_port;
pddev->irq_ack_mask = PCI_ASIC_PCI_IRQF;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: pcps_probe_device: interface is MBGPEX",
+ pcps_driver_name );
+
+ #if _PCPS_USE_MM_IO
+ if ( force_io_access )
+ {
+ #if defined( MBG_TGT_LINUX ) //##+++++++++++++++++++++++
+ printk( KERN_INFO "%s: Forced I/O access for %s\n",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ) );
+ #endif
+ }
+ else
+ {
+ if ( map_sys_virtual_address( pddev ) < 0 )
+ goto fail_with_cleanup;
+
+ #if DEBUG_IO && defined( MBG_TGT_LINUX )
+ printk( KERN_ERR "io_addr: 0x%llX, cmd: 0x%llX\n",
+ (unsigned long long) _pcps_ddev_io_base_mapped( pddev, 0 ),
+ (unsigned long long) _pcps_ddev_io_base_mapped( pddev, 0 ) + offsetof( PCI_ASIC, pci_data )
+ );
+
+ printk( KERN_ERR "mm_addr: %p, cmd: %p, tstamp: %p\n",
+ pddev->mm_addr,
+ &pddev->mm_addr->mbgpex.asic.pci_data.ul,
+ pddev->mm_tstamp_addr
+ );
+ #endif
+
+ pddev->read = pcps_read_asic_mm;
+ pddev->use_mm_io = 1;
+ }
+ #endif // _PCPS_USE_MM_IO
+
goto chip_setup_done;
}
- // setup additional properties depending on the
- // type of bus interface chip
+ // Setup additional properties depending on the
+ // type of bus interface chip.
+
if ( _pcps_ddev_is_pci_pex8311( pddev ) )
{
// I/O and memory ranges must be swapped for the
@@ -2712,12 +4067,12 @@ int pcps_start_device( PCPS_DDEV *pddev,
// Attention: the interrupt control/status register is located in
// the PLX configuration space which is addressed by a different
// port address range than the normal data ports !!
- pddev->irq_enb_disb_port = _pcps_ddev_io_base_mapped( pddev, 1 ) + PLX8311_REG_INTCSR;
- pddev->irq_enb_mask = PLX8311_INT_ENB;
- pddev->irq_disb_mask = PLX8311_INT_ENB;
+ pddev->irq_enb_disb_port = _pcps_ddev_io_base_mapped( pddev, 1 ) + PLX_LCS_INTCSR;
+ pddev->irq_enb_mask = PLX_LCS_INTCSR_INT_ENB;
+ pddev->irq_disb_mask = PLX_LCS_INTCSR_INT_ENB;
- pddev->irq_flag_port = _pcps_ddev_io_base_mapped( pddev, 1 ) + PLX8311_REG_INTCSR;
- pddev->irq_flag_mask = PLX8311_INT_FLAG;
+ pddev->irq_flag_port = _pcps_ddev_io_base_mapped( pddev, 1 ) + PLX_LCS_INTCSR;
+ pddev->irq_flag_mask = PLX_LCS_INTCSR_INT_FLAG;
pddev->irq_ack_port = _pcps_ddev_io_base_mapped( pddev, 0 ) + offsetof( PCI_ASIC, control_status );
pddev->irq_ack_mask = PCI_ASIC_PCI_IRQF;
@@ -2753,6 +4108,8 @@ int pcps_start_device( PCPS_DDEV *pddev,
chip_setup_done:
+ // Chip-specific setup done. Continue with common device setup.
+
pddev->status_port = _pcps_ddev_io_base_mapped( pddev, 0 ) + status_port_offs;
// Set up the resource list in pddev->dev.cfg which
@@ -2767,8 +4124,8 @@ chip_setup_done:
prsrc = &pddev->rsrc_info.port[i];
- // if the resource len has not yet been set
- // then use the default resource len
+ // If the resource len has not yet been set
+ // then use the default resource len.
if ( prsrc->num == 0 )
prsrc->num = port_rsrc_len[i];
@@ -2777,7 +4134,7 @@ chip_setup_done:
pddev->dev.cfg.irq_num = pddev->rsrc_info.num_rsrc_irq ?
pddev->rsrc_info.irq.num : -1;
- pddev->dev.cfg.status_port = _pcps_ddev_port_base( pddev, 0 ) + status_port_offs;
+ pddev->dev.cfg.short_status_port = _pcps_ddev_short_port_base( pddev, 0 ) + status_port_offs;
pddev->dev.cfg.timeout_clk = PCPS_TIMEOUT_CNT;
@@ -2801,7 +4158,7 @@ chip_setup_done:
#if _PCPS_USE_RSRCMGR
rc = pcps_rsrc_claim( pddev );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
_mbgddmsg_1( MBG_DBG_INIT_DEV, "PCPS start device %X: failed to alloc resources",
_pcps_ddev_dev_id( pddev ) );
@@ -2812,32 +4169,41 @@ chip_setup_done:
// There are some BIOSs out there which don't configure some PEX cards
// properly, and thus the cards can not be accessed properly.
- // See note near the definition of _pcps_pci_cfg_err() for details.
+ // See note near the definition of ::_pcps_pci_cfg_err for details.
if ( _pcps_ddev_pci_cfg_err( pddev ) )
{
-#if 0 //##+++++++++++++++++++++++++
#if defined( MBG_TGT_LINUX )
- printk( KERN_WARNING "PTP270PEX startup delay: %li.%03li s\n",
- dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
+ printk( KERN_WARNING "%s: duplicate base address 0x%04lX, device %s will not work properly (BIOS faulty)\n",
+ pcps_driver_name, (ulong) _pcps_ddev_io_base_raw( pddev, 0 ), _pcps_ddev_type_name( pddev ) );
#elif defined( MBG_TGT_BSD )
- printf( "PTP270PEX startup delay: %li.%03li s\n",
- dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
+ printf( "%s: duplicate base address 0x%04lX, device %s will not work properly (BIOS faulty)\n",
+ pcps_driver_name, (ulong) _pcps_ddev_io_base_raw( pddev, 0 ), _pcps_ddev_type_name( pddev ) );
#elif defined( MBG_TGT_WIN32 )
- swprintf( wcs_msg, L"PTP270PEX startup delay: %li.%03li s",
- dt / 1000, ( ( dt < 0 ) ? -dt : dt ) % 1000 );
- _evt_msg( GlbDriverObject, wcs_msg );
+ swprintf( pddev->wcs_msg, L"duplicate base address 0x%04lX, device %s will not work properly (BIOS faulty)",
+ (ulong) _pcps_ddev_io_base_raw( pddev, 0 ), _pcps_ddev_type_name( pddev ) );
+ _evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#endif
-#endif
}
- // Make sure a PTP270PEX card has finished booting.
- if ( _pcps_ddev_dev_id( pddev ) == PCI_DEV_PTP270PEX )
- check_uptime();
- // try to read EPROM ID
+ #if 0 && DEBUG //###++++++++++++++ TODO testing only
+ {
+ MBG_SYS_UPTIME uptime;
+ mbg_get_sys_uptime( &uptime );
+ mbg_sleep_sec( 1 );
+ mbg_get_sys_uptime( &uptime );
+ }
+ #endif
+
+ // A PTP270PEX card must have finished booting
+ // before it can be accessed.
+ if ( pcps_ddev_is_ptp270pex( pddev ) )
+ wait_ptp270pex_ready( pddev );
+
+ // try to read firmware ID
rc = pcps_get_fw_id( pddev, pddev->dev.cfg.fw_id );
- if ( rc < 0 )
+ if ( mbg_rc_is_error( rc ) )
{
if ( _pcps_ddev_is_isa( pddev ) )
{
@@ -2845,12 +4211,12 @@ chip_setup_done:
// a given port, so if the firmware ID could not be read then this
// just means there is no device using the given port address.
#if defined( MBG_TGT_WIN32 )
- swprintf( pddev->wcs_msg, L"No ISA card found at port %03lXh.",
- (ulong) _pcps_ddev_port_base( pddev, 0 ) );
- _evt_msg( GlbDriverObject, pddev->wcs_msg );
+ swprintf( pddev->wcs_msg, L"No ISA card found at port %03lXh.",
+ (ulong) _pcps_ddev_io_base_raw( pddev, 0 ) );
+ _evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#else
_mbgddmsg_1( MBG_DBG_INIT_DEV, "No ISA card found at port %03lXh.",
- (ulong) _pcps_ddev_port_base( pddev, 0 ) );
+ (ulong) _pcps_ddev_io_base_raw( pddev, 0 ) );
#endif
}
else
@@ -2858,7 +4224,7 @@ chip_setup_done:
// Non-ISA devices are detected by some other means, so if the firmware
// ID could not be read this is a serious error.
#if defined( MBG_TGT_WIN32 ) //##+++ debug or not debug ... ;-)
- _evt_msg( GlbDriverObject, L"StartDevice: failed to read firmware ID" );
+ _evt_msg_w( GlbDriverObject, L"StartDevice: failed to read firmware ID" );
#else
_mbgddmsg_1( MBG_DBG_INIT_DEV, "PCPS start device %X: failed to read firmware ID",
_pcps_ddev_dev_id( pddev ) );
@@ -2879,7 +4245,7 @@ chip_setup_done:
dev_type = PCPS_TYPE_GPS167PC;
else
{
- if ( pcps_check_id( pddev, fw_id_ref_pcps ) == MBG_SUCCESS )
+ if ( mbg_rc_is_success( pcps_check_id( pddev, fw_id_ref_pcps ) ) )
{
// Device is a PC31, or a PC32 if it has signature code.
// If no support for MCA has been compiled in, it may even
@@ -2891,7 +4257,7 @@ chip_setup_done:
}
else
{
- _pcps_ddev_set_err_flags( pddev, PCPS_EF_INV_EPROM_ID );
+ _pcps_ddev_set_err_flags( pddev, PCPS_EF_INV_FW_ID );
goto fail_with_cleanup;
}
}
@@ -2909,21 +4275,35 @@ chip_setup_done:
// If the device has an ASIC or EPLD read the ASIC version number
if ( _pcps_ddev_has_asic_version( pddev ) )
{
- pddev->raw_asic_version = _mbg_inp32_to_cpu( pddev, 0, _pcps_ddev_io_base_mapped( pddev, 0 )
- + offsetof( PCI_ASIC, raw_version ) );
-
- _mbg_swab_asic_version( &pddev->raw_asic_version );
+ #if _PCPS_USE_MM_IO
+ if ( pddev->use_mm_io )
+ {
+ pddev->raw_asic_version = pddev->mm_addr->mbgpex.asic.raw_version;
+ _mbg_swab_asic_version( &pddev->raw_asic_version );
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: pcps_probe_device: raw ASIC version %04X read via MM",
+ pcps_driver_name, pddev->raw_asic_version );
+ }
+ else
+ #endif // _PCPS_USE_MM_IO
+ {
+ pddev->raw_asic_version = _mbg_inp32_to_cpu( pddev, 0, _pcps_ddev_io_base_mapped( pddev, 0 )
+ + offsetof( PCI_ASIC, raw_version ) );
+ _mbg_swab_asic_version( &pddev->raw_asic_version );
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: pcps_probe_device: raw ASIC version %04X read via I/O",
+ pcps_driver_name, pddev->raw_asic_version );
+ }
pddev->asic_version = _convert_asic_version_number( pddev->raw_asic_version );
}
- // Setup some feature flags which depend on the device type
+ // Setup some feature flags which depend on the device type
// and firmware version.
- switch( _pcps_ddev_type_num( pddev ) )
+ switch ( _pcps_ddev_type_num( pddev ) )
{
case PCPS_TYPE_PC31:
case PCPS_TYPE_PS31_OLD:
case PCPS_TYPE_PS31:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PC31PS31;
check_feature( pddev, REV_CAN_SET_TIME_PC31PS31, PCPS_CAN_SET_TIME );
check_feature( pddev, REV_HAS_SERIAL_PC31PS31, PCPS_HAS_SERIAL );
@@ -2932,20 +4312,24 @@ chip_setup_done:
break;
case PCPS_TYPE_PC32:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PC32;
break;
case PCPS_TYPE_PCI32:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PCI32;
break;
case PCPS_TYPE_GPS167PC:
+ pddev->builtin_features = BUILTIN_FEAT_GPS167PC;
pddev->dev.cfg.features = PCPS_FEAT_GPS167PC;
check_feature( pddev, REV_HAS_HR_TIME_GPS167PC, PCPS_HAS_HR_TIME );
check_feature( pddev, REV_HAS_CABLE_LEN_GPS167PC, PCPS_HAS_CABLE_LEN );
break;
case PCPS_TYPE_GPS167PCI:
+ pddev->builtin_features = BUILTIN_FEAT_GPS167PCI;
pddev->dev.cfg.features = PCPS_FEAT_GPS167PCI;
check_feature( pddev, REV_HAS_CABLE_LEN_GPS167PCI, PCPS_HAS_CABLE_LEN );
check_feature( pddev, REV_CAN_CLR_UCAP_BUFF_GPS167PCI, PCPS_CAN_CLR_UCAP_BUFF );
@@ -2953,43 +4337,52 @@ chip_setup_done:
break;
case PCPS_TYPE_PCI509:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PCI509;
break;
case PCPS_TYPE_GPS168PCI:
+ pddev->builtin_features = BUILTIN_FEAT_GPS168PCI;
pddev->dev.cfg.features = PCPS_FEAT_GPS168PCI;
check_feature( pddev, REV_CAN_CLR_UCAP_BUFF_GPS168PCI, PCPS_CAN_CLR_UCAP_BUFF );
check_feature( pddev, REV_HAS_UCAP_GPS168PCI, PCPS_HAS_UCAP );
break;
case PCPS_TYPE_PCI510:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PCI510;
break;
case PCPS_TYPE_GPS169PCI:
+ pddev->builtin_features = BUILTIN_FEAT_GPS169PCI;
pddev->dev.cfg.features = PCPS_FEAT_GPS169PCI;
check_feature( pddev, REV_HAS_GPS_DATA_16_GPS169PCI, PCPS_HAS_GPS_DATA_16 );
break;
case PCPS_TYPE_TCR510PCI:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_TCR510PCI;
check_feature( pddev, REV_HAS_HR_TIME_TCR510PCI, PCPS_HAS_HR_TIME );
break;
case PCPS_TYPE_TCR167PCI:
+ pddev->builtin_features = BUILTIN_FEAT_TCR167PCI;
pddev->dev.cfg.features = PCPS_FEAT_TCR167PCI;
break;
case PCPS_TYPE_GPS170PCI:
+ pddev->builtin_features = BUILTIN_FEAT_GPS170PCI;
pddev->dev.cfg.features = PCPS_FEAT_GPS170PCI;
break;
case PCPS_TYPE_PCI511:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PCI511;
check_feature( pddev, REV_HAS_HR_TIME_PCI511, PCPS_HAS_HR_TIME );
break;
case PCPS_TYPE_TCR511PCI:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_TCR511PCI;
check_feature( pddev, REV_HAS_IRIG_CTRL_BITS_TCR511PCI, PCPS_HAS_IRIG_CTRL_BITS );
check_feature( pddev, REV_HAS_IRIG_TIME_TCR511PCI, PCPS_HAS_IRIG_TIME );
@@ -2997,8 +4390,9 @@ chip_setup_done:
break;
case PCPS_TYPE_PEX511:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_PEX511;
- // HR time support for the PEX511 requires both a certain ASIC
+ // HR time support for the PEX511 requires both a certain ASIC
// version plus a certain firmware version.
if ( _pcps_asic_version_greater_equal( _pcps_ddev_asic_version( pddev ),
PCI_ASIC_MAJOR_PEX511, PCI_ASIC_HR_TIME_MINOR_PEX511 ) )
@@ -3009,6 +4403,7 @@ chip_setup_done:
break;
case PCPS_TYPE_TCR511PEX:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_TCR511PEX;
check_feature( pddev, REV_HAS_IRIG_CTRL_BITS_TCR511PEX, PCPS_HAS_IRIG_CTRL_BITS );
check_feature( pddev, REV_HAS_IRIG_TIME_TCR511PEX, PCPS_HAS_IRIG_TIME );
@@ -3018,16 +4413,19 @@ chip_setup_done:
break;
case PCPS_TYPE_GPS170PEX:
+ pddev->builtin_features = BUILTIN_FEAT_GPS170PEX;
pddev->dev.cfg.features = PCPS_FEAT_GPS170PEX;
pcps_check_pex_irq_unsafe( pddev, REV_HAS_IRQ_FIX_MINOR_GPS170PEX,
PCI_ASIC_MAJOR_GPS170PEX, PCI_ASIC_FIX_IRQ_MINOR_GPS170PEX );
break;
case PCPS_TYPE_USB5131:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_USB5131;
break;
case PCPS_TYPE_TCR51USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_TCR51USB;
check_feature( pddev, REV_HAS_IRIG_CTRL_BITS_TCR51USB, PCPS_HAS_IRIG_CTRL_BITS );
check_feature( pddev, REV_HAS_IRIG_TIME_TCR51USB, PCPS_HAS_IRIG_TIME );
@@ -3035,53 +4433,80 @@ chip_setup_done:
break;
case PCPS_TYPE_MSF51USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_MSF51USB;
break;
case PCPS_TYPE_PTP270PEX:
+ pddev->builtin_features = BUILTIN_FEAT_PTP270PEX;
pddev->dev.cfg.features = PCPS_FEAT_PTP270PEX;
break;
case PCPS_TYPE_FRC511PEX:
+ pddev->builtin_features = BUILTIN_FEAT_FRC511PEX;
pddev->dev.cfg.features = PCPS_FEAT_FRC511PEX;
break;
case PCPS_TYPE_TCR170PEX:
+ pddev->builtin_features = BUILTIN_FEAT_TCR170PEX;
pddev->dev.cfg.features = PCPS_FEAT_TCR170PEX;
break;
case PCPS_TYPE_WWVB51USB:
+ pddev->builtin_features = BUILTIN_FEAT_WWVB511;
pddev->dev.cfg.features = PCPS_FEAT_WWVB51USB;
break;
case PCPS_TYPE_GPS180PEX:
+ pddev->builtin_features = BUILTIN_FEAT_GPS180PEX;
pddev->dev.cfg.features = PCPS_FEAT_GPS180PEX;
break;
case PCPS_TYPE_TCR180PEX:
+ pddev->builtin_features = BUILTIN_FEAT_TCR180PEX;
pddev->dev.cfg.features = PCPS_FEAT_TCR180PEX;
break;
case PCPS_TYPE_DCF600USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_DCF600USB;
break;
case PCPS_TYPE_PZF180PEX:
+ pddev->builtin_features = BUILTIN_FEAT_PZF180PEX;
pddev->dev.cfg.features = PCPS_FEAT_PZF180PEX;
break;
case PCPS_TYPE_TCR600USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_TCR600USB;
break;
case PCPS_TYPE_MSF600USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_MSF600USB;
break;
case PCPS_TYPE_WVB600USB:
+ pddev->builtin_features = BUILTIN_FEAT_UNDEFINED;
pddev->dev.cfg.features = PCPS_FEAT_WVB600USB;
break;
+ case PCPS_TYPE_GLN180PEX:
+ pddev->builtin_features = BUILTIN_FEAT_GLN180PEX;
+ pddev->dev.cfg.features = PCPS_FEAT_GLN180PEX;
+ break;
+
+ case PCPS_TYPE_GPS180AMC:
+ pddev->builtin_features = BUILTIN_FEAT_GPS180AMC;
+ pddev->dev.cfg.features = PCPS_FEAT_GPS180AMC;
+ break;
+
+ case PCPS_TYPE_GNS181PEX:
+ pddev->builtin_features = BUILTIN_FEAT_GNS181PEX;
+ pddev->dev.cfg.features = PCPS_FEAT_GNS181PEX;
+ break;
+
default:
#if defined( MBG_TGT_LINUX )
printk( KERN_WARNING "%s: no feature detection for device %s\n",
@@ -3092,7 +4517,7 @@ chip_setup_done:
#elif defined( MBG_TGT_WIN32 )
swprintf( pddev->wcs_msg, L"no feature detection for device %S",
_pcps_ddev_type_name( pddev ) );
- _evt_msg( GlbDriverObject, pddev->wcs_msg );
+ _evt_msg_w( GlbDriverObject, pddev->wcs_msg );
#endif
goto fail_with_cleanup;
@@ -3101,15 +4526,15 @@ chip_setup_done:
if ( _pcps_ddev_has_receiver_info( pddev ) )
{
- rc = _pcps_read_gps_var( pddev, PC_GPS_RECEIVER_INFO, pddev->ri );
+ rc = _pcps_read_gps_var( pddev, PC_GPS_RECEIVER_INFO, *p_ri );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
- _mbg_swab_receiver_info( &pddev->ri );
+ _mbg_swab_receiver_info( p_ri );
_mbgddmsg_1( MBG_DBG_INIT_DEV, "Successfully read receiver info from dev %X",
_pcps_ddev_dev_id( pddev ) );
- goto check;
+ goto receiver_info_done;
}
_mbgddmsg_1( MBG_DBG_INIT_DEV, "Failed to read receiver info from dev %X",
@@ -3121,21 +4546,70 @@ chip_setup_done:
_pcps_ddev_dev_id( pddev ) );
if ( _pcps_ddev_is_gps( pddev ) )
- _setup_default_receiver_info_gps( &pddev->ri );
+ _setup_default_receiver_info_gps( p_ri );
else
- _setup_default_receiver_info_dcf( &pddev->ri, &pddev->dev );
+ _setup_default_receiver_info_dcf( p_ri, &pddev->dev );
+receiver_info_done:
-check:
- #if DEBUG_IO
- _mbgddmsg_1( MBG_DBG_DETAIL, "ri.sw_rev.code: %04X", pddev->ri.sw_rev.code );
- _mbgddmsg_1( MBG_DBG_DETAIL, "ri.model_code: %04X", pddev->ri.model_code );
- _mbgddmsg_3( MBG_DBG_DETAIL, "ri.model_name: %-*.*s", (int) sizeof( pddev->ri.model_name ),
- (int) sizeof( pddev->ri.model_name ), pddev->ri.model_name );
- #endif
+ #if defined( DEBUG )
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.model_code: 0x%04X",
+ p_ri->model_code );
+
+ _mbgddmsg_3( MBG_DBG_DETAIL, "ri.model_name: \"%-*.*s\"",
+ (int) sizeof( p_ri->model_name ),
+ (int) sizeof( p_ri->model_name ),
+ p_ri->model_name );
+
+ _mbgddmsg_4( MBG_DBG_DETAIL, "ri.sw_rev: code 0x%04X, name \"%-*.*s\"",
+ p_ri->sw_rev.code,
+ (int) sizeof( p_ri->sw_rev.name ),
+ (int) sizeof( p_ri->sw_rev.name ),
+ p_ri->sw_rev.name );
+
+ _mbgddmsg_3( MBG_DBG_DETAIL, "ri.sernum: \"%-*.*s\"",
+ (int) sizeof( p_ri->sernum ),
+ (int) sizeof( p_ri->sernum ),
+ p_ri->sernum );
+
+ _mbgddmsg_3( MBG_DBG_DETAIL, "ri.epld_name: \"%-*.*s\"",
+ (int) sizeof( p_ri->epld_name ),
+ (int) sizeof( p_ri->epld_name ),
+ p_ri->epld_name );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.n_channels: %u",
+ p_ri->n_channels );
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.ticks_per_sec: %lu",
+ (ulong) p_ri->ticks_per_sec );
-#if 0 //##+++++++++ check if this is reasonnable
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.features: 0x%08lX",
+ (ulong) p_ri->features );
+
+ _mbgddmsg_2( MBG_DBG_DETAIL, "ri.fixed_freq: khz_val %u, range %i",
+ p_ri->fixed_freq.khz_val,
+ p_ri->fixed_freq.range );
+
+ _mbgddmsg_2( MBG_DBG_DETAIL, "ri.osc type: %u, flags: 0x%02X",
+ p_ri->osc_type, p_ri->osc_flags );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.n_ucaps: %u",
+ p_ri->n_ucaps );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.n_com_ports: %u",
+ p_ri->n_com_ports );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.n_str_type: %u",
+ p_ri->n_str_type );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.n_prg_out: %u",
+ p_ri->n_prg_out );
+
+ _mbgddmsg_1( MBG_DBG_DETAIL, "ri.flags: 0x%04X",
+ p_ri->flags );
+#endif
+
+#if 0 //###+++++++++ TODO check if this is reasonable
// Make sure this program supports at least as many ports as
// the current clock device.
@@ -3156,43 +4630,67 @@ check:
}
#endif
-
// detect the presence of some optional features at run time
_mbgddmsg_3( MBG_DBG_INIT_DEV, "%s v%03X RECEIVER_INFO features: 0x%08lX",
_pcps_ddev_type_name( pddev ), _pcps_ddev_fw_rev_num( pddev ),
- (ulong) pddev->ri.features );
-
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_IRIG_TX, PCPS_HAS_IRIG_TX );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_IRIG_CTRL_BITS, PCPS_HAS_IRIG_CTRL_BITS );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_SYNTH, PCPS_HAS_SYNTH );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_TIME_SCALE, PCPS_HAS_TIME_SCALE );
-
- // Devices which support a configurable time scale do also
- // support reading/writing the GPS UTC parameters via the PC bus.
- // This is not explicitely coded in the rcvr_info structure
- // since the the rcvr_info structure can also be read via
- // the serial port, and reading/writing the GPS UTC parameters
- // via the serial port is supported by all GPS devices anyway.
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_TIME_SCALE, PCPS_HAS_UTC_PARM );
-
- // Devices which support reading raw IRIG data via the PC interface also support
- // reading the raw IRIG time. However, there is no receiver info feature flag
- // since this call is not supported via the serial interface, so we use the
- // GPS_HAS_RAW_IRIG_DATA flag to check both features.
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_RAW_IRIG_DATA, PCPS_HAS_IRIG_TIME );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_RAW_IRIG_DATA, PCPS_HAS_RAW_IRIG_DATA );
-
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_LAN_IP4, PCPS_HAS_LAN_INTF );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_PTP, PCPS_HAS_PTP );
- check_ri_feature( pddev, &pddev->ri, GPS_HAS_PTP_UNICAST, 0 ); // no equivalent in PCPS_DDEV features
+ (ulong) *_ri_addr( pddev ).features );
+
+ check_ri_features( pddev );
+
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s v%03X actual features 1: 0x%08lX",
+ _pcps_ddev_type_name( pddev ), _pcps_ddev_fw_rev_num( pddev ),
+ (ulong) _pcps_ddev_features( pddev ) );
#if !defined( MBG_TGT_OS2 ) && !defined( MBG_TGT_BSD )
// Function strstr may not be supported at kernel level,
- // but this is not required, in most cases, either.
+ // but this is not required, in most cases, anyway.
if ( strstr( _pcps_ddev_fw_id( pddev ), "CERN" ) != NULL )
pddev->dev.cfg.features |= PCPS_HAS_EVENT_TIME;
#endif
+
+ // Check if the device supports extended features
+
+ rc = pcps_chk_dev_feat( pddev, DEV_FEAT_REQ_TYPE_RI, GPS_FEAT_XFEATURE );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s going to read XFEATURE_BUFFER", _pcps_ddev_type_name( pddev ) );
+
+ rc = _pcps_read_gps_var( pddev, PC_GPS_XFEATURE_BUFFER, *_xfeat_addr( pddev ) );
+
+ if ( mbg_rc_is_error( rc ) )
+ {
+ #if defined( MBG_TGT_LINUX )
+ printk( KERN_ERR "%s: failed to read XFEATURE_BUFFER from device %s\n",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ) );
+ #endif
+ memset( _xfeat_addr( pddev ), 0, sizeof( *_xfeat_addr( pddev ) ) );
+ }
+ }
+
+
+ // Check if the device supports the TLV API
+
+ rc = pcps_chk_dev_feat( pddev, DEV_FEAT_REQ_TYPE_XFEAT, MBG_XFEATURE_TLV_API );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s going to read TLV_INFO", _pcps_ddev_type_name( pddev ) );
+
+ rc = _pcps_read_gps_var( pddev, PC_GPS_TLV_INFO, *_tlv_info_addr( pddev ) );
+
+ if ( mbg_rc_is_error( rc ) )
+ {
+ #if defined( MBG_TGT_LINUX )
+ printk( KERN_ERR "%s: failed to read TLV_INFO from device %s\n",
+ pcps_driver_name, _pcps_ddev_type_name( pddev ) );
+ #endif
+ memset( _tlv_info_addr( pddev ), 0, sizeof( *_tlv_info_addr( pddev ) ) );
+ }
+ }
+
+
#if DEBUG_IO && defined( MBG_TGT_LINUX )
{
PCPS_TIME t = { 0 };
@@ -3215,6 +4713,10 @@ check:
_mbg_swab_asic_features( &pddev->asic_features );
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s v%03X asic_features: 0x%08lX",
+ _pcps_ddev_type_name( pddev ), _pcps_ddev_fw_rev_num( pddev ),
+ (ulong) pddev->asic_features );
+
#if MBG_TGT_SUPP_MEM_ACC
if ( pddev->asic_features & PCI_ASIC_HAS_MM_IO )
pddev->dev.cfg.features |= PCPS_HAS_FAST_HR_TSTAMP;
@@ -3227,10 +4729,10 @@ check:
"Warning: ASIC features don't reflect memory mapped time stamp support." );
}
- if ( pddev->dev.cfg.features & PCPS_HAS_FAST_HR_TSTAMP )
- if ( map_sys_virtual_address( pddev ) < 0 )
- goto fail_with_cleanup;
-
+ if ( !has_mapped_sys_virtual_address( pddev ) )
+ if ( pddev->dev.cfg.features & PCPS_HAS_FAST_HR_TSTAMP )
+ if ( map_sys_virtual_address( pddev ) < 0 )
+ goto fail_with_cleanup;
#endif
}
@@ -3249,11 +4751,18 @@ fail_with_cleanup:
fail:
return MBG_ERR_GENERIC;
-} // pcps_start_device
+} // pcps_probe_device
/*HDR*/
+/**
+ * @brief Clean up function called by ::pcps_probe_device on error
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ *
+ * @see ::pcps_probe_device
+ */
void pcps_cleanup_device( PCPS_DDEV *pddev )
{
pddev->read = pcps_read_null;
@@ -3270,17 +4779,27 @@ void pcps_cleanup_device( PCPS_DDEV *pddev )
-/*--------------------------------------------------------------
- * PCI functions
- *-------------------------------------------------------------*/
-
#if _PCPS_USE_PCI_BIOS
static /*HDR*/
+/**
+ * @brief Read PCI recources for a PCI device on non-PnP systems
+ *
+ * This function should be called by the probe routines of any
+ * target-specific kernel drivers.
+ * If the device is supported then all specific information including
+ * supported features is read from the device and stored in sub-structures
+ * of the device structure addressed by pdev.
+ *
+ * @param[in] bus_num The PCI bus number
+ * @param[in] dev_fnc_num The PCI device/function number
+ * @param[in,out] pddev Pointer to the device structure to be set up
+ *
+ * @return 0 on success, or a combination of @ref PCPS_ERR_FLAG_MASKS masks on error
+ */
PCPS_ERR_FLAGS pcps_read_pci_rsrc( PCPS_BUS_NUM bus_num,
PCPS_SLOT_NUM dev_fnc_num,
- PCPS_DDEV *pddev,
- PCPS_BUS_FLAGS bus_flags )
+ PCPS_DDEV *pddev )
{
PCPS_ERR_FLAGS err_flags = 0;
uchar irq;
@@ -3336,20 +4855,36 @@ done:
static /*HDR*/
+/**
+ * @brief Enable a PCI device which has not yet been enabled
+ *
+ * In PnP systems only PCI devices that are required for booting
+ * are always enabled by the PCI BIOS. Other PCI devices may only
+ * be fully enabled if a PC BIOS setup option "PNP OS installed"
+ * is set to "NO".
+ * If this option is set to "YES" then I/O access to the board
+ * may still be disabled, and a PnP operating system is expected
+ * to enable remaining devices when it boots up.
+ * Drivers can call this function to enable I/O and memory access,
+ * if required, in case this hasn't been done by the PCI BIOS
+ * or operating system.
+ *
+ * @param[in] bus_num The PCI bus number
+ * @param[in] dev_fnc_num The PCI device/function number
+ * @param[in] num_rsrc_mem If != 0 then memory access is also enabled
+ *
+ * @return 0 on success, or a combination of @ref PCPS_ERR_FLAG_MASKS masks on error
+ */
PCPS_ERR_FLAGS pcps_enable_pci_dev( PCPS_BUS_NUM bus_num,
PCPS_SLOT_NUM dev_fnc_num,
int num_rsrc_mem )
{
PCPS_ERR_FLAGS err_flags = 0;
- uint16_t pci_command;
- uint16_t new_pci_command;
+ uint16_t pci_command; // current value read from the PCI cfg "command" register
+ uint16_t new_pci_command; // new value to be written to the PCI cfg "command" register
int rc;
- // If the option "PNP OS installed" is set to "YES" in the
- // PC's BIOS setup, then I/O access to the board may still
- // be disabled, so check if the clock is enabled and enable
- // access to the board, if nessessary.
rc = _mbg_pci_read_cfg_word( bus_num, dev_fnc_num,
PCI_CS_COMMAND, &pci_command );
new_pci_command = pci_command | PCI_CMD_ENB_IO_ACC;
@@ -3377,13 +4912,19 @@ PCPS_ERR_FLAGS pcps_enable_pci_dev( PCPS_BUS_NUM bus_num,
/*HDR*/
+/**
+ * @brief Setup and start a PCI device in a non-PnP system
+ *
+ * @param[in,out] pddev Pointer to the device structure to be set up
+ * @param[in] bus_num The PCI bus number returned by the PCI BIOS
+ * @param[in] dev_fnc_num The PCI device/function number returned by the PCI BIOS
+ */
void pcps_setup_and_start_pci_dev( PCPS_DDEV *pddev,
PCPS_BUS_NUM bus_num, PCPS_SLOT_NUM dev_fnc_num )
{
PCPS_ERR_FLAGS err_flags;
- err_flags = pcps_read_pci_rsrc( bus_num, dev_fnc_num,
- pddev, _pcps_ddev_bus_flags( pddev ) );
+ err_flags = pcps_read_pci_rsrc( bus_num, dev_fnc_num, pddev );
_pcps_ddev_set_err_flags( pddev, err_flags );
if ( !( err_flags & PCPS_EF_IO_INIT ) )
@@ -3393,17 +4934,26 @@ void pcps_setup_and_start_pci_dev( PCPS_DDEV *pddev,
_pcps_ddev_set_err_flags( pddev, err_flags );
}
- pcps_start_device( pddev, bus_num, dev_fnc_num );
+ pcps_probe_device( pddev, bus_num, dev_fnc_num );
} // pcps_setup_and_start_pci_dev
/*HDR*/
-void pcps_detect_pci_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg,
- PCPS_DDEV_CLEANUP_FNC cleanup_fnc,
- ushort vendor_id, PCPS_DEV_TYPE dev_type[],
- int n_dev_types )
+/**
+ * @brief Detect and initialize PCI devices in a non-PnP system
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ * @param[in] cleanup_fnc Pointer to function called if the device structure needs to be de-allocated in case of error.
+ * @param[in] vendor_id The PCI vendor ID code.
+ * @param[in] dev_type An array with known PCI devices for the specified vendor ID
+ * @param[in] n_dev_types The number of entries in the PCI device table
+ */
+void pcps_detect_pci_devices( PCPS_DDEV_ALLOC_FNC *alloc_fnc,
+ PCPS_DDEV_CLEANUP_FNC *cleanup_fnc,
+ ushort vendor_id, PCPS_DEV_TYPE dev_type[],
+ int n_dev_types )
{
#if defined( MBG_TGT_QNX )
#if defined( MBG_TGT_QNX_NTO )
@@ -3468,6 +5018,9 @@ void pcps_detect_pci_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg,
break; // go to try next device ID
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "Found PCI device %s (0x%04X)",
+ p->name, p->dev_id );
+
// New device found, try to add to list.
pddev = alloc_fnc();
@@ -3493,6 +5046,8 @@ void pcps_detect_pci_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg,
if ( cleanup_fnc )
cleanup_fnc( pddev );
}
+ #else
+ (void) cleanup_fnc; // avoid compiler warning
#endif
}
}
@@ -3503,24 +5058,29 @@ void pcps_detect_pci_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg,
_mbg_pci_fnc_deinit();
#endif
-} // pcps_detect_pci_clocks
+} // pcps_detect_pci_devices
#endif // _PCPS_USE_PCI_BIOS
-/*--------------------------------------------------------------
- * Try to detect ISA clocks
- *-------------------------------------------------------------*/
-
#if !_PCPS_USE_ISA_PNP
/*HDR*/
-void pcps_detect_isa_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc,
- PCPS_DDEV_CLEANUP_FNC cleanup_fnc,
- PCPS_DDEV_REGISTER_FNC register_fnc,
- int isa_ports[PCPS_MAX_ISA_CARDS],
- int isa_irqs[PCPS_MAX_ISA_CARDS] )
+/**
+ * @brief Detect and initialize ISA devices in a non-PnP system
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ * @param[in] cleanup_fnc Pointer to function called if the device structure needs to be de-allocated in case of error.
+ * @param[in] register_fnc Pointer to function called to register a detected device.
+ * @param[in] isa_ports An array with potential I/O base addresses for ISA devices.
+ * @param[in] isa_irqs An array with potential IRQ numbers assigned to ISA devices.
+ */
+void pcps_detect_isa_devices( PCPS_DDEV_ALLOC_FNC *alloc_fnc,
+ PCPS_DDEV_CLEANUP_FNC *cleanup_fnc,
+ PCPS_DDEV_REGISTER_FNC *register_fnc,
+ int isa_ports[PCPS_MAX_ISA_CARDS],
+ int isa_irqs[PCPS_MAX_ISA_CARDS] )
{
int *p_port = isa_ports;
int *p_irq = isa_irqs;
@@ -3562,7 +5122,7 @@ void pcps_detect_isa_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc,
// Init the device structure. This includes registration
// of I/O ports with the OS's resource manager (if supported),
// and reading the firmware ID.
- pcps_start_device( pddev, 0, 0 );
+ pcps_probe_device( pddev, 0, 0 );
// If an error has occurred, then remove the last
// device from the list and try next.
@@ -3583,7 +5143,7 @@ void pcps_detect_isa_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc,
}
}
-} // pcps_detect_isa_clocks
+} // pcps_detect_isa_devices
#endif //!_PCPS_USE_ISA_PNP
@@ -3591,48 +5151,60 @@ void pcps_detect_isa_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc,
#if !_PCPS_USE_PNP
-/*--------------------------------------------------------------
- * Try to detect any plug-in device. If a DOS TSR is
- * installed, be sure it is disabled (BUSY flag set) when
- * this function is called.
- *-------------------------------------------------------------*/
-
-/*HDR*/
-void _MBG_INIT_CODE_ATTR pcps_detect_clocks_alloc( PCPS_DDEV_ALLOC_FNC alloc_fnc,
- void *alloc_arg,
- PCPS_DDEV_CLEANUP_FNC cleanup_fnc,
- int isa_ports[PCPS_MAX_ISA_CARDS],
- int isa_irqs[PCPS_MAX_ISA_CARDS] )
+static /*HDR*/
+/**
+ * @brief Detect all bus-level devices in a non-PnP system, use specific alloc/cleanup functions
+ *
+ * @note If a DOS TSR is installed, be sure it is disabled (BUSY flag set)
+ * when this function is called.
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ * @param[in] cleanup_fnc Pointer to function called if the device structure needs to be de-allocated in case of error.
+ * @param[in] isa_ports An array with potential I/O base addresses for ISA devices.
+ * @param[in] isa_irqs An array with potential IRQ numbers assigned to ISA devices.
+ */
+void _MBG_INIT_CODE_ATTR pcps_detect_devices_alloc( PCPS_DDEV_ALLOC_FNC *alloc_fnc,
+ PCPS_DDEV_CLEANUP_FNC *cleanup_fnc,
+ int isa_ports[PCPS_MAX_ISA_CARDS],
+ int isa_irqs[PCPS_MAX_ISA_CARDS] )
{
#if defined( MBG_TGT_OS2 )
rsrc_register_driver(); // register driver and init resource manager
#endif
#if _PCPS_USE_PCI_BIOS
- pcps_detect_pci_clocks( alloc_fnc, alloc_arg, cleanup_fnc,
- PCI_VENDOR_MEINBERG, pcps_dev_type, N_PCPS_DEV_TYPE );
+ pcps_detect_pci_devices( alloc_fnc, cleanup_fnc, PCI_VENDOR_MEINBERG,
+ pcps_dev_type, N_PCPS_DEV_TYPE );
#endif
#if _PCPS_USE_MCA
- pcps_detect_mca_clocks( alloc_fnc, alloc_arg );
+ pcps_detect_mca_devices( alloc_fnc );
#endif
#if !_PCPS_USE_ISA_PNP
- pcps_detect_isa_clocks( alloc_fnc, cleanup_fnc, NULL, isa_ports, isa_irqs );
+ pcps_detect_isa_devices( alloc_fnc, cleanup_fnc, NULL, isa_ports, isa_irqs );
#endif
-} // pcps_detect_clocks_alloc
+} // pcps_detect_devices_alloc
/*HDR*/
-void _MBG_INIT_CODE_ATTR pcps_detect_clocks( int isa_ports[PCPS_MAX_ISA_CARDS],
- int isa_irqs[PCPS_MAX_ISA_CARDS] )
+/**
+ * @brief Detect all bus-level devices in a non-PnP system
+ *
+ * @note If a DOS TSR is installed, be sure it is disabled (BUSY flag set)
+ * when this function is called.
+ *
+ * @param[in] isa_ports An array with potential I/O base addresses for ISA devices.
+ * @param[in] isa_irqs An array with potential IRQ numbers assigned to ISA devices.
+ */
+void _MBG_INIT_CODE_ATTR pcps_detect_devices( int isa_ports[PCPS_MAX_ISA_CARDS],
+ int isa_irqs[PCPS_MAX_ISA_CARDS] )
{
- pcps_detect_clocks_alloc( pcps_alloc_ddev, NULL, pcps_free_ddev,
- isa_ports, isa_irqs );
+ pcps_detect_devices_alloc( pcps_alloc_ddev, pcps_free_ddev, isa_ports, isa_irqs );
-} // pcps_detect_clocks
+} // pcps_detect_devices
#endif // !_PCPS_USE_PNP
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.h
index 8f203c4..405002e 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsdrvr.h 1.41.1.34 2011/07/19 12:48:39 martin TRASH $
+ * $Id: pcpsdrvr.h 1.46 2017/07/04 16:50:48 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,79 +10,52 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsdrvr.h $
- * Revision 1.41.1.34 2011/07/19 12:48:39 martin
+ * Revision 1.46 2017/07/04 16:50:48 martin
+ * Support GPS180AMC and GNS181PEX.
+ * Support new module parameter force_io_access to provide
+ * runtime support for forcing I/O rather than MM access.
+ * Cleaned up I/O port usage.
+ * Added _pcps_ddev_has_xmr() macro.
+ * Older defines N_SUPP_DEV, PCPS_MAX_DDEVS, and MBG_MAX_DEVICES
+ * have been obsoleted by new defines N_SUPP_DEV_BUS, N_SUPP_DEV_EXT,
+ * and N_SUPP_DEV_TOTAL.
+ * Conditional USB debug code.
+ * Use more versatile types for function pointers.
+ * Fixed macro definition syntax to avoid clang compiler warnings.
+ * Prepare to use MBG_XDEV_FEATURES in PCPS_DDEV.
+ * Updated function prototypes.
+ * Revision 1.45 2013/09/26 09:08:09 martin
+ * Support GLN180PEX and GNSS API.
+ * Revision 1.44 2013/03/15 10:01:09 martin
+ * Optionally override setting to support memory mapped I/O.
+ * Revision 1.43 2012/11/02 09:48:04 martin
+ * Removed obsolete include.
+ * Revision 1.42 2012/10/02 19:09:20 martin
+ * Conditionally support memory mapped access for MBGPEX cards.
+ * Support on-board event logs.
+ * New macro _pcps_ddev_has_debug_status().
+ * Added some macros to test if specific stat_info stuff is supported.
* Updated function prototypes.
- * Code cleanup.
- * Revision 1.41.1.33 2011/07/06 11:23:09 martin
* Added macros _pcps_ddev_has_corr_info() and _pcps_ddev_has_tr_distance().
- * Revision 1.41.1.32 2011/07/04 10:29:44 martin
- * Modified a comment.
- * Revision 1.41.1.31 2011/06/29 14:01:32 martin
- * Renamed PZF600PEX to PZF180PEX.
- * Added support for TCR600USB, MSF600USB, and WVB600USB.
+ * Support GPS180PEX, TCR180PEX, and PZF180PEX.
+ * Support DCF600USB, TCR600USB, MSF600USB, and WVB600USB.
* New macros _pcps_ddev_is_usb_v2() and _pcps_ddev_has_pcf().
- * Updated some comments.
- * Revision 1.41.1.30 2011/06/29 09:10:27 martin
- * Renamed PZF600PEX to PZF180PEX.
- * Revision 1.41.1.29 2011/05/31 14:24:18 martin
- * Revision 1.41.1.28 2011/05/16 16:39:20 martin
- * Allocate non-paged memory under Windows.
- * Revision 1.41.1.27 2011/05/06 13:47:40Z martin
- * Support PZF600PEX.
- * Revision 1.41.1.26 2011/04/12 15:50:57 martin
- * Revision 1.41.1.25 2011/04/12 15:26:10Z martin
- * Moved mutex definitions to new mbgmutex.h.
- * Revision 1.41.1.24 2011/04/01 13:32:45 martin
- * Added missing mutex destroy for Windows.
- * Revision 1.41.1.23 2011/04/01 10:38:42Z martin
- * Support mutex/spinlock destroy.
- * Revision 1.41.1.22 2011/03/31 10:35:57 martin
- * Fixed a typo.
- * Revision 1.41.1.21 2011/03/28 09:53:52Z martin
- * Modifications for NetBSD from Frank Kardel.
- * Revision 1.41.1.20 2011/03/25 11:11:44 martin
* Optionally support timespec for sys time (USE_TIMESPEC).
- * Started to support NetBSD.
- * Revision 1.41.1.19 2011/02/15 14:24:58 martin
- * Revision 1.41.1.18 2011/02/09 17:08:31 martin
+ * Support FreeBSD and NetBSD.
* Specify I/O range number when calling port I/O macros
* so they can be used for different ranges under BSD.
- * Revision 1.41.1.17 2011/02/04 14:44:46 martin
- * Revision 1.41.1.16 2011/02/04 10:10:18 martin
- * Revision 1.41.1.15 2011/02/02 12:20:42 martin
- * Revision 1.41.1.14 2011/02/01 17:12:05 martin
- * Revision 1.41.1.13 2011/02/01 14:49:43 martin
- * Revision 1.41.1.12 2011/02/01 12:12:19 martin
- * Revision 1.41.1.11 2011/01/31 17:30:02 martin
- * Modified resource storage for *BSD.
- * Revision 1.41.1.10 2011/01/27 13:39:01 martin
- * Revision 1.41.1.9 2011/01/27 11:04:45 martin
- * Revision 1.41.1.8 2011/01/27 11:01:49 martin
- * Support static device list (no malloc) and use it under FreeBSD.
- * Revision 1.41.1.7 2011/01/26 16:42:07 martin
- * Fixed build under FreeBSD.
- * Revision 1.41.1.6 2011/01/25 09:47:27 martin
- * Fixed build under FreeBSD.
- * Revision 1.41.1.5 2010/11/23 11:07:57 martin
- * Support memory mapped access under DOS.
- * Revision 1.41.1.4 2010/11/11 09:15:39Z martin
- * Added definitions to support DCF600USB.
- * Revision 1.41.1.3 2010/08/20 09:35:12 martin
* Added macro _pcps_ddev_features().
- * Revision 1.41.1.2 2010/07/14 14:52:12 martin
- * Revision 1.41.1.1 2010/06/30 15:01:52 martin
- * Support GPS180PEX and TCR180PEX.
* Revision 1.41 2010/06/30 13:44:49 martin
* Use new preprocessor symbol MBG_ARCH_X86.
* Revision 1.40 2010/01/12 14:05:05 daniel
- * Added macro to check if reading the
+ * Added macro to check if reading the
* raw IRIG data bits is supported.
* Revision 1.39 2009/09/29 07:24:51Z martin
* Use standard feature flag to check if fast HR time is supported.
* Revision 1.38 2009/06/19 12:13:05 martin
* Added _pcps_ddev_has_irig_time() macro.
* Revision 1.37 2009/06/09 10:13:59 daniel
- * Added macros _pcps_ddev_has_lan_intf( _p ) and
+ * Added macros _pcps_ddev_has_lan_intf( _p ) and
* _pcps_ddev_has_ptp_cfg( _p ).
* Cleaned up the low level interface and provided a
* possibility to override the macros for special purposes.
@@ -95,13 +68,13 @@
* and replaced/merged them with mbg_get_pc_cycles...() functions.
* Under Linux use own inline function to read TSC on x86 architectures.
* Normally USB timeouts are short with retries in order to increase
- * responsiveness. On some systems this may lead to problems, so
+ * responsiveness. On some systems this may lead to problems, so
* optionally one long timeout can be used now by define.
* Revision 1.34 2008/12/16 14:40:47 martin
* Account for new devices PTP270PEX, FRC270PEX, TCR170PEX, and WWVB51USB.
- * Added macros _pcps_ddev_is_ptp(), _pcps_ddev_is_frc(),
+ * Added macros _pcps_ddev_is_ptp(), _pcps_ddev_is_frc(),
* and _pcps_ddev_is_wwvb().
- * Don't use pragma pack( 1 ) but use native alignment since structures
+ * Don't use pragma pack( 1 ) but use native alignment since structures
* defined here are not used across system boundaries.
* Added fields to PCPS_DDEV to store the ASIC version, and macros
* _pcps_ddev_raw_asic_version() and _pcps_ddev_asic_version().
@@ -151,11 +124,11 @@
* Added macro _pcps_ddev_status_busy().
* Added kernel malloc/free macros and USB I/O macros.
* Use PCPS_DDEV as private device data.
- * Use ms values for USB timeouts also under Linux. This may not be
+ * Use ms values for USB timeouts also under Linux. This may not be
* appropriate for older kernels.
* Limited length of some older RCS log messages.
* Revision 1.30 2007/07/25 14:22:23Z martin
- * Under Linux include param.h for definition of HZ under
+ * Under Linux include param.h for definition of HZ under
* kernels 2.6.21 and newer.
* Revision 1.29 2007/07/17 08:22:48 martin
* Added support for TCR511PEX and GPS170PEX.
@@ -171,7 +144,7 @@
* Preliminary support for *BSD.
* Preliminary support for USB.
* Revision 1.26 2006/07/07 09:44:23 martin
- * Fixed definition of control macros for the case where
+ * Fixed definition of control macros for the case where
* _PCPS_USE_PCI_PNP is overridden from the command line.
* Revision 1.25 2006/06/19 15:31:09 martin
* Added support for TCR511PCI.
@@ -193,8 +166,8 @@
* Revision 1.19 2004/10/14 15:01:24Z martin
* Added support for TCR167PCI.
* Revision 1.18 2004/09/06 15:11:04Z martin
- * Support a GPS_DATA interface where sizes are specified
- * by 16 instead of the original 8 bit quantities, thus allowing
+ * 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.
* Revision 1.17 2004/04/14 10:29:45Z martin
* Pack structures 1 byte aligned.
@@ -231,7 +204,7 @@
* New macro _pcps_ddev_has_mod().
* Revision 1.8 2002/02/26 09:34:03 MARTIN
* Removed macro _pcps_read_sernum() which was replaced
- * by a function pcps_read_sernum() which reads the S/N from
+ * by a function pcps_read_sernum() which reads the S/N from
* any clock that supports a S/N.
* Updated function prototypes.
* Revision 1.7 2002/02/19 09:28:01 MARTIN
@@ -242,12 +215,12 @@
* to follow naming conventions.
* Source code cleanup.
* Revision 1.5 2001/11/30 09:52:48 martin
- * Added support for event_time which, however, requires
+ * Added support for event_time which, however, requires
* a custom GPS firmware.
* Revision 1.4 2001/10/16 10:15:44 MARTIN
- * New Macro _pcps_ddev_has_serial_hs() which determines
+ * New Macro _pcps_ddev_has_serial_hs() which determines
* whether DCF77 clock supports baud rate higher than default.
- * Added some macros and comments corresponding to
+ * Added some macros and comments corresponding to
* pcpsdev.h.
* Revision 1.3 2001/09/18 06:53:57 MARTIN
* Two sets of preprocessor symbols for Win9x/ME and WinNT/2k.
@@ -273,7 +246,9 @@
#define DEBUG_LVL_IO 12
+/* Other headers to be included */
#include <mbg_tgt.h>
+#include <xdevfeat.h>
#if defined( MBG_TGT_NETWARE )
#define _DEFAULT_PCPS_USE_CLOCK_TICK 1
@@ -399,10 +374,17 @@
#define _MBG_INIT_CODE_ATTR
#endif
+#if !defined( DEBUG_USB_IO )
+ #if ( 0 && defined( DEBUG ) && defined( MBG_TGT_LINUX ) )
+ #define DEBUG_USB_IO 1
+ #else
+ #define DEBUG_USB_IO 0
+ #endif
+#endif
-/* Other headers to be included */
#include <pcpsdev.h>
+#include <cfg_hlp.h>
#include <mbgmutex.h>
#include <pci_asic.h>
#include <mbgerror.h>
@@ -410,7 +392,6 @@
#include <mbggenio.h>
#if defined( MBG_TGT_FREEBSD )
- #include <mbg_bsd.h>
#include <sys/malloc.h>
#include <sys/_null.h>
#include <sys/param.h>
@@ -432,6 +413,8 @@
#endif
#if defined( MBG_TGT_LINUX )
+ #include <linux/slab.h> // for kmalloc()/kfree()
+
#if _PCPS_USE_USB
#include <linux/usb.h>
#endif
@@ -486,16 +469,47 @@
extern "C" {
#endif
+#define _DEFAULT_PCPS_USE_MM_IO ( MBG_TGT_SUPP_MEM_ACC && !MBG_USE_MM_IO_FOR_PCI )
+
+#if !defined( _PCPS_USE_MM_IO )
+ #define _PCPS_USE_MM_IO _DEFAULT_PCPS_USE_MM_IO
+#endif
+
+#if _PCPS_USE_MM_IO
+
+ #define _mbg_inp32_ex( _d, _i, _p, _r ) \
+ ( (_d)->use_mm_io ? \
+ (_d)->mm_addr->mbgpex.asic.control_status.ul : \
+ _mbg_inp32( (_d), (_i), (_p) ) \
+ )
+
+ #define _mbg_outp32_ex( _d, _i, _p, _r, _v ) \
+ do \
+ { \
+ if ( (_d)->use_mm_io ) \
+ (_d)->mm_addr->mbgpex.asic.control_status.ul = (_v); \
+ else \
+ _mbg_outp32( _d, _i, _p, _v ); \
+ } while ( 0 )
+
+#else
+
+ #define _mbg_inp32_ex( _d, _i, _p, _r ) _mbg_inp32( _d, _i, _p )
+ #define _mbg_outp32_ex( _d, _i, _p, _r, _v ) _mbg_outp32( _d, _i, _p, _v )
+
+#endif
+
+
+
// Define some OS-specific primitives to alloc / free memory and handle
// mutexes and spinlocks in kernel space.
#if defined( MBG_TGT_LINUX )
- #define _pcps_kmalloc( _sz ) kmalloc( _sz, GFP_ATOMIC )
- #define _pcps_kfree( _p, _sz ) kfree( _p )
+ #define _pcps_kmalloc( _sz ) kmalloc( _sz, GFP_ATOMIC )
+ #define _pcps_kfree( _p, _sz ) kfree( _p )
- //##+++++++++++++++++++
- // The special versions of _pcps_sem_inc() and _pcps_sem_dec() below
+ // These special versions of _pcps_sem_inc() and _pcps_sem_dec()
// are only required to prevent interference with the IRQ handler
// under Linux which implements the serial port emulation for the
// NTP parse driver.
@@ -522,20 +536,31 @@ extern "C" {
// See "man 9 malloc" for details.
MALLOC_DECLARE( M_MBGCLOCK );
- #define _pcps_kmalloc( _sz ) malloc( _sz, M_MBGCLOCK, M_NOWAIT | M_ZERO )
- #define _pcps_kfree( _p, _sv ) free( _p, M_MBGCLOCK )
+ #define _pcps_kmalloc( _sz ) malloc( _sz, M_MBGCLOCK, M_NOWAIT | M_ZERO )
+ #define _pcps_kfree( _p, _sv ) free( _p, M_MBGCLOCK )
#elif defined( MBG_TGT_NETBSD )
// For older NetBSD versions which do not suppport the calls
// used below, see 'man 9 malloc'.
- #define _pcps_kmalloc( _sz ) kmem_alloc( _sz, KM_NOSLEEP )
- #define _pcps_kfree( _p, _sz ) kmem_free( _p, _sz )
+ #define _pcps_kmalloc( _sz ) kmem_alloc( _sz, KM_NOSLEEP )
+ #define _pcps_kfree( _p, _sz ) kmem_free( _p, _sz )
#elif defined( MBG_TGT_WIN32 )
- #define _pcps_kmalloc( _sz ) ExAllocatePool( NonPagedPool, _sz )
- #define _pcps_kfree( _p, _sz ) ExFreePool( _p )
+ #define _pcps_kmalloc( _sz ) ExAllocatePool( NonPagedPool, _sz )
+ #define _pcps_kfree( _p, _sz ) ExFreePool( _p )
+
+#elif defined( MBG_TGT_DOS )
+
+ // No multitasking, no device driver,
+ // so we don't need this.
+
+ #define _pcps_sem_inc( _pddev ) \
+ _nop_macro_fnc()
+
+ #define _pcps_sem_dec( _pddev ) \
+ _nop_macro_fnc()
#endif
@@ -550,7 +575,7 @@ extern "C" {
-// If the macros below have not yet been defined then define some dummies:
+// If these macros have not yet been defined then define some dummies:
#if !defined( _pcps_sem_inc ) || !defined( _pcps_sem_dec )
@@ -564,9 +589,7 @@ extern "C" {
-/* ------ definitions used with PCI clocks -------------------------- */
-
-/* Default timeout count accessing the board */
+// Default timeout count when accessing a device
#if _PCPS_USE_CLOCK_TICK
#if defined( MBG_TGT_NETWARE )
@@ -587,10 +610,10 @@ extern "C" {
#endif
-// The structures below are used to provide a consistent
+// These structures are used to provide a consistent
// resource handling across different platforms.
-// This is kept completely inside the kernel drivers, so these
-// structures can be modified safely to suit our needs.
+// This is kept completely inside the kernel drivers, so the
+// structures can be modified safely, as appropriate.
#if MBG_USE_MM_IO_FOR_PCI
@@ -610,7 +633,11 @@ extern "C" {
#else
- typedef PCPS_PORT_ADDR PCPS_IO_ADDR_RAW;
+ #if !defined( MBG_TGT_POSIX ) || defined( MBG_ARCH_X86 )
+ typedef uint16_t PCPS_IO_ADDR_RAW; ///< ### TODO ::PCPS_PORT_ADDR_X
+ #else
+ typedef uint64_t PCPS_IO_ADDR_RAW;
+ #endif
typedef PCPS_IO_ADDR_RAW PCPS_IO_ADDR_MAPPED;
#if defined( MBG_TGT_BSD )
@@ -628,19 +655,19 @@ extern "C" {
typedef struct
{
-#if defined ( MBG_TGT_FREEBSD )
+#if defined( MBG_TGT_FREEBSD )
int rid; /* resource ID */
- struct resource *res;
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
-#elif defined ( MBG_TGT_NETBSD )
- int reg; /* BAR */
- int type; /* type */
- int valid; /* valid flag */
- bus_space_tag_t bst; /* bus space tag */
- bus_space_handle_t bsh; /* bus space handle */
- bus_addr_t base; /* base address */
- bus_size_t size; /* size */
+ struct resource *res; ///< Resource information
+ bus_space_tag_t bst; ///< Bus space tag
+ bus_space_handle_t bsh; ///< Bus space handle
+#elif defined( MBG_TGT_NETBSD )
+ int reg; ///< Base Address Register (BAR)
+ int type; ///< Type
+ int valid; ///< Valid flag
+ bus_space_tag_t bst; ///< Bus space tag
+ bus_space_handle_t bsh; ///< Bus space handle
+ bus_addr_t base; ///< Base address
+ bus_size_t size; ///< Size
#endif
} BSD_RSRC_INFO;
@@ -649,27 +676,33 @@ typedef struct
/**
- The structure below describes an I/O port resource
- used by a clock.
-*/
+ * @brief I/O port resource information for a device
+ *
+ * @see ::PCPS_MEM_RSRC
+ * @see ::PCPS_IRQ_RSRC
+ */
typedef struct
{
#if defined( MBG_TGT_BSD )
- BSD_RSRC_INFO bsd;
+ BSD_RSRC_INFO bsd; ///< *BSD-specific stuff
#endif
- PCPS_IO_ADDR_MAPPED base_mapped;
- PCPS_IO_ADDR_RAW base_raw;
- uint16_t num;
-} PCPS_IO_RSRC;
+ PCPS_IO_ADDR_MAPPED base_mapped; ///< A mapped port base address
+ PCPS_IO_ADDR_RAW base_raw; ///< A raw port base address
+ ulong num; ///< Number of addresses in this range
+} PCPS_IO_RSRC;
-// The structure below describes a bus memory resource
-// used by a clock.
+/**
+ * @brief Bus memory resource information for a device
+ *
+ * @see ::PCPS_IO_RSRC
+ * @see ::PCPS_IRQ_RSRC
+ */
typedef struct
{
#if defined( MBG_TGT_BSD )
- BSD_RSRC_INFO bsd;
+ BSD_RSRC_INFO bsd; ///< *BSD-specific stuff
#endif
MBG_MEM_ADDR start;
ulong len;
@@ -677,84 +710,104 @@ typedef struct
} PCPS_MEM_RSRC;
-
-// The structure below describes a bus IRQ resource
-// used by a clock.
-
+/**
+ * @brief IRQ resource information for a device
+ *
+ * @see ::PCPS_IO_RSRC
+ * @see ::PCPS_MEM_RSRC
+ */
typedef struct
{
#if defined( MBG_TGT_BSD )
- BSD_RSRC_INFO bsd;
+ BSD_RSRC_INFO bsd; ///< *BSD-specific stuff
#endif
- ushort num;
+ uint16_t num; ///< The IRQ number
} PCPS_IRQ_RSRC;
-// The max number of bus memory resources used by a device.
+/**
+ * @brief The max number of bus memory resources used by a device.
+ */
#define N_PCPS_MEM_RSRC 2
-// The max number of bus memory and I/O resources used by a device.
+
+/**
+ * @brief The max number of bus memory and I/O resources used by a device.
+ */
#define MAX_PCPS_RSRC ( N_PCPS_MEM_RSRC + N_PCPS_PORT_RSRC )
+
+/**
+ * @brief Resource info summary for a device
+ */
typedef struct
{
- int num_rsrc_io;
- int num_rsrc_mem;
- int num_rsrc_irq;
- PCPS_IO_RSRC port[N_PCPS_PORT_RSRC];
- PCPS_MEM_RSRC mem[N_PCPS_MEM_RSRC];
- PCPS_IRQ_RSRC irq;
+ int num_rsrc_io; ///< Number of actually assigned I/O address ranges
+ int num_rsrc_mem; ///< Number of actually assigned memory address ranges
+ int num_rsrc_irq; ///< Number of actually assigned IRQ numbers
+ PCPS_IO_RSRC port[N_PCPS_PORT_RSRC]; ///< Info on actually assigned port ranges
+ PCPS_MEM_RSRC mem[N_PCPS_MEM_RSRC]; ///< Info on actually assigned memory ranges
+ PCPS_IRQ_RSRC irq; ///< Info on actually assigned IRQ numbers
+
} PCPS_RSRC_INFO;
#if _PCPS_USE_USB
- typedef struct
- {
- uint8_t addr;
- uint16_t max_packet_size;
- } PCPS_USB_EP;
+/**
+ * @brief Information on a USB endpoint
+ */
+typedef struct
+{
+ uint8_t addr;
+ uint16_t max_packet_size;
+} PCPS_USB_EP;
- #if defined( MBG_TGT_LINUX )
- // definitions used to control the cyclic USB read thread
+#if defined( MBG_TGT_LINUX )
+
+ // definitions used to control the cyclic USB read thread
- #if _PCPS_USE_LINUX_KTHREAD
+ #if _PCPS_USE_LINUX_KTHREAD
- // use kthread_run() / kthread_stop()
- typedef struct task_struct *PCPS_THREAD_INFO;
+ // Used by kthread_run() / kthread_stop()
+ typedef struct task_struct *PCPS_THREAD_INFO;
- #else
+ #else
+
+ // Used by kernel_thread() / daemonize() / kill_proc()
+ typedef struct
+ {
+ pid_t pid;
+ char name[17]; // 16 chars as supported by the kernel, plus trailing 0
+ struct completion exit;
- // use kernel_thread() / daemonize() / kill_proc()
- typedef struct
- {
- pid_t pid;
- char name[17]; // 16 chars as supported by the kernel, plus trailing 0
- struct completion exit;
- } PCPS_THREAD_INFO;
+ } PCPS_THREAD_INFO;
- #endif // _PCPS_USE_LINUX_KTHREAD
+ #endif // _PCPS_USE_LINUX_KTHREAD
- #endif // defined( MBG_TGT_LINUX )
+#endif // defined( MBG_TGT_LINUX )
#endif // _PCPS_USE_USB
+/**
+ * @brief Memory layout of Meinberg PCI interface register
+ */
typedef union
{
- struct
+ struct pex8311
{
PCI_ASIC asic;
PCPS_TIME_STAMP tstamp;
} pex8311;
- struct
+ struct mbgpex
{
PCI_ASIC asic;
uint8_t b[256 - sizeof( PCI_ASIC ) ];
@@ -765,100 +818,102 @@ typedef union
} PCPS_MM_LAYOUT;
+
struct PCPS_DDEV_s;
+typedef struct PCPS_DDEV_s PCPS_DDEV;
-typedef short (*PCPS_READ_FNC)( struct PCPS_DDEV_s *pddev, uint8_t cmd, void FAR *buffer, uint16_t count );
-typedef short (*PCPS_WRITE_FNC)( struct PCPS_DDEV_s *pddev, uint8_t cmd, const void FAR *buffer, uint16_t count );
-typedef struct PCPS_DDEV_s *(*PCPS_DDEV_ALLOC_FNC)( void );
-typedef void (*PCPS_DDEV_CLEANUP_FNC)( struct PCPS_DDEV_s * );
-typedef int (*PCPS_DDEV_REGISTER_FNC)( struct PCPS_DDEV_s * );
+typedef int PCPS_READ_FNC( PCPS_DDEV *pddev, uint8_t cmd, void FAR *buffer, uint16_t count );
+typedef int PCPS_WRITE_FNC( PCPS_DDEV *pddev, uint8_t cmd, const void FAR *buffer, uint16_t count );
+typedef PCPS_DDEV *PCPS_DDEV_ALLOC_FNC( void );
+typedef void PCPS_DDEV_CLEANUP_FNC( PCPS_DDEV *pddev );
+typedef int PCPS_DDEV_REGISTER_FNC( PCPS_DDEV *pddev );
-typedef struct PCPS_DDEV_s
+struct PCPS_DDEV_s
{
- // the device info data
- PCPS_DEV dev;
+ PCPS_DEV dev; ///< Device info data that can be passed to user space
- PCPS_READ_FNC read;
+ PCPS_READ_FNC *read; ///< Pointer to the read function depending on the PCI interface type
- PCPS_IO_ADDR_MAPPED status_port;
- PCPS_IO_ADDR_MAPPED irq_enb_disb_port;
- PCPS_IO_ADDR_MAPPED irq_flag_port;
- PCPS_IO_ADDR_MAPPED irq_ack_port;
- uint32_t irq_enb_mask;
- uint32_t irq_disb_mask;
- uint32_t irq_flag_mask;
- uint32_t irq_ack_mask;
+ PCPS_IO_ADDR_MAPPED status_port; ///< Address of the status port register
+ PCPS_IO_ADDR_MAPPED irq_enb_disb_port; ///< Address of the IRQ control register
+ PCPS_IO_ADDR_MAPPED irq_flag_port; ///< Address of the IRQ status register
+ PCPS_IO_ADDR_MAPPED irq_ack_port; ///< Address of the register to acknowledge an IRQ
+ uint32_t irq_enb_mask; ///< Bit mask to be set to enable IRQs
+ uint32_t irq_disb_mask; ///< Bit mask to be cleared to disable IRQs
+ uint32_t irq_flag_mask; ///< Bit mask used to check if device has generated an IRQ
+ uint32_t irq_ack_mask; ///< Bit mask to be set to acknowledge an IRQ
- PCI_ASIC_VERSION raw_asic_version;
- PCI_ASIC_VERSION asic_version;
- PCI_ASIC_FEATURES asic_features;
- PCPS_RSRC_INFO rsrc_info;
+ PCI_ASIC_VERSION raw_asic_version; ///< Raw ASIC version
+ PCI_ASIC_VERSION asic_version; ///< ASIC version
+ PCI_ASIC_FEATURES asic_features; ///< ASIC feature mask
+ PCPS_RSRC_INFO rsrc_info; ///< Summary of resources used by the device
- MBG_PC_CYCLES acc_cycles;
+ MBG_PC_CYCLES acc_cycles; ///< Cycles count taken when device was accessed last time
#if defined( _MBG_MUTEX_DEFINED )
- MBG_MUTEX dev_mutex;
+ MBG_MUTEX dev_mutex; ///< Mutex used for device access serialization
#endif
- PCPS_MM_LAYOUT FAR *mm_addr;
- volatile PCPS_TIME_STAMP FAR *mm_tstamp_addr;
+ PCPS_MM_LAYOUT FAR *mm_addr; ///< Base address of the memory-mapped register block
+ volatile PCPS_TIME_STAMP FAR *mm_tstamp_addr; ///< Memory mapped address of the timestamp register
#if defined( _MBG_SPINLOCK_DEFINED )
- MBG_SPINLOCK mm_lock;
- MBG_SPINLOCK irq_lock;
+ MBG_SPINLOCK mm_lock; ///< Spinlock used to protect memory mapped access
+ MBG_SPINLOCK irq_lock; ///< Spinlock used to protect access to data updated by IRQ handler
#endif
- // The flag below holds IRQ information, e.g. whether the device's
- // IRQ is possibly unsafe, and whether IRQ has been enabled on the device.
+ /// IRQ status information, e.g. whether the device's IRQ is
+ /// possibly unsafe, and whether IRQ has been enabled on the device.
PCPS_IRQ_STAT_INFO irq_stat_info;
- RECEIVER_INFO ri;
+ BUILTIN_FEATURE_MASK builtin_features; ///< Mask of builtin features, depending on device type
+ MBG_XDEV_FEATURES xdev_features; ///< Receiver info plus extended device features
+
+ #if _PCPS_USE_MM_IO
+ int use_mm_io; ///< Flag indicating if memory mapped I/O is being used
+ #endif
#if _PCPS_USE_USB
- int n_usb_ep; // number of endpoints supp. by the device
- PCPS_USB_EP ep[MBGUSB_MAX_ENDPOINTS];
- uint8_t usb_20_mode;
+ int n_usb_ep; ///< Number of USB endpoints supported by the device
+ PCPS_USB_EP ep[MBGUSB_MAX_ENDPOINTS]; ///< Array of actual USB endpoints
+ bool usb_20_mode; ///< Flag indicating if USB 2.0 microframing is supported
#endif
#if defined( MBG_TGT_WIN32 )
- _pcps_ddev_data_win
+ _pcps_ddev_data_win ///< Some windows-specific stuff
#endif
#if defined( MBG_TGT_LINUX )
- atomic_t connected;
- atomic_t access_in_progress;
- atomic_t data_avail;
- unsigned long jiffies_at_irq;
- struct fasync_struct *fasyncptr;
- PCPS_TIME t;
+ atomic_t connected; ///< Flag indicating if the device is "connected"
+ atomic_t access_in_progress; ///< Flag indicating if device access is currently in progress
+ atomic_t data_avail; ///< Flag indicating if data has been made available by IRQ handler
+ unsigned long jiffies_at_irq; ///< Set by IRQ handler, used to check if cyclic IRQs still occur
+ struct fasync_struct *fasyncptr; ///< Used for asynchronous signalling when data is available
+ PCPS_TIME t; ///< Date and time read by IRQ handler
#if NEW_WAIT_QUEUE
- wait_queue_head_t wait_queue;
+ wait_queue_head_t wait_queue; ///< Used for asynchronous I/O (newer kernel API)
#else
- struct wait_queue *wait_queue;
+ struct wait_queue *wait_queue; ///< Used for asynchronous I/O (older kernel API)
#endif
- dev_t lx_dev;
- atomic_t open_count;
+ atomic_t open_count; ///< Number of processes that have opened this device
- #if _PCPS_USE_LINUX_CHRDEV
- struct cdev cdev;
- #elif _PCPS_USE_LINUX_MISC_DEV
- struct miscdevice mdev;
- #endif
+ struct cdev cdev; ///< Linux device class
+ dev_t lx_dev; ///< Linux device associated with this device
#if _PCPS_USE_USB
- struct usb_device *udev;
- struct usb_interface *intf;
- PCPS_THREAD_INFO usb_read_thread;
- struct semaphore sem_usb_cyclic;
+ struct usb_device *udev; ///< Linux USB device associated with this device
+ struct usb_interface *intf; ///< Linux USB interface associated with this device
+ PCPS_THREAD_INFO usb_read_thread; ///< Kernel thread to receive cyclic USB messages
+ struct semaphore sem_usb_cyclic; ///< Semaphore used for cyclic USB messages
#endif
#endif
#if defined( MBG_TGT_BSD )
- int connected;
- int open_count;
+ int connected; ///< BSD flag indicating if the device is "connected"
+ int open_count; ///< BSD number of processes that have opened this device
#endif
#if _PCPS_USE_RSRCMGR
@@ -867,64 +922,83 @@ typedef struct PCPS_DDEV_s
RSRC_LIST rsrc;
#endif
#endif
-
-} PCPS_DDEV;
+};
-/* The PCI vendor ID and device ID numbers are used to detect a
- * PCI clock in a system and query which resources have been
- * assigned by the BIOS.
- * (PCI vendor ID and PCI device IDs are defined in PCPSDEFS.H)
+/**
+ * @brief The number of address lines decoded by a PCI clock
*/
-
-/* the number of address lines decoded by a PCI clock */
#define PCPS_DECODE_WIDTH_PCI 16
/* ------ definitions used with MCA clocks -------------------------- */
-/* The MCA adapter ID number is used to detect a MCA clock in a
+/*
+ * The MCA adapter ID number is used to detect a MCA clock in a
* system and query which resources have been assigned by the
* system's POS (programmable option select).
*/
-/* MCA Adapter ID numbers */
-#define MCA_ID_PS31 0x6AAC /* assigned by IBM */
-#define MCA_ID_PS31_OLD 0x6303 /* assigned by Meinberg, used with */
- /* the first series of PS31 boards */
+#define MCA_ID_PS31 0x6AAC ///< MCA adapter ID assigned by IBM
+#define MCA_ID_PS31_OLD 0x6303 ///< MCA adapter ID assigned by Meinberg, used with the first series of PS31 boards
-/* the total number of ports acquired by a MCA clock */
+/**
+ * @brief The total number of ports acquired by an MCA device
+ */
#define PCPS_NUM_PORTS_MCA 16
-/* the number of address lines decoded by a MCA clock */
+/**
+ * @brief The number of address lines decoded by an MCA device
+ */
#define PCPS_DECODE_WIDTH_MCA 16
/* ------ definitions used with ISA clocks -------------------------- */
-/* A board ID for the newer clocks with ISA bus. The number can
- * be read at port_base+2 (low byte) and port_base+3 (high byte)
- * of ISA clocks. This ID number matches the MCA adapter ID
- * defined above and is not available on PC31 clocks.
+/**
+ * @brief A board ID for later ISA bus devices
+ *
+ * The number can be read at port_base + 2 (low byte), and
+ * port_base + 3 (high byte) of ISA devices. This ID number
+ * matches the MCA adapter ID ::MCA_ID_PS31 and is not
+ * provided by PC31 devices.
*/
#define ISA_ID_PCPS MCA_ID_PS31
-/* The default port base address for ISA clocks.
- * Some programs assume a default port for an ISA clock,
- * others do not but require a cmd line parameter.
+
+/**
+ * @brief The default port base address for ISA bus devices
+ *
+ * Some programs assume a default port for an ISA default,
+ * but others do not but require a cmd line parameter.
*/
#define PCPS_DEFAULT_PORT 0x0300
-/* the total number of ports acquired by a ISA clock */
+
+/**
+ * @brief The total number of I/O ports used by an ISA bus device
+ */
#define PCPS_NUM_PORTS_ISA 4
-/* the number of address lines decoded by a ISA clock */
+
+/**
+ * @brief The number of address lines decoded by an ISA bus device
+ */
#define PCPS_DECODE_WIDTH_ISA 10
/* ------ common definitions -------------------------- */
+#if defined( DEBUG )
+ _ext int debug
+ #ifdef _DO_INIT
+ = DEBUG
+ #endif
+ ;
+#endif
+
+
_ext PCPS_DEV_TYPE pcps_dev_type[N_PCPS_DEV_TYPE]
#ifdef _DO_INIT
= { // attention, the name is limited to PCPS_CLOCK_NAME_SZ, including terminating 0
@@ -960,32 +1034,32 @@ _ext PCPS_DEV_TYPE pcps_dev_type[N_PCPS_DEV_TYPE]
{ PCPS_TYPE_PZF180PEX, "PZF180PEX", PCI_DEV_PZF180PEX, PCPS_REF_DCF, PCPS_BUS_PCI_MBGPEX },
{ PCPS_TYPE_TCR600USB, "TCR600USB", USB_DEV_TCR600USB, PCPS_REF_IRIG, PCPS_BUS_USB_V2 },
{ PCPS_TYPE_MSF600USB, "MSF600USB", USB_DEV_MSF600USB, PCPS_REF_MSF, PCPS_BUS_USB_V2 },
- { PCPS_TYPE_WVB600USB, "WVB600USB", USB_DEV_WVB600USB, PCPS_REF_WWVB, PCPS_BUS_USB_V2 }
+ { PCPS_TYPE_WVB600USB, "WVB600USB", USB_DEV_WVB600USB, PCPS_REF_WWVB, PCPS_BUS_USB_V2 },
+ { PCPS_TYPE_GLN180PEX, "GLN180PEX", PCI_DEV_GLN180PEX, PCPS_REF_GPS, PCPS_BUS_PCI_MBGPEX },
+ { PCPS_TYPE_GPS180AMC, "GPS180AMC", PCI_DEV_GPS180AMC, PCPS_REF_GPS, PCPS_BUS_PCI_MBGPEX },
+ { PCPS_TYPE_GNS181PEX, "GNS181PEX", PCI_DEV_GNS181PEX, PCPS_REF_GPS, PCPS_BUS_PCI_MBGPEX }
// If a new device is added here, don't forget to add it also
- // to the Windows .inf file of supported PCI an USB devices,
- // and in case of USB to the Linux driver file mbgdrvr.c.
+ // to the Windows .inf file of supported PCI and USB devices,
+ // and in case of USB to the table mbgclock_usb_tbl of the Linux
+ // driver file mbgclock_main.c.
}
#endif
;
-#if !defined( PCPS_MAX_DDEVS )
- #define PCPS_MAX_DDEVS 4
-#endif
-
#if !defined( PCPS_MAX_ISA_CARDS )
- #define PCPS_MAX_ISA_CARDS PCPS_MAX_DDEVS // the number of ISA cards supported
+ #define PCPS_MAX_ISA_CARDS N_SUPP_DEV_BUS // the number of ISA cards supported
#endif
_ext int pcps_isa_ports[PCPS_MAX_ISA_CARDS + 1];
#if _PCPS_STATIC_DEV_LIST
- _ext PCPS_DDEV pcps_ddev[PCPS_MAX_DDEVS];
+ _ext PCPS_DDEV pcps_ddev[N_SUPP_DEV_BUS];
_ext int n_ddevs;
#endif
-#if defined( MBG_TGT_DOS ) || defined( MBG_TGT_NETWARE ) //##++
+#if defined( MBG_TGT_DOS ) || defined( MBG_TGT_NETWARE ) //##++
_ext int curr_ddev_num;
_ext PCPS_DDEV *curr_ddev
#ifdef _DO_INIT
@@ -994,14 +1068,16 @@ _ext int pcps_isa_ports[PCPS_MAX_ISA_CARDS + 1];
;
#endif
-/* the first characters of a valid EPROM ID */
+/**
+ * @brief The first characters of a valid firmware ID
+ */
_ext const char *fw_id_ref[]
#ifdef _DO_INIT
= {
"PC3", // PC31, PS31, PC32
"PCI", // PCI32, PCI509, PCI510, PCI511
- "GPS", // GPS167PC, GPS167PCI, GPS168PCI, GPS169PCI, GPS170PCI, GPS170PEX, GPS180PEX
+ "GPS", // GPS167PC, GPS167PCI, GPS168PCI, GPS169PCI, GPS170PCI, GPS170PEX, GPS180PEX, GPS180AMC
"TCR", // TCR510PCI, TCR167PCI, TCR511PCI, TCR511PEX, TCR51USB, TCR170PEX, TCR180PEX
"PEX", // PEX511
"USB", // USB5131
@@ -1009,20 +1085,25 @@ _ext const char *fw_id_ref[]
"WWVB", // WWVB51USB, WVB600USB
"DCF", // DCF600USB
"PZF", // PZF180PEX
+ "GLN", // GLN180PEX
+ "GNS", // GNS181PEX
NULL
}
#endif
;
-// The macros below are used to distinguish ISA cards:
-
+// These macros are used to distinguish ISA cards:
#define fw_id_ref_pcps fw_id_ref[0]
#define fw_id_ref_gps fw_id_ref[2]
+#if _PCPS_USE_MM_IO
+ _ext int force_io_access;
+#endif
-// The macros below accept a (PCPS_DDEV *) for easy access
+
+// These macros accept a (PCPS_DDEV *) for easy access
// to the information stored in PCPS_DDEV structures.
// Access device type information:
@@ -1033,6 +1114,7 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_bus_flags( _p ) _pcps_bus_flags( &(_p)->dev )
// Query device type features:
+
#define _pcps_ddev_is_gps( _p ) _pcps_is_gps( &(_p)->dev )
#define _pcps_ddev_is_dcf( _p ) _pcps_is_dcf( &(_p)->dev )
#define _pcps_ddev_is_msf( _p ) _pcps_is_msf( &(_p)->dev )
@@ -1042,6 +1124,8 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_is_frc( _p ) _pcps_is_frc( &(_p)->dev )
#define _pcps_ddev_is_lwr( _p ) _pcps_is_lwr( &(_p)->dev )
+#define _pcps_ddev_is_gnss( _p ) _pcps_is_gnss( &(_p)->dev )
+
// Generic bus types:
#define _pcps_ddev_is_isa( _p ) _pcps_is_isa( &(_p)->dev )
@@ -1063,12 +1147,14 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_bus_num( _p ) _pcps_bus_num( &(_p)->dev )
#define _pcps_ddev_slot_num( _p ) _pcps_slot_num( &(_p)->dev )
-#define _pcps_ddev_port_rsrc( _p, _n ) _pcps_port_rsrc( &(_p)->dev, _n )
-#define _pcps_ddev_port_base( _p, _n ) _pcps_port_base( &(_p)->dev, _n )
-#define _pcps_ddev_io_rsrc( _p, _n ) ( (_p)->rsrc_info.port[_n] )
-#define _pcps_ddev_io_base_mapped( _p, _n ) ( _pcps_ddev_io_rsrc( _p, _n ).base_mapped )
-#define _pcps_ddev_irq_num( _p ) _pcps_irq_num( &(_p)->dev )
-#define _pcps_ddev_timeout_clk( _p ) _pcps_timeout_clk( &(_p)->dev )
+#define _pcps_ddev_short_port_rsrc( _p, _n ) _pcps_short_port_rsrc( &(_p)->dev, _n )
+#define _pcps_ddev_short_port_base( _p, _n ) _pcps_short_port_base( &(_p)->dev, _n )
+
+#define _pcps_ddev_io_rsrc( _p, _n ) ( (_p)->rsrc_info.port[_n] )
+#define _pcps_ddev_io_base_raw( _p, _n ) ( _pcps_ddev_io_rsrc( _p, _n ).base_raw )
+#define _pcps_ddev_io_base_mapped( _p, _n ) ( _pcps_ddev_io_rsrc( _p, _n ).base_mapped )
+#define _pcps_ddev_irq_num( _p ) _pcps_irq_num( &(_p)->dev )
+#define _pcps_ddev_timeout_clk( _p ) _pcps_timeout_clk( &(_p)->dev )
#define _pcps_ddev_fw_rev_num( _p ) _pcps_fw_rev_num( &(_p)->dev )
#define _pcps_ddev_features( _p ) _pcps_features( &(_p)->dev )
@@ -1078,7 +1164,7 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_raw_asic_version( _p ) ( (_p)->raw_asic_version )
#define _pcps_ddev_asic_version( _p ) ( (_p)->asic_version )
-// The macros below handle the device's err_flags.
+// These macros handle the device's err_flags:
#define _pcps_ddev_chk_err_flags( _p, _msk ) \
_pcps_chk_err_flags( &(_p)->dev, _msk )
@@ -1089,9 +1175,7 @@ _ext const char *fw_id_ref[]
_pcps_clr_err_flags( &(_p)->dev, _msk )
-// Query whether a special feature is supported:
-#define _pcps_ddev_has_feature( _p, _f ) _pcps_has_feature( &(_p)->dev, _f )
-
+// Query whether a specific feature is supported:
#define _pcps_ddev_can_set_time( _p ) _pcps_can_set_time( &(_p)->dev )
#define _pcps_ddev_has_serial( _p ) _pcps_has_serial( &(_p)->dev )
#define _pcps_ddev_has_sync_time( _p ) _pcps_has_sync_time( &(_p)->dev )
@@ -1111,7 +1195,7 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_has_ucap( _p ) _pcps_has_ucap( &(_p)->dev )
#define _pcps_ddev_has_irig_tx( _p ) _pcps_has_irig_tx( &(_p)->dev )
-// The macro below determines whether a DCF77 clock
+// This macro determines whether a DCF77 clock
// supports a higher baud rate than standard
#define _pcps_ddev_has_serial_hs( _p ) \
_pcps_has_serial_hs( &(_p)->dev )
@@ -1175,7 +1259,7 @@ _ext const char *fw_id_ref[]
_pcps_has_ptp( &(_p)->dev )
#define _pcps_ddev_has_ptp_unicast( _p ) \
- _pcps_has_ri_ptp_unicast( &(_p)->ri )
+ _pcps_has_ri_ptp_unicast( _ri_addr( _p ) )
#define _pcps_ddev_has_pzf( _p ) \
_pcps_has_pzf( &(_p)->dev )
@@ -1186,14 +1270,35 @@ _ext const char *fw_id_ref[]
#define _pcps_ddev_has_tr_distance( _p ) \
_pcps_has_tr_distance( &(_p)->dev )
+#define _pcps_ddev_has_evt_log( _p ) \
+ _pcps_has_evt_log( &(_p)->dev )
+
+#define _pcps_ddev_has_debug_status( _p ) \
+ _pcps_has_debug_status( &(_p)->dev )
+
+#define _pcps_ddev_has_stat_info( _p ) \
+ _pcps_has_stat_info( &(_p)->dev )
+
+#define _pcps_ddev_has_stat_info_mode( _p ) \
+ _pcps_has_stat_info_mode( &(_p)->dev ) \
+
+#define _pcps_ddev_has_stat_info_svs( _p ) \
+ _pcps_has_stat_info_svs( &(_p)->dev ) \
+
#define _pcps_ddev_incoming_tfom_ignored( _p ) \
_pcps_incoming_tfom_ignored( &(_p)->dev )
#define _pcps_ddev_pci_cfg_err( _p ) \
_pcps_pci_cfg_err( &(_p)->dev )
+#define _pcps_ddev_has_gpio( _p ) \
+ _pcps_has_ri_gpio( _ri_addr( _p ) )
-// The macros below simplify read/write access to the clocks.
+#define _pcps_ddev_has_xmr( _p ) \
+ _pcps_has_ri_xmr( _ri_addr( _p ) )
+
+
+// These macros simplify read/write access to the clocks.
// Call the device's read function to write the command byte _cmd
// and read _n bytes to buffer _s.
@@ -1203,7 +1308,8 @@ _ext const char *fw_id_ref[]
#endif
// Write a byte _b to a device. This is typically done by just writing
-// the command byte from inside the read function.
+// the command byte from within the read function, without actually
+// reading any data bytes.
#if !defined( _pcps_write_byte )
#define _pcps_write_byte( _pddev, _b ) \
_pcps_read( (_pddev), (_b), NULL, 0 )
@@ -1217,21 +1323,22 @@ _ext const char *fw_id_ref[]
pcps_write( (_pddev), (_cmd), (uchar FAR *)(_p), (_n) )
#endif
-// Read data structures which exceed PCPS_FIFO_SIZE bytes.
-// This can't be handled in a single read cycle and due to limitations
-// of the clock's microprocessor these calls can up to 20 milliseconds.
-// Currently these function is only used to read GPS specific data
-// from GPS clocks.
+// Read data structures which exceed ::PCPS_FIFO_SIZE bytes.
+// This can't be handled in a single read cycle and due to
+// limitations of the device's microprocessor the execution time
+// can be up to 20 milliseconds, depending on the device type.
+// This has been introduced with the first GPS devices but is
+// now in fact also used with non-GPS devices.
#define _pcps_read_gps( _pddev, _cmd, _p, _n ) \
pcps_read_gps( (_pddev), (_cmd), (uchar FAR *) (_p), (_n) )
-// The write function opposite to the read function above.
+// The complementary write function for the read function above.
#define _pcps_write_gps( _pddev, _cmd, _p, _n ) \
pcps_write_gps( (_pddev), (_cmd), (uchar FAR *) (_p), (_n) )
-// The macros below simplify reading/writing typed variables by
+// These macros simplify reading/writing typed variables by
// determining the size automatically from the type of the variable.
// Read data from a device to variable _s.
@@ -1255,7 +1362,7 @@ _ext const char *fw_id_ref[]
#define _pcps_read_gps_var( _pddev, _cmd, _s ) \
_pcps_read_gps( (_pddev), (_cmd), &(_s), sizeof( (_s) ) )
-// The write function opposite to the read function above.
+// The complementary write function for the read function above.
#define _pcps_write_gps_var( _pddev, _cmd, _s ) \
_pcps_write_gps( (_pddev), (_cmd), &(_s), sizeof( (_s) ) )
@@ -1267,18 +1374,32 @@ _ext const char *fw_id_ref[]
_pcps_write_byte( (_pddev), PCPS_FORCE_RESET )
-// The macro below reads a device's status port which includes
-// the BUSY flag and the modulation signal of DCF77 receivers.
+// This macro reads a device's status port which includes
+// the BUSY flag (::PCPS_ST_BUSY )and the modulation signal
+// of DCF77 and other long wave receivers.
// The macro takes a (PCPS_DDEV *) as argument.
-#define _pcps_ddev_read_status_port( _d ) \
- _mbg_inp8( (_d), 0, (_d)->status_port )
+#if _PCPS_USE_MM_IO
+
+ #define _pcps_ddev_read_status_port( _d ) \
+ ( (_d)->use_mm_io ? \
+ (uint8_t) (_d)->mm_addr->mbgpex.asic.status_port.ul : \
+ _mbg_inp8( (_d), 0, (_d)->status_port ) \
+ )
+
+#else
+
+ #define _pcps_ddev_read_status_port( _d ) \
+ _mbg_inp8( (_d), 0, (_d)->status_port )
+
+#endif
+
#define _pcps_ddev_status_busy( _d ) \
( _pcps_ddev_read_status_port( pddev ) & PCPS_ST_BUSY )
-// The macro below checks whether a workaround is required to get/set
-// IRIG cfg from a GPS169PCI with IRIG output and early firmware version
+// This macro checks whether a workaround is required to get/set
+// IRIG cfg from a GPS169PCI with IRIG output and early firmware version.
// This is handled in mbgdevio.c for direct access environments, and in
// macioctl.h for kernel device drivers.
#define _pcps_ddev_requires_irig_workaround( _d ) \
@@ -1352,19 +1473,31 @@ _ext const char *fw_id_ref[]
_pcps_usb_read_ep_tmo( _d, _p, _sz, MBGUSB_EP_IDX_HOST_IN_CYCLIC, MBGUSB_TIMEOUT_RECEIVE_CYCLIC, _irp )
#define _pcps_usb_read_var_cyclic( _d, _p, _irp ) \
- _pcps_usb_read_cyclic( _d, _p, sizeof( *(_p) ), _irp )
+ _pcps_usb_read_cyclic( _d, _p, sizeof( *(_p) ), _irp )
#elif defined( MBG_TGT_LINUX )
- #define _pcps_usb_write_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
- usb_bulk_msg( (_d)->udev, \
- usb_sndbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
- _p, _sz, &actual_count, _tmo )
+ #if DEBUG_USB_IO
+ #define _pcps_usb_write_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
+ usb_bulk_msg_dbg( (_d)->udev, \
+ usb_sndbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
+ _p, _sz, &actual_count, _tmo )
- #define _pcps_usb_read_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
- usb_bulk_msg( (_d)->udev, \
- usb_rcvbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
- _p, _sz, &actual_count, _tmo )
+ #define _pcps_usb_read_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
+ usb_bulk_msg_dbg( (_d)->udev, \
+ usb_rcvbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
+ _p, _sz, &actual_count, _tmo )
+ #else
+ #define _pcps_usb_write_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
+ usb_bulk_msg( (_d)->udev, \
+ usb_sndbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
+ _p, _sz, &actual_count, _tmo )
+
+ #define _pcps_usb_read_ep_tmo( _d, _p, _sz, _ep_idx, _tmo ) \
+ usb_bulk_msg( (_d)->udev, \
+ usb_rcvbulkpipe( (_d)->udev, (_d)->ep[_ep_idx].addr ), \
+ _p, _sz, &actual_count, _tmo )
+ #endif
#define _pcps_usb_write( _d, _p, _sz ) \
_pcps_usb_write_ep_tmo( _d, _p, _sz, MBGUSB_EP_IDX_HOST_OUT, MBGUSB_TIMEOUT_SEND )
@@ -1376,7 +1509,7 @@ _ext const char *fw_id_ref[]
_pcps_usb_read_ep_tmo( _d, _p, _sz, MBGUSB_EP_IDX_HOST_IN_CYCLIC, MBGUSB_TIMEOUT_RECEIVE_CYCLIC )
#define _pcps_usb_read_var_cyclic( _d, _p ) \
- _pcps_usb_read_cyclic( _d, _p, sizeof( *(_p) ) )
+ _pcps_usb_read_cyclic( _d, _p, sizeof( *(_p) ) )
#endif // target specific definitions
@@ -1390,44 +1523,289 @@ _ext const char *fw_id_ref[]
#endif
+/**
+ * @defgroup pcps_io_fncs Low level functions used to access the hardware device
+ */
+
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
-/* PCPS_WRITE_FNC */
- short pcps_write( PCPS_DDEV *pddev, uint8_t cmd, const void FAR *buffer, uint16_t count ) ;
+ /**
+ * @brief Write data to a device
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] cmd The command code for the board, see @ref PCPS_CMD_CODES
+ * @param[in] buffer A buffer with data to be written according to the cmd code
+ * @param[in] count The number of bytes to be written according to the cmd code
+ *
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
+ *
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+ int pcps_write( PCPS_DDEV *pddev, uint8_t cmd, const void FAR *buffer, uint16_t count ) ;
- short pcps_generic_io( PCPS_DDEV *pddev, uint8_t type, const void FAR *in_buff, uint8_t in_cnt, void FAR *out_buff, uint8_t out_cnt ) ;
-/* PCPS_READ_FNC */
- short pcps_read_gps( PCPS_DDEV *pddev, uint8_t data_type, void FAR *buffer, uint16_t buffer_size ) ;
+ /**
+ * @brief Generic I/O function
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] type The type of data to be read/written, see @ref PCPS_CMD_CODES
+ * @param[in] in_buff A buffer with data to be written according to the type code
+ * @param[in] in_cnt The number of bytes to be written according to the type code
+ * @param[out] out_buff A buffer with data to be read according to the type code
+ * @param[in] out_cnt The number of bytes to be read according to the type code
+ *
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
+ *
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+ int pcps_generic_io( PCPS_DDEV *pddev, uint8_t type, const void FAR *in_buff, uint8_t in_cnt, void FAR *out_buff, uint8_t out_cnt ) ;
-/* PCPS_WRITE_FNC */
- short pcps_write_gps( PCPS_DDEV *pddev, uint8_t data_type, const void FAR *buffer, uint16_t buffer_size ) ;
+ /**
+ * @brief Read a large data structure from a device
+ *
+ * Read data structures which exceed ::PCPS_FIFO_SIZE bytes.
+ * This can't be handled in a single read cycle, and due to
+ * limitations of the device's microprocessor the execution time
+ * can be up to 20 milliseconds, depending on the device type.
+ * This has been introduced with the first GPS devices but is
+ * now in fact also used with non-GPS devices.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] data_type The code assigned to the dadta type, see @ref PC_GPS_CMD_CODES
+ * @param[out] buffer A buffer with data to be read according to the data_type
+ * @param[in] buffer_size The number of bytes to be read according to the data_type
+ *
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
+ *
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+ int pcps_read_gps( PCPS_DDEV *pddev, uint8_t data_type, void FAR *buffer, uint16_t buffer_size ) ;
+
+ /**
+ * @brief Write a large data structure to a device
+ *
+ * This has been introduced with the first GPS devices but is
+ * now in fact also used with non-GPS devices.
+ *
+ * @param[in] pddev Pointer to the device structure
+ * @param[in] data_type The code assigned to the dadta type, see @ref PC_GPS_CMD_CODES
+ * @param[in] buffer A buffer with data to be written according to the data_type
+ * @param[in] buffer_size The number of bytes to be written according to the data_type
+ *
+ * @return ::MBG_SUCCESS on success,
+ * ::MBG_ERR_TIMEOUT if device didn't respond in time,
+ * ::MBG_ERR_NBYTES if the number of parameter bytes did not match
+ * the number of data bytes expected by the device,
+ * or one of the other @ref MBG_RETURN_CODES
+ *
+ * @ingroup pcps_io_fncs
+ * @see @ref pcps_io_fncs
+ */
+ int pcps_write_gps( PCPS_DDEV *pddev, uint8_t data_type, const void FAR *buffer, uint16_t buffer_size ) ;
- short pcps_get_fw_id( PCPS_DDEV *pddev, PCPS_ID_STR FAR fw_id ) ;
- short pcps_check_id( PCPS_DDEV *pddev, const char FAR *ref ) ;
- short pcps_get_rev_num( char FAR *idstr ) ;
+ /**
+ * @brief Read the serial number from a device, if supported
+ *
+ * If the serial number could be read successfully then it is
+ * stored in one of the sub-structures of pddev.
+ *
+ * @param[in,out] pddev Pointer to a device structure
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_read_sernum( PCPS_DDEV *pddev ) ;
- int pcps_rsrc_claim( PCPS_DDEV *pddev ) ;
+
+ /**
+ * @brief Release an I/O port resource range that has been claimed before
+ *
+ * @param[in,out] pddev The device structure
+ */
void pcps_rsrc_release( PCPS_DDEV *pddev ) ;
- ushort pcps_port_from_pos( ushort pos ) ;
- uchar pcps_pos_from_port( ushort port ) ;
- PCPS_DEV_TYPE *pcps_get_dev_type( int bus_mask, ushort dev_id ) ;
+
+ /**
+ * @brief Lookup a specific device in the device table
+ *
+ * The function below takes a bus flag and device ID to search
+ * the table of known devices for a device which matches the
+ * given criteria.
+ *
+ * @param[in] bus_mask Mask of the bus type to look up, see @ref PCPS_BUS_FLAG_MASKS
+ * @param[in] dev_id The device ID to lookup, see @ref MEINBERG_PCI_DEVICE_IDS
+ * or @ref MBG_USB_DEVICE_IDS, depending on the bus_mask
+ *
+ * @return A pointer to the device table entry, or NULL if no entry found
+ */
+ PCPS_DEV_TYPE *pcps_get_dev_type_table_entry( PCPS_BUS_FLAGS bus_mask, PCPS_DEV_ID dev_id ) ;
+
+ /**
+ * @brief Allocate a device info structure for a device
+ *
+ * @return A pointer to the allocated structure, or NULL if failed
+ */
PCPS_DDEV *pcps_alloc_ddev( void ) ;
+
+ /**
+ * @brief Free a previously allocated device info structure
+ *
+ * @param[in] pddev Pointer to the device structure to be freed
+ */
void pcps_free_ddev( PCPS_DDEV *pddev ) ;
+
+ /**
+ * @brief Add an I/O address range resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] base Base address of the I/O address range
+ * @param[in] num Number of addresses of the I/O address range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_io( PCPS_DDEV *pddev, ulong base, ulong num ) ;
+
+ /**
+ * @brief Add a memory address range resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] start Start address of the memory range
+ * @param[in] len Size of the memory range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_mem( PCPS_DDEV *pddev, MBG_MEM_ADDR start, ulong len ) ;
+
+ /**
+ * @brief Add an IRQ number resource to the device structure
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] irq_num Start address of the memory range
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int pcps_add_rsrc_irq( PCPS_DDEV *pddev, int16_t irq_num ) ;
- int pcps_init_ddev( PCPS_DDEV *pddev, int bus_flags, ushort dev_id ) ;
- int pcps_start_device( PCPS_DDEV *pddev, PCPS_BUS_NUM bus_num, PCPS_SLOT_NUM dev_fnc_num ) ;
+
+ /**
+ * @brief Initialize an allocated device structure for a specific device
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ * @param[in] bus_mask Mask of the bus type to look up, see @ref PCPS_BUS_FLAG_MASKS
+ * @param[in] dev_id The device ID to lookup, see @ref MEINBERG_PCI_DEVICE_IDS
+ * or @ref MBG_USB_DEVICE_IDS, depending on the bus_mask
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ int pcps_init_ddev( PCPS_DDEV *pddev, PCPS_BUS_FLAGS bus_mask, PCPS_DEV_ID dev_id ) ;
+
+ /**
+ * @brief Check if a specific feature of a specific feature type is supported
+ *
+ * There are different structures where information can be stored
+ * if a specific feature is supported. All information is set up
+ * when the ::pcps_probe_device function is called to probe and
+ * initialize the device.
+ * This generic low-level function can be called by API functions
+ * to check if a specific feature is supported.
+ *
+ * @param[in] p_ddev Pointer to the device structure
+ * @param[in] feat_req_type See ::DEV_FEAT_REQ_TYPES
+ * @param[in] feat_num Number and range depending on feat_req_type value
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @see ::pcps_probe_device
+ */
+ int pcps_chk_dev_feat( PCPS_DDEV *p_ddev, uint32_t feat_req_type, uint32_t feat_num ) ;
+
+ /**
+ * @brief Probe if a device is supported, and allocate and setup the device structure
+ *
+ * This function should be called by the probe routines of any
+ * target-specific kernel drivers.
+ * If the device is supported then all specific information including
+ * supported features is read from the device and stored in sub-structures
+ * of the device structure addressed by pdev.
+ *
+ * @param[in,out] pddev Pointer to the device structure which has been initialized and will be set up
+ * @param[in] bus_num The bus number if supported (e.g. PCI), else 0
+ * @param[in] dev_fnc_num The device/function number if supported (e.g. PCI), else 0
+ *
+ * @return ::MBG_SUCCESS if the requested feature is supported, ::MBG_ERR_NOT_SUPP_BY_DEV
+ * if not supported, or one of the other @ref MBG_ERROR_CODES
+ *
+ * @see ::pcps_cleanup_device
+ * @see ::pcps_chk_dev_feat
+ */
+ int pcps_probe_device( PCPS_DDEV *pddev, PCPS_BUS_NUM bus_num, PCPS_SLOT_NUM dev_fnc_num ) ;
+
+ /**
+ * @brief Clean up function called by ::pcps_probe_device on error
+ *
+ * @param[in,out] pddev Pointer to the device structure
+ *
+ * @see ::pcps_probe_device
+ */
void pcps_cleanup_device( PCPS_DDEV *pddev ) ;
+
+ /**
+ * @brief Setup and start a PCI device in a non-PnP system
+ *
+ * @param[in,out] pddev Pointer to the device structure to be set up
+ * @param[in] bus_num The PCI bus number returned by the PCI BIOS
+ * @param[in] dev_fnc_num The PCI device/function number returned by the PCI BIOS
+ */
void pcps_setup_and_start_pci_dev( PCPS_DDEV *pddev, PCPS_BUS_NUM bus_num, PCPS_SLOT_NUM dev_fnc_num ) ;
- void pcps_detect_pci_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg, PCPS_DDEV_CLEANUP_FNC cleanup_fnc, ushort vendor_id, PCPS_DEV_TYPE dev_type[], int n_dev_types ) ;
- void pcps_detect_isa_clocks( PCPS_DDEV_ALLOC_FNC alloc_fnc, PCPS_DDEV_CLEANUP_FNC cleanup_fnc, PCPS_DDEV_REGISTER_FNC register_fnc, int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS] ) ;
- void _MBG_INIT_CODE_ATTR pcps_detect_clocks_alloc( PCPS_DDEV_ALLOC_FNC alloc_fnc, void *alloc_arg, PCPS_DDEV_CLEANUP_FNC cleanup_fnc, int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS] ) ;
- void _MBG_INIT_CODE_ATTR pcps_detect_clocks( int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS] ) ;
+
+ /**
+ * @brief Detect and initialize PCI devices in a non-PnP system
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ * @param[in] cleanup_fnc Pointer to function called if the device structure needs to be de-allocated in case of error.
+ * @param[in] vendor_id The PCI vendor ID code.
+ * @param[in] dev_type An array with known PCI devices for the specified vendor ID
+ * @param[in] n_dev_types The number of entries in the PCI device table
+ */
+ void pcps_detect_pci_devices( PCPS_DDEV_ALLOC_FNC *alloc_fnc, PCPS_DDEV_CLEANUP_FNC *cleanup_fnc, ushort vendor_id, PCPS_DEV_TYPE dev_type[], int n_dev_types ) ;
+
+ /**
+ * @brief Detect and initialize ISA devices in a non-PnP system
+ *
+ * @param[in] alloc_fnc Pointer to function called to allocate a device structure for each detected device.
+ * @param[in] cleanup_fnc Pointer to function called if the device structure needs to be de-allocated in case of error.
+ * @param[in] register_fnc Pointer to function called to register a detected device.
+ * @param[in] isa_ports An array with potential I/O base addresses for ISA devices.
+ * @param[in] isa_irqs An array with potential IRQ numbers assigned to ISA devices.
+ */
+ void pcps_detect_isa_devices( PCPS_DDEV_ALLOC_FNC *alloc_fnc, PCPS_DDEV_CLEANUP_FNC *cleanup_fnc, PCPS_DDEV_REGISTER_FNC *register_fnc, int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS] ) ;
+
+ /**
+ * @brief Detect all bus-level devices in a non-PnP system
+ *
+ * @note If a DOS TSR is installed, be sure it is disabled (BUSY flag set)
+ * when this function is called.
+ *
+ * @param[in] isa_ports An array with potential I/O base addresses for ISA devices.
+ * @param[in] isa_irqs An array with potential IRQ numbers assigned to ISA devices.
+ */
+ void _MBG_INIT_CODE_ATTR pcps_detect_devices( int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS] ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsirq.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsirq.h
index 7bb2b1f..8156f87 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsirq.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsirq.h
@@ -1,16 +1,23 @@
/**************************************************************************
*
- * $Id: pcpsirq.h 1.7 2008/12/05 12:20:36 martin REL_M $
+ * $Id: pcpsirq.h 1.8 2012/10/15 09:50:44 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* OS independent definitions used to handle interrupts from
- * Meinberg radio clock devices.
+ * Meinberg PCI devices.
*
* -----------------------------------------------------------------------
* $Log: pcpsirq.h $
+ * Revision 1.8 2012/10/15 09:50:44 martin
+ * Account for modified low level macros.
+ * Revision 1.7.1.3 2011/12/20 13:46:07 martin
+ * Conditionally support memory mapped access for MBGPEX cards.
+ * Revision 1.7.1.2 2011/06/29 11:03:28 martin
+ * Updated a comment.
+ * Revision 1.7.1.1 2011/02/09 17:22:36 martin
* Revision 1.7 2008/12/05 12:20:36 martin
* Protect HW access to enable/disable IRQ by mutex.
* Support mapped I/O resources.
@@ -41,13 +48,6 @@
#include <pci_asic.h>
-#define _set_port_bit( _d, _adr, _msk ) \
- _mbg_outp8( (_d), _adr, _mbg_inp8( (_d), _adr ) | (_msk) )
-
-#define _clear_port_bit( _d, _adr, _msk ) \
- _mbg_outp8( (_d), _adr, _mbg_inp8( (_d), _adr ) & ~(_msk) )
-
-
// Each of the macros below expects a parameter _d which is
// a pointer to the PCPS_DDEV structure which represents the
// hardware device.
@@ -55,6 +55,12 @@
// The macros below generate code only if MCA support is enabled.
#if _PCPS_USE_MCA
+ #define _set_mca_port_bit( _d, _adr, _msk ) \
+ _mbg_outp8( (_d), 0, _adr, _mbg_inp8( (_d), 0, _adr ) | (_msk) )
+
+ #define _clear_mca_port_bit( _d, _adr, _msk ) \
+ _mbg_outp8( (_d), 0, _adr, _mbg_inp8( (_d), 0, _adr ) & ~(_msk) )
+
#define MCIC_IRQ 0x04
#define _mcic_enb_reg( _r ) ( (_r) + 0x0A )
#define _mcic_ack_reg( _r ) ( (_r) + 0x0B )
@@ -68,7 +74,7 @@
if ( _pcps_ddev_is_mca( _d ) ) \
{ \
PCPS_IO_ADDR_MAPPED port = _mcic_ack_reg( _pcps_ddev_io_base_mapped( _d, 0 ) ); \
- _set_port_bit( (_d), port, MCIC_IRQ ); \
+ _set_mca_port_bit( (_d), port, MCIC_IRQ ); \
}
// In IRQ init function, enable IRQ on the
@@ -78,7 +84,7 @@
{ \
uint16_t port = _mcic_enb_reg( _pcps_ddev_io_base_mapped( _d, 0 ) ); \
set_pos_reg( 4, _pcps_ddev_slot_num( _d ), active_irq.map_code ); \
- _set_port_bit( (_d), port, MCIC_IRQ ); \
+ _set_mca_port_bit( (_d), port, MCIC_IRQ ); \
}
// In IRQ de-init function, disable IRQ on the
@@ -87,15 +93,15 @@
if ( _pcps_ddev_is_mca( _d ) ) \
{ \
uint16_t port = _mcic_enb_reg( _pcps_ddev_io_base_mapped( _d, 0 ) ); \
- _clear_port_bit( (_d), port, MCIC_IRQ ); \
+ _clear_mca_port_bit( (_d), port, MCIC_IRQ ); \
}
#else
// Do nothing if MCA not supported.
- #define _pcps_ddev_enb_irq_mca( _d );
- #define _pcps_ddev_disb_irq_mca( _d );
- #define _pcps_ddev_ack_irq_mca( _d );
+ #define _pcps_ddev_enb_irq_mca( _d ) _nop_macro_fnc()
+ #define _pcps_ddev_disb_irq_mca( _d ) _nop_macro_fnc()
+ #define _pcps_ddev_ack_irq_mca( _d ) _nop_macro_fnc()
#endif
@@ -110,41 +116,44 @@
// 2.) Clear interrupt source, deassert INTA# signal
// and leave interrupt enabled by writing '1's to
// the interrupt flag and interrupt enable bits.
- #define _pcps_ddev_ack_irq_pci( _d ) \
- if ( (_d)->irq_ack_mask ) \
- { \
- if ( _pcps_ddev_is_pci_amcc( _d ) ) \
- _mbg_inp32( (_d), _pcps_ddev_io_base_mapped( _d, 0 ) \
- + AMCC_OP_REG_IMB4 ); \
- \
- _mbg_outp32( (_d), (_d)->irq_ack_port, (_d)->irq_ack_mask ); \
+ #define _pcps_ddev_ack_irq_pci( _d ) \
+ if ( (_d)->irq_ack_mask ) \
+ { \
+ if ( _pcps_ddev_is_pci_amcc( _d ) ) \
+ _mbg_inp32( (_d), 0, _pcps_ddev_io_base_mapped( _d, 0 ) \
+ + AMCC_OP_REG_IMB4 ); \
+ \
+ _mbg_outp32_ex( (_d), 0, (_d)->irq_ack_port, control_status, \
+ (_d)->irq_ack_mask ); \
}
// In IRQ init function, enable IRQ on the
// interface chip.
- #define _pcps_ddev_enb_irq_pci( _d ) \
- if ( (_d)->irq_enb_mask ) \
- { \
- uint32_t intcsr = _mbg_inp32_to_cpu( (_d), (_d)->irq_enb_disb_port ); \
- _mbg_outp32( (_d), (_d)->irq_enb_disb_port, \
- intcsr | (_d)->irq_enb_mask ); \
+ #define _pcps_ddev_enb_irq_pci( _d ) \
+ if ( (_d)->irq_enb_mask ) \
+ { \
+ uint32_t intcsr = _mbg32_to_cpu( _mbg_inp32_ex( (_d), 0, \
+ (_d)->irq_enb_disb_port, control_status ) ); \
+ _mbg_outp32_ex( (_d), 0, (_d)->irq_enb_disb_port, control_status, \
+ intcsr | (_d)->irq_enb_mask ); \
}
// In IRQ de-init function, disable IRQ on the
// interface chip.
- #define _pcps_ddev_disb_irq_pci( _d ) \
- if ( (_d)->irq_disb_mask ) \
- { \
- uint32_t intcsr = _mbg_inp32_to_cpu( (_d), (_d)->irq_enb_disb_port ); \
- _mbg_outp32( (_d), (_d)->irq_enb_disb_port, \
- intcsr & ~(_d)->irq_disb_mask ); \
+ #define _pcps_ddev_disb_irq_pci( _d ) \
+ if ( (_d)->irq_disb_mask ) \
+ { \
+ uint32_t intcsr = _mbg32_to_cpu( _mbg_inp32_ex( (_d), 0, \
+ (_d)->irq_enb_disb_port, control_status ) ); \
+ _mbg_outp32_ex( (_d), 0, (_d)->irq_enb_disb_port, control_status, \
+ intcsr & ~(_d)->irq_disb_mask ); \
}
#else
// Do nothing if PCI not supported.
- #define _pcps_ddev_enb_irq_pci( _d );
- #define _pcps_ddev_disb_irq_pci( _d );
- #define _pcps_ddev_ack_irq_pci( _d );
+ #define _pcps_ddev_enb_irq_pci( _d ) _nop_macro_fnc()
+ #define _pcps_ddev_disb_irq_pci( _d ) _nop_macro_fnc()
+ #define _pcps_ddev_ack_irq_pci( _d ) _nop_macro_fnc()
#endif
@@ -155,10 +164,10 @@
// For non-PCI devices check the IRQ flag of the clock's
// status port.
#if ( _PCPS_USE_PCI )
- #define _pcps_ddev_has_gen_irq( _d ) \
- ( ( (_d)->irq_flag_mask ) ? \
- ( _mbg_inp32( (_d), (_d)->irq_flag_port ) & (_d)->irq_flag_mask ) : \
- ( _pcps_ddev_read_status_port( _d ) & PCPS_ST_IRQF ) \
+ #define _pcps_ddev_has_gen_irq( _d ) \
+ ( ( (_d)->irq_flag_mask ) ? \
+ ( _mbg_inp32_ex( (_d), 0, (_d)->irq_flag_port, control_status ) & (_d)->irq_flag_mask ) : \
+ ( _pcps_ddev_read_status_port( _d ) & PCPS_ST_IRQF ) \
)
#else
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.c b/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.c
index 944cee0..151a0e0 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpslstr.c 1.22.1.4 2011/02/07 10:34:59 martin TEST $
+ * $Id: pcpslstr.c 1.25 2017/07/05 07:43:53 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,13 +11,16 @@
*
* -----------------------------------------------------------------------
* $Log: pcpslstr.c $
- * Revision 1.22.1.4 2011/02/07 10:34:59 martin
+ * Revision 1.25 2017/07/05 07:43:53 martin
+ * Use safe string functions from str_util.c.
+ * Started to add doxygen comments.
+ * Revision 1.24 2014/03/13 14:32:27 martin
+ * Fixed compiler warning.
+ * Revision 1.23 2012/10/15 13:09:35Z martin
+ * Added function sprint_utc_offs().
+ * Cleaned up get_tz_name().
* Fixed potential compiler warning for sprintf().
- * Revision 1.22.1.3 2011/01/28 09:34:20 martin
* Fixed build under FreeBSD.
- * Revision 1.22.1.2 2010/11/05 12:55:10 martin
- * Revision 1.22.1.1 2010/07/15 12:39:34 martin
- * Added function sprint_utc_offs().
* Revision 1.22 2010/06/25 13:57:57Z daniel
* Account for time zone offsets with minutes other than 0.
* Revision 1.21 2009/03/19 08:06:58Z daniel
@@ -40,7 +43,7 @@
* Revision 1.15 2007/07/20 10:55:27Z martin
* Some modifications to avoid compiler warnings.
* Revision 1.14 2007/03/30 13:23:42 martin
- * In pcps_status_strs() handle case where time has been
+ * In pcps_status_strs() handle case where time has been
* set manually.
* Revision 1.13 2007/03/29 12:58:18Z martin
* Moved some definitions to the header file to make them public.
@@ -108,26 +111,41 @@ typedef struct
} CLSTR_STATUS;
-static const char *tz_name_utc = TZ_NAME_UTC;
+static const char tz_name_utc[] = TZ_NAME_UTC;
static CLSTR str_dst = { "DST", "Sommerzeit" };
/*HDR*/
+/**
+ * @brief Return a language dependend string for "invalid"
+ *
+ * @return A language dependend string for "invalid"
+ */
const char *inv_str( void )
{
static CLSTR s = { "** invalid **", "** ung" LCUE "ltig **" };
return _lstr( s );
-} /* inv_str */
+} // inv_str
/*HDR*/
-int sprint_utc_offs( char *s, const char *info, long utc_offs )
+/**
+ * @brief Print the UTC offset into a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] info An optional info string to be prepended, may be NULL
+ * @param[in] utc_offs UTC offset in [s]
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ */
+size_t snprint_utc_offs( char *s, size_t max_len, const char *info, long utc_offs )
{
- int n = 0;
+ size_t n = 0;
// utc_offs is in [s]
char utc_offs_sign = ( utc_offs < 0 ) ? '-' : '+';
@@ -138,17 +156,17 @@ int sprint_utc_offs( char *s, const char *info, long utc_offs )
ulong utc_offs_secs = tmp % MINS_PER_HOUR;
if ( info )
- n += sprintf( &s[n], "%s", info );
+ n += snprintf_safe( &s[n], max_len - n, "%s", info );
- n += sprintf( &s[n], "%c%lu", utc_offs_sign, utc_offs_hours );
+ n += snprintf_safe( &s[n], max_len - n, "%c%lu", utc_offs_sign, utc_offs_hours );
if ( utc_offs_mins || utc_offs_secs )
- n += sprintf( &s[n], ":%02lu", utc_offs_mins );
+ n += snprintf_safe( &s[n], max_len - n, ":%02lu", utc_offs_mins );
if ( utc_offs_secs )
- n += sprintf( &s[n], ":%02lu", utc_offs_secs );
+ n += snprintf_safe( &s[n], max_len - n, ":%02lu", utc_offs_secs );
- n += sprintf( &s[n], "h" );
+ n += sn_cpy_str_safe( &s[n], max_len - n, "h" );
return n;
@@ -157,12 +175,28 @@ int sprint_utc_offs( char *s, const char *info, long utc_offs )
static /*HDR*/
+/**
+ * @brief Return a static string with the name of the timezone, depending on the UTC offset
+ *
+ * @param[in] pcps_status Status flags read from a clock device
+ * @param[in] utc_offs UTC offset in [s]
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_hr_status
+ * @see ::pcps_tz_name_from_status
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *get_tz_name( PCPS_TIME_STATUS_X pcps_status, long utc_offs,
ushort flags, int is_msf )
{
static char ws[40];
const char *cp = NULL;
- int n = 0;
+ size_t n = 0;
if ( ( pcps_status & PCPS_UTC ) && ( utc_offs == 0 ) )
return tz_name_utc; // no offset, no DST
@@ -197,7 +231,7 @@ const char *get_tz_name( PCPS_TIME_STATUS_X pcps_status, long utc_offs,
}
}
- n = sprint_utc_offs( ws, tz_name_utc, utc_offs );
+ n = snprint_utc_offs( ws, sizeof( ws ), tz_name_utc, utc_offs );
check_flags:
if ( cp )
@@ -205,30 +239,45 @@ check_flags:
if ( flags == 0 )
return cp;
- strcpy( ws, cp );
+ n = sn_cpy_str_safe( ws, sizeof( ws ), cp );
if ( flags & PCPS_TZ_NAME_FORCE_UTC_OFFS )
{
- n = strlen( ws );
- n += sprintf( &ws[n], "%*c(", pcps_time_tz_dist, ' ' );
- n += sprint_utc_offs( &ws[n], tz_name_utc, utc_offs );
- sprintf( &ws[n], ")" );
+ n += snprintf_safe( &ws[n], sizeof( ws ) - n, "%*c(", pcps_time_tz_dist, ' ' );
+ n += snprint_utc_offs( &ws[n], sizeof( ws ) - n, tz_name_utc, utc_offs );
+ n += sn_cpy_char_safe( &ws[n], sizeof( ws ) - n, ')' );
}
}
if ( flags & PCPS_TZ_NAME_APP_DST )
{
if ( pcps_status & PCPS_DL_ENB )
- sprintf( _eos( ws ), ",%*c%s", pcps_time_tz_dist,
- ' ', _lstr( str_dst ) );
+ snprintf_safe( &ws[n], sizeof( ws ) - n, ",%*c%s", pcps_time_tz_dist,
+ ' ', _lstr( str_dst ) );
}
return ws;
-}
+
+} // get_tz_name
/*HDR*/
+/**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_TIME structure
+ *
+ * @param[in] t A ::PCPS_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_hr_status
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name( const PCPS_TIME *t, ushort flags, int is_msf )
{
return get_tz_name( t->status, t->offs_utc * SECS_PER_HOUR, flags, is_msf );
@@ -238,6 +287,21 @@ const char *pcps_tz_name( const PCPS_TIME *t, ushort flags, int is_msf )
/*HDR*/
+/**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * @param[in] hrt A ::PCPS_HR_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_hr_status
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name_from_hr_time( const PCPS_HR_TIME *hrt, ushort flags, int is_msf )
{
return get_tz_name( hrt->status, hrt->utc_offs, flags, is_msf );
@@ -246,22 +310,36 @@ const char *pcps_tz_name_from_hr_time( const PCPS_HR_TIME *hrt, ushort flags, in
-// The function below can be used to build a name for
-// the time zone if the TIMESCALE, the UTC/DST status and the
-// UTC offset are known, e.g. from plug-in clocks.
-
/*HDR*/
+/**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * This function can be used to build a name for the time zone if the timescale,
+ * the %UTC/DST status and the %UTC offset are known, e.g. from plug-in clock devices.
+ *
+ * @param[in] t A ::PCPS_HR_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name_hr_status( const PCPS_HR_TIME *t, ushort flags, int is_msf )
{
static char ws[40];
if ( t->status & PCPS_SCALE_GPS )
- strcpy( ws, "GPS" );
+ strncpy_safe( ws, "GPS", sizeof( ws ) );
else
if ( t->status & PCPS_SCALE_TAI )
- strcpy( ws, "TAI" );
+ strncpy_safe( ws, "TAI", sizeof( ws ) );
else
- return pcps_tz_name_from_hr_time( t, flags, is_msf);
+ return pcps_tz_name_from_hr_time( t, flags, is_msf );
return ws;
@@ -269,13 +347,25 @@ const char *pcps_tz_name_hr_status( const PCPS_HR_TIME *t, ushort flags, int is_
-// The function below can be used to build a name for
-// the time zone if only the UTC/DST status is known
-// but the UTC offset is not. This is the case, for example,
-// if the Meinberg standard time string is decoded.
-
/*HDR*/
-const char *pcps_tz_name_from_status( ushort status )
+/**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * This function can be used to build a name for the time zone
+ * if only the %UTC/DST status is known, but the UTC offset is not.
+ * This is the case, for example, if the Meinberg standard time string is decoded.
+ *
+ * @param[in] status Clock status in ::PCPS_TIME_STATUS_X format
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_hr_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
+const char *pcps_tz_name_from_status( PCPS_TIME_STATUS_X status )
{
if ( status & PCPS_UTC )
return tz_name_utc;
@@ -287,33 +377,39 @@ const char *pcps_tz_name_from_status( ushort status )
/*HDR*/
-char *pcps_date_time_str( char *s, const PCPS_TIME *t,
+char *pcps_date_time_str( char *s, size_t max_len, const PCPS_TIME *t,
ushort year_limit, const char *tz_str )
{
if ( !_pcps_time_is_read( t ) )
- strcpy( s, str_not_avail );
+ strncpy_safe( s, str_not_avail, max_len );
else
{
- char *cp;
+ size_t n;
int i;
- _pcps_sprint_wday( s, t, language );
- cp = _eos( s );
- *cp++ = ',';
+ _pcps_snprint_wday( s, max_len, t, language );
+ n = strlen( s );
+
+ n += sn_cpy_char_safe( &s[n], max_len - n, ',' );
+
for ( i = 0; i < pcps_wday_date_dist; i++ )
- *cp++ = ' ';
- _pcps_sprint_date( cp, t, year_limit );
- cp = _eos( s );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ' ' );
+
+ _pcps_snprint_date( &s[n], max_len - n, t, year_limit );
+ n = strlen( s );
+
for ( i = 0; i < pcps_date_time_dist; i++ )
- *cp++ = ' ';
- _pcps_sprint_time_long( cp, t );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ' ' );
+
+ _pcps_snprint_time_long( &s[n], max_len - n, t );
+ n = strlen( s );
if ( tz_str )
{
- cp = _eos( s );
for ( i = 0; i < pcps_time_tz_dist; i++ )
- *cp++ = ' ';
- strcpy( cp, tz_str );
+ n += sn_cpy_char_safe( &s[n], max_len - n, ' ' );
+
+ n += sn_cpy_str_safe( &s[n], max_len - n, tz_str );
}
}
@@ -326,34 +422,22 @@ char *pcps_date_time_str( char *s, const PCPS_TIME *t,
#if MBG_TGT_HAS_WCHAR_T && defined( MBG_TGT_WIN32 )
/*HDR*/
-wchar_t *pcps_date_time_wstr( wchar_t *ws, const PCPS_TIME *t,
+wchar_t *pcps_date_time_wstr( wchar_t *ws, size_t count, const PCPS_TIME *t,
ushort year_limit, const wchar_t *tz_str )
{
- char stemp[80];
- wchar_t wstemp[80];
-
- if ( !_pcps_time_is_read( t ) )
- mbstowcs( ws, str_not_avail, 32 );
- else
- {
- char *cp;
- int i;
+ //#error Remove this error directive and check if the function works properly.
+ char tmp_str[80];
- _pcps_sprint_wday( stemp, t, language );
- cp = _eos( stemp );
- *cp++ = ',';
- for ( i = 0; i < pcps_wday_date_dist; i++ )
- *cp++ = ' ';
- _pcps_sprint_date( cp, t, year_limit );
- cp = _eos( stemp );
- for ( i = 0; i < pcps_date_time_dist; i++ )
- *cp++ = ' ';
- _pcps_sprint_time_long( cp, t );
+ pcps_date_time_str( tmp_str, sizeof( tmp_str ), t, year_limit, NULL );
- mbstowcs( wstemp, stemp, sizeof( wstemp ) );
+ mbstowcs( ws, tmp_str, count );
+ ws[count - 1] = L'0'; // force terminating 0
- if ( tz_str )
- _snwprintf( ws, sizeof( wstemp ) + 32, L"%s %s", wstemp, tz_str );
+ if ( tz_str )
+ {
+ size_t n = wcslen( ws );
+ _snwprintf( &ws[n], count - n, L" %s", tz_str );
+ ws[count - 1] = L'0'; // force terminating 0
}
return ws;
@@ -447,16 +531,16 @@ void pcps_status_strs( ushort status, int status_is_read,
/*HDR*/
-char *pcps_port_str( char *s, const PCPS_DEV *pdev )
+char *pcps_port_str( char *s, size_t max_len, const PCPS_DEV *pdev )
{
- ushort port = _pcps_port_base( pdev, 0 );
+ ushort port = _pcps_short_port_base( pdev, 0 );
- ushort n = sprintf( s, "%3Xh", port );
+ size_t n = snprintf_safe( s, max_len, "%3Xh", port );
- port = _pcps_port_base( pdev, 1 );
+ port = _pcps_short_port_base( pdev, 1 );
if ( port )
- sprintf( &s[n], ", %3Xh", port );
+ snprintf_safe( &s[n], max_len - n, ", %3Xh", port );
return s;
@@ -477,25 +561,26 @@ const char *pcps_tzcode_str( PCPS_TZCODE tzcode )
/*HDR*/
-char *pcps_serial_str( char *s, int i, const RECEIVER_PORT_CFG *p,
+char *pcps_serial_str( char *s, size_t max_len, int i, const RECEIVER_PORT_CFG *p,
const RECEIVER_INFO *p_ri, int short_strs )
{
const PORT_SETTINGS *p_ps = &p->pii[i].port_info.port_settings;
const STR_TYPE_INFO *p_sti = &p->stii[p_ps->str_type].str_type_info;
+ size_t n;
- sprintf( s, "%lu,%s", (ulong) p_ps->parm.baud_rate, p_ps->parm.framing );
+ n = snprintf_safe( s, max_len, "%lu,%s", (ulong) p_ps->parm.baud_rate, p_ps->parm.framing );
if ( short_strs )
- sprintf( _eos( s ), ",%s", short_mode_name[p_ps->mode] );
+ n += snprintf_safe( &s[n], max_len - n, ",%s", short_mode_name[p_ps->mode] );
else
{
if ( p_ri->n_str_type > 1 )
- sprintf( _eos( s ), ", %s", p_sti->long_name );
+ n += snprintf_safe( &s[n], max_len - n, ", %s", p_sti->long_name );
- sprintf( _eos( s ), ", %s", _lstr( mode_name[p_ps->mode] ) );
+ n += snprintf_safe( &s[n], max_len - n, ", %s", _lstr( mode_name[p_ps->mode] ) );
}
- return( s );
+ return s;
} // pcps_serial_str
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.h
index adf4b5e..241364c 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpslstr.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpslstr.h 1.27.1.5 2011/02/16 09:34:23 martin TRASH $
+ * $Id: pcpslstr.h 1.30 2017/07/05 17:37:03 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,14 +10,23 @@
*
* -----------------------------------------------------------------------
* $Log: pcpslstr.h $
- * Revision 1.27.1.5 2011/02/16 09:34:23 martin
+ * Revision 1.30 2017/07/05 17:37:03 martin
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Account for new modes for programmable pulse outputs.
+ * Started to add doxygen comments.
+ * Fixed typos, wording, and doxygen comments.
+ * Updated function prototypes.
+ * Revision 1.29 2012/11/20 10:47:29 martin
+ * Moved some code definitions for special chars
+ * to new header charcode.h.
+ * Revision 1.28 2012/10/15 13:01:23 martin
+ * Include cfg_hlp.h.
+ * Made all declarations extern C.
* Added menu titles for PTP and PTP Unicast configuration.
- * Revision 1.27.1.4 2011/02/09 14:43:42Z martin
- * Revision 1.27.1.3 2011/01/28 09:34:38 martin
- * Fixed build under FreeBSD.
- * Revision 1.27.1.2 2010/11/22 15:23:06 martin
+ * Added DEFAULT_OPT_NAME_TR_DISTANCE.
+ * Support time slots mode for programmable pulse outputs.
* Added strings for programmable output synthesizer mode.
- * Revision 1.27.1.1 2010/07/15 13:02:16 martin
+ * Fixed build under FreeBSD.
* Also use ANSI umlauts under QNX.
* Updated function prototypes.
* Revision 1.27 2010/06/28 08:28:17Z stefan
@@ -80,7 +89,7 @@
* Updated function prototypes.
* Revision 1.6 2002/12/18 13:57:53 martin
* Some definitions and variables made global.
- * Added some new macros _pcps_sprint_vernum...()
+ * Added some new macros _pcps_sprint_vernum...()
* and _pcps_sprint_dev_id().
* Revision 1.5 2002/02/19 10:01:36Z MARTIN
* New initializers for string mode names.
@@ -108,14 +117,13 @@
/* Other headers to be included */
-#include <mbg_tgt.h>
-#include <parmpcps.h>
+#include <str_util.h>
+#include <charcode.h>
+#include <cfg_hlp.h>
+#include <pcpsdev.h>
#include <ctrydttm.h>
#include <cnv_wday.h>
-#if MBG_TGT_HAS_WCHAR_T
- #include <wchar.h>
-#endif
#ifdef _PCPSLSTR
#define _ext
@@ -127,92 +135,57 @@
/* Start of header body */
-// upper case 'A' umlaut
-#define ANSI_UC_A_UML '\xC4' // single char
-#define ANSI_US_A_UML "\xC4" // string
-
-// upper case 'O' umlaut
-#define ANSI_UC_O_UML '\xD6' // single char
-#define ANSI_US_O_UML "\xD6" // string
-
-// upper case 'U' umlaut
-#define ANSI_UC_U_UML '\xDC' // single char
-#define ANSI_US_U_UML "\xDC" // string
-
-// lower case 'a' umlaut
-#define ANSI_LC_A_UML '\xE4' // single char
-#define ANSI_LS_A_UML "\xE4" // string
-
-// lower case 'o' umlaut
-#define ANSI_LC_O_UML '\xF6' // single char
-#define ANSI_LS_O_UML "\xF6" // string
-
-// lower case 'u' umlaut
-#define ANSI_LC_U_UML '\xFC' // single char
-#define ANSI_LS_U_UML "\xFC" // string
-
-// 'sz' umlaut
-#define ANSI_LC_SZ_UML '\xDF' // single char
-#define ANSI_LS_SZ_UML "\xDF" // string
-
-// degree character
-#define ANSI_C_DEGREE '\xB0' // single char
-#define ANSI_S_DEGREE "\xB0" // string
+#ifdef __cplusplus
+extern "C" {
+#endif
-// greek mu character
-#define ANSI_C_MU '\xB5' //single char
-#define ANSI_S_MU "\xB5" //string
#if defined( MBG_TGT_WIN32 ) \
- || defined( MBG_TGT_UNIX ) \
+ || defined( MBG_TGT_POSIX ) \
|| defined( MBG_TGT_QNX )
+
#define DEFAULT_PCPS_WDAY_DATE_DIST 1
#define DEFAULT_PCPS_DATE_TIME_DIST 2
#define DEFAULT_PCPS_TIME_TZ_DIST 1
- #define UCAE ANSI_US_A_UML
- #define UCOE ANSI_US_O_UML
- #define UCUE ANSI_US_U_UML
-
- #define LCAE ANSI_LS_A_UML
- #define LCOE ANSI_LS_O_UML
- #define LCUE ANSI_LS_U_UML
-
- #define LCSZ ANSI_LS_SZ_UML
- #define DEG ANSI_S_DEGREE
- #define MU ANSI_S_MU
#else
+
#define DEFAULT_PCPS_WDAY_DATE_DIST 1
#define DEFAULT_PCPS_DATE_TIME_DIST 2
#define DEFAULT_PCPS_TIME_TZ_DIST 1
- #define UCAE "\x8E"
- #define UCOE "\x99"
- #define UCUE "\x9A"
-
- #define LCAE "\x84"
- #define LCOE "\x94"
- #define LCUE "\x81"
-
- #define LCSZ "\xE1"
- #define DEG "\xF8"
- #define MU "\xE6"
#endif
-// The flags defined below can be passed to pcps_tz_name()
-// in order to control the generation of time zone names
-enum
+/**
+ * @brief Flag bits used to define ::PCPS_TZ_NAME_FLAGS
+ *
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
+enum PCPS_TZ_NAME_BITS
{
- PCPS_TZ_NAME_BIT_FORCE_UTC_OFFS, // always print "UTC+offs"
- PCPS_TZ_NAME_BIT_APP_DST, // append DST status
+ PCPS_TZ_NAME_BIT_FORCE_UTC_OFFS, ///< always print "UTC+offs"
+ PCPS_TZ_NAME_BIT_APP_DST, ///< append DST status
N_PCPS_TZ_NAME_FLAG
};
-// bit masks corresponding to the flags above
-#define PCPS_TZ_NAME_FORCE_UTC_OFFS ( 1UL << PCPS_TZ_NAME_BIT_FORCE_UTC_OFFS )
-#define PCPS_TZ_NAME_APP_DST ( 1UL << PCPS_TZ_NAME_BIT_APP_DST )
+
+/**
+ * @brief Flag bits used to control the string generated by ::pcps_tz_name
+ *
+ * The flags defined below can be passed to ::pcps_tz_name
+ * to control the formatting of the generated time zone names
+ *
+ * @see ::pcps_tz_name
+ * @see ::PCPS_TZ_NAME_BITS
+ */
+enum PCPS_TZ_NAME_FLAGS
+{
+ PCPS_TZ_NAME_FORCE_UTC_OFFS = ( 1UL << PCPS_TZ_NAME_BIT_FORCE_UTC_OFFS ), ///< see ::PCPS_TZ_NAME_FORCE_UTC_OFFS
+ PCPS_TZ_NAME_APP_DST = ( 1UL << PCPS_TZ_NAME_BIT_APP_DST ), ///< see ::PCPS_TZ_NAME_APP_DST
+};
+
// The definitions below are used with pcps_get_status_strs().
@@ -467,7 +440,7 @@ typedef struct
#define DEFAULT_TZCODE_HINT_CET_CEST \
{ \
- "Central European Time or Summer Time, as broadcasted by DCF77", \
+ "Central European Time or Summer Time, as broadcast by DCF77", \
"Mitteleurop" LCAE "ische Zeit oder Sommerzeit, wie von DCF77 gesendet" \
}
@@ -479,7 +452,7 @@ typedef struct
#define DEFAULT_TZCODE_HINT_GMT_BST \
{ \
- "Greenwich Mean Time or British Summer Time, as broadcasted by MSF", \
+ "Greenwich Mean Time or British Summer Time, as broadcast by MSF", \
"Westeurop" LCAE "ische Zeit oder britische Sommerzeit, wie von MSF gesendet" \
}
@@ -568,6 +541,15 @@ typedef struct
}
+// menu option: setup distance from transmitter
+
+#define DEFAULT_OPT_NAME_TR_DISTANCE \
+{ \
+ "Distance from Transmitter", \
+ "Senderentfernung" \
+}
+
+
// menu option: setup IRIG config
#define DEFAULT_OPT_NAME_IRIG_TX_EN "IRIG Output"
@@ -791,12 +773,16 @@ typedef struct
#define GER_POUT_NAME_DCF77 "DCF77-Zeitmarken"
#define GER_POUT_NAME_POS_OK "Position OK"
#define GER_POUT_NAME_TIME_SYNC "Zeit synchron"
-#define GER_POUT_NAME_ALL_SYNC "alles synchron"
+#define GER_POUT_NAME_ALL_SYNC "Alles synchron"
#define GER_POUT_NAME_TIMECODE "DCLS-Zeitcode"
-#define GER_POUT_NAME_TIMESTR "COM-Zeittelegramm"
+#define GER_POUT_NAME_TIMESTR "Serielles Zeittelegramm"
#define GER_POUT_NAME_10MHZ "Festfrequenz 10 MHz"
#define GER_POUT_NAME_DCF77_M59 "DCF77-Zeitmarken mit 59. Impuls"
-#define GER_POUT_NAME_SYNTH "Frequenz-Synthesizer"
+#define GER_POUT_NAME_SYNTH "Synthesizer-Frequenz"
+#define GER_POUT_NAME_TIME_SLOTS "Zeitschlitze pro Minute"
+#define GER_POUT_NAME_GPIO "GPIO-Signal"
+#define GER_POUT_PTTI_PPS "PTTI 1 PPS"
+#define GER_POUT_HAVEQUICK "HaveQuick"
#define DEFAULT_GER_POUT_NAMES \
{ \
@@ -815,7 +801,11 @@ typedef struct
GER_POUT_NAME_TIMESTR, \
GER_POUT_NAME_10MHZ, \
GER_POUT_NAME_DCF77_M59, \
- GER_POUT_NAME_SYNTH \
+ GER_POUT_NAME_SYNTH, \
+ GER_POUT_NAME_TIME_SLOTS, \
+ GER_POUT_NAME_GPIO, \
+ GER_POUT_PTTI_PPS, \
+ GER_POUT_HAVEQUICK \
}
/*
@@ -838,6 +828,10 @@ typedef struct
#define GER_POUT_HINT_10MHZ "Feste Ausgangsfrequenz 10 MHz"
#define GER_POUT_HINT_DCF77_M59 "Zeitmarken wie DCF77, aber mit 500 ms Impuls in 59. Sekunde"
#define GER_POUT_HINT_SYNTH "Durch programmierbaren Synthesizer erzeugte Frequenz"
+#define GER_POUT_HINT_TIME_SLOTS "Programmierbare Zeitslots, die in jeder Minute aktiviert werden"
+#define GER_POUT_HINT_GPIO "Signal des spezifizierten GPIO-Ein- oder Ausgangs"
+#define GER_POUT_HINT_PTTI_PPS "20 us-Impuls zum Sekundenbeginn"
+#define GER_POUT_HINT_HAVEQUICK "Dupliziertes HaveQuick-Signal"
#define DEFAULT_GER_POUT_HINTS \
{ \
@@ -856,83 +850,80 @@ typedef struct
GER_POUT_HINT_TIMESTR, \
GER_POUT_HINT_10MHZ, \
GER_POUT_HINT_DCF77_M59, \
- GER_POUT_HINT_SYNTH \
+ GER_POUT_HINT_SYNTH, \
+ GER_POUT_HINT_TIME_SLOTS, \
+ GER_POUT_HINT_GPIO, \
+ GER_POUT_HINT_PTTI_PPS, \
+ GER_POUT_HINT_HAVEQUICK \
}
// some macros which generate proper function calls
-#define _pcps_sprint_vernum_dec( _s, _v ) \
- sprintf( (_s), "v%u.%02u", \
- ( (unsigned) (_v) ) / 100, \
- ( (unsigned) (_v) ) % 100 )
+#define _pcps_snprint_vernum_dec( _s, _sz, _v ) \
+ snprintf_safe( (_s), (_sz), "v%u.%02u", \
+ ( (unsigned) (_v) ) / 100, \
+ ( (unsigned) (_v) ) % 100 )
-#define _pcps_sprint_vernum_hex( _s, _v ) \
- sprintf( (_s), "v%X.%02X", \
- ( (unsigned) (_v) ) >> 8, \
+#define _pcps_snprint_vernum_hex( _s, _sz, _v ) \
+ snprintf_safe( (_s), (_sz), "v%X.%02X", \
+ ( (unsigned) (_v) ) >> 8, \
( (unsigned) (_v) ) & 0xFF )
#if defined( MBG_TGT_WIN32 )
- #define _pcps_sprint_vernum _pcps_sprint_vernum_dec
+ #define _pcps_snprint_vernum _pcps_snprint_vernum_dec
#else
- #define _pcps_sprint_vernum _pcps_sprint_vernum_hex
+ #define _pcps_snprint_vernum _pcps_snprint_vernum_hex
#endif
-#define _pcps_sprint_dev_id( _s, _n ) \
- sprintf( (_s), "%04Xh", _n )
+#define _pcps_snprint_dev_id( _s, _sz, _n ) \
+ snprintf_safe( (_s), (_sz), "%04Xh", _n )
-#define _pcps_sprint_wday( _s, _t, _l ) \
- sprint_ctry_wday( (_s), _wday_mon17_to_sun06( (_t)->wday ), (_l) )
+#define _pcps_snprint_wday( _s, _sz, _t, _l ) \
+ snprint_ctry_wday( (_s), (_sz), _wday_mon17_to_sun06( (_t)->wday ), (_l) )
-#define _pcps_sprint_date( _s, _t, _yl ) \
- sprint_ctry_dt( (_s), (_t)->mday, (_t)->month, \
+#define _pcps_snprint_date( _s, _sz, _t, _yl ) \
+ snprint_ctry_dt( (_s), (_sz), (_t)->mday, (_t)->month, \
pcps_exp_year( (_t)->year, (_yl) ) )
-#define _pcps_sprint_time( _s, _t ) \
- sprint_ctry_tm( (_s), (_t)->hour, (_t)->min, (_t)->sec )
+#define _pcps_snprint_time( _s, _sz, _t ) \
+ snprint_ctry_tm( (_s), (_sz), (_t)->hour, (_t)->min, (_t)->sec )
-#define _pcps_sprint_time_long( _s, _t ) \
- sprint_ctry_tm_long( (_s), (_t)->hour, (_t)->min, (_t)->sec, (_t)->sec100, 2 )
+#define _pcps_snprint_time_long( _s, _sz, _t ) \
+ snprint_ctry_tm_long( (_s), (_sz), (_t)->hour, (_t)->min, (_t)->sec, (_t)->sec100, 2 )
-#define _cput_pcps_date( _t, _yl ) \
-{ \
- char s[80]; \
- _pcps_sprint_date( s, (_t), (_yl) ); \
- cputs( s ); \
+#define _cput_pcps_date( _t, _yl ) \
+{ \
+ char s[80]; \
+ _pcps_snprint_date( s, sizeof( s ), (_t), (_yl) ); \
+ cputs( s ); \
}
-#define _cput_pcps_time( _t ) \
-{ \
- char s[80]; \
- _pcps_sprint_time( s, (_t) ); \
- cputs( s ); \
+#define _cput_pcps_time( _t ) \
+{ \
+ char s[80]; \
+ _pcps_snprint_time( s, sizeof( s ), (_t) ); \
+ cputs( s ); \
}
-#define _cput_pcps_time_long( _t ) \
-{ \
- char s[80]; \
- _pcps_sprint_time_long( s, (_t) ); \
- cputs( s ); \
+#define _cput_pcps_time_long( _t ) \
+{ \
+ char s[80]; \
+ _pcps_snprint_time_long( s, sizeof( s ), (_t) ); \
+ cputs( s ); \
}
-#define _cput_pcps_date_and_time( _t, _yl, _tz ) \
-{ \
- char s[80]; \
- cputs( pcps_date_time_str( s, (_t), (_yl), (_tz) ) ); \
+#define _cput_pcps_date_and_time( _t, _yl, _tz ) \
+{ \
+ char s[80]; \
+ cputs( pcps_date_time_str( s, sizeof( s ), (_t), (_yl), (_tz) ) ); \
}
-_ext const char *str_not_avail
-#ifdef _DO_INIT
- = "N/A"
-#endif
-;
-
-
_ext CLSTR lstr_cet
#ifdef _DO_INIT
= { TZ_NAME_CET, TZ_NAME_MEZ }
@@ -1001,27 +992,109 @@ _ext const char *short_mode_name[N_STR_MODE]
;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
+ /**
+ * @brief Return a language dependend string for "invalid"
+ *
+ * @return A language dependend string for "invalid"
+ */
const char *inv_str( void ) ;
- int sprint_utc_offs( char *s, const char *info, long utc_offs ) ;
+
+ /**
+ * @brief Print the UTC offset into a string
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] info An optional info string to be prepended, may be NULL
+ * @param[in] utc_offs UTC offset in [s]
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ */
+ size_t snprint_utc_offs( char *s, size_t max_len, const char *info, long utc_offs ) ;
+
+ /**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_TIME structure
+ *
+ * @param[in] t A ::PCPS_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_hr_status
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name( const PCPS_TIME *t, ushort flags, int is_msf ) ;
+
+ /**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * @param[in] hrt A ::PCPS_HR_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_hr_status
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name_from_hr_time( const PCPS_HR_TIME *hrt, ushort flags, int is_msf ) ;
+
+ /**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * This function can be used to build a name for the time zone if the timescale,
+ * the %UTC/DST status and the %UTC offset are known, e.g. from plug-in clock devices.
+ *
+ * @param[in] t A ::PCPS_HR_TIME structure read from a clock device
+ * @param[in] flags A combination of ::PCPS_TZ_NAME_FLAGS contolling the output string format
+ * @param[in] is_msf A Flag used to indicate if the clock is an MSF receiver
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_from_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
const char *pcps_tz_name_hr_status( const PCPS_HR_TIME *t, ushort flags, int is_msf ) ;
- const char *pcps_tz_name_from_status( ushort status ) ;
- char *pcps_date_time_str( char *s, const PCPS_TIME *t, ushort year_limit, const char *tz_str ) ;
- wchar_t *pcps_date_time_wstr( wchar_t *ws, const PCPS_TIME *t, ushort year_limit, const wchar_t *tz_str ) ;
+
+ /**
+ * @brief Return a static time zone string depending on the UTC offset from a ::PCPS_HR_TIME structure
+ *
+ * This function can be used to build a name for the time zone
+ * if only the %UTC/DST status is known, but the UTC offset is not.
+ * This is the case, for example, if the Meinberg standard time string is decoded.
+ *
+ * @param[in] status Clock status in ::PCPS_TIME_STATUS_X format
+ *
+ * @return Pointer to a static string which has been set up
+ *
+ * @see ::pcps_tz_name
+ * @see ::pcps_tz_name_from_hr_time
+ * @see ::pcps_tz_name_hr_status
+ * @see ::get_tz_name
+ * @see ::PCPS_TZ_NAME_FLAGS
+ */
+ const char *pcps_tz_name_from_status( PCPS_TIME_STATUS_X status ) ;
+
+ char *pcps_date_time_str( char *s, size_t max_len, const PCPS_TIME *t, ushort year_limit, const char *tz_str ) ;
+ wchar_t *pcps_date_time_wstr( wchar_t *ws, size_t count, const PCPS_TIME *t, ushort year_limit, const wchar_t *tz_str ) ;
void pcps_status_strs( ushort status, int status_is_read, int is_gps, PCPS_STATUS_STRS *pstrs ) ;
- char *pcps_port_str( char *s, const PCPS_DEV *pdev ) ;
+ char *pcps_port_str( char *s, size_t max_len, const PCPS_DEV *pdev ) ;
const char *pcps_tzcode_str( PCPS_TZCODE tzcode ) ;
- char *pcps_serial_str( char *s, int i, const RECEIVER_PORT_CFG *p, const RECEIVER_INFO *p_ri, int short_strs ) ;
+ char *pcps_serial_str( char *s, size_t max_len, int i, const RECEIVER_PORT_CFG *p, const RECEIVER_INFO *p_ri, int short_strs ) ;
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.c b/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.c
index 212dfb3..b26b1a8 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsmktm.c 1.4 2006/12/14 15:27:49 martin REL_M $
+ * $Id: pcpsmktm.c 1.5 2017/07/05 08:05:11 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsmktm.c $
+ * Revision 1.5 2017/07/05 08:05:11 martin
+ * Let pcps_mktime() return a 'time_t' instead of 'long', and made
+ * the PCPS_TIME pointer parameter 'const'.
+ * Added doxygen comments.
* Revision 1.4 2006/12/14 15:27:49 martin
* Include time.h.
* Revision 1.3 2006/08/22 09:10:03 martin
@@ -27,25 +31,40 @@
#include <mbgmktm.h>
-#include <time.h>
/*HDR*/
-long pcps_mktime( PCPS_TIME *tp )
+/**
+ * @brief Compute a linear time_t value from ::PCPS_TIME
+ *
+ * This function works like the standard mktime() function but does not
+ * account for a timezone setting configured for the standard C library.
+ * Instead, since ::PCPS_TIME contains local time with specified UTC offset
+ * the UTC offset is removed to yield UTC time.
+ *
+ * @param[in] tp A timestamp in ::PCPS_TIME format
+ *
+ * @return seconds since 1970-01-01 (Unix time_t format) or ((time_t) -1) if range overflow
+ */
+time_t pcps_mktime( const PCPS_TIME *tp )
{
time_t secs;
int year = tp->year;
+ // Expand 2 digit year number (year of the century) to 4 digits
+ // including the century.
if ( year < 70 )
year += 100;
+ // Plausibility checks are made by mbg_mktime().
secs = mbg_mktime( year, tp->month - 1, tp->mday - 1,
tp->hour, tp->min, tp->sec );
- if ( secs != -1 )
- secs -= tp->offs_utc * 3600;
+ // Convert to UTC if result is valid.
+ if ( secs != ( (time_t) -1 ) )
+ secs -= tp->offs_utc * 3600UL;
- return( secs );
+ return secs;
} // pcps_mktime
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.h
index efcc2df..eb4c05b 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsmktm.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsmktm.h 1.1 2001/02/02 15:31:07 MARTIN REL_M $
+ * $Id: pcpsmktm.h 1.2 2017/07/05 08:18:54 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsmktm.h $
+ * Revision 1.2 2017/07/05 08:18:54 martin
+ * Cleaned up to conform to standard header file format.
+ * Updated function prototypes.
* Revision 1.1 2001/02/02 15:31:07 MARTIN
*
**************************************************************************/
@@ -22,9 +25,12 @@
#include <pcpsdefs.h>
+#include <time.h>
+
#ifdef _PCPSMKTM
#define _ext
+ #define _DO_INIT
#else
#define _ext extern
#endif
@@ -32,25 +38,31 @@
/* Start of header body */
-//_ext PCPS_TIME tx;
-
-/* End of header body */
-
-#undef _ext
-
-
-/* function prototypes: */
-
#ifdef __cplusplus
extern "C" {
#endif
+
+
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
- long pcps_mktime( PCPS_TIME *tp ) ;
+ /**
+ * @brief Compute a linear time_t value from ::PCPS_TIME
+ *
+ * This function works like the standard mktime() function but does not
+ * account for a timezone setting configured for the standard C library.
+ * Instead, since ::PCPS_TIME contains local time with specified UTC offset
+ * the UTC offset is removed to yield UTC time.
+ *
+ * @param[in] tp A timestamp in ::PCPS_TIME format
+ *
+ * @return seconds since 1970-01-01 (Unix time_t format) or ((time_t) -1) if range overflow
+ */
+ time_t pcps_mktime( const PCPS_TIME *tp ) ;
+
/* ----- function prototypes end ----- */
@@ -58,5 +70,9 @@ extern "C" {
}
#endif
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
#endif /* _PCPSMKTM_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.c b/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.c
deleted file mode 100755
index 0dcf53d..0000000
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.c
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/**************************************************************************
- *
- * $Id: pcpsutil.c 1.14 2011/06/29 11:03:44 martin TRASH $
- *
- * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
- *
- * Description:
- * Utility functions used with programs for Meinberg devices.
- *
- * -----------------------------------------------------------------------
- * $Log: pcpsutil.c $
- * Revision 1.14 2011/06/29 11:03:44 martin
- * Updated a comment.
- * Revision 1.13 2009/03/09 13:39:45 martin
- * Made pcps_exp_year() an inline function.
- * Revision 1.12 2008/12/10 19:59:48 martin
- * Made frac_sec_from_bin() an inline function.
- * Revision 1.11 2008/11/25 10:00:25 martin
- * Use new definitions of fraction conversion type and scale
- * from pcpsdefs.h.
- * Revision 1.10 2006/06/29 10:38:24Z martin
- * New function pcps_time_is_valid().
- * Modified pcps_str_to_port(), doesn't add a 0 entry to the list anymore.
- * Fixed a compiler warning related to type conversion.
- * Revision 1.9 2005/01/14 10:14:31Z martin
- * Changed type of ISA port addr to int.
- * Revision 1.8 2004/11/09 14:29:27Z martin
- * Rewrote functions using C99 fixed-size definitions.
- * Revision 1.7 2003/04/17 10:08:59Z martin
- * Added some type casts to fix compiler warnings.
- * Revision 1.6 2001/11/28 14:39:16Z MARTIN
- * In frac_sec_from_bin(), define the divisor as floating point
- * constant to avoid a domain errors on 16 bit systems.
- * Revision 1.5 2001/09/17 07:28:01 MARTIN
- * New function frac_sec_from_bin() to convert
- * PCPS_HR_TIME fractions.
- * Revision 1.4 2001/03/01 14:01:09 MARTIN
- * Modified parameters for pcps_setup_isa_ports().
- * Revision 1.3 2000/08/31 14:05:30 MARTIN
- * Replaced pcps_str_to_port() by pcps_setup_isa_ports().
- * Revision 1.2 2000/07/21 13:42:54 MARTIN
- * Initial revision
- *
- **************************************************************************/
-
-#define _PCPSUTIL
- #include <pcpsutil.h>
-#undef _PCPSUTIL
-
-#include <stdlib.h>
-
-
-/*--------------------------------------------------------------
- * Name: pcps_time_is_valid()
- *
- * Purpose: Pack a structure with serial port parameters
- *
- * Input/Output: p address of a structure holding both the
- * packed and unpacked information
- *
- * Ret value: --
- *-------------------------------------------------------------*/
-
-/*HDR*/
-int pcps_time_is_valid( const PCPS_TIME *p )
-{
- return ( p->sec100 <= 99 )
- && ( p->sec <= 60 ) /* allow for leap second */
- && ( p->min <= 59 )
- && ( p->hour <= 23 )
- && ( p->mday >= 1 ) && ( p->mday <= 31 )
- && ( p->wday >= 1 ) && ( p->wday <= 7 )
- && ( p->month >= 1 ) && ( p->month <= 12 )
- && ( p->year <= 99 );
-
-} /* pcps_time_is_valid */
-
-
-
-/*--------------------------------------------------------------
- * Name: pcps_str_to_port()
- *
- * Purpose: Try to convert a string to a valid port
- * address.
- *
- * Input: s the string
- *
- * Output: --
- *
- * Ret value: a valid port number or 0
- *+-------------------------------------------------------------*/
-
-/*HDR*/
-void pcps_setup_isa_ports( char *s,
- int *port_vals,
- int n_vals )
-{
- ushort i;
-
-
- for ( i = 0; i < n_vals; i++ )
- {
- if ( *s == 0 )
- break;
-
- *port_vals++ = (uint16_t) strtoul( s, &s, 16 );
-
- if ( *s == ',' )
- s++;
- }
-
-} // pcps_setup_isa_ports
-
-
-
-/*--------------------------------------------------------------
- * Name: pcps_unpack_serial()
- *
- * Purpose: Unpack a structure with serial port parameters
- *
- * Input/Output: p address of a structure holding both the
- * packed and unpacked information
- *
- * Ret value: --
- *-------------------------------------------------------------*/
-
-/*HDR*/
-void pcps_unpack_serial( PCPS_SER_PACK *p )
-{
- uint8_t pack = p->pack;
-
- p->baud = (uint8_t) ( pack & BITMASK( PCPS_BD_BITS ) );
- p->frame = (uint8_t) ( ( pack >> PCPS_FR_SHIFT ) & BITMASK( PCPS_FR_BITS ) );
- p->mode = (uint8_t) ( ( pack >> PCPS_MOD_SHIFT ) & BITMASK( PCPS_MOD_BITS ) );
-
-} // pcps_unpack_serial
-
-
-
-/*--------------------------------------------------------------
- * Name: pcps_pack_serial()
- *
- * Purpose: Pack a structure with serial port parameters
- *
- * Input/Output: p address of a structure holding both the
- * packed and unpacked information
- *
- * Ret value: --
- *-------------------------------------------------------------*/
-
-/*HDR*/
-void pcps_pack_serial( PCPS_SER_PACK *p )
-{
- p->pack = (uint8_t) ( ( p->baud & BITMASK( PCPS_BD_BITS ) )
- | ( ( p->frame & BITMASK( PCPS_FR_BITS ) ) << PCPS_FR_SHIFT )
- | ( ( p->mode & BITMASK( PCPS_MOD_BITS ) ) << PCPS_MOD_SHIFT ) );
-
-} /* pcps_pack_serial */
-
-
-
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.h b/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.h
index e5cab81..29dfdc7 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/pcpsutil.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: pcpsutil.h 1.14 2009/03/09 13:39:45 martin REL_M $
+ * $Id: pcpsutil.h 1.23 2017/05/10 15:26:09 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,27 @@
*
* -----------------------------------------------------------------------
* $Log: pcpsutil.h $
+ * Revision 1.23 2017/05/10 15:26:09 martin
+ * Tiny cleanup.
+ * Revision 1.22 2017/03/17 11:45:51 martin
+ * Moved binary fraction conversion functions to cfg_hlp.h.
+ * Revision 1.21 2015/10/26 16:09:58 martin
+ * Moved definition of PCPS_SER_PACK to deviohlp.h.
+ * The .c file is now obsolete, so there are no prototypes anymore.
+ * Revision 1.20 2014/07/22 12:22:27Z martin
+ * Fixed a compiler warning.
+ * Revision 1.19 2014/07/14 15:43:23Z martin
+ * Updated doxygen comment.
+ * Revision 1.18 2014/06/26 14:52:50 martin
+ * Fixed build on targets not supporting 64 bit types.
+ * Updated some comments to doxygen format.
+ * Revision 1.17 2014/05/27 10:39:33Z martin
+ * More inline functions to convert binary fractions by thomas-b.
+ * Moved definitions of some signal constants to pcpsdefs.h.
+ * Revision 1.16 2013/03/04 15:51:02Z martin
+ * Added dfrac_sec_from_bin().
+ * Revision 1.15 2012/10/15 09:41:32 martin
+ * Cleaned up handling of pragma pack().
* Revision 1.14 2009/03/09 13:39:45 martin
* Made pcps_exp_year() an inline function.
* Revision 1.13 2008/12/10 19:59:48 martin
@@ -63,48 +84,27 @@
/* Start of header body */
-#if defined( _USE_PACK ) // set byte alignment
- #pragma pack( 1 )
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
#endif
-
-// The following constants are used to draw a signal bar
-// depending on a DCF77 clock's signal value:
-#define PCPS_SIG_BIAS 55
-#define PCPS_SIG_ERR 1
-#define PCPS_SIG_MIN 20
-#define PCPS_SIG_MAX 68
-
-
-// the structure below is used with a DCF77 clock's serial interface
-typedef struct
-{
- PCPS_SERIAL pack; // this byte is passed to the board as parameter
-
- uint8_t baud; // the other bytes can hold the unpacked values
- uint8_t frame;
- uint8_t mode;
-
-} PCPS_SER_PACK;
-
+#ifdef __cplusplus
+extern "C" {
+#endif
-/*--------------------------------------------------------------
- * Name: pcps_exp_year()
- *
- * Purpose: Convert a 2-digit year number to a 4-digit
- * year number. The resulting year number is in
- * the range [year_lim ... ( year_lim + 99 )].
+/**
+ * @brief Expand a 2-digit year number to a 4-digit year number
*
- * Input: year the 2-digit year number
- * year_lim the smallest 4-digit year number
- * to be returned
+ * The resulting year number includes the century and is
+ * in the range [year_lim ... ( year_lim + 99 )].
*
- * Output: --
+ * @param[in] year The 2-digit year number to be converted
+ * @param[in] year_lim The smallest 4-digit year number to be returned
*
- * Ret value: the calculated 4-digit year num
- *+-------------------------------------------------------------*/
-
+ * @return The resulting 4 digit year number including century
+ */
static __mbg_inline
uint16_t pcps_exp_year( uint8_t year, uint16_t year_lim )
{
@@ -120,21 +120,12 @@ uint16_t pcps_exp_year( uint8_t year, uint16_t year_lim )
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
- int pcps_time_is_valid( const PCPS_TIME *p ) ;
- void pcps_setup_isa_ports( char *s, int *port_vals, int n_vals ) ;
- void pcps_unpack_serial( PCPS_SER_PACK *p ) ;
- void pcps_pack_serial( PCPS_SER_PACK *p ) ;
+/* (no header definitions found) */
/* ----- function prototypes end ----- */
@@ -143,36 +134,10 @@ extern "C" {
#endif
-/*--------------------------------------------------------------
- * Name: frac_sec_from_bin()
- *
- * Purpose: Convert a fraction of a second from binary
- * format (as returned in a PCPS_HR_TIME structure
- * to a decimal fraction, using a specified scale
- * factor. See also the definitions of
- * PCPS_HRT_FRAC_SCALE and PCPS_HRT_FRAC_SCALE_FMT
- * in the header file.
- *
- * Input: b the binary fraction
- * scale the scale factor
- *
- * Output: --
- *
- * Ret value: the calculated number
- *+-------------------------------------------------------------*/
-
-static __mbg_inline
-uint32_t frac_sec_from_bin( uint32_t b, uint32_t scale )
-{
- return (uint32_t) ( (PCPS_HRT_FRAC_CONVERSION_TYPE) b * scale
- / PCPS_HRT_BIN_FRAC_SCALE );
-
-} // frac_sec_from_bin
-
-
-#if defined( _USE_PACK ) // set default alignment
- #pragma pack()
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
#endif
/* End of header body */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/plxdefs.h b/src/external/bsd/meinberg/dist/mbglib/common/plxdefs.h
index ba1ce53..f59cc0d 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/plxdefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/plxdefs.h
@@ -1,16 +1,36 @@
/**************************************************************************
*
- * $Id: plxdefs.h 1.2 2010/01/28 15:46:31 martin REL_M $
+ * $Id: plxdefs.h 1.5 2017/05/10 15:26:09 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
- * Definitions to be used with PLX PCIexpress interface chips.
+ * Definitions to be used with PLX PCI Express interface chips.
+ * Some Meinberg cards use the PLX8311 chip in endpoint mode.
+ *
+ * The PLX8311 chip is combined of a PLX8111 PCIe-to-PCI bridge
+ * plus a PCI-to-Local bus interface combined in a single package.
+ * Thus each card using a PLX8311 implements an additional internal
+ * PCI bus with a single device connected to this bus.
+ *
+ * Each of these devices are individually visible from the PC's
+ * PCI bus and thus provide their own configuration spaces,
+ * configuration EEPROM, etc.
+ *
+ * Care must be taken not to confuse the registers of the PLX8311
+ * with the correspondent registers of the built-in PLX8111 bridge.
*
* -----------------------------------------------------------------------
* $Log: plxdefs.h $
- * Revision 1.2 2010/01/28 15:46:31 martin
+ * Revision 1.5 2017/05/10 15:26:09 martin
+ * Tiny cleanup.
+ * Revision 1.4 2013/03/15 10:24:09 martin
+ * Renamed register and bit mask definitions to match the names in the data sheet.
+ * Added doxygen comments.
+ * Revision 1.3 2012/10/15 09:21:42Z martin
+ * Added some mailbox register addresses.
+ * Revision 1.2 2010/01/28 15:46:31Z martin
* Added PLX8311_REG_CTRL.
* Revision 1.1 2007/06/08 07:46:56Z martin
* Initial revision.
@@ -20,7 +40,6 @@
#ifndef _PLXDEFS_H
#define _PLXDEFS_H
-
/* Other headers to be included */
@@ -33,31 +52,113 @@
/* Start of header body */
-// The following PLX8311 operation registers can
-// be accessed via port I/O or memory mapped:
-#define PLX8311_REG_INTCSR 0x68
+#ifdef __cplusplus
+extern "C" {
+#endif
-// The following bits must be set in the INTCSR register
-// to let the local microcontroller be able to generate
-// interrupts on the PCI bus via the chip's LINTi# line:
-#define PLX8311_INT_ENB ( (1UL << 11) | (1UL << 8) )
+/**
+ * PCI device ID of the PCI bridge also built into the PLX8311
+ */
+#define PCI_DEVICE_ID_PLX_8111 0x8111
-// The bit below signals if an LINTi# interrupt is active:
-#define PLX8311_INT_FLAG (1UL << 15)
-#define PLX8311_REG_CNTRL 0x6C
+/**
+ * @brief PLX PCI Express Configuration Space (PECS) registers
+ *
+ * These registers are located in the PCI configuration space
+ * and can be accessed using standard PCI configuration register
+ * access functions.
+ *
+ * In addition the PECS registers are mirrored into the 64k
+ * memory space addressed via PCI base register 0, and thus
+ * can be accessed using memory reads or writes via the PCI bus.
+ *
+ * The default values of these registers can be overwritten
+ * by the PCI Express interface serial EEPROM.
+ *
+ * Care must be taken not to confuse the registers of the PLX8311
+ * with the correspondent registers of the built-in PLX8111.
+ * Similarly the serial EEPROM for the PLX8311 must not be confused
+ * with the serial EEPROM for the built-in PEX8111 PCI bridge.
+ *
+ * Address Offset:
+ * 0000h - 0FFFh PCI compatible configuration registers
+ * 1000h - 1FFFh Main configuration registers
+ * 2000h - 2FFFh Memory mapped indirect access (PLX8311 only, see manual)
+ * 8000h - 9FFFh 8k internal shared memory
+ *
+ * See chapter 19 of the PLX8311 manual.
+ */
+enum PLX_PECS_REGS
+{
+ PLX_PECS_PCICAPPTR = 0x34, ///< PCI capabilities pointer
+ // PLX_PECS_LINKSTAT = 0x72, ///< Link status
+ PLX_PECS_MAININDEX = 0x84, ///< Main Control Register index
+ PLX_PECS_MAINDATA = 0x88, ///< Main Control Register data
+
+ PLX_PECS_EECTL = 0x1004, ///< Serial EEPROM control
+ PLX_PECS_EECLKFREQ = 0x1008, ///< Serial EEPROM clock frequency control
+ PLX_PECS_GPIOCTL = 0x1020, ///< General Purpose I/O control
+ PLX_PECS_GPIOSTAT = 0x1024, ///< General Purpose I/O status
+ PLX_PECS_TLPCFG0 = 0x1048, ///< TLP controller configuration 0
+
+ N_PLX_PECS_REGS // dummy
+};
+
+
+// Bit masks used with the PLX_PECS_EECTL register.
+// See chap 18.10 of the manual
+#define PLX_PECS_EECTL_WRITE_DATA_SHIFT 0
+#define PLX_PECS_EECTL_READ_DATA_SHIFT 8
+#define PLX_PECS_EECTL_WRITE_START ( 1UL << 16 )
+#define PLX_PECS_EECTL_READ_START ( 1UL << 17 )
+#define PLX_PECS_EECTL_CS_ENB ( 1UL << 18 )
+#define PLX_PECS_EECTL_BUSY ( 1UL << 19 )
+#define PLX_PECS_EECTL_VALID ( 1UL << 20 )
+#define PLX_PECS_EECTL_PRESENT ( 1UL << 21 )
+#define PLX_PECS_EECTL_CS_ACTIVE ( 1UL << 22 )
+#define PLX_PECS_EECTL_RELOAD ( 1UL << 31 )
+
+// Bit masks used with the PLX_PECS_EECLKFREQ register.
+#define PLX_PECS_EECLKFREQ_8_3_MHZ 0x02 // 3 LSBs
+
+// Bit masks used with the PLX_PECS_GPIOCTL register.
+#define PLX_PECS_GPIOCTL_GPIO3_DATA ( 1UL << 3 )
+
+
+
+/**
+ * @brief Local Configuration Space (LCS) registers
+ *
+ * These registers are accessed with different addresses from
+ * local or PCI, and these addresses are to be used from PCI.
+ * See chapter 20 of the PLX8311 manual.
+ */
+enum PLX_LCS_REGS_PCI
+{
+ PLX_LCS_INTCSR = 0x68, ///< Interrupt control / status
+ PLX_LCS_CNTRL = 0x6C, ///< 0xEC from local
+
+ N_PLX_LCS_REGS_PCI // dummy
+};
-/* End of header body */
+// Bit masks used with the PLX_LCS_CNTRL register.
+#define PLX_LCS_CNTRL_USERO ( 1UL << 16 )
+#define PLX_LCS_CNTRL_USERI ( 1UL << 17 )
-#undef _ext
+// The following bits must be set in the INTCSR register
+// to let the local microcontroller be able to generate
+// interrupts on the PCI bus via the chip's LINTi# line:
+#define PLX_LCS_INTCSR_INT_ENB ( ( 1UL << 11 ) /* Local Interrupt Input Enable */ \
+ | ( 1UL << 8 ) /* Internal PCI Wire Interrupt Enable */ \
+ )
+
+// The bit below signals if an LINTi# interrupt is active:
+#define PLX_LCS_INTCSR_INT_FLAG ( 1UL << 15 ) /* Local Interrupt Input Active */
-/* function prototypes: */
-#ifdef __cplusplus
-extern "C" {
-#endif
/* ----- function prototypes begin ----- */
@@ -72,5 +173,8 @@ extern "C" {
}
#endif
+/* End of header body */
+
+#undef _ext
#endif /* _PLXDEFS_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/ptp_util.h b/src/external/bsd/meinberg/dist/mbglib/common/ptp_util.h
new file mode 100755
index 0000000..0b4c099
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/ptp_util.h
@@ -0,0 +1,190 @@
+
+/**************************************************************************
+ *
+ * $Id: ptp_util.h 1.6 2017/05/10 15:26:10 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for ptp_util.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: ptp_util.h $
+ * Revision 1.6 2017/05/10 15:26:10 martin
+ * Tiny cleanup.
+ * Revision 1.5 2017/04/25 12:54:21 gregoire.diehl
+ * Merge changes from 1.3.1.7 & 1.4
+ * Revision 1.4 2016/11/10 09:05:26Z martin
+ * Support for PTP Time Monitor role added by udo.
+ * Support for NTP modes added by daniel.
+ * Updated some comments.
+ * Revision 1.3 2013/09/12 11:05:44 martin
+ * Added inline function get_supp_ptp_role_mask().
+ * Revision 1.2 2013/08/06 12:08:06 udo
+ * new ptp_clock_id_from_str()
+ * Revision 1.1 2011/11/14 16:03:39 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _PTP_UTIL_H
+#define _PTP_UTIL_H
+
+
+/* Other headers to be included */
+#include <stdio.h>
+#include <lan_util.h>
+#include <gpsdefs.h>
+
+
+#ifdef _PTP_UTIL
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#if defined( _USE_PACK )
+ #pragma pack( 1 ) // set byte alignment
+ #define _USING_BYTE_ALIGNMENT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Derive a "supported PTP roles" bit mask from ::PTP_CFG_INFO::supp_flags
+ *
+ * The relevant bits used with ::PTP_CFG_INFO::supp_flags have not been
+ * defined sequentially, so we need to test them individually to put a
+ * supported roles bit mask together.
+ *
+ * @note Originally, all devices supported the multicast slave role, so
+ * there was no extra flag to indicate this. However, some newer devices
+ * may not support the multicast slave role, so two new flags have been
+ * introduced to cope with this:<br>
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is set then a different flag
+ * ::PTP_CFG_CAN_BE_MULTICAST_SLAVE needs to be checked to tell if
+ * the multicast slave role is supported, or not.<br>
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is not set then the device
+ * definitely supports the multicast slave role.
+ *
+ * @param flags bit mask from ::PTP_CFG_INFO::supp_flags, see @ref PTP_CFG_FLAG_MASKS
+ *
+ * @return bit mask of supported PTP roles, see ::PTP_ROLE_MASKS
+ */
+static __mbg_inline
+uint32_t get_supp_ptp_role_mask( uint32_t flags )
+{
+ uint32_t role_mask = 0;
+
+ if ( flags & PTP_CFG_MSK_SUPP_MCAST_SLAVE_FLAG )
+ {
+ // multicast slave role is only supported
+ // if a different flag is also set
+ if ( flags & PTP_CFG_MSK_CAN_BE_MULTICAST_SLAVE )
+ role_mask |= PTP_ROLE_MSK_MULTICAST_SLAVE;
+ }
+ else // multicast slave role is definitely supported
+ role_mask |= PTP_ROLE_MSK_MULTICAST_SLAVE;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE )
+ role_mask |= PTP_ROLE_MSK_UNICAST_SLAVE;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER )
+ role_mask |= PTP_ROLE_MSK_MULTICAST_MASTER;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_UNICAST_MASTER )
+ role_mask |= PTP_ROLE_MSK_UNICAST_MASTER;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_MULTICAST_AUTO )
+ role_mask |= PTP_ROLE_MSK_MULTICAST_AUTO;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_BOTH_MASTER )
+ role_mask |= PTP_ROLE_MSK_BOTH_MASTER;
+
+ if ( flags & PTP_CFG_MSK_NTP_HW_TS_MASTER )
+ role_mask |= PTP_ROLE_MSK_NTP_SERVER;
+
+ if ( flags & PTP_CFG_MSK_NTP_HW_TS_SLAVE )
+ role_mask |= PTP_ROLE_MSK_NTP_CLIENT;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_TIME_MONITOR )
+ role_mask |= PTP_ROLE_MSK_TIME_MONITOR;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_V1_MASTER )
+ role_mask |= PTP_ROLE_MSK_V1_MASTER;
+
+ if ( flags & PTP_CFG_MSK_CAN_BE_V1_SLAVE )
+ role_mask |= PTP_ROLE_MSK_V1_SLAVE;
+
+ return role_mask;
+
+} // get_supp_ptp_role_mask
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Get the MAC addr from a PTP clock ID
+ *
+ * The clock ID is usually the MAC ID with 2 octets
+ * 0xFF and 0xFE inserted in the middle.
+ *
+ * @param p_mac_addr The MAC ID to be filled up
+ * @param p_clock_id The PTP clock ID
+ */
+ void mac_from_ptp_clock_id( MBG_MAC_ADDR *p_mac_addr, const PTP_CLOCK_ID *p_clock_id ) ;
+
+ /**
+ * @brief Get the PTP clock ID from the MAC addr
+ *
+ * The clock ID is usually the MAC ID with 2 octets
+ * 0xFF and 0xFE inserted in the middle.
+ *
+ * @param p_clock_id The PTP clock ID
+ * @param p_mac_addr The MAC ID to be filled up
+ */
+ void ptp_clock_id_from_mac( PTP_CLOCK_ID *p_clock_id, const MBG_MAC_ADDR *p_mac_addr ) ;
+
+ /**
+ * @brief Get the PTP clock ID from a string
+ *
+ * The clock ID is usually the MAC ID with 2 octets
+ * 0xFF and 0xFE inserted in the middle.
+ *
+ * @param p_clock_id The PTP clock ID
+ * @param p_str The UUID as string with format e.g. 0050C2FFFED287DE
+ */
+ void ptp_clock_id_from_str( PTP_CLOCK_ID *p_clock_id, const char *p_str ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined( _USING_BYTE_ALIGNMENT )
+ #pragma pack() // set default alignment
+ #undef _USING_BYTE_ALIGNMENT
+#endif
+
+/* End of header body */
+
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _PTP_UTIL_H */
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/rsrc.h b/src/external/bsd/meinberg/dist/mbglib/common/rsrc.h
index 744e443..cc97d76 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/rsrc.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/rsrc.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: rsrc.h 1.4.1.1 2006/09/19 14:52:02 martin TEST $
+ * $Id: rsrc.h 1.6 2017/05/10 15:26:10 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,8 +11,10 @@
*
* -----------------------------------------------------------------------
* $Log: rsrc.h $
- * Revision 1.4.1.1 2006/09/19 14:52:02 martin
- * Preliminary support for *BSD.
+ * Revision 1.6 2017/05/10 15:26:10 martin
+ * Tiny cleanup.
+ * Revision 1.5 2012/10/12 11:25:14 martin
+ * Support *BSD.
* Revision 1.4 2001/02/28 15:45:11 MARTIN
* Modified preprocessor syntax.
* Revision 1.3 2001/02/05 10:22:24 MARTIN
@@ -51,6 +53,10 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum
{
RSRC_BUS_ISA,
@@ -60,17 +66,6 @@ enum
};
-/* End of header body */
-
-#undef _ext
-
-
-/* function prototypes: */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* ----- function prototypes begin ----- */
/* This section was generated automatically */
@@ -85,5 +80,9 @@ extern "C" {
#endif
+/* End of header body */
+
+#undef _ext
+
#endif /* _RSRC_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/str_util.c b/src/external/bsd/meinberg/dist/mbglib/common/str_util.c
new file mode 100755
index 0000000..c3c89cb
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/str_util.c
@@ -0,0 +1,449 @@
+
+/**************************************************************************
+ *
+ * $Id: str_util.c 1.3 2016/10/24 08:10:04 thomas-b REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg Library module providing portable, safe string functions.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: str_util.c $
+ * Revision 1.3 2016/10/24 08:10:04 thomas-b
+ * Fixed counter var check in mbg_memcpy_reversed
+ * Revision 1.2 2016/08/05 12:31:04 martin
+ * New functions mbg_memcpy() and mbg_memcpy_reversed().
+ * Moved string trim functions from cfg_util module here.
+ * Fixed some compiler warnings.
+ * Revision 1.1 2015/08/25 15:57:21 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _STR_UTIL
+ #include <str_util.h>
+#undef _STR_UTIL
+
+#include <stdio.h>
+#include <string.h>
+
+
+#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI )
+ #define mbg_vsnprintf _vsnprintf
+#else
+ #define mbg_vsnprintf vsnprintf
+#endif
+
+
+#if defined( MBG_TGT_DOS )
+
+static /*HDR*/
+// Under DOS we use the Borland C/C++ v3.1 compiler by default, which
+// doesn't provide a vsnprintf() function, so we use a simple replacement
+// here. Since we share most of the source code between several target
+// systems we assume that if it our code works properly for other targets
+// which really provide a vsnprintf() function then it also works properly
+// under DOS. ;-)
+int vsnprintf( char *s, size_t max_len, const char *fmt, va_list arg_list )
+{
+ (void) max_len; // quiet compiler warning "not used"
+
+ return vsprintf( s, fmt, arg_list );
+
+} // vsnprintf
+
+#endif
+
+
+
+/*HDR*/
+/**
+ * @brief A portable, safe implementation of vsnprintf()
+ *
+ * Unfortunately the behaviour of vsnprintf() and thus snprintf()
+ * differs in detail across various build environments and run time
+ * libraries.
+ *
+ * If the output exceeds the buffer size and thus is truncated then:<br>
+ *
+ * - Under Windows a negative value is returned and eventually *no*
+ * terminating 0 is written to the output buffer, so the output string
+ * may not be terminated properly.
+ *
+ * - Some versions of glibc return the number of bytes that *would*
+ * have been written to the buffer *if* the buffer would have been
+ * large enough, instead of the true number of characters that have
+ * been written to the buffer.
+ *
+ * So subsequent calls like
+ *
+ * n = snprintf( s, max_len, ... );
+ * n += snprintf( &s[n], max_len - n, ... );
+ *
+ * may always work properly, or fail with buffer overruns or stack
+ * corruption depending on the build environment.
+ * This wrapper function takes care that strings are always terminated
+ * properly, and that the returned value always matches the number of
+ * characters really written to the string buffer, excluding the
+ * terminating 0
+ *
+ * @note The "size_t" type parameter used to specify the buffer size
+ * can be larger (e.g. "unsigned long") than the "int" type returned
+ * by mostly all functions of the printf() family. So if a very large
+ * buffer is specified, and a large number of characters (more than
+ * MAXINT) are written to that buffer then how can an "int" type
+ * return the large number of characters written to the buffer?
+ * We also try to workaround this here.
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ap Variable argument list in va_list format
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+size_t __attribute__( ( format( printf, 3, 0 ) ) )
+vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap )
+{
+ if ( s == NULL || max_len == 0 )
+ return 0; // nothing to do anyway
+
+
+ mbg_vsnprintf( s, max_len, fmt, ap );
+
+ // Force proper worst-case termination of the output string.
+ s[max_len - 1] = 0;
+
+ // The return type of strlen() is usually size_t, so
+ // we can safely return the true length of the string
+ // written to the buffer.
+ return strlen( s );
+
+} // vsnprintf_safe
+
+
+
+/*HDR*/
+/**
+ * @brief A portable, safe implementation of snprintf()
+ *
+ * For a detailed description see ::vsnprintf_safe
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ... Variable argument list according to the format string
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+size_t __attribute__( ( format( printf, 3, 4 ) ) )
+snprintf_safe( char *s, size_t max_len, const char * fmt, ... )
+{
+ va_list ap;
+ size_t len;
+
+ va_start( ap, fmt );
+
+ len = vsnprintf_safe( s, max_len, fmt, ap );
+
+ va_end( ap );
+
+ return len;
+
+} // snprintf_safe
+
+
+
+static __mbg_inline
+/* (explicitly excluded from doxygen)
+ * @brief A portable, safe implementation of a copy function
+ *
+ * This is the basic function used to implemment ::strncpy_safe and
+ * ::sn_cpy_safe. This function takes care that the copied string
+ * is always terminated by 0, but any remaining buffer space
+ * is *not* filled up with '0' characters.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] src Pointer to the input buffer
+ * @param[in] n Number of characters to copy at most
+ * @param[in,out] p_i Pointer to a counter variable
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+void do_str_copy_safe( char *dst, const char *src, size_t n, size_t *p_i )
+{
+ *p_i = 0;
+
+ if ( n > 0 )
+ {
+ for (;;)
+ {
+ *dst = *src;
+
+ if ( *dst == 0 )
+ break; // just copied the terminating 0, done
+
+ if ( --n == 0 ) // no more space left in buffer
+ {
+ *dst = 0; // force terminating 0
+ break;
+ }
+
+ (*p_i)++; // count normal characters
+ src++;
+ dst++;
+ }
+ }
+
+} // do_str_copy_safe
+
+
+
+/*HDR*/
+/**
+ * @brief A portable, safe implementation of strncpy()
+ *
+ * In the original implementation of strncpy(), if the length of the
+ * string to be copied into the destination buffer exceeds the specified
+ * buffer length then the string in the output buffer is not 0-terminated.
+ *
+ * Our implementation always forces a proper termination by 0, but unlike
+ * the original implementation of strncpy() it does *not* fill the whole
+ * remaining buffer space with '0' characters.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] src Pointer to the input buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ *
+ * @return Pointer to the destination buffer
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+char *strncpy_safe( char *dst, const char *src, size_t max_len )
+{
+ size_t i = 0;
+
+ do_str_copy_safe( dst, src, max_len, &i );
+
+ return dst;
+
+} // strncpy_safe
+
+
+
+/*HDR*/
+/**
+ * @brief A function to copy a string safely, returning the number of characters copied
+ *
+ * This basically works like ::strncpy_safe but instead of a pointer to
+ * the destination buffer it returns the number of characters copied
+ * to the destination buffer.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] src Pointer to the input buffer
+ *
+ * @return Number of characters copied to the destination buffer
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_char_safe
+ */
+size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src )
+{
+ size_t i = 0;
+
+ do_str_copy_safe( dst, src, max_len, &i );
+
+ return i;
+
+} // sn_cpy_str_safe
+
+
+
+/*HDR*/
+/**
+ * @brief A function to copy a character safely to a string buffer
+ *
+ * This basically works like ::sn_cpy_str_safe but expects a character
+ * to be copied to the destination buffer. Appends a terminating 0 to
+ * the string buffer and returns the number of characters copied to
+ * the destination buffer, usually 0 or 1.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] c Character to be copied to the destination buffer
+ *
+ * @return Number of characters copied to the destination buffer, without the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ */
+size_t sn_cpy_char_safe( char *dst, size_t max_len, char c )
+{
+ size_t i = 0;
+ char tmp_str[2];
+
+ tmp_str[0] = c;
+ tmp_str[1] = 0;
+
+ do_str_copy_safe( dst, tmp_str, max_len, &i );
+
+ return i;
+
+} // sn_cpy_char_safe
+
+
+
+/*HDR*/
+/**
+ * @brief Trim whitespace at the end of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+void trim_trailing_whitespace( char *s )
+{
+ char *cp;
+
+ // set all trailing spaces to 0
+ for ( cp = &s[strlen( s )]; cp > s; )
+ {
+ --cp;
+
+ if ( *cp >= ' ' )
+ break;
+
+ *cp = 0;
+ }
+
+} // trim_trailing_whitespace
+
+
+
+/*HDR*/
+/**
+ * @brief Trim whitespace at the beginning of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+void trim_leading_whitespace( char *s )
+{
+ char *srcp;
+ char *dstp;
+
+ // Search the first non-space character.
+ for ( srcp = s; *srcp; srcp++ )
+ if ( *srcp > ' ' )
+ break;
+
+ // If there are leading spaces then srcp now
+ // points behind the beginning of the string,
+ // otherwise there's nothing to do.
+ if ( srcp > s )
+ {
+ // Copy the remaining string.
+ dstp = s;
+
+ while ( *srcp )
+ *dstp++ = *srcp++;
+
+ *dstp = 0;
+ }
+
+} // trim_leading_whitespace
+
+
+
+/*HDR*/
+/**
+ * @brief Trim both leading and trailing whitespace from a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+void trim_whitespace( char *s )
+{
+ trim_trailing_whitespace( s );
+ trim_leading_whitespace( s );
+
+} // trim_whitespace
+
+
+
+/*HDR*/
+/**
+ * @brief Copy array of bytes starting at beginning of buffer
+ *
+ * Can be used if the destination address is in the same buffer
+ * in front of the source address. Even though you would expect
+ * that memcpy() would also work for this properly, we have seen
+ * cases where it didn't, and only memmove() worked correctly.
+ * Anyway, we try to avoid the overhead of memmove().
+ *
+ * @param[out] dst Destination address behind the source address
+ * @param[in] src Source address
+ * @param[in] n_bytes Number of bytes to copy
+ *
+ * @see ::mbg_memcpy_reversed
+ */
+void mbg_memcpy( void *dst, const void *src, size_t n_bytes )
+{
+ uint8_t *dstp = (uint8_t *) dst;
+ uint8_t *srcp = (uint8_t *) src;
+
+ while ( n_bytes-- )
+ *dstp++ = *srcp++;
+
+} // mbg_memcpy
+
+
+
+/*HDR*/
+/**
+ * @brief Copy an array of bytes in reversed order, starting at end of buffer
+ *
+ * Can be used if the destination address is in the same buffer
+ * behind the source address, so the source address would be
+ * overwritten by a normal memcpy().
+ *
+ * @param[out] dst Destination address behind the source address
+ * @param[in] src Source address
+ * @param[in] n_bytes Number of bytes to copy
+ *
+ * @see ::mbg_memcpy
+ */
+void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes )
+{
+ if ( n_bytes ) // just to be sure it isn't 0
+ {
+ uint8_t *dstp = ( (uint8_t *) dst ) + n_bytes;
+ uint8_t *srcp = ( (uint8_t *) src ) + n_bytes;
+
+ while ( n_bytes-- )
+ *(--dstp) = *(--srcp);
+ }
+
+} // mbg_memcpy_reversed
+
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/str_util.h b/src/external/bsd/meinberg/dist/mbglib/common/str_util.h
new file mode 100755
index 0000000..3b49318
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/str_util.h
@@ -0,0 +1,269 @@
+
+/**************************************************************************
+ *
+ * $Id: str_util.h 1.4 2017/05/10 15:26:10 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for str_util.c
+ *
+ * -----------------------------------------------------------------------
+ * $Log: str_util.h $
+ * Revision 1.4 2017/05/10 15:26:10 martin
+ * Tiny cleanup.
+ * Revision 1.3 2016/12/14 16:22:24 martin
+ * Added macro _sn_cpy_str_safe() to simplify calls.
+ * Revision 1.2 2016/08/05 12:33:17 martin
+ * Moved string trim functions from cfg_util module here.
+ * Added variable str_not_avail.
+ * Fixed some spelling.
+ * Updated function prototypes.
+ * Revision 1.1 2015/08/25 15:57:43 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _STR_UTIL_H
+#define _STR_UTIL_H
+
+/* Other headers to be included */
+
+#include <words.h> // implicitly includes mbg_tgt.h for non-firmware projects
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+#ifdef _STR_UTIL
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+_ext const char *str_not_avail
+#ifdef _DO_INIT
+ = "N/A"
+#endif
+;
+
+#define _sn_cpy_str_safe( _dst, _src ) sn_cpy_str_safe( _dst, sizeof( _dst ), _src )
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief A portable, safe implementation of vsnprintf()
+ *
+ * Unfortunately the behaviour of vsnprintf() and thus snprintf()
+ * differs in detail across various build environments and run time
+ * libraries.
+ *
+ * If the output exceeds the buffer size and thus is truncated then:<br>
+ *
+ * - Under Windows a negative value is returned and eventually *no*
+ * terminating 0 is written to the output buffer, so the output string
+ * may not be terminated properly.
+ *
+ * - Some versions of glibc return the number of bytes that *would*
+ * have been written to the buffer *if* the buffer would have been
+ * large enough, instead of the true number of characters that have
+ * been written to the buffer.
+ *
+ * So subsequent calls like
+ *
+ * n = snprintf( s, max_len, ... );
+ * n += snprintf( &s[n], max_len - n, ... );
+ *
+ * may always work properly, or fail with buffer overruns or stack
+ * corruption depending on the build environment.
+ * This wrapper function takes care that strings are always terminated
+ * properly, and that the returned value always matches the number of
+ * characters really written to the string buffer, excluding the
+ * terminating 0
+ *
+ * @note The "size_t" type parameter used to specify the buffer size
+ * can be larger (e.g. "unsigned long") than the "int" type returned
+ * by mostly all functions of the printf() family. So if a very large
+ * buffer is specified, and a large number of characters (more than
+ * MAXINT) are written to that buffer then how can an "int" type
+ * return the large number of characters written to the buffer?
+ * We also try to workaround this here.
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ap Variable argument list in va_list format
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+ size_t __attribute__( ( format( printf, 3, 0 ) ) ) vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap ) ;
+
+ /**
+ * @brief A portable, safe implementation of snprintf()
+ *
+ * For a detailed description see ::vsnprintf_safe
+ *
+ * @param[out] s The string buffer to be filled
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] fmt Format string according to subsequent parameters
+ * @param[in] ... Variable argument list according to the format string
+ *
+ * @return Number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+ size_t __attribute__( ( format( printf, 3, 4 ) ) ) snprintf_safe( char *s, size_t max_len, const char * fmt, ... ) ;
+
+ /**
+ * @brief A portable, safe implementation of strncpy()
+ *
+ * In the original implementation of strncpy(), if the length of the
+ * string to be copied into the destination buffer exceeds the specified
+ * buffer length then the string in the output buffer is not 0-terminated.
+ *
+ * Our implementation always forces a proper termination by 0, but unlike
+ * the original implementation of strncpy() it does *not* fill the whole
+ * remaining buffer space with '0' characters.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] src Pointer to the input buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ *
+ * @return Pointer to the destination buffer
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::sn_cpy_str_safe
+ * @see ::sn_cpy_char_safe
+ */
+ char *strncpy_safe( char *dst, const char *src, size_t max_len ) ;
+
+ /**
+ * @brief A function to copy a string safely, returning the number of characters copied
+ *
+ * This basically works like ::strncpy_safe but instead of a pointer to
+ * the destination buffer it returns the number of characters copied
+ * to the destination buffer.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] src Pointer to the input buffer
+ *
+ * @return Number of characters copied to the destination buffer
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_char_safe
+ */
+ size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src ) ;
+
+ /**
+ * @brief A function to copy a character safely to a string buffer
+ *
+ * This basically works like ::sn_cpy_str_safe but expects a character
+ * to be copied to the destination buffer. Appends a terminating 0 to
+ * the string buffer and returns the number of characters copied to
+ * the destination buffer, usually 0 or 1.
+ *
+ * @param[out] dst Pointer to the output buffer
+ * @param[in] max_len Size of the output buffer for 0-terminated string
+ * @param[in] c Character to be copied to the destination buffer
+ *
+ * @return Number of characters copied to the destination buffer, without the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ * @see ::strncpy_safe
+ * @see ::sn_cpy_str_safe
+ */
+ size_t sn_cpy_char_safe( char *dst, size_t max_len, char c ) ;
+
+ /**
+ * @brief Trim whitespace at the end of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_trailing_whitespace( char *s ) ;
+
+ /**
+ * @brief Trim whitespace at the beginning of a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_leading_whitespace( char *s ) ;
+
+ /**
+ * @brief Trim both leading and trailing whitespace from a string
+ *
+ * @param[in,out] s The string to be trimmed
+ */
+ void trim_whitespace( char *s ) ;
+
+ /**
+ * @brief Copy array of bytes starting at beginning of buffer
+ *
+ * Can be used if the destination address is in the same buffer
+ * in front of the source address. Even though you would expect
+ * that memcpy() would also work for this properly, we have seen
+ * cases where it didn't, and only memmove() worked correctly.
+ * Anyway, we try to avoid the overhead of memmove().
+ *
+ * @param[out] dst Destination address behind the source address
+ * @param[in] src Source address
+ * @param[in] n_bytes Number of bytes to copy
+ *
+ * @see ::mbg_memcpy_reversed
+ */
+ void mbg_memcpy( void *dst, const void *src, size_t n_bytes ) ;
+
+ /**
+ * @brief Copy an array of bytes in reversed order, starting at end of buffer
+ *
+ * Can be used if the destination address is in the same buffer
+ * behind the source address, so the source address would be
+ * overwritten by a normal memcpy().
+ *
+ * @param[out] dst Destination address behind the source address
+ * @param[in] src Source address
+ * @param[in] n_bytes Number of bytes to copy
+ *
+ * @see ::mbg_memcpy
+ */
+ void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _STR_UTIL_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/timeutil.c b/src/external/bsd/meinberg/dist/mbglib/common/timeutil.c
new file mode 100755
index 0000000..be65f18
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/timeutil.c
@@ -0,0 +1,164 @@
+
+/**************************************************************************
+ *
+ * $Id: timeutil.c 1.2 2017/07/05 07:10:48 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Meinberg Library module for safe time conversion routines.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: timeutil.c $
+ * Revision 1.2 2017/07/05 07:10:48 martin
+ * Added mbg_clock_gettime(), mbg_clock_settime(),
+ * and check_precise_time_api() for Windows.
+ * Revision 1.1 2016/07/15 14:14:19Z martin
+ * Initial revision
+ *
+ **************************************************************************/
+
+#define _TIMEUTIL
+ #include <timeutil.h>
+#undef _TIMEUTIL
+
+#include <mbgtime.h>
+#include <str_util.h>
+
+#if defined( MBG_TGT_WIN32 )
+ #include <mbgerror.h> // NSECS_PER_SEC
+ #include <stdio.h>
+#endif
+
+
+
+/*HDR*/
+size_t snprint_gmtime_error( char *s, size_t max_len, int mbg_errno, time_t t, const char *calling_fnc )
+{
+ size_t n = snprintf_safe( s, max_len, "gmtime() call failed" );
+
+ if ( calling_fnc )
+ n += snprintf_safe( &s[n], max_len - n, " in %s", calling_fnc );
+
+ #if defined( _MSC_VER ) && ( _MSC_VER < 1500 )
+ //### TODO E.g. in VC6 time_t is only 32 bit anyway.
+ n += snprintf_safe( &s[n], max_len - n, " for time_t %lu: %s",
+ (unsigned long) t, mbg_strerror( mbg_errno ) );
+ #else
+ n += snprintf_safe( &s[n], max_len - n, " for time_t %llu: %s",
+ (unsigned long long) t, mbg_strerror( mbg_errno ) );
+ #endif
+
+ return n;
+
+} // snprint_gmtime_error
+
+
+
+#if defined( MBG_TGT_WIN32 )
+
+typedef int clockid_t;
+#define clockid_t clockid_t
+
+#define CLOCK_REALTIME ( (clockid_t) 0 )
+
+/*HDR*/
+int mbg_clock_gettime( clockid_t clock_id, struct timespec *tp )
+{
+ if ( clock_id == CLOCK_REALTIME )
+ {
+ #if defined( TIME_UTC ) // C11 / VS2015+
+ int rc = timespec_get( tp, TIME_UTC ); // TODO Check this code
+ return ( rc == 0 ) ? -1 : 0 // rc == 0 means error
+ #else
+ #define EPOCH_HNS 116444736000000000i64
+ FILETIME ft;
+ unsigned __int64 tmp;
+ gstaft_fnc( &ft );
+ tmp = ( (__int64) ft.dwHighDateTime << 32 ) | ft.dwLowDateTime;
+ tmp -= EPOCH_HNS; // convert to Unix epoch
+ tmp *= 100; // convert to nanoseconds
+ tp->tv_sec = ( tmp / NSECS_PER_SEC );
+ tp->tv_nsec = ( tmp % NSECS_PER_SEC );
+ return 0;
+ #endif
+ }
+ else
+ return -1; // TODO this is e.g. in case of CLOCK_MONOTONIC, we could use QPC then.
+
+} // mbg_clock_gettime
+
+
+
+/*HDR*/
+int mbg_clock_settime( clockid_t clock_id, const struct timespec *tp )
+{
+ if ( clock_id == CLOCK_REALTIME )
+ {
+#if 0 // ### TODO FIXME This needs to be implemented.
+ #if defined( TIME_UTC ) // C11 / VS2015+
+ int rc = timespec_get( res, TIME_UTC ); // TODO Check this code
+ return ( rc == 0 ) ? -1 : 0 // rc == 0 means error
+ #else
+ #define EPOCH_HNS 116444736000000000i64
+ FILETIME ft;
+ unsigned __int64 tmp;
+ gstaft_fnc( &ft );
+ tmp = ( (__int64) ft.dwHighDateTime << 32 ) | ft.dwLowDateTime;
+ tmp -= EPOCH_HNS; // convert to Unix epoch
+ tmp *= 100; // convert to nanoseconds
+ res->tv_sec = ( tmp / NSECS_PER_SEC );
+ res->tv_nsec = ( tmp % NSECS_PER_SEC );
+ return 0;
+ #endif
+#endif
+
+ return 0; // FIXME this is actually not true
+ }
+ else
+ return -1; // TODO this is e.g. in case of CLOCK_MONOTONIC, we could use QPC then.
+
+} // mbg_clock_settime
+
+
+
+bool force_legacy_gstaft;
+
+
+/*HDR*/
+void check_precise_time_api( void )
+{
+ const char *info ="";
+ GSTAFT_FNC tmp_fnc;
+ HINSTANCE h = LoadLibrary( "kernel32.dll" );
+
+ if ( h == NULL )
+ {
+ info = "Precise system time may not be supported; failed to get handle for kernel32.dll.";
+ goto out;
+ }
+
+ tmp_fnc = (GSTAFT_FNC) GetProcAddress( h, "GetSystemTimePreciseAsFileTime" );
+
+ if ( tmp_fnc == NULL )
+ {
+ info = "Precise system time NOT supported";
+ goto out;
+ }
+
+ if ( force_legacy_gstaft )
+ {
+ info = "Precise system time is supported, but legacy function used by request";
+ goto out;
+ }
+
+ gstaft_fnc = tmp_fnc;
+ info = "Precise system time is supported and used";
+
+out:
+ printf( "%s\n", info );
+
+} // check_precise_time_api
+
+#endif
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/timeutil.h b/src/external/bsd/meinberg/dist/mbglib/common/timeutil.h
new file mode 100755
index 0000000..233c174
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/timeutil.h
@@ -0,0 +1,129 @@
+
+/**************************************************************************
+ *
+ * $Id: timeutil.h 1.3 2017/07/05 07:15:00 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for timeutil.c
+ *
+ * -----------------------------------------------------------------------
+ * $Log: timeutil.h $
+ * Revision 1.3 2017/07/05 07:15:00 martin
+ * Provide basic support for clock_gettime()/clock_settime()
+ * compatible functions for Windows.
+ * Updated function prototypes.
+ * Revision 1.1 2016/07/15 14:14:20Z martin
+ * Initial revision
+ *
+ **************************************************************************/
+
+#ifndef _TIMEUTIL_H
+#define _TIMEUTIL_H
+
+/* Other headers to be included */
+
+#include <words.h> // implicitly includes mbg_tgt.h for non-firmware projects
+#include <mbgerror.h>
+
+#include <time.h>
+#include <stddef.h>
+
+
+#ifdef _TIMEUTIL
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS )
+
+typedef int clockid_t;
+#define clockid_t clockid_t
+
+#define CLOCK_REALTIME ( (clockid_t) 0 )
+
+#endif
+
+
+
+#if defined( MBG_TGT_WIN32 )
+
+#define __const__ const
+
+/**
+ * @brief A pointer to a function returning the system time as FILETIME
+ *
+ * This can be e.g. the standard Windows API call GetSystemTimeAsFileTime()
+ * or the GetSystemTimeAsPreciseFileTime() API call introduced with Windows 8.
+ */
+typedef VOID (WINAPI *GSTAFT_FNC)(LPFILETIME lpSystemTimeAsFileTime);
+
+_ext GSTAFT_FNC gstaft_fnc
+#ifdef _DO_INIT
+ = GetSystemTimeAsFileTime
+#endif
+;
+
+#endif
+
+
+static __mbg_inline
+time_t cvt_to_time_t( time_t t )
+{
+ // Eventually we can do some epoch check here.
+ return (time_t) t;
+
+} // cvt_to_time_t
+
+
+
+static __mbg_inline
+int mbg_gmtime( struct tm *p_tm, const time_t *p_time )
+{
+ struct tm *p_tm_tmp = gmtime( p_time );
+
+ if ( p_tm_tmp == NULL ) // conversion failed
+ return mbg_get_last_error( NULL );
+
+ *p_tm = *p_tm_tmp;
+
+ return MBG_SUCCESS;
+
+} // mbg_gmtime
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ size_t snprint_gmtime_error( char *s, size_t max_len, int mbg_errno, time_t t, const char *calling_fnc ) ;
+ int mbg_clock_gettime( clockid_t clock_id, struct timespec *tp ) ;
+ int mbg_clock_settime( clockid_t clock_id, const struct timespec *tp ) ;
+ void check_precise_time_api( void ) ;
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _TIMEUTIL_H */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/toolutil.c b/src/external/bsd/meinberg/dist/mbglib/common/toolutil.c
index 717ed89..5657910 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/toolutil.c
+++ b/src/external/bsd/meinberg/dist/mbglib/common/toolutil.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: toolutil.c 1.3.2.6 2011/07/08 11:39:00 martin TRASH $
+ * $Id: toolutil.c 1.5 2017/07/05 07:32:38 martin REL_M $
*
* Description:
* Common functions which can be used with Meinberg command line
@@ -9,15 +9,35 @@
*
* -----------------------------------------------------------------------
* $Log: toolutil.c $
- * Revision 1.3.2.6 2011/07/08 11:39:00 martin
- * Revision 1.3.2.5 2011/07/06 07:55:32 martin
- * Revision 1.3.2.4 2011/07/05 15:35:56 martin
- * Modified version handling.
- * Revision 1.3.2.3 2011/07/05 14:36:47 martin
- * New way to maintain version information.
- * Revision 1.3.2.2 2011/06/27 13:02:11 martin
+ * Revision 1.5 2017/07/05 07:32:38 martin
+ * Renamed mbg_check_devices() to mbg_handle_devices() and added
+ * a new parameter which controls if only one or all devices
+ * should be handled if no device has been specified.
+ * New function mbg_open_device_by_param() which can be used e.g. to
+ * check if a parameter string is an device file name (MBG_DEV_FN),
+ * or a device index number, or a device name in MBG_DEV_NAME format,
+ * and calls the appropriate open function to open the device.
+ * Made mbg_snprint_hr_tstamp() more versatile by passing a new
+ * optional UTC offset parameter.
+ * Account for PCPS_HRT_BIN_FRAC_SCALE renamed to MBG_FRAC32_UNITS_PER_SEC.
+ * Account for frac_sec_from_bin() obsoleted by bin_frac_32_to_dec_frac().
+ * Print device options with OS-specific device names.
+ * Print special firmware version info, if appropriate.
+ * Reworked error checking after opening device.
+ * mbg_print_program_info() which is usually called first after program
+ * start now makes stdout unbuffered if output is redirected.
+ * Use safe string functions from str_util.c.
+ * Support Windows and QNX Neutrino targets.
+ * Added doxygen comments.
+ * Revision 1.4 2012/10/15 09:33:48 martin
+ * Use common way to handle version information.
* Open device with O_RDWR flag.
- * Revision 1.3.2.1 2010/11/05 12:56:02 martin
+ * Fixed printing delta timestamps.
+ * Added function to print PCPS_TIME.
+ * Added function to show PZF correlation.
+ * Added function mbg_print_hr_time() which optionally prints hex status.
+ * Let the display functions for HR timestamps optionally show
+ * the raw (hex) timestamps.
* Revision 1.3 2009/06/19 12:12:14 martin
* Added function mbg_print_hr_timestamp().
* Revision 1.2 2009/02/18 09:15:55 martin
@@ -34,30 +54,110 @@
#undef _TOOLUTIL
// include Meinberg headers
+#include <cfg_hlp.h>
#include <pcpsutil.h>
+#include <timeutil.h>
+#include <str_util.h>
// include system headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+
+
+
+#if defined( MBG_TGT_WIN32 )
+ #define isatty _isatty
+ #define fileno _fileno
+#endif
+
+
+
+static __mbg_inline
+/**
+ * @brief Compute the difference between two ::PCPS_TIME_STAMP values
+ *
+ * @param[in] p_ts Pointer to the current time stamp.
+ * @param[in] p_prv_ts Pointer to a previous time stamp.
+ *
+ * @return The time difference as double, in microseconds.
+ */
+double delta_timestamps( const PCPS_TIME_STAMP *p_ts, const PCPS_TIME_STAMP *p_prv_ts )
+{
+ uint64_t ts = pcps_time_stamp_to_uint64( p_ts );
+ uint64_t prv_ts = pcps_time_stamp_to_uint64( p_prv_ts );
+
+ // We divide by MBG_FRAC32_UNITS_PER_SEC to get the correct fractions
+ // and we multiply by 1E6 to get the result in microseconds.
+ return (double) ( (int64_t) ( ts - prv_ts ) ) * 1E6 / MBG_FRAC32_UNITS_PER_SEC;
+
+} // delta_timestamps
+
/*HDR*/
+/**
+ * @brief Print the program version to a string buffer
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] micro_version Micro version code for the application.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+int mbg_program_version_str( char *s, size_t max_len, int micro_version )
+{
+ int n;
+
+ #if defined( MBG_MICRO_VERSION_CODE_DEV )
+ micro_version = MBG_MICRO_VERSION_CODE_DEV;
+ #endif
+
+ n = snprintf_safe( s, max_len, "%i.%i.%i", MBG_MAJOR_VERSION_CODE,
+ MBG_MINOR_VERSION_CODE, micro_version );
+
+ return n;
+
+} // mbg_program_version_str
+
+
+
+/*HDR*/
+/**
+ * @brief Print some program info to a string buffer
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] pname The program name.
+ * @param[in] micro_version Micro version code for the application.
+ * @param[in] first_year First copyright year.
+ * @param[in] last_year Last copyright year.
+ *
+ * @return The number of characters printed to the buffer.
+ */
int mbg_program_info_str( char *s, size_t max_len, const char *pname,
int micro_version, int first_year, int last_year )
{
- int n;
+ int n = 0;
+
+ #if defined( MBG_MICRO_VERSION_CODE_DEV )
+ micro_version = MBG_MICRO_VERSION_CODE_DEV;
+ #endif
if ( last_year == 0 )
last_year = MBG_CURRENT_COPYRIGHT_YEAR;
- n = snprintf( s, max_len, "%s v%i.%i.%i Copyright Meinberg ", pname,
- MBG_MAJOR_VERSION_CODE, MBG_MINOR_VERSION_CODE, micro_version );
+ n += snprintf_safe( &s[n], max_len - n, "%s v", pname );
+
+ n += mbg_program_version_str( &s[n], max_len - n, micro_version );
+
+ n += snprintf_safe( &s[n], max_len - n, " copyright Meinberg " );
if ( first_year != last_year )
- n += snprintf( &s[n], max_len - n, "%04i-", first_year );
+ n += snprintf_safe( &s[n], max_len - n, "%04i-", first_year );
- n += snprintf( &s[n], max_len - n, "%04i", last_year );
+ n += snprintf_safe( &s[n], max_len - n, "%04i", last_year );
return n;
@@ -66,12 +166,23 @@ int mbg_program_info_str( char *s, size_t max_len, const char *pname,
/*HDR*/
+/**
+ * @brief Print program info to console
+ *
+ * @param[in] pname The program name.
+ * @param[in] micro_version Micro version code for the application.
+ * @param[in] first_year First copyright year.
+ * @param[in] last_year Last copyright year.
+ */
void mbg_print_program_info( const char *pname, int micro_version, int first_year, int last_year )
{
char ws[256];
- #if defined( MBG_MICRO_VERSION_CODE_DEV )
- micro_version = MBG_MICRO_VERSION_CODE_DEV;
- #endif
+
+ // If the output has been redirected then make stdout unbuffered,
+ // e.g. to see the output immediately even though piped through 'tee'.
+ if ( !isatty( fileno( stdout ) ) )
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
mbg_program_info_str( ws, sizeof( ws ), pname, micro_version, first_year, last_year );
printf( "\n%s\n\n", ws );
@@ -81,6 +192,12 @@ void mbg_print_program_info( const char *pname, int micro_version, int first_yea
/*HDR*/
+/**
+ * @brief Print usage intro to console
+ *
+ * @param[in] pname The program name.
+ * @param[in] info An optional additional info string, may be NULL.
+ */
void mbg_print_usage_intro( const char *pname, const char *info )
{
printf( "Usage: %s [[opt] [opt] ...] [[dev] [dev] ...]\n\n", pname );
@@ -94,23 +211,19 @@ void mbg_print_usage_intro( const char *pname, const char *info )
/*HDR*/
-void mbg_print_help_options( void )
-{
- puts( "where opt is one of the options:" );
- mbg_print_opt_info( "-? or -h", "print this usage information" );
-
-} // mbg_print_help_options
-
-
-
-/*HDR*/
+/**
+ * @brief Print info on a single program option / argument
+ *
+ * @param[in] opt_name The option name, optional, may be NULL.
+ * @param[in] opt_info The option info, optional, may be NULL.
+ */
void mbg_print_opt_info( const char *opt_name, const char *opt_info )
{
if ( opt_name == NULL )
- opt_name = "";
+ opt_name = str_empty;
if ( opt_info == NULL )
- opt_info = "";
+ opt_info = str_empty;
printf( " %8s %s\n", opt_name, opt_info );
@@ -119,17 +232,51 @@ void mbg_print_opt_info( const char *opt_name, const char *opt_info )
/*HDR*/
+/**
+ * @brief Print info on common program help arguments
+ *
+ * Lists program parameters causing printing
+ * of help / usage information.
+ */
+void mbg_print_help_options( void )
+{
+ puts( "where \"opt\" is one of the options:" );
+ mbg_print_opt_info( "-? or -h", "print this usage information" );
+
+} // mbg_print_help_options
+
+
+
+/*HDR*/
+/**
+ * @brief Print common info on how to specify devices on the command line
+ */
void mbg_print_device_options( void )
{
- puts( "\nwhere dev is the name of a device, e.g.:\n"
- " /dev/mbgclock0"
- );
+ printf( "\n" );
+
+ puts( "where \"dev\" can be:" );
+
+ #if MBG_TGT_HAS_DEV_FN
+ printf( " a device file name, e.g. \"%s\" or \"%s\"\n",
+ EXAMPLE_DEV_FN_1, EXAMPLE_DEV_FN_2 );
+ #endif
+ printf( " a device type name, with or with S/N appended, e.g. \"%s\" or \"%s\"\n",
+ EXAMPLE_DEV_NAME_1, EXAMPLE_DEV_NAME_2 );
+
+ printf( " a device index, e.g. \"0\", \"1\",\"2\", ...\n" );
} // mbg_print_device_options
/*HDR*/
+/**
+ * @brief Print program info and default usage information
+ *
+ * @param[in] pname The program name.
+ * @param[in] prog_info An optional additional info string, may be NULL.
+ */
void mbg_print_default_usage( const char *pname, const char *prog_info )
{
mbg_print_usage_intro( pname, prog_info );
@@ -141,30 +288,21 @@ void mbg_print_default_usage( const char *pname, const char *prog_info )
-// test if ioctl error and print msg if true
-
-/*HDR*/
-int mbg_ioctl_err( int rc, const char *descr )
-{
- if ( rc < 0 )
- {
- fprintf( stderr, "** IOCTL error %i: ", rc );
- perror( descr );
- return -1;
- }
-
- return 0;
-
-} // mbg_ioctl_err
-
-
-
/*HDR*/
+/**
+ * @brief Retrieve and print some common device info
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] dev_name A device name string to be printed
+ * @param[out] p_dev Pointer to a device info structure to be read from the device
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int mbg_get_show_dev_info( MBG_DEV_HANDLE dh, const char *dev_name, PCPS_DEV *p_dev )
{
- unsigned long long port;
+ RECEIVER_INFO ri;
+ unsigned long port;
int irq_num;
- int ret_val = 0;
int rc;
if ( dev_name )
@@ -173,31 +311,39 @@ int mbg_get_show_dev_info( MBG_DEV_HANDLE dh, const char *dev_name, PCPS_DEV *p_
// get information about the device
rc = mbg_get_device_info( dh, p_dev );
- if ( mbg_ioctl_err( rc, "mbg_get_device_info" ) )
- goto fail;
+ if ( mbg_cond_err_msg( rc, "mbg_get_device_info" ) )
+ goto out;
+
+ rc = mbg_setup_receiver_info( dh, p_dev, &ri );
+
+ if ( mbg_cond_err_msg( rc, "mbg_setup_receiver_info" ) )
+ goto out;
printf( "%s", _pcps_type_name( p_dev ) );
- if ( strlen( _pcps_sernum( p_dev ) ) &&
+ if ( strlen( _pcps_sernum( p_dev ) ) &&
strcmp( _pcps_sernum( p_dev ), "N/A" ) )
printf( " %s", _pcps_sernum( p_dev ) );
- printf( " (FW %X.%02X",
+ printf( " (FW %X.%02X",
_pcps_fw_rev_num_major( _pcps_fw_rev_num( p_dev ) ),
_pcps_fw_rev_num_minor( _pcps_fw_rev_num( p_dev ) )
);
+ if ( chk_sw_rev_name( &ri.sw_rev, 0 ) )
+ printf( " \"%s\"", ri.sw_rev.name );
+
if ( _pcps_has_asic_version( p_dev ) )
{
PCI_ASIC_VERSION av;
int rc = mbg_get_asic_version( dh, &av );
- if ( rc == MBG_SUCCESS )
+ if ( mbg_rc_is_success( rc ) )
{
av = _convert_asic_version_number( av );
- printf( ", ASIC %X.%02X",
+ printf( ", ASIC %u.%02u",
_pcps_asic_version_major( av ),
_pcps_asic_version_minor( av )
);
@@ -206,148 +352,443 @@ int mbg_get_show_dev_info( MBG_DEV_HANDLE dh, const char *dev_name, PCPS_DEV *p_
printf( ")" );
- port = _pcps_port_base( p_dev, 0 );
+ port = _pcps_short_port_base( p_dev, 0 );
if ( port )
- printf( " at port 0x%03LX", port );
+ printf( " at port 0x%03lX", port );
- port = _pcps_port_base( p_dev, 1 );
+ port = _pcps_short_port_base( p_dev, 1 );
if ( port )
- printf( "/0x%03LX", port );
+ printf( "/0x%03lX", port );
irq_num = _pcps_irq_num( p_dev );
if ( irq_num != -1 )
printf( ", irq %i", irq_num );
- goto done;
+ rc = MBG_SUCCESS;
-fail:
- ret_val = -1;
-
-done:
- puts( "" );
- return ret_val;
+out:
+ puts( str_empty );
+ return rc;
} // mbg_get_show_dev_info
/*HDR*/
-int mbg_check_device( MBG_DEV_HANDLE dh, const char *dev_name,
- int (*fnc)( MBG_DEV_HANDLE, const PCPS_DEV *) )
+/**
+ * @brief Print device info and take some action on a specific device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] dev_name A device name string to be printed.
+ * @param[in] fnc Pointer to a callback function that actually takes the action.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int mbg_handle_device( MBG_DEV_HANDLE dh, const char *dev_name,
+ MBG_DEV_HANDLER_FNC *fnc )
{
PCPS_DEV dev;
- int ret_val = 0;
+ int rc;
- if ( dh == MBG_INVALID_DEV_HANDLE )
- {
- if ( dev_name )
- fprintf( stderr, "%s: ", dev_name );
+ rc = mbg_get_show_dev_info( dh, dev_name, &dev );
- perror( "Unable to open device" );
- return -1;
- }
+ if ( mbg_rc_is_success( rc ) )
+ if ( fnc )
+ rc = fnc( dh, &dev );
+
+ mbg_close_device( &dh );
- if ( mbg_get_show_dev_info( dh, dev_name, &dev ) < 0 )
- goto fail;
+ puts( "" );
- if ( fnc )
- ret_val = fnc( dh, &dev );
+ return rc;
- goto done;
+} // mbg_handle_device
-fail:
- ret_val = -1;
-done:
- mbg_close_device( &dh );
- puts( "" );
- return ret_val;
+/*HDR*/
+/**
+ * @brief Get the number of devices actually present
+ *
+ * Do a real search only when called for the first time.
+ *
+ * @return The number of devices currently present.
+ */
+int chk_get_num_devices( void )
+{
+ static int num_devices;
+ static bool has_searched_devices;
+
+ if ( !has_searched_devices )
+ {
+ num_devices = mbg_find_devices();
+ has_searched_devices = true;
+ }
+
+ return num_devices;
-} // mbg_check_device
+} // chk_get_num_devices
/*HDR*/
-int mbg_check_devices( int argc, char *argv[], int optind, int (*fnc)( MBG_DEV_HANDLE, const PCPS_DEV *) )
+int mbg_open_device_by_param( MBG_DEV_HANDLE *p_dh, const char *dev_param_str,
+ int dev_idx, int devices_specified,
+ char *dev_name_buffer, size_t dev_name_buffer_size,
+ int chk_dev_flags )
{
- MBG_DEV_HANDLE dh;
- int ret_val = 0;
- int num_devices = argc - optind;
+ MBG_DEV_HANDLE dh = MBG_INVALID_DEV_HANDLE;
+ int devices_found;
+ int rc = MBG_ERR_GENERIC;
+
+ if ( dev_name_buffer_size ) // This should always be the case
+ dev_name_buffer[0] = 0; // Make string empty
- if ( num_devices == 0 ) // no device name given on the command line
+ if ( dev_param_str )
{
- // No devices specified on the command line, so
- // try to find devices.
- int devices = mbg_find_devices();
+ // A device parameter string has been specified.
+ // This can be:
+ // - A device file name, see ::MBG_DEV_FN
+ // - A device model name like "GPS180PEX", eventually with the serial number
+ // appended after an underscore, as in "GPS180PEX_029511026220".
+ // See ::MBG_DEV_NAME.
+ // - A device index number as string, e.g "0" or "3".
+
+ char *endptr;
+ long l;
+
+ #if MBG_TGT_HAS_DEV_FN
+ // Check if the device parameter represents a device file name
+ if ( strncmp( dev_param_str, mbg_dev_fn_base, strlen( mbg_dev_fn_base ) ) == 0 )
+ {
+ snprintf_safe( dev_name_buffer, dev_name_buffer_size, "%s", dev_param_str );
+ dh = mbg_open_device_by_dev_fn( dev_param_str );
+ goto out_chk;
+ }
+ #endif
+
+
+ // Check if the device parameter string is an index number.
+ endptr = NULL;
+ l = strtol( dev_param_str, &endptr, 0 );
+
+ // If endptr now points past the string then the
+ // whole string has been interpreted as number.
+ if ( endptr == &dev_param_str[strlen( dev_param_str )] )
+ {
+ long l_max = (long) ( ( (unsigned int) -1 ) >> 1 );
+
+ if ( l > l_max )
+ {
+ // The decoded number exceeds the maximum number
+ // that can be passed to ::mbg_open_device.
+ rc = MBG_ERR_RANGE;
+ goto out;
+ }
+
+ // We use the decoded number as device index.
+ dev_idx = (int) l;
+ goto open_dev_with_idx;
+ }
+
+
+ // Finally assume the device name is a model name, eventually
+ // with serial number appended.
+ snprintf_safe( dev_name_buffer, dev_name_buffer_size, "%s", dev_param_str );
+ dh = mbg_open_device_by_name( dev_param_str, MBG_MATCH_MODEL );
+ goto out_chk;
+ }
+
- if ( devices == 0 )
+ // No device has been specified on the command line.
+
+#if 0 // TODO
+ if ( chk_dev_flags & CHK_DEV_WITHOUT_DEV )
+ {
+ // TODO Check if this branch is useful
+ // We have been called without a device to be used.
+ // This may be useful e.g. if we just want to print
+ // some general usage information.
+ if ( fnc )
{
- printf( "No device found.\n" );
- return 1;
+ *p_dh = MBG_INVALID_DEV_HANDLE;
+ rc = fnc( *p_dh, NULL );
}
+ else
+ {
+ // TODO Should we report an error if we have been called
+ // without callback function and without device?
+ }
+ goto out;
+ }
+#endif
+
- // Handle only first device found.
- dh = mbg_open_device( 0 );
- ret_val = mbg_check_device( dh, NULL, fnc );
+open_dev_with_idx:
+ devices_found = chk_get_num_devices();
+
+ if ( devices_found == 0 ) // no device found
+ {
+ // Don't continue without any device, unless
+ // explicitly requested to do so.
+ if ( !( chk_dev_flags & CHK_DEV_WITHOUT_DEV ) )
+ return MBG_ERR_NO_DEV;
+
+ // We may continue even if no device is available,
+ // but have to process the callback loop only once.
+ devices_found = 1;
}
- else
+
+ // Unless explicitly requested to handle all devices
+ // we have found, we only handle the first one.
+ if ( !( chk_dev_flags & CHK_DEV_ALL_DEVICES ) )
+ devices_found = 1;
+
+
+ // Try to open the device with the specified index number.
+ mbg_dev_fn_from_dev_idx( dev_name_buffer, dev_name_buffer_size, dev_idx );
+ dh = mbg_open_device( dev_idx );
+
+out_chk:
+ // Now check if the "open" function we've just called before
+ // was successful.
+ if ( dh == MBG_INVALID_DEV_HANDLE )
+ {
+ char msg[256];
+ int n = 0;
+ rc = mbg_get_last_error( NULL );
+
+ n = snprintf_safe( msg, sizeof( msg ), "** Failed to open device" );
+
+ if ( dev_name_buffer[0] ) // string not empty
+ n += snprintf_safe( &msg[n], sizeof( msg ) - n, " %s", dev_name_buffer );
+
+ n += snprintf_safe( &msg[n], sizeof( msg ) - n, ": %s", mbg_strerror( rc ) );
+ fprintf( stderr, "%s\n\n", msg );
+ goto out;
+ }
+
+ rc = MBG_SUCCESS;
+
+
+out:
+ *p_dh = dh;
+
+ return rc;
+
+} // mbg_open_device_by_param
+
+
+
+/*HDR*/
+/**
+ * @brief Main action handler that can be called by utility programs
+ *
+ * This function checks the command line parameters passed to the program.
+ * Those which have not been evaluated before are interpreted as device specifiers.
+ *
+ * Device specifiers can be device file names like "/dev/mbgclock0" on target
+ * platforms that support such device names, see ::MBG_DEV_FN,
+ * or device type names like "GPS180PEX" which can optionally have a serial
+ * number appended, like "GPS180PEX_029511026220", to be able to distinguish
+ * between several devices of the same type (see ::MBG_DEV_NAME),
+ * or just an index number as required for the ::mbg_open_device call.
+ *
+ * For each of the specified devices the callback function @p fnc is called to
+ * take some specific action on the device.
+ *
+ * If no device has been specified in the argument list then ::mbg_find_devices
+ * is called to set up a device list, and depending on whether ::CHK_DEV_ALL_DEVICES
+ * is set in @p chk_dev_flags the callback function @p fnc is either called
+ * for every device from the list, or only for the first one.
+ *
+ * @param[in] argc Number of parameters of the program argument list.
+ * @param[in] argv Array of program argument strings.
+ * @param[in] optind Number of the command line arguments that have already been handled.
+ * @param[in] fnc Pointer to a callback function that actually takes an action on each specified device.
+ * @param[in] chk_dev_flags Bit mask controlling the behavior of the function, see ::CHK_DEV_FLAGS
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int mbg_handle_devices( int argc, char *argv[], int optind,
+ MBG_DEV_HANDLER_FNC *fnc, int chk_dev_flags )
+{
+ MBG_DEV_FN tmp_dev_fn;
+ MBG_DEV_HANDLE dh;
+ int devices_specified = argc - optind;
+ int devices_found = 0;
+ const char *dev_param_str = NULL;
+ int rc = MBG_ERR_NO_DEV;
+ int i;
+
+ if ( devices_specified )
{
- int i;
- // One or more device names have been specified
+ // One or more device names have been specified
// on the command line, so handle each device.
for ( i = optind; i < argc; i++ )
{
- // Print device name only if output for several devices
- // shall be displayed.
- const char *fn = ( num_devices > 1 ) ? argv[i] : NULL;
+ dev_param_str = argv[i];
- dh = open( argv[i], O_RDWR );
- ret_val = mbg_check_device( dh, fn, fnc );
+ rc = mbg_open_device_by_param( &dh, dev_param_str, 0, devices_specified,
+ tmp_dev_fn, sizeof( tmp_dev_fn ), chk_dev_flags );
- if ( ret_val )
+ if ( mbg_rc_is_success( rc ) )
+ rc = mbg_handle_device( dh, ( devices_specified > 1 ) ? tmp_dev_fn : NULL, fnc );
+
+ // Don't continue if one of the specified devices failed.
+ if ( mbg_rc_is_error( rc ) )
break;
}
+
+ goto out;
+ }
+
+
+ // No device has been specified on the command line.
+
+ if ( chk_dev_flags & CHK_DEV_WITHOUT_DEV )
+ {
+ // TODO Check if this branch is useful
+ // We have been called without a device to be used.
+ // This may be useful e.g. if we just want to print
+ // some general usage information.
+ if ( fnc )
+ {
+ dh = MBG_INVALID_DEV_HANDLE;
+ rc = fnc( dh, NULL );
+ }
+ else
+ {
+ // TODO Should we report an error if we have been called
+ // without callback function and without device?
+ }
+ goto out;
+ }
+
+
+ devices_found = chk_get_num_devices();
+
+ if ( devices_found == 0 ) // no device found
+ {
+ // Don't continue without any device, unless
+ // explicitly requested to do so.
+ if ( !( chk_dev_flags & CHK_DEV_WITHOUT_DEV ) )
+ {
+ printf( "No device found.\n" ); // TODO
+ rc = MBG_ERR_NO_DEV;
+ goto out;
+ }
+
+ // We may continue even if no device is available,
+ // but must process the callback loop only once.
+ devices_found = 1;
}
- return ret_val;
+ // Unless explicitly requested to handle all devices
+ // we have found, we only handle the first one.
+ if ( !( chk_dev_flags & CHK_DEV_ALL_DEVICES ) )
+ devices_found = 1;
-} // mbg_check_devices
+ for ( i = 0; i < devices_found; i++ )
+ {
+ rc = mbg_open_device_by_param( &dh, NULL, i, 0, tmp_dev_fn,
+ sizeof( tmp_dev_fn ), chk_dev_flags );
+
+ if ( mbg_rc_is_success( rc ) )
+ rc = mbg_handle_device( dh, ( devices_found > 1 ) ? tmp_dev_fn : NULL, fnc );
+
+ // If one of the unspecified devices failed we continue anyway
+ // and don't break here.
+ }
+
+
+out:
+ return rc;
+
+} // mbg_handle_devices
/*HDR*/
-int mbg_snprint_hr_tstamp( char *s, int len_s, const PCPS_TIME_STAMP *p )
+/**
+ * @brief Print date and time from a ::PCPS_TIME structure to a string
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_TIME structure to be evaluated.
+ * @param[in] verbose Increase verbosity of the output:<br>
+ * > 0: append UTC offset and status<br>
+ * > 1: append signal value
+ *
+ * @return The number of characters printed to the buffer.
+ */
+size_t mbg_snprint_date_time( char *s, size_t max_len, const PCPS_TIME *p, int verbose )
{
- int n = 0;
+ size_t n = 0;
+
+ n += snprintf_safe( &s[n], max_len - n, "%04u-%02u-%02u %02u:%02u:%02u.%02u",
+ pcps_exp_year( p->year, mbg_exp_year_limit ), p->month, p->mday,
+ p->hour, p->min, p->sec, p->sec100 );
+
+ if ( verbose > 0 )
+ n += snprintf_safe( &s[n], max_len - n, " (UTC%+ih), st: %02Xh",
+ p->offs_utc, p->status );
+
+ if ( verbose > 1 )
+ n += snprintf_safe( &s[n], max_len - n, ", sig: %i", p->signal );
+
+ return n;
+
+} // mbg_snprint_date_time
+
+
+
+/*HDR*/
+/**
+ * @brief Print date and time from a ::PCPS_TIME_STAMP structure to a string
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] utc_offs A local time offset added to the time stamp before converted to date and time.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+size_t mbg_snprint_hr_tstamp( char *s, size_t max_len, const PCPS_TIME_STAMP *p,
+ long utc_offs, int show_raw )
+{
+ long l;
+ time_t t;
+ struct tm tm = { 0 };
+ size_t n = 0;
+ int rc;
+
+ if ( show_raw )
+ n += snprintf_safe( &s[n], max_len - n, "raw: 0x%08lX.%08lX, ",
+ (ulong) p->sec, (ulong) p->frac );
// We'll use the standard C library functions to convert the seconds
// to broken-down calendar date and time.
- time_t t = p->sec;
+ l = (long) p->sec + utc_offs;
+ t = cvt_to_time_t( l );
// Our time stamp may be UTC, or have been converted to local time.
- // Anyway, since we don't want to account for the system's time zone
- // settings, we always use the gmtime() function for conversion:
- struct tm *tmp = gmtime( &t );
-
- #if defined( DEBUG )
- n += snprintf( s + n, len_s - n, "raw: %08lX.%08lX, ",
- (ulong) p->sec,
- (ulong) p->frac );
- #endif
-
- n += snprintf( s + n, len_s - n, "%04i-%02i-%02i %02i:%02i:%02i." PCPS_HRT_FRAC_SCALE_FMT,
- tmp->tm_year + 1900,
- tmp->tm_mon + 1,
- tmp->tm_mday,
- tmp->tm_hour,
- tmp->tm_min,
- tmp->tm_sec,
- (ulong) frac_sec_from_bin( p->frac, PCPS_HRT_FRAC_SCALE )
- );
+ // Anyway, since we don't want to account for the system's time zone
+ // settings, we always use the gmtime() function for conversion,
+ // or our own wrapper, respectively:
+ rc = mbg_gmtime( &tm, &t );
+
+ if ( mbg_rc_is_success( rc ) )
+ n += snprintf_safe( &s[n], max_len - n, "%04i-%02i-%02i %02i:%02i:%02i." PCPS_HRT_FRAC_SCALE_FMT,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ (ulong) bin_frac_32_to_dec_frac( p->frac, PCPS_HRT_FRAC_SCALE ) );
+ else
+ n += snprint_gmtime_error( &s[n], max_len - n, rc, t, __func__ );
return n;
@@ -356,11 +797,24 @@ int mbg_snprint_hr_tstamp( char *s, int len_s, const PCPS_TIME_STAMP *p )
/*HDR*/
-int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p )
+/**
+ * @brief Print date and time from a ::PCPS_HR_TIME structure to a string
+ *
+ * Converts the UTC timestamp first to local time according to
+ * the ::PCPS_HR_TIME::utc_offs value.
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_HR_TIME structure to be evaluated.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+size_t mbg_snprint_hr_time( char *s, int max_len, const PCPS_HR_TIME *p, int show_raw )
{
char ws[80];
PCPS_TIME_STAMP ts = p->tstamp;
- int n;
+ size_t n;
const char *time_scale_name;
const char *cp;
@@ -368,19 +822,13 @@ int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p )
// and set up a string telling the offset.
if ( p->utc_offs )
{
- ldiv_t ldt;
-
- ts.sec += p->utc_offs;
-
// The local time offset is in seconds and may be negative, so we
// convert to absolute hours and minutes first.
- ldt = ldiv( labs( p->utc_offs ) / 60, 60 );
+ ldiv_t ldt = ldiv( labs( p->utc_offs ) / 60, 60 );
- snprintf( ws, sizeof( ws ), "%c%lu:%02luh",
- ( p->utc_offs < 0 ) ? '-' : '+',
- ldt.quot,
- ldt.rem
- );
+ snprintf_safe( ws, sizeof( ws ), "%c%lu:%02luh",
+ ( p->utc_offs < 0 ) ? '-' : '+',
+ ldt.quot, ldt.rem );
cp = ws;
}
else
@@ -388,7 +836,7 @@ int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p )
// Convert the local time stamp to calendar date and time.
- n = mbg_snprint_hr_tstamp( s, len_s, &ts );
+ n = mbg_snprint_hr_tstamp( s, max_len, &ts, p->utc_offs, show_raw );
// By default the time stamp represents UTC plus an optional local time offset.
time_scale_name = "UTC";
@@ -400,7 +848,7 @@ int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p )
if ( p->status & PCPS_SCALE_GPS )
time_scale_name = "GPS"; // time stamp represents GPS system time
- n += snprintf( s + n, len_s - n, " %s%s", time_scale_name, cp );
+ n += snprintf_safe( &s[n], max_len - n, " %s%s", time_scale_name, cp );
return n;
@@ -409,30 +857,154 @@ int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p )
/*HDR*/
-void mbg_print_hr_timestamp( PCPS_TIME_STAMP *p_ts, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts, int raw )
+/**
+ * @brief Print date and time from a ::PCPS_TIME_STAMP structure
+ *
+ * First the HR timestamp passed by parameter @p p_ts is printed.
+ *
+ * If the parameter @p p_prv_ts is not NULL then it should specify
+ * an earlier timestamp, and the elapsed time since @p p_ts
+ * is appended.
+ *
+ * Finally the latency value is printed in microseconds, unless
+ * parameter @p no_latency is != 0.
+ *
+ * @param[in] p_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] hns_latency A latency number in hectonanoseconds, i.e. 100 ns units.
+ * @param[in] p_prv_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated, may be NULL
+ * @param[in] no_latency A flag indicating if printing the latency should be suppressed.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @see ::mbg_print_hr_time
+ */
+void mbg_print_hr_timestamp( PCPS_TIME_STAMP *p_ts, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts,
+ int no_latency, int show_raw )
{
char ws[80];
- mbg_snprint_hr_tstamp( ws, sizeof( ws ), p_ts );
- printf( "Fast HR time %s", ws );
+ mbg_snprint_hr_tstamp( ws, sizeof( ws ), p_ts, 0, show_raw );
+ printf( "HR time %s", ws );
if ( p_prv_ts )
- {
- // print the difference between the current and the previous time stamp
- uint64_t ts = pcps_time_stamp_to_uint64( p_ts );
- uint64_t prv_ts = pcps_time_stamp_to_uint64( p_prv_ts );
- // we divide by PCPS_HRT_BIN_FRAC_SCALE to get the correct fractions
- // and we multiply by 1E6 to get the result in microseconds
- double delta_t = (double) ( ts - prv_ts ) * 1E6 / PCPS_HRT_BIN_FRAC_SCALE;
- printf( " (%+.1f us)", delta_t );
- }
+ printf( " (%+.1f us)", delta_timestamps( p_ts, p_prv_ts ) );
- if ( !raw )
+ if ( !no_latency )
printf( ", latency: %.1f us", ( (double) hns_latency ) / 10 );
- puts( "" );
+ puts( str_empty );
} // mbg_print_hr_timestamp
+/*HDR*/
+/**
+ * @brief Print date and time from a ::PCPS_HR_TIME structure
+ *
+ * First the HR timestamp passed by parameter @p p_ht is printed.
+ *
+ * If the parameter @p p_prv_ts is not NULL then it should specify
+ * an earlier timestamp, and the elapsed time since @p p_ht
+ * is appended.
+ *
+ * Next the latency value is printed in microseconds, unless
+ * parameter @p no_latency is != 0.
+ *
+ * @param[in] p_ht Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] hns_latency A latency number in hectonanoseconds, i.e. 100 ns units.
+ * @param[in] p_prv_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated, may be NULL
+ * @param[in] no_latency A flag indicating if printing the latency should be suppressed.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ * @param[in] verbose Increase verbosity of the output:<br>
+ * > 0: append status code<br>
+ * > 1: append signal value
+ *
+ * @see ::mbg_print_hr_timestamp
+ */
+void mbg_print_hr_time( PCPS_HR_TIME *p_ht, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts,
+ int no_latency, int show_raw, int verbose )
+{
+ char ws[80];
+
+ mbg_snprint_hr_time( ws, sizeof( ws ), p_ht, show_raw );
+ printf( "HR time %s", ws );
+
+ if ( p_prv_ts )
+ printf( " (%+.1f us)", delta_timestamps( &p_ht->tstamp, p_prv_ts ) );
+
+ if ( !no_latency )
+ printf( ", latency: %.1f us", ( (double) hns_latency ) / 10 );
+
+ if ( verbose > 0 )
+ printf( ", st: 0x%04lX", (ulong) p_ht->status );
+
+ if ( verbose > 1 )
+ printf( ", sig: %i", p_ht->signal );
+
+ puts( "" );
+
+} // mbg_print_hr_time
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve and print PZF correlation info for a device which supports this
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] show_corr_step A flag indicating if correlation step indicators are to be appended
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int mbg_show_pzf_corr_info( MBG_DEV_HANDLE dh, int show_corr_step )
+{
+ CORR_INFO ci;
+ char ws[80];
+ const char *cp;
+
+ int rc = mbg_get_corr_info( dh, &ci );
+
+ if ( mbg_cond_err_msg( rc, "mbg_get_corr_info" ) )
+ return rc;
+
+
+ if ( ci.status < N_PZF_CORR_STATE )
+ cp = pzf_corr_state_name[ci.status];
+ else
+ {
+ snprintf_safe( ws, sizeof( ws ), "unknown status code: 0x%02X", ci.status );
+ cp = ws;
+ }
+
+ printf( "%s, PZF correlation: %u%%", cp, ci.val );
+
+ if ( show_corr_step )
+ if ( ci.corr_dir != ' ' )
+ printf( " Shift: %c", ci.corr_dir );
+
+ return MBG_SUCCESS;
+
+} // mbg_show_pzf_corr_info
+
+
+
+/*HDR*/
+/**
+ * @brief Retrieve a ::MBG_GNSS_MODE_INFO structure from a device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+int mbg_get_gps_gnss_mode_info_chk( MBG_DEV_HANDLE dh, MBG_GNSS_MODE_INFO *p )
+{
+ int rc = mbg_get_gps_gnss_mode_info( dh, p );
+ mbg_cond_err_msg( rc, "mbg_get_gps_gnss_mode_info" );
+
+ return rc;
+
+} // mbg_get_gps_gnss_mode_info_chk
+
+
+
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/toolutil.h b/src/external/bsd/meinberg/dist/mbglib/common/toolutil.h
index cef7d44..103e8af 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/toolutil.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/toolutil.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: toolutil.h 1.2.1.2 2011/07/05 15:35:56 martin TRASH martin $
+ * $Id: toolutil.h 1.4 2017/07/05 07:38:06 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,10 +10,18 @@
*
* -----------------------------------------------------------------------
* $Log: toolutil.h $
- * Revision 1.2.1.2 2011/07/05 15:35:56 martin
- * Modified version handling.
- * Revision 1.2.1.1 2011/07/05 14:36:42 martin
- * New way to maintain version information.
+ * Revision 1.4 2017/07/05 07:38:06 martin
+ * Support Windows target.
+ * Defined function type MBG_DEV_HANDLER_FNC.
+ * Defined some OS-specific strings e.g. for example
+ * file and device names used in help messages.
+ * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX.
+ * Doxygen comments.
+ * Updated function prototypes.
+ * Revision 1.3 2012/10/15 09:36:22 martin
+ * Use common way to handle version information.
+ * Added string table with PZF state names.
+ * Updated function prototypes.
* Revision 1.2 2009/06/19 12:11:35 martin
* Updated function prototypes.
* Revision 1.1 2008/12/17 10:45:14 martin
@@ -32,6 +40,25 @@
#include <mbgdevio.h>
#include <mbgversion.h>
+#if defined( MBG_TGT_POSIX )
+
+ #include <unistd.h>
+
+#elif defined( MBG_TGT_WIN32 )
+
+ #include <io.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <wingetopt.h>
+
+ #define open _open
+ #define snprintf _snprintf
+ #define sleep( _x ) Sleep( (_x) * 1000 )
+ #define usleep( _x ) Sleep( (_x) / 1000 )
+
+#endif
+
#ifdef _TOOLUTIL
@@ -44,12 +71,85 @@
/* Start of header body */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+enum CHK_DEV_FLAGS
+{
+ CHK_DEV_ALL_DEVICES = 0x0001, ///< call callback for all devices
+ CHK_DEV_WITHOUT_DEV = 0x0002 ///< call callback once if no device found
+};
+
+
+
+#if MBG_TGT_HAS_DEV_FN
+ #define EXAMPLE_DEV_FN_1 MBGCLOCK_DEV_FN_BASE "0"
+ #define EXAMPLE_DEV_FN_1_TCR EXAMPLE_DEV_FN_1
+ #define EXAMPLE_DEV_FN_2 MBGCLOCK_DEV_FN_BASE "3"
+#endif
+
+#define EXAMPLE_DEV_NAME_1 "gps180pex"
+#define EXAMPLE_DEV_NAME_1_TCR "tcr167pci"
+#define EXAMPLE_DEV_NAME_2 "tcr170pex_027911002000"
+
+
+#if defined( MBG_TGT_POSIX )
+ #define ROOT_PRIVILEGES_STR "with root privileges"
+#else
+ #define ROOT_PRIVILEGES_STR "as administrator"
+#endif
+
+
+#if !defined( MBG_EXP_YEAR_LIMIT )
+ #define MBG_EXP_YEAR_LIMIT 1980
+#endif
+
+
+_ext uint16_t mbg_exp_year_limit
+#ifdef _DO_INIT
+ = MBG_EXP_YEAR_LIMIT
+#endif
+;
+
_ext int must_print_usage;
+_ext const char str_empty[]
+#ifdef _DO_INIT
+ = ""
+#endif
+;
-#ifdef __cplusplus
-extern "C" {
+
+_ext const char *pzf_corr_state_name[N_PZF_CORR_STATE]
+#ifdef _DO_INIT
+ = PZF_CORR_STATE_NAMES_ENG
#endif
+;
+
+
+
+/**
+ * @brief The type of functions to called to handle a device in a specific way.
+ */
+typedef int MBG_DEV_HANDLER_FNC( MBG_DEV_HANDLE, const PCPS_DEV *);
+
+
+
+/**
+ * @brief Exit codes returned by the command line tools
+ */
+enum MBG_EXIT_CODES
+{
+ MBG_EXIT_CODE_SUCCESS, ///< Device handled successfully for requested action
+ MBG_EXIT_CODE_USAGE, ///< Device not handled successfully, usage printed
+ MBG_EXIT_CODE_NOT_SUPP, ///< Not supported on the running OS
+ MBG_EXIT_CODE_FAIL, ///< Action failed for device
+ MBG_EXIT_CODE_INV_TIME, ///< Device has no valid time to set the system time with
+ N_MBG_EXIT_CODES
+};
+
/* ----- function prototypes begin ----- */
@@ -57,20 +157,250 @@ extern "C" {
/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */
+ /**
+ * @brief Print the program version to a string buffer
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] micro_version Micro version code for the application.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+ int mbg_program_version_str( char *s, size_t max_len, int micro_version ) ;
+
+ /**
+ * @brief Print some program info to a string buffer
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] pname The program name.
+ * @param[in] micro_version Micro version code for the application.
+ * @param[in] first_year First copyright year.
+ * @param[in] last_year Last copyright year.
+ *
+ * @return The number of characters printed to the buffer.
+ */
int mbg_program_info_str( char *s, size_t max_len, const char *pname, int micro_version, int first_year, int last_year ) ;
+
+ /**
+ * @brief Print program info to console
+ *
+ * @param[in] pname The program name.
+ * @param[in] micro_version Micro version code for the application.
+ * @param[in] first_year First copyright year.
+ * @param[in] last_year Last copyright year.
+ */
void mbg_print_program_info( const char *pname, int micro_version, int first_year, int last_year ) ;
+
+ /**
+ * @brief Print usage intro to console
+ *
+ * @param[in] pname The program name.
+ * @param[in] info An optional additional info string, may be NULL.
+ */
void mbg_print_usage_intro( const char *pname, const char *info ) ;
- void mbg_print_help_options( void ) ;
+
+ /**
+ * @brief Print info on a single program option / argument
+ *
+ * @param[in] opt_name The option name, optional, may be NULL.
+ * @param[in] opt_info The option info, optional, may be NULL.
+ */
void mbg_print_opt_info( const char *opt_name, const char *opt_info ) ;
+
+ /**
+ * @brief Print info on common program help arguments
+ *
+ * Lists program parameters causing printing
+ * of help / usage information.
+ */
+ void mbg_print_help_options( void ) ;
+
+ /**
+ * @brief Print common info on how to specify devices on the command line
+ */
void mbg_print_device_options( void ) ;
+
+ /**
+ * @brief Print program info and default usage information
+ *
+ * @param[in] pname The program name.
+ * @param[in] prog_info An optional additional info string, may be NULL.
+ */
void mbg_print_default_usage( const char *pname, const char *prog_info ) ;
- int mbg_ioctl_err( int rc, const char *descr ) ;
+
+ /**
+ * @brief Retrieve and print some common device info
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] dev_name A device name string to be printed
+ * @param[out] p_dev Pointer to a device info structure to be read from the device
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
int mbg_get_show_dev_info( MBG_DEV_HANDLE dh, const char *dev_name, PCPS_DEV *p_dev ) ;
- int mbg_check_device( MBG_DEV_HANDLE dh, const char *dev_name, int (*fnc)( MBG_DEV_HANDLE, const PCPS_DEV *) ) ;
- int mbg_check_devices( int argc, char *argv[], int optind, int (*fnc)( MBG_DEV_HANDLE, const PCPS_DEV *) ) ;
- int mbg_snprint_hr_tstamp( char *s, int len_s, const PCPS_TIME_STAMP *p ) ;
- int mbg_snprint_hr_time( char *s, int len_s, const PCPS_HR_TIME *p ) ;
- void mbg_print_hr_timestamp( PCPS_TIME_STAMP *p_ts, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts, int raw ) ;
+
+ /**
+ * @brief Print device info and take some action on a specific device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] dev_name A device name string to be printed.
+ * @param[in] fnc Pointer to a callback function that actually takes the action.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ int mbg_handle_device( MBG_DEV_HANDLE dh, const char *dev_name, MBG_DEV_HANDLER_FNC *fnc ) ;
+
+ /**
+ * @brief Get the number of devices actually present
+ *
+ * Do a real search only when called for the first time.
+ *
+ * @return The number of devices currently present.
+ */
+ int chk_get_num_devices( void ) ;
+
+ int mbg_open_device_by_param( MBG_DEV_HANDLE *p_dh, const char *dev_param_str, int dev_idx, int devices_specified, char *dev_name_buffer, size_t dev_name_buffer_size, int chk_dev_flags ) ;
+ /**
+ * @brief Main action handler that can be called by utility programs
+ *
+ * This function checks the command line parameters passed to the program.
+ * Those which have not been evaluated before are interpreted as device specifiers.
+ *
+ * Device specifiers can be device file names like "/dev/mbgclock0" on target
+ * platforms that support such device names, see ::MBG_DEV_FN,
+ * or device type names like "GPS180PEX" which can optionally have a serial
+ * number appended, like "GPS180PEX_029511026220", to be able to distinguish
+ * between several devices of the same type (see ::MBG_DEV_NAME),
+ * or just an index number as required for the ::mbg_open_device call.
+ *
+ * For each of the specified devices the callback function @p fnc is called to
+ * take some specific action on the device.
+ *
+ * If no device has been specified in the argument list then ::mbg_find_devices
+ * is called to set up a device list, and depending on whether ::CHK_DEV_ALL_DEVICES
+ * is set in @p chk_dev_flags the callback function @p fnc is either called
+ * for every device from the list, or only for the first one.
+ *
+ * @param[in] argc Number of parameters of the program argument list.
+ * @param[in] argv Array of program argument strings.
+ * @param[in] optind Number of the command line arguments that have already been handled.
+ * @param[in] fnc Pointer to a callback function that actually takes an action on each specified device.
+ * @param[in] chk_dev_flags Bit mask controlling the behavior of the function, see ::CHK_DEV_FLAGS
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ int mbg_handle_devices( int argc, char *argv[], int optind, MBG_DEV_HANDLER_FNC *fnc, int chk_dev_flags ) ;
+
+ /**
+ * @brief Print date and time from a ::PCPS_TIME structure to a string
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_TIME structure to be evaluated.
+ * @param[in] verbose Increase verbosity of the output:<br>
+ * > 0: append UTC offset and status<br>
+ * > 1: append signal value
+ *
+ * @return The number of characters printed to the buffer.
+ */
+ size_t mbg_snprint_date_time( char *s, size_t max_len, const PCPS_TIME *p, int verbose ) ;
+
+ /**
+ * @brief Print date and time from a ::PCPS_TIME_STAMP structure to a string
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] utc_offs A local time offset added to the time stamp before converted to date and time.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+ size_t mbg_snprint_hr_tstamp( char *s, size_t max_len, const PCPS_TIME_STAMP *p, long utc_offs, int show_raw ) ;
+
+ /**
+ * @brief Print date and time from a ::PCPS_HR_TIME structure to a string
+ *
+ * Converts the UTC timestamp first to local time according to
+ * the ::PCPS_HR_TIME::utc_offs value.
+ *
+ * @param[out] s Address of a string buffer to be filled.
+ * @param[in] max_len Size of the string buffer.
+ * @param[in] p Pointer to a ::PCPS_HR_TIME structure to be evaluated.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @return The number of characters printed to the buffer.
+ */
+ size_t mbg_snprint_hr_time( char *s, int max_len, const PCPS_HR_TIME *p, int show_raw ) ;
+
+ /**
+ * @brief Print date and time from a ::PCPS_TIME_STAMP structure
+ *
+ * First the HR timestamp passed by parameter @p p_ts is printed.
+ *
+ * If the parameter @p p_prv_ts is not NULL then it should specify
+ * an earlier timestamp, and the elapsed time since @p p_ts
+ * is appended.
+ *
+ * Finally the latency value is printed in microseconds, unless
+ * parameter @p no_latency is != 0.
+ *
+ * @param[in] p_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] hns_latency A latency number in hectonanoseconds, i.e. 100 ns units.
+ * @param[in] p_prv_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated, may be NULL
+ * @param[in] no_latency A flag indicating if printing the latency should be suppressed.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ *
+ * @see ::mbg_print_hr_time
+ */
+ void mbg_print_hr_timestamp( PCPS_TIME_STAMP *p_ts, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts, int no_latency, int show_raw ) ;
+
+ /**
+ * @brief Print date and time from a ::PCPS_HR_TIME structure
+ *
+ * First the HR timestamp passed by parameter @p p_ht is printed.
+ *
+ * If the parameter @p p_prv_ts is not NULL then it should specify
+ * an earlier timestamp, and the elapsed time since @p p_ht
+ * is appended.
+ *
+ * Next the latency value is printed in microseconds, unless
+ * parameter @p no_latency is != 0.
+ *
+ * @param[in] p_ht Pointer to a ::PCPS_TIME_STAMP structure to be evaluated.
+ * @param[in] hns_latency A latency number in hectonanoseconds, i.e. 100 ns units.
+ * @param[in] p_prv_ts Pointer to a ::PCPS_TIME_STAMP structure to be evaluated, may be NULL
+ * @param[in] no_latency A flag indicating if printing the latency should be suppressed.
+ * @param[in] show_raw Flag indicating if a raw timestamp (hex) is to be printed, too.
+ * @param[in] verbose Increase verbosity of the output:<br>
+ * > 0: append status code<br>
+ * > 1: append signal value
+ *
+ * @see ::mbg_print_hr_timestamp
+ */
+ void mbg_print_hr_time( PCPS_HR_TIME *p_ht, int32_t hns_latency, PCPS_TIME_STAMP *p_prv_ts, int no_latency, int show_raw, int verbose ) ;
+
+ /**
+ * @brief Retrieve and print PZF correlation info for a device which supports this
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[in] show_corr_step A flag indicating if correlation step indicators are to be appended
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ int mbg_show_pzf_corr_info( MBG_DEV_HANDLE dh, int show_corr_step ) ;
+
+ /**
+ * @brief Retrieve a ::MBG_GNSS_MODE_INFO structure from a device
+ *
+ * @param[in] dh Valid ::MBG_DEV_HANDLE handle to a Meinberg device.
+ * @param[out] p Pointer to a ::MBG_GNSS_MODE_INFO structure to be filled up.
+ *
+ * @return ::MBG_SUCCESS on success, else one of the @ref MBG_ERROR_CODES
+ */
+ int mbg_get_gps_gnss_mode_info_chk( MBG_DEV_HANDLE dh, MBG_GNSS_MODE_INFO *p ) ;
+
/* ----- function prototypes end ----- */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/usbdefs.h b/src/external/bsd/meinberg/dist/mbglib/common/usbdefs.h
index 30a39e2..b69cbcb 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/usbdefs.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/usbdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: usbdefs.h 1.13 2011/06/29 14:11:23 martin TRASH $
+ * $Id: usbdefs.h 1.30 2017/05/17 09:52:53 thomas.fasse REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,53 @@
*
* -----------------------------------------------------------------------
* $Log: usbdefs.h $
- * Revision 1.13 2011/06/29 14:11:23 martin
+ * Revision 1.30 2017/05/17 09:52:53 thomas.fasse
+ * Device BITS was rennamed to LSG180.
+ * Revision 1.29 2017/05/16 07:19:40Z thomas.fasse
+ * Added ID, name string and table entry for LIU variant BITS by Paul
+ * Revision 1.28 2017/04/04 10:43:34Z paul.kretz
+ * Added ID, name string and table entry for FDM180M
+ * Added missing table entry for MicroSync power supply module
+ * Revision 1.27 2017/03/28 09:37:15Z paul.kretz
+ * Added ID, name string and table entry for MicroSync power supply module
+ * Revision 1.26 2017/02/13 09:57:45Z paul.kretz
+ * Added ID, name string and table entry for PZF180.
+ * Revision 1.25 2016/11/11 09:24:04Z lars.meihost
+ * Added ID, name string and table entry for TCR180.
+ * Revision 1.24 2016/11/04 11:49:15Z paul.kretz
+ * Added device ID and associated class code for MDU312
+ * Revision 1.23 2016/09/26 07:28:10Z paul.kretz
+ * Added class code and device for N2X180
+ * Revision 1.22 2016/07/06 13:55:15Z martin
+ * Definitions for IMS-SPT, REL1000, MDU300, and SDI added by stephan.
+ * Class code and device ID for LUE added by daniel-vdh.
+ * Class code and device ID for HPS added by daniel.
+ * Device IDs and associated class codes for SCG, FDM180, CPC180,
+ * VSG180, and GTS180 added by paul.
+ * Removed obsolete multiple definitions for FTDI serial interface chips.
+ * Added a new definition for unique FTDI chip.
+ * Added definitions for serial refclocks.
+ * Added definitions for LNE180SFP, GRC180 and GRC181.
+ * Added definitions USB_VENDOR_WILDCARD and USB_PROD_WILDCARD.
+ * Added device name string and string table initializers.
+ * Doxygen fixes.
+ * Revision 1.21 2014/01/16 15:26:09 daniel
+ * Added class codes and devices for USB to serial adapters and ASIX network chips
+ * Revision 1.20 2013/10/08 09:13:04 daniel
+ * Added definition and class code for RSC.
+ * Revision 1.19 2013/06/04 10:45:53 daniel
+ * Added class codes and device IDs for IMS devices MRI and BPE
+ * Revision 1.18 2013/01/24 11:29:21 joerg
+ * Added class code and device ID for LNE-GB
+ * Revision 1.17 2012/08/08 07:53:29Z daniel
+ * Added class code and device ID for LIU
+ * Revision 1.16 2012/02/13 09:29:59 paul
+ * added class code for LNO180
+ * Revision 1.15 2011/10/11 06:21:04Z andre
+ * added class code for GPS180
+ * Revision 1.14 2011/10/07 10:13:25Z daniel
+ * New class code and device id for CPE
+ * Revision 1.13 2011/06/29 14:11:23Z martin
* Added device IDs for TCR600USB, MSF600USB, and WVB600USB.
* Revision 1.12 2011/05/11 07:20:37 daniel
* New class code and device id for fan control unit
@@ -55,58 +101,305 @@ extern "C" {
#endif
-/* Meinberg's USB vendor ID number (assigned by USB-IF Administration) */
+/** Meinberg's USB vendor ID number (assigned by USB-IF administration) */
#define USB_VENDOR_MEINBERG 0x1938
+#define USB_VENDOR_WILDCARD 0
+#define USB_PROD_WILDCARD 0
-/*
- * USB device class codes (assigned by Meinberg)
+
+/**
+ * @brief USB device class codes assigned by Meinberg
*/
-enum
+enum MBG_USB_CLASS_CODES
{
- 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
- MBG_USB_CLASS_SCU, // Meinberg Signal Changeover Unit
- MBG_USB_CLASS_ESI, // External Synchronization Interface
- MBG_USB_CLASS_FCU, // Fan Control Unit
- N_MBG_USB_CLASS // number of known device class codes
+ 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
+
+ MBG_USB_CLASS_SCU, ///< Meinberg Signal Changeover Unit
+ MBG_USB_CLASS_ESI, ///< External Synchronization Interface
+ MBG_USB_CLASS_FCU, ///< Fan Control Unit
+ MBG_USB_CLASS_CPE, ///< Configurable Port Expander
+ MBG_USB_CLASS_GPS, ///< GPS Receiver
+ MBG_USB_CLASS_LNO, ///< Low Phase Noise Option
+ MBG_USB_CLASS_LIU, ///< Line Interface Unit
+ MBG_USB_CLASS_LNE, ///< LNE-GB
+
+ MBG_USB_CLASS_MRI, ///< MRS Input card for IMS
+ MBG_USB_CLASS_BPE, ///< IMS Backplane Port Expander
+ MBG_USB_CLASS_RSC, ///< RSC Redundant Switch Control
+ MBG_USB_CLASS_SERIAL, ///< USB to Serial controller, FTDI chip connected to Meinberg serial device
+ MBG_USB_CLASS_SCG, ///< Studio Clock Generator
+ MBG_USB_CLASS_SDI, ///< SDI Input card for IMS
+ MBG_USB_CLASS_FDM, ///< Frequency Deviation Monitor
+ MBG_USB_CLASS_NIC, ///< ASIX AX88179 Network interface chips on LNE, modified by Meinberg (this *must* be 0x17)
+
+ MBG_USB_CLASS_MDU, ///< Modular Distribution Unit
+ MBG_USB_CLASS_SPT, ///< Single Path Through
+ MBG_USB_CLASS_REL, ///< Relais Error Card
+ MBG_USB_CLASS_LUE, ///< Lantime USB Expansion
+ MBG_USB_CLASS_HPS, ///< High Performance Synchronization Card (PTP/NTP)
+ MBG_USB_CLASS_VSG, ///< Video Sync Generator
+ MBG_USB_CLASS_GTS, ///< Greenwich Time Signal
+ MBG_USB_CLASS_GRC, ///< GNSS receivers (GPS, GLONASS, ... )
+
+ MBG_USB_CLASS_N2X, ///< NTP/PTP receiver
+ MBG_USB_CLASS_USYNC, ///< MicroSync
+
+ N_MBG_USB_CLASS ///< number of known Meinberg USB 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
+/**
+ * @brief USB device ID numbers assigned by Meinberg
+ *
+ * High byte: USB device class, see ::MBG_USB_CLASS_CODES<br>
+ * Low byte: enumeration of devices of a class
+ *
+ * @see @ref MBG_USB_DEVICE_NAMES
+ * @see ::DEFAULT_MBG_USB_DEVICE_NAMES
+ * @see ::MBG_USB_CLASS_CODES
+ *
+ * @anchor MBG_USB_DEVICE_IDS @{
*/
-#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_CPC_01 ( ( MBG_USB_CLASS_CPC << 8 ) | 0x01 )
+#define USB_DEV_CPC180 ( ( MBG_USB_CLASS_CPC << 8 ) | 0x02 )
+
+#define USB_DEV_TSU_01 ( ( MBG_USB_CLASS_TSU << 8 ) | 0x01 )
+
+#define USB_DEV_USB5131 ( ( MBG_USB_CLASS_DCF << 8 ) | 0x01 )
+#define USB_DEV_DCF600USB ( ( MBG_USB_CLASS_DCF << 8 ) | 0x02 )
+#define USB_DEV_PZF180 ( ( MBG_USB_CLASS_DCF << 8 ) | 0x03 )
+
+#define USB_DEV_CMC ( ( MBG_USB_CLASS_CMC << 8 ) | 0x01 )
+
+#define USB_DEV_TCR51USB ( ( MBG_USB_CLASS_TCR << 8 ) | 0x01 )
+#define USB_DEV_TCR600USB ( ( MBG_USB_CLASS_TCR << 8 ) | 0x02 )
+#define USB_DEV_TCR180 ( ( MBG_USB_CLASS_TCR << 8 ) | 0x03 )
+
+#define USB_DEV_MSF51USB ( ( MBG_USB_CLASS_MSF << 8 ) | 0x01 )
+#define USB_DEV_MSF600USB ( ( MBG_USB_CLASS_MSF << 8 ) | 0x02 )
+
+#define USB_DEV_WWVB51USB ( ( MBG_USB_CLASS_WWVB << 8 ) | 0x01 )
+#define USB_DEV_WVB600USB ( ( MBG_USB_CLASS_WWVB << 8 ) | 0x02 )
+
+#define USB_DEV_SCU_USB ( ( MBG_USB_CLASS_SCU << 8 ) | 0x01 )
+
+#define USB_DEV_ESI_01 ( ( MBG_USB_CLASS_ESI << 8 ) | 0x01 )
+
+#define USB_DEV_FCU_01 ( ( MBG_USB_CLASS_FCU << 8 ) | 0x01 )
+
+#define USB_DEV_CPE_01 ( ( MBG_USB_CLASS_CPE << 8 ) | 0x01 )
+
+#define USB_DEV_GPS180 ( ( MBG_USB_CLASS_GPS << 8 ) | 0x01 )
-#define USB_DEV_USB5131 ( ( MBG_USB_CLASS_DCF << 8 ) | 0x01 )
-#define USB_DEV_DCF600USB ( ( MBG_USB_CLASS_DCF << 8 ) | 0x02 )
+#define USB_DEV_LNO180 ( ( MBG_USB_CLASS_LNO << 8 ) | 0x01 )
-#define USB_DEV_CMC ( ( MBG_USB_CLASS_CMC << 8 ) | 0x01 )
+#define USB_DEV_LIU_01 ( ( MBG_USB_CLASS_LIU << 8 ) | 0x01 )
+#define USB_DEV_LSG180 ( ( MBG_USB_CLASS_LIU << 8 ) | 0x02 )
-#define USB_DEV_TCR51USB ( ( MBG_USB_CLASS_TCR << 8 ) | 0x01 )
-#define USB_DEV_TCR600USB ( ( MBG_USB_CLASS_TCR << 8 ) | 0x02 )
+#define USB_DEV_LNE_01 ( ( MBG_USB_CLASS_LNE << 8 ) | 0x01 ) // LNE with standard copper
+#define USB_DEV_LNE180SFP ( ( MBG_USB_CLASS_LNE << 8 ) | 0x02 ) // LNE with SFP (fiber optic)
-#define USB_DEV_MSF51USB ( ( MBG_USB_CLASS_MSF << 8 ) | 0x01 )
-#define USB_DEV_MSF600USB ( ( MBG_USB_CLASS_MSF << 8 ) | 0x02 )
+#define USB_DEV_MRI_01 ( ( MBG_USB_CLASS_MRI << 8 ) | 0x01 )
-#define USB_DEV_WWVB51USB ( ( MBG_USB_CLASS_WWVB << 8 ) | 0x01 )
-#define USB_DEV_WVB600USB ( ( MBG_USB_CLASS_WWVB << 8 ) | 0x02 )
+#define USB_DEV_BPE_01 ( ( MBG_USB_CLASS_BPE << 8 ) | 0x01 )
-#define USB_DEV_SCU_USB ( ( MBG_USB_CLASS_SCU << 8 ) | 0x01 )
+#define USB_DEV_RSC_01 ( ( MBG_USB_CLASS_RSC << 8 ) | 0x01 )
+
+#define USB_DEV_SPT_01 ( ( MBG_USB_CLASS_SPT << 8 ) | 0x01 )
+
+#define USB_DEV_REL_01 ( ( MBG_USB_CLASS_REL << 8 ) | 0x01 )
+
+/// LANTIME CPU quad FTDI serial interface chip
+#define USB_DEV_LAN_CPU_SERIAL ( ( MBG_USB_CLASS_SERIAL << 8 ) | 0x01 )
+
+#define USB_DEV_SCG_01 ( ( MBG_USB_CLASS_SCG << 8 ) | 0x01 )
+
+#define USB_DEV_SDI_01 ( ( MBG_USB_CLASS_SDI << 8 ) | 0x01 )
+
+#define USB_DEV_FDM180 ( ( MBG_USB_CLASS_FDM << 8 ) | 0x01 ) // FDM for IMS Systems
+#define USB_DEV_FDM180M ( ( MBG_USB_CLASS_FDM << 8 ) | 0x02 ) // FDM for old Lantime Systems (M300/M600/M900)
+
+#define USB_DEV_MDU300 ( ( MBG_USB_CLASS_MDU << 8 ) | 0x01 )
+#define USB_DEV_MDU312 ( ( MBG_USB_CLASS_MDU << 8 ) | 0x02 )
+
+#define USB_DEV_LUE_01 ( ( MBG_USB_CLASS_LUE << 8 ) | 0x01 )
+
+#define USB_DEV_HPS100 ( ( MBG_USB_CLASS_HPS << 8 ) | 0x01 )
+
+#define USB_DEV_VSG180 ( ( MBG_USB_CLASS_VSG << 8 ) | 0x01 )
+
+#define USB_DEV_GTS180 ( ( MBG_USB_CLASS_GTS << 8 ) | 0x01 )
+
+#define USB_DEV_GRC180 ( ( MBG_USB_CLASS_GRC << 8 ) | 0x01 )
+#define USB_DEV_GRC181 ( ( MBG_USB_CLASS_GRC << 8 ) | 0x02 )
+
+#define USB_DEV_N2X180 ( ( MBG_USB_CLASS_N2X << 8 ) | 0x01 )
+
+#define USB_DEV_USYNCPWR ( ( MBG_USB_CLASS_USYNC << 8 ) | 0x01 ) // MicroSync Power Supply Module
+
+// If new devices are defined here then appropriate definitions should also
+// be added to MBG_USB_DEVICE_NAMES and DEFAULT_MBG_USB_DEVICE_NAMES.
+
+/** @} anchor MBG_USB_DEVICE_IDS */
+
+
+
+/**
+ * @brief Device name strings for Meinberg USB devices
+ *
+ * @see @ref MBG_USB_DEVICE_IDS
+ * @see ::DEFAULT_MBG_USB_DEVICE_NAMES
+ *
+ * @anchor MBG_USB_DEVICE_NAMES @{
+ */
+
+#define USB_DEV_NAME_CPC_01 "CPC_01"
+#define USB_DEV_NAME_CPC180 "CPC180"
+
+#define USB_DEV_NAME_TSU_01 "TSU_01"
+
+#define USB_DEV_NAME_USB5131 "USB5131"
+#define USB_DEV_NAME_DCF600USB "DCF600USB"
+#define USB_DEV_NAME_PZF180 "PZF180"
+
+#define USB_DEV_NAME_CMC "CMC"
+
+#define USB_DEV_NAME_TCR51USB "TCR51USB"
+#define USB_DEV_NAME_TCR600USB "TCR600USB"
+#define USB_DEV_NAME_TCR180 "TCR180"
+
+#define USB_DEV_NAME_MSF51USB "MSF51USB"
+#define USB_DEV_NAME_MSF600USB "MSF600USB"
+
+#define USB_DEV_NAME_WWVB51USB "WWVB51USB"
+#define USB_DEV_NAME_WVB600USB "WVB600USB"
+
+#define USB_DEV_NAME_SCU_USB "SCU_USB"
+
+#define USB_DEV_NAME_ESI_01 "ESI_01"
+
+#define USB_DEV_NAME_FCU_01 "FCU_01"
+
+#define USB_DEV_NAME_CPE_01 "CPE_01"
+
+#define USB_DEV_NAME_GPS180 "GPS180"
+
+#define USB_DEV_NAME_LNO180 "LNO180"
+
+#define USB_DEV_NAME_LIU_01 "LIU_01"
+#define USB_DEV_NAME_LSG180 "LSG180"
+
+#define USB_DEV_NAME_LNE_01 "LNE_01"
+#define USB_DEV_NAME_LNE180SFP "LNE180SFP"
+
+#define USB_DEV_NAME_MRI_01 "MRI_01"
+
+#define USB_DEV_NAME_BPE_01 "BPE_01"
+
+#define USB_DEV_NAME_RSC_01 "RSC_01"
+
+#define USB_DEV_NAME_SPT_01 "SPT_01"
+
+#define USB_DEV_NAME_REL_01 "REL_01"
+
+#define USB_DEV_NAME_LAN_CPU_SERIAL "LAN_CPU_SERIAL"
+
+#define USB_DEV_NAME_SCG_01 "SCG_01"
+
+#define USB_DEV_NAME_SDI_01 "SDI_01"
+
+#define USB_DEV_NAME_FDM180 "FDM180"
+#define USB_DEV_NAME_FDM180M "FDM180M"
+
+#define USB_DEV_NAME_MDU300 "MDU300"
+#define USB_DEV_NAME_MDU312 "MDU312"
+
+#define USB_DEV_NAME_LUE_01 "LUE_01"
+
+#define USB_DEV_NAME_HPS100 "HPS100"
+
+#define USB_DEV_NAME_VSG180 "VSG180"
+
+#define USB_DEV_NAME_GTS180 "GTS180"
+
+#define USB_DEV_NAME_GRC180 "GRC180"
+#define USB_DEV_NAME_GRC181 "GRC181"
+
+#define USB_DEV_NAME_N2X180 "N2X180"
+
+#define USB_DEV_NAME_USYNCPWR "MICROSYNC-PWR"
+
+/** @} anchor MBG_USB_DEVICE_NAMES */
+
+
+
+/**
+ * @brief Initializer for a table of USB device ISs and name strings
+ *
+ * Can be used e.g. to initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY.
+ *
+ * @see @ref MBG_USB_DEVICE_IDS
+ * @see @ref MBG_USB_DEVICE_NAMES
+ */
+#define DEFAULT_MBG_USB_DEVICE_NAMES \
+{ \
+ { USB_DEV_CPC_01, USB_DEV_NAME_CPC_01 }, \
+ { USB_DEV_CPC180, USB_DEV_NAME_CPC180 }, \
+ { USB_DEV_TSU_01, USB_DEV_NAME_TSU_01 }, \
+ { USB_DEV_USB5131, USB_DEV_NAME_USB5131 }, \
+ { USB_DEV_DCF600USB, USB_DEV_NAME_DCF600USB }, \
+ { USB_DEV_CMC, USB_DEV_NAME_CMC }, \
+ { USB_DEV_TCR51USB, USB_DEV_NAME_TCR51USB }, \
+ { USB_DEV_TCR600USB, USB_DEV_NAME_TCR600USB }, \
+ { USB_DEV_TCR180, USB_DEV_NAME_TCR180 }, \
+ { USB_DEV_MSF51USB, USB_DEV_NAME_MSF51USB }, \
+ { USB_DEV_MSF600USB, USB_DEV_NAME_MSF600USB }, \
+ { USB_DEV_WWVB51USB, USB_DEV_NAME_WWVB51USB }, \
+ { USB_DEV_WVB600USB, USB_DEV_NAME_WVB600USB }, \
+ { USB_DEV_SCU_USB, USB_DEV_NAME_SCU_USB }, \
+ { USB_DEV_ESI_01, USB_DEV_NAME_ESI_01 }, \
+ { USB_DEV_FCU_01, USB_DEV_NAME_FCU_01 }, \
+ { USB_DEV_CPE_01, USB_DEV_NAME_CPE_01 }, \
+ { USB_DEV_GPS180, USB_DEV_NAME_GPS180 }, \
+ { USB_DEV_LNO180, USB_DEV_NAME_LNO180 }, \
+ { USB_DEV_LIU_01, USB_DEV_NAME_LIU_01 }, \
+ { USB_DEV_LNE_01, USB_DEV_NAME_LNE_01 }, \
+ { USB_DEV_MRI_01, USB_DEV_NAME_MRI_01 }, \
+ { USB_DEV_BPE_01, USB_DEV_NAME_BPE_01 }, \
+ { USB_DEV_RSC_01, USB_DEV_NAME_RSC_01 }, \
+ { USB_DEV_SPT_01, USB_DEV_NAME_SPT_01 }, \
+ { USB_DEV_REL_01, USB_DEV_NAME_REL_01 }, \
+ { USB_DEV_LAN_CPU_SERIAL, USB_DEV_NAME_LAN_CPU_SERIAL }, \
+ { USB_DEV_SCG_01, USB_DEV_NAME_SCG_01 }, \
+ { USB_DEV_SDI_01, USB_DEV_NAME_SDI_01 }, \
+ { USB_DEV_FDM180, USB_DEV_NAME_FDM180 }, \
+ { USB_DEV_MDU300, USB_DEV_NAME_MDU300 }, \
+ { USB_DEV_LUE_01, USB_DEV_NAME_LUE_01 }, \
+ { USB_DEV_HPS100, USB_DEV_NAME_HPS100 }, \
+ { USB_DEV_VSG180, USB_DEV_NAME_VSG180 }, \
+ { USB_DEV_LNE180SFP, USB_DEV_NAME_LNE180SFP }, \
+ { USB_DEV_GTS180, USB_DEV_NAME_GTS180 }, \
+ { USB_DEV_GRC180, USB_DEV_NAME_GRC180 }, \
+ { USB_DEV_GRC181, USB_DEV_NAME_GRC181 }, \
+ { USB_DEV_N2X180, USB_DEV_NAME_N2X180 }, \
+ { USB_DEV_MDU312, USB_DEV_NAME_MDU312 }, \
+ { USB_DEV_PZF180, USB_DEV_NAME_PZF180 }, \
+ { USB_DEV_USYNCPWR, USB_DEV_NAME_USYNCPWR }, \
+ { USB_DEV_FDM180M, USB_DEV_NAME_FDM180M }, \
+ { USB_DEV_LSG180, USB_DEV_NAME_LSG180 }, \
+ { 0, /* end of table */ NULL } \
+}
-#define USB_DEV_ESI_01 ( ( MBG_USB_CLASS_ESI << 8 ) | 0x01 )
-#define USB_DEV_FCU_01 ( ( MBG_USB_CLASS_FCU << 8 ) | 0x01 )
enum
{
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/use_pack.h b/src/external/bsd/meinberg/dist/mbglib/common/use_pack.h
index aaacd42..5edcdfe 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/use_pack.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/use_pack.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: use_pack.h 1.3 2011/01/26 10:01:41 martin REL_M $
+ * $Id: use_pack.h 1.5 2012/10/12 12:40:01 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,6 +11,10 @@
*
* -----------------------------------------------------------------------
* $Log: use_pack.h $
+ * Revision 1.5 2012/10/12 12:40:01 martin
+ * Removed temporary changes.
+ * Revision 1.4 2012/10/02 18:06:25 martin
+ * Temporary changes to test alignment under Linux/Sparc.
* Revision 1.3 2011/01/26 10:01:41 martin
* Provided a way to suppress packing of structures on a project base.
* Revision 1.2 2002/02/25 08:50:33 Andre
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/words.h b/src/external/bsd/meinberg/dist/mbglib/common/words.h
index 7fff493..9cbc841 100755
--- a/src/external/bsd/meinberg/dist/mbglib/common/words.h
+++ b/src/external/bsd/meinberg/dist/mbglib/common/words.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: words.h 1.27 2011/07/18 10:21:38 martin TRASH $
+ * $Id: words.h 1.42 2017/07/26 14:28:50 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,7 +10,51 @@
*
* -----------------------------------------------------------------------
* $Log: words.h $
- * Revision 1.27 2011/07/18 10:21:38 martin
+ * Revision 1.42 2017/07/26 14:28:50 martin
+ * Fixed build for NetBSD.
+ * Revision 1.41 2017/07/05 12:06:35 martin
+ * Moved macro _int_from_size_t() here.
+ * Revision 1.40 2017/06/12 11:14:25 martin
+ * Empty _DEPRECATED_BY definition for firmware targets.
+ * Revision 1.39 2017/03/15 10:01:09 martin
+ * Added comments how to represent negative numbers in NANO_TIME
+ * and NANO_TIME_64 structures.
+ * Added macros _nano_time_zero() and _nano_time_64_zero().
+ * Revision 1.38 2017/02/22 11:56:33 martin
+ * Made MBG_CODE_NAME_TABLE_ENTRY::code signed to
+ * avoid signed/unsigned warnings with some code tables.
+ * Revision 1.37 2017/01/27 12:24:35Z martin
+ * Moved STRINGIFY() macro here.
+ * Revision 1.36 2017/01/27 08:59:43 martin
+ * Fixed macro syntax.
+ * Revision 1.35 2016/08/05 12:17:21 martin
+ * Moved definitions for NANO_TIME and NANO_TIME_64 here.
+ * New macro _nano_time_64_negative().
+ * Conditionally define _abs64() macro.
+ * Include <inttypes.h> for Keil ARMCC target.
+ * Added some conditional debugging code.
+ * Fixed some spelling.
+ * Revision 1.34 2014/10/20 12:31:20 martin
+ * Moved macro _isdigit() here.
+ * Revision 1.33 2014/05/27 10:18:35Z martin
+ * Finer control of which types are required for or already
+ * available on particular target systems.
+ * Added macros helpful to simplify declarations of code/name tables.
+ * Revision 1.32 2014/01/07 15:43:52 martin
+ * Define __mbg_inline for ARM firmware targets.
+ * Revision 1.31 2012/11/29 11:54:39Z martin
+ * Removed #if sizeof() definitions which may cause build errors
+ * with some older compilers.
+ * Include stdbool.h for __ARMCC_VERSION targets.
+ * Moved _nop_macro_fnc() definition here.
+ * Revision 1.30 2012/11/02 09:12:29Z martin
+ * Moved most feature detection code to mbg_tgt.h.
+ * Tried to define missing features most flexibly and portably.
+ * Revision 1.29 2012/07/11 16:45:45Z martin
+ * New macros to access individual bytes of long constants.
+ * Revision 1.28 2012/04/05 14:36:18Z martin
+ * Support CVI 2010 compiler which provides C99 types.
+ * Revision 1.27 2011/07/18 10:21:38Z martin
* Added definition for MBG_CODE_NAME_TABLE_ENTRY which can
* be used to define tables assigning strings to numeric codes.
* Revision 1.26 2011/04/06 10:23:03 martin
@@ -85,23 +129,38 @@
#if !defined( _IS_MBG_FIRMWARE )
-#if defined( _C166 ) || \
- defined( _CC51 ) || \
- defined( __ARM ) || \
- defined( __ARMCC_VERSION )
- #define _IS_MBG_FIRMWARE 1
-#else
- #define _IS_MBG_FIRMWARE 0
-#endif
-
+ #if defined( _C166 ) || \
+ defined( _CC51 ) || \
+ defined( __ARM ) || \
+ defined( __ARMCC_VERSION )
+ #define _IS_MBG_FIRMWARE 1
+ #else
+ #define _IS_MBG_FIRMWARE 0
+ #endif
#endif
+
#if !_IS_MBG_FIRMWARE
#include <mbg_tgt.h>
+#else
+ #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
+ #define __mbg_inline __inline
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
+ #else
+ #define MBG_TGT_MISSING_64_BIT_TYPES 1
+ #endif
+
+ #if !defined( _DEPRECATED_BY )
+ #define _DEPRECATED_BY( _s ) // empty definition
+ #endif
#endif
+
#ifdef _WORDS
#define _ext
#else
@@ -111,175 +170,261 @@
/* Start of header body */
-
-// The compilers below support native bit types.
-
-#if defined( _C166 ) || defined( _CC51 )
- #define _BIT_DEFINED 1
+#if defined( _C166 ) \
+ || defined( _CC51 )
+ #define _BIT_DEFINED 1 // these compilers natively support the "bit" type
+ #define USE_LONG_FOR_INT32 1
#endif
-// Check whether the target system supports C99 fixed-size types.
+#if !defined( MBG_TGT_HAS_EXACT_SIZE_TYPES )
-#if defined( MBG_TGT_LINUX ) // any Linux target
+ #if defined( MBG_TGT_HAS_INT_8_16_32 )
- #if defined( __KERNEL__ )
- #include <linux/types.h>
- #else
- #include <stdint.h>
- #include <sys/types.h>
- #endif
+ // Define C99 exact size types using non-standard exact-size types
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
- #define _C99_BIT_TYPES_DEFINED 1
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
-#elif defined( MBG_TGT_BSD )
+ typedef __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
- #include <sys/types.h>
-
- #define _C99_BIT_TYPES_DEFINED 1
-
- // avoid inclusion of stdbool.h later
- #define bit int
- #define _BIT_DEFINED 1
-
-#elif defined( MBG_TGT_QNX ) // QNX 4.x or QNX 6.x
-
- #if defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino) with gcc
- #include <stdint.h>
- #else // QNX 4.x with Watcom C 10.6
- #include <sys/types.h> // 64 bit types not supported
- #endif
+ #else
- #define _C99_BIT_TYPES_DEFINED 1
+ // Assume a 16 or 32 bit compiler which doesn't
+ // support exact-size types.
-#endif
+ typedef char int8_t;
+ typedef unsigned char uint8_t;
+ typedef short int16_t;
+ typedef unsigned short uint16_t;
+ // Using #if sizeof() to determine the size of a type may not
+ // be supported by all preprocessors, and may even result in
+ // build errors if used in a conditional preprocessor section,
+ // so we can't use this here without compatibility problems.
-// If it's not yet clear whether fixed-size types are supported,
-// check the build environment which may be multi-platform.
+ #if defined( USE_LONG_FOR_INT32 )
+ typedef long int32_t;
+ typedef unsigned long uint32_t;
+ #elif defined( USE_INT_FOR_INT32 )
+ typedef int int32_t;
+ typedef unsigned int uint32_t;
+ #else
+ #error Need to define int32_t and uint32_t
+ #endif
-#if !defined( _C99_BIT_TYPES_DEFINED )
+ #endif
- #if defined( __WATCOMC__ )
- #if __WATCOMC__ > 1230 // Open Watcom C 1.3 and above
- #include <stdint.h>
- #define _C99_BIT_TYPES_DEFINED 1
- #elif defined( __WATCOM_INT64__ ) // Watcom C 11, non-QNX
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
+ #if defined( MBG_TGT_MISSING_64_BIT_TYPES )
- #define _C99_BIT_TYPES_DEFINED 1
- #endif
- #endif
+ // The build environment does not support 64 bit types. However,
+ // 64 bit types need to be defined to avoid build errors
+ // if these types are formally used in function prototypes.
+ // We explicitly use abnormal data types to hopefully
+ // cause compiler errors in case these types are
+ // unexpectedly used to generate real code for a target
+ // platform which does not support 64 bit types.
+ typedef void *int64_t;
+ typedef void *uint64_t;
- #if defined( __BORLANDC__ )
- #if ( __BORLANDC__ >= 0x570 ) // at least Borland Developer Studio 2006
- #define _C99_BIT_TYPES_DEFINED 1
- #endif
- #endif
+ #else
- #if defined( __GNUC__ )
- #include <stdint.h>
- #define _C99_BIT_TYPES_DEFINED 1
- #endif
+ // Define C99 types using non-standard exact-size types
+ // which are usually supported by build envonronments
+ // supporting 64 bit types but no C99 types.
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
- #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
- #include <stdint.h>
- #define _C99_BIT_TYPES_DEFINED 1
#endif
#endif
-// If neither the target system nor the build environment define C99 fixed-size
-// types define those types based on standard types with the proper sizes
-// commonly used in 16/32 bit environments.
-#if defined( _C99_BIT_TYPES_DEFINED )
+#if defined( MBG_TGT_MISSING_64_BIT_TYPES )
- #define MBG_TGT_HAS_64BIT_TYPES 1
+ #define MBG_TGT_HAS_64BIT_TYPES 0
#else
- typedef char int8_t;
- typedef unsigned char uint8_t;
-
- typedef short int16_t;
- typedef unsigned short uint16_t;
+ #define MBG_TGT_HAS_64BIT_TYPES 1
- typedef long int32_t;
- typedef unsigned long uint32_t;
+ #if !defined( MBG_TGT_HAS_ABS64 )
+ #define _abs64( _i ) ( (int64_t) ( ( (_i) < 0 ) ? -(_i) : (_i) ) )
+ #endif
+#endif
- #if defined( MBG_TGT_WIN32 )
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- #define MBG_TGT_HAS_64BIT_TYPES 1
+// Some commonly used types
- #else
- // The types below are required to avoid build errors
- // if these types are formally used in function prototypes.
- // We explicitely use abnormal data types to hopefully
- // cause compiler errors in case these types are
- // unexpectedly used to generate real code for a target
- // platform which does not support 64 bit types.
- typedef void *int64_t;
- typedef void *uint64_t;
- #endif
+#if !defined( _UCHAR_DEFINED )
+ typedef unsigned char uchar;
+ #define uchar uchar
+#endif
+#if !defined( _USHORT_DEFINED )
+ typedef unsigned short ushort;
+ #define ushort ushort
#endif
+#if !defined( _UINT_DEFINED )
+ typedef unsigned int uint;
+ #define uint uint
+#endif
+#if !defined( _ULONG_DEFINED )
+ typedef unsigned long ulong;
+ #define ulong ulong
+#endif
-#if !defined( MBG_TGT_HAS_64BIT_TYPES )
+#if !defined( _UDOUBLE_DEFINED )
+ typedef double udouble;
+ #define udouble udouble
+#endif
- #define MBG_TGT_HAS_64BIT_TYPES 0
+#if !defined( _BYTE_DEFINED )
+ typedef unsigned char byte;
+ #define byte byte
+#endif
+#if !defined( _WORD_DEFINED )
+ typedef unsigned short word;
+ #define word word
#endif
+#if !defined( _LONGWORD_DEFINED )
+ typedef unsigned long longword;
+ #define longword longword
+#endif
+#if !defined( _DWORD_DEFINED )
+// typedef unsigned long dword;
+// #define dword dword
+#endif
-// Some commonly used types
-typedef unsigned char uchar;
+#if defined( MBG_TGT_MISSING_BOOL_TYPE )
+ //#error MBG_TGT_MISSING_BOOL_TYPE is defined
+ // BDS/Borland C++ Builder 2006 (non-C++ mode)
+ // Borland C++ Builder 5 (non-C++ mode)
+ // BC 3.1
+ // VC6
+ // DDKbuild
+ // VS2008
+#endif
-#if !defined( MBG_TGT_LINUX ) && !( defined ( MBG_TGT_NETBSD ) && defined ( MBG_TGT_KERNEL ) )
- typedef unsigned short ushort;
- typedef unsigned int uint;
- typedef unsigned long ulong;
+#if defined( __cplusplus )
+ //#error __cplusplus is defined
#endif
-typedef double udouble;
+#if defined( __bool_true_false_are_defined )
+ //#error __bool_true_false_are_defined is defined
+ // Keil armcc
+ // gcc / Linux user space
+ // clang / FreeBSD user space and kernel
+#endif
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long longword;
-typedef unsigned long dword;
-#if !defined( _BIT_DEFINED )
+#if defined( MBG_TGT_MISSING_BOOL_TYPE ) /* from mbg_tgt.h */ \
+ || ( !defined( __cplusplus ) /* C++ */ \
+ && !defined( __bool_true_false_are_defined ) /* C99 */ \
+ && !defined( _LINUX_TYPES_H ) ) /* Linux kernel */ \
+ && !( defined( MBG_TGT_NETBSD ) && defined( _SYS_TYPES_H_ ) ) /* NetBSD kernel */
- #if _C99_BIT_TYPES_DEFINED
- #include <stdbool.h>
+ // There's no native support for a "bool" type, so we
+ // need a substitute.
- typedef bool bit;
+ #if defined( _BIT_DEFINED )
+ // A native "bit" type is supported, so we use it for bool.
+ //#error substituting bit for bool
+ // C166
+ typedef bit bool;
#else
- typedef int bit;
+ // Fall back to "int". This is just a hack which
+ // may yield unexpected results with code like:
+ // return (bool) ( val & 0x10 );
+ // A safe way of coding would be:
+ // return (bool) ( ( val & 0x10 ) != 0 );
+ //#error substituting int for bool
+ // Borland C++ Builder 5
+ // BC 3.1
+ // VC6
+ // DDKbuild
+ // VS2008
+ typedef int bool;
#endif
+ // Eventually provoke a build error if the build
+ // environment unexpectedly supports "bool" natively.
+ #define bool bool
+ #define true 1
+ #define false 0
+#else
+ //#error native bool type supported
+ // Borland C++ Builder 5 and newer (C++ mode only)
+ // Keil armcc
+ // gcc / Linux user space
+ // gcc / Linux kernel
+ // clang / FreeBSD user space and kernel
+#endif
+
+
+#if !defined( _BIT_DEFINED )
+
+ // There's no native support for a "bit" type, so we
+ // need a substitute. The "bool" type would fit best
+ // and should be fine if it's supported natively.
+ //
+ // However, if "bool" has been substituted above
+ // by "int"then this is just a hack which may yield
+ // unexpected results with code like:
+ // return (bit) ( val & 0x10 );
+ // A safe way of coding would be:
+ // return (bit) ( ( val & 0x10 ) != 0 );
+
+ //#error substituting bool for bit
+ // Keil armcc
+ // Borland C++ Builder 5
+ // BC 3.1
+ // VC6
+ // DDKbuild
+ // VS2008
+ // gcc / Linux user space
+ // gcc / Linux kernel
+ // clang / FreeBSD user space and kernel
+ typedef bool bit;
+
+ // Eventually provoke a build error if the build
+ // environment unexpectedly supports "bit" natively.
+ #define bit bit
+
#define _BIT_REDEFINED 1
+#else
+ //#error native bit type supported
+ // C166
#endif
-#define HI_BYTE( _x ) ( (_x) >> 8 )
-#define LO_BYTE( _x ) ( (_x) & 0xFF )
-#define HI_WORD( _x ) ( (_x) >> 16 )
-#define LO_WORD( _x ) ( (_x) & 0xFFFF )
+#define BYTE_0( _x ) ( (uint8_t ) ( (_x) & 0xFF ) )
+#define BYTE_1( _x ) ( (uint8_t ) ( ( ( (uint16_t) (_x) ) >> 8 ) & 0xFF ) )
+#define BYTE_2( _x ) ( (uint8_t ) ( ( ( (uint32_t) (_x) ) >> 16 ) & 0xFF ) )
+#define BYTE_3( _x ) ( (uint8_t ) ( ( ( (uint32_t) (_x) ) >> 24 ) & 0xFF ) )
+
+
+#define HI_BYTE( _x ) ( (uint8_t ) ( (_x) >> 8 ) )
+#define LO_BYTE( _x ) ( (uint8_t ) ( (_x) & 0xFF ) )
+
+#define HI_WORD( _x ) ( (uint16_t ) ( (_x) >> 16 ) )
+#define LO_WORD( _x ) ( (uint16_t ) ( (_x) & 0xFFFF ) )
// the macros below assume little endianess
// these macros expect the name of a variable
@@ -336,15 +481,202 @@ typedef unsigned long dword;
#endif
+
+#define _set_array_bit( _n, _byte_array, _max_bytes ) \
+do \
+{ \
+ int byte_idx = (_n) >> 3; \
+ \
+ if ( byte_idx < _max_bytes ) \
+ _byte_array[byte_idx] |= ( 1 << ( (_n) & 0x07 ) ); \
+ \
+} while ( 0 )
+
+
+#define _clear_array_bit( _n, _byte_array, _max_bytes ) \
+do \
+{ \
+ int byte_idx = (_n) >> 3; \
+ \
+ if ( byte_idx < _max_bytes ) \
+ _byte_array[byte_idx] &= ~( 1 << ( (_n) & 0x07 ) ); \
+ \
+} while ( 0 )
+
+
+
+#define _isdigit( _c ) ( (_c) >= '0' && (_c) <= '9' )
+
+
+// A macro function which can safely be used without
+// side effects as a macro doing nothing.
+// This is useful to define debug macros away in
+// release builds, etc.
+#if !defined( _nop_macro_fnc )
+ #define _nop_macro_fnc() do {} while (0)
+#endif
+
+
/**
* @brief A table entry which can be used to map codes to names.
*/
typedef struct
{
- ulong code;
+ long code;
const char *name;
+
} MBG_CODE_NAME_TABLE_ENTRY;
+/**
+ * @brief A macro defining a ::MBG_CODE_NAME_TABLE_ENTRY
+ *
+ * The stringified parameter is used for the name.
+ *
+ * @param _n The symbolic name of the numeric code
+ */
+#define _mbg_cn_table_entry( _n ) { _n, #_n }
+
+/**
+ * @brief A macro defining an empty ::MBG_CODE_NAME_TABLE_ENTRY
+ *
+ * This is used to terminate a table.
+ */
+#define _mbg_cn_table_end() { 0, NULL }
+
+
+
+/**
+ * @brief A timestamp with nanosecond resolution
+ *
+ * @note If the structure is to represent a negative value then both the
+ * fields nano_secs and secs have to be set to the negative values.
+ * Otherwise the sign of the represented number was ambiguous if either
+ * of the fields was accidentally 0, and only the other field was not 0.
+ * The macro ::_nano_time_negative should always be used to determine
+ * if the sign of the represented value is negative, or not.
+ *
+ * @note The secs field will roll over on 2038-01-19 03:14:07
+ * if used for the number of seconds since 1970-01-01, just like
+ * 32 bit POSIX time_t.
+ *
+ * @see ::_nano_time_negative
+ * @see ::_nano_time_zero
+ * @see ::NANO_TIME_64
+ */
+typedef struct
+{
+ // ATTENTION:
+ // This structure is and has has been used in public API calls for a long time,
+ // so even though the order of member fields is different than in NANO_TIME_64
+ // this must *NOT* be changed, or API compatibility will get lost!
+ int32_t nano_secs; ///< [nanoseconds]
+ int32_t secs; ///< [seconds], usually since 1970-01-01 00:00:00
+
+} NANO_TIME;
+
+#define _mbg_swab_nano_time( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->nano_secs ); \
+ _mbg_swab32( &(_p)->secs ); \
+} while ( 0 )
+
+/**
+ * Check if the value of the ::NANO_TIME structure _nt is negative
+ */
+#define _nano_time_negative( _nt ) \
+ ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) )
+
+/**
+ * Check if the value of the ::NANO_TIME structure _nt is 0
+ */
+#define _nano_time_zero( _nt ) \
+ ( ( (_nt)->secs == 0 ) && ( (_nt)->nano_secs == 0 ) )
+
+
+
+/**
+ * @brief A timestamp with nanosecond resolution, but 64 bit size
+ *
+ * @note If the structure is to represent a negative value then both the
+ * fields nano_secs and secs have to be set to the negative values.
+ * Otherwise the sign of the represented number was ambiguous if either
+ * of the fields was accidentally 0, and only the other field was not 0.
+ * The macro ::_nano_time_64_negative should always be used to determine
+ * if the sign of the represented value is negative, or not.
+ *
+ * @see ::_nano_time_64_negative
+ * @see ::_nano_time_64_zero
+ * @see ::NANO_TIME
+ */
+typedef struct
+{
+ // ATTENTION:
+ // This structure is and has been used in public API calls for a long time,
+ // so even though the order of member fields is different than in NANO_TIME
+ // this must *NOT* be changed, or API compatibility will get lost!
+ int64_t secs; ///< [seconds], usually since 1970-01-01 00:00:00
+ int64_t nano_secs; ///< [nanoseconds]
+
+} NANO_TIME_64;
+
+#define _mbg_swab_nano_time_64( _p ) \
+do \
+{ \
+ _mbg_swab64( &(_p)->secs ); \
+ _mbg_swab64( &(_p)->nano_secs ); \
+} while ( 0 )
+
+/**
+ * Check if the value of the ::NANO_TIME_64 structure _nt is negative
+ */
+#define _nano_time_64_negative( _nt ) \
+ ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) )
+
+/**
+ * Check if the value of the ::NANO_TIME_64 structure _nt is 0
+ */
+#define _nano_time_64_zero( _nt ) \
+ ( ( (_nt)->secs == 0 ) && ( (_nt)->nano_secs == 0 ) )
+
+
+
+// The size_t type can eventually be larger than an int type.
+// However, some snprintf-like functions expect a size_t value
+// to specify the buffer size, but just return an int value.
+// So we take care that at least the return value is limited
+// to MAXINT.
+#if defined( MBG_TGT_WIN32 )
+ #define _int_from_size_t( _n ) \
+ ( ( (_n) > INT_MAX ) ? INT_MAX : (int) (_n) )
+#else
+ #define _int_from_size_t( _n ) (_n)
+#endif
+
+
+
+/**
+ * @brief Make a string from a constant definition
+ *
+ * This macro can be used e.g. to define a constant string on the
+ * compiler's command line, e.g. like -DVERSION_STRING="v1.0 BETA".
+ * Source code like
+ * @code{.c}
+ const char version_string[] = VERSION_STRING;
+ * @endcode
+ *
+ * may not work for every compiler since the double quotes
+ * in VERSION_STRING may be removed when the definition is evaluated.
+ * A proper solution is to use the STRINGIFY() macro defined here:
+ * @code{.c}
+ const char version_string[] = STRINGIFY( VERSION_STRING );
+ * @endcode
+ */
+#define STRINGIFY(x) XSTRINGIFY(x)
+
+// The XSTRINGIFY() macro is just a helper macro to implement STRINGIFY()
+// and should not be used alone.
+#define XSTRINGIFY(x) #x
/* End of header body */
diff --git a/src/external/bsd/meinberg/dist/mbglib/common/xdevfeat.h b/src/external/bsd/meinberg/dist/mbglib/common/xdevfeat.h
new file mode 100755
index 0000000..19cc633
--- /dev/null
+++ b/src/external/bsd/meinberg/dist/mbglib/common/xdevfeat.h
@@ -0,0 +1,893 @@
+
+/**************************************************************************
+ *
+ * $Id: xdevfeat.h 1.2 2017/07/06 07:49:25 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes for xdevfeat.c.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: xdevfeat.h $
+ * Revision 1.2 2017/07/06 07:49:25 martin
+ * Added some macros and inline function simplifying
+ * implementation of the individual check functions.
+ * Updated function prototypes.
+ * Revision 1.1 2016/03/16 14:32:52 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _XDEVFEAT_H
+#define _XDEVFEAT_H
+
+
+/* Other headers to be included */
+
+#include <gpsdefs.h>
+#include <mbgerror.h>
+
+#ifdef _XDEVFEAT
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup chk_supp_fncs Groups of functions used to check if a particular feature is supported
+ *
+ * Each of these functions can be used to check if a device supports a particular
+ * feature. ::MBG_SUCCESS is returned if the requested feature is supported,
+ * otherwise one of the @ref MBG_ERROR_CODES is returned, as appropriate.
+ *
+ * Some features are supported by a device if an associated bit is set in the
+ * ::RECEIVER_INFO::features field, but since the number of bits in this field
+ * is limited, newer feature bits are defined in a ::MBG_XFEATURE_BUFFER.
+ * Finally there are some builtin features which may be implicitly supported
+ * by a particular device model, or not.
+ *
+ * These functions provide a unified API for all feature types to make
+ * application code more straightforward.
+ *
+ * If the mbgextio API is used then a ::MBG_XDEV_FEATURES structure embedded in
+ * the ::MBG_MSG_CTL structure is set up automatically when the device is opened,
+ * and there are mbgextio_... wrapper functions available which just expect the
+ * MBG_MSG_CTL * associated with the device to check if a feature is supported.
+ * See @ref mbgextio_chk_supp_fncs.
+ *
+ * Other implementations which retrieve the ::MBG_XDEV_FEATURES structure of
+ * a device in a different way can use some lower level functions.
+ * See @ref xdevfeat_chk_supp_fncs.
+ */
+
+
+/**
+ * @defgroup xdevfeat_chk_supp_fncs Low level functions used to check if a particular feature is supported
+ * @ingroup chk_supp_fncs
+ *
+ * @note Applications using the mbgextio API should use the mbgextio_ wrapper
+ * functions preferably. See @ref mbgextio_chk_supp_fncs.
+ */
+
+
+/**
+ * @brief A structure combining all device feature information
+ */
+typedef struct
+{
+ uint32_t reserved; ///< Currently reserved, unused, always 0
+ RECEIVER_INFO receiver_info; ///< Receiver info provided by the device
+ MBG_XFEATURE_BUFFER xfeature_buffer; ///< Extended features provided by the device
+ MBG_TLV_INFO tlv_info; ///< TLV info provided by a device
+
+} MBG_XDEV_FEATURES;
+
+
+
+/**
+ * @brief Type of functions to check if a feature is supported
+ */
+typedef int _NO_MBG_API XDEVFEAT_CHK_SUPP_FNC( const MBG_XDEV_FEATURES *p_xdf );
+
+
+
+/**
+ * @brief Check if all bits of a specific mask are set in an integer bit mask
+ *
+ * This macros checks if specific bits are set in an integer bit mask.
+ * This is implemented as macro since the macro works properly with
+ * all integer sizes.
+ *
+ * @param[in] _supp_msk An integer bit mask
+ * @param[in] _chk_msk The bit mask to be tested
+ *
+ * @return ::MBG_SUCCESS if all bits of the test mask are set, or
+ * ::MBG_ERR_NOT_SUPP_BY_DEV if not.
+ */
+#define _check_feat_supp_mask( _supp_msk, _chk_msk ) \
+ ( ( ( (_supp_msk) & (_chk_msk) ) == (_chk_msk) ) ? \
+ MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV )
+
+
+
+/**
+ * @brief Check if a bits with a specific number is set in an integer bit mask
+ *
+ * This macros checks if a bits with specific number is set in an integer bit mask.
+ * This is implemented as macro since the macro works properly with
+ * all integer sizes.
+ *
+ * @param[in] _supp_msk An integer bit mask
+ * @param[in] _bit_num The bit mask to be tested
+ *
+ * @return ::MBG_SUCCESS if all bits of the test mask are set, or
+ * ::MBG_ERR_NOT_SUPP_BY_DEV if not.
+ */
+#define _check_feat_supp_bit( _supp_msk, _bit_num ) \
+ ( ( (_supp_msk) & ( 1UL << (_bit_num) ) ) ? \
+ MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV )
+
+
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Check if a specific bit is set in a byte array
+ *
+ * This function checks if a specific bit is set in an array of bytes.
+ * Bits are counted starting from the least significant bit of the least
+ * significant byte.
+ *
+ * @param[in] bit_num Number of the bit to be tested, 0..(8*(max_bytes-1))
+ * @param[in] p Pointer to a buffer with an array of bytes
+ * @param[in] max_bytes The number of bytes in the buffer p
+ *
+ * @return ::MBG_SUCCESS if the bit is set, ::MBG_ERR_NOT_SUPP_BY_DEV if not,
+ * or ::MBG_ERR_RANGE if the bit number is out of the range of the array
+ */
+int check_feat_supp_byte_array( int bit_num, const uint8_t *p, int max_bytes )
+{
+ int byte_num = bit_num >> 3;
+
+ if ( byte_num < max_bytes ) // the normal case
+ {
+ ulong bit_mask = 1UL << ( bit_num & 0x07 );
+
+ return ( p[byte_num] & bit_mask ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV;
+ }
+
+ return MBG_ERR_RANGE;
+
+} // check_feat_supp_byte_array
+
+
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Check if a device can receive the GPS satellite system
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_dev_is_gps
+ * @see ::mbg_chk_dev_is_gps
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gps( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the GNSS API
+ *
+ * This is usually supported by devices which can receive signals
+ * from different satellite systems, e.g. GPS, GLONASS, ...
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_dev_is_gnss
+ * @see ::mbg_chk_dev_is_gnss
+ * @see ::MBG_GNSS_TYPES
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gnss( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is a time code receiver (IRIG or similar)
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_dev_is_tcr
+ * @see ::mbg_chk_dev_is_tcr
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_tcr( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is a DCF77 AM receiver
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_dev_is_dcf
+ * @see ::mbg_chk_dev_is_dcf
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_dcf( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device can receive DCF77 PZF
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_dev_has_pzf
+ * @see ::mbg_chk_dev_has_pzf
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pzf( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is an MSF receiver
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_msf( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is a JJY receiver
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_jjy( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is a WWVB receiver
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_wwvb( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device is a bus level device
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_bus_lvl_dev( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ims( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gpio( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_synth( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_prog_pulses( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_tx( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_rx( const MBG_XDEV_FEATURES *p_xdf ) ;
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_serouts( const MBG_XDEV_FEATURES *p_xdf ) ;
+ /**
+ * @brief Check if a device supports the ::BVAR_STAT structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_bvar_stat( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports reading the position as ::XYZ array
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_xyz( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports reading the position as ::LLA array
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_lla( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if the device supports the builtin feature TIME
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_ttm( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::MBG_TIME_SCALE_INFO structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_time_scale_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_scale( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::TZDL structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzdl( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::TZCODE API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzcode( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::ANT_INFO structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_info( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::ENABLE_FLAGS structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_enable_flags( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::STAT_INFO structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_stat_info( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::ANT_CABLE_LEN structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_cable_length( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::IGNORE_LOCK structure and API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_ignore_lock( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if the device supports the SCU_STAT structures
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ * @see @ref group_scu
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_scu_stat( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if the device supports the SV_INFO structures
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV
+ * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs)
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_sv_info( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a timecode receiver provides ::MBG_RAW_IRIG_DATA
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_raw_irig_data
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_raw_irig_data( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the old LAN_IP4 API
+ *
+ * The LAN_IP4 API provides structures and functions to configure
+ * parts of the networking of a device and is superseded by the
+ * NET_CFG API. Some devices combine NET_CFG and LAN_IP4.
+ * Therefore, ::mbgextio_get_all_net_cfg_info should be used
+ * preferably to read the network configuration.
+ * It will translate the old structures into the new ones.
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_all_net_cfg_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lan_ip4( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the new NET_CFG API
+ *
+ * The NET_CFG API provides structures and functions to configure
+ * the complete networking part of a device and supersedes the
+ * LAN_IP4 API. Not all devices support the whole feature set
+ * of the NET_CFG API or combine NET_CFG and LAN_IP4.
+ * Therefore, ::mbgextio_get_all_net_cfg_info should be used
+ * preferably to read the network configuration.
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_all_net_cfg_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_net_cfg( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the PTP API
+ *
+ * The PTP API consists of different calls and associated structures
+ * which * have evolved over time. Not all devices support every call,
+ * so ::mbgextio_get_all_ptp_cfg_info takes care to check which parts are
+ * supported and thus should be used preferably to read PTP information.
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_all_ptp_cfg_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ptp( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the NTP API
+ *
+ * The NTP API consists of different calls and associated structures
+ * which have evolved over time. Not all devices support every call,
+ * so ::mbgextio_get_all_ntp_cfg_info takes care to check which parts are
+ * supported and thus should be used preferably to read NTP information.
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_all_ntp_cfg_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ntp( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the event log API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_evt_log( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the USB lock feature, see ::MBG_XFEATURE_USB_LOCK
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref group_usb_lock
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_usb_lock( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the user capture API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the user capture via network feature
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref group_ucap_net
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap_net( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the TLV API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref group_tlv_api
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tlv_api( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports a firmware update via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_xmt_fw_update
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_fw_update( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports creating / sending a diagnostics file via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO //refer to get diag function
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_diag_file( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports PTPv2 license infos
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv2_license( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports NTP license infos via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ntp_license( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports PTPv1 License Infos via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv1_license( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports Time Monitor License infos via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_time_monitor_license( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports UFU (Unified Firmware Update) via TLV
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ufu( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::GPS_SAVE_CFG command
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_cmd_save_cfg
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_cmd_save_cfg( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the extended feature monitoring
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_monitoring( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the LED API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO ###
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_led_api( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the LNE API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO ###
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lne_api( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the power control API
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO ###
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pwr_ctl_api( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the ::MBG_EXT_SYS_INFO command
+ *
+ * @param[in,out] p_xdf Pointer to a valid message control structure
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO ###
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ext_sys_info( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_io_ports( const MBG_XDEV_FEATURES *p_xdf ) ;
+ /**
+ * @brief Check if a device has ::MBG_XFEATURE_TRANSACTIONS
+ *
+ * @param[in,out] p_xdf Pointer to a valid message control structure
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::TODO ###
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_transactions( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device has ::MBG_XFEATURE_REBOOT
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_reboot( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device has ::MBG_XFEATURE_REQ_TTM
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ * @see mbgextio_get_time
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_req_ttm( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the extended multi ref features including multi instances
+ *
+ * The different multi ref feature and its appropriate flags have evolved over time.
+ * This function only checks the currently up-to-date GPS_HAS_XMRS_MULT_INSTC flag.
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see ::mbgextio_get_all_xmulti_ref_info
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xmulti_ref( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+ /**
+ * @brief Check if a device supports the extended binary protocol (XBP) feature
+ *
+ * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device
+ *
+ * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature
+ *
+ * @ingroup xdevfeat_chk_supp_fncs
+ * @see @ref xdevfeat_chk_supp_fncs
+ */
+ _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xbp( const MBG_XDEV_FEATURES *p_xdf ) ;
+
+
+/* ----- function prototypes end ----- */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* End of header body */
+
+#undef _ext
+#undef _DO_INIT
+
+#endif /* _XDEVFEAT_H */
diff --git a/src/external/bsd/meinberg/dist/mbgsetsystime/Makefile b/src/external/bsd/meinberg/dist/mbgsetsystime/Makefile
index 07ec4e4..b0e6c89 100755
--- a/src/external/bsd/meinberg/dist/mbgsetsystime/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgsetsystime/Makefile
@@ -1,15 +1,18 @@
#########################################################################
#
-# $Id: Makefile 1.8.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.9.1.1 2017/07/26 14:30:28 martin TEST $
#
# Description:
# Makefile for mbgsetsystime.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.8.1.2 2010/08/30 09:05:23 martin
-# Revision 1.8.1.1 2010/08/30 08:21:54 martin
+# Revision 1.9.1.1 2017/07/26 14:30:28 martin
+# Removed lines that are not required / supported with *BSD.
+# Revision 1.9 2017/07/05 18:26:10 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.8 2009/07/24 10:31:17 martin
# Moved declarations to a common file which is now included.
# Revision 1.7 2008/12/22 11:56:59 martin
@@ -30,11 +33,15 @@
#########################################################################
TARGET = mbgsetsystime
-INST_DIR = /usr/local/sbin
+INST_TO_SBIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
OBJS += mbgmktm.o
OBJS += pcpsmktm.o
diff --git a/src/external/bsd/meinberg/dist/mbgsetsystime/mbgsetsystime.c b/src/external/bsd/meinberg/dist/mbgsetsystime/mbgsetsystime.c
index 62b57ac..62068be 100755
--- a/src/external/bsd/meinberg/dist/mbgsetsystime/mbgsetsystime.c
+++ b/src/external/bsd/meinberg/dist/mbgsetsystime/mbgsetsystime.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgsetsystime.c 1.8.1.2 2011/07/05 15:35:55 martin TRASH martin $
+ * $Id: mbgsetsystime.c 1.9 2017/07/05 18:24:44 martin REL_M $
*
* Description:
* Main file for mbgsetsystime program which reads the current date
@@ -14,10 +14,14 @@
*
* -----------------------------------------------------------------------
* $Log: mbgsetsystime.c $
- * Revision 1.8.1.2 2011/07/05 15:35:55 martin
- * Modified version handling.
- * Revision 1.8.1.1 2011/07/05 14:36:01 martin
+ * Revision 1.9 2017/07/05 18:24:44 martin
* New way to maintain version information.
+ * Support build under Windows.
+ * Use high resolution time if the device supports it.
+ * Use codes and inline functions from mbgerror.h.
+ * Use functions from new module timeutil.
+ * Account for frac_sec_from_bin() obsoleted by bin_frac_32_to_dec_frac().
+ * Proper return codes and exit codes.
* Revision 1.8 2009/09/29 15:02:15 martin
* Updated version number to 3.4.0.
* Revision 1.7 2009/07/24 09:50:09 martin
@@ -45,14 +49,16 @@
// include Meinberg headers
#include <mbgdevio.h>
#include <pcpsmktm.h>
+#include <pcpsutil.h>
#include <toolutil.h>
+#include <timeutil.h>
+#include <str_util.h>
+#include <mbgerror.h>
// include system headers
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
#include <sys/types.h>
@@ -65,66 +71,244 @@ static const char *pname = "mbgsetsystime";
static /*HDR*/
-void set_system_time( PCPS_TIME *tp )
+size_t sn_printf_timespec( char *s, size_t max_len, const struct timespec *p_ts )
{
- struct timeval tv_set;
+ struct tm tm = { 0 };
+ int rc = mbg_gmtime( &tm, &p_ts->tv_sec );
+ if ( mbg_rc_is_error( rc ) ) // conversion failed
+ return sn_cpy_str_safe( s, max_len, "(invalid time)" );
- tv_set.tv_sec = pcps_mktime( tp );
- tv_set.tv_usec = (ulong) tp->sec100 * 10000;
- settimeofday( &tv_set, NULL );
+ return snprintf_safe( s, max_len, "%04i-%02i-%02i %02i:%02i:%02i.%09li UTC",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ (long) p_ts->tv_nsec );
- printf( "Date/time set to %02u.%02u.%02u %02u:%02u:%02u.%02u (UTC %+02ih)\n",
- tp->mday, tp->month, tp->year,
- tp->hour, tp->min, tp->sec, tp->sec100,
- tp->offs_utc
- );
+} // sn_printf_timespec
+
+
+
+static /*HDR*/
+int set_system_time( const struct timespec *p_ts )
+{
+ char ws[100];
+
+#if defined( MBG_TGT_WIN32 )
+ #define clock_settime mbg_clock_settime //### TODO cleanup
+#endif
+
+ int rc = clock_settime( CLOCK_REALTIME, p_ts );
+
+ sn_printf_timespec( ws, sizeof( ws ), p_ts );
+
+ if ( rc < 0 ) // usually 0 on success, -1 on error
+ {
+ rc = mbg_get_last_error( NULL );
+
+ fprintf( stderr, "Failed to set system time to %s: %s\n", ws, mbg_strerror( rc ) );
+ return rc;
+ }
+
+ printf( "Date/time set to %s\n", ws );
+
+ return MBG_SUCCESS;
} // set_system_time
static /*HDR*/
-int do_mbgsetsystime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
+int set_system_time_from_pcps_time( const PCPS_TIME *p_t )
{
- static int system_time_has_been_set;
-
- PCPS_TIME t;
- int ret_val = 0;
+ struct tm tm = { 0 };
+ time_t t_rev;
+ time_t t;
int rc;
- if ( system_time_has_been_set )
- goto done;
+ t = pcps_mktime( p_t );
+
+ if ( t == (time_t) -1 ) // error
+ {
+ fprintf( stderr, "Failed to convert %02u.%02u.%02u %02u:%02u:%02u.%02u (UTC%+02ih) to system time\n",
+ p_t->mday, p_t->month, p_t->year,
+ p_t->hour, p_t->min, p_t->sec, p_t->sec100,
+ p_t->offs_utc
+ );
+ return MBG_ERR_OVERFLOW;
+ }
- rc = mbg_get_time( dh, &t );
+ t_rev = t + p_t->offs_utc * SECS_PER_HOUR;
- if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
+ rc = mbg_gmtime( &tm, &t_rev );
+
+ if ( mbg_rc_is_error( rc ) )
+ return rc;
+
+ if ( ( tm.tm_year % 100 != p_t->year ) ||
+ ( tm.tm_mon + 1 != p_t->month ) ||
+ ( tm.tm_mday != p_t->mday ) ||
+ ( tm.tm_hour != p_t->hour ) ||
+ ( tm.tm_min != p_t->min ) ||
+ ( tm.tm_sec != p_t->sec ) )
{
- ret_val = -2;
- goto done;
+ fprintf( stderr, "reversely computed date/time differs from original\n" );
+ return MBG_ERR_RANGE;
+ }
+
+ #if defined( MBG_TGT_WIN32 )
+ {
+ SYSTEMTIME st;
+
+ union
+ {
+ FILETIME ft;
+ ULONGLONG ull;
+ } u;
+
+ // Convert seconds and fractions to 100 ns units.
+ u.ull = FILETIME_1970 +
+ (ULONGLONG) t * 10 * 1000 * 1000 +
+ (ULONGLONG) (ulong) p_t->sec100 * 100000;
+
+ if ( !FileTimeToSystemTime( &u.ft, &st ) )
+ {
+ int err = mbg_win32_last_err_to_mbg( GetLastError(), NULL );
+
+ fprintf( stderr, "Failed to convert FILETIME to system time: %s\n",
+ mbg_strerror( err ) );
+ return err;
+ }
+
+ if ( !SetSystemTime( &st ) )
+ {
+ #if 0
+ LPVOID lpMsgBuf;
+ DWORD last_error = GetLastError();
+
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ last_error,
+ MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ fprintf( stderr, "Failed to set system time: %s (code 0x%08lX)\n",
+ lpMsgBuf, (ulong) last_error );
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+ #else
+ int err = mbg_win32_last_err_to_mbg( GetLastError(), NULL );
+
+ fprintf( stderr, "Failed to set system time: err %i\n", err );
+ #endif
+ return err;
+ }
+
+ return MBG_SUCCESS;
}
+ #else // assuming POSIX
+ {
+ struct timespec ts;
+
+ ts.tv_sec = t;
+ ts.tv_nsec = (long) p_t->sec100 * ( NSECS_PER_SEC / 100 ); // convert to nanoseconds
+
+ return set_system_time( &ts );
+ }
+ #endif
+
+} // set_system_time_from_pcps_time
+
+
+
+static /*HDR*/
+int do_set_system_time_from_pcps_time( MBG_DEV_HANDLE dh )
+{
+ PCPS_TIME t;
+
+ int rc = mbg_get_time( dh, &t );
+
+ if ( mbg_cond_err_msg( rc, "mbg_get_time" ) )
+ return rc;
if ( t.status & PCPS_INVT )
{
// This may happen if the radio clock's battery
- // was low or disconnected.
+ // has been discharged or disconnected.
printf( "Radio clock has no valid date/time.\n" );
- ret_val = -1;
- goto done;
+ return MBG_ERR_INV_TIME;
}
- set_system_time( &t );
- system_time_has_been_set = 1;
+ rc = set_system_time_from_pcps_time( &t );
+
+ return rc;
+
+} // do_set_system_time_from_pcps_time
+
+
+
+static /*HDR*/
+int do_set_system_time_from_pcps_hr_time( MBG_DEV_HANDLE dh )
+{
+ PCPS_HR_TIME ht;
+ struct timespec ts = { 0 };
+
+ int rc = mbg_get_hr_time( dh, &ht );
+
+ if ( mbg_cond_err_msg( rc, "mbg_get_hr_time" ) )
+ return rc;
+
+ if ( ht.status & PCPS_INVT )
+ {
+ // This may happen if the radio clock's battery
+ // has been discharged or disconnected.
+ printf( "Radio clock has no valid date/time.\n" );
+ return MBG_ERR_INV_TIME;
+ }
+
+ ts.tv_sec = ht.tstamp.sec;
+ ts.tv_nsec = bin_frac_32_to_dec_frac( ht.tstamp.frac, NSECS_PER_SEC );
+
+ return set_system_time( &ts );
+
+} // do_set_system_time_from_pcps_hr_time
+
+
+
+static /*HDR*/
+int do_mbgsetsystime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
+{
+ static int system_time_has_been_set;
+
+ int rc = MBG_SUCCESS;
+
+ if ( system_time_has_been_set )
+ goto done;
+
+ rc = mbg_chk_dev_has_hr_time( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ rc = do_set_system_time_from_pcps_hr_time( dh );
+ else
+ rc = do_set_system_time_from_pcps_time( dh );
+
+ if ( mbg_rc_is_success( rc ) )
+ system_time_has_been_set = 1;
puts( "" );
done:
- mbg_close_device( &dh );
-
- return 0;
+ return rc;
} // do_mbgsetsystime
+static MBG_DEV_HANDLER_FNC do_mbgsetsystime;
+
static /*HDR*/
@@ -132,7 +316,8 @@ void usage( void )
{
mbg_print_usage_intro( pname,
"This program can be used to set the system time to the card's time.\n"
- "This should be done only at boot time, before the NTP daemon is started."
+ "This should be done only at boot time, before the NTP daemon is started.\n"
+ "Please *don't* run this program while ntpd is already active."
);
mbg_print_help_options();
mbg_print_device_options();
@@ -164,15 +349,19 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbgsetsystime );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbgsetsystime, 0 );
+
+ // determine the exit code based on the return code
+
+ if ( mbg_rc_is_success( rc ) )
+ return MBG_EXIT_CODE_SUCCESS; // success
+
+ if ( rc == MBG_ERR_INV_TIME )
+ return MBG_EXIT_CODE_INV_TIME; // device has no valid time to set the system time with
- return abs( rc );
+ return MBG_EXIT_CODE_FAIL; // any error occurred
}
diff --git a/src/external/bsd/meinberg/dist/mbgshowsignal/Makefile b/src/external/bsd/meinberg/dist/mbgshowsignal/Makefile
index c10b915..7bc355d 100755
--- a/src/external/bsd/meinberg/dist/mbgshowsignal/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgshowsignal/Makefile
@@ -1,15 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.7.1.2 2010/08/30 09:05:23 martin TEST $
+# $Id: Makefile 1.8 2017/07/05 18:26:51 martin REL_M $
#
# Description:
# Makefile for mbgshowsignal.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.7.1.2 2010/08/30 09:05:23 martin
-# Revision 1.7.1.1 2010/08/30 08:22:00 martin
+# Revision 1.8 2017/07/05 18:26:51 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.7 2009/07/24 10:31:17 martin
# Moved declarations to a common file which is now included.
# Revision 1.6 2008/12/22 11:56:59 martin
@@ -28,11 +29,15 @@
#########################################################################
TARGET = mbgshowsignal
-INST_DIR = /usr/local/bin
+INST_TO_BIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbgshowsignal/mbgshowsignal.c b/src/external/bsd/meinberg/dist/mbgshowsignal/mbgshowsignal.c
index d8f39c1..f08bd95 100755
--- a/src/external/bsd/meinberg/dist/mbgshowsignal/mbgshowsignal.c
+++ b/src/external/bsd/meinberg/dist/mbgshowsignal/mbgshowsignal.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgshowsignal.c 1.8.1.3 2011/07/05 15:35:55 martin TRASH martin $
+ * $Id: mbgshowsignal.c 1.9 2017/07/05 18:31:14 martin REL_M $
*
* Description:
* Main file for mbgshowsignal program which demonstrates how to
@@ -10,12 +10,13 @@
*
* -----------------------------------------------------------------------
* $Log: mbgshowsignal.c $
- * Revision 1.8.1.3 2011/07/05 15:35:55 martin
- * Modified version handling.
- * Revision 1.8.1.2 2011/07/05 14:35:19 martin
+ * Revision 1.9 2017/07/05 18:31:14 martin
* New way to maintain version information.
- * Revision 1.8.1.1 2011/07/04 13:19:04 martin
+ * Support build under Windows.
* Update modulation status continuously.
+ * Show PZF correlation state.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.8 2009/09/29 15:02:15 martin
* Updated version number to 3.4.0.
* Revision 1.7 2009/07/24 09:50:09 martin
@@ -43,11 +44,9 @@
// include Meinberg headers
#include <mbgdevio.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
// include system headers
-#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -69,10 +68,13 @@ int show_modulation( MBG_DEV_HANDLE dh )
PCPS_STATUS_PORT status_port; // current value of the clock's status port
PCPS_TIME t;
int signal;
+
+ bool dev_has_pzf = mbg_chk_dev_has_pzf( dh ) == MBG_SUCCESS;
+
int rc = mbg_get_status_port( dh, &status_port ); // read status port
- if ( mbg_ioctl_err( rc, "mbg_get_status_port" ) )
- return -1;
+ if ( mbg_cond_err_msg( rc, "mbg_get_status_port" ) )
+ return rc;
// show signal only once per second
sys_t = time( NULL );
@@ -81,8 +83,8 @@ int show_modulation( MBG_DEV_HANDLE dh )
{
rc = mbg_get_time( dh, &t );
- if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
- return -1;
+ if ( mbg_cond_err_msg( rc, "mbg_get_time" ) )
+ return rc;
prv_sys_t = sys_t;
}
@@ -99,9 +101,14 @@ int show_modulation( MBG_DEV_HANDLE dh )
if ( signal > PCPS_SIG_MAX )
signal = PCPS_SIG_MAX;
- printf( " Signal: %u%% ", signal * 100 / PCPS_SIG_MAX );
+ printf( " Signal: %u%% ", signal * 100 / PCPS_SIG_MAX );
+
+ if ( dev_has_pzf )
+ rc = mbg_show_pzf_corr_info( dh, 1 );
+
+ printf( " " );
- return 0;
+ return rc;
} // show_modulation
@@ -110,32 +117,27 @@ int show_modulation( MBG_DEV_HANDLE dh )
static /*HDR*/
int do_mbgshowsignal( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
- int has_mod = 0;
- int rc = mbg_dev_has_mod( dh, &has_mod );
+ int rc = mbg_chk_dev_has_mod( dh );
- if ( mbg_ioctl_err( rc, "mbg_dev_has_mod" ) )
- goto fail;
-
- if ( !has_mod )
+ if ( mbg_rc_is_error( rc ) )
{
- printf( "This device does not support monitoring signal modulation.\n" );
- goto done;
+ mbg_cond_err_msg_info( rc, "mbg_dev_has_mod",
+ "support monitoring signal modulation" );
+ return rc;
}
printf( "\nMonitoring signal modulation:\n" );
for (;;)
- if ( show_modulation( dh ) < 0 )
- goto fail;
-
-done:
- return 0;
+ if ( mbg_rc_is_error( rc = show_modulation( dh ) ) )
+ break;
-fail:
- return -1;
+ return rc;
} // do_mbgshowsignal
+static MBG_DEV_HANDLER_FNC do_mbgshowsignal;
+
static /*HDR*/
@@ -175,15 +177,11 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbgshowsignal );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbgshowsignal, 0 );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbgstatus/Makefile b/src/external/bsd/meinberg/dist/mbgstatus/Makefile
index 3d86873..214c076 100755
--- a/src/external/bsd/meinberg/dist/mbgstatus/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgstatus/Makefile
@@ -1,24 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.7.1.4.1.2 2011/04/20 09:34:06 martin TRASH $
+# $Id: Makefile 1.8 2017/07/05 18:27:30 martin REL_M $
#
# Description:
# Makefile for mbgstatus.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.7.1.4.1.2 2011/04/20 09:34:06 martin
-# Added module lan_util.
-# Revision 1.7.1.4.1.1 2010/09/20 12:07:06 stefan
-# Updated for use with latest base Makefile.
-# Revision 1.7.1.4 2010/08/30 09:05:24 martin
-# Revision 1.7.1.3 2010/08/30 08:20:32 martin
-# Revision 1.7.1.2 2010/08/24 08:35:11 martin
-# This basically builds kernel modules and user space apps correctly.
-# However, there's still an absolute path specification which needs
-# to be resolved.
-# Revision 1.7.1.1 2010/08/24 08:02:05 martin
+# Revision 1.8 2017/07/05 18:27:30 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.7 2009/07/24 10:31:17 martin
# Moved declarations to a common file which is now included.
# Revision 1.6 2008/12/22 11:54:32 martin
@@ -40,16 +32,19 @@ INST_TO_BIN = 1
OBJS := $(TARGET).o
OBJS += mbgdevio.o
+OBJS += mbgutil.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
-OBJS += pcpsutil.o
-OBJS += mbgmktm.o
OBJS += pcpslstr.o
-OBJS += parmpcps.o
-OBJS += parmgps.o
+OBJS += deviohlp.o
OBJS += ctrydttm.o
OBJS += ctry.o
OBJS += lan_util.o
+OBJS += nanotime.o
BASEDIR := ..
include $(BASEDIR)/Makefile
diff --git a/src/external/bsd/meinberg/dist/mbgstatus/mbgstatus.c b/src/external/bsd/meinberg/dist/mbgstatus/mbgstatus.c
index 5517eb6..e801034 100755
--- a/src/external/bsd/meinberg/dist/mbgstatus/mbgstatus.c
+++ b/src/external/bsd/meinberg/dist/mbgstatus/mbgstatus.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgstatus.c 1.13.1.12 2011/07/08 11:02:47 martin TRASH $
+ * $Id: mbgstatus.c 1.14 2017/07/05 18:34:46 martin REL_M $
*
* Description:
* Main file for mbgstatus program which demonstrates how to
@@ -10,27 +10,13 @@
*
* -----------------------------------------------------------------------
* $Log: mbgstatus.c $
- * Revision 1.13.1.12 2011/07/08 11:02:47 martin
- * Revision 1.13.1.11 2011/07/05 15:35:55 martin
- * Modified version handling.
- * Revision 1.13.1.10 2011/07/05 14:35:19 martin
+ * Revision 1.14 2017/07/05 18:34:46 martin
* New way to maintain version information.
- * Revision 1.13.1.9 2011/04/20 16:08:27 martin
- * Use snprint_ip4_addr() from module lan_util.
- * Revision 1.13.1.8 2011/03/03 10:01:23 daniel
- * Indicate Unicast role in PTP port state
- * Revision 1.13.1.7 2011/02/07 12:10:58 martin
- * Use mbg_get_ptp_status() API call.
- * Revision 1.13.1.6 2010/11/25 14:54:51 martin
- * Revision 1.13.1.5 2010/11/05 12:54:22 martin
- * Introduce "verbose" flag and associated command line parameter -v.
- * Revision 1.13.1.4 2010/10/15 11:28:56 martin
- * Display UTC offs from IRIG signal.
- * Revision 1.13.1.3 2010/08/30 08:22:24 martin
- * Revision 1.13.1.2 2010/08/11 15:06:49 martin
- * Preliminarily display raw IRIG data, if supported by the device.
- * Revision 1.13.1.1 2010/02/17 14:11:43 martin
- * Cosmetics ...
+ * Support build under Windows.
+ * Show many more details, at different verbosity levels.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.13 2009/09/29 15:02:16 martin
* Updated version number to 3.4.0.
* Revision 1.12 2009/07/24 14:02:59 martin
@@ -79,16 +65,19 @@
// include Meinberg headers
#include <mbgdevio.h>
+#include <mbgutil.h>
#include <mbgtime.h>
#include <pcpslstr.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
#include <lan_util.h>
+#include <deviohlp.h>
+#include <timeutil.h>
+#include <str_util.h>
+#include <nanotime.h>
// include system headers
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#define MBG_MICRO_VERSION 0
@@ -98,6 +87,10 @@
static const char *pname = "mbgstatus";
+static int loops;
+static int must_list_device_names;
+static long sleep_secs;
+static long sleep_usecs;
static unsigned int verbose;
static const char *ref_name[N_PCPS_REF]= PCPS_REF_NAMES_ENG;
@@ -107,6 +100,9 @@ static const char *osc_name[N_GPS_OSC] = DEFAULT_GPS_OSC_NAMES;
static int year_limit = 1990;
static int max_ref_offs_h = MBG_REF_OFFS_MAX / MINS_PER_HOUR;
+static int invt_reason;
+
+static const char *wdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
LANGUAGE language;
CTRY ctry;
@@ -114,6 +110,29 @@ CTRY ctry;
static /*HDR*/
+void show_invt_reason( void )
+{
+ static const char fmt[] = "\n** Warning: %s\nThe command %s.\n";
+
+ switch ( invt_reason )
+ {
+ case 2:
+ printf( fmt, DEFAULT_STR_IRIG_NOT_CFGD_EN,
+ "\"mbgirigcfg\" can be used to change the settings" );
+ break;
+
+ case 1:
+ printf( fmt, DEFAULT_STR_IRIG_INVT_EN,
+ "\"mbgctrl DATE=...\" can be used to set the on-board date" );
+ break;
+
+ } // switch
+
+} // show_invt_reason
+
+
+
+static /*HDR*/
void print_pcps_time( const char *s, const PCPS_TIME *tp, const char *tail )
{
const char *fmt = "%s";
@@ -122,9 +141,10 @@ void print_pcps_time( const char *s, const PCPS_TIME *tp, const char *tail )
if ( s )
printf( fmt, s );
- printf( fmt, pcps_date_time_str( ws, tp, year_limit, pcps_tz_name( tp, PCPS_TZ_NAME_FORCE_UTC_OFFS, 0 ) ) );
+ printf( fmt, pcps_date_time_str( ws, sizeof( ws ), tp, year_limit,
+ pcps_tz_name( tp, PCPS_TZ_NAME_FORCE_UTC_OFFS, 0 ) ) );
- if ( verbose > 1 )
+ if ( ( verbose > 0 ) && _pcps_time_is_read( tp ) )
printf( ", st: 0x%02lX", (ulong) tp->status );
if ( tail )
@@ -139,7 +159,7 @@ void print_dms( const char *s, const DMS *p, const char *tail )
{
const char *fmt = "%s";
- printf( "%s %c %3i deg %02i min %05.2f sec",
+ printf( "%s %c %3i deg %02i min %06.3f sec",
s,
p->prefix,
p->deg,
@@ -162,9 +182,14 @@ void print_position( const char *s, const POS *p, const char *tail )
if ( s )
+ {
printf( fmt, s );
- if ( verbose > 0 )
+ if ( verbose )
+ printf( "\n" );
+ }
+
+ if ( verbose > 1 )
{
printf( " x: %.0fm y: %.0fm z: %.0fm",
p->xyz[XP], p->xyz[YP], p->xyz[ZP] );
@@ -180,57 +205,22 @@ void print_position( const char *s, const POS *p, const char *tail )
if ( tail )
printf( fmt, tail );
- print_dms( " latitude: ", &p->latitude, tail );
- print_dms( " longitude:", &p->longitude, tail );
+ if ( verbose )
+ {
+ print_dms( " latitude: ", &p->latitude, tail );
+ print_dms( " longitude:", &p->longitude, tail );
+ }
+
} // print_position
static /*HDR*/
-void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *tail )
+void show_signal( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, int signal )
{
- const char *status_fmt = "Status info: %s%s\n";
- const char *status_err = "*** ";
- const char *status_ok = "";
- PCPS_TIME t;
- PCPS_STATUS_STRS strs;
- int signal;
int ref_type;
- int i;
- int rc = mbg_get_time( dh, &t );
- if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
- return;
-
-
- print_pcps_time( "Date/time: ", &t, tail );
-
- if ( ( verbose > 0 ) && _pcps_has_hr_time( pdev ) )
- {
- PCPS_HR_TIME ht;
- char ws[80];
-
- rc = mbg_get_hr_time( dh, &ht );
-
- if ( mbg_ioctl_err( rc, "mbg_get_hr_time" ) )
- return;
-
- mbg_snprint_hr_time( ws, sizeof( ws ), &ht );
- printf( "Local HR time: %s", ws );
-
- if ( verbose > 1 )
- printf( ", st: 0x%04lX", (ulong) ht.status );
-
- printf( "%s", tail );
- }
-
- signal = t.signal - PCPS_SIG_BIAS;
-
- if ( signal < 0 )
- signal = 0;
- else
- if ( signal > PCPS_SIG_MAX )
- signal = PCPS_SIG_MAX;
+ int rc;
ref_type = _pcps_ref_type( pdev );
@@ -274,35 +264,88 @@ void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *
}
}
}
+ else
+ if ( _pcps_has_pzf( pdev ) )
+ printf( "/PZF" );
+
+ printf( ")\n" );
- puts( ")" );
+} // show_signal
- if ( _pcps_has_irig_time( pdev ) )
+
+
+static /*HDR*/
+void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *tail )
+{
+ const char status_fmt[] = "Status info: %s%s\n";
+ const char status_err[] = "*** ";
+ const char status_ok[] = "";
+ const char *info_err = ( _pcps_is_gps( pdev ) || _pcps_is_lwr( pdev ) ) ?
+ "ANTENNA FAULTY" : "NO INPUT SIGNAL";
+ const char info_ok[] = "Input signal available";
+ PCPS_TIME t;
+ PCPS_STATUS_STRS strs;
+ int signal;
+ int i;
+ int rc = mbg_get_time( dh, &t );
+
+ if ( mbg_cond_err_msg( rc, "mbg_get_time" ) )
+ return;
+
+
+ print_pcps_time( "Date/time: ", &t, tail );
+
+ if ( ( verbose > 0 ) && _pcps_has_hr_time( pdev ) )
{
- PCPS_IRIG_TIME it;
+ PCPS_HR_TIME ht;
+ char ws[80];
- rc = mbg_get_irig_time( dh, &it );
+ rc = mbg_get_hr_time( dh, &ht );
- if ( !mbg_ioctl_err( rc, "mbg_get_irig_time" ) )
- printf( "Raw IRIG time: yday %u, %02u:%02u:%02u\n",
- it.yday, it.hour, it.min, it.sec );
+ if ( mbg_cond_err_msg( rc, "mbg_get_hr_time" ) )
+ return;
+
+ mbg_snprint_hr_time( ws, sizeof( ws ), &ht, 0 ); // raw timestamp?
+ printf( "Local HR time: %s", ws );
+
+ if ( verbose > 0 )
+ printf( ", st: 0x%04lX", (ulong) ht.status );
+
+ printf( "%s", tail );
}
- if ( _pcps_is_irig_rx( pdev ) )
+ signal = t.signal - PCPS_SIG_BIAS;
+
+ if ( signal < 0 )
+ signal = 0;
+ else
+ if ( signal > PCPS_SIG_MAX )
+ signal = PCPS_SIG_MAX;
+
+ if ( _pcps_has_signal( pdev ) )
+ show_signal( dh, pdev, signal );
+
+ if ( _pcps_has_pzf( pdev ) )
{
- printf( status_fmt,
- ( signal < PCPS_SIG_ERR ) ? status_err : status_ok,
- ( signal < PCPS_SIG_ERR ) ? "NO INPUT SIGNAL"
- : "Input signal available" );
+ mbg_show_pzf_corr_info( dh, 0 );
+ printf( "\n" );
}
- else
+
+ if ( verbose && _pcps_has_irig_time( pdev ) )
{
- printf( status_fmt,
- ( signal < PCPS_SIG_ERR ) ? status_err : status_ok,
- ( signal < PCPS_SIG_ERR ) ? "ANTENNA IS NOT CONNECTED"
- : "Antenna is connected" );
+ PCPS_IRIG_TIME it;
+
+ rc = mbg_get_irig_time( dh, &it );
+
+ if ( !mbg_cond_err_msg( rc, "mbg_get_irig_time" ) )
+ printf( "Raw IRIG time: yday %u, %02u:%02u:%02u\n",
+ it.yday, it.hour, it.min, it.sec );
}
+ printf( status_fmt,
+ ( signal < PCPS_SIG_ERR ) ? status_err : status_ok,
+ ( signal < PCPS_SIG_ERR ) ? info_err : info_ok );
+
// Evaluate the status code and setup status messages.
pcps_status_strs( t.status, _pcps_time_is_read( &t ),
_pcps_is_gps( pdev ), &strs );
@@ -317,6 +360,23 @@ void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *
pstr->cp );
}
+ invt_reason = 0;
+
+ if ( _pcps_is_irig_rx( pdev ) && ( t.status & PCPS_INVT ) )
+ {
+ MBG_REF_OFFS ref_offs;
+
+ rc = mbg_get_ref_offs( dh, &ref_offs );
+
+ if ( !mbg_cond_err_msg( rc, "mbg_get_ref_offs" ) )
+ {
+ if ( _pcps_ref_offs_out_of_range( ref_offs ) )
+ invt_reason = 2;
+ else
+ invt_reason = 1;
+ }
+ }
+
} // show_time_and_status
@@ -327,7 +387,7 @@ void show_sync_time( MBG_DEV_HANDLE dh, const char *tail )
PCPS_TIME t;
int rc = mbg_get_sync_time( dh, &t );
- if ( mbg_ioctl_err( rc, "mbg_get_sync_time" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_sync_time" ) )
return;
print_pcps_time( "Last sync: ", &t, tail );
@@ -340,49 +400,133 @@ static /*HDR*/
void show_ext_stat_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *tail )
{
const char *fmt = "%s";
- RECEIVER_INFO ri;
- STAT_INFO si = { 0 };
+ RECEIVER_INFO ri = { 0 };
+ ALL_GNSS_INFO agi = { { 0 } };
+ GNSS_SAT_INFO *p_gsi;
char ws[80];
- char *mode_name;
+ const char *cp;
+ int i;
+ int rc;
- int rc = mbg_setup_receiver_info( dh, p_dev, &ri );
+ // first collect all information
- if ( mbg_ioctl_err( rc, "mbg_get_gps_stat_info" ) )
- return;
+ rc = mbg_setup_receiver_info( dh, p_dev, &ri );
+ if ( mbg_cond_err_msg( rc, "mbg_setup_receiver_info" ) )
+ return;
- if ( _pcps_is_gps( p_dev ) )
+ if ( mbg_rc_is_success( mbg_chk_dev_is_gps( dh ) ) )
{
- rc = mbg_get_gps_stat_info( dh, &si );
+ rc = mbg_chk_get_all_gnss_info( dh, &agi );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_stat_info" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_chk_get_gnss_info" ) )
return;
+ }
+
+ // now print information
+
+ if ( verbose )
+ printf( "Feature mask: 0x%08lX\n", (ulong) ri.features );
- switch ( si.mode )
+ if ( _pcps_has_stat_info( p_dev ) )
+ {
+ if ( _pcps_has_stat_info_mode( p_dev ) )
{
- case AUTO_166: mode_name = "Normal Operation"; break;
- case WARM_166: mode_name = "Warm Boot"; break;
- case COLD_166: mode_name = "Cold Boot"; break;
+ switch ( agi.stat_info.mode )
+ {
+ case AUTO_166: cp = "Normal Operation"; break;
+ case WARM_166: cp = "Warm Boot"; break;
+ case COLD_166: cp = "Cold Boot"; break;
- default: // This should never happen!
- sprintf( ws, "Unknown mode of operation: %02Xh", si.mode );
- mode_name = ws;
+ default: // This should never happen!
+ snprintf_safe( ws, sizeof( ws ), "%s mode of operation: %02Xh",
+ str_unknown, agi.stat_info.mode );
+ cp = ws;
- } // switch
+ } // switch
- printf( "%s, %i sats in view, %i sats used\n", mode_name, si.svs_in_view, si.good_svs );
+ printf( "%s", cp );
+ }
}
- printf( "Osc type: %s", osc_name[( ri.osc_type < N_GPS_OSC ) ? ri.osc_type : GPS_OSC_UNKNOWN] );
-
- if ( _pcps_is_gps( p_dev ) )
+ if ( agi.n_gnss_supp )
{
- printf( ", DAC cal: %+i, fine: %+i",
- (int) ( si.dac_cal - OSC_DAC_BIAS ),
- (int) ( si.dac_val - OSC_DAC_BIAS ) );
+ #if defined( DEBUG ) // TODO
+ int must_print_sv_list = _pcps_has_stat_info_svs( p_dev ) && verbose;
+ #else
+ int must_print_sv_list = _pcps_is_gnss( p_dev ) && verbose;
+ #endif
+ int print_multi_lines = ( agi.n_gnss_supp > 1 ) || must_print_sv_list;
+
+ // print multiple lines
+ // otherwise append to line
+ printf( print_multi_lines ? ":\n" : ", " );
+
+ for ( i = 0; i < agi.n_gnss_supp; i++ )
+ {
+ static const char * const gnss_type_names[N_GNSS_TYPES] = GNSS_TYPE_STRS;
+ int gnss_type;
+
+ p_gsi = &agi.gnss_sat_info_idx[i].gnss_sat_info;
+ gnss_type = p_gsi->gnss_type;
+
+ if ( gnss_type >= N_GNSS_TYPES )
+ {
+ mbg_snprintf( ws, sizeof( ws ), "(%s GNSS type %i): ", str_unknown, gnss_type );
+ cp = ws;
+ }
+ else
+ cp = gnss_type_names[gnss_type];
+
+ if ( print_multi_lines )
+ printf( " " );
+
+ if ( agi.gnss_mode_info.settings.gnss_set & ( 1UL << gnss_type ) )
+ {
+ printf( "%i %s sats tracked, %i expected to be visible\n", p_gsi->good_svs, cp, p_gsi->svs_in_view );
+
+ if ( must_print_sv_list )
+ {
+ int sat_idx;
+
+ for ( sat_idx = 0; sat_idx < MAX_USED_SATS; sat_idx++ )
+ {
+ int sat_num = p_gsi->svs[sat_idx];
+
+ #if !defined( DEBUG )
+ if ( sat_num == 0 )
+ break;
+ #endif
+
+ printf( "%s%i", ( sat_idx == 0 ) ? " Sats: " : ", ", sat_num );
+ }
+
+ if ( sat_idx ) // the satellite list has been printed
+ printf( "\n" );
+ }
+ }
+ else
+ printf( "%s reception disabled by configuration\n", cp );
+ }
}
- puts( "" );
+ if ( verbose )
+ {
+ #if 0 //##+++++++++++++++++++++++++
+ printf( "Feature mask: 0x%08lX\n", (ulong) ri.features );
+ #endif
+
+ printf( "Osc type: %s", osc_name[( ri.osc_type < N_GPS_OSC ) ? ri.osc_type : GPS_OSC_UNKNOWN] );
+
+ if ( _pcps_has_stat_info( p_dev ) )
+ {
+ printf( ", DAC cal: %+i, fine: %+i",
+ (int) ( agi.stat_info.dac_cal - OSC_DAC_BIAS ),
+ (int) ( agi.stat_info.dac_val - OSC_DAC_BIAS ) );
+ }
+
+ puts( "" );
+ }
if ( tail )
printf( fmt, tail );
@@ -397,10 +541,10 @@ void show_gps_pos( MBG_DEV_HANDLE dh, const char *tail )
POS pos;
int rc = mbg_get_gps_pos( dh, &pos );
- if ( mbg_ioctl_err( rc, "mbg_get_gps_pos" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_gps_pos" ) )
return;
- print_position( "Receiver Position:\n", &pos, tail );
+ print_position( "Receiver Position:", &pos, tail );
} // show_gps_pos
@@ -413,45 +557,59 @@ void show_utc_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
int rc = mbg_get_utc_parm( dh, &utc );
- if ( mbg_ioctl_err( rc, "mbg_get_utc_parm" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_utc_parm" ) )
return;
- if ( !utc.valid )
- {
- puts( "** UTC parameters not valid" );
- return;
- }
- if ( verbose > 1 )
+ if ( utc.valid )
{
- //##++++ utc.delta_tls = utc.delta_tlsf - 1;
-
- printf( "CSUM: %04X, valid: %04X\n", utc.csum, utc.valid );
- printf( "t0t: %u|%u.%07u, A0: %g A1: %g\n",
- utc.t0t.wn, utc.t0t.sec, utc.t0t.tick,
- utc.A0, utc.A1 );
- printf( "WNlsf: %u, DN: %u, offs: %i/%i\n",
- utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf );
- }
+ char tmp_str[80];
+ struct tm tm = { 0 };
- if ( utc.delta_tls != utc.delta_tlsf )
- {
- // a leap second is currently being announced
- time_t t_ls = (time_t) utc.WNlsf * SECS_PER_WEEK
- + (time_t) utc.DNt * SECS_PER_DAY
- + GPS_SEC_BIAS - 1;
-
- struct tm *tm = gmtime( &t_ls );
-
- printf( "UTC offset transition from %is to %is due to leap second\n"
- "%s at UTC midnight at the end of %04i-%02i-%02i.\n",
- utc.delta_tls, utc.delta_tlsf,
- ( utc.delta_tls < utc.delta_tlsf ) ? "insertion" : "deletion",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday
- );
+ long t_ls_long = (long) utc.WNlsf * SECS_PER_WEEK
+ + (long) utc.DNt * SECS_PER_DAY
+ + GPS_SEC_BIAS - 1;
+ time_t t_ls = cvt_to_time_t( t_ls_long );
+
+ rc = mbg_gmtime( &tm, &t_ls );
+
+ if ( mbg_rc_is_success( rc ) )
+ mbg_snprintf( tmp_str, sizeof( tmp_str ), "at UTC midnight at the end of %s, %04i-%02i-%02i",
+ wdays[tm.tm_wday], tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday );
+ else
+ snprint_gmtime_error( tmp_str, sizeof( tmp_str ), rc, t_ls, __func__ );
+
+ if ( verbose > 1 )
+ {
+ //##++++++++++ utc.delta_tls = utc.delta_tlsf - 1;
+
+ printf( "CSUM: %04X, valid: %04X\n", utc.csum, utc.valid );
+ printf( "t0t: %u|%u.%07u, A0: %g A1: %g\n",
+ utc.t0t.wn, utc.t0t.sec, utc.t0t.tick,
+ utc.A0, utc.A1 );
+ printf( "WNlsf: %u, DN: %u, offs: %i/%i\n",
+ utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf );
+ }
+
+ if ( utc.delta_tls != utc.delta_tlsf )
+ {
+ // a leap second is currently being announced
+ printf( "UTC offset transition from %is to %is due to leap second\n"
+ "%s %s.\n",
+ utc.delta_tls, utc.delta_tlsf,
+ ( utc.delta_tls < utc.delta_tlsf ) ? "insertion" : "deletion",
+ tmp_str
+ );
+ }
+ else
+ if ( verbose )
+ printf( "Leap second eventually %s\n", tmp_str );
+ else
+ printf( "UTC offset parameter: %is, no leap second announced.\n", utc.delta_tls );
}
else
- printf( "UTC offset parameter: %is, no leap second announced.\n", utc.delta_tls );
+ puts( "** UTC parameters not valid" );
+
} // show_utc_info
@@ -464,7 +622,7 @@ void show_irig_ctrl_bits( MBG_DEV_HANDLE dh )
int rc = mbg_get_irig_ctrl_bits( dh, &irig_ctrl_bits );
- if ( mbg_ioctl_err( rc, "mbg_get_irig_ctrl_bits" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_irig_ctrl_bits" ) )
return;
printf( "IRIG control bits: %08lX (hex, LSB first)", (ulong) irig_ctrl_bits );
@@ -484,10 +642,10 @@ char *str_raw_irig_utc_offs_hours( char *s, int max_len, const MBG_RAW_IRIG_DATA
| ( ( p->data_bytes[8] >> 4 ) & 0x02 )
| ( ( p->data_bytes[8] >> 6 ) & 0x01 );
- n = snprintf( s, max_len, "%c%li", ( p->data_bytes[8] & 0x80 ) ? '-' : '+', offs );
+ n = mbg_snprintf( s, max_len, "%c%li", ( p->data_bytes[8] & 0x80 ) ? '-' : '+', offs );
if ( p->data_bytes[8] & 0x02 )
- n += snprintf( &s[n], max_len - n, "%s", ".5" );
+ n += mbg_snprintf( &s[n], max_len - n, "%s", ".5" );
return s;
@@ -504,7 +662,7 @@ void show_raw_irig_data( MBG_DEV_HANDLE dh )
int rc = mbg_get_raw_irig_data( dh, &raw_irig_data );
- if ( mbg_ioctl_err( rc, "mbg_get_raw_irig_data" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_raw_irig_data" ) )
return;
printf( "Raw IRIG data:" );
@@ -530,7 +688,7 @@ void show_irig_debug_status( MBG_DEV_HANDLE dh )
int i;
int rc = _mbg_generic_read_var( dh, PCPS_GET_DEBUG_STATUS, st );
- if ( mbg_ioctl_err( rc, "show_irig_debug_status" ) )
+ if ( mbg_cond_err_msg( rc, "show_irig_debug_status" ) )
return;
printf( "Debug status (hex): %08lX\n", (ulong) st );
@@ -552,25 +710,18 @@ void show_lan_intf_state( MBG_DEV_HANDLE dh )
int rc = mbg_get_ip4_state( dh, &ip4_settings );
- if ( mbg_ioctl_err( rc, "mbg_get_ip4_state" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ip4_state" ) )
return;
rc = mbg_get_lan_if_info( dh, &lan_if_info );
- if ( mbg_ioctl_err( rc, "mbg_get_lan_if_info" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_lan_if_info" ) )
return;
printf( "On-board LAN interface settings:\n" );
- snprintf( ws, sizeof( ws ), "%02X-%02X-%02X-%02X-%02X-%02X",
- lan_if_info.mac_addr[0],
- lan_if_info.mac_addr[1],
- lan_if_info.mac_addr[2],
- lan_if_info.mac_addr[3],
- lan_if_info.mac_addr[4],
- lan_if_info.mac_addr[5]
- );
+ snprint_mac_addr( ws, sizeof( ws ), &lan_if_info.mac_addr );
printf( " MAC Address: %s\n", ws );
snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.ip_addr, NULL );
@@ -595,58 +746,214 @@ void show_lan_intf_state( MBG_DEV_HANDLE dh )
static /*HDR*/
void show_ptp_state( MBG_DEV_HANDLE dh )
{
- static const char *ptp_stat_str[N_PTP_PORT_STATE] = PTP_PORT_STATE_STRS;
+ static const char *ptp_role_strs[N_PTP_ROLES] = PTP_ROLE_STRS;
+ static const char *ptp_state_strs[N_PTP_PORT_STATE] = PTP_PORT_STATE_STRS;
+ static const char *ptp_nw_prot_strs[N_PTP_NW_PROT] = PTP_NW_PROT_STRS;
+ static const char *ptp_delay_mech_names[N_PTP_DELAY_MECH] = PTP_DELAY_MECH_NAMES;
+ static const PTP_TABLE ptp_time_source_tbl[] = PTP_TIME_SOURCE_TABLE;
+ static const char *ptp_clock_accuracy_strs[] = PTP_CLOCK_ACCURACY_STRS;
+
char ws[100];
const char *cp;
- int ptp_state_available;
+ int must_show_slave_mode_info;
+ int must_show_master_mode_info;
+ int slave_mode_active;
+ int master_mode_active;
+ int any_mode_active;
+ int utc_offset_valid;
PTP_STATE ptp_state;
PTP_CFG_INFO ptp_info;
+ int tmp;
int rc = mbg_get_ptp_state( dh, &ptp_state );
- if ( mbg_ioctl_err( rc, "mbg_get_ptp_state" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ptp_state" ) )
return;
rc = mbg_get_ptp_cfg_info( dh, &ptp_info );
- if ( mbg_ioctl_err( rc, "mbg_get_ptp_info" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_ptp_info" ) )
return;
- printf( "PTP port status:\n" );
- ptp_state_available = ( ptp_state.port_state == PTP_PORT_STATE_SLAVE );
+ // set up some flags controlling which information to be shown
- printf( " Port mode: %s%s\n", ( ptp_state_available && ptp_info.settings.ptp_role == PTP_ROLE_UNICAST_SLAVE ) ? "Unicast" : "",
- ( ptp_state.port_state < N_PTP_PORT_STATE ) ? ptp_stat_str[ptp_state.port_state] : "(undefined)" );
+ must_show_slave_mode_info = ( verbose > 1 ) ||
+ ( ( ( 1UL << ptp_info.settings.ptp_role ) & PTP_ROLE_MSK_SLAVES ) != 0 );
- cp = ptp_state_available ? ws : str_not_avail;
+ must_show_master_mode_info = ( verbose > 1 ) ||
+ ( ( ( 1UL << ptp_info.settings.ptp_role ) & PTP_ROLE_MSK_MASTERS ) != 0 );
-//##++++++++++
- snprintf( ws, sizeof( ws ), "%02X-%02X-%02X-%02X-%02X-%02X",
- ptp_state.gm_id.b[0],
- ptp_state.gm_id.b[1],
- ptp_state.gm_id.b[2],
- ptp_state.gm_id.b[5],
- ptp_state.gm_id.b[6],
- ptp_state.gm_id.b[7]
- );
- printf( " Grandmaster MAC: %s\n", cp );
+ slave_mode_active = ( ptp_state.port_state == PTP_PORT_STATE_UNCALIBRATED )
+ || ( ptp_state.port_state == PTP_PORT_STATE_SLAVE );
+ master_mode_active = ( ptp_state.port_state == PTP_PORT_STATE_PRE_MASTER )
+ || ( ptp_state.port_state == PTP_PORT_STATE_MASTER )
+ || ( ptp_state.port_state == PTP_PORT_STATE_PASSIVE );
- snprintf( ws, sizeof( ws ), "%c%li.%09li s",
- _nano_time_negative( &ptp_state.path_delay ) ? '-' : '+',
- labs( (long) ptp_state.path_delay.secs ),
- labs( (long) ptp_state.path_delay.nano_secs )
- );
- printf( " PTP path delay: %s\n", cp );
+ any_mode_active = slave_mode_active || master_mode_active;
+
+
+ // PTP role and port state
+
+ printf( "PTP port state:\n" );
+
+ printf( " Port mode: " );
+
+ if ( any_mode_active )
+ printf( "%s", ( ptp_state.flags & PTP_FLAG_MSK_IS_UNICAST ) ?
+ "Unicast " : "Multicast " );
+
+ if ( ptp_state.port_state < N_PTP_PORT_STATE )
+ printf( "%s", ptp_state_strs[ptp_state.port_state] );
+ else
+ printf( "%s, code %i", str_undefined, ptp_state.port_state );
+
+ if ( !any_mode_active || ( verbose > 1 ) )
+ printf( " in %s role",
+ ( ptp_info.settings.ptp_role < N_PTP_ROLES ) ?
+ ptp_role_strs[ptp_info.settings.ptp_role] : str_undefined );
+
+ printf( "\n" );
+
+
+ if ( !any_mode_active || verbose )
+ {
+ printf( " PTP protocol: " );
+
+ // If not fully synchronized then not all fields of the PTP_STATE
+ // structure may have been filled, so we show configuration settings
+ // in this case.
+
+ if ( ptp_state.ptp_prot_version )
+ printf( "v%i, ", ptp_state.ptp_prot_version );
+
+ tmp = any_mode_active ? ptp_state.nw_prot : ptp_info.settings.nw_prot;
+ printf( "%s", ( tmp < N_PTP_NW_PROT ) ?
+ ptp_nw_prot_strs[tmp] : str_undefined );
+
+ printf( ", %s step",
+ ( ptp_state.flags & PTP_FLAG_MSK_ONE_STEP ) ? "one" : "two" );
+
+ tmp = any_mode_active ? ptp_state.domain_number : ptp_info.settings.domain_number;
+ printf( ", domain %i", tmp );
+
+ tmp = any_mode_active ? ptp_state.delay_mech : ptp_info.settings.delay_mech;
+ printf( ", delay mech. %s", ( tmp < N_PTP_DELAY_MECH ) ?
+ ptp_delay_mech_names[tmp] : str_undefined );
+
+ tmp = any_mode_active ? ptp_state.log_delay_req_intv : ptp_info.settings.delay_req_intv;
+ printf( ", dly req. intv. 2^%i s", tmp );
+
+ printf( "\n" );
+ }
+
+
+ if ( must_show_slave_mode_info )
+ {
+ cp = ( slave_mode_active || ( verbose > 1 ) ) ? ws : str_not_avail;
+
+ snprint_octets( ws, sizeof( ws ), ptp_state.gm_id.b,
+ sizeof( ptp_state.gm_id.b ), MAC_SEP_CHAR_ALT, NULL );
+ printf( " Grandmaster ID: %s\n", cp );
+
+ snprint_nano_time( ws, sizeof( ws ), &ptp_state.offset );
+ printf( " PTP time offset: %s\n", cp );
+
+ snprint_nano_time( ws, sizeof( ws ), &ptp_state.path_delay );
+ printf( " PTP path delay: %s\n", cp );
+
+ if ( verbose > 1 )
+ {
+ snprint_nano_time( ws, sizeof( ws ), &ptp_state.mean_path_delay );
+ printf( " Mean path delay: %s\n", cp );
+
+ snprint_nano_time( ws, sizeof( ws ), &ptp_state.delay_asymmetry );
+ printf( " Delay asymmetry: %s\n", cp );
+ }
+ }
+
+
+ // PTP time scale
+
+ cp = NULL;
+
+ if ( ptp_state.flags & PTP_FLAG_MSK_TIMESCALE_IS_PTP ) // this is the default
+ {
+ if ( must_show_master_mode_info || verbose )
+ cp = "TAI (standard)";
+ }
+ else // unusual case, print info if available
+ if ( any_mode_active )
+ cp = "arbitrary (non-standard)";
+
+ if ( cp )
+ printf( " PTP time scale: %s\n", cp );
+
+
+ // UTC offset and leap second status
+
+ utc_offset_valid = ( ptp_state.flags & PTP_FLAG_MSK_UTC_VALID ) != 0;
+
+ printf( " PTP UTC offset: " );
+
+ if ( !utc_offset_valid )
+ printf( " %s", str_unknown ); // UTC offset not valid
+
+ if ( utc_offset_valid || ( verbose > 1 ) )
+ {
+ printf( utc_offset_valid ? " " : " (" );
+
+ printf( "%+i s", ptp_state.utc_offset );
+
+ if ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN ) // leap second is announced
+ {
+ // distinguish between leap second insertion and deletion
+ printf( ", leap second %s scheduled",
+ ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN_NEG ) ? "deletion" : "insertion" );
+ }
+
+ if ( !utc_offset_valid )
+ printf( ")" );
+ }
+
+ printf( "\n" );
+
+
+ if ( verbose > 1 )
+ {
+ const PTP_TABLE *p_tbl;
+
+ printf( "PTP clock state:\n" );
+
+ for ( p_tbl = ptp_time_source_tbl; p_tbl->name; p_tbl++ )
+ if ( p_tbl->value == ptp_state.time_source )
+ break;
+
+ printf( " Time source: %s\n", p_tbl->name ? p_tbl->name : str_unknown );
+
+ printf( " Clock class: %i\n", ptp_state.clock_class );
+
+ tmp = N_PTP_CLOCK_ACCURACY - PTP_CLOCK_ACCURACY_NUM_BIAS;
+
+ if ( ( ptp_state.clock_accuracy >= PTP_CLOCK_ACCURACY_NUM_BIAS ) &&
+ ( ptp_state.clock_accuracy < N_PTP_CLOCK_ACCURACY ) )
+ cp = ptp_clock_accuracy_strs[ptp_state.clock_accuracy - PTP_CLOCK_ACCURACY_NUM_BIAS];
+ else
+ cp = str_undefined;
+
+ printf( " Clock accuracy: %s\n", cp );
+
+#if 0
+ time_source
+ clock_class
+ clock_accuracy
+#endif
+ printf( " Offs sc. log var: %u", ptp_state.clock_offset_scaled_log_variance );
+ printf( "\n" );
+ }
- snprintf( ws, sizeof( ws ), "%c%li.%09li s",
- _nano_time_negative( &ptp_state.offset ) ? '-' : '+',
- labs( (long) ptp_state.offset.secs ),
- labs( (long) ptp_state.offset.nano_secs )
- );
- printf( " PTP time offset: %s\n", cp );
} // show_ptp_state
@@ -659,8 +966,8 @@ int check_irq_unsafe( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
int ret_val = 0;
int rc = mbg_get_irq_stat_info( dh, &irq_stat_info );
- if ( mbg_ioctl_err( rc, "mbg_get_irq_stat_info" ) )
- return -1;
+ if ( mbg_cond_err_msg( rc, "mbg_get_irq_stat_info" ) )
+ return rc;
if ( irq_stat_info & PCPS_IRQ_STAT_UNSAFE )
{
@@ -712,38 +1019,61 @@ int do_mbgstatus( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
if ( check_irq_unsafe( dh, p_dev ) < 0 )
goto done;
- if ( _pcps_has_gps_data( p_dev ) )
- show_ext_stat_info( dh, p_dev, NULL );
+ for (;;)
+ {
+ if ( _pcps_has_gps_data( p_dev ) )
+ show_ext_stat_info( dh, p_dev, NULL );
+
+ show_time_and_status( dh, p_dev, "\n" );
+ show_sync_time( dh, "\n" );
+
+ if ( _pcps_is_gps( p_dev ) )
+ show_gps_pos( dh, "\n" );
+
+ if ( _pcps_has_utc_parm( p_dev ) && ( _pcps_is_gps( p_dev ) || ( verbose > 0 ) ) )
+ show_utc_info( dh, p_dev );
- show_time_and_status( dh, p_dev, "\n" );
- show_sync_time( dh, "\n" );
+ if ( verbose && _pcps_has_irig_ctrl_bits( p_dev ) )
+ show_irig_ctrl_bits( dh );
- if ( _pcps_is_gps( p_dev ) )
- show_gps_pos( dh, "\n" );
+ if ( verbose && ( mbg_chk_dev_has_raw_irig_data( dh ) == MBG_SUCCESS ) )
+ show_raw_irig_data( dh );
- if ( _pcps_has_utc_parm( p_dev ) )
- show_utc_info( dh, p_dev );
+ if ( verbose && _pcps_is_irig_rx( p_dev ) )
+ show_irig_debug_status( dh );
- if ( _pcps_has_irig_ctrl_bits( p_dev ) )
- show_irig_ctrl_bits( dh );
+ if ( mbg_chk_dev_has_lan_intf( dh ) == MBG_SUCCESS )
+ show_lan_intf_state( dh );
- if ( _pcps_has_raw_irig_data( p_dev ) )
- show_raw_irig_data( dh );
+ if ( _pcps_has_ptp( p_dev ) )
+ show_ptp_state( dh );
- if ( _pcps_is_irig_rx( p_dev ) )
- show_irig_debug_status( dh );
+ if ( loops > 0 )
+ loops--;
- if ( _pcps_has_lan_intf( p_dev ) )
- show_lan_intf_state( dh );
+ if ( loops == 0 )
+ break;
- if ( _pcps_has_ptp( p_dev ) )
- show_ptp_state( dh );
+ if ( sleep_secs )
+ sleep( sleep_secs );
+ else
+ if ( sleep_usecs )
+ usleep( sleep_usecs );
+
+ printf( "\n" );
+
+ // if this_loops is < 0 then loop forever
+ }
+
+ show_invt_reason();
done:
return ret_val;
} // do_mbgstatus
+static MBG_DEV_HANDLER_FNC do_mbgstatus;
+
static /*HDR*/
@@ -754,6 +1084,12 @@ void usage( void )
"The displayed information depends on the type of the card."
);
mbg_print_help_options();
+ mbg_print_opt_info( "-c", "run continuously" );
+ mbg_print_opt_info( "-l", "list device names" );
+ mbg_print_opt_info( "-n num", "run num loops" );
+ mbg_print_opt_info( "-s num", "sleep num seconds between calls (implies -c)" );
+ mbg_print_opt_info( "-u num", "sleep num microseconds between calls (implies -c)" );
+ mbg_print_opt_info( "-v", "increase verbosity" );
mbg_print_device_options();
puts( "" );
@@ -774,10 +1110,32 @@ int main( int argc, char *argv[] )
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
// check command line parameters
- while ( ( c = getopt( argc, argv, "vh?" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "cln:s:u:vh?" ) ) != -1 )
{
switch ( c )
{
+ case 'c':
+ loops = -1;
+ break;
+
+ case 'l':
+ must_list_device_names = 1;
+ break;
+
+ case 'n':
+ loops = atoi( optarg );
+ break;
+
+ case 's':
+ sleep_secs = atoi( optarg );
+ loops = -1;
+ break;
+
+ case 'u':
+ sleep_usecs = atoi( optarg );
+ loops = -1;
+ break;
+
case 'v':
verbose++;
break;
@@ -792,19 +1150,38 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
+ if ( must_list_device_names )
+ {
+ MBG_DEV_NAME_LIST_ENTRY *list_head = NULL;
+ int n_dev = mbg_find_devices_with_names( &list_head, N_SUPP_DEV_BUS );
+
+ if ( n_dev )
+ {
+ MBG_DEV_NAME_LIST_ENTRY *pos;
+
+ printf( "Unique names of devices found:\n" );
+
+ for ( pos = list_head; pos; pos = pos->next )
+ printf( " %s\n", pos->dev_name );
+ }
+ else
+ printf( "No device found.\n" );
+
+ mbg_free_device_name_list( list_head );
+ printf( "\n" );
+
+ return MBG_EXIT_CODE_SUCCESS;
+ }
+
if ( verbose )
pcps_date_time_dist = 1;
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbgstatus );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbgstatus, CHK_DEV_ALL_DEVICES );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbgsvcd/Makefile b/src/external/bsd/meinberg/dist/mbgsvcd/Makefile
index 1e940ae..74286eb 100755
--- a/src/external/bsd/meinberg/dist/mbgsvcd/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgsvcd/Makefile
@@ -1,20 +1,21 @@
#########################################################################
#
-# $Id: Makefile 1.1.1.2.1.2 2011/06/16 10:44:42 martin TRASH $
+# $Id: Makefile 1.3.1.1 2017/07/26 14:30:41 martin TEST $
#
# Description:
# Makefile for mbgsvcd.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.1.1.2.1.2 2011/06/16 10:44:42 martin
-# Install mbgsvcd to sbin.
-# Revision 1.1.1.2.1.1 2010/09/20 12:07:10 stefan
+# Revision 1.3.1.1 2017/07/26 14:30:41 martin
+# Removed lines that are not required / supported with *BSD.
+# Revision 1.3 2017/07/03 10:51:51 martin
+# *** empty log message ***
+# Revision 1.2 2017/01/27 12:19:47 martin
# Updated for use with latest base Makefile.
-# Revision 1.1.1.2 2010/08/30 09:05:24 martin
-# Revision 1.1.1.1 2010/08/30 08:22:06 martin
-# Revision 1.1 2010/02/03 16:07:18 daniel
+# Updated list of object files.
+# Support registering mbgsvcd with the init system.
# Revision 1.1 2009/09/29 08:34:23 martin
#
#########################################################################
@@ -24,10 +25,15 @@ INST_TO_SBIN = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
-OBJS += mbgmktm.o
-OBJS += pcpsmktm.o
+OBJS += chk_time_info.o
+OBJS += ntp_shm.o
BASEDIR := ..
include $(BASEDIR)/Makefile
+
diff --git a/src/external/bsd/meinberg/dist/mbgsvcd/mbgsvcd.c b/src/external/bsd/meinberg/dist/mbgsvcd/mbgsvcd.c
index af0dcab..b5f03d7 100755
--- a/src/external/bsd/meinberg/dist/mbgsvcd/mbgsvcd.c
+++ b/src/external/bsd/meinberg/dist/mbgsvcd/mbgsvcd.c
@@ -1,37 +1,35 @@
/**************************************************************************
*
- * $Id: mbgsvcd.c 1.3.1.10 2011/07/14 13:30:57 martin TRASH $
+ * $Id: mbgsvcd.c 1.4 2017/07/05 18:45:29 martin REL_M $
*
* Description:
- * Main file for mbgsvcd which compares the system time to a PCI card's
+ * Main file for mbgsvcd which compares the system time to a PCI card's
* time and transfers this data pair to the SHM driver of the ntpd.
*
* -----------------------------------------------------------------------
* $Log: mbgsvcd.c $
- * Revision 1.3.1.10 2011/07/14 13:30:57 martin
- * Code cleanup.
- * Eliminated some potential warnings due to ignored function return values.
- * Revision 1.3.1.9 2011/07/05 15:35:55 martin
- * Modified version handling.
- * Revision 1.3.1.8 2011/07/05 14:35:19 martin
+ * Revision 1.4 2017/07/05 18:45:29 martin
* New way to maintain version information.
- * Revision 1.3.1.7 2011/06/23 15:35:40 martin
- * Skip devices which don't support HR time immediately at startup.
- * Revision 1.3.1.6 2011/06/23 15:02:55 martin
+ * Print PC cycles counter frequency at program start.
+ * Use /var/run as directory for the lockfile.
+ * Using generic MBG_SYS_TIME with nanosecond resolution.
+ * Workaround in case cycle frequency can not be determined.
* Compute execution time limit in cycles instead of us so this can also
* be done if the cycle counter clock rate can not be determined.
- * Revision 1.3.1.5 2011/06/23 12:45:37 martin
- * Workaround in case cycle frequency can not be determined.
- * Revision 1.3.1.4 2011/06/20 15:10:22 martin
- * Using generic MBG_SYS_TIME with nanosecond resolution.
- * Revision 1.3.1.3 2011/03/25 11:05:24 martin
- * Optionally support timespec for sys time.
- * Cleanup.
- * Revision 1.3.1.2 2011/03/23 16:30:40 martin
- * Use /var/run as directory for the lockfile.
- * Revision 1.3.1.1 2010/04/26 14:37:41 martin
- * Print PC cycles counter frequency at program start.
+ * Skip devices which don't support HR time immediately at startup.
+ * Log reasons for error if function calls fail.
+ * Combined printf() and syslog() to mbg_log().
+ * Added leap second support.
+ * Moved some code to some extra modules which can be shared.
+ * Use seconds for the trust time.
+ * Support options -q and -r.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Patch submitted by <juergen.perlinger@t-online.de>:
+ * Support variable number of SHM units and number
+ * of the first unit to use.
+ * Proper return codes and exit codes.
* Revision 1.3 2010/03/03 14:59:36 martin
* Support -p parameter to pretend sync.
* Revision 1.2 2010/02/03 16:15:09 daniel
@@ -43,7 +41,10 @@
#include <mbgdevio.h>
#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
+#include <mbgerror.h>
#include <pcpsmktm.h>
+#include <chk_time_info.h>
+#include <ntp_shm.h>
// include system headers
#include <stdio.h>
@@ -53,174 +54,71 @@
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/time.h>
+#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <syslog.h>
-
-
+#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
-#define NTPD_BASE 0x4e545030 /* "NTP0" */
-#define SHM_UNIT 0 /* SHM driver unit number (0..3) */
-#define MAX_SHM_REFCLOCKS 4
-
-#define RUNNING_DIR "/var/run"
-#define LOCK_FILE "mbgsvcd.pid"
+#define RUNNING_DIR "/var/run"
+#define LOCK_FILE "mbgsvcd.pid"
#define MBG_MICRO_VERSION 0
-#define MBG_FIRST_COPYRIGHT_YEAR 2011 //##++++ 20101
-#define MBG_LAST_COPYRIGHT_YEAR 0 // use default
+#define MBG_FIRST_COPYRIGHT_YEAR 2010
+#define MBG_LAST_COPYRIGHT_YEAR 0 // use default
static const char *pname = "mbgsvcd";
-static int sleep_intv = 1;
-static int pretend_sync;
-
-
-
-#define MAX_FILTER_ENTRIES 32
-
-typedef struct
-{
- MBG_PC_CYCLES cyc[MAX_FILTER_ENTRIES];
- MBG_PC_CYCLES sum;
- int entries;
- int index;
-} FILTER;
-
-static FILTER filter;
-
-
-/*HDR*/ static
-MBG_PC_CYCLES do_filter( FILTER *p, MBG_PC_CYCLES cyc )
-{
- if ( p->entries < MAX_FILTER_ENTRIES )
- p->entries++;
-
- if ( ++( p->index ) >= MAX_FILTER_ENTRIES )
- p->index = 0;
-
- // update the sum of filter entries
- p->sum -= p->cyc[p->index]; // subtract oldest sample
- p->cyc[p->index] = cyc; // save new sample
- p->sum += cyc; // add new sample
-
- return p->sum / p->entries; // return mean value
-
-} /* do_filter */
-
-
-
-struct shmTime {
- int mode; /* 0 - if valid set
- * use values,
- * clear valid
- * 1 - if valid set
- * if count before and after read of
- * values is equal,
- * use values
- * clear valid
- */
- int count;
- time_t clockTimeStampSec; /* external clock */
- int clockTimeStampUSec; /* external clock */
- time_t receiveTimeStampSec; /* internal clock, when external value was received */
- int receiveTimeStampUSec; /* internal clock, when external value was received */
- int leap;
- int precision;
- int nsamples;
- int valid;
- int dummy[10];
-};
-
-struct shmTime *shmTime[MAX_SHM_REFCLOCKS];
-
-
-static
-struct shmTime *getShmTime(int unit)
-{
- int shmid = shmget( (key_t) ( NTPD_BASE + unit ),
- sizeof( struct shmTime ), IPC_CREAT | 0644 );
-
- if ( shmid == -1 )
- {
- syslog(LOG_ERR, "shmget failed\n");
- return NULL;
- }
- else
- {
- struct shmTime *p = ( struct shmTime * ) shmat( shmid, 0, 0);
-
- if ( (int) (long) p == -1 )
- {
- syslog(LOG_ERR, "shmat failed\n" );
- return NULL;
- }
+static int foreground; // -f
+static int quiet; // -q
+static int pretend_sync; // -p
+static int print_raw; // -r
+static int sleep_intv = 1; // -s
+static unsigned long trust_time_seconds; // -t
+static int n_unit0 = 0; // -o
+static int n_units = MAX_SHM_REFCLOCKS; // -n
+static int frac_digits = 9;
- syslog(LOG_INFO, "shmat(%d,0,0) succeeded\n", shmid);
- return p;
- }
-}
+MBG_PC_CYCLES_FREQUENCY cyc_freq;
+static struct shmTime *shmTime[MAX_SHM_REFCLOCKS];
+static FILTER filter; //##++++ [MAX_SHM_REFCLOCKS] ?
-static /*HDR*/
-void ntpshm_init( void )
-{
- int i = 0;
-
- syslog(LOG_INFO, "Initializing shared memory for ntpd");
+static int has_synced_after_reset[MAX_SHM_REFCLOCKS] = { 0 };
+static long int ref_trust_time_start[MAX_SHM_REFCLOCKS] = { 0 };
+static long int ref_trust_time_expire[MAX_SHM_REFCLOCKS] = { 0 };
- for ( i = 0; i< MAX_SHM_REFCLOCKS; i++ )
- shmTime[i] = getShmTime( i );
-} // ntpshm_init
-
-
-static /*HDR*/
-int ntpshm_alloc( void )
+/*HDR*/
+void mbg_log( int lvl, const char *fmt, ... )
{
- int i;
-
- for ( i = 0; i< MAX_SHM_REFCLOCKS; i++)
- {
- struct shmTime *p = shmTime[i];
-
- if ( p )
- {
- memset( p, 0, sizeof( *p ) );
-
- p->mode = 1;
- p->precision = -5; /* initially 0.5 sec */
- p->nsamples = 3; /* stages of median filter */
+ char ws[256];
+ va_list ap;
- printf( "Shared memory %d initialized\n", i );
- }
- }
+ va_start( ap, fmt );
+ vsnprintf( ws, sizeof( ws ), fmt, ap );
+ va_end( ap );
- return 0;
+ syslog( lvl, "%s", ws );
+ fprintf( stdout, "%s\n", ws );
-} // ntpshm_alloc
+} // mbg_log
static /*HDR*/
int do_mbgsvctasks( void )
{
- MBG_PC_CYCLES_FREQUENCY cyc_freq;
- MBG_TIME_INFO_HRT hrti;
- PCPS_TIME_STAMP *p_ref_ts;
- MBG_PC_CYCLES *p_ref_cyc;
- MBG_SYS_TIME_CYCLES *p_sys_tic;
char ws[256];
- double d_ref;
- double d_sys;
int rc = 0;
int n_devices_found;
int n_devices;
@@ -239,15 +137,15 @@ int do_mbgsvctasks( void )
if ( rc < 0 )
{
- printf( "Failed to read device info from device #%i.\n", i );
+ mbg_log( LOG_WARNING, "Failed to read device info from device #%i.", i );
mbg_close_device( &dh );
continue;
}
if ( !_pcps_has_hr_time( &dev_info ) )
{
- printf( "Device %s does not support HR time stamps.\n",
- _pcps_type_name( &dev_info ) );
+ mbg_log( LOG_WARNING, "Device %s does not support HR time stamps.",
+ _pcps_type_name( &dev_info ) );
mbg_close_device( &dh );
continue;
}
@@ -255,151 +153,142 @@ int do_mbgsvctasks( void )
dhs[n_devices] = dh;
devs[n_devices] = dev_info;
- if ( ++n_devices >= MAX_SHM_REFCLOCKS )
+ if ( ++n_devices >= n_units )
break;
}
if ( n_devices == 0 )
{
- printf( "No usable devices found!\n" );
+ mbg_log( LOG_WARNING, "No usable device found!" );
goto done;
}
- // Search for devices up to the maximum of supported NTP SHM refclocks
+ // Search for devices up to the maximum of supported number of NTP SHM refclocks
if ( n_devices > MAX_SHM_REFCLOCKS )
n_devices = MAX_SHM_REFCLOCKS;
- syslog( LOG_INFO, "Found %d devices usable for the NTP daemon", n_devices ); //##++++
+ mbg_log( LOG_INFO, "Found %d devices usable for the NTP daemon", n_devices ); //##++++
rc = mbg_get_default_cycles_frequency_from_dev( dhs[0], &cyc_freq );
- if ( mbg_ioctl_err( rc, "mbg_get_default_cycles_frequency_from_dev" ) )
+ if ( mbg_cond_err_msg( rc, "mbg_get_default_cycles_frequency_from_dev" ) )
goto done;
- if ( cyc_freq == 0 )
- printf( "*** Warning: " );
-
- printf( "PC cycles counter clock frequency: %Lu Hz\n",
- (unsigned long long) cyc_freq );
+ mbg_log( LOG_INFO, "%sPC cycles counter clock frequency: %Lu Hz",
+ ( cyc_freq == 0 ) ? "*** Warning: " : "",
+ (unsigned long long) cyc_freq );
// Initialize NTP shared memory area
- ntpshm_init();
- ntpshm_alloc();
+ ntpshm_init( shmTime, n_devices, n_unit0 );
for (;;)
{
for ( i = 0; i < n_devices; i++ )
{
- double ltcy_sec;
- double d_ref_comp;
- MBG_PC_CYCLES ltcy_cyc;
- MBG_PC_CYCLES exec_cyc;
- MBG_PC_CYCLES exec_cyc_limit;
- MBG_PC_CYCLES tmp;
+ MBG_CHK_TIME_INFO cti;
const char *cp;
+ int leap;
- rc = mbg_get_time_info_hrt( dhs[i], &hrti );
+ rc = mbg_chk_time_info( dhs[i], &cti, &filter, 0 ); //##+++++ one or more filter instances ?
- if ( mbg_ioctl_err( rc, "mbg_get_time_info_..." ) )
+ if ( mbg_cond_err_msg( rc, "mbg_chk_time_info" ) )
continue;
+ cp = "";
+ leap = 0;
- p_ref_ts = &hrti.ref_hr_time_cycles.t.tstamp;
- p_ref_cyc = &hrti.ref_hr_time_cycles.cycles;
- p_sys_tic = &hrti.sys_time_cycles;
-
- d_ref = (double) p_ref_ts->sec + ( (double) p_ref_ts->frac ) / (double) PCPS_HRT_BIN_FRAC_SCALE;
- d_sys = (double) p_sys_tic->sys_time.sec + (double) p_sys_tic->sys_time.nsec / 1e9;
-
- ltcy_cyc = mbg_delta_pc_cycles( p_ref_cyc, &p_sys_tic->cyc_after );
- exec_cyc = mbg_delta_pc_cycles( &p_sys_tic->cyc_after, &p_sys_tic->cyc_before );
-
- ltcy_sec = cyc_freq ? ( ( (double) ltcy_cyc ) / (double) cyc_freq ) : 0.0;
-
- // Compensate latencies between time stamps ->
- // normalize ref time to system time stamp
- d_ref_comp = d_ref - ltcy_sec;
-
- exec_cyc_limit = do_filter( &filter, exec_cyc );
-
- // Try to set the limit to 1.7 of the mean execution cycles.
- tmp = ( 7 * exec_cyc_limit ) / 10;
+ if ( ( has_synced_after_reset[i] == 1 ) && ( ( ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_FREER ) == 1 )
+ || ( ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_SYNCD ) == 0 ) ))
+ {
+ struct timespec ts;
- // If execution takes only a few cycles make sure the limit
- // is above the mean number of cycles.
- if ( tmp == 0 )
- tmp++;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
- exec_cyc_limit += tmp;
+ if (ref_trust_time_start[i] == 0 )
+ {
+ mbg_log( LOG_WARNING, "Device #%i, entering holdover mode", i );
+ ref_trust_time_start[i] = ts.tv_sec;
+ ref_trust_time_expire[i] = ts.tv_sec + trust_time_seconds;
+ }
- cp = "";
+ if ( ts.tv_sec > ref_trust_time_expire[i] )
+ {
+ mbg_log( LOG_WARNING, "Device #%i, trust time expired", i );
+ has_synced_after_reset[i] = 0;
+ ref_trust_time_start[i] = 0;
+ ref_trust_time_expire[i] = 0;
+ }
+ }
// check if refclock is sync and if exec time of the system time call was fast enough
- if ( ( exec_cyc <= exec_cyc_limit ) && ( pretend_sync || (
- ( ( hrti.ref_hr_time_cycles.t.status & PCPS_FREER ) == 0 ) &&
- ( ( hrti.ref_hr_time_cycles.t.status & PCPS_SYNCD ) != 0 ) ) ) )
+ if ( ( cti.exec_cyc <= cti.exec_cyc_limit ) && ( pretend_sync || has_synced_after_reset[i] || (
+ ( ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_FREER ) == 0 ) &&
+ ( ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_SYNCD ) != 0 ) ) ) )
{
struct shmTime *p = shmTime[i];
- cp = " *";
-
- // fill SHM structure
- p->count++;
- p->clockTimeStampSec = (time_t) d_ref_comp;
- p->clockTimeStampUSec = (int) ( ( d_ref_comp - p->clockTimeStampSec ) * 1e6 ); // get µs from d_ref
- p->receiveTimeStampSec = (time_t) p_sys_tic->sys_time.sec;
- p->receiveTimeStampUSec = (int) ( p_sys_tic->sys_time.nsec / 1000 );
+ has_synced_after_reset[i] = 1;
- // patch precision value according to the ref time accuracy
- if ( _pcps_is_lwr( &devs[i] ) )
- p->precision = -8;
- else
+ if ( p )
{
- if ( _pcps_is_irig_rx( &devs[i] ) )
+ MBG_SYS_TIME_CYCLES *p_sys_tic = &cti.hrti.sys_time_cycles;
+ cp = " *";
+
+ // fill SHM structure
+ p->count++;
+ p->clockTimeStampSec = (time_t) cti.d_ref_comp;
+ p->clockTimeStampUSec = (int) ( ( cti.d_ref_comp - p->clockTimeStampSec ) * 1e6 ); // get microseconds from d_ref
+ p->receiveTimeStampSec = (time_t) p_sys_tic->sys_time.secs;
+ p->receiveTimeStampUSec = (int) ( p_sys_tic->sys_time.nano_secs / 1000 );
+
+ // These fields are only supported by newer versions of ntpd //##++++++++++++++++++ which versions ?
+ p->clockTimeStampNSec = (int) ( ( cti.d_ref_comp - p->clockTimeStampSec ) * 1e9 ); // get nanoseconds from d_ref
+ p->receiveTimeStampNSec = (int) ( p_sys_tic->sys_time.nano_secs );
+
+ // patch precision value according to the ref time accuracy
+ if ( _pcps_is_lwr( &devs[i] ) )
+ p->precision = -8;
+ else
{
- if ( _pcps_is_usb( &devs[i] ) )
- p->precision = -10;
+ if ( _pcps_is_irig_rx( &devs[i] ) )
+ {
+ if ( _pcps_is_usb( &devs[i] ) )
+ p->precision = -10;
+ else
+ p->precision = -18;
+ }
else
- p->precision = -18;
+ p->precision = -20;
}
- else
- p->precision = -20;
- }
-
- p->count++;
- p->valid = 1;
- }
-
- mbg_snprint_hr_tstamp( ws, sizeof( ws ), p_ref_ts );
- printf( "%-9s: %s: %.7f-%.7f: %+.7f %+.7f, ltcy: ",
- _pcps_type_name( &devs[i] ), ws, d_ref, d_sys,
- d_ref - d_sys, d_ref_comp - d_sys );
+ if ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_LS_ANN_NEG )
+ p->leap = LEAP_DELSECOND;
+ else
+ if ( cti.hrti.ref_hr_time_cycles.t.status & PCPS_LS_ANN )
+ p->leap = LEAP_ADDSECOND;
+ else
+ p->leap = LEAP_NOWARNING;
- if ( cyc_freq != 0 ) // print latency and execution time in microseconds
- {
- double exec_sec = (double) exec_cyc / (double) cyc_freq;
- double exec_sec_limit = (double) exec_cyc_limit / (double) cyc_freq;
+ leap = p->leap; //##+++
- printf( "%.2f us, exec: %.2f us, limit: %.2f us",
- ltcy_sec * 1e6, exec_sec * 1e6, exec_sec_limit * 1e6 );
+ p->count++;
+ p->valid = 1;
+ }
}
- else // print latency and execution time in cycles only
+
+ if ( !quiet )
{
- printf( "%lli cyc, exec: %lli cyc, limit: %lli cyc",
- (long long) ltcy_cyc, (long long) exec_cyc,
- (long long) exec_cyc_limit );
+ snprint_chk_time_info( ws, sizeof( ws ), &cti, &devs[i], frac_digits, print_raw );
+ printf( "%s, leap: %02X%s\n", ws, leap, cp );
}
- printf( "%s\n", cp );
-
usleep( 10 );
}
if ( n_devices > 1 )
- printf("\n");
+ printf( "\n" );
if ( sleep_intv )
sleep( sleep_intv );
@@ -428,8 +317,13 @@ void usage( void )
);
mbg_print_help_options();
mbg_print_opt_info( "-f", "run program in foreground" );
+ mbg_print_opt_info( "-q", "quiet, don't print time differences on stdout" );
+ mbg_print_opt_info( "-r", "print raw time stamps when printing on stdout" );
mbg_print_opt_info( "-s num", "sleep num seconds between calls" );
mbg_print_opt_info( "-p", "pretend device is always synchronized" );
+ mbg_print_opt_info( "-t num", "set num seconds for refclock trust time, default 4 days (345600 seconds)" );
+ mbg_print_opt_info( "-n num", "number of SHM segments to use" );
+ mbg_print_opt_info( "-o num", "SHM segment number offset (default 0)" );
mbg_print_device_options();
puts( "" );
@@ -448,7 +342,7 @@ void startup_daemon( void )
if ( getppid() == 1 )
return; /* already a daemon */
- printf( "Daemon mode, backgrounding ... \n" );
+ mbg_log( LOG_INFO, "Daemon mode, backgrounding" );
i = fork();
if ( i < 0 )
@@ -477,9 +371,9 @@ void startup_daemon( void )
if ( lfp < 0 )
exit( 1 ); /* unable to open lock file */
- if ( lockf( lfp, F_TLOCK, 0 ) < 0 )
+ if ( lockf( lfp, F_TLOCK, 0 ) < 0 )
{
- syslog( LOG_ERR, "Lock file already exists, another instance of this daemon seems to be running" );
+ mbg_log( LOG_ERR, "Lock file already exists, another instance of this daemon seems to be running" );
closelog();
exit( 0 ); /* can not lock */
}
@@ -488,6 +382,8 @@ void startup_daemon( void )
snprintf( str, sizeof( str ), "%d\n", getpid() );
rc = write( lfp, str, strlen( str ) ); /* record pid to lockfile */
+ (void) rc; // avoid warning "set but not used"
+
signal( SIGCHLD, SIG_IGN ); /* ignore child */
signal( SIGTSTP, SIG_IGN ); /* ignore tty signals */
signal( SIGTTOU, SIG_IGN );
@@ -501,12 +397,11 @@ int main( int argc, char *argv[] )
{
int rc;
int c;
- int foreground = 0;
mbg_print_program_info( pname, MBG_MICRO_VERSION, MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
// check command line parameters
- while ( ( c = getopt( argc, argv, "fps:h?" ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "fpqrst:n:o:h?" ) ) != -1 )
{
switch ( c )
{
@@ -518,10 +413,52 @@ int main( int argc, char *argv[] )
pretend_sync = 1;
break;
+ case 'q':
+ quiet++;
+ break;
+
+ case 'r':
+ print_raw = 1;
+ break;
+
case 's':
sleep_intv = atoi( optarg );
break;
+ case 't':
+ {
+ long tt = atol( optarg );
+
+ if ( tt > 0 )
+ trust_time_seconds = tt;
+
+ break;
+ }
+
+ case 'n':
+ n_units = atoi( optarg );
+
+ if ( n_units < 0 || n_units > MAX_SHM_REFCLOCKS )
+ {
+ mbg_log( LOG_WARNING, "Configured number of SHM units %i out of range, truncating to %i",
+ n_units, MAX_SHM_REFCLOCKS );
+ n_units = MAX_SHM_REFCLOCKS;
+ }
+
+ break;
+
+ case 'o':
+ n_unit0 = atoi( optarg );
+
+ if ( n_unit0 < 0 || n_unit0 >= MAX_SHM_UNIT_OFFSET )
+ {
+ mbg_log( LOG_WARNING, "Configured SHM unit offset %i out of range %i to %i, truncating to %i",
+ n_unit0, 0, MAX_SHM_UNIT_OFFSET, 0 );
+ n_unit0 = 0;
+ }
+
+ break;
+
case 'h':
case '?':
default:
@@ -532,7 +469,7 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
if ( foreground == 0 )
@@ -542,12 +479,15 @@ int main( int argc, char *argv[] )
mbg_program_info_str( ws, sizeof( ws ), pname, MBG_MICRO_VERSION,
MBG_FIRST_COPYRIGHT_YEAR, MBG_LAST_COPYRIGHT_YEAR );
- syslog( LOG_INFO, "Starting Meinberg Service Daemon %s", ws );
+ mbg_log( LOG_INFO, "Starting Meinberg Service Daemon %s", ws );
startup_daemon();
}
+ if ( trust_time_seconds )
+ mbg_log( LOG_INFO, "refclock trust time: %ul seconds", trust_time_seconds );
+
rc = do_mbgsvctasks();
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/dist/mbgversion.h b/src/external/bsd/meinberg/dist/mbgversion.h
index a3a3300..f3ef207 100755
--- a/src/external/bsd/meinberg/dist/mbgversion.h
+++ b/src/external/bsd/meinberg/dist/mbgversion.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgversion.h 1.1 2011/07/08 12:09:55 martin TRASH $
+ * $Id: mbgversion.h 1.1.1.1 2017/07/26 14:21:26 martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,13 +10,15 @@
*
* -----------------------------------------------------------------------
* $Log: mbgversion.h $
+ * Revision 1.1.1.1 2017/07/26 14:21:26 martin
+ * Updated copyright year to 2017.
* Revision 1.1 2011/07/08 12:09:55 martin
* Initial revision for pre-release.
*
**************************************************************************/
-#define MBG_CURRENT_COPYRIGHT_YEAR 2011
-#define MBG_CURRENT_COPYRIGHT_YEAR_STR "2011"
+#define MBG_CURRENT_COPYRIGHT_YEAR 2017
+#define MBG_CURRENT_COPYRIGHT_YEAR_STR "2017"
#define MBG_MAJOR_VERSION_CODE 0
#define MBG_MINOR_VERSION_CODE 9
diff --git a/src/external/bsd/meinberg/dist/mbgxhrtime/Makefile b/src/external/bsd/meinberg/dist/mbgxhrtime/Makefile
index 75d6673..a507de6 100755
--- a/src/external/bsd/meinberg/dist/mbgxhrtime/Makefile
+++ b/src/external/bsd/meinberg/dist/mbgxhrtime/Makefile
@@ -1,17 +1,16 @@
#########################################################################
#
-# $Id: Makefile 1.2.1.2.1.1 2010/09/20 12:07:14 stefan TEST $
+# $Id: Makefile 1.3 2017/07/05 18:36:06 martin REL_M $
#
# Description:
# Makefile for mbgxhrtime.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
-# Revision 1.2.1.2.1.1 2010/09/20 12:07:14 stefan
-# Updated for use with latest base Makefile.
-# Revision 1.2.1.2 2010/08/30 09:05:24 martin
-# Revision 1.2.1.1 2010/08/30 08:22:11 martin
+# Revision 1.3 2017/07/05 18:36:06 martin
+# Updated list of object files and use top level
+# Makefile properly.
# Revision 1.2 2009/07/24 10:31:17 martin
# Moved declarations to a common file which is now included.
# Revision 1.1 2008/12/22 11:05:24 martin
@@ -26,7 +25,11 @@ USE_THREAD_API = 1
OBJS = $(TARGET).o
OBJS += mbgdevio.o
+OBJS += timeutil.o
+OBJS += str_util.o
OBJS += toolutil.o
+OBJS += mbgerror.o
+OBJS += cfg_hlp.o
OBJS += gpsutils.o
BASEDIR := ..
diff --git a/src/external/bsd/meinberg/dist/mbgxhrtime/mbgxhrtime.c b/src/external/bsd/meinberg/dist/mbgxhrtime/mbgxhrtime.c
index af26ece..c24b715 100755
--- a/src/external/bsd/meinberg/dist/mbgxhrtime/mbgxhrtime.c
+++ b/src/external/bsd/meinberg/dist/mbgxhrtime/mbgxhrtime.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgxhrtime.c 1.5.1.2 2011/07/05 15:35:56 martin TRASH martin $
+ * $Id: mbgxhrtime.c 1.6 2017/07/05 18:38:18 martin REL_M $
*
* Description:
* Main file for mbgxhrtime program which demonstrates how to retrieve
@@ -41,10 +41,12 @@
*
* -----------------------------------------------------------------------
* $Log: mbgxhrtime.c $
- * Revision 1.5.1.2 2011/07/05 15:35:56 martin
- * Modified version handling.
- * Revision 1.5.1.1 2011/07/05 14:36:11 martin
+ * Revision 1.6 2017/07/05 18:38:18 martin
* New way to maintain version information.
+ * Support build under Windows.
+ * Use more functions from common library modules.
+ * Use codes and inline functions from mbgerror.h.
+ * Proper return codes and exit codes.
* Revision 1.5 2009/09/29 14:25:07 martin
* Display measured and default PC cycles frequency.
* Updated version number to 3.4.0.
@@ -62,23 +64,24 @@
// include Meinberg headers
#include <mbgdevio.h>
-#include <pcpsutil.h>
#include <toolutil.h> // common utility functions
// include system headers
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <sched.h>
+#if !defined( MBG_TGT_WIN32 )
+ #include <unistd.h>
+ #include <pthread.h>
+ #include <sched.h>
+#endif
#if !defined( MBGDEVIO_USE_THREAD_API )
#error Symbol MBGDEVIO_USE_THREAD_API needs to be defined, see the Makefile.
#endif
-#if !defined ( USE_PROCESS_AFFINITY )
+#if !defined( USE_PROCESS_AFFINITY )
#define USE_PROCESS_AFFINITY 1
#endif
@@ -182,7 +185,7 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
rc = mbg_xhrt_poll_thread_create( &poll_thread_info, dh, 0, 0 );
if ( rc != MBG_SUCCESS )
- return -1;
+ return rc;
for (;;)
@@ -216,10 +219,10 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
{
puts( "" );
- printf( "PC cycles freq: %.6f MHz", ( (double) freq_hz ) / 1E6 );
+ printf( "PC cycles freq: %.6f MHz", ( (double) (int64_t) freq_hz ) / 1E6 );
if ( default_freq_hz )
- printf( ", default: %.6f MHz", ( (double) default_freq_hz ) / 1E6 );
+ printf( ", default: %.6f MHz", ( (double) (int64_t) default_freq_hz ) / 1E6 );
printf( "\n" );
@@ -236,10 +239,10 @@ int do_mbgxhrtime( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev )
goto fail;
// compute the latency
- latency = ( (double) cyc_2 - (double) cyc_1 ) / (double) freq_hz * 1E6;
+ latency = ( (double) cyc_2 - (double) cyc_1 ) / (double) (int64_t) freq_hz * 1E6;
// convert to human readable date and time
- mbg_snprint_hr_time( ws, sizeof( ws ), &hrt );
+ mbg_snprint_hr_time( ws, sizeof( ws ), &hrt, 0 ); // raw timestamp?
printf( "t: %s (%.3f us)\n", ws, latency );
if ( this_loops > 0 )
@@ -259,12 +262,12 @@ fail:
done:
mbg_xhrt_poll_thread_stop( &poll_thread_info );
- mbg_close_device( &dh );
-
return rc;
} // do_mbgxhrtime
+static MBG_DEV_HANDLER_FNC do_mbgxhrtime;
+
static /*HDR*/
@@ -322,7 +325,7 @@ int main( int argc, char *argv[] )
if ( must_print_usage )
{
usage();
- return 1;
+ return MBG_EXIT_CODE_USAGE;
}
#if USE_PROCESS_AFFINITY
@@ -330,12 +333,8 @@ int main( int argc, char *argv[] )
puts( "" );
#endif
- // The function below checks which devices have been specified
- // on the command, and for each device
- // - tries to open the device
- // - shows basic device info
- // - calls the function passed as last parameter
- rc = mbg_check_devices( argc, argv, optind, do_mbgxhrtime );
+ // Handle each of the specified devices.
+ rc = mbg_handle_devices( argc, argv, optind, do_mbgxhrtime, 0 );
- return abs( rc );
+ return mbg_rc_is_success( rc ) ? MBG_EXIT_CODE_SUCCESS : MBG_EXIT_CODE_FAIL;
}
diff --git a/src/external/bsd/meinberg/mbgclock/Makefile b/src/external/bsd/meinberg/mbgclock/Makefile
new file mode 100755
index 0000000..85ad982
--- /dev/null
+++ b/src/external/bsd/meinberg/mbgclock/Makefile
@@ -0,0 +1 @@
+.include "Makefile.kmod" \ No newline at end of file
diff --git a/src/external/bsd/meinberg/mbgclock/Makefile.kmod b/src/external/bsd/meinberg/mbgclock/Makefile.kmod
new file mode 100755
index 0000000..0136033
--- /dev/null
+++ b/src/external/bsd/meinberg/mbgclock/Makefile.kmod
@@ -0,0 +1,20 @@
+# $NetBSD: Makefile,v 1.1 2009/02/05 17:32:10 haad Exp $
+
+.include "../Makefile.inc"
+
+.PATH: ${MBG_LIB_COMMON} ${MBG_LIB_BSD}
+
+MKMAN=no
+# CFLAGS+=-D_HAVE_PPS_REF_EVENT -DPPS_SYNC
+
+KMOD= mbgclock
+SRCS= mbgclock_main.c
+SRCS+= pcpsdrvr.c
+SRCS+= identdec.c
+SRCS+= rsrc_bsd.c
+
+.if !defined (MKMODULAR) || ( defined(MKMODULAR) && (${MKMODULAR}!="no") )
+.include <bsd.kmodule.mk>
+.else
+.include <bsd.kmod.mk>
+.endif
diff --git a/src/external/bsd/meinberg/mbgclock/files.mbgclock b/src/external/bsd/meinberg/mbgclock/files.mbgclock
new file mode 100755
index 0000000..94310bc
--- /dev/null
+++ b/src/external/bsd/meinberg/mbgclock/files.mbgclock
@@ -0,0 +1,13 @@
+# $NetBSD: files.drm,v 1.6 2011/02/18 14:26:09 jmcneill Exp $
+
+device mbgclock
+attach mbgclock at pci
+file external/bsd/meinberg/dist/mbglib/bsd/rsrc_bsd.c mbgclock
+file external/bsd/meinberg/dist/mbglib/common/identdec.c mbgclock
+file external/bsd/meinberg/dist/mbglib/common/pcpsdrvr.c mbgclock
+file external/bsd/meinberg/mbgclock/mbgclock_main.c mbgclock
+
+makeoptions mbgclock CPPFLAGS+="-I$S/external/bsd/meinberg/dist/mbglib/common"
+makeoptions mbgclock CPPFLAGS+="-I$S/external/bsd/meinberg/dist/mbglib/bsd"
+
+
diff --git a/src/external/bsd/meinberg/mbgclock/mbgclock_main.c b/src/external/bsd/meinberg/mbgclock/mbgclock_main.c
new file mode 100755
index 0000000..1eafb29
--- /dev/null
+++ b/src/external/bsd/meinberg/mbgclock/mbgclock_main.c
@@ -0,0 +1,1134 @@
+/*
+ * $Header: /repository/clkdrv/bsd/netbsd/soft/mbgtools-nbsd/mbgclock/RCS/mbgclock_main.c 1.1.1.13 2017/07/26 15:25:56 martin TEST $
+ *
+ * NetBSD Meinberg mbgclock driver, Frank Kardel
+ *
+ * $Created: Sat Mar 26 15:03:37 2011 $
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/lwp.h>
+#include <sys/callout.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/fcntl.h>
+#include <sys/kauth.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcivar.h>
+#include <sys/timetc.h>
+#include <sys/timepps.h>
+#include <sys/errno.h>
+#include <sys/atomic.h>
+
+#ifdef MBG_DEBUG
+ #define DEBUG MBG_DEBUG
+#endif
+
+#include <pcpsdrvr.h>
+#include <mbgddmsg.h>
+
+#ifndef PCI_BAR
+#define PCI_BAR(__n) (0x10 + 4 * (__n))
+#endif
+
+#define REV_NUM 0x100
+#define REV_NUM_STR "1.00"
+#define MBG_COPYRIGHT "(c) Meinberg 2011"
+#define MBG_DRVR_NAME "mbgclock"
+#define MBG_VENDOR "Meinberg Funkuhren"
+
+const char pcps_driver_name[] = MBG_DRVR_NAME;
+
+static MBG_DBG_DATA mbg_dbg_data;
+static MBG_DBG_PORT mbg_dbg_port = 0x378 + 0; //##++
+static PCPS_IO_ADDR_MAPPED mbg_dbg_port_mapped; //##++
+static PCPS_DRVR_INFO drvr_info = { REV_NUM, 0, MBG_DRVR_NAME " radio clock driver" };
+
+#ifndef MBG_PCPS_FMT_STATUS
+#define MBG_PCPS_FMT_STATUS "\177\20b\0FREER\0b\1DL_ENB\0b\2SYNCD\0b\3DL_ANN\0b\4UTC\0b\5LS_ANN\0b\6IFTM\0b\7INVT\0b\x08LS_ENB\0b\11ANT_FAIL\0b\x0aLS_ANN_NEG\0b\x0bSCALE_GPS\0b\x0cSCALE_TAI\0\0"
+#endif
+
+#include <macioctl.h>
+
+static dev_type_open(mbgclockopen);
+static dev_type_close(mbgclockclose);
+static dev_type_read(mbgclockread);
+static dev_type_write(mbgclockwrite);
+static dev_type_ioctl(mbgclockioctl);
+static int mbgclock_match(device_t, cfdata_t, void *);
+static void mbgclock_attach(device_t, device_t, void *);
+static int mbgclock_detach(device_t, int);
+static void mbgclock_tick(void *);
+static timecounter_get_t mbgclock_get_timecount;
+
+struct mbgclock_softc
+{
+ device_t dev; /* device backling */
+ struct pci_attach_args pa; /* attach argument */
+ int isopen; /* openflag */
+ PCPS_DDEV *pddev; /* driver handle */
+ struct pps_state pps_state; /* pps state */
+ kmutex_t mutex; /* callout termination */
+ callout_t callout; /* callout structure */
+ PCPS_TIME_STATUS_X last_status; /* last device status */
+ struct timecounter tc; /* timecounter - if available */
+};
+
+#define MBG_UNITBITS 6 /* up to 64 devices */
+#define MBG_UNITMASK ((1<<MBG_UNITBITS)-1)
+#define MBG_UNIT(x) (minor(x) & MBG_UNITMASK)
+#define MBG_UNITTYPE(x) (minor(x) >> MBG_UNITBITS)
+
+const struct cdevsw mbgclock_cdevsw = {
+ .d_open = mbgclockopen,
+ .d_close = mbgclockclose,
+ .d_read = mbgclockread,
+ .d_write = mbgclockwrite,
+ .d_ioctl = mbgclockioctl,
+ .d_stop = nostop,
+ .d_tty = notty,
+ .d_poll = nopoll,
+ .d_mmap = nommap,
+ .d_kqfilter = nokqfilter,
+ D_OTHER|D_MPSAFE
+};
+
+#ifdef CFATTACH_DECL3_NEW
+CFATTACH_DECL3_NEW(mbgclock,
+ sizeof(struct mbgclock_softc),
+ mbgclock_match,
+ mbgclock_attach,
+ mbgclock_detach,
+ NULL,
+ NULL,
+ NULL,
+ DVF_DETACH_SHUTDOWN);
+#else
+CFATTACH_DECL2_NEW(mbgclock,
+ sizeof(struct mbgclock_softc),
+ mbgclock_match,
+ mbgclock_attach,
+ mbgclock_detach,
+ NULL,
+ NULL,
+ NULL);
+#endif
+
+extern struct cfdriver mbgclock_cd;
+
+#undef DEBUG /* XXX for now */
+
+#if defined( MBG_DEBUG )
+int debug = MBG_DEBUG;
+#endif
+
+#if defined( DEBUG )
+static int mbgclockdebug = ~0;
+#define DB_FOLLOW 0x00000001
+#define DPRINTF(_X_, _Y_) do { \
+ if (mbgclockdebug & (_X_)) { \
+ printf _Y_; \
+ } \
+ } \
+ while (/*CONST_COND*/0)
+#else
+#define DPRINTF(_X_, _Y_) /* empty */
+#endif
+
+/*----- loadables -----*/
+#if defined (_LKM) || defined(_MODULE)
+
+static volatile uint32_t opencount = 0; /* number of open char drivers */
+#define INC_REF atomic_inc_32(&opencount)
+#define DEC_REF atomic_dec_32(&opencount)
+
+CFDRIVER_DECL(mbgclock, DV_DULL, NULL);
+
+static int mbgclock_loc[] = { -1, -1 };
+
+static struct cfparent pciparent = {
+ "pci", "pci", DVUNIT_ANY
+};
+
+static struct cfdata mbgclock_cfdata[] = {
+ {
+ .cf_name = "mbgclock",
+ .cf_atname = "mbgclock",
+ .cf_unit = 0,
+ .cf_fstate = FSTATE_STAR,
+ .cf_loc = mbgclock_loc,
+ .cf_flags = 0,
+ .cf_pspec = &pciparent,
+ },
+ { NULL }
+};
+#else
+#define INC_REF
+#define DEC_REF
+#endif
+
+/*----- module -----*/
+#ifdef _MODULE
+
+#include <sys/module.h>
+
+MODULE(MODULE_CLASS_DRIVER, mbgclock, NULL);
+
+static int
+mbgclock_modcmd(modcmd_t cmd, void *arg)
+{
+ int bmajor = -1, cmajor = -1, error = 0;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ DPRINTF(DB_FOLLOW, ("%s: MOD_CMD_INIT\n", mbgclock_cd.cd_name));
+
+ error = config_cfdriver_attach(&mbgclock_cd);
+ if (error)
+ break;
+
+ error = config_cfattach_attach(mbgclock_cd.cd_name, &mbgclock_ca);
+ if (error) {
+ config_cfdriver_detach(&mbgclock_cd);
+ aprint_error("%s: unable to register cfattach\n",
+ mbgclock_cd.cd_name);
+ break;
+ }
+
+ /* s = splaudio(); */
+ error = config_cfdata_attach(mbgclock_cfdata, 1);
+ /* splx(s); */
+
+ if (error == 0)
+ {
+ error = devsw_attach("mbgclock", NULL, &bmajor,
+ &mbgclock_cdevsw, &cmajor);
+ }
+
+ if (error) {
+ config_cfattach_detach(mbgclock_cd.cd_name, &mbgclock_ca);
+ config_cfdriver_detach(&mbgclock_cd);
+ break;
+ } else {
+ DPRINTF(DB_FOLLOW, ("%s: registered character major = %d\n",
+ mbgclock_cd.cd_name, cmajor));
+ }
+
+ break;
+
+ case MODULE_CMD_FINI:
+ DPRINTF(DB_FOLLOW, ("%s: MOD_CMD_FINI\n", mbgclock_cd.cd_name));
+
+ if (opencount) {
+ error = EBUSY;
+ break;
+ }
+
+ error = config_cfdata_detach(mbgclock_cfdata);
+ if (error)
+ break;
+
+ error = config_cfattach_detach(mbgclock_cd.cd_name, &mbgclock_ca);
+ if (error)
+ break;
+
+ config_cfdriver_detach(&mbgclock_cd);
+ devsw_detach(NULL, &mbgclock_cdevsw);
+ break;
+
+ case MODULE_CMD_STAT:
+ error = ENOTTY;
+ break;
+
+ default:
+ error = ENOTTY;
+ break;
+ }
+
+ DPRINTF(DB_FOLLOW, ("modcmd rc = %d\n", error));
+
+ return error;
+}
+#endif
+
+/*------ LKM -----*/
+#if defined(_LKM) && !defined(_MODULE)
+
+#include <sys/lkm.h>
+
+int mbgclock_lkmentry(struct lkm_table *, int, int);
+
+static struct cfdriver *mbgclock_cfdrivers[] = {
+ &mbgclock_cd,
+ NULL
+};
+static struct cfattach *mbgclock_cfattachs[] = {
+ &mbgclock_ca,
+ NULL
+};
+static const struct cfattachlkminit mbgclock_cfattachinit[] = {
+ { "mbgclock", mbgclock_cfattachs },
+ { NULL }
+};
+
+MOD_DRV("mbgclock",
+ mbgclock_cfdrivers,
+ mbgclock_cfattachinit,
+ mbgclock_cfdata);
+
+static int
+mbgclock_lkmload(struct lkm_table *lkm, int cmd)
+{
+ int bmajor = -1;
+ int cmajor = -1;
+ int error;
+
+ error = devsw_attach("mbgclock", NULL, &bmajor,
+ &mbgclock_cdevsw, &cmajor);
+
+#ifdef DEBUG
+ if (error == 0) {
+ DPRINTF(DB_FOLLOW, ("%s: registered character major = %d\n",
+ mbgclock_cd.cd_name, cmajor));
+ } else {
+ DPRINTF(DB_FOLLOW, ("%s: device driver registry failed errno = %d\n",
+ mbgclock_cd.cd_name, error));
+ }
+#endif
+ return error;
+}
+
+static int
+mbgclock_lkmunload(struct lkm_table *lkm, int cmd)
+{
+ if (opencount)
+ return EBUSY;
+
+ devsw_detach(NULL, &mbgclock_cdevsw);
+ return 0;
+}
+
+int
+mbgclock_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
+{
+ DISPATCH(lkmtp, cmd, ver, mbgclock_lkmload, mbgclock_lkmunload, lkm_nofunc);
+}
+#endif
+
+/*----- autoconf -----*/
+
+/* PCI Support Functions */
+
+static void
+mbg_deallocate_resource( BSD_RSRC_INFO *p_ri )
+{
+ if ( p_ri->valid )
+ {
+ bus_space_unmap( p_ri->bst, p_ri->bsh, p_ri->size);
+ p_ri->valid = 0;
+ }
+}
+
+/*
+ * deallocate resources
+ */
+static void
+mbg_dealloc_rsrcs( struct mbgclock_softc *psc )
+{
+ PCPS_DDEV *pddev = psc->pddev;
+
+/* mbg_deallocate_resource( device, &prsrci->irq.bsd, SYS_RES_IRQ ); */
+
+ if ( pddev != NULL )
+ {
+ PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info;
+ int i;
+
+ for ( i = 0; i < N_PCPS_MEM_RSRC; i++ )
+ mbg_deallocate_resource( &prsrci->mem[i].bsd );
+
+ for ( i = 0; i < N_PCPS_PORT_RSRC; i++ )
+ mbg_deallocate_resource( &prsrci->port[i].bsd );
+ }
+}
+
+static void
+mbg_alloc_rsrc( struct mbgclock_softc *psc , int reg, BSD_RSRC_INFO *p_ri, int type )
+{
+ p_ri->reg = reg;
+ p_ri->type = type;
+
+ if (!pci_mapreg_map(&psc->pa, reg, type, 0,
+ &p_ri->bst, &p_ri->bsh,
+ &p_ri->base, &p_ri->size))
+ {
+ p_ri->valid = 1;
+ } else {
+ p_ri->valid = 0;
+ }
+}
+
+static void
+mbg_alloc_rsrcs( struct mbgclock_softc *psc )
+{
+ PCPS_DDEV *pddev = psc->pddev;
+ PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info;
+ BSD_RSRC_INFO ri;
+ int bar;
+
+ /* clear valid flags */
+ for ( bar = 0; bar < prsrci->num_rsrc_io; bar ++)
+ prsrci->port[bar].bsd.valid = 0;
+
+ for ( bar = 0; bar < prsrci->num_rsrc_mem; bar ++)
+ prsrci->mem[bar].bsd.valid = 0;
+
+ for ( bar = 0; bar < 6; bar ++ )
+ {
+ int type;
+ int reg = PCI_BAR( bar );
+
+ _mbgddmsg_4( MBG_DBG_INIT_DEV,
+ "%s: alloc I/O range %i: PCI device 0x%04X:0x%04X supported",
+ pcps_driver_name, bar, PCI_VENDOR(psc->pa.pa_id),
+ PCI_PRODUCT(psc->pa.pa_id) );
+
+ switch ((type = pci_mapreg_type(psc->pa.pa_pc, psc->pa.pa_tag, reg)))
+ {
+ case PCI_MAPREG_TYPE_IO:
+ if ( prsrci->num_rsrc_io < N_PCPS_PORT_RSRC )
+ {
+ mbg_alloc_rsrc( psc, reg, &ri, type );
+
+ if ( ri.valid )
+ {
+ prsrci->port[prsrci->num_rsrc_io].bsd = ri;
+ pcps_add_rsrc_io( pddev, ri.base, ri.size );
+ continue;
+ }
+ else
+ {
+ _mbgddmsg_2( MBG_DBG_INIT_DEV,
+ "%s: alloc I/O range %i failed",
+ pcps_driver_name, bar );
+ }
+ }
+ break;
+
+ case PCI_MAPREG_MEM_TYPE_64BIT:
+#if __LP64__
+#if 0
+ aprint_error_dev(psc->dev,
+ "WARNING: ignoring 64-bit BAR @ 0x%02x\n", reg);
+ continue;
+#endif
+#else
+ /*FALLTHROUGH*/
+#endif
+ case PCI_MAPREG_TYPE_MEM:
+ /* case PCI_MAPREG_TYPE_ROM: currently same as above */
+ if ( prsrci->num_rsrc_mem < N_PCPS_MEM_RSRC )
+ {
+ mbg_alloc_rsrc( psc, reg, &ri, type );
+
+ if ( ri.valid )
+ {
+ prsrci->mem[prsrci->num_rsrc_mem].bsd = ri;
+ pcps_add_rsrc_mem( pddev,
+ (MBG_MEM_ADDR)bus_space_vaddr( ri.bst, ri.bsh),
+ ri.size );
+ continue;
+ }
+ }
+ break;
+
+ default:
+ printf("XXX unsupported type from pci_mapreg_type: %d\n", type);
+ break;
+ }
+ }
+
+ /* single IRQ resource */
+#if 0 /* currently not used / required */
+ mbg_alloc_rsrc( device, 0, &ri, SYS_RES_IRQ, RF_SHAREABLE | RF_ACTIVE );
+
+ if ( ri.res )
+ {
+ prsrci->port[prsrci->num_rsrc_irq].bsd = ri;
+ pcps_add_rsrc_irq( pddev, rman_get_start( ri.res ) );
+ }
+#endif
+
+}
+
+static int
+mbgclock_match(struct device *parent, struct cfdata *match, void *aux)
+{
+ struct pci_attach_args *pa;
+ int16_t vend_id;
+ int16_t dev_id;
+
+ DPRINTF(DB_FOLLOW, ("mbgclock_match(0x%p, 0x%p, 0x%p)\n", parent, match, aux));
+
+ pa = aux;
+ vend_id = PCI_VENDOR(pa->pa_id);
+ dev_id = PCI_PRODUCT(pa->pa_id);
+
+ if (vend_id == PCI_VENDOR_MEINBERG)
+ {
+ PCPS_DEV_TYPE *pdt;
+
+ pdt = pcps_get_dev_type_table_entry( PCPS_BUS_PCI, dev_id );
+
+ if (pdt != NULL)
+ {
+ _mbgddmsg_3( MBG_DBG_INIT_DEV,
+ "%s: probe: PCI device 0x%04X:0x%04X supported",
+ pcps_driver_name, vend_id, dev_id );
+
+ return 1;
+ }
+ }
+
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s: probe: PCI device 0x%04X:0x%04X not supported",
+ pcps_driver_name, vend_id, dev_id );
+ return 0;
+}
+
+
+static void
+mbgclock_attach(struct device *parent, struct device *self, void *aux)
+{
+ int rc = 0;
+ int idx;
+ char devinfo[256];
+ struct mbgclock_softc *psc = device_private(self);
+ struct pci_attach_args *pa = aux;
+ uint16_t dev_id = PCI_PRODUCT(pa->pa_id);
+
+ DPRINTF(DB_FOLLOW, ("mbgclock_attach(0x%p, 0x%p, 0x%p)\n", parent, self, aux));
+
+ psc->dev = self;
+ psc->pa = *pa;
+ psc->last_status = 0;
+
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: attach for device 0x%04X",
+ pcps_driver_name, dev_id );
+
+ psc->pddev = pcps_alloc_ddev();
+
+ if ( psc->pddev == NULL )
+ {
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: attach device 0x%04X: pcps_alloc_ddev() failed",
+ pcps_driver_name, dev_id );
+ goto fail;
+ }
+
+ rc = pcps_init_ddev( psc->pddev, PCPS_BUS_PCI, dev_id );
+
+ if ( rc != PCPS_SUCCESS )
+ {
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s: attach device 0x%04X: pcps_init_ddev() failed, rc: %i",
+ pcps_driver_name, dev_id, rc );
+ goto fail;
+ }
+
+ mbg_alloc_rsrcs( psc );
+
+ rc = pcps_probe_device( psc->pddev, 0, 0 );
+
+ if ( rc != PCPS_SUCCESS )
+ {
+ _mbgddmsg_3( MBG_DBG_INIT_DEV, "%s: attach device 0x%04X: pcps_probe_device() failed, rc: %i",
+ pcps_driver_name, dev_id, rc );
+ goto fail;
+ }
+
+ idx = snprintf(devinfo, sizeof(devinfo) - idx, "%s", _pcps_type_name( &psc->pddev->dev ) );
+
+ if ( strlen( _pcps_sernum( &psc->pddev->dev ) ) &&
+ strcmp( _pcps_sernum( &psc->pddev->dev ), "N/A" ) )
+ idx += snprintf(devinfo + idx, sizeof(devinfo) - idx, " %s", _pcps_sernum( &psc->pddev->dev ) );
+
+ idx += snprintf(devinfo + idx, sizeof(devinfo) - idx, " (FW %X.%02X",
+ _pcps_fw_rev_num_major( _pcps_fw_rev_num( &psc->pddev->dev ) ),
+ _pcps_fw_rev_num_minor( _pcps_fw_rev_num( &psc->pddev->dev ) )
+ );
+
+ if ( _pcps_has_asic_version( &psc->pddev->dev ) )
+ {
+ PCI_ASIC_VERSION av;
+ av = _convert_asic_version_number( psc->pddev->raw_asic_version );
+
+ idx += snprintf(devinfo + idx, sizeof(devinfo) - idx, ", ASIC %X.%02X",
+ _pcps_asic_version_major( av ),
+ _pcps_asic_version_minor( av )
+ );
+ }
+
+ idx += snprintf(devinfo + idx, sizeof(devinfo) - idx, ")" );
+
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: device 0x%04X attached successfully",
+ pcps_driver_name, dev_id );
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
+ aprint_normal(": "MBG_VENDOR" %s (rev. 0x%02x)\n", devinfo,
+ PCI_REVISION(pa->pa_class));
+
+ mutex_init(&psc->mutex, MUTEX_DEFAULT, IPL_HIGH);
+
+ psc->isopen = 0;
+
+ /*
+ * prepare timecounter - to have a clean state
+ */
+ psc->tc.tc_get_timecount = mbgclock_get_timecount;
+ psc->tc.tc_poll_pps = NULL;
+ psc->tc.tc_counter_mask = ~(uint)0;
+ /* actually 10 MHz as fraction counter covering 2^32 ticks */
+ psc->tc.tc_frequency = 0x100000000ULL;
+ psc->tc.tc_name = NULL; /* NULL -> not enabled */
+ psc->tc.tc_quality = -10000;
+ psc->tc.tc_priv = psc;
+ psc->tc.tc_next = NULL;
+
+ /* if we have a counter source register the timecounter */
+ if (_pcps_ddev_has_fast_hr_timestamp( psc->pddev )) {
+ psc->tc.tc_name = device_xname( psc->dev );
+
+ tc_init(&psc->tc);
+ }
+
+ callout_init(&psc->callout, CALLOUT_MPSAFE);
+
+ return;
+
+fail:
+ pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
+
+ aprint_normal(": %s (rev. 0x%02x) - not supported\n", devinfo,
+ PCI_REVISION(pa->pa_class));
+
+ mbg_dealloc_rsrcs( psc );
+
+ if ( psc->pddev != NULL )
+ pcps_free_ddev( psc->pddev );
+
+ psc->pddev = NULL;
+
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: failed to attach device 0x%04X",
+ pcps_driver_name, dev_id );
+ return;
+}
+
+static int
+mbgclock_detach(struct device *self, int flags)
+{
+ struct mbgclock_softc *psc = device_private(self);
+ PCPS_DDEV *pddev;
+ uint16_t dev_id;
+
+ DPRINTF(DB_FOLLOW, ("mbgclock_detach(0x%p, 0x%x)\n", self, flags));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ (void)callout_halt(&psc->callout, &psc->mutex);
+
+ if (psc->tc.tc_name != NULL) {
+ tc_detach(&psc->tc);
+ psc->tc.tc_name = NULL;
+ }
+
+ pddev = psc->pddev;
+
+ dev_id = PCI_PRODUCT(psc->pa.pa_id);
+
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: detach for device 0x%04X",
+ pcps_driver_name, dev_id );
+
+ /* XXX insure not outstanding requests */
+ mbg_dealloc_rsrcs( psc );
+
+ if ( psc->pddev != NULL ) {
+ pcps_free_ddev( psc->pddev );
+ pmf_device_deregister(self);
+ }
+
+ psc->pddev = NULL;
+
+ _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: device 0x%04X detached",
+ pcps_driver_name, dev_id );
+
+ callout_destroy(&psc->callout);
+
+ mutex_destroy(&psc->mutex);
+
+ return 0;
+}
+
+/*------- driver -------*/
+
+static
+int mbgclockopen(dev_t dev, int flags, int mode, struct lwp *l)
+{
+ struct mbgclock_softc *psc = device_lookup_private(&mbgclock_cd, MBG_UNIT(dev));
+ PCPS_DDEV *pddev;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: open called", pcps_driver_name );
+ DPRINTF(DB_FOLLOW, ("mbgclockopen(0x%"PRIx64", 0x%x, 0x%x, %p)\n", dev, flags, mode, l));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ pddev = psc->pddev;
+
+ if (pddev == NULL)
+ return ENXIO;
+
+ mutex_enter(&psc->mutex);
+ if (!psc->isopen) {
+ DPRINTF(DB_FOLLOW, ("mbgclockopen(0x%"PRIx64", 0x%x, 0x%x, %p): first open\n", dev, flags, mode, l));
+ psc->isopen = 1;
+
+ INC_REF;
+
+ /* Clear PPS capture state on first open. */
+ mutex_spin_enter(&timecounter_lock);
+ memset(&psc->pps_state, 0, sizeof(psc->pps_state));
+ psc->pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
+ pps_init(&psc->pps_state);
+ mutex_spin_exit(&timecounter_lock);
+
+ callout_reset(&psc->callout, hz, mbgclock_tick, psc);
+ }
+ mutex_exit(&psc->mutex);
+
+ return 0;
+}
+
+static
+int mbgclockclose(dev_t dev, int flags, int mode, struct lwp *l)
+{
+ struct mbgclock_softc *psc = device_lookup_private(&mbgclock_cd, MBG_UNIT(dev));
+ PCPS_DDEV *pddev;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: close called", pcps_driver_name );
+ DPRINTF(DB_FOLLOW,("mbgclockclose(0x%"PRIx64", 0x%x, 0x%x, %p)\n", dev, flags, mode, l));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ pddev = psc->pddev;
+
+ if (pddev == NULL)
+ return ENXIO;
+
+ mutex_enter(&psc->mutex);
+ psc->isopen = 0;
+ DEC_REF;
+ callout_stop(&psc->callout);
+ mutex_exit(&psc->mutex);
+
+ return 0;
+}
+
+static
+int mbgclockread(dev_t dev, struct uio *uio, int flags)
+{
+ struct mbgclock_softc *psc = device_lookup_private(&mbgclock_cd, MBG_UNIT(dev));
+ PCPS_DDEV *pddev;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: read called", pcps_driver_name );
+ DPRINTF(DB_FOLLOW,("mbgclockread(0x%"PRIx64", %p)\n", dev, uio));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ pddev = psc->pddev;
+
+ if (pddev == NULL)
+ return ENXIO;
+
+ return 0;
+}
+
+static
+int mbgclockwrite(dev_t dev, struct uio *uio, int flags)
+{
+ struct mbgclock_softc *psc = device_lookup_private(&mbgclock_cd, MBG_UNIT(dev));
+ PCPS_DDEV *pddev;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: write called", pcps_driver_name );
+ DPRINTF(DB_FOLLOW, ("mbgclockwrite(0x%"PRIx64", %p)\n", dev, uio));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ pddev = psc->pddev;
+
+ if (pddev == NULL)
+ return ENXIO;
+
+ return 0;
+}
+
+#include <sys/ioctl.h>
+
+static
+int mbgclockioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
+{
+ struct mbgclock_softc *psc = device_lookup_private(&mbgclock_cd, MBG_UNIT(dev));
+ PCPS_DDEV *pddev;
+ int rc;
+
+ _mbgddmsg_1( MBG_DBG_INIT_DEV, "%s: ioctl called", pcps_driver_name );
+ DPRINTF(DB_FOLLOW, ("mbgclockioctl(0x%"PRIx64", 0x%lx, %p, 0x%x, %p)\n",
+ dev, cmd, data, flag, l->l_proc));
+
+ if (psc == NULL)
+ return ENXIO;
+
+ pddev = psc->pddev;
+
+ if (pddev == NULL)
+ return ENXIO;
+
+ switch ( cmd )
+ {
+ case PPS_IOC_CREATE: /* handle PPSAPI */
+ case PPS_IOC_DESTROY:
+ case PPS_IOC_GETPARAMS:
+ case PPS_IOC_SETPARAMS:
+ case PPS_IOC_GETCAP:
+ case PPS_IOC_FETCH:
+#ifdef PPS_SYNC
+ case PPS_IOC_KCBIND:
+#endif
+ mutex_spin_enter(&timecounter_lock);
+
+ rc = pps_ioctl(cmd, data, &psc->pps_state);
+
+ if ((rc == 0) &&
+ (psc->pps_state.kcmode & PPS_CAPTUREBOTH) &&
+ (!_pcps_ddev_has_hr_time( psc->pddev ))) {
+ psc->pps_state.kcmode = 0;
+ mutex_spin_exit(&timecounter_lock);
+
+ aprint_error_dev(psc->dev,
+ "ioctl(KCBIND): high resolution time stamping not supported\n");
+ rc = EOPNOTSUPP;
+ } else {
+ mutex_spin_exit(&timecounter_lock);
+ }
+
+ break;
+
+ default: /* handle clock ioctls */
+ {
+ /* Find out which privilege level is required to execute this IOCTL command. */
+ int priv_lvl = ioctl_get_required_privilege( cmd );
+
+ /* Check if the calling process has the required privilege. */
+ switch ( priv_lvl )
+ {
+ case MBG_REQ_PRIVL_NONE:
+ /* Always allow. */
+ break;
+
+ case MBG_REQ_PRIVL_EXT_STATUS:
+ /* This may require some privilege for the calling process. */
+ if ((flag & FREAD) == 0 ||
+ kauth_authorize_device_passthru(l->l_cred,
+ dev,
+ KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READ,
+ &cmd))
+ {
+ _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: READ/PASSTHRU READ permission denied, dev %s_%s",
+ pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ return EPERM;
+ }
+ break;
+
+ case MBG_REQ_PRIVL_CFG_READ:
+ /* This may require some privilege for the calling process. */
+ if ((flag & FREAD) == 0 ||
+ kauth_authorize_device_passthru(l->l_cred,
+ dev,
+ KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF,
+ &cmd))
+ {
+ _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: READ/PASSTHRU_READCONF permission denied, dev %s_%s",
+ pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ return EPERM;
+ }
+ break;
+
+ case MBG_REQ_PRIVL_SYSTEM:
+ if ((flag & FWRITE) == 0 ||
+ kauth_authorize_device_passthru(l->l_cred,
+ dev,
+ KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITE,
+ &cmd))
+ {
+ _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: WRTIE/PASSTHRU_WRITE permission denied, dev %s_%s",
+ pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ return EPERM;
+ }
+ break;
+
+ case MBG_REQ_PRIVL_CFG_WRITE:
+ if ((flag & FWRITE) == 0 ||
+ kauth_authorize_device_passthru(l->l_cred,
+ dev,
+ KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITECONF,
+ &cmd))
+ {
+ _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: WRITE/PASSTHRU_WRITECONF permission denied, dev %s_%s",
+ pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ return EPERM;
+ }
+ break;
+
+ default:
+ _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: unknown, permission denied, dev %s_%s",
+ pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ return EPERM;
+ }
+
+ /*
+ * now do the actual work - access the device
+ */
+ rc = ioctl_switch( pddev, cmd, (void *) data, (void *) data );
+
+ /* On success we return quickly.*/
+
+ if ( rc != MBG_SUCCESS )
+ {
+ /* An error has occurred. */
+ /* Generate an appropriate debug/error message */
+ /* and return an error status. */
+
+ switch ( rc )
+ {
+ case MBG_ERR_INV_DEV_REQUEST:
+ _mbgddmsg_7( MBG_DBG_WARN, "%s: %d,%d ioctl 0x%04lX: invalid cmd %04lX, dev %s_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, IOCBASECMD( cmd ),
+ _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = EINVAL;
+ break;
+
+
+ case MBG_ERR_NOT_SUPP_BY_DEV:
+ _mbgddmsg_6( MBG_DBG_WARN, "%s: %d,%d ioctl 0x%02lX: not supported by dev %s_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = ENODEV;
+ break;
+
+
+ case MBG_ERR_NO_MEM:
+ _mbgddmsg_6( MBG_DBG_WARN, "%s: %d,%d ioctl 0x%02lX: unable to allocate buffer for dev %s_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = ENOMEM;
+ break;
+
+
+ case MBG_ERR_IRQ_UNSAFE:
+ _mbgddmsg_6( MBG_DBG_DETAIL, "%s: %d,%d ioctl 0x%02lX: busy since unsafe IRQ enabled, dev %s_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = EBUSY;
+ break;
+
+
+ default: /* any access error code returned by the low level routine */
+ /* or copying from or to user space */
+ _mbgddmsg_7( MBG_DBG_WARN, "%s: %d,%d ioctl 0x%02lX: error %i accessing dev %s_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, rc, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = EIO;
+ }
+ } else {
+ _mbgddmsg_6( MBG_DBG_INFO, "%s: %d,%d IOCTL 0x%02lX: success, dev %p_%s",
+ pcps_driver_name, major(dev), minor(dev), cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) );
+ rc = 0;
+ }
+ }
+ }
+
+ DPRINTF(DB_FOLLOW, ("mbgclockioctl(0x%"PRIx64", 0x%lx, %p, 0x%x, %p) return rc=\n",
+ dev, cmd, data, flag, l->l_proc, rc));
+
+ return rc;
+}
+
+static uint
+mbgclock_get_timecount(struct timecounter *tc)
+{
+ struct mbgclock_softc *psc = tc->tc_priv;
+ PCPS_TIME_STAMP ref_ts;
+ int s;
+
+ /* pick up reference counter */
+ /*
+ * XXX for now this counter is NOT free running and
+ * may be re-set at any time - so this is only proof
+ * of concept code until Meinberg devices provide
+ * a truely free running counter hanging off the
+ * frequency controlled oscillator
+ * also we should only pick up the fraction part saving
+ * a PCIe bus transaction and change the coordination
+ * scheme to a generation number base one
+ */
+ s = splhigh();
+ /*
+ * XXX splhigh() shouldn't be necessary,
+ * but ci_curspl seems to be high after following call
+ */
+ /*
+ * we only need the fraction
+ * do_get_fast_hr_timestamp_fraction_safe( psc->pddev, &ref_ts );
+ */
+ do_get_fast_hr_timestamp_safe( psc->pddev, &ref_ts );
+ splx(s);
+
+ /*
+ * format is correct as it is a fraction counter thus
+ * our 'frequency' is nominally 0x100000000 Hz
+ */
+ return ref_ts.frac;
+}
+
+static void
+mbgclock_tick(void *arg)
+{
+ struct mbgclock_softc *psc = arg;
+ struct timeval tv;
+
+ /*
+ * TODO: should trigger poll machine
+ */
+
+#ifdef _HAVE_PPS_REF_EVENT
+ /* start work only of we need to provide PPS simulation */
+ if (psc->pps_state.ppsparam.mode & PPS_CAPTUREBOTH) {
+ do {
+ int rc;
+ struct pps_state *pps = &psc->pps_state;
+ struct bintime bintime_ref_ts;
+ PCPS_HR_TIME ht;
+ PCPS_TIME_STAMP ref_ts;
+ int valid;
+
+ if (!_pcps_ddev_has_fast_hr_timestamp( psc->pddev )) {
+ /*
+ * pick up status and PPS simulated time stamps
+ * from HR_TIME operation
+ */
+ mutex_spin_enter(&timecounter_lock);
+
+ /* pick up first system timestamp */
+ pps_capture(&psc->pps_state); /* picks up capcount + th */
+
+ _pcps_sem_inc( psc->pddev );
+ rc = _pcps_read_var( psc->pddev, PCPS_GIVE_HR_TIME, ht );
+ _pcps_sem_dec( psc->pddev );
+
+ valid = (rc == MBG_SUCCESS) &&
+ !((ht.status & (PCPS_INVT|PCPS_IFTM|PCPS_FREER) != 0) ||
+ ((ht.status & PCPS_SYNCD) == 0));
+
+ /* process reftime (picks up second system timestamp) */
+ if (valid) {
+ bintime_ref_ts.sec = ref_ts.sec;
+ bintime_ref_ts.frac = (uint64_t)ref_ts.frac << 32;
+
+ pps_ref_event(&psc->pps_state,
+ (psc->pps_state.ppsparam.mode & PPS_CAPTUREASSERT) ?
+ PPS_CAPTUREASSERT : PPS_CAPTURECLEAR,
+ &bintime_ref_ts);
+ }
+
+ mutex_spin_exit(&timecounter_lock);
+ } else {
+ /* pick up fast time stamp when clock is ok */
+
+ _pcps_sem_inc( psc->pddev );
+ rc = _pcps_read_var( psc->pddev, PCPS_GIVE_HR_TIME, ht );
+ _pcps_sem_dec( psc->pddev );
+
+ valid = (rc == MBG_SUCCESS) &&
+ !((ht.status & (PCPS_INVT|PCPS_IFTM|PCPS_FREER) != 0) ||
+ ((ht.status & PCPS_SYNCD) == 0));
+
+ if (valid) {
+ mutex_spin_enter(&timecounter_lock);
+
+ /* pick up first system timestamp */
+ pps_capture(&psc->pps_state); /* picks up capcount + th */
+
+ /* pick up reference time */
+ do_get_fast_hr_timestamp_safe( psc->pddev, &ref_ts );
+
+ bintime_ref_ts.sec = ref_ts.sec;
+ bintime_ref_ts.frac = (uint64_t)ref_ts.frac << 32;
+
+ /* process reftime (picks up second system timestamp) */
+ pps_ref_event(&psc->pps_state,
+ (psc->pps_state.ppsparam.mode & PPS_CAPTUREASSERT) ?
+ PPS_CAPTUREASSERT : PPS_CAPTURECLEAR,
+ &bintime_ref_ts);
+
+ mutex_spin_exit(&timecounter_lock);
+ }
+ }
+
+ /* leave when we cannot the the timestamp */
+ if ( rc != MBG_SUCCESS ) {
+ aprint_error_dev(psc->dev,
+ "clock read failed\n");
+ break;
+ }
+
+ /* document status changes */
+ if (!valid) {
+ if (ht.status != psc->last_status) {
+ char b[80];
+ snprintb(b, sizeof b, MBG_PCPS_FMT_STATUS, ht.status);
+
+ aprint_error_dev(psc->dev,
+ "clock nut synchronized: Status=%s\n",
+ b);
+ /* XXX kill timecounter - only needed while counter is linked to time */
+ if (psc->tc.tc_name != NULL) {
+ tc_gonebad(&psc->tc);
+ }
+ }
+ psc->last_status = ht.status;
+
+ break;
+ }
+
+ if ((ht.status ^ psc->last_status) &
+ (PCPS_INVT|PCPS_IFTM|PCPS_FREER|PCPS_SYNCD)) {
+ char b[80];
+
+ snprintb(b, sizeof b, MBG_PCPS_FMT_STATUS, ht.status);
+ aprint_error_dev(psc->dev,
+ "clock synchronized: Status=%s\n",
+ b);
+ }
+
+ psc->last_status = ht.status;
+ } while (0); /* for break instead of goto */
+ }
+#endif
+
+ /*
+ * calculate next callout shortly after next second
+ */
+ microtime(&tv);
+ callout_schedule(&psc->callout, hz - mstohz(tv.tv_usec / 1000));
+}