diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2011-05-06 12:01:00 +0200 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2011-05-06 12:01:00 +0200 |
commit | 89b44c58a33547e6bd2e202b6a031e3c94bbcbb6 (patch) | |
tree | db1ccb51d76335689bf26e19aa315a331b84ce6b | |
parent | 13fbb36ec8d403c68cb85d86650c2d0b5ff4f0c7 (diff) | |
download | mbgtools-fbsd-89b44c58a33547e6bd2e202b6a031e3c94bbcbb6.tar.gz mbgtools-fbsd-89b44c58a33547e6bd2e202b6a031e3c94bbcbb6.zip |
Update some files to current versionsmbgtools-fbsd-dev-2011-05-06
Also account for renamed mbgclock_main.c.
-rwxr-xr-x | Makefile | 2 | ||||
-rwxr-xr-x | mbgclock/Makefile | 5 | ||||
-rwxr-xr-x | mbgclock/mbgclock_main.c | 4 | ||||
-rwxr-xr-x | mbgctrl/Makefile | 9 | ||||
-rwxr-xr-x | mbgctrl/mbgctrl.c | 1027 | ||||
-rwxr-xr-x | mbgirigcfg/mbgirigcfg.c | 2 | ||||
-rwxr-xr-x | mbglib/common/gpsdefs.h | 1225 | ||||
-rwxr-xr-x | mbglib/common/lan_util.c | 197 | ||||
-rwxr-xr-x | mbglib/common/lan_util.h | 138 | ||||
-rwxr-xr-x | mbglib/common/macioctl.h | 88 | ||||
-rwxr-xr-x | mbglib/common/mbg_arch.h | 5 | ||||
-rwxr-xr-x | mbglib/common/mbg_tgt.h | 6 | ||||
-rwxr-xr-x | mbglib/common/mbgdevio.c | 144 | ||||
-rwxr-xr-x | mbglib/common/mbgdevio.h | 96 | ||||
-rwxr-xr-x | mbglib/common/mbgerror.h | 31 | ||||
-rwxr-xr-x | mbglib/common/mbgioctl.h | 24 | ||||
-rwxr-xr-x | mbglib/common/mbgmutex.h | 259 | ||||
-rwxr-xr-x | mbglib/common/mbgtime.h | 13 | ||||
-rwxr-xr-x | mbglib/common/parmpcps.h | 8 | ||||
-rwxr-xr-x | mbglib/common/pci_asic.h | 71 | ||||
-rwxr-xr-x | mbglib/common/pcpsdefs.h | 74 | ||||
-rwxr-xr-x | mbglib/common/pcpsdev.h | 50 | ||||
-rwxr-xr-x | mbglib/common/pcpsdrvr.c | 41 | ||||
-rwxr-xr-x | mbglib/common/pcpsdrvr.h | 125 | ||||
-rwxr-xr-x | mbglib/common/usbdefs.h | 11 | ||||
-rwxr-xr-x | mbglib/common/words.h | 13 | ||||
-rwxr-xr-x | mbgstatus/Makefile | 9 | ||||
-rwxr-xr-x | mbgstatus/mbgstatus.c | 32 |
28 files changed, 2587 insertions, 1122 deletions
@@ -1,7 +1,7 @@ ######################################################################### # -# $Id: Makefile 1.1.1.6 2011/03/25 11:05:55 martin TRASH $ +# $Id: Makefile 1.1.1.6 2011/03/25 11:05:55 martin TRASH martin $ # # Description: # Makefile for mbgtools which recurses into the subdirectories. diff --git a/mbgclock/Makefile b/mbgclock/Makefile index 7dd2450..51475e0 100755 --- a/mbgclock/Makefile +++ b/mbgclock/Makefile @@ -1,7 +1,7 @@ ######################################################################### # -# $Id: Makefile 1.1.1.4 2011/02/03 14:10:39 martin TEST martin $ +# $Id: Makefile 1.1.1.5 2011/05/06 14:12:02 martin TRASH $ # # Description: # Makefile for mbgclock driver to support Meinberg bus level @@ -9,6 +9,7 @@ # # ----------------------------------------------------------------------- # $Log: Makefile $ +# Revision 1.1.1.5 2011/05/06 14:12:02 martin # Revision 1.1.1.4 2011/02/03 14:10:39 martin # Revision 1.1.1.3 2011/01/26 17:38:58 martin # Add support for DEBUG build. @@ -35,7 +36,7 @@ CFLAGS= -I$(MBGLIB_COMMON) -I$(MBGLIB_BSD) CFLAGS+= -D DEBUG=$(DEBUG) .endif -SRCS= mbgdrvr.c +SRCS= mbgclock_main.c SRCS+= pcpsdrvr.c SRCS+= identdec.c SRCS+= rsrc_bsd.c diff --git a/mbgclock/mbgclock_main.c b/mbgclock/mbgclock_main.c index e2f968c..bde66cc 100755 --- a/mbgclock/mbgclock_main.c +++ b/mbgclock/mbgclock_main.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgdrvr.c 1.1.1.11.1.3 2011/03/25 11:06:27 martin TRASH martin $ + * $Id: mbgclock_main.c 1.1.1.11.1.3 2011/03/25 11:06:27 martin TRASH martin $ * * Description: * Main file for for mbgclock driver to support Meinberg bus level @@ -13,7 +13,7 @@ * Based on FreeBSD's mypci.c sample program by Murray Stokely. * * ----------------------------------------------------------------------- - * $Log: mbgdrvr.c $ + * $Log: mbgclock_main.c $ * Revision 1.1.1.11.1.3 2011/03/25 11:06:27 martin * Fixed typo. * Revision 1.1.1.11.1.2 2011/03/23 16:49:53 martin diff --git a/mbgctrl/Makefile b/mbgctrl/Makefile index e485fc0..01e3abf 100755 --- a/mbgctrl/Makefile +++ b/mbgctrl/Makefile @@ -1,13 +1,17 @@ ######################################################################### # -# $Id: Makefile 1.7.1.2 2010/08/30 09:05:22 martin TEST $ +# $Id: Makefile 1.7.1.2.1.2 2011/04/20 09:34:06 martin TRASH $ # # 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.7 2009/07/24 10:31:16 martin @@ -27,7 +31,7 @@ ######################################################################### TARGET = mbgctrl -INST_DIR = /usr/local/sbin +INST_TO_SBIN = 1 # By default these tools only need a simple set of mbgdevio API # functions, but here we use all API calls. @@ -40,6 +44,7 @@ OBJS += gpsutils.o OBJS += pcpsutil.o OBJS += parmgps.o OBJS += parmpcps.o +OBJS += lan_util.o BASEDIR := .. include $(BASEDIR)/Makefile diff --git a/mbgctrl/mbgctrl.c b/mbgctrl/mbgctrl.c index d7c6d9f..f13fc15 100755 --- a/mbgctrl/mbgctrl.c +++ b/mbgctrl/mbgctrl.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgctrl.c 1.22.1.5 2011/03/21 08:32:18 martin TRASH $ + * $Id: mbgctrl.c 1.22.1.7.1.15 2011/05/04 14:53:18 martin TRASH $ * * Description: * Main file for mbgctrl program which sends commands and @@ -9,6 +9,27 @@ * * ----------------------------------------------------------------------- * $Log: mbgctrl.c $ + * 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 @@ -35,9 +56,9 @@ * Revision 1.17 2009/06/19 12:38:51 martin * Updated version number to 3.2.0. * Revision 1.16 2009/06/18 15:14:53 martin - * Added command TZOFFS which can be used to set TZDL to UTC, and then - * configure the standard TZDL offset to a dedicated number of seconds, to the - * output time has a configurable UTC offset against the time derived from the + * Added command TZOFFS which can be used to set TZDL to UTC, and then + * configure the standard TZDL offset to a dedicated number of seconds, to the + * output time has a configurable UTC offset against the time derived from the * input signal. * Revision 1.15 2009/03/20 11:53:19 martin * Updated version number to 3.1.0. @@ -47,7 +68,7 @@ * Updated description, copyright, revision number and string. * Use unified functions from toolutil module. * Accept device name(s) on the command line. - * Don't use printf() without format, which migth produce warnings + * Don't use printf() without format, which migth produce warnings * with newer gcc versions. * Revision 1.13 2008/11/07 10:25:49 martin * Support modification of a card's ENABLE_FLAGS. @@ -87,7 +108,7 @@ * **************************************************************************/ -// include Meinberg headers +// include Meinberg headers #include <mbgdevio.h> #include <pcpsmktm.h> #include <pcpsutil.h> @@ -97,6 +118,7 @@ #include <gpsutils.h> #include <cnv_wday.h> #include <toolutil.h> +#include <lan_util.h> // include system headers #include <stdio.h> @@ -112,31 +134,34 @@ static const char *pcopyright = "(c) Meinberg 2001-2009"; static char *dev_name; +static int err_unicast_nsupp; +static const char str_unknown[] = "(unknown)"; + static TZDL tzdl_utc = DEFAULT_TZDL_UTC; static TZDL tzdl_cet_cest = DEFAULT_TZDL_CET_CEST_EN; static TZDL tzdl_eet_eest = DEFAULT_TZDL_EET_EEST_EN; static long max_tzdl_offs = 0x7FFFFFFFL; // max val for int32_t -static const char *tz_info_utc = TZ_INFO_UTC; -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 tz_info_utc[] = TZ_INFO_UTC; +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; #define _get_time_scale_name( _i ) \ - ( ( (_i) < N_MBG_TIME_SCALE ) ? time_scale_name[_i] : "(unknown)" ) + ( ( (_i) < N_MBG_TIME_SCALE ) ? time_scale_name[_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_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_ptp = "does not provide PTP"; -static const char *no_cab_len = "does not support antenna signal delay compensation"; +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_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_ptp[] = "does not provide PTP"; +static const char no_cab_len[] = "does not support antenna signal delay compensation"; typedef struct { @@ -147,9 +172,9 @@ typedef struct #define N_EF_INFO 3 -static const char *ef_name_serial = "SERIAL"; -static const char *ef_name_pulses = "PULSES"; -static const char *ef_name_synth = "SYNTH"; +static const char ef_name_serial[] = "SERIAL"; +static const char ef_name_pulses[] = "PULSES"; +static const char ef_name_synth[] = "SYNTH"; typedef struct @@ -160,23 +185,43 @@ typedef struct #define N_IP4_INFO 4 -static const char *ip4_name_ip = "IP"; -static const char *ip4_name_nm = "NM"; -static const char *ip4_name_ba = "BA"; -static const char *ip4_name_gw = "GW"; +static const char ip4_name_ip[] = "IP"; +static const char ip4_name_nm[] = "NM"; +static const char ip4_name_ba[] = "BA"; +static const char ip4_name_gw[] = "GW"; + +static const char ptp_name_net[] = "NP"; +static const char ptp_name_del[] = "DM"; +static const char ptp_name_dom[] = "DO"; +static const char ptp_name_v1[] = "HW"; + +static const char ptp_name_role[] = "ROLE"; + +static const char ptp_name_gm_ip[] = "GMIP"; +static const char ptp_name_gm_id[] = "GMID"; +static const char ptp_name_tp_id[] = "PID"; +static const char ptp_name_dur[] = "DUR"; +static const char ptp_name_sr[] = "SR"; +static const char ptp_name_ar[] = "AR"; +static const char ptp_name_dr[] = "DR"; + +//##+++++ +static const char *delay_mech[] = PTP_DELAY_MECH_NAMES; +static const char *network_prot[] = PTP_NW_PROT_STRS; +static const char *network_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; + +// 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 ) \ + ( ( (_i) < N_PTP_ROLES ) ? ptp_roles[_i] : str_unknown ) + +#define _ptp_role_name_short( _i ) \ + ( ( (_i) < N_PTP_ROLES ) ? ptp_roles_short[_i] : str_unknown ) -static const char *ptp_name_net = "NP"; -static const char *ptp_name_del = "DM"; -static const char *ptp_name_dom = "DO"; -static const char *ptp_name_v1 = "HW"; -static const char *ptp_name_gm_ip = "GMIP"; -static const char *ptp_name_gm_id = "GMID"; -static const char *ptp_name_tp_id = "PID"; -static const char *ptp_name_dur = "DUR"; -static const char *ptp_name_sr = "SR"; -static const char *ptp_name_ar = "AR"; -static const char *ptp_name_dr = "DR"; static /*HDR*/ @@ -295,7 +340,7 @@ int set_tzdl_offs( MBG_DEV_HANDLE dh, const char *s ) if ( labs( tzdl_offs ) > max_tzdl_offs ) // max val for int32_t { - fprintf( stderr, "** Time zone offset %li exceeds range (%li..%li)\n", + fprintf( stderr, "** Time zone offset %li exceeds range (%li..%li)\n", tzdl_offs, -max_tzdl_offs, max_tzdl_offs ); return MBG_ERR_CFG; } @@ -309,152 +354,151 @@ int set_tzdl_offs( MBG_DEV_HANDLE dh, const char *s ) static /*HDR*/ -int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr ) +int show_lan_intf( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info ) { - int n; - - n = snprintf( s, max_len, "%i.%i.%i.%i", - BYTE_OF( *addr, 3 ), - BYTE_OF( *addr, 2 ), - BYTE_OF( *addr, 1 ), - BYTE_OF( *addr, 0 ) - ); - - return n; - -} // snprint_ip4_addr + IP4_SETTINGS ip4_settings; + char ws[256]; + int rc = mbg_get_ip4_settings( dh, &ip4_settings ); + if ( mbg_ioctl_err( rc, "mbg_get_ip4_settings" ) ) + return rc; -/*HDR*/ -const char *str_to_ip4_addr( IP4_ADDR *p, const char *s ) -{ - IP4_ADDR tmp_ip4_addr = 0; - char *cp; - int i; + printf( "On-board LAN interface settings:" ); - for ( i = 0, cp = (char *) s; ; ) + if ( ip4_settings.flags & IP4_MSK_DHCP ) + printf( " (DHCP client)\n" ); + else { - unsigned long ul = strtoul( cp, &cp, 10 ); - - if ( ul > 255 ) // invalid number - return NULL; + printf( "\n" ); - tmp_ip4_addr |= ul << ( 8 * (3 - i) ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.ip_addr, NULL ); + printf( " IP Address: %s\n", ws ); - if ( ++i >= 4 ) - break; // done + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.netmask, NULL ); + printf( " Net Mask: %s\n", ws ); - if ( *cp != '.' ) - return NULL; // invalid string format, dot expected + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.broad_addr, NULL ); + printf( " Broadcast Addr: %s\n", ws ); - cp++; // skip dot + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.gateway, NULL ); + printf( " Gateway: %s\n", ws ); } - if ( p ) - *p = tmp_ip4_addr; + return MBG_SUCCESS; + +} // show_lan_intf + - return cp; // success -} // str_to_ip4_addr +//##+++++++++++++++ +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; static /*HDR*/ -int show_lan_intf( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info ) +int mbg_get_all_ptp_cfg_info( MBG_DEV_HANDLE dh, ALL_PTP_CFG_INFO *p ) { - IP4_SETTINGS ip4_settings; - char ws[256]; + int rc; - int rc = mbg_get_ip4_settings( dh, &ip4_settings ); + memset( p, 0, sizeof( *p ) ); - if ( mbg_ioctl_err( rc, "mbg_get_ip4_settings" ) ) - return rc; + rc = mbg_get_ptp_cfg_info( dh, &p->ptp_cfg_info ); - printf( "On-board LAN interface settings:" ); + if ( mbg_ioctl_err( rc, "mbg_get_ptp_cfg_info" ) ) + goto ret; - if ( ip4_settings.flags & IP4_MSK_DHCP ) - printf( " (DHCP client)\n" ); - else + + if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) { - printf( "\n" ); + rc = mbg_get_ptp_uc_master_cfg_limits( dh, &p->ptp_uc_master_cfg_limits ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.ip_addr ); - printf( " IP Address: %s\n", ws ); + if ( mbg_ioctl_err( rc, "mbg_get_ptp_uc_master_cfg_limits" ) ) + goto ret; - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.netmask ); - printf( " Net Mask: %s\n", ws ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.broad_addr ); - printf( " Broadcast Addr: %s\n", ws ); + 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; + } - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.gateway ); - printf( " Gateway: %s\n", ws ); + + rc = mbg_get_all_ptp_uc_master_info( dh, p->all_ptp_uc_master_info, &p->ptp_uc_master_cfg_limits ); + + if ( mbg_ioctl_err( rc, "mbg_get_all_ptp_uc_master_info" ) ) + goto ret; } - return MBG_SUCCESS; +ret: + return rc; -} // show_lan_intf +} // mbg_get_all_ptp_cfg_info static /*HDR*/ int show_ptp_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info ) { - PTP_CFG_INFO ptp_settings; - PTP_UNICAST_CFG_INFO ptp_unicast_settings; - - const char* delay_mech[] = PTP_DELAY_MECH_NAMES; - const char* network_prot[] = PTP_NW_PROT_STRS; - const char* network_prot_short[] = PTP_NW_PROT_STRS_SHORT; - const char* ptp_roles[] = PTP_ROLE_STRS; - - int supports_unicast = 0; - - int rc = mbg_get_ptp_cfg_info( dh, &ptp_settings ); + ALL_PTP_CFG_INFO all_ptp_cfg_info; + char ws[256]; + int unicast_supported; + int idx; - if ( mbg_ioctl_err( rc, "mbg_get_ptp_cfg_info" ) ) + int rc = mbg_get_all_ptp_cfg_info( dh, &all_ptp_cfg_info ); + + if ( rc < 0 ) return rc; - supports_unicast = ptp_settings.supported_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST; + unicast_supported = ( all_ptp_cfg_info.ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) != 0; printf( "\nPTP configuration:\n"); - supports_unicast ? printf( " PTP Role : %s\n", ptp_roles[ptp_settings.settings.ptp_role] ) : - printf( " PTP Role : %s\n", ptp_roles[0] ); + idx = all_ptp_cfg_info.ptp_cfg_info.settings.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.network_protocol; + printf( " Network Protocol: %s (%s)\n", network_prot_short[idx], network_prot[idx] ); - printf( " Network Protocol: %s (%s)\n", network_prot_short[ptp_settings.settings.network_protocol], network_prot[ptp_settings.settings.network_protocol] ); - printf( " Delay Mechanism : %s\n", delay_mech[ptp_settings.settings.delay_mechanism] ); - printf( " Domain Number : %d\n", ptp_settings.settings.domain_number ); - printf( " V1 HW Compat. : %d\n", ( ptp_settings.settings.flags & PTP_CFG_MSK_V1_HW_COMPAT ) ? 1:0 ); - - if ( supports_unicast ) + 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 ); + + if ( unicast_supported ) { + PTP_UC_MASTER_CFG_LIMITS *p_uc_limits = &all_ptp_cfg_info.ptp_uc_master_cfg_limits; int i; - - int rc = mbg_get_ptp_unicast_cfg_info( dh, &ptp_unicast_settings); - - if ( mbg_ioctl_err( rc, "mbg_get_ptp_unicast_cfg_info" ) ) - return rc; - printf( "\nPTP Unicast configuration:\n"); - printf( " GM Host: %s\n", ptp_unicast_settings.settings.gm_host); - - printf( " GM Clock ID: "); - for ( i = 0; i < 8; i++ ) + for ( i = 0; i < p_uc_limits->n_supp_master; i++ ) { - printf( "%02X", ptp_unicast_settings.settings.gm_clock_id.b[i] ); - if ( i < 7 ) - printf(":"); - } - - printf("\n"); - - printf( " GM Port ID: %d\n\n", ptp_unicast_settings.settings.gm_port_id ); - printf( " Sync Msg Interval [2^x s]: %i\n", ptp_unicast_settings.settings.sync_interval ); - printf( " Ann. Msg Interval [2^x s]: %i\n", ptp_unicast_settings.settings.announce_interval ); - printf( " DelReq Msg Interval [2^x s]: %i\n", ptp_unicast_settings.settings.delay_request_interval ); - printf( " Message Duration: %i s\n", ptp_unicast_settings.settings.message_duration ); + PTP_UC_MASTER_SETTINGS *p = &all_ptp_cfg_info.all_ptp_uc_master_info[i].info.settings; + + printf( "\nPTP unicast master" ); + + if ( p_uc_limits->n_supp_master > 1 ) + printf( " %i", i ); + + 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 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 ); + } + } return MBG_SUCCESS; @@ -463,339 +507,452 @@ int show_ptp_cfg( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info ) +static /*HDR*/ +/** + * @brief Lookup a string in a string table and return the table index + * + * @param s The string to be searched for in the string table + * @param tbl A table of strings to be searched + * @param n_entries The number of strings in the string table + * @param supp_mask A string with a given index is only supported if the + * corresponding bit is set in this mask. + * @param info A descriptive name of the parameter which is to be + * set to the index of the searched string + * + * @return >=0 A valid, supported table index + * <0 Unknown or unsupported parameter + */ +int get_chk_str_table_idx( const char *s, const char *tbl[], int n_entries, + uint32_t supp_mask, const char *info ) +{ + int i; + const char *cp; + + for ( i = 0; i < n_entries; i++ ) + { + cp = tbl[i]; + + if ( strncmp( s, cp, strlen( cp ) ) == 0 ) + if ( supp_mask & ( 1UL << i ) ) + return i; + } + + printf( "error: %s %s\n", + ( i == n_entries ) ? "unknown" : "unsupported", + info ); + + return -3; + +} // get_chk_str_table_idx + + static /*HDR*/ -int set_ptp_cfg( MBG_DEV_HANDLE dh, const char *arg, const PCPS_DEV *p_dev ) +/** + * @brief Lookup a parameter in an argument list and check if a colon is appended + * + * @param arg An argument list of the form: "name:val,name:val,..." + * @param s A parameter name searched for in the argument list + * @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. + */ +int chk_parm_name( const char *arg, const char *id, char **p ) +{ + char *cp = strstr( arg, id ); + + if ( cp ) + { + cp += strlen( id ); + + if ( *cp != ':' ) + return -1; + + cp++; + } + + if ( p ) + *p = cp; // may be NULL + + return 0; + +} // chk_parm_name + + + +static /*HDR*/ +/** + * @brief Lookup a parameter in an argument list and check if the value string is valid + * + * This function expects that the parameter value is a known string which can + * be found in a table of known strings. A bit mask indicates if a string with + * a given table index is supported, or not. + * + * @param arg An argument list of the form: "name:val,name:val,..." + * @param id The name of the argument to be checked. + * @param tbl A table of strings with predefined parameter values + * @param n_entries The number of strings in the string table + * @param supp_mask A string with a given index is only supported if the + * corresponding bit is set in this mask. + * @param info A descriptive name of the parameter which is to be + * set to the index of the searched string + * + * @return >=0 A valid, supported table index + * -1 Parameter not found + * -2 Unknown or unsupported parameter, or syntax error + */ +int chk_tbl_parm( const char *arg, const char *id, const char *tbl[], + int n_entries, uint32_t supp_mask, const char *info ) { - PTP_CFG_INFO prv_ptp_settings; - PTP_CFG_SETTINGS ptp_settings; - PTP_UNICAST_CFG_INFO prv_ptp_unicast_settings; - PTP_UNICAST_CFG_SETTINGS ptp_unicast_settings; - char *cp; - int l; + int rc = chk_parm_name( arg, id, &cp ); - int supports_unicast = 0; - - int rc = mbg_get_ptp_cfg_info( dh, &prv_ptp_settings); + if ( rc < 0 ) + return -2; - if ( mbg_ioctl_err( rc, "mbg_get_ptp_cfg_info" ) ) - return rc; - - supports_unicast = prv_ptp_settings.supported_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST; - - if ( supports_unicast ) - { - int rc = mbg_get_ptp_unicast_cfg_info( dh, &prv_ptp_unicast_settings); - - if ( mbg_ioctl_err( rc, "mbg_get_ptp_unicast_cfg_info" ) ) - return rc; - - memcpy( &ptp_unicast_settings, &prv_ptp_unicast_settings.settings, sizeof(ptp_unicast_settings) ); - } - - memcpy( &ptp_settings, &prv_ptp_settings.settings, sizeof(ptp_settings) ); - - - // Network protocol - cp = strstr( arg, ptp_name_net ); - - if ( cp != NULL ) + if ( cp == NULL ) + return -1; + + rc = get_chk_str_table_idx( cp, tbl, n_entries, supp_mask, info ); + + if ( rc < 0 ) + return -2; + + return rc; + +} // chk_tbl_parm + + + +static /*HDR*/ +/** + * @brief Lookup an int16_t parameter in an argument list + * + * Check and save the numeric parameter if in a valid range. + * + * @param arg An argument list of the form: "name:val,name:val,..." + * @param id The name of the argument to be checked. + * @param p A pointer to a variable where the parameter value is + * saved if valid + * @param range_min The minimum allowed value for the parameter + * @param range_max The maximum allowed value for the parameter + * @param is_supported A flag indicating if the parameter is actually supported + * @param info A descriptive name of the parameter + * + * @return >=0 A valid, supported table index + * -1 Parameter not found, or out of range + */ +int chk_int16_parm( const char *arg, const char *id, int16_t *p, int16_t range_min, + int16_t range_max, int is_supported, const char *info ) +{ + char *cp; + int idx = chk_parm_name( arg, id, &cp ); + + if ( idx < 0 ) // parameter error + return -1; + + if ( cp ) // parameter found { - l = strlen(ptp_name_net); - - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - if ( strstr( (cp+l) , "IP4" ) != 0 ) - ptp_settings.network_protocol = PTP_NW_PROT_BIT_UDP_IPV4; - else if ( strstr( (cp+l) , "ETH" ) != 0 ) - ptp_settings.network_protocol = PTP_NW_PROT_BIT_IEEE_802_3; - else - { - printf("error: Invalid or unsupported network protocol type!\n"); - goto fail; - } + if ( !is_supported ) + err_unicast_nsupp = 1; + else + { + int16_t tmp = atoi( cp ); + + 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; + } + + *p = tmp; + printf( " setting %s: %i\n", info, tmp ); + } } - + + return 0; + +} // chk_int16_parm + + + +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 prv_all_ptp_cfg_info; + PTP_CFG_INFO *p_info; + PTP_CFG_SETTINGS *p_settings; + PTP_UC_MASTER_CFG_LIMITS *p_uc_limits; + PTP_UC_MASTER_INFO *p_uc_info; + PTP_UC_MASTER_SETTINGS *p_uc_settings; + uint32_t supp_mask; + IP4_ADDR ip4addr; + char ws[256]; + char *cp; + int idx; + int unicast_supported; + int uc_master_idx = 0; + int16_t tmp_int16; + + int rc = mbg_get_all_ptp_cfg_info( dh, &all_ptp_cfg_info ); + + if ( rc < 0 ) + return rc; // failed to read current settings and capabilities + + + err_unicast_nsupp = 0; + + // save a copy of the current settings + prv_all_ptp_cfg_info = all_ptp_cfg_info; + + p_info = &all_ptp_cfg_info.ptp_cfg_info; + p_settings = &p_info->settings; + 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; + p_uc_settings = &p_uc_info->settings; + + + // Network protocol + idx = chk_tbl_parm( arg, ptp_name_net, network_prot_short, N_PTP_NW_PROT, p_info->supp_network_prot, "network protocol type" ); + + if ( idx >= 0 ) // valid parameter found + p_settings->network_protocol = idx; + else + if ( idx < -1 ) + goto fail; + + // Delay Mechanism - cp = strstr( arg, ptp_name_del ); - - if ( cp != NULL ) - { - l = strlen(ptp_name_del); - - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - if ( strstr( (cp+l) , "E2E" ) != 0 ) - ptp_settings.delay_mechanism = PTP_DELAY_MECH_BIT_E2E; - else if ( strstr( (cp+l) , "P2P" ) != 0 ) - ptp_settings.delay_mechanism = PTP_DELAY_MECH_BIT_P2P; - else - { - printf("error: Invalid delay mechanism\n"); - goto fail; - } - } - + idx = chk_tbl_parm( arg, ptp_name_del, delay_mech, N_PTP_DELAY_MECH, p_info->supp_delay_mech, "delay mechanism" ); + + if ( idx >= 0 ) // valid parameter found + p_settings->delay_mech = idx; + else + if ( idx < -1 ) + goto fail; + + // Domain Number - cp = strstr( arg, ptp_name_dom ); - - if ( cp != NULL ) + idx = chk_parm_name( arg, ptp_name_dom, &cp ); + + if ( idx < 0 ) // parameter error + goto fail; + + if ( cp ) // parameter found { - l = strlen(ptp_name_dom); - - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - ptp_settings.domain_number = atoi( cp+l ); + idx = atoi( cp ); + //##+++++ must check range!! + p_settings->domain_number = idx; } - + + // V1 Hardware compatibility flag - cp = strstr( arg, ptp_name_v1 ); - - if ( cp != NULL ) - { - l = strlen(ptp_name_v1); - - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - if( atoi( cp+l) == 1 ) - ptp_settings.flags |= PTP_CFG_MSK_V1_HW_COMPAT; - else if( atoi( cp+l) == 0 ) - ptp_settings.flags &= ~PTP_CFG_MSK_V1_HW_COMPAT; - else - { - printf("error: No valid V1 HWC settings!\n"); - goto fail; - } - } - - if ( supports_unicast ) + idx = chk_parm_name( arg, ptp_name_v1, &cp ); + + if ( idx < 0 ) // parameter error + goto fail; + + if ( cp ) // parameter found { - - // PTP role - cp = strstr( arg, "ROLE" ); - - if ( cp != NULL ) + idx = atoi( cp ); + + switch ( idx ) { - l = strlen("ROLE"); + case 0: + p_settings->flags &= ~PTP_CFG_MSK_V1_HW_COMPAT; + break; - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - if ( strstr( (cp+l) , "UCS" ) != 0 ) - ptp_settings.ptp_role = PTP_ROLE_UNICAST_SLAVE; - else - ptp_settings.ptp_role = PTP_ROLE_MULTICAST_SLAVE; + case 1: + p_settings->flags |= PTP_CFG_MSK_V1_HW_COMPAT; + break; + + default: + printf( "error: No valid V1 HWC settings!\n" ); + goto fail; } + } - - // GM Host - // (currently IP addresses accepted only) ##++ - cp = strstr( arg, ptp_name_gm_ip ); - - if ( cp != NULL ) - { - IP4_ADDR ip4addr; - l = strlen(ptp_name_gm_ip); + //---- unicast stuff ---- - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - if ( str_to_ip4_addr( &ip4addr, cp+l ) != NULL ) + // PTP role + supp_mask = _get_supp_ptp_role_idx_msk( 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 + { + if ( !unicast_supported ) + err_unicast_nsupp = 1; + else + p_settings->ptp_role = idx; + } + else + if ( idx < -1 ) // parameter error + goto fail; + + + // GM Host + idx = chk_parm_name( arg, ptp_name_gm_ip, &cp ); + + if ( idx < 0 ) // parameter error + goto fail; + + if ( cp ) // parameter found + { + if ( !unicast_supported ) + err_unicast_nsupp = 1; + else + { + // currently IP addresses are accepted only, so check for + // a valid IPv4 address + if ( str_to_ip4_addr( &ip4addr, cp ) ) { - char ws[50]; - - snprint_ip4_addr( ws, sizeof( ws ), &ip4addr ); - printf( " GM IP Address: %s\n", ws ); - - strcpy( ptp_unicast_settings.gm_host, ws ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4addr, NULL ); + printf( " GM IP Address: %s\n", ws ); + + memset( p_uc_settings->gm_host, 0, sizeof( p_uc_settings->gm_host ) ); + strcpy( p_uc_settings->gm_host, ws ); } + else + goto fail; } - + } - // GM Clock ID - cp = strstr( arg, ptp_name_gm_id ); - - if ( cp != NULL ) - { - int i = 0; - char* p_tail; - - l = strlen(ptp_name_gm_id); - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - - l++; - - for ( i= 0; i < sizeof( ptp_unicast_settings.gm_clock_id ); i++ ) - { - if ( (*(cp+l+i) == 0) || (*(cp+l+i) == ',') ) - break; - - if ( *(cp+l+i) == ':' ) - { - l++; - continue; - } - - ptp_unicast_settings.gm_clock_id.b[i] = strtoul( (cp+l+i), &p_tail, 16 ); - - if ( p_tail == cp ) // no number found - goto fail; - - l+=2; - } - - - if ( i != sizeof( ptp_unicast_settings.gm_clock_id ) ) + // GM Clock ID + idx = chk_parm_name( arg, ptp_name_gm_id, &cp ); + + if ( idx < 0 ) // parameter error + goto fail; + + if ( cp ) // parameter found + { + if ( !unicast_supported ) + err_unicast_nsupp = 1; + else + { + PTP_CLOCK_IDENTITY gm_clock_id; + idx = str_to_octets( gm_clock_id.b, sizeof( gm_clock_id.b ), cp ); + + if ( idx != sizeof( gm_clock_id ) ) { - printf("Syntax error in specifying GM Clock ID\n"); - goto fail; + printf( "Syntax error in specified GM Clock ID\n" ); + goto fail; } else { - printf( " setting GM Clock ID: "); - - for ( i = 0; i < sizeof( ptp_unicast_settings.gm_clock_id ); i++ ) - { - printf( "%02X", ptp_unicast_settings.gm_clock_id.b[i] ); - - if ( i < ( sizeof( ptp_unicast_settings.gm_clock_id ) - 1 ) ) - printf(":"); - } - - printf("\n"); + 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 ); } } + } - // GM Target Port ID - cp = strstr( arg, ptp_name_tp_id ); - - if ( cp != NULL ) - { - char* p_tail; - - l = strlen( ptp_name_tp_id ); + // GM Target Port ID + idx = chk_parm_name( arg, ptp_name_tp_id, &cp ); - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon + if ( idx < 0 ) // parameter error + goto fail; - l++; - - ptp_unicast_settings.gm_port_id = strtoul( cp+l, &p_tail, 10 ); - printf( " setting GM port id: %d\n", ptp_unicast_settings.gm_port_id ); + if ( cp ) // parameter found + { + if ( !unicast_supported ) + 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 ); } + } - // Sync Message Rate - cp = strstr( arg, ptp_name_sr ); - - if ( cp != NULL ) - { - l = strlen( ptp_name_sr ); + // Sync Message Rate + idx = chk_int16_parm( arg, ptp_name_sr, &p_uc_settings->sync_intv, + p_uc_limits->sync_intv_min, p_uc_limits->sync_intv_max, + unicast_supported, "sync intv." ); + if ( idx < 0 ) + goto fail; - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon - l++; - - ptp_unicast_settings.sync_interval = atoi( cp+l ); - printf( " setting Sync Int: %i\n", ptp_unicast_settings.sync_interval ); - } + // Announce Message Rate + idx = chk_int16_parm( arg, ptp_name_ar, &p_uc_settings->ann_intv, + p_uc_limits->ann_intv_min, p_uc_limits->ann_intv_max, + unicast_supported, "ann. intv." ); + if ( idx < 0 ) + goto fail; - // Announce Message Rate - cp = strstr( arg, ptp_name_ar ); - - if ( cp != NULL ) - { - l = strlen( ptp_name_ar ); - - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon + // Delay Message Rate + idx = chk_int16_parm( arg, ptp_name_dr, &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." ); + if ( idx < 0 ) + goto fail; - l++; - - ptp_unicast_settings.announce_interval = atoi( cp+l ); - printf( " setting Ann Int: %i\n", ptp_unicast_settings.announce_interval ); - } - - // Delay Message Rate - cp = strstr( arg, ptp_name_dr ); - - if ( cp != NULL ) - { - l = strlen( ptp_name_dr ); + // Message Duration + tmp_int16 = p_uc_settings->message_duration; + idx = chk_int16_parm( arg, ptp_name_dur, &tmp_int16, + PTP_UC_MSG_DURATION_MIN, PTP_UC_MSG_DURATION_MAX, + unicast_supported, "msg. duration" ); + if ( idx < 0 ) + goto fail; - if ( *(cp+l) != ':' ) - goto fail; // parameter syntax error: name not followed by colon + p_uc_settings->message_duration = tmp_int16; - l++; - - ptp_unicast_settings.delay_request_interval = atoi( cp+l ); - printf( " setting DelayReq Int: %i\n", ptp_unicast_settings.delay_request_interval ); - } +#if 0 //##++++++++++++ - - // Message Duration 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 + 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 ); } - } - - rc = mbg_set_ptp_cfg_settings( dh, &ptp_settings ); +#endif + + + rc = mbg_set_ptp_cfg_settings( dh, p_settings ); if ( mbg_ioctl_err( rc, "mbg_set_ptp_cfg_settings" ) ) return rc; - - - if ( supports_unicast ) + + +#if 0 //##+++++++++ + if ( unicast_supported ) { rc = mbg_set_ptp_unicast_cfg_settings( dh, &ptp_unicast_settings ); if ( mbg_ioctl_err( rc, "mbg_set_ptp_unicast_cfg_settings" ) ) return rc; } +#endif return MBG_SUCCESS; - -fail: - printf("Syntax error in argument!\n"); + +fail: + printf( "Syntax error in argument!\n" ); return MBG_ERR_CFG; - + } // set_ptp_cfg @@ -804,7 +961,7 @@ static /*HDR*/ int ip4_check_parm( const char *s, IP4_INFO *p ) { int l = strlen( p->name ); - const char *cp; + int n; if ( strncmp( s, p->name, l ) != 0 ) return 0; // parameter does not match @@ -814,12 +971,12 @@ int ip4_check_parm( const char *s, IP4_INFO *p ) l++; - cp = str_to_ip4_addr( p->addr, &s[l] ); + n = str_to_ip4_addr( p->addr, &s[l] ); - if ( cp == NULL ) + if ( n < 0 ) goto fail; // parameter syntax error: failed to convert numeric address - return cp - s; + return n + l; //##++++++ needs to be verified fail: return MBG_ERR_CFG; @@ -911,8 +1068,8 @@ done: // now check static configuration { char ws1[40]; char ws2[40]; - snprint_ip4_addr( ws1, sizeof( ws1 ), &ip4_settings.broad_addr ); - snprint_ip4_addr( ws2, sizeof( ws2 ), &default_broad_addr ); + snprint_ip4_addr( ws1, sizeof( ws1 ), &ip4_settings.broad_addr, NULL ); + snprint_ip4_addr( ws2, sizeof( ws2 ), &default_broad_addr, NULL ); printf( "*** Warning: Broadcast address %s does not match the default broadcast address %s\n", ws1, ws2 ); } @@ -979,7 +1136,7 @@ int set_gps_pos( MBG_DEV_HANDLE dh, const char *gp ) if ( mbg_ioctl_err( 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", + printf( "The clock's receiver position has been set to lat=%+.4f, lon=%+.4f, alt=%.0fm\n", new_pos_lla[LAT] * r2d, new_pos_lla[LON] * r2d, new_pos_lla[ALT] ); return rc; @@ -1009,9 +1166,9 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, unsigned int sec100 = 0; int rc; - // Either a date string, a time string, or both + // Either a date string, a time string, or both // may have been passed to this function. - // If either of them is NULL read the current date/time + // If either of them is NULL read the current date/time // as default values. if ( sdate == NULL || stime == NULL ) { @@ -1051,8 +1208,8 @@ int set_date_time( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, } } - // GPS and non-GPS cards require different API calls which use - // different structures to set the on-board date and time, + // GPS and non-GPS cards require different API calls which use + // different structures to set the on-board date and time, // so we have to distinguish. if ( _pcps_is_gps( p_dev ) ) // is a GPS card @@ -1152,11 +1309,11 @@ 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, +void check_setup_receiver_info( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, RECEIVER_INFO *p_ri ) { - // 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 + // 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 ); @@ -1173,10 +1330,10 @@ int check_get_receiver_port_cfg( MBG_DEV_HANDLE dh, RECEIVER_PORT_CFG *p_rpcfg, check_setup_receiver_info( dh, p_dev, p_ri ); - // 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 + // 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 // baud rate is still 0 to see if the structure has already been set up. - if ( ( p_ri->n_com_ports > 0 ) && + if ( ( p_ri->n_com_ports > 0 ) && ( p_rpcfg->pii[0].port_info.port_settings.parm.baud_rate == 0 ) ) { rc = mbg_get_serial_settings( dh, p_dev, p_rpcfg, p_ri ); @@ -1191,7 +1348,7 @@ int check_get_receiver_port_cfg( MBG_DEV_HANDLE dh, RECEIVER_PORT_CFG *p_rpcfg, static /*HDR*/ -int snprint_port_cfg( char *s, int sz, unsigned int port_num, +int snprint_port_cfg( char *s, int sz, unsigned int port_num, const RECEIVER_PORT_CFG *p_rpcfg ) { const PORT_SETTINGS *p_ps = &p_rpcfg->pii[port_num].port_info.port_settings; @@ -1227,7 +1384,7 @@ void show_serial_settings( MBG_DEV_HANDLE dh, const RECEIVER_PORT_CFG *p_rpcfg, static /*HDR*/ -void print_port_info_errors( const char *port_name, unsigned int port_num, +void print_port_info_errors( const char *port_name, unsigned int port_num, int flags, const RECEIVER_PORT_CFG *p_rpcfg ) { const char *msg_nsupp_drvr = "is not supported by the driver software"; @@ -1240,7 +1397,7 @@ void print_port_info_errors( const char *port_name, unsigned int port_num, printf( "** Baud rate %lu %s.\n", (ulong) p_ps->parm.baud_rate, msg_nsupp_drvr ); else if ( flags & MBG_PS_MSK_BAUD_RATE ) - printf( "** Baud rate %lu is not supported by %s%u.\n", + printf( "** Baud rate %lu is not supported by %s%u.\n", (ulong) p_ps->parm.baud_rate, port_name, port_num ); @@ -1248,7 +1405,7 @@ void print_port_info_errors( const char *port_name, unsigned int port_num, printf( "** Framing %s %s.\n", p_ps->parm.framing, msg_nsupp_drvr ); else if ( flags & MBG_PS_MSK_FRAMING ) - printf( "** Framing %s is not supported by %s%u.\n", + printf( "** Framing %s is not supported by %s%u.\n", p_ps->parm.framing, port_name, port_num ); @@ -1256,27 +1413,27 @@ void print_port_info_errors( const char *port_name, unsigned int port_num, printf( "** Handshake mode %u %s.\n", p_ps->parm.handshake, msg_nsupp_drvr ); else if ( flags & MBG_PS_MSK_HS ) - printf( "** Handshake mode %u is not supported by %s%u.\n", + printf( "** Handshake mode %u is not supported by %s%u.\n", (unsigned int) p_ps->parm.handshake, port_name, port_num ); if ( flags & MBG_PS_MSK_STR_TYPE_OVR_DEV ) - printf( "** String type index %u exceeds number of string types supp. by device.\n", + printf( "** String type index %u exceeds number of string types supp. by device.\n", p_ps->str_type ); else if ( flags & MBG_PS_MSK_STR_TYPE ) - printf( "** String type \"%s\" is not supported by %s%u.\n", + printf( "** String type \"%s\" is not supported by %s%u.\n", p_rpcfg->stii[p_ps->str_type].str_type_info.long_name, port_name, port_num ); if ( flags & MBG_PS_MSK_STR_MODE_OVR_SW ) - printf( "** String mode index %u exceeds number of string modes supported by driver software (%u).\n", + printf( "** String mode index %u exceeds number of string modes supported by driver software (%u).\n", p_ps->mode, N_STR_MODE ); else if ( flags & MBG_PS_MSK_STR_MODE ) - printf( "** String mode \"%s\" is not supported by string type \"%s\" via %s%u .\n", - mode_names[p_ps->mode], + printf( "** String mode \"%s\" is not supported by string type \"%s\" via %s%u .\n", + mode_names[p_ps->mode], p_rpcfg->stii[p_ps->str_type].str_type_info.long_name, port_name, port_num ); @@ -1628,7 +1785,7 @@ int show_time_scale( MBG_DEV_HANDLE dh, const PCPS_DEV *p_dev, const char *info if ( mbg_ioctl_err( rc, "mbg_get_time_scale_info" ) ) return rc; - printf( "%s time scale index: %u (%s)", info, tsci.settings.scale, + printf( "%s time scale index: %u (%s)", info, tsci.settings.scale, _get_time_scale_name( tsci.settings.scale ) ); printf( "\n" ); @@ -1829,19 +1986,19 @@ void usage( MBG_DEV_HANDLE dh, PCPS_DEV *p_dev, RECEIVER_INFO *p_ri, " DM:P2P specifies peer-to-peer delay mechanism\n" " DO:0 specifies PTP domain number [0..255]\n" " HW:1 specifies if the \"v1 hardware compatibility flag\" shall be set ('1') or disabled ('0')\n" - "\n" + "\n" ); - -printf( " If the PTP device supports unicast mode then the following\n" + + printf( " If the PTP device supports unicast mode then the following\n" " additional parameters can be set:\n" " PTP=ROLE:<rl>[,GMIP:<ip>][,GMID:<id>][,PID:<po>][,SR:<sr>][,AR:<ar>][,DR:<dr>][,DUR:<du>] set PTP unicast parameters\n" "\n" - " where, e.g. :\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 FF:FF:... as wildcard\n" - " PID:1 specifies the target port id of the grandmaster port that shall be used or 65535 as wildcard\n" + " PID:1 specifies the target port id of the grandmaster port to be used or 65535 as wildcard\n" " SR:0 specifies the Sync message rate requested from the grandmaster in 2^x seconds [-6..6]\n" " AR:1 specifies the Announce message rate requested from the grandmaster in 2^x seconds [-6..6]\n" " DR:1 specifies the DelayRequest message rate requested from the grandmaster in 2^x seconds [-6..6]\n" @@ -1849,7 +2006,7 @@ printf( " If the PTP device supports unicast mode then the following\n" "\n" ); -printf( " ANT_CABLE_LEN show the configured antenna cable length\n" + printf( " ANT_CABLE_LEN show the configured antenna cable length\n" " ANT_CABLE_LEN=<len> set the antenna cable length to be compensated to <len>, in meters.\n" "\n" " Please note note this parameter is only supported with cards which provide\n" @@ -1871,7 +2028,7 @@ static /*HDR*/ const char *str_parm_p(const char *s, const char *keyword ) { char *match = strstr( s, keyword ); - + if ( match && ( match == s ) ) return &s[strlen( keyword )]; else @@ -2185,7 +2342,6 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p if ( *cp == '=' ) { - rc = set_ptp_cfg( dh, ++cp, p_dev ); if ( rc < 0 ) @@ -2195,7 +2351,6 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p } info = "New"; - } show_ptp_cfg( dh, p_dev, info ); @@ -2203,7 +2358,7 @@ int check_cmd_line( int argc, char *argv[], MBG_DEV_HANDLE dh, const PCPS_DEV *p continue; } - cp = str_parm_p( argv[i], "ANT_CABLE_LEN" ); + cp = str_parm_p( argv[i], "ANT_CABLE_LEN" ); if ( cp ) { diff --git a/mbgirigcfg/mbgirigcfg.c b/mbgirigcfg/mbgirigcfg.c index 95f6238..cd3993b 100755 --- a/mbgirigcfg/mbgirigcfg.c +++ b/mbgirigcfg/mbgirigcfg.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgirigcfg.c 1.10.1.4 2011/02/02 12:28:44 martin TEST $ + * $Id: mbgirigcfg.c 1.10.1.4 2011/02/02 12:28:44 martin TEST martin $ * * Description: * Main file for the mbgirigcfg program which can be used to configure diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h index 80a4e1d..75510c5 100755 --- a/mbglib/common/gpsdefs.h +++ b/mbglib/common/gpsdefs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsdefs.h 1.91.1.8 2011/02/23 15:11:23 martin TRASH $ + * $Id: gpsdefs.h 1.91.1.19.1.10 2011/05/06 13:47:37 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -13,6 +13,43 @@ * * ----------------------------------------------------------------------- * $Log: gpsdefs.h $ + * Revision 1.91.1.19.1.10 2011/05/06 13:47:37 martin + * Support PZF600PEX. + * Revision 1.91.1.19.1.9 2011/04/21 15:01:35 martin + * Revision 1.91.1.19.1.8 2011/04/21 12:29:14 martin + * Revision 1.91.1.19.1.7 2011/04/21 11:30:11 martin + * Revision 1.91.1.19.1.6 2011/04/21 11:09:43 martin + * Revision 1.91.1.19.1.5 2011/04/20 16:08:42 martin + * Revision 1.91.1.19.1.4 2011/04/19 15:26:03 martin + * Cleanup. + * Revision 1.91.1.19.1.3 2011/04/19 15:05:44 martin + * PTP unicast cfg stuff ... + * Revision 1.91.1.19.1.2 2011/04/19 13:08:32 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.91.1.19.1.1 2011/04/18 15:30:28 martin + * Started PTP unicast + * 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_.. + * 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 @@ -426,7 +463,7 @@ typedef struct /** - * @defgroup bvar_stat BVAR_STAT status of buffered GPS data + * @defgroup group_bvar_stat BVAR_STAT status of buffered GPS data * * Status word, associated bit numbers and bit masks indicating * whether certain data from the GPS satellites are @@ -460,15 +497,15 @@ enum N_BVAR_BIT /**< @brief number of defined ::BVAR_STAT bits */ }; -#define BVAR_CFGH_INVALID ( 1UL << BVAR_BIT_CFGH_INVALID ) /**< @brief ::CFGH not valid*/ -#define BVAR_ALM_NOT_COMPLETE ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ) /**< @brief ::ALM not complete */ +#define BVAR_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 IONO data not valid */ -#define BVAR_RCVR_POS_INVALID ( 1UL << BVAR_BIT_RCVR_POS_INVALID ) /**< @brief ::POS 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 */ @@ -574,6 +611,7 @@ enum GPS_MODEL_GLN170, GPS_MODEL_GPS180PEX, GPS_MODEL_TCR180PEX, + GPS_MODEL_PZF600PEX, N_GPS_MODEL /* If new model codes are added then care must be taken * to update the associated string initializers below @@ -622,6 +660,7 @@ enum #define GPS_MODEL_NAME_GLN170 "GLN170" #define GPS_MODEL_NAME_GPS180PEX "GPS180PEX" #define GPS_MODEL_NAME_TCR180PEX "TCR180PEX" +#define GPS_MODEL_NAME_PZF600PEX "PZF600PEX" /* @@ -665,7 +704,8 @@ enum GPS_MODEL_NAME_GPS180, \ GPS_MODEL_NAME_GLN170, \ GPS_MODEL_NAME_GPS180PEX, \ - GPS_MODEL_NAME_TCR180PEX \ + GPS_MODEL_NAME_TCR180PEX, \ + GPS_MODEL_NAME_PZF600PEX \ } @@ -843,6 +883,7 @@ enum 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 */ }; @@ -868,7 +909,8 @@ enum "Nav. Engine Settings", \ "Raw IRIG Data", \ "Raw IRIG Time", \ - "PTP/IEEE1588 Unicast" \ + "PTP/IEEE1588 Unicast", \ + "General Purpose I/O" \ } @@ -896,6 +938,7 @@ enum #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 @@ -1089,7 +1132,7 @@ enum #define TM_MSK_TIME_VALID ( TM_UTC | TM_SCALE_GPS | TM_SCALE_TAI ) /** - This structure is used to transmit information on date and time + * @brief A structure used to transmit information on date and time */ typedef struct { @@ -1135,7 +1178,7 @@ typedef struct /* sequence and number of components of a cartesian position */ enum { XP, YP, ZP, N_XYZ }; - /** a type of array holding a cartesian position */ + /** @brief An array holding a cartesian position */ typedef double XYZ[N_XYZ]; /**< values are in [m] */ #define _XYZ_DEFINED @@ -1148,7 +1191,7 @@ typedef struct /* sequence and number of components of a geographic position */ enum { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */ - /** a type of array holding a geographic position */ + /** @brief An array holding a geographic position */ typedef double LLA[N_LLA]; /**< lon, lat in [rad], alt in [m] */ #define _LLA_DEFINED @@ -1158,7 +1201,7 @@ typedef struct /** - @defgroup group_synth Synthesizer parameters + @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 @@ -1201,13 +1244,11 @@ typedef struct #define MAX_SYNTH_FREQ_EDIT 9999 /**< max sequence of digits when editing */ -/** The maximum frequency that can be configured for the synthesizer */ +/** @brief The maximum frequency that can be configured for the synthesizer */ #define MAX_SYNTH_FREQ_VAL 10000000UL /**< 10 MHz */ /* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */ -/** - The synthesizer phase will only be synchronized if the frequency - is below this limit: */ +/** @brief The synthesizer's phase is only be synchronized if the frequency is below this limit */ #define SYNTH_PHASE_SYNC_LIMIT 10000UL /**< 10 kHz */ /** @@ -1270,7 +1311,7 @@ typedef struct #define SYNTH_FLAG_PHASE_IGNORED 0x01 -/** @} */ // endgroup +/** @} group_synth */ /** @defgroup group_tzdl Time zone/daylight saving parameters @@ -1426,7 +1467,7 @@ typedef struct DEFAULT_TZDL_NAMES_EET_EEST_DE /* name[] */ \ } -/** @} */ // endgroup +/** @} group_tzdl */ /** * The structure below reflects the status of the antenna, @@ -2000,7 +2041,7 @@ enum /** - @defgroup group_icode IRIG Codes + @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 @@ -2049,19 +2090,19 @@ enum AFNOR codes are based on the french standard AFNOR NF S87-500 IEEE1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible - with B002/B122 but provides some welldefined extensions in the control field which + 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 IEEE1344 standard from 1995. These codes provide the same extensions as IEEE1344 + 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. - <b>ATTENTION:</b> There are 3rd party IRIG devices out there which apply the UTC offset - as specified in C37.118, but claim to be compatible with IEEE1344. So if local time is - transmitted in the IRIG signal then care must be taken that the UTC offset is evaluated - by the IRIG receiver in the same way as output by the IRIG generator. Otherwise the UTC - time computed by the receiver may be wrong. + @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>. @{ */ @@ -2515,7 +2556,8 @@ enum MSK_ICODE_RX_AFNOR_DC \ ) #endif -/** @} */ + +/** @} group_icode */ @@ -2537,10 +2579,10 @@ typedef struct /** - @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS::flags - - (others are reserved) -* @{ + * @defgroup group_irig_flags Bit Masks used with IRIG_SETTINGS::flags + * + * (others are reserved) + * @{ */ #define IFLAGS_DISABLE_TFOM 0x0001 /**< RX ignore/TX don't gen TFOM */ #define IFLAGS_TX_GEN_LOCAL_TIME 0x0002 /**< gen local time, not UTC */ @@ -2553,7 +2595,7 @@ typedef struct // this flag. See the comments near the declaration of the _pcps_incoming_tfom_ignored() // macro in pcpsdev.h for details. -/** @} */ +/** @} group_irig_flags */ /** * @brief Current IRIG settings and supported codes @@ -2735,7 +2777,7 @@ typedef struct /** - @defgroup group_scale Time Scale Configuration + @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 @@ -2801,7 +2843,7 @@ typedef struct _mbg_swab32( &(_p)->supp_scales ); \ } -/** @} */ // endgroup +/** @} group_time_scale */ /* @@ -2832,10 +2874,10 @@ typedef struct */ typedef struct { - uint8_t hour; /* 0..23 */ - uint8_t min; /* 0..59 */ - uint8_t sec; /* 0..59,60 */ - uint8_t sec100; /* reserved, currently always 0 */ + uint8_t hour; /**< 0..23 */ + uint8_t min; /**< 0..59 */ + uint8_t sec; /**< 0..59,60 */ + uint8_t sec100; /**< reserved, currently always 0 */ } MBG_TIME; #define _mbg_swab_mbg_time( _p ) \ @@ -3132,23 +3174,24 @@ typedef struct */ -/* - * All possibly supported ref time sources +/** + * @brief All possibly supported ref time sources */ enum { - MULTI_REF_NONE = -1, // nothing, undefined - MULTI_REF_GPS = 0, // standard GPS - MULTI_REF_10MHZ, // 10 MHz input frequency - MULTI_REF_PPS, // 1 PPS input signal - MULTI_REF_10MHZ_PPS, // combined 10 MHz plus PPS - MULTI_REF_IRIG, // IRIG input - MULTI_REF_NTP, // Network Time Protocol (NTP) - MULTI_REF_PTP, // Precision Time Protocol (PTP, IEEE1588) - MULTI_REF_PTP_E1, // PTP over E1 - MULTI_REF_FREQ, // fixed frequency - MULTI_REF_PPS_STRING, // 1 PPS in addition to string - N_MULTI_REF // the number of defined sources + 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 */ }; @@ -3166,7 +3209,8 @@ enum "PTP (IEEE1588)", \ "PTP over E1", \ "Fixed Freq. in", \ - "PPS plus string" \ + "PPS plus string", \ + "Var. freq. via GPIO" \ } @@ -3183,6 +3227,7 @@ enum #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 ) /* @@ -3268,41 +3313,55 @@ enum -/* +/** + * @defgroup group_xmr_cfg Extended multiref configuration stuff + * * If the RECEIVER_INFO::features flag GPS_FEAT_XMULTI_REF is set * then the following XMULTI_REF_... data structures must be used - * instead of the older MULTI_REF_... structures above. + * instead of the older MULTI_REF_... structures. * * Those devices support a number of priority levels addressed by * the priority index, starting at 0 for highest priority. A single * reference time source from the set of supported sources can be * assigned to each priority level. * - * The structures below are used to configure the individual + * 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. - */ + * + * @{ */ +/** + * @brief Identifier for a reference source + */ typedef struct { - uint8_t type; /* 0..N_MULTI_REF-1 from the enum above */ - uint8_t instance; /* reserved, currently always 0 */ + uint8_t type; /**< 0..N_MULTI_REF-1 from the enum above */ + uint8_t instance; /**< instance number, if multiple instances are supported, else 0 */ + } XMULTI_REF_ID; + + +/** + * @brief Reference source configuration settings + */ typedef struct { - XMULTI_REF_ID id; /* time source identifier */ - uint16_t flags; /* reserved, currently always 0 */ - NANO_TIME bias; /* time bias, e.g. path delay */ - NANO_TIME precision; /* precision of the time source */ - uint32_t fine_limit; /* smooth control if below this limit */ + XMULTI_REF_ID id; /**< time source identifier */ + uint16_t flags; /**< reserved, currently always 0 */ + NANO_TIME bias; /**< time bias, e.g. path delay */ + NANO_TIME precision; /**< precision of the time source */ + uint32_t fine_limit; /**< smooth control if below this limit */ + } XMULTI_REF_SETTINGS; -/* - * The structure below is used to retrieve or configure the time source - * for a specific priority level. - * After configuring, a structure with idx == 0xFFFF (-1) must be sent + +/** + * @brief Reference source configuration settings for a specific priority level + * + * @note After configuring, a structure with idx == 0xFFFF (-1) must be sent * to let the changes become effective. */ typedef struct @@ -3313,79 +3372,100 @@ typedef struct } XMULTI_REF_SETTINGS_IDX; -/* - * The structure below contains the XMULTI_REF configuration - * for a single priority level, plus information on supported - * ref time sources, and the number of supported priority levels. + +/** + * @brief Reference source configuration settings and capabilities */ typedef struct { - XMULTI_REF_SETTINGS settings; /* current settings */ - uint32_t supp_ref; /* supp. HAS_MULTI_REF_... codes or'ed */ - uint8_t n_supp_ref; /* number of supported ref time sources */ - uint8_t n_prio; /* number of supported priority levels */ - uint16_t flags; /* reserved, currently 0, e.g. multiple instance support */ + XMULTI_REF_SETTINGS settings; /**< current settings */ + 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_INFO; -/* - * The structure below is used to retrieve the XMULTI_REF configuration - * information for a specific priority level. + +/** + * @brief Reference source configuration settings and capabilities for a specific priority level */ typedef struct { - uint16_t idx; /* the priority level index, highest == 0 */ - XMULTI_REF_INFO info; + uint16_t idx; /**< the priority level index, highest == 0 */ + XMULTI_REF_INFO info; /**< ref source cfg and capabilities */ } XMULTI_REF_INFO_IDX; -/* - * The structure below contains status information on a single - * ref time source. + +/** + * @brief Status information on a single ref time source */ typedef struct { - XMULTI_REF_ID id; /* time source identifier */ - uint16_t status; /* flag bits as defined below */ - NANO_TIME offset; /* time offset from main time base */ - uint32_t reserved; /* reserved, currently always 0 */ + XMULTI_REF_ID id; /**< time source identifier */ + uint16_t status; /**< flag bits as defined below */ + NANO_TIME offset; /**< time offset from main time base */ + uint32_t flags; /**< see flags specidied below */ } XMULTI_REF_STATUS; -/* - * The structure below is used to retrieve the the status information - * of the time source at a specific priority level. + +/** + * @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. + */ +enum +{ + 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 +}; + +#define XMRSF_MSK_MULT_INSTC_SUPP ( 1UL << XMRSF_BIT_MULT_INSTC_SUPP ) +#define XMRSF_MSK_IS_EXTERNAL ( 1UL << XMRSF_BIT_IS_EXTERNAL ) + + + +/** + * @brief Status information on a ref time source at a specific priority level */ typedef struct { - uint16_t idx; /* the priority level index, highest == 0 */ - XMULTI_REF_STATUS status; + uint16_t idx; /**< the priority level index, highest == 0 */ + XMULTI_REF_STATUS status; /**< status information */ } XMULTI_REF_STATUS_IDX; -/* - * Bits used with XMULTI_REF_STATUS. + +/** + * @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. */ enum { - XMRS_BIT_NOT_SUPP, /* ref type cfg'd for this level is not supported */ - XMRS_BIT_NO_CONN, /* input signal is disconnected */ - XMRS_BIT_NO_SIGNAL, /* no input signal */ - XMRS_BIT_IS_MASTER, /* reference is master source */ - XMRS_BIT_IS_LOCKED, /* locked to input signal */ - XMRS_BIT_IS_ACCURATE, /* oscillator control has reached full accuracy */ - XMRS_BIT_NOT_SETTLED, /* reference time signal not settled */ - XMRS_BIT_NOT_PHASE_LOCKED, /* oscillator not phase locked to PPS */ - N_XMRS_BITS + XMRS_BIT_NOT_SUPP, /**< ref type cfg'd for this level is not supported */ + XMRS_BIT_NO_CONN, /**< input signal is disconnected */ + XMRS_BIT_NO_SIGNAL, /**< no input signal */ + XMRS_BIT_IS_MASTER, /**< reference is master source */ + XMRS_BIT_IS_LOCKED, /**< locked to input signal */ + XMRS_BIT_IS_ACCURATE, /**< oscillator control has reached full accuracy */ + XMRS_BIT_NOT_SETTLED, /**< reference time signal not settled */ + XMRS_BIT_NOT_PHASE_LOCKED, /**< oscillator not phase locked to PPS */ + XMRS_BIT_NUM_SRC_EXC, /**< number of available sources exceeds what can be handled */ + XMRS_BIT_IS_EXTERNAL, /**< this ref source is on extension card */ + N_XMRS_BITS /**< number of know status bits */ }; - -/* bit masks corresponding to the flag bits above */ - #define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) #define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) #define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) @@ -3394,6 +3474,8 @@ enum #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 ) @@ -3410,6 +3492,153 @@ enum } +/** + * @brief The number of supported instances of each ref source type + * + * @note This structure is only supported if bit XMRS_FLAG_MULT_INSTC_SUPP + * is set in XMULTI_REF_STATUS::flags. + */ +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 */ + +} XMULTI_REF_INSTANCES; + +/** @} group_xmr_cfg */ + + + +/** + * @defgroup group_gpio GPIO port configuration stuff + * + * @{ */ + +/** + * @brief General GPIO config info to be read from a device + */ +typedef struct +{ + uint32_t num_io; /**< number of supported GPIO ports */ + uint32_t reserved; /**< currently always 0 */ + uint32_t flags; /**< currently always 0 */ + +} MBG_GPIO_CFG_LIMITS; + + + +/** + * @brief A structure used to specify a frequency + */ +typedef struct +{ + uint32_t hz; /**< integral number, HZ */ + uint32_t frac; /**< fractional part, binary */ + +} MBG_GPIO_FREQ; + + + +/** + * @brief A structure used to configure a GPIO as frequency output + */ +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 */ + +} MBG_GPIO_FREQ_OUT_SETTINGS; + + + +/** + * @brief A structure used to specify the supported features of a GPIO frequency output + */ +typedef struct +{ + MBG_GPIO_FREQ max_freq; /** maximum frequency */ + uint32_t reserved; /**< currently always 0 */ + uint32_t flags; /**< currently always 0 */ + +} MBG_GPIO_FREQ_OUT_INFO; + + + +/** + * @brief A structure used to configure a GPIO port + */ +typedef struct +{ + uint32_t mode; /** frequency out, frequency in, pulse out, etc. */ + uint32_t reserved; /**< currently always 0 */ + uint32_t flags; /**< currently always 0 */ + + union + { + MBG_GPIO_FREQ_OUT_SETTINGS frequ_out; /** if type is frequency output */ + } u; + +} MBG_GPIO_SETTINGS; + + + +/** + * @brief A structure used to configure a specific GPIO port + */ +typedef struct +{ + uint32_t idx; /**< port number, 0..(MBG_GPIO_CFG_LIMITS::num_io - 1) */ + MBG_GPIO_SETTINGS settings; /**< configuration settings */ + +} MBG_GPIO_SETTINGS_IDX; + + + +/** + * @brief A structure used query the current GPIO port settings and capabilities + */ +typedef struct +{ + MBG_GPIO_SETTINGS settings; /**< current configuration */ + uint32_t supp_modes; /**< bit mask of supported modes */ + uint32_t supp_flags; /**< bit mask of flags recognized by the device */ + + union + { + MBG_GPIO_FREQ_OUT_INFO frequ_out; /** < capabilities in frequency output mode */ + } u; + +} MBG_GPIO_INFO; + + + +/** + * @brief A structure used to query configuration and capabilities of 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; + + + +/** + * @brief Definitions for MBG_GPIO_SETTINGS::mode + */ +enum +{ + MBG_GPIO_SIGNAL_TYPE_FREQ_OUT, /**< frequency output */ + N_MBG_GPIO_SIGNAL_TYPES /**< number of known modes */ +}; + +/** @} group_gpio */ + /*------------------------------------------------------------------------*/ @@ -3512,10 +3741,12 @@ enum /*------------------------------------------------------------------------*/ -/* - * GPS receiver modes of operation. Some of the codes combinations - * are obsolete with recent GPS receivers. However, that doesn't - * matter since the mode is just read from the receiver: +/** + * @brief Satellite receiver modes of operation. + * + * @note Some of the code combinations are obsolete with recent + * satellite receivers. However, this doesn't matter since the mode + * is just read from the receiver. */ #define REMOTE 0x10 #define BOOT 0x20 @@ -3539,9 +3770,12 @@ typedef int16_t DAC_VAL; +/** + * @brief Satellite receiver status information + */ typedef struct { - uint16_t mode; /**< Mode of operation */ + 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 */ @@ -3563,31 +3797,26 @@ typedef struct -/* - The enumeration below lists all - known satellite navigation systems -*/ +/** + * @brief An enumeration of known satellite navigation systems + */ enum { - GNSS_TYPE_GPS, - GNSS_TYPE_GLONASS, - GNSS_TYPE_BEIDOU, - GNSS_TYPE_GALILEO, - N_GNSS_TYPES + GNSS_TYPE_GPS, /**< GPS, United States */ + GNSS_TYPE_GLONASS, /**< GLONASS, Russia */ + GNSS_TYPE_BEIDOU, /**< BEIDOU, China */ + GNSS_TYPE_GALILEO, /**< GALILEO, Europe */ + N_GNSS_TYPES /**< Number of defined codes */ }; - - -#define GNSS_TYPE_STRS \ -{ \ - "GPS", \ - "GLONASS", \ - "BEIDOU" , \ - "GALILEO" \ +#define GNSS_TYPE_STRS \ +{ \ + "GPS", \ + "GLONASS", \ + "BEIDOU" , \ + "GALILEO" \ } - - #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 ) @@ -3603,10 +3832,10 @@ typedef struct uint32_t flags; /**< see below */ } MBG_GNSS_MODE_SETTINGS; -#define _mbg_swab_mbg_gnss_mode_settings( _p ) \ -{ \ - _mbg_swab32( &(_p)->gnss_set ); \ - _mbg_swab32( &(_p)->flags ); \ +#define _mbg_swab_mbg_gnss_mode_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->gnss_set ); \ + _mbg_swab32( &(_p)->flags ); \ } @@ -3618,16 +3847,17 @@ typedef struct uint32_t flags; /**< indicates which of the defined flags are supported by the device */ } MBG_GNSS_MODE_INFO; -#define _mbg_swab_mbg_gnss_mode_info( _p ) \ -{ \ - _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \ - _mbg_swab32( &(_p)->supp_gnss_types ); \ - _mbg_swab32( &(_p)->flags ); \ +#define _mbg_swab_mbg_gnss_mode_info( _p ) \ +{ \ + _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_gnss_types ); \ + _mbg_swab32( &(_p)->flags ); \ } -/* Flags used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags: */ - +/** + * @brief Flags used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags + */ enum { MBG_GNSS_FLAG_EXCLUSIVE, /**< (read only) only one of the supported GNSS systems can be used at the same time */ @@ -3642,10 +3872,9 @@ enum #define MAX_USED_SATS 32 -/* - The structure below allos to transfer - SV information from a certain GNSS type. -*/ +/** + * @brief SV information from a certain GNSS type. + */ typedef struct { uint8_t gnss_type; /**< GNSS type from the enumeration above */ @@ -3655,7 +3884,7 @@ typedef struct uint8_t svs[MAX_USED_SATS]; } GNSS_SAT_INFO; -#define _mbg_swab_gnss_sat_info( _p ) \ +#define _mbg_swab_gnss_sat_info( _p ) \ { \ _mbg_swab16( &(_p)->good_svs ); \ _mbg_swab16( &(_p)->svs_in_view ); \ @@ -3682,8 +3911,7 @@ typedef struct } /** - * The type below is used to configure the length of the - * antenna cable in [m]: + * @brief A data type used to configure the length of an antenna cable [m] */ typedef uint16_t ANT_CABLE_LEN; @@ -3691,29 +3919,36 @@ typedef uint16_t ANT_CABLE_LEN; -/* Configuration data for an optional LAN interface. +/** + * @defgroup group_ip4_cfg Simple configuration and status + * of an optional LAN interface. * - * This is only supported if the flag GPS_HAS_LAN_IP4 - * is set in RECEIVER_INFO::features. - */ - + * @note This is only supported if the flag GPS_HAS_LAN_IP4 is set + * in RECEIVER_INFO::features. + * + * @{ */ -/* Basic network settings */ +/** + * @brief An IPv4 address + */ typedef uint32_t IP4_ADDR; #define _mbg_swab_ip4_addr( _p ) \ _mbg_swab32( _p ); +/** + * @brief Settings of an IPv4 network interface + */ typedef struct { - IP4_ADDR ip_addr; - IP4_ADDR netmask; - IP4_ADDR broad_addr; - IP4_ADDR gateway; - uint16_t flags; /* see below */ - uint16_t vlan_cfg; /* see below */ + 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 */ } IP4_SETTINGS; @@ -3728,30 +3963,34 @@ typedef struct } -// IP4_SETTINGS::vlan_cfg contains a combination of -// a VLAN ID number plus a VLAN priiority code. -// Definitions used with IP4_SETTINGS::vlan_cfg: - -#define VLAN_ID_BITS 12 // number of bits to hold the ID -#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) // number of ID values -#define MIN_VLAN_ID 0 // minimum ID value -#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) // maximum ID value +/** + * @brief Definitions used with IP4_SETTINGS::vlan_cfg + * + * @note IP4_SETTINGS::vlan_cfg contains 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 // 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_MSK ( ( 1 << VLAN_PRIORITY_BITS ) - 1 ) -// The macros below can be used to encode/decode packed vlan_cfg variables: +/** + * @brief Macros used to encode/decode packed vlan_cfg variables + */ #define _decode_vlan_id( _cfg ) ( ( (_cfg) >> VLAN_ID_SHIFT ) & VLAN_ID_MSK ) #define _decode_vlan_priority( _cfg ) ( ( (_cfg) >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK ) #define _encode_vlan_cfg( _id, _prty ) ( ( (_id) << VLAN_ID_SHIFT ) | ( (_prty) << VLAN_PRIORITY_SHIFT ) ) @@ -3785,18 +4024,23 @@ typedef struct -/* LAN interface information */ - +/** + * @brief LAN interface information + * + * This structure can be retrieved from a device + * to check the device's capabilities. + */ typedef struct { - uint16_t type; /* codes see below */ - uint8_t mac_addr[6]; /* MAC address */ - uint16_t ver_code; /* high byte.low byte, in hex */ - char ver_str[GPS_ID_STR_SIZE]; - char sernum[GPS_ID_STR_SIZE]; - uint32_t rsvd_0; /* reserved, currently always 0 */ - uint16_t flags; /* see below */ - uint16_t rsvd_1; /* reserved, currently always 0 */ + uint16_t type; //< type of LAN interface, see 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 + } LAN_IF_INFO; #define _mbg_swab_lan_if_info( _p ) \ @@ -3810,41 +4054,54 @@ typedef struct -/* codes used with LAN_IF_INFO::type: */ - +/** + * @brief Codes used with LAN_IF_INFO::type + */ enum { - LAN_IF_TYPE_XPORT, - LAN_IF_TYPE_PTP, - N_LAN_IF_TYPE + 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 }; -/* Flags used with IP4_SETTINGS::flags and LAN_IF_INFO::flags: */ - +/** + * @brief Flags used with IP4_SETTINGS::flags and LAN_IF_INFO::flags + */ enum { - 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 + 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 }; #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 */ + + +/** + * @defgroup group_ptp Definitions used with PTP/IEEE1588 + * + * @{ */ + +/** + * @brief Enumeration of protocols possibly used with PTP + */ enum { - PTP_NW_PROT_BIT_RESERVED, - PTP_NW_PROT_BIT_UDP_IPV4, - PTP_NW_PROT_BIT_UDP_IPV6, - PTP_NW_PROT_BIT_IEEE_802_3, - PTP_NW_PROT_BIT_DEVICE_NET, - PTP_NW_PROT_BIT_CONTROL_NET, - PTP_NW_PROT_BIT_PROFINET, - N_PTP_NW_PROT + 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 ) @@ -3859,18 +4116,24 @@ enum #define DEFAULT_PTP_NW_PROT_MASK ( PTP_NW_PROT_MSK_UDP_IPV4 | PTP_NW_PROT_MSK_IEEE_802_3 ) #endif +/** + * @brief Name strings for the protocols possibly used with PTP + */ #define PTP_NW_PROT_STRS \ { \ "Reserved", \ - "UDP/IPv4", \ - "UDP/IPv6", \ - "IEEE 802.3", \ + "UDP/IPv4 (L3)", \ + "UDP/IPv6 (L3)", \ + "IEEE 802.3 (L2)", \ "DeviceNet", \ "ControlNet", \ "PROFINET" \ } +/** + * @brief Short name strings for the protocols possibly used with PTP + */ #define PTP_NW_PROT_STRS_SHORT \ { \ "RES", \ @@ -3882,21 +4145,29 @@ enum "PN" \ } + +/** + * @brief Possible states of a PTP port + */ enum { - PTP_PORT_STATE_UNINITIALIZED, - PTP_PORT_STATE_INITIALIZING, - PTP_PORT_STATE_FAULTY, - PTP_PORT_STATE_DISABLED, - PTP_PORT_STATE_LISTENING, - PTP_PORT_STATE_PRE_MASTER, - PTP_PORT_STATE_MASTER, - PTP_PORT_STATE_PASSIVE, - PTP_PORT_STATE_UNCALIBRATED, - PTP_PORT_STATE_SLAVE, - N_PTP_PORT_STATE + PTP_PORT_STATE_UNINITIALIZED, //< uninitialized + PTP_PORT_STATE_INITIALIZING, //< currently initializing + PTP_PORT_STATE_FAULTY, //< faulty + PTP_PORT_STATE_DISABLED, //< disabled + PTP_PORT_STATE_LISTENING, //< listening for PTP packets + PTP_PORT_STATE_PRE_MASTER, //< going to become master + PTP_PORT_STATE_MASTER, //< master + PTP_PORT_STATE_PASSIVE, //< passive + PTP_PORT_STATE_UNCALIBRATED, //< uncalibrated + PTP_PORT_STATE_SLAVE, //< slave + N_PTP_PORT_STATE //< number of defined port states }; + +/** + * @brief Name strings for the PTP port states + */ #define PTP_PORT_STATE_STRS \ { \ "UNINITIALIZED", \ @@ -3912,18 +4183,28 @@ enum } +/** + * @brief An entry for a table of parameters which can not be accessed by an enumerated index + */ typedef struct { - uint8_t value; - const char *name; + uint8_t value; //< the parameter value + const char *name; //< the parameter name } PTP_TABLE; +/** + * @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". + */ enum { - PTP_DELAY_MECH_BIT_E2E, // in PTP2 specs: 0x01 - PTP_DELAY_MECH_BIT_P2P, // in PTP2 specs: 0x02 - N_PTP_DELAY_MECH // additionally the specs define 0xFE for disabled + 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 }; #define PTP_DELAY_MECH_MSK_E2E ( 1UL << PTP_DELAY_MECH_BIT_E2E ) @@ -3933,6 +4214,9 @@ enum #define DEFAULT_PTP_DELAY_MECH_MASK ( PTP_DELAY_MECH_MSK_E2E | PTP_DELAY_MECH_MSK_P2P ) #endif +/** + * @brief Name strings for the PTP delay mechanisms + */ #define PTP_DELAY_MECH_NAMES \ { \ "E2E", \ @@ -3941,11 +4225,17 @@ enum -#define PTP_CLOCK_ACCURACY_RESERVED_OFFSET 0x20 +#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. + */ enum { - PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_RESERVED_OFFSET, + PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_NUM_BIAS, PTP_CLOCK_ACCURACY_100ns, PTP_CLOCK_ACCURACY_250ns, PTP_CLOCK_ACCURACY_1us, @@ -3971,8 +4261,13 @@ enum }; -// Attention: Substract offset of PTP_CLOCK_ACCURACY_RESERVED_OFFSET when -// using the enum above as index for the initializer below! +/** + * @brief Name strings for PTP accuracy classes + * + * @note The enumeration does not start at 0 but with a bias + * specified by PTP_CLOCK_ACCURACY_NUM_BIAS, so this bias needs + * to be accounted for when accessing a string table. + */ #define PTP_CLOCK_ACCURACY_STRS \ { \ "< 25 ns", \ @@ -4001,6 +4296,9 @@ enum +/** + * @brief Codes to specify the type of a time source used with PTP + */ #define PTP_TIME_SOURCE_ATOMIC_CLOCK 0x10 #define PTP_TIME_SOURCE_GPS 0x20 #define PTP_TIME_SOURCE_TERRESTRIAL_RADIO 0x30 @@ -4012,6 +4310,9 @@ enum +/** + * @brief A table of PTP time source codes plus associated name strings + */ #define PTP_TIME_SOURCE_TABLE \ { \ { PTP_TIME_SOURCE_ATOMIC_CLOCK, "Atomic Clock" }, \ @@ -4026,17 +4327,26 @@ 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. + * Depending on its specification a devices may not be able to take + * each of the specified roles. + */ enum { - PTP_ROLE_MULTICAST_SLAVE, - PTP_ROLE_UNICAST_SLAVE, - PTP_ROLE_MULTICAST_MASTER, - PTP_ROLE_UNICAST_MASTER, - N_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 + N_PTP_ROLES //< number of defined roles }; +/** + * @brief Name strings for defined PTP roles + */ #define PTP_ROLE_STRS \ { \ "Multicast Slave", \ @@ -4046,9 +4356,24 @@ enum } +/** + * @brief Short name strings for defined PTP roles + */ +#define PTP_ROLE_STRS_SHORT \ +{ \ + "MCS", \ + "UCS", \ + "MCM", \ + "UCM" \ +} -/* PTP configuration stuff */ +/** + * @brief A PTP clock identity + * + * @note This usually consists of a 6 byte MAC address with + * 2 fixed bytes inserted. + */ typedef struct { uint8_t b[8]; @@ -4058,35 +4383,88 @@ typedef struct +/** + * @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. + */ +enum +{ + PTP_TIMESCALE_PTP, /* default */ + PTP_TIMESCALE_ARB, + N_PTP_TIMESCALE +}; + + +/** + * @brief Name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAME_PTP "PTP Standard (TAI)" +#define PTP_TIMESCALE_NAME_ARB "Arbitrary" + +/** + * @brief Short name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAME_PTP_SHORT "PTP" +#define PTP_TIMESCALE_NAME_ARB_SHORT "Arb" + + +/** + * @brief A table of name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAMES \ +{ \ + PTP_TIMESCALE_NAME_PTP, \ + PTP_TIMESCALE_NAME_ARB \ +} + +/** + * @brief A table of short name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAMES_SHORT \ +{ \ + PTP_TIMESCALE_NAME_PTP_SHORT, \ + PTP_TIMESCALE_NAME_ARB_SHORT \ +} + + + +/** + * @brief A structure to used to read the status of the PTP protocol stack + */ typedef struct { - uint16_t network_protocol; // enum - uint8_t ptp_proto_version; // PTP v1 or v2 - uint8_t port_state; // enum - uint32_t flags; - NANO_TIME offset; + //##++++ Do we need a port identifier ?? + uint16_t network_protocol; /**< one of the enumerated protocols (@see N_PTP_NW_PROT) */ + uint8_t ptp_proto_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 */ NANO_TIME path_delay; NANO_TIME mean_path_delay; NANO_TIME delay_asymmetry; - PTP_CLOCK_IDENTITY gm_identity; + PTP_CLOCK_IDENTITY gm_identity; /**< identifier ot the upstream time source */ uint16_t clock_offset_scaled_log_variance; uint8_t clock_class; - uint8_t clock_accuracy; // enum + uint8_t clock_accuracy; /**< one of the enumerated accuracy class codes (@see N_PTP_CLOCK_ACCURACY) */ - uint32_t reserved_1; - uint32_t reserved_2; + uint32_t reserved_1; /**< reserved, currently always 0 */ + uint32_t reserved_2; /**< reserved, currently always 0 */ - uint8_t domain_number; - uint8_t time_source; // enum - uint8_t delay_mech; + 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 */ int8_t log_delay_req_intv; - int16_t utc_offset; - DAC_VAL osc_dac_cal; + int16_t utc_offset; /**< UTC offset observed against TAI */ + DAC_VAL osc_dac_cal; /**< disiplination value of the oscillator */ + + uint32_t reserved_3; /**< reserved, currently always 0 */ - uint32_t reserved_3; } PTP_STATE; #define _mbg_swab_ptp_state( _p ) \ @@ -4099,22 +4477,26 @@ typedef struct _mbg_swab_nano_time( &(_p)->delay_asymmetry ); \ _mbg_swab_ptp_clock_identity( &(_p)->gm_identity ); \ _mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \ - _mbg_swab32( &(_p)->num_clients ); \ - _mbg_swab32( &(_p)->num_masters ); \ - _mbg_swab32( &(_p)->utc_offset ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab16( &(_p)->utc_offset ); \ _mbg_swab_dac_val( &(_p)->osc_dac_cal ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ } +/** + * @brief Flag bits used with PTP_STATE::flags + */ enum { - PTP_FLAG_BIT_SLAVE_ONLY, - PTP_FLAG_BIT_IS_SLAVE, - PTP_FLAG_BIT_TIMESCALE_IS_PTP, - PTP_FLAG_BIT_LS_ANN, - PTP_FLAG_BIT_LS_ANN_NEG, - PTP_FLAG_BIT_IS_UNICAST, - N_PTP_FLAG_BIT + 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 */ }; #define PTP_FLAG_MSK_SLAVE_ONLY ( 1UL << PTP_FLAG_BIT_SLAVE_ONLY ) @@ -4125,6 +4507,7 @@ enum #define PTP_FLAG_MSK_IS_UNICAST ( 1UL << PTP_FLAG_BIT_IS_UNICAST ) + #define PTP_SYNC_INTERVAL_MIN -6 #define PTP_SYNC_INTERVAL_MAX 6 @@ -4140,99 +4523,125 @@ enum #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 A structure used to configure a PTP port + */ typedef struct { - uint16_t network_protocol; // enum, only 1 or 3 - uint8_t profile; // currently only 0 = default - uint8_t domain_number; // 0:3 + //##++++ Do we need a port identifier ?? + uint16_t network_protocol; /**< 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 */ - uint8_t delay_mechanism; // 0 (E2E) or 1 (P2P), unless disabled - uint8_t ptp_role; // MC_SLAVE/UC_SLAVE/MC_Master/UC_MASTER as defined in enum above - uint8_t priority_1; - uint8_t priority_2; + 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 dflt_clk_class_unsync_cold; // 6:255 uint8_t dflt_clk_class_unsync_warm; // 6:255 uint8_t dflt_clk_class_sync_cold; // 6:255 uint8_t dflt_clk_class_sync_warm; // 6:255 - uint8_t reserved_1; // currently always 0 - uint8_t reserved_2; // currently always 0 - int16_t sync_interval; // log 2 + uint8_t reserved_1; /**< reserved, currently always 0 */ + uint8_t reserved_2; /**< reserved, currently always 0 */ + int16_t sync_intv; /**< log2 of the sync interval [s] */ - int16_t announce_interval; // log 2 - int16_t delay_request_interval; // log 2 + int16_t ann_intv; /**< log2 of the announce interval [s] */ + int16_t delay_req_intv; /**< log2 of the delay request interval [s] */ - uint32_t upper_bound; // [ns] sync state set to false if above this limit - uint32_t lower_bound; // [ns] sync state set to true if below this limit + uint32_t upper_bound; /**< sync state set to false if above this limit [ns] */ + uint32_t lower_bound; /**< sync state set to true if below this limit [ns] */ - uint32_t reserved_3; // currently always 0 - uint32_t flags; // (see below) + uint32_t reserved_3; /**< reserved, currently always 0 */ + uint32_t flags; /**< bit masks as defined below */ } PTP_CFG_SETTINGS; -#define _mbg_swab_ptp_cfg_settings( _p ) \ -{ \ - _mbg_swab16( &(_p)->network_protocol ); \ - _mbg_swab16( &(_p)->sync_interval ); \ - _mbg_swab16( &(_p)->announce_interval ); \ - _mbg_swab16( &(_p)->delay_request_interval ); \ - _mbg_swab32( &(_p)->upper_bound ); \ - _mbg_swab32( &(_p)->lower_bound ); \ - _mbg_swab32( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->flags ); \ +#define _mbg_swab_ptp_cfg_settings( _p ) \ +{ \ + _mbg_swab16( &(_p)->network_protocol ); \ + _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 ); \ } +/** + * @brief A structure to used to query the current configurration and capabilities of a PTP port + */ typedef struct { - PTP_CFG_SETTINGS settings; + PTP_CFG_SETTINGS settings; /**< the current configuration */ - uint8_t ptp_proto_version; // PTP v1 or v2 - uint8_t reserved_1; // currently always 0 - uint16_t reserved_2; // currently always 0 + uint8_t ptp_proto_version; /**< PTP protocol version, 1, or 2, usually 2 for v2 */ + uint8_t reserved_1; /**< reserved, currently always 0 */ + uint16_t reserved_2; /**< reserved, currently always 0 */ - int16_t sync_interval_min; // log 2 - int16_t sync_interval_max; // log 2 - int16_t announce_interval_min; // log 2 - int16_t announce_interval_max; // log 2 - int16_t delay_request_interval_min; // log 2 - int16_t delay_request_interval_max; // log 2 + int16_t sync_intv_min; /**< log2 of minimum sync interval [s] */ + int16_t sync_intv_max; /**< log2 of maximum sync interval [s] */ + int16_t ann_intv_min; /**< log2 of minimum announce interval [s] */ + int16_t ann_intv_max; /**< log2 of maximum announce interval [s] */ + int16_t delay_req_intv_min; /**< log2 of minimum delay request interval [s] */ + int16_t delay_req_intv_max; /**< log2 of maximum delay request interval [s] */ - uint32_t supported_flags; // (see below) - uint32_t supported_network_protocols; - uint32_t supported_profiles; - uint32_t supported_delay_mechanisms; + uint32_t supp_flags; /**< a bit mask of supported features (see below) */ + uint32_t supp_network_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 */ } PTP_CFG_INFO; -#define _mbg_swab_ptp_cfg_info( _p ) \ -{ \ - _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \ - _mbg_swab16( &(_p)->sync_interval_min ); \ - _mbg_swab16( &(_p)->sync_interval_max ); \ - _mbg_swab16( &(_p)->announce_interval_min ); \ - _mbg_swab16( &(_p)->announce_interval_max ); \ - _mbg_swab16( &(_p)->delay_request_interval_min ); \ - _mbg_swab16( &(_p)->delay_request_interval_max ); \ - _mbg_swab32( &(_p)->supported_flags ); \ - _mbg_swab32( &(_p)->supported_profiles ); \ - _mbg_swab32( &(_p)->supported_delay_mechanisms ); \ +#define _mbg_swab_ptp_cfg_info( _p ) \ +{ \ + _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab16( &(_p)->sync_intv_min ); \ + _mbg_swab16( &(_p)->sync_intv_max ); \ + _mbg_swab16( &(_p)->ann_intv_min ); \ + _mbg_swab16( &(_p)->ann_intv_max ); \ + _mbg_swab16( &(_p)->delay_req_intv_min ); \ + _mbg_swab16( &(_p)->delay_req_intv_max ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_network_protocols ); \ + _mbg_swab32( &(_p)->supp_profiles ); \ + _mbg_swab32( &(_p)->supp_delay_mechanisms ); \ } -// flags used with PTP_CFG_SETTINGS::flags and PTP_CFG_INFO::supported_flags: -// possibly also: can be master (i.e not slave only), v1 hw compat, ... +/** + * @brief Flags used with PTP_CFG_SETTINGS::flags and PTP_CFG_INFO::supp_flags + */ enum { - PTP_CFG_BIT_TIME_SCALE_IS_PTP, // time scale is PTP/TAI, else arbitrary - PTP_CFG_BIT_V1_HW_COMPAT, - PTP_CFG_BIT_CAN_BE_UNICAST_SLAVE, - PTP_CFG_BIT_CAN_BE_MULTICAST_MASTER, - PTP_CFG_BIT_CAN_BE_UNICAST_MASTER + 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 */ }; #define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_BIT_TIME_SCALE_IS_PTP ) @@ -4249,75 +4658,159 @@ enum #define PTP_CFG_MSK_SUPPORT_PTP_UNICAST ( PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE | \ PTP_CFG_MSK_CAN_BE_UNICAST_MASTER ) +/** + * @brief Derive a "supported PTP roles" bit mask from PTP_CFG_INFO::supp_flags + * + * 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. + */ +#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) -// Set Multicast as default -#define _get_supp_ptp_roles( _r ) ((((_r) & ~3UL) >> PTP_CFG_BIT_V1_HW_COMPAT ) | 1UL) -// The MBG_HOSTNAME type can hold a host's fully qualified domain name (FQDN), -// or the ASCII string of a numeric IP address. -// 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. +/** + * @brief A host's fully qualified domain name (FQDN), or a numeric IP address string + * + * In theory each single component (host name, domain name, top level domain name) + * of a FQDN can have up to 63 characters, but the overall length is limited to + * 255 characters. We specify one more character for the trailing 0. + */ typedef char MBG_HOSTNAME[256]; + +/** + * @brief Limits to be considered when specifying PTP unicast masters + */ typedef struct { - MBG_HOSTNAME gm_host; /**< grandmaster's hostname or IP address */ - PTP_CLOCK_IDENTITY gm_clock_id; /**< use clock ID of master port, or FF:FF:FF:FF:FF:FF:FF:FF as wildcard */ - uint16_t gm_port_id; /**< use target port ID of master port (e.g. '1') or 0xFFFF as wildcard */ - int16_t sync_interval; /**< log 2 */ - int16_t announce_interval; /**< log 2 */ - int16_t delay_request_interval; /**< log 2 */ - uint16_t message_duration; /**< time period until master stops sending the messages */ - uint16_t reserved; - uint32_t flags; - -} PTP_UNICAST_CFG_SETTINGS; - -#define _mbg_swab_ptp_unicast_cfg_settings( _p ) \ + uint16_t n_supp_master; /**< number of unicast masters which can be specified */ + int16_t sync_intv_min; /**< log2 of minimum sync interval [s] */ + int16_t sync_intv_max; /**< log2 of maximum sync interval [s] */ + int16_t ann_intv_min; /**< log2 of minimum announce interval [s] */ + int16_t ann_intv_max; /**< log2 of maximum announce interval [s] */ + int16_t delay_req_intv_min; /**< log2 of minimum delay request interval [s] */ + int16_t delay_req_intv_max; /**< log2 of maximum delay request interval [s] */ + uint16_t reserved_0; /**< reserved, currently always 0 */ + uint32_t supp_flags; /**< a bit mask indicating which flags are supported */ + uint32_t reserved_1; /**< reserved, currently always 0 */ + +} PTP_UC_MASTER_CFG_LIMITS; + +#define _mbg_swab_ptp_uc_master_cfg_limits( _p ) \ +{ \ + _mbg_swab16( &(_p)->n_supp_master ); \ + _mbg_swab16( &(_p)->sync_intv_min ); \ + _mbg_swab16( &(_p)->sync_intv_max ); \ + _mbg_swab16( &(_p)->ann_intv_min ); \ + _mbg_swab16( &(_p)->ann_intv_max ); \ + _mbg_swab16( &(_p)->delay_req_intv_min ); \ + _mbg_swab16( &(_p)->delay_req_intv_max ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} + + +/** + * @brief Specification of unicast masters + * + * 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. + */ +typedef struct +{ + MBG_HOSTNAME gm_host; /**< grandmaster's hostname or IP address */ + PTP_CLOCK_IDENTITY gm_clock_id; /**< use clock ID of master port, or FF:FF:FF:FF:FF:FF:FF:FF as wildcard */ + uint16_t gm_port_id; /**< use target port ID of master port (e.g. '1') or 0xFFFF as wildcard */ + int16_t sync_intv; /**< log2 of sync interval [s] */ + int16_t ann_intv; /**< log2 of announce interval [s] */ + int16_t delay_req_intv; /**< log2 of delay request interval [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 */ + +} PTP_UC_MASTER_SETTINGS; + +#define _mbg_swab_ptp_uc_master_settings( _p ) \ { \ _mbg_swab_ptp_clock_identity( &(_p)->gm_clock_id ); \ _mbg_swab16( &(_p)->gm_port_id ); \ - _mbg_swab16( &(_p)->sync_interval ); \ - _mbg_swab16( &(_p)->announce_interval ); \ - _mbg_swab16( &(_p)->delay_request_interval ); \ + _mbg_swab16( &(_p)->sync_intv ); \ + _mbg_swab16( &(_p)->ann_intv ); \ + _mbg_swab16( &(_p)->delay_req_intv ); \ + _mbg_swab32( &(_p)->fix_offset ); \ _mbg_swab16( &(_p)->message_duration ); \ - _mbg_swab16( &(_p)->reserved ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->flags ); \ } +/** + * @brief Specification of a certain unicast master + */ +typedef struct +{ + uint32_t idx; /**< index, 0..(PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1) */ + PTP_UC_MASTER_SETTINGS settings; /**< specification for the unicast master with that index */ + +} PTP_UC_MASTER_SETTINGS_IDX; + +#define _mbg_swab_ptp_uc_master_settings_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ +} + +/** + * @brief Capabilities and current settings of a unicast master + */ typedef struct { - PTP_UNICAST_CFG_SETTINGS settings; + PTP_UC_MASTER_SETTINGS settings; /**< current settings */ + uint32_t reserved; /**< reserved, currently always 0 */ + uint32_t flags; /**< reserved, currently always 0 */ - int16_t sync_interval_min; // log 2 - int16_t sync_interval_max; // log 2 - int16_t announce_interval_min; // log 2 - int16_t announce_interval_max; // log 2 - int16_t delay_request_interval_min; // log 2 - int16_t delay_request_interval_max; // log 2 +} PTP_UC_MASTER_INFO; - uint32_t supported_flags; - uint32_t reserved; +#define _mbg_swab_ptp_uc_master_info( _p ) \ +{ \ + _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} -} PTP_UNICAST_CFG_INFO; -#define _mbg_swab_ptp_unicast_cfg_info( _p ) \ -{ \ - _mbg_swab_ptp_unicast_cfg_settings( &(_p)->settings ); \ - _mbg_swab16( &(_p)->sync_interval_min ); \ - _mbg_swab16( &(_p)->sync_interval_max ); \ - _mbg_swab16( &(_p)->announce_interval_min ); \ - _mbg_swab16( &(_p)->announce_interval_max ); \ - _mbg_swab16( &(_p)->delay_request_interval_min ); \ - _mbg_swab16( &(_p)->delay_request_interval_max ); \ - _mbg_swab32( &(_p)->supported_flags ); \ - _mbg_swab32( &(_p)->reserved ); \ +/** + * @brief Capabilities and current settings of a specific unicast master + */ +typedef struct +{ + uint32_t idx; /**< index, 0..(PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1) */ + PTP_UC_MASTER_INFO info; /**< capabilities and current settings */ + +} PTP_UC_MASTER_INFO_IDX; + +#define _mbg_swab_ptp_uc_master_info_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_uc_master_info( &(_p)->info ); \ } +/** @} group_ptp */ + + /*------------------------------------------------------------------------*/ @@ -4411,8 +4904,8 @@ typedef struct /** - @brief GPS UTC correction parameters -*/ + * @brief GPS UTC correction parameters + */ typedef struct { CSUM csum; /**< Checksum of the remaining bytes */ diff --git a/mbglib/common/lan_util.c b/mbglib/common/lan_util.c new file mode 100755 index 0000000..c9c221f --- /dev/null +++ b/mbglib/common/lan_util.c @@ -0,0 +1,197 @@ + +/************************************************************************** + * + * $Id: lan_util.c 1.1.1.2 2011/04/20 16:08:55 martin TRASH martin $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Utility functions useful for network programming. + * + * ----------------------------------------------------------------------- + * $Log: lan_util.c $ + * Revision 1.1.1.2 2011/04/20 16:08:55 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.1 2011/03/04 10:01:32Z martin + * Initial revision. + * + **************************************************************************/ + +#define _LAN_UTIL + #include <lan_util.h> +#undef _LAN_UTIL + +#include <stdio.h> + + +#if defined( __BORLANDC__ ) \ + && ( __BORLANDC__ <= 0x410 ) // BC3.1 defines 0x410 ! + + +#include <stdarg.h> + +static /*HDR*/ +int snprintf( char *s, size_t max_len, const char *fmt, ... ) +{ + int n; + va_list arg_list; + + va_start( arg_list, fmt ); + n = vsprintf( s, fmt, arg_list ); + va_end( arg_list ); + + return n; + +} // snprintf + +#endif + + + +/*HDR*/ +/** + * @brief Print a MAC ID or similar array of octets to a string. + * + * @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 overall number of characters printed to the string + */ +int snprint_octets( char *s, size_t max_len, const uint8_t *octets, + int num_octets, char sep, const char *info ) +{ + int n = 0; + int i; + + if ( info ) + n += snprintf( 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( &s[n], max_len - n, "%02X", octets[i] ); + } + + return n; + +} // snprint_octets + + + +/*HDR*/ +/** + * @brief Set a MAC ID or a similar array of bytes from a string. + * + * @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 octets decoded from the string + */ +int str_to_octets( uint8_t *octets, int num_octets, const char *s ) +{ + char *cp = (char *) s; + int i; + + // don't use strtok() since that functions modifies the original string + for ( i = 0; i < num_octets; ) + { + octets[i] = (uint8_t) strtoul( cp, &cp, 16 ); + i++; + + if ( *cp == 0 ) + break; // end of string + + if ( ( *cp != MAC_SEP_CHAR ) && ( *cp != MAC_SEP_CHAR_ALT ) ) + break; // invalid character + + cp++; + } + + return i; + +} // str_to_octets + + + +/*HDR*/ +/** + * @brief Print an IPv4 address to a dotted quad format string. + * + * @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 overall number of characters printed to the string + */ +int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr, const char *info ) +{ + int n = 0; + + if ( info ) + n += snprintf( s, max_len, "%s", info ); + + 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; + +} // snprint_ip4_addr + + + +/*HDR*/ +/** + * @brief Convert a string to an IP4_ADDR. + * + * @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 >= 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 '.' + */ +int str_to_ip4_addr( IP4_ADDR *p, const char *s ) +{ + IP4_ADDR tmp_ip4_addr = 0; + char *cp; + int i; + + for ( i = 0, cp = (char *) s; ; ) + { + unsigned long ul = strtoul( cp, &cp, 10 ); + + if ( ul > 255 ) // invalid number + return -1; + + tmp_ip4_addr |= ul << ( 8 * (3 - i) ); + + if ( ++i >= 4 ) + break; // done + + if ( *cp != '.' ) + return -2; // invalid string format, dot expected + + cp++; // skip dot + } + + if ( p ) + *p = tmp_ip4_addr; + + return cp - s; // success + +} // str_to_ip4_addr + diff --git a/mbglib/common/lan_util.h b/mbglib/common/lan_util.h new file mode 100755 index 0000000..d7ee5e3 --- /dev/null +++ b/mbglib/common/lan_util.h @@ -0,0 +1,138 @@ + +/************************************************************************** + * + * $Id: lan_util.h 1.1.1.1 2011/04/20 16:09:02 martin TRASH martin $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for lan_util.c. + * + * ----------------------------------------------------------------------- + * $Log: lan_util.h $ + * Revision 1.1.1.1 2011/04/20 16:09:02 martin + * Revision 1.1 2011/03/04 10:01:32 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _LAN_UTIL_H +#define _LAN_UTIL_H + + +/* Other headers to be included */ + +#include <gpsdefs.h> + +#include <stdlib.h> + + +#ifdef _LAN_UTIL + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#if defined( _USE_PACK ) // set byte alignment + #pragma pack( 1 ) +#endif + + +#if !defined( MAC_SEP_CHAR ) + #define MAC_SEP_CHAR ':' // character used to separate octets of a MAC ID +#endif + +#if !defined( MAC_SEP_CHAR_ALT ) + #define MAC_SEP_CHAR_ALT '-' // alternate character +#endif + + + +/* function prototypes: */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief Print a MAC ID or similar array of octets to a string. + * + * @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 overall number of characters printed to the string + */ + int snprint_octets( char *s, size_t max_len, const uint8_t *octets, int num_octets, char sep, const char *info ) ; + + /** + * @brief Set a MAC ID or a similar array of bytes from a string. + * + * @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 octets decoded from the string + */ + int str_to_octets( uint8_t *octets, int num_octets, const char *s ) ; + + /** + * @brief Print an IPv4 address to a dotted quad format string. + * + * @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 overall number of characters printed to the string + */ + int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr, const char *info ) ; + + /** + * @brief Convert a string to an IP4_ADDR. + * + * @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 >= 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 '.' + */ + int str_to_ip4_addr( IP4_ADDR *p, const char *s ) ; + + +/* ----- 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 /* _LAN_UTIL_H */ + diff --git a/mbglib/common/macioctl.h b/mbglib/common/macioctl.h index fb85639..172fcfe 100755 --- a/mbglib/common/macioctl.h +++ b/mbglib/common/macioctl.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: macioctl.h 1.33.1.13 2011/03/23 16:50:30 martin TRASH martin $ + * $Id: macioctl.h 1.33.1.17.1.3 2011/04/19 15:05:44 martin TRASH martin $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,6 +11,21 @@ * * ----------------------------------------------------------------------- * $Log: macioctl.h $ + * Revision 1.33.1.17.1.3 2011/04/19 15:05:44 martin + * PTP unicast cfg stuff ... + * Revision 1.33.1.17.1.2 2011/04/19 13:08:33 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.33.1.17.1.1 2011/04/19 09:58:38 martin + * Started PTP unicast + * 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 + * + * --- Added comments --- martin [2011/03/31 10:41:58Z] + * 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 @@ -230,7 +245,9 @@ typedef struct #define _io_unmap_mapped_mem_address( _pddev, _pin ) \ _nop_macro_fnc() -#elif defined( MBG_TGT_FREEBSD ) + #define USE_COPY_KERNEL_USER 1 + +#elif defined( MBG_TGT_BSD ) #include <sys/malloc.h> @@ -252,36 +269,6 @@ typedef struct #define _io_unmap_mapped_mem_address( _pddev, _pin ) \ goto err_inval -#elif defined( MBG_TGT_NETBSD ) - - #include <sys/malloc.h> - - #define _pcps_iob( _type, _s ) _type _s - #define _pcps_iob_arr( _type, _s, n ) _type _s[_n] - - int - copyin(const void *uaddr, void *kaddr, size_t len); // to from user to kernel - - int - copyout(const void *kaddr, void *uaddr, size_t len); // from kernel to user - - #define _pcps_iob_to_pout_size( _type, _iob, _pout, _size ) \ - if ( copyout( (_type *)(_pout), &(_iob), _size ) ) \ - goto err_to_user; - - #define _pcps_iob_from_pin_size( _type, _iob, _pin, _size ) \ - if ( copyin( &(_iob), (_type *) (_pin), _size ) ) \ - goto err_from_user; - - #define _io_wait_pcps_sec_change( _pddev, _cmd, _type, _pout ) \ - goto err_inval - - #define _io_get_mapped_mem_address( _pddev, _pout ) \ - goto err_inval - - #define _io_unmap_mapped_mem_address( _pddev, _pin ) \ - goto err_inval - #elif defined( MBG_TGT_WIN32 ) #define _pcps_iob( _type, _s ) _type _s @@ -610,7 +597,7 @@ void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts ) mbg_get_pc_cycles( &cyc_1 ); #endif - _pcps_spin_lock( &pddev->mm_lock ); + _mbg_spin_lock_acquire( &pddev->mm_lock ); #if TEST_MM_ACCESS_64 *( (volatile uint64_t *) p_ts ) = *p; @@ -632,7 +619,7 @@ void do_get_fast_hr_timestamp_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts ) #endif #endif - _pcps_spin_unlock( &pddev->mm_lock ); + _mbg_spin_lock_release( &pddev->mm_lock ); #if TEST_FRAC_ONLY p_ts->sec = 0; @@ -688,11 +675,11 @@ void do_get_fast_hr_timestamp_cycles_safe( PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYC { volatile uint32_t *p = (volatile uint32_t *) pddev->mm_tstamp_addr; - _pcps_spin_lock( &pddev->mm_lock ); + _mbg_spin_lock_acquire( &pddev->mm_lock ); mbg_get_pc_cycles( &p_ts_cyc->cycles ); p_ts_cyc->tstamp.frac = _mbg32_to_cpu( *p++ ); p_ts_cyc->tstamp.sec = _mbg32_to_cpu( *p ); - _pcps_spin_unlock( &pddev->mm_lock ); + _mbg_spin_lock_release( &pddev->mm_lock ); } // do_get_fast_hr_timestamp_cycles_safe @@ -1742,16 +1729,25 @@ int ioctl_switch( PCPS_DDEV *pddev, int ioctl_code, break; - case IOCTL_GET_PTP_UNICAST_CFG_INFO: - _io_read_gps_var_chk( pddev, PC_GPS_PTP_UNICAST_CFG, - PTP_UNICAST_CFG_INFO, pout, + case IOCTL_PTP_UC_MASTER_CFG_LIMITS: + _io_read_gps_var_chk( pddev, PC_GPS_PTP_UC_MASTER_CFG_LIMITS, + PTP_UC_MASTER_CFG_LIMITS, pout, _pcps_ddev_has_ptp_unicast( pddev ) ); break; - case IOCTL_SET_PTP_UNICAST_CFG_SETTINGS: - _io_write_gps_var_chk( pddev, PC_GPS_PTP_UNICAST_CFG, - PTP_UNICAST_CFG_SETTINGS, pin, + #if _MBG_SUPP_VAR_ACC_SIZE + case IOCTL_GET_ALL_PTP_UC_MASTER_INFO: + _io_read_gps_var_chk( pddev, PC_GPS_ALL_PTP_UC_MASTER_INFO, + ALL_PTP_UC_MASTER_INFO, pout, + _pcps_ddev_has_ptp_unicast( pddev ) ); + break; + #endif + + + case IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX: + _io_write_gps_var_chk( pddev, PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, + PTP_UC_MASTER_SETTINGS_IDX, pin, _pcps_ddev_has_ptp_unicast( pddev ) ); break; @@ -1866,15 +1862,15 @@ err_access: return rc; // return the rc from the low level routine -#if defined( MBG_TGT_LINUX ) || defined( MBG_TGT_NETBSD ) +#if defined( USE_COPY_KERNEL_USER ) err_to_user: - return -EFAULT; + return MBG_ERR_COPY_TO_USER; err_from_user: - return -EFAULT; + return MBG_ERR_COPY_FROM_USER; -#endif // defined( MBG_TGT_LINUX ) +#endif // defined( USE_COPY_KERNEL_USER ) } // ioctl_switch diff --git a/mbglib/common/mbg_arch.h b/mbglib/common/mbg_arch.h index cdf6f01..4878922 100755 --- a/mbglib/common/mbg_arch.h +++ b/mbglib/common/mbg_arch.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_arch.h 1.3.1.2 2011/02/09 15:46:48 martin TRASH $ + * $Id: mbg_arch.h 1.3.1.3 2011/04/12 12:55:28 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,8 @@ * * ----------------------------------------------------------------------- * $Log: mbg_arch.h $ + * 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.3 2009/06/12 13:12:37Z martin @@ -25,6 +27,7 @@ #define _MBG_ARCH_H #include <mbg_tgt.h> +#include <words.h> #if !defined( MBG_TGT_KERNEL ) #include <stdlib.h> diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h index a3c45d1..95d1111 100755 --- a/mbglib/common/mbg_tgt.h +++ b/mbglib/common/mbg_tgt.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_tgt.h 1.22.2.11 2011/03/22 10:25:26 martin TRASH $ + * $Id: mbg_tgt.h 1.22.2.12 2011/04/12 15:36:00 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,7 +11,8 @@ * * ----------------------------------------------------------------------- * $Log: mbg_tgt.h $ - * Revision 1.22.2.11 2011/03/22 10:25:26 martin + * 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 @@ -308,6 +309,7 @@ #endif #if defined( _KDD_ ) + #define MBG_TGT_KERNEL #include <ntddk.h> #else // This must not be used for kernel drivers. diff --git a/mbglib/common/mbgdevio.c b/mbglib/common/mbgdevio.c index e4f8c8b..b058f07 100755 --- a/mbglib/common/mbgdevio.c +++ b/mbglib/common/mbgdevio.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgdevio.c 1.35.1.15 2011/02/16 10:15:13 martin TRASH martin(2011.02.16.10.15.13) $ + * $Id: mbgdevio.c 1.35.1.17.1.4 2011/04/19 15:05:45 martin TRASH martin $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,18 @@ * * ----------------------------------------------------------------------- * $Log: mbgdevio.c $ + * Revision 1.35.1.17.1.4 2011/04/19 15:05:45 martin + * PTP unicast cfg stuff ... + * Revision 1.35.1.17.1.3 2011/04/19 13:08:34 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.35.1.17.1.2 2011/04/19 09:59:09 martin + * More PTP unicast cfg ... + * Revision 1.35.1.17.1.1 2011/04/18 15:30:42 martin + * Started PTP unicast + * 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 @@ -386,14 +398,14 @@ typedef struct #if !defined( _MBG_SUPP_VAR_ACC_SIZE ) // If this symbol has not yet been defined then mbgioctl.h has probably // not yet been included. On target systems where the hardware is accessed - // directly without a kernel driver variable buffer sizes are supported, + // directly without a kernel driver variable buffer sizes are supported, // so we set the default to 1. #define _MBG_SUPP_VAR_ACC_SIZE 1 #endif #if !defined( _mbgdevio_chk_cond ) - // If the macro has not been defined previously then + // If the macro has not been defined previously then // it is not be required for the target environment and // is defined as empty string. #define _mbgdevio_chk_cond( _cond ); @@ -2299,8 +2311,8 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_irig_ctrl_bits( MBG_DEV_HANDLE dh, int *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 ) +_MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh, + MBG_IRIG_CTRL_BITS *p ) { _mbgdevio_vars(); _mbgdevio_read_var( dh, PCPS_GET_IRIG_CTRL_BITS, IOCTL_GET_IRIG_CTRL_BITS, p ); @@ -2346,8 +2358,8 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_raw_irig_data( MBG_DEV_HANDLE dh, int *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 ) +_MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh, + MBG_RAW_IRIG_DATA *p ) { _mbgdevio_vars(); _mbgdevio_read_var( dh, PCPS_GET_RAW_IRIG_DATA, IOCTL_GET_RAW_IRIG_DATA, p ); @@ -2376,8 +2388,8 @@ _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh, @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 ) +_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; @@ -2432,8 +2444,8 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_irig_time( MBG_DEV_HANDLE dh, int *p ) @see mbg_dev_has_irig_time() */ -_MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh, - PCPS_IRIG_TIME *p ) +_MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh, + PCPS_IRIG_TIME *p ) { _mbgdevio_vars(); _mbgdevio_read_var( dh, PCPS_GIVE_IRIG_TIME, IOCTL_GET_IRIG_TIME, p ); @@ -4201,8 +4213,8 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int @see mbg_get_fast_hr_timestamp_comp() @see mbg_get_fast_hr_timestamp() */ -_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_cycles( MBG_DEV_HANDLE dh, - PCPS_TIME_STAMP_CYCLES *p ) +_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(); @@ -4279,8 +4291,8 @@ _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_comp( MBG_DEV_HANDLE dh, @see mbg_get_fast_hr_timestamp_comp() @see mbg_get_fast_hr_timestamp_cycles() */ -_MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp( MBG_DEV_HANDLE dh, - PCPS_TIME_STAMP *p ) +_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(); @@ -5202,7 +5214,8 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_ptp( MBG_DEV_HANDLE dh, int *p ) @return ::MBG_SUCCESS or error code returned by device I/O control function. @see mbg_get_ptp_state() - @see mbg_get_ptp_unicast_cfg_info() + @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 ) @@ -5316,16 +5329,75 @@ _MBG_API_ATTR int _MBG_API mbg_set_ptp_cfg_settings( MBG_DEV_HANDLE dh, @see mbg_dev_has_ptp_unicast() @see mbg_set_ptp_unicast_cfg_settings() */ -_MBG_API_ATTR int _MBG_API mbg_get_ptp_unicast_cfg_info( MBG_DEV_HANDLE dh, PTP_UNICAST_CFG_INFO *p ) +_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_read_gps_var_chk( dh, PC_GPS_PTP_UNICAST_CFG, - IOCTL_GET_PTP_UNICAST_CFG_INFO, p, + _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 ) ); - _mbg_swab_ptp_unicast_cfg_info( p ); + _mbg_swab_ptp_uc_master_cfg_limits( p ); + return _mbgdevio_ret_val; + +} // mbg_get_ptp_uc_master_cfg_limits + + + +/*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 +*/ +_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 ) +{ + _mbgdevio_vars(); + + #if _MBG_SUPP_VAR_ACC_SIZE + _mbgdevio_read_gps_chk( dh, PC_GPS_ALL_PTP_UC_MASTER_INFO, + IOCTL_GET_ALL_PTP_UC_MASTER_INFO, pii, + p_umsl->n_supp_master * sizeof( pii[0] ), + _pcps_ddev_has_ptp_unicast( dh ) ); + #else + if ( p_umsl && p_umsl->n_supp_master ) + _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 ); + #endif + + #if defined( MBG_ARCH_BIG_ENDIAN ) + if ( rc == MBG_SUCCESS ) + { + int i; + for ( i = 0; i < p_umsl->n_supp_master; i++ ) + { + PTP_UC_MASTER_INFO_IDX *p = &pii[i]; + _mbg_swab_ptp_uc_master_info_idx( p ); + } + } + #endif + return _mbgdevio_ret_val; -} // mbg_get_ptp_unicast_cfg_info +} // mbg_get_all_ptp_uc_master_info @@ -5345,21 +5417,21 @@ _MBG_API_ATTR int _MBG_API mbg_get_ptp_unicast_cfg_info( MBG_DEV_HANDLE dh, PTP_ @see mbg_get_ptp_cfg_info() @see mbg_get_ptp_unicast_cfg_info() */ -_MBG_API_ATTR int _MBG_API mbg_set_ptp_unicast_cfg_settings( MBG_DEV_HANDLE dh, - const PTP_UNICAST_CFG_SETTINGS *p ) +_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(); #if defined( MBG_ARCH_BIG_ENDIAN ) - PTP_UNICAST_CFG_SETTINGS tmp = *p; - _mbg_swab_ptp_unicast_cfg_settings( &tmp ); + PTP_UC_MASTER_SETTINGS_IDX tmp = *p; + _mbg_swab_ptp_uc_master_settings_idx( &tmp ); p = &tmp; #endif - _mbgdevio_write_gps_var_chk( dh, PC_GPS_PTP_UNICAST_CFG, - IOCTL_SET_PTP_UNICAST_CFG_SETTINGS, p, + _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; -} // mbg_set_ptp_unicast_cfg_settings +} // mbg_set_ptp_uc_master_settings_idx @@ -5776,7 +5848,7 @@ MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR mbg_xhrt_poll_thread_fnc( void *p_voi } - _mbg_mutex_lock( &p->mutex ); + _mbg_crit_sect_enter( &p->crit_sect ); if ( rc == MBG_SUCCESS ) { @@ -5791,7 +5863,7 @@ MBG_THREAD_FNC_RET_VAL MBG_THREAD_FNC_ATTR mbg_xhrt_poll_thread_fnc( void *p_voi sleep_ms = p->sleep_ms; - _mbg_mutex_unlock( &p->mutex ); + _mbg_crit_sect_leave( &p->crit_sect ); if ( rc == MBG_SUCCESS ) @@ -5843,7 +5915,7 @@ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_create( MBG_POLL_THREAD_INFO *p_ p_pti->xhrt_info.dh = dh; p_pti->xhrt_info.freq_hz = freq_hz; p_pti->xhrt_info.sleep_ms = sleep_ms ? sleep_ms : 1000; // sleep 1 second by default - _mbg_mutex_init( &p_pti->xhrt_info.mutex ); + _mbg_crit_sect_init( &p_pti->xhrt_info.crit_sect ); rc = mbg_thread_create( &p_pti->ti, mbg_xhrt_poll_thread_fnc, p_pti ); @@ -5873,7 +5945,7 @@ _MBG_API_ATTR int _MBG_API mbg_xhrt_poll_thread_stop( MBG_POLL_THREAD_INFO *p_pt int rc = mbg_thread_stop( &p_pti->ti ); if ( rc == MBG_SUCCESS ) - _mbg_mutex_deinit( &p_pti->xhrt_info.mutex ); + _mbg_crit_sect_destroy( &p_pti->xhrt_info.crit_sect ); return rc; @@ -5892,11 +5964,11 @@ int mbg_get_xhrt_data( MBG_XHRT_INFO *p, uint64_t *tstamp, MBG_XHRT_VARS *vars ) mbg_get_pc_cycles( &cyc_now ); - _mbg_mutex_lock( &p->mutex ); + _mbg_crit_sect_enter( &p->crit_sect ); xhrt_vars = p->vars; freq_hz = p->freq_hz; ioctl_status = p->ioctl_status; - _mbg_mutex_unlock( &p->mutex ); + _mbg_crit_sect_leave( &p->crit_sect ); if ( freq_hz && xhrt_vars.pcps_hr_tstamp64 ) { @@ -6024,10 +6096,10 @@ _MBG_API_ATTR int _MBG_API mbg_get_xhrt_cycles_frequency( MBG_XHRT_INFO *p, MBG_ MBG_PC_CYCLES_FREQUENCY freq_hz; int ioctl_status; - _mbg_mutex_lock( &p->mutex ); + _mbg_crit_sect_enter( &p->crit_sect ); freq_hz = p->freq_hz; ioctl_status = p->ioctl_status; - _mbg_mutex_unlock( &p->mutex ); + _mbg_crit_sect_leave( &p->crit_sect ); if ( p_freq_hz ) *p_freq_hz = freq_hz; diff --git a/mbglib/common/mbgdevio.h b/mbglib/common/mbgdevio.h index d1910e7..568c7c4 100755 --- a/mbglib/common/mbgdevio.h +++ b/mbglib/common/mbgdevio.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgdevio.h 1.39.1.13 2011/02/15 14:26:22 martin TRASH martin(2011.02.16.09.52.26) $ + * $Id: mbgdevio.h 1.39.1.15.1.4 2011/04/19 15:05:47 martin TRASH martin $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,20 @@ * * ----------------------------------------------------------------------- * $Log: mbgdevio.h $ - * Revision 1.39.1.13 2011/02/15 14:26:22 martin + * Revision 1.39.1.15.1.4 2011/04/19 15:05:47 martin + * PTP unicast cfg stuff ... + * Revision 1.39.1.15.1.3 2011/04/19 13:08:36 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.39.1.15.1.2 2011/04/19 10:00:08 martin + * More PTP unicast cfg ... + * Revision 1.39.1.15.1.1 2011/04/18 15:30:52 martin + * Started PTP unicast + * 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 @@ -168,10 +181,11 @@ /* Other headers to be included */ -#include <mbggeo.h> #include <mbg_tgt.h> #include <mbg_arch.h> +#include <mbgmutex.h> #include <mbgerror.h> +#include <mbggeo.h> #include <pcpsdev.h> #include <pcpsutil.h> #include <pci_asic.h> @@ -325,12 +339,6 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1]; #define MBG_THREAD_FNC_RET_VAL void * #define _mbg_thread_exit( _v ) return (void *) (_v) - #define MBG_MUTEX pthread_mutex_t - #define _mbg_mutex_init( _pm ) pthread_mutex_init( (_pm), NULL ) - #define _mbg_mutex_deinit( _pm ) _nop_macro_fnc() - #define _mbg_mutex_lock( _pm ) pthread_mutex_lock( (_pm) ) - #define _mbg_mutex_unlock( _pm ) pthread_mutex_unlock( (_pm) ) - #endif #elif defined( MBG_TGT_WIN32 ) @@ -347,12 +355,6 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1]; #define MBG_THREAD_FNC_RET_VAL DWORD #define _mbg_thread_exit( _v ) ExitThread( _v ); return (_v) - #define MBG_MUTEX CRITICAL_SECTION - #define _mbg_mutex_init( _pm ) InitializeCriticalSection( (_pm) ) - #define _mbg_mutex_deinit( _pm ) DeleteCriticalSection( (_pm) ) - #define _mbg_mutex_lock( _pm ) EnterCriticalSection( (_pm) ) - #define _mbg_mutex_unlock( _pm ) LeaveCriticalSection( (_pm) ) - #endif // target specific @@ -413,26 +415,6 @@ typedef char MBG_HW_NAME[PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1]; #endif -#if !defined( MBG_MUTEX ) - #define MBG_MUTEX int -#endif - -#if !defined( _mbg_mutex_init ) - #define _mbg_mutex_init( _pm ) _nop_macro_fnc() -#endif - -#if !defined( _mbg_mutex_deinit ) - #define _mbg_mutex_deinit( _pm ) _nop_macro_fnc() -#endif - -#if !defined( _mbg_mutex_lock ) - #define _mbg_mutex_lock( _pm ) _nop_macro_fnc() -#endif - -#if !defined( _mbg_mutex_unlock ) - #define _mbg_mutex_unlock( _pm ) _nop_macro_fnc() -#endif - typedef struct { MBG_THREAD_ID thread_id; @@ -457,7 +439,7 @@ typedef struct MBG_PC_CYCLES_FREQUENCY freq_hz; int ioctl_status; int sleep_ms; - MBG_MUTEX mutex; + MBG_CRIT_SECT crit_sect; MBG_DEV_HANDLE dh; } MBG_XHRT_INFO; @@ -1162,7 +1144,7 @@ extern "C" { @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 ) ; + _MBG_API_ATTR int _MBG_API mbg_get_irig_ctrl_bits( MBG_DEV_HANDLE dh, MBG_IRIG_CTRL_BITS *p ) ; /** Check if a specific device supports the mbg_get_raw_irig_data() call. @@ -1191,7 +1173,7 @@ extern "C" { @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 ) ; + _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ; /** Read a ::MBG_RAW_IRIG_DATA type just after a second change which contains all data @@ -1210,7 +1192,7 @@ extern "C" { @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 ) ; + _MBG_API_ATTR int _MBG_API mbg_get_raw_irig_data_on_sec_change( MBG_DEV_HANDLE dh, MBG_RAW_IRIG_DATA *p ) ; /** Check if a specific device supports the mbg_get_irig_time() call. @@ -1239,7 +1221,7 @@ extern "C" { @see mbg_dev_has_irig_time() */ - _MBG_API_ATTR int _MBG_API mbg_get_irig_time( MBG_DEV_HANDLE dh, PCPS_IRIG_TIME *p ) ; + _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. @@ -2115,7 +2097,7 @@ extern "C" { @see mbg_get_fast_hr_timestamp_comp() @see mbg_get_fast_hr_timestamp() */ - _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp_cycles( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP_CYCLES *p ) ; + _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, @@ -2151,7 +2133,7 @@ extern "C" { @see mbg_get_fast_hr_timestamp_comp() @see mbg_get_fast_hr_timestamp_cycles() */ - _MBG_API_ATTR int _MBG_API mbg_get_fast_hr_timestamp( MBG_DEV_HANDLE dh, PCPS_TIME_STAMP *p ) ; + _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. @@ -2712,7 +2694,8 @@ extern "C" { @return ::MBG_SUCCESS or error code returned by device I/O control function. @see mbg_get_ptp_state() - @see mbg_get_ptp_unicast_cfg_info() + @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 ) ; @@ -2778,7 +2761,30 @@ extern "C" { @see mbg_dev_has_ptp_unicast() @see mbg_set_ptp_unicast_cfg_settings() */ - _MBG_API_ATTR int _MBG_API mbg_get_ptp_unicast_cfg_info( MBG_DEV_HANDLE dh, PTP_UNICAST_CFG_INFO *p ) ; + _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 +*/ + _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. @@ -2795,7 +2801,7 @@ extern "C" { @see mbg_get_ptp_cfg_info() @see mbg_get_ptp_unicast_cfg_info() */ - _MBG_API_ATTR int _MBG_API mbg_set_ptp_unicast_cfg_settings( MBG_DEV_HANDLE dh, const PTP_UNICAST_CFG_SETTINGS *p ) ; + _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 diff --git a/mbglib/common/mbgerror.h b/mbglib/common/mbgerror.h index f51c61d..714dd45 100755 --- a/mbglib/common/mbgerror.h +++ b/mbglib/common/mbgerror.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgerror.h 1.4 2008/12/05 13:28:50 martin REL_M $ + * $Id: mbgerror.h 1.5.1.1 2011/04/20 16:09:19 martin TRASH martin $ * $Name: $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany @@ -12,6 +12,9 @@ * * ----------------------------------------------------------------------- * $Log: mbgerror.h $ + * Revision 1.5.1.1 2011/04/20 16:09:19 martin + * Revision 1.5 2011/03/31 10:56:17 martin + * Added MBG_ERR_COPY_TO_USER and MBG_ERR_COPY_FROM_USER. * Revision 1.4 2008/12/05 13:28:50 martin * Added new code MBG_ERR_IRQ_UNSAFE. * Revision 1.3 2008/02/26 14:50:14Z daniel @@ -44,7 +47,7 @@ /* Start of header body */ -/** +/** @defgroup group_error_codes Error codes Error codes used with Meinberg devices and drivers. @@ -54,13 +57,14 @@ 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 + @{ */ -// Attention!! -// These error codes below must fit exactly to the corresponding codes that are evaluated in user space. -// For Windows, they are located in messages.mc/.h in mbgsvctl.dll #define MBG_SUCCESS PCPS_SUCCESS /**< 0, no error */ @@ -99,14 +103,23 @@ #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 */ - -// Codes used with DOS TSRs only: +// 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 */ -/** @} */ // endgroup + +#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 -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 diff --git a/mbglib/common/mbgioctl.h b/mbglib/common/mbgioctl.h index e4f94f0..4e5fb94 100755 --- a/mbglib/common/mbgioctl.h +++ b/mbglib/common/mbgioctl.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgioctl.h 1.24.1.2 2011/03/22 11:19:46 martin TRASH $ + * $Id: mbgioctl.h 1.24.1.2.1.4 2011/04/19 15:28:46 martin TRASH martin $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,14 @@ * * ----------------------------------------------------------------------- * $Log: mbgioctl.h $ + * Revision 1.24.1.2.1.4 2011/04/19 15:28:46 martin + * Cleanup. + * Revision 1.24.1.2.1.3 2011/04/19 15:05:48 martin + * PTP unicast cfg stuff ... + * Revision 1.24.1.2.1.2 2011/04/19 13:08:37 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.24.1.2.1.1 2011/04/18 15:30:59 martin + * Started PTP unicast * 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 @@ -289,8 +297,8 @@ #define IOCTL_SET_GPS_ANT_CABLE_LEN _MBG_IOW( IOTYPE, 0x38, ANT_CABLE_LEN ) #define IOCTL_GET_GPS_RECEIVER_INFO _MBG_IOR( IOTYPE, 0x39, RECEIVER_INFO ) -#define IOCTL_GET_GPS_ALL_STR_TYPE_INFO _MBG_IO( IOTYPE, 0x3A ) // size variable -#define IOCTL_GET_GPS_ALL_PORT_INFO _MBG_IO( IOTYPE, 0x3B ) // size variable +#define IOCTL_GET_GPS_ALL_STR_TYPE_INFO _MBG_IO( IOTYPE, 0x3A ) // variable size +#define IOCTL_GET_GPS_ALL_PORT_INFO _MBG_IO( IOTYPE, 0x3B ) // variable size #define IOCTL_SET_GPS_PORT_SETTINGS_IDX _MBG_IOW( IOTYPE, 0x3C, PORT_SETTINGS_IDX ) @@ -335,7 +343,7 @@ #define IOCTL_GET_SYNTH_STATE _MBG_IOR( IOTYPE, 0x5C, SYNTH_STATE ) -#define IOCTL_GET_GPS_ALL_POUT_INFO _MBG_IO( IOTYPE, 0x5D ) // size variable +#define IOCTL_GET_GPS_ALL_POUT_INFO _MBG_IO( IOTYPE, 0x5D ) // variable size #define IOCTL_SET_GPS_POUT_SETTINGS_IDX _MBG_IOW( IOTYPE, 0x5E, POUT_SETTINGS_IDX ) #define IOCTL_GET_MAPPED_MEM_ADDR _MBG_IOR( IOTYPE, 0x5F, PCPS_MAPPED_MEM ) @@ -389,9 +397,11 @@ #define IOCTL_DEV_HAS_RAW_IRIG_DATA _MBG_IOR( IOTYPE, 0x82, int ) #define IOCTL_GET_RAW_IRIG_DATA _MBG_IOR( IOTYPE, 0x83, MBG_RAW_IRIG_DATA ) -#define IOCTL_DEV_HAS_PTP_UNICAST _MBG_IOR( IOTYPE, 0x84, int ) -#define IOCTL_GET_PTP_UNICAST_CFG_INFO _MBG_IOR( IOTYPE, 0x85, PTP_UNICAST_CFG_INFO ) -#define IOCTL_SET_PTP_UNICAST_CFG_SETTINGS _MBG_IOW( IOTYPE, 0x86, PTP_UNICAST_CFG_SETTINGS ) +#define IOCTL_DEV_HAS_PTP_UNICAST _MBG_IOR( IOTYPE, 0x84, int ) +#define IOCTL_PTP_UC_MASTER_CFG_LIMITS _MBG_IOR( IOTYPE, 0x85, PTP_UC_MASTER_CFG_LIMITS ) +#define IOCTL_GET_ALL_PTP_UC_MASTER_INFO _MBG_IO( IOTYPE, 0x86 ) // variable size +#define IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX _MBG_IOW( IOTYPE, 0x87, PTP_UC_MASTER_SETTINGS_IDX ) + // 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. diff --git a/mbglib/common/mbgmutex.h b/mbglib/common/mbgmutex.h new file mode 100755 index 0000000..e079914 --- /dev/null +++ b/mbglib/common/mbgmutex.h @@ -0,0 +1,259 @@ + +/************************************************************************** + * + * $Id: mbgmutex.h 1.1.1.4 2011/05/06 09:11:16 martin TRASH $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Portable macros to deal with spinlocks, mutexes, + * and critical sections. + * + * ----------------------------------------------------------------------- + * $Log: mbgmutex.h $ + * Revision 1.1.1.4 2011/05/06 09:11:16 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. + * + **************************************************************************/ + +#ifndef _MBGMUTEX_H +#define _MBGMUTEX_H + + +/* Other headers to be included */ + +#include <mbg_tgt.h> +#include <words.h> + +#ifdef _MBGMUTEX + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#if defined( MBG_TGT_KERNEL ) // definitions used in kernel space + + #if defined( MBG_TGT_WIN32 ) // Windows kernel space + + typedef KSPIN_LOCK MBG_SPINLOCK; + #define _mbg_spin_lock_init( _spl ) KeInitializeSpinLock( _spl ) + #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc() + #define _mbg_spin_lock_acquire( _spl ) KeAcquireSpinLockAtDpcLevel( _spl ) + #define _mbg_spin_lock_release( _spl ) KeReleaseSpinLockFromDpcLevel( _spl ) + + #define MBG_SPINLOCK_DEFINED 1 + + + typedef FAST_MUTEX MBG_MUTEX; + #define _mbg_mutex_init( _pmtx ) ExInitializeFastMutex( _pmtx ) + #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc() + #define _mbg_mutex_acquire( _pmtx ) ExAcquireFastMutex( _pmtx ) + #define _mbg_mutex_release( _pmtx ) ExReleaseFastMutex( _pmtx ) + + #define _MBG_MUTEX_DEFINED 1 + + #elif defined( MBG_TGT_LINUX ) // Linux kernel space + + #include <linux/spinlock.h> + #include <linux/version.h> + + #if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 26 ) ) + #include <linux/semaphore.h> + #else + #include <asm/semaphore.h> + #endif + + typedef spinlock_t MBG_SPINLOCK; + #define _mbg_spin_lock_init( _spl ) spin_lock_init( _spl ) + #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc() + #define _mbg_spin_lock_acquire( _spl ) spin_lock( _spl ) + #define _mbg_spin_lock_release( _spl ) spin_unlock( _spl ) + + #define MBG_SPINLOCK_DEFINED 1 + + + typedef struct semaphore MBG_MUTEX; + #define _mbg_mutex_init( _pmtx ) sema_init( _pmtx, 1 ) + #define _mbg_mutex_destroy( _pmtx ) _nop_macro_fnc() + #define _mbg_mutex_acquire( _pmtx ) down_interruptible( _pmtx ) + #define _mbg_mutex_release( _pmtx ) up( _pmtx ) + + #define _MBG_MUTEX_DEFINED 1 + + #elif defined( MBG_TGT_FREEBSD ) // FreeBSD kernel space + + #include <sys/lock.h> + #include <sys/mutex.h> + + typedef struct mtx MBG_SPINLOCK; + #define _mbg_spin_lock_init( _spl ) mtx_init( _spl, "mbg_spin_lock", NULL, MTX_SPIN ) + #define _mbg_spin_lock_destroy( _spl ) mtx_destroy( _spl ) + #define _mbg_spin_lock_acquire( _spl ) mtx_lock_spin( _spl ) + #define _mbg_spin_lock_release( _spl ) mtx_unlock_spin( _spl ) + + #define MBG_SPINLOCK_DEFINED 1 + + + typedef struct mtx MBG_MUTEX; + #define _mbg_mutex_init( _pmtx ) mtx_init( _pmtx, "mbg_mutex", NULL, MTX_DEF ) + #define _mbg_mutex_destroy( _pmtx ) mtx_destroy( _pmtx ) + #define _mbg_mutex_acquire( _pmtx ) mtx_lock( _pmtx ) + #define _mbg_mutex_release( _pmtx ) mtx_unlock( _pmtx ) + + #define _MBG_MUTEX_DEFINED 1 + + #elif defined( MBG_TGT_NETBSD ) + + #include <sys/mutex.h> + + // The API used below has been introduced in NetBSD 5.0 + // For earlier NetBSD versions see 'man 9 lockinit'. + + typedef kmutex_t MBG_SPINLOCK; + #define _mbg_spin_lock_init( _spl ) mutex_init( _spl, MUTEX_DEFAULT, IPL_HIGH ) + #define _mbg_spin_lock_destroy( _spl ) mutex_destroy( _spl ) + #define _mbg_spin_lock_acquire( _spl ) mutex_spin_enter( _spl ) + #define _mbg_spin_lock_release( _spl ) mutex_spin_exit( _spl ) + + #define MBG_SPINLOCK_DEFINED 1 + + + typedef kmutex_t MBG_MUTEX; + #define _mbg_mutex_init( _pmtx ) mutex_init( _pmtx, MUTEX_DEFAULT, IPL_NONE ) + #define _mbg_mutex_destroy( _spl ) mutex_destroy( _spl ) + #define _mbg_mutex_acquire( _pmtx ) mutex_enter( _pmtx ) + #define _mbg_mutex_release( _pmtx ) mutex_exit( _pmtx ) + + #define _MBG_MUTEX_DEFINED 1 + + #endif + +#else // user space applications + + #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 ) + #define _mbg_mutex_destroy( _pm ) CloseHandle( *(_pm) ); *(_pm) = INVALID_HANDLE_VALUE + #define _mbg_mutex_acquire( _pm ) WaitForSingleObject( *(_pm), INFINITE ) + #define _mbg_mutex_release( _pm ) ReleaseMutex( *(_pm) ) + + #define _MBG_MUTEX_DEFINED 1 + + // definitions used with critical sections + typedef CRITICAL_SECTION MBG_CRIT_SECT; + #define _mbg_crit_sect_init( _pcs ) InitializeCriticalSection( (_pcs) ) + #define _mbg_crit_sect_destroy( _pcs ) DeleteCriticalSection( (_pcs) ) + #define _mbg_crit_sect_enter( _pcs ) EnterCriticalSection( (_pcs) ) + #define _mbg_crit_sect_leave( _pcs ) LeaveCriticalSection( (_pcs) ) + + #define _MBG_CRIT_SECT_DEFINED 1 + + #elif defined( MBG_TGT_UNIX ) // Unix user space use pthread library + + #include <pthread.h> + + // Mutex types: + // PTHREAD_MUTEX_INITIALIZER /* Fast */ + // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP /* Recursive */ + // PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* Errorcheck */ + typedef pthread_mutex_t MBG_MUTEX; + #define _mbg_mutex_init( _pm ) pthread_mutex_init( (_pm), NULL ) + #define _mbg_mutex_destroy( _pm ) pthread_mutex_destroy( (_pm) ) + #define _mbg_mutex_acquire( _pm ) pthread_mutex_lock( (_pm) ) + #define _mbg_mutex_release( _pm ) pthread_mutex_unlock( (_pm) ) + + #define _MBG_MUTEX_DEFINED 1 + + // For critical sections use defaults specified below + + #elif defined( MBG_TGT_DOS ) + + typedef int MBG_MUTEX; // just a dummy declaration + + #define _MBG_MUTEX_DEFINED 1 + + #endif + +#endif + + +#if !defined( MBG_SPINLOCK_DEFINED ) + + #define _mbg_spin_lock_init( _spl ) _nop_macro_fnc() + #define _mbg_spin_lock_destroy( _spl ) _nop_macro_fnc() + #define _mbg_spin_lock_acquire( _spl ) _nop_macro_fnc() + #define _mbg_spin_lock_release( _spl ) _nop_macro_fnc() + +#endif + + +#if !defined( _MBG_MUTEX_DEFINED ) + + #define _MBG_MUTEX_DEFINED 1 + + typedef MBG_CRIT_SECT MBG_MUTEX; + + #define _mbg_mutex_init( _pm ) _nop_macro_fnc() + #define _mbg_mutex_destroy( _pm ) _nop_macro_fnc() + #define _mbg_mutex_acquire( _pm ) _nop_macro_fnc() + #define _mbg_mutex_release( _pm ) _nop_macro_fnc() + +#endif + + +#if !defined( _MBG_CRIT_SECT_DEFINED ) + + // use mutex by default, e.g. with the pthread library + + #define _MBG_CRIT_SECT_DEFINED 1 + + typedef MBG_MUTEX MBG_CRIT_SECT; + #define _mbg_crit_sect_init _mbg_mutex_init + #define _mbg_crit_sect_destroy _mbg_mutex_destroy + #define _mbg_crit_sect_enter _mbg_mutex_acquire + #define _mbg_crit_sect_leave _mbg_mutex_release + +#endif + + + +/* function prototypes: */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + +/* (no header definitions found) */ + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _MBGMUTEX_H */ diff --git a/mbglib/common/mbgtime.h b/mbglib/common/mbgtime.h index c7ab670..ba6900f 100755 --- a/mbglib/common/mbgtime.h +++ b/mbglib/common/mbgtime.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgtime.h 1.17.1.4 2011/02/09 15:46:48 martin TRASH $ + * $Id: mbgtime.h 1.17.1.6 2011/05/06 09:03:12 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,11 @@ * * ----------------------------------------------------------------------- * $Log: mbgtime.h $ - * Revision 1.17.1.4 2011/02/09 15:46:48 martin + * 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 @@ -61,8 +65,9 @@ #include <gpsdefs.h> -#if !defined( MBG_ARCH_ARM ) && \ - !defined( MBG_TGT_KERNEL ) +#if _IS_MBG_FIRMWARE \ + || defined( MBG_TGT_WIN32 ) \ + || defined( MBG_TGT_DOS ) #include <time.h> #endif diff --git a/mbglib/common/parmpcps.h b/mbglib/common/parmpcps.h index eafe487..7095d48 100755 --- a/mbglib/common/parmpcps.h +++ b/mbglib/common/parmpcps.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: parmpcps.h 1.6 2011/02/16 10:13:12 martin TEST $ + * $Id: parmpcps.h 1.7 2011/04/01 10:30:51 martin REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,8 @@ * * ----------------------------------------------------------------------- * $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 @@ -102,7 +104,7 @@ extern "C" { * * Parameters: (RECEIVER_INFO *) _p */ -#define _setup_default_receiver_info_dcf( _p, _pdev ); \ +#define _setup_default_receiver_info_dcf( _p, _pdev ) \ do \ { \ memset( (_p), 0, sizeof( *(_p) ) ); \ @@ -115,7 +117,7 @@ do \ } while ( 0 ) -#define DEFAULT_MAX_STR_TYPE 2 //##++DEFAULT_N_STR_TYPE_GPS +#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 diff --git a/mbglib/common/pci_asic.h b/mbglib/common/pci_asic.h index 2feef9b..b641e51 100755 --- a/mbglib/common/pci_asic.h +++ b/mbglib/common/pci_asic.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pci_asic.h 1.16 2010/04/16 11:12:21 martin REL_M $ + * $Id: pci_asic.h 1.18.1.1 2011/05/06 13:47:48 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,13 @@ * * ----------------------------------------------------------------------- * $Log: pci_asic.h $ - * Revision 1.16 2010/04/16 11:12:21 martin + * Revision 1.18.1.1 2011/05/06 13:47:48 martin + * Revision 1.18 2011/04/06 12:31:48 martin + * Updated minor versions for PTP270PEX and GPS180PEX. + * Revision 1.17 2010/09/10 14:03:25Z martin + * Support GPS180PEX and TCR180PEX. + * New table initializer to simplify EPLD version checking. + * Revision 1.16 2010/04/16 11:12:21Z martin * Updated GPS170PEX ASIC version. * Revision 1.15 2009/03/27 09:39:15 martin * Increased current ASIC minor number for TCR170PEX to 0x02. @@ -263,6 +269,9 @@ enum 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_PZF600PEX, // PEX EPLD for PZF600PEX N_PCI_ASIC_MAJOR // the number of known codes }; @@ -274,30 +283,66 @@ enum */ #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 +// 0x04 // EPLD sources shared with PEX511 0x04 +#define PCI_ASIC_FIX_IRQ_MINOR_TCR511PEX 0x03 // fixes IRQ problem, increases HRT accuracy -#define PCI_ASIC_CURRENT_MINOR_PTP270PEX 0x01 +#define PCI_ASIC_CURRENT_MINOR_PTP270PEX 0x02 #define PCI_ASIC_REQUIRED_MINOR_PTP270PEX 0x01 +// 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 0x02 +#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_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 0x01 +#define PCI_ASIC_REQUIRED_MINOR_GPS180PEX 0x01 +// 0x01 // updated VHDL compiler and associated primitives + +#define PCI_ASIC_CURRENT_MINOR_TCR180PEX 0x00 +#define PCI_ASIC_REQUIRED_MINOR_TCR180PEX 0x00 + +#define PCI_ASIC_CURRENT_MINOR_PZF600PEX 0x00 +#define PCI_ASIC_REQUIRED_MINOR_PZF600PEX 0x00 + + +typedef struct +{ + unsigned int dev_type_num; + unsigned int major; + unsigned int current_minor; + unsigned int required_minor; +} 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 }, \ + { PCPS_TYPE_GPS170PEX, PCI_ASIC_MAJOR_GPS170PEX, PCI_ASIC_CURRENT_MINOR_GPS170PEX, PCI_ASIC_REQUIRED_MINOR_GPS170PEX }, \ + { PCPS_TYPE_TCR511PEX, PCI_ASIC_MAJOR_TCR511PEX, PCI_ASIC_CURRENT_MINOR_TCR511PEX, PCI_ASIC_REQUIRED_MINOR_TCR511PEX }, \ + { PCPS_TYPE_PTP270PEX, PCI_ASIC_MAJOR_PTP270PEX, PCI_ASIC_CURRENT_MINOR_PTP270PEX, PCI_ASIC_REQUIRED_MINOR_PTP270PEX }, \ + { PCPS_TYPE_FRC511PEX, PCI_ASIC_MAJOR_FRC511PEX, PCI_ASIC_CURRENT_MINOR_FRC511PEX, PCI_ASIC_REQUIRED_MINOR_FRC511PEX }, \ + { PCPS_TYPE_TCR170PEX, PCI_ASIC_MAJOR_TCR170PEX, PCI_ASIC_CURRENT_MINOR_TCR170PEX, PCI_ASIC_REQUIRED_MINOR_TCR170PEX }, \ + { 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_PZF600PEX, PCI_ASIC_MAJOR_PZF600PEX, PCI_ASIC_CURRENT_MINOR_PZF600PEX, PCI_ASIC_REQUIRED_MINOR_PZF600PEX }, \ + { 0 } \ +} /* function prototypes: */ diff --git a/mbglib/common/pcpsdefs.h b/mbglib/common/pcpsdefs.h index f36b251..53fa6a3 100755 --- a/mbglib/common/pcpsdefs.h +++ b/mbglib/common/pcpsdefs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsdefs.h 1.46.1.1 2011/02/15 10:55:28 daniel TRASH $ + * $Id: pcpsdefs.h 1.46.1.3.1.7 2011/05/06 13:47:38 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,25 @@ * * ----------------------------------------------------------------------- * $Log: pcpsdefs.h $ + * Revision 1.46.1.3.1.7 2011/05/06 13:47:38 martin + * Support PZF600PEX. + * Revision 1.46.1.3.1.6 2011/04/21 12:31:00 martin + * Renamed *_GPIO_CFG_INFO to *_GPIO_CFG_LIMITS + * to follow common naming conventions. + * Revision 1.46.1.3.1.5 2011/04/19 15:14:19 martin + * Cleanup. + * Revision 1.46.1.3.1.4 2011/04/19 15:05:48 martin + * PTP unicast cfg stuff ... + * Revision 1.46.1.3.1.3 2011/04/19 13:08:37 martin + * Modified naming conventions for PTP unicast master configuration. + * Revision 1.46.1.3.1.2 2011/04/19 09:59:11 martin + * More PTP unicast cfg ... + * Revision 1.46.1.3.1.1 2011/04/18 15:31:05 martin + * Started PTP unicast + * 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 * Revision 1.46 2011/01/13 11:44:29Z martin @@ -294,6 +313,7 @@ enum #define PCI_DEV_PCI510 ( ( PCPS_REF_DCF << 8 ) | 0x03 ) #define PCI_DEV_PCI511 ( ( PCPS_REF_DCF << 8 ) | 0x04 ) #define PCI_DEV_PEX511 ( ( PCPS_REF_DCF << 8 ) | 0x05 ) +#define PCI_DEV_PZF600PEX ( ( PCPS_REF_DCF << 8 ) | 0x06 ) //##+++++ Should we use a new ref type for PZF reception? #define PCI_DEV_GPS167PCI ( ( PCPS_REF_GPS << 8 ) | 0x01 ) #define PCI_DEV_GPS168PCI ( ( PCPS_REF_GPS << 8 ) | 0x02 ) @@ -317,7 +337,7 @@ enum // 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" */ +typedef uint8_t PCPS_STATUS_PORT; /**< see @ref group_status_port "Bitmask" */ /** @defgroup group_status_port Bit masks of PCPS_STATUS_PORT @@ -334,8 +354,7 @@ typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */ The macro _pcps_ddev_has_gen_irq() cares about this and should be used to determine in a portable way whether a card has generated an IRQ. - * @{ - */ + * @{ */ #define PCPS_ST_BUSY 0x01 /**< the clock is busy filling the output FIFO */ #define PCPS_ST_IRQF 0x02 /**< the clock has generated an IRQ on the PC bus (ISA only)*/ @@ -343,7 +362,7 @@ typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */ #define PCPS_ST_SEC 0x40 /**< seconds have changed since last reading */ #define PCPS_ST_MIN 0x80 /**< minutes have changed since last reading */ -/** @} */ +/** @} group_status_port */ @@ -576,8 +595,9 @@ typedef uint8_t PCPS_STATUS_PORT; /**< see \ref group_status_port "Bitmask" */ The command codes listed above are defined below. The commands are grouped for bytes having the same high nibble: - @{ -*/ + + @{ */ + #define PCPS_GIVE_TIME_GROUP 0x00 #define PCPS_SET_TIME_GROUP 0x10 #define PCPS_IRQ_GROUP 0x20 @@ -649,6 +669,7 @@ enum #define PCPS_SET_PCPS_TZDL ( PCPS_CFG_GROUP | 0x5 ) /* on error, return PCPS_ERR_CFG */ + /** * The structures below can be used to configure a clock's * time zone/daylight saving setting. This structure is shorter @@ -781,7 +802,8 @@ typedef struct */ #define PCPS_FORCE_RESET 0x80 -/** @} */ +/** @} group_cmd_bytes */ + /* Codes returned when commands with parameters have been passed */ /* to the board */ @@ -1192,19 +1214,19 @@ enum }; -/** - * @defgroup gps_cmds_bus GPS commands passed via the system bus - * - * This enumeration defines the various types of data that can be read - * from or written to Meinberg bus level devices which support this. - * Access should be done using the functions ::pcps_read_gps_data() - * and ::pcps_write_gps_data() since the size of some of the structures - * exceeds the size of the devices's I/O buffer and must therefore be - * accessed in several portions. - * - * The structures to be used are defined in gpsdefs.h. Not all structures - * are supportet, yet. Check the R/W indicators for details. - */ +/** @defgroup group_gps_cmds_bus GPS commands passed via the system bus + + This enumeration defines the various types of data that can be read + from or written to Meinberg bus level devices which support this. + Access should be done using the functions ::pcps_read_gps_data() + and ::pcps_write_gps_data() since the size of some of the structures + exceeds the size of the devices's I/O buffer and must therefore be + accessed in several portions. + + 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 ----------------------------------------------- @@ -1236,7 +1258,12 @@ enum 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_UNICAST_CFG, // R/W PTP_CFG_UNICAST_{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 // GPS data PC_GPS_CFGH = 0x80, // -/- CFGH SVs' config. and health codes @@ -1258,6 +1285,9 @@ enum N_PC_GPS_CMD /**< no command, just the number of known commands */ }; +/** @} group_gps_cmds_bus */ + + // 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. diff --git a/mbglib/common/pcpsdev.h b/mbglib/common/pcpsdev.h index 3c856ed..e83958b 100755 --- a/mbglib/common/pcpsdev.h +++ b/mbglib/common/pcpsdev.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsdev.h 1.49.1.32 2011/03/25 11:09:43 martin TRASH $ + * $Id: pcpsdev.h 1.49.1.36 2011/05/06 13:47:38 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -17,6 +17,14 @@ * * ----------------------------------------------------------------------- * $Log: pcpsdev.h $ + * Revision 1.49.1.36 2011/05/06 13:47:38 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. @@ -288,7 +296,12 @@ #endif #if defined( MBG_TGT_FREEBSD ) && defined( MBG_ARCH_X86 ) && defined( MBG_TGT_KERNEL ) - #include <machine/clock.h> // for symbol 'tsc_freq', not supported e.g. on MBG_TGT_NETBSD + #include <machine/clock.h> /* for symbol 'tsc_freq' */ + #endif + + #if defined( MBG_TGT_NETBSD ) && defined( MBG_TGT_KERNEL ) + #include <machine/cpu.h> + #include <machine/cpu_counter.h> /* for cycle counter abstraction */ #endif #endif @@ -369,6 +382,14 @@ #include <sys/time.h> #endif + #if defined( MBG_TGT_NETBSD ) + #ifdef __LP64__ + #define MBG_MEM_ADDR uint64_t + #else + #define MBG_MEM_ADDR uint32_t + #endif + #endif + #elif defined( MBG_TGT_OS2 ) typedef uint32_t MBG_PC_CYCLES; //##++ should differentiate more @@ -526,6 +547,12 @@ void mbg_get_pc_cycles( MBG_PC_CYCLES *p ) #define MBG_PC_CYCLES_SUPPORTED 1 + #elif defined( MBG_TGT_NETBSD ) && defined ( MBG_TGT_KERNEL ) + + *p = cpu_counter(); //##++ or cpu_counter_serializing() + + #define MBG_PC_CYCLES_SUPPORTED 1 + #elif defined( MBG_TGT_BSD ) && defined( MBG_ARCH_X86 ) *p = mbg_rdtscll(); @@ -599,6 +626,10 @@ void mbg_get_pc_cycles_frequency( MBG_PC_CYCLES_FREQUENCY *p ) *p = tsc_freq; + #elif defined( MBG_TGT_NETBSD ) && defined( MBG_TGT_KERNEL ) + + *p = cpu_frequency( curcpu() ); + #else *p = 0; @@ -916,6 +947,7 @@ enum PCPS_TYPES PCPS_TYPE_GPS180PEX, PCPS_TYPE_TCR180PEX, PCPS_TYPE_DCF600USB, + PCPS_TYPE_PZF600PEX, N_PCPS_DEV_TYPE }; @@ -1244,6 +1276,8 @@ enum #define PCPS_FEAT_DCF600USB ( PCPS_FEAT_USB5131 ) +#define PCPS_FEAT_PZF600PEX ( PCPS_FEAT_PEX511 ) //##++++++ PZF reception as feature ?? + // Some features of the API used to access Meinberg plug-in radio clocks // have been implemented starting with the special firmware revision // numbers defined below. @@ -1581,6 +1615,18 @@ typedef POUT_INFO_IDX ALL_POUT_INFO[MAX_PARM_POUT]; +/* + * The definitions and types below are used to collect + * all configuration parameters of PTP device's unicast + * master specification: + */ + +#define MAX_PARM_PTP_UC_MASTER 4 + +typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO[MAX_PARM_PTP_UC_MASTER]; + + + // The macros below can be used to mark a PCPS_TIME variable // as unread, i.e. its contents have not been read from the clock, // and to check if such a variable is marked as unread. diff --git a/mbglib/common/pcpsdrvr.c b/mbglib/common/pcpsdrvr.c index 4ec7909..7c2f754 100755 --- a/mbglib/common/pcpsdrvr.c +++ b/mbglib/common/pcpsdrvr.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsdrvr.c 1.46.2.35 2011/03/25 11:10:34 martin TRASH $ + * $Id: pcpsdrvr.c 1.46.2.39 2011/05/06 13:47:39 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -61,6 +61,15 @@ * * ----------------------------------------------------------------------- * $Log: pcpsdrvr.c $ + * Revision 1.46.2.39 2011/05/06 13:47:39 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 + * 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 @@ -2170,8 +2179,14 @@ PCPS_DDEV *pcps_alloc_ddev( void ) #endif if ( pddev ) + { memset( pddev, 0, sizeof( *pddev ) ); + _mbg_mutex_init( &pddev->dev_mutex ); + _mbg_spin_lock_init( &pddev->mm_lock ); + _mbg_spin_lock_init( &pddev->irq_lock ); + } + return pddev; } // pcps_alloc_ddev @@ -2183,8 +2198,18 @@ void pcps_free_ddev( PCPS_DDEV *pddev ) { #if !_PCPS_STATIC_DEV_LIST if ( pddev ) + { + _mbg_mutex_destroy( &pddev->dev_mutex ); + _mbg_spin_lock_destroy( &pddev->mm_lock ); + _mbg_spin_lock_destroy( &pddev->irq_lock ); + _pcps_kfree( pddev, sizeof( *pddev ) ); + } #else + _mbg_mutex_destroy( &pddev->dev_mutex ); + _mbg_spin_lock_destroy( &pddev->mm_lock ); + _mbg_spin_lock_destroy( &pddev->irq_lock ); + memset( pddev, 0, sizeof( *pddev ) ); if ( n_ddevs ) @@ -2400,9 +2425,8 @@ int pcps_start_device( PCPS_DDEV *pddev, goto fail; } - _pcps_mutex_init( &pddev->dev_mutex ); - _pcps_spin_lock_init( &pddev->mm_lock ); - _pcps_spin_lock_init( &pddev->irq_lock ); + // mutexes / spinlocks have already been initialized + // when the *pddef has been allocated. switch ( _pcps_ddev_bus_flags( pddev ) ) { @@ -2922,18 +2946,20 @@ chip_setup_done: pddev->dev.cfg.features = PCPS_FEAT_DCF600USB; break; + case PCPS_TYPE_PZF600PEX: + pddev->dev.cfg.features = PCPS_FEAT_PZF600PEX; + break; + } // switch if ( _pcps_ddev_has_receiver_info( pddev ) ) { - int rc; - rc = _pcps_read_gps_var( pddev, PC_GPS_RECEIVER_INFO, pddev->ri ); if ( rc == MBG_SUCCESS ) { - _mbg_swab_receiver_info( &rcvr_info ); + _mbg_swab_receiver_info( &pddev->ri ); goto check; } } @@ -2946,6 +2972,7 @@ chip_setup_done: else _setup_default_receiver_info_dcf( &pddev->ri, &pddev->dev ); + check: #if DEBUG_IO _mbgddmsg_1( MBG_DBG_DETAIL, "ri.sw_rev.code: %04X", pddev->ri.sw_rev.code ); diff --git a/mbglib/common/pcpsdrvr.h b/mbglib/common/pcpsdrvr.h index 720ff81..13e0e4a 100755 --- a/mbglib/common/pcpsdrvr.h +++ b/mbglib/common/pcpsdrvr.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsdrvr.h 1.41.1.20 2011/03/25 11:11:44 martin TRASH $ + * $Id: pcpsdrvr.h 1.41.1.27 2011/05/06 13:47:40 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,6 +10,19 @@ * * ----------------------------------------------------------------------- * $Log: pcpsdrvr.h $ + * Revision 1.41.1.27 2011/05/06 13:47:40 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. @@ -372,8 +385,9 @@ /* Other headers to be included */ -#include <pci_asic.h> #include <pcpsdev.h> +#include <mbgmutex.h> +#include <pci_asic.h> #include <mbgerror.h> #include <use_pack.h> #include <mbggenio.h> @@ -384,11 +398,9 @@ #include <sys/_null.h> #include <sys/param.h> #include <sys/lock.h> - #include <sys/mutex.h> #include <machine/bus.h> #elif defined( MBG_TGT_NETBSD ) #include <sys/kmem.h> - #include <sys/mutex.h> #else #include <stddef.h> #endif @@ -453,20 +465,15 @@ // We use native alignment for structures which are not accessed across system boundaries. +// 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 MBG_SPINLOCK spinlock_t - #define _pcps_spin_lock_init( _spl ) spin_lock_init( _spl ) - #define _pcps_spin_lock_deinit( _spl ) nop_macro_fnc() - #define _pcps_spin_lock( _spl ) spin_lock( _spl ) - #define _pcps_spin_unlock( _spl ) spin_unlock( _spl ) - - #define MBG_SYS_MUTEX struct semaphore - #define _pcps_mutex_init( _pmtx ) sema_init( _pmtx, 1 ) - + //##+++++++++++++++++++ // The special versions of _pcps_sem_inc() and _pcps_sem_dec() below // are only required to prevent interference with the IRQ handler // under Linux which implements the serial port emulation for the @@ -475,7 +482,7 @@ { \ ulong flags; \ \ - if ( down_interruptible( &(_pddev)->dev_mutex ) < 0 ) \ + if ( _mbg_mutex_acquire( &(_pddev)->dev_mutex ) < 0 ) \ return -ERESTARTSYS; \ \ spin_lock_irqsave( &(_pddev)->irq_lock, flags ); \ @@ -485,7 +492,7 @@ #define _pcps_sem_dec( _pddev ) \ atomic_dec( &(_pddev)->access_in_progress ); \ - up( &(_pddev)->dev_mutex ) + _mbg_mutex_release( &(_pddev)->dev_mutex ) #elif defined( MBG_TGT_FREEBSD ) @@ -494,55 +501,20 @@ // 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 MBG_SPINLOCK struct mtx - #define _pcps_spin_lock_init( _spl ) mtx_init( _spl, "mbgclock_spin", NULL, MTX_SPIN ) - #define _pcps_spin_lock( _spl ) mtx_lock_spin( _spl ) - #define _pcps_spin_unlock( _spl ) mtx_unlock_spin( _spl ) - - #define MBG_SYS_MUTEX struct mtx - #define _pcps_mutex_init( _pmtx ) mtx_init( _pmtx, "mbgclock_sema", NULL, MTX_DEF ) - #define _pcps_mutex_acquire( _pmtx ) mtx_lock( _pmtx ) - #define _pcps_mutex_release( _pmtx ) mtx_unlock( _pmtx ) + #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 ) - - // The API used below has been introduced in NetBSD 5.0 - // For earlier NetBSD versions see 'man 9 lockinit'. - - #define MBG_SPINLOCK kmutex_t - #define _pcps_spin_lock_init( _spl ) mutex_init( _spl, MUTEX_DEFAULT, IPL_HIGH ) - #define _pcps_spin_lock_deinit( _spl ) mutex_destroy( _spl ) - #define _pcps_spin_lock( _spl ) mutex_spin_enter( _spl ) - #define _pcps_spin_unlock( _spl ) mutex_spin_exit( _spl ) - - #define MBG_SYS_MUTEX kmutex_t - #define _pcps_mutex_init( _pmtx ) mtx_init( _pmtx, MUTEX_DEFAULT, IPL_NONE ) - #define _pcps_mutex_deinit( _spl ) mutex_destroy( _spl ) - #define _pcps_mutex_acquire( _pmtx ) mutex_enter( _pmtx ) - #define _pcps_mutex_release( _pmtx ) mutex_exit( _pmtx ) + #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( PagedPool, _sz ) - #define _pcps_kfree( _p, , _sz ) ExFreePool( _p ) - - #define MBG_SPINLOCK KSPIN_LOCK - #define _pcps_spin_lock_init( _spl ) KeInitializeSpinLock( _spl ) - #define _pcps_spin_lock( _spl ) KeAcquireSpinLockAtDpcLevel( _spl ) - #define _pcps_spin_unlock( _spl ) KeReleaseSpinLockFromDpcLevel( _spl ) - - #define MBG_SYS_MUTEX FAST_MUTEX - #define _pcps_mutex_init( _pmtx ) ExInitializeFastMutex( _pmtx ) - #define _pcps_mutex_acquire( _pmtx ) ExAcquireFastMutex( _pmtx ) - #define _pcps_mutex_release( _pmtx ) ExReleaseFastMutex( _pmtx ) + #define _pcps_kmalloc( _sz ) ExAllocatePool( PagedPool, _sz ) + #define _pcps_kfree( _p, _sz ) ExFreePool( _p ) #endif @@ -559,31 +531,13 @@ // If the macros below have not yet been defined then define some dummies: -#if !defined( MBG_SYS_MUTEX ) - - #define _pcps_mutex_init( _pmtx ) _nop_macro_fnc() - #define _pcps_mutex_acquire( _pmtx ) _nop_macro_fnc() - #define _pcps_mutex_release( _pmtx ) _nop_macro_fnc() - -#endif - - -#if !defined( MBG_SPINLOCK ) - - #define _pcps_spin_lock_init( _spl ) _nop_macro_fnc() - #define _pcps_spin_lock( _spl ) _nop_macro_fnc() - #define _pcps_spin_unlock( _spl ) _nop_macro_fnc() - -#endif - - #if !defined( _pcps_sem_inc ) || !defined( _pcps_sem_dec ) #define _pcps_sem_inc( _pddev ) \ - _pcps_mutex_acquire( &(_pddev)->dev_mutex ) + _mbg_mutex_acquire( &(_pddev)->dev_mutex ) #define _pcps_sem_dec( _pddev ) \ - _pcps_mutex_release( &(_pddev)->dev_mutex ) + _mbg_mutex_release( &(_pddev)->dev_mutex ) #endif @@ -653,10 +607,20 @@ typedef struct { +#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 */ +#endif } BSD_RSRC_INFO; #endif @@ -806,14 +770,14 @@ typedef struct PCPS_DDEV_s MBG_PC_CYCLES acc_cycles; - #if defined( MBG_SYS_MUTEX ) - MBG_SYS_MUTEX dev_mutex; + #if defined( _MBG_MUTEX_DEFINED ) + MBG_MUTEX dev_mutex; #endif PCPS_MM_LAYOUT FAR *mm_addr; volatile PCPS_TIME_STAMP FAR *mm_tstamp_addr; - #if defined( MBG_SPINLOCK ) + #if defined( MBG_SPINLOCK_DEFINED ) MBG_SPINLOCK mm_lock; MBG_SPINLOCK irq_lock; #endif @@ -965,7 +929,8 @@ _ext PCPS_DEV_TYPE pcps_dev_type[N_PCPS_DEV_TYPE] { PCPS_TYPE_WWVB51USB, "WWVB51USB", USB_DEV_WWVB51USB, PCPS_REF_WWVB, PCPS_BUS_USB }, { PCPS_TYPE_GPS180PEX, "GPS180PEX", PCI_DEV_GPS180PEX, PCPS_REF_GPS, PCPS_BUS_PCI_MBGPEX }, { PCPS_TYPE_TCR180PEX, "TCR180PEX", PCI_DEV_TCR180PEX, PCPS_REF_IRIG, PCPS_BUS_PCI_MBGPEX }, - { PCPS_TYPE_DCF600USB, "DCF600USB", USB_DEV_DCF600USB, PCPS_REF_DCF, PCPS_BUS_USB } + { PCPS_TYPE_DCF600USB, "DCF600USB", USB_DEV_DCF600USB, PCPS_REF_DCF, PCPS_BUS_USB }, + { PCPS_TYPE_PZF600PEX, "PZF600PEX", PCI_DEV_PZF600PEX, PCPS_REF_DCF, PCPS_BUS_PCI_MBGPEX } //##+++++ Should we encode PZF reception in ref? // 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, diff --git a/mbglib/common/usbdefs.h b/mbglib/common/usbdefs.h index d853118..c557c86 100755 --- a/mbglib/common/usbdefs.h +++ b/mbglib/common/usbdefs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: usbdefs.h 1.10 2010/11/11 09:16:33 martin REL_M $ + * $Id: usbdefs.h 1.11 2011/04/13 07:59:11 daniel TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,10 @@ * * ----------------------------------------------------------------------- * $Log: usbdefs.h $ - * Revision 1.10 2010/11/11 09:16:33 martin + * Revision 1.11 2011/04/13 07:59:11 daniel + * New class code and device id for external + * synchronization interface device. + * Revision 1.10 2010/11/11 09:16:33Z martin * Added device ID for DCF600USB. * Revision 1.9 2009/03/13 09:02:24 martin * Removed definitions for timeout intervals. @@ -66,6 +69,7 @@ enum 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 N_MBG_USB_CLASS // number of known device class codes }; @@ -92,6 +96,9 @@ enum #define USB_DEV_SCU_USB ( ( MBG_USB_CLASS_SCU << 8 ) | 0x01 ) +#define USB_DEV_ESI_01 ( ( MBG_USB_CLASS_ESI << 8 ) | 0x01 ) + + enum { MBGUSB_EP_IDX_HOST_IN, // transfers from device to host diff --git a/mbglib/common/words.h b/mbglib/common/words.h index 2593bb2..4216e17 100755 --- a/mbglib/common/words.h +++ b/mbglib/common/words.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: words.h 1.25.1.2 2011/03/22 09:41:32 martin TRASH $ + * $Id: words.h 1.26 2011/04/06 10:23:03 martin REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,10 +10,9 @@ * * ----------------------------------------------------------------------- * $Log: words.h $ - * Revision 1.25.1.2 2011/03/22 09:41:32 martin + * Revision 1.26 2011/04/06 10:23:03 martin * Added FBYTE_OF() and FWORD_OF() macros. - * Revision 1.25.1.1 2011/01/25 08:25:49Z martin - * Avoid build errors under FreeBSD. + * Modifications required for *BSD. * Revision 1.25 2010/11/17 10:23:09 martin * Define _BIT_REDEFINED if bit type is redefined. * Revision 1.24 2010/11/17 08:44:56Z martin @@ -137,9 +136,9 @@ #define _C99_BIT_TYPES_DEFINED 1 - //##++ a workaround for now to avoid inclusion of stdbool.h later + // avoid inclusion of stdbool.h later #define bit int - #define _BIT_DEFINED + #define _BIT_DEFINED 1 #elif defined( MBG_TGT_QNX ) // QNX 4.x or QNX 6.x @@ -245,7 +244,7 @@ typedef unsigned char uchar; -#if !defined( MBG_TGT_LINUX ) +#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; diff --git a/mbgstatus/Makefile b/mbgstatus/Makefile index 3501003..3d86873 100755 --- a/mbgstatus/Makefile +++ b/mbgstatus/Makefile @@ -1,13 +1,17 @@ ######################################################################### # -# $Id: Makefile 1.7.1.4 2010/08/30 09:05:24 martin TEST $ +# $Id: Makefile 1.7.1.4.1.2 2011/04/20 09:34:06 martin TRASH $ # # 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 @@ -32,7 +36,7 @@ ######################################################################### TARGET = mbgstatus -INST_DIR = /usr/local/bin +INST_TO_BIN = 1 OBJS := $(TARGET).o OBJS += mbgdevio.o @@ -45,6 +49,7 @@ OBJS += parmpcps.o OBJS += parmgps.o OBJS += ctrydttm.o OBJS += ctry.o +OBJS += lan_util.o BASEDIR := .. include $(BASEDIR)/Makefile diff --git a/mbgstatus/mbgstatus.c b/mbgstatus/mbgstatus.c index 2409c5c..e0e7c47 100755 --- a/mbgstatus/mbgstatus.c +++ b/mbgstatus/mbgstatus.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgstatus.c 1.13.1.8 2011/03/03 10:01:23 daniel TRASH $ + * $Id: mbgstatus.c 1.13.1.9 2011/04/20 16:08:27 martin TRASH $ * * Description: * Main file for mbgstatus program which demonstrates how to @@ -10,6 +10,8 @@ * * ----------------------------------------------------------------------- * $Log: mbgstatus.c $ + * 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 @@ -76,7 +78,7 @@ #include <pcpslstr.h> #include <pcpsutil.h> #include <toolutil.h> // common utility functions - +#include <lan_util.h> // include system headers #include <stdio.h> @@ -177,24 +179,6 @@ void print_position( const char *s, const POS *p, const char *tail ) -/*HDR*/ -int snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *addr ) -{ - int n; - - n = snprintf( s, max_len, "%i.%i.%i.%i", - BYTE_OF( *addr, 3 ), - BYTE_OF( *addr, 2 ), - BYTE_OF( *addr, 1 ), - BYTE_OF( *addr, 0 ) - ); - - return n; - -} // snprint_ip4_addr - - - static /*HDR*/ void show_time_and_status( MBG_DEV_HANDLE dh, const PCPS_DEV *pdev, const char *tail ) { @@ -581,17 +565,17 @@ void show_lan_intf_state( MBG_DEV_HANDLE dh ) ); printf( " MAC Address: %s\n", ws ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.ip_addr ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.ip_addr, NULL ); printf( " IP Address: %s%s\n", ws, ( ip4_settings.flags & IP4_MSK_DHCP ) ? " (DHCP)" : "" ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.netmask ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.netmask, NULL ); printf( " Net Mask: %s\n", ws ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.broad_addr ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.broad_addr, NULL ); printf( " Broadcast Addr: %s\n", ws ); - snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.gateway ); + snprint_ip4_addr( ws, sizeof( ws ), &ip4_settings.gateway, NULL ); printf( " Gateway: %s\n", ws ); printf( " Link detected: %s\n", ( ip4_settings.flags & IP4_MSK_LINK ) ? "YES" : "NO" ); |