Commit 73cc4b37 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'ppsi-integration'

parents aa191d56 a0943281
[submodule "ptp-noposix"]
path = ptp-noposix
url = git://ohwr.org/white-rabbit/ppsi/ptp-noposix.git
[submodule "ppsi"]
path = ppsi
url = git://ohwr.org/white-rabbit/ppsi.git
......@@ -10,8 +10,46 @@ config RAMSIZE
more features you may want to adjust the FPGA size and
choose your preferred value here.
choice
prompt "Choose your preferred ptp engine"
default PTP_NOPOSIX
config PTP_NOPOSIX
boolean "ptp-noposix"
help
Select this option for the ptp-noposix engine
config PPSI
boolean "ppsi"
help
Select this option for the ppsi engine. Warning: this option is
work in progress, may not work or not compile at all.
endchoice
config PPSI_VERBOSITY
depends on PPSI
int "Default verbosity for PPSI"
help
This option makes you select the verbosity of PPSI at startup:
0 means silent
1 means normal verbosity messages
2 means more verbose messages
default 0
range 0 2
config PPSI_RUNTIME_VERBOSITY
depends on PPSI
boolean "Enable runtime verbosity setting"
default n
help
If set, this option permits to change the verbosity of PPSI engine
runtime. This causes a bigger RAM occupation, so it is suggested
to set it only for debugging purpose.
config STACKSIZE
int "Size of the stack area needed by this program"
default 3584 if PPSI
default 2048
help
The linker complains if the code doesn't fit into RAM, but
......@@ -20,6 +58,7 @@ config STACKSIZE
config MPRINTF
boolean "Use the old mprintf implementation for printf"
depends on !PPSI
default y
help
wrpc-sw has traditionally used mprintf as its printf engine.
......@@ -97,7 +136,4 @@ config DETERMINISTIC_BINARY
If in doubt, say No.
# The following will soon become a choice with ppsi
config PTP_NOPOSIX
boolean
default y
\ No newline at end of file
......@@ -17,12 +17,13 @@ SIZE = $(CROSS_COMPILE)size
AUTOCONF = $(CURDIR)/include/generated/autoconf.h
PTP_NOPOSIX = ptp-noposix
PPSI = ppsi
# we miss CONFIG_ARCH_LM32 as we have no other archs by now
obj-y = arch/lm32/crt0.o arch/lm32/irq.o arch/lm32/debug.o
LDS = arch/lm32/ram.ld
obj-y += wrc_main.o wrc_ptp.o monitor/monitor.o
obj-y += wrc_main.o
obj-y += softpll/softpll_ng.o
......@@ -31,13 +32,11 @@ obj-y += softpll/softpll_ng.o
$(CC) -include $(AUTOCONF) -E -P $*.ld.S -o $@
cflags-y = -include $(AUTOCONF) -Iinclude -I. -Isoftpll
cflags-y = -ffreestanding -include $(AUTOCONF) -Iinclude -I. -Isoftpll
cflags-$(CONFIG_PP_PRINTF) += -I$(CURDIR)/pp_printf
cflags-$(CONFIG_PTP_NOPOSIX) += \
-ffreestanding \
-DPTPD_FREESTANDING \
-DWRPC_EXTRA_SLIM \
-DPTPD_MSBF \
......@@ -48,11 +47,12 @@ cflags-$(CONFIG_PTP_NOPOSIX) += \
-include $(PTP_NOPOSIX)/compat.h \
-include $(PTP_NOPOSIX)/PTPWRd/dep/trace.h \
-include $(PTP_NOPOSIX)/libposix/ptpd-wrappers.h \
-I$(PTP_NOPOSIX)/wrsw_hal \
-I$(PTP_NOPOSIX)/libptpnetif \
-I$(PTP_NOPOSIX)/PTPWRd
obj-$(CONFIG_PTP_NOPOSIX) += $(PTP_NOPOSIX)/PTPWRd/arith.o \
obj-$(CONFIG_PTP_NOPOSIX) += wrc_ptp_noposix.o \
monitor/monitor.o \
$(PTP_NOPOSIX)/PTPWRd/arith.o \
$(PTP_NOPOSIX)/PTPWRd/bmc.o \
$(PTP_NOPOSIX)/PTPWRd/dep/msg.o \
$(PTP_NOPOSIX)/PTPWRd/dep/net.o \
......@@ -65,6 +65,27 @@ obj-$(CONFIG_PTP_NOPOSIX) += $(PTP_NOPOSIX)/PTPWRd/arith.o \
$(PTP_NOPOSIX)/libposix/freestanding-startup.o \
$(PTP_NOPOSIX)/libposix/freestanding-wrapper.o
cflags-$(CONFIG_PPSI) += \
-ffreestanding \
-include include/ppsi-wrappers.h \
-Iinclude \
-I$(PPSI)/include \
-I$(PPSI)/arch-spec \
-I$(PPSI)/arch-spec/include \
-I$(PPSI)/proto-ext-whiterabbit \
-Iboards/spec
# FIXM: The following it temporary, untile we clean up
cflags-$(CONFIG_PPSI) += \
-I$(PTP_NOPOSIX)/PTPWRd \
-include $(PTP_NOPOSIX)/PTPWRd/dep/trace.h \
obj-$(CONFIG_PPSI) += wrc_ptp_ppsi.o \
monitor/monitor_ppsi.o \
lib/ppsi-wrappers.o \
$(PPSI)/ppsi.o \
$(PPSI)/arch-spec/libarch.a
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled \
-nostdlib -T $(LDS)
......@@ -93,7 +114,11 @@ REVISION=$(shell git describe --dirty --always)
all: tools $(OUTPUT).ram $(OUTPUT).vhd $(OUTPUT).mif
.PRECIOUS: %.elf %.bin
.PHONY: all tools clean gitmodules
.PHONY: all tools clean gitmodules $(PPSI)/ppsi.o
$(PPSI)/ppsi.o:
$(MAKE) -C $(PPSI) ARCH=spec PROTO_EXT=whiterabbit HAS_FULL_DIAG=y \
CROSS_COMPILE=$(CROSS_COMPILE)
$(OUTPUT).elf: $(LDS) $(AUTOCONF) gitmodules $(OUTPUT).o
$(CC) $(CFLAGS) -DGIT_REVISION=\"$(REVISION)\" -c revision.c
......@@ -126,6 +151,7 @@ include/board.h:
clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram include/board.h
$(MAKE) -C $(PPSI) clean
%.o: %.c
${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $*.c -o $@
......
#
# Automatically generated make config: don't edit
#
CONFIG_RAMSIZE=90112
# CONFIG_PTP_NOPOSIX is not set
CONFIG_PPSI=y
CONFIG_PPSI_VERBOSITY=0
# CONFIG_PPSI_RUNTIME_VERBOSITY is not set
CONFIG_STACKSIZE=2048
CONFIG_PP_PRINTF=y
# CONFIG_PRINTF_FULL is not set
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
CONFIG_PRINT_BUFSIZE=128
# CONFIG_ETHERBONE is not set
# CONFIG_DETERMINISTIC_BINARY is not set
#ifndef __HAL_EXPORTS_H
#define __HAL_EXPORTS_H
#include <stdint.h>
#define HAL_MAX_PORTS 32
#define WRSW_HAL_SERVER_ADDR "wrsw_hal"
// checks if the calibration unit is idle
#define HEXP_CAL_CMD_CHECK_IDLE 1
// enables/disables transmission of calibration pattern
#define HEXP_CAL_CMD_TX_PATTERN 2
// requests a measurement of TX delta
#define HEXP_CAL_CMD_TX_MEASURE 4
// requests a measurement of RX delta
#define HEXP_CAL_CMD_RX_MEASURE 5
#define HEXP_CAL_RESP_BUSY 1
#define HEXP_CAL_RESP_OK 0
#define HEXP_CAL_RESP_ERROR -1
#define HEXP_LOCK_CMD_START 1
#define HEXP_LOCK_CMD_CHECK 2
#define HEXP_LOCK_CMD_ENABLE_TRACKING 3
#define HEXP_LOCK_STATUS_LOCKED 0
#define HEXP_LOCK_STATUS_BUSY 1
#define HEXP_LOCK_STATUS_NONE 2
#define HEXP_PPSG_CMD_GET 0
#define HEXP_PPSG_CMD_ADJUST_PHASE 1
#define HEXP_PPSG_CMD_ADJUST_SEC 2
#define HEXP_PPSG_CMD_ADJUST_NSEC 3
#define HEXP_PPSG_CMD_POLL 4
#define HEXP_PPSG_CMD_SET_VALID 5
#define HEXP_ON 1
#define HEXP_OFF 0
#define HEXP_FREQ 0
#define HEXP_PHASE 1
/////////////////added by ML//////////
#define HEXP_EXTSRC_CMD_CHECK 0
#define HEXP_EXTSRC_STATUS_LOCKED 0
#define HEXP_LOCK_STATUS_BUSY 1
#define HEXP_EXTSRC_STATUS_NOSRC 2
/////////////////////////////////////
#define HAL_TIMING_MODE_GRAND_MASTER 0
#define HAL_TIMING_MODE_FREE_MASTER 1
#define HAL_TIMING_MODE_BC 2
typedef struct {
char port_name[16];
int pps_valid;
uint32_t current_phase_shift;
int32_t adjust_phase_shift;
int64_t adjust_sec;
int32_t adjust_nsec;
uint64_t current_sec;
uint32_t current_nsec;
} hexp_pps_params_t;
/* Port modes (hexp_port_state_t.mode) */
#define HEXP_PORT_MODE_WR_M_AND_S 4
#define HEXP_PORT_MODE_WR_MASTER 1
#define HEXP_PORT_MODE_WR_SLAVE 2
#define HEXP_PORT_MODE_NON_WR 3
#define FIX_ALPHA_FRACBITS 40
/*
#define HEXP_PORT_TSC_RISING 1
#define HEXP_PORT_TSC_FALLING 2
*/
typedef struct {
/* When non-zero: port state is valid */
int valid;
/* WR-PTP role of the port (Master, Slave, etc.) */
int mode;
/* TX and RX delays (combined, big Deltas from the link model in the spec) */
uint32_t delta_tx;
uint32_t delta_rx;
/* DDMTD raw phase value in picoseconds */
uint32_t phase_val;
/* When non-zero: phase_val contains a valid phase readout */
int phase_val_valid;
/* When non-zero: link is up */
int up;
/* When non-zero: TX path is calibrated (delta_tx contains valid value) */
int tx_calibrated;
/* When non-zero: RX path is calibrated (delta_rx contains valid value) */
int rx_calibrated;
int tx_tstamp_counter;
int rx_tstamp_counter;
int is_locked;
int lock_priority;
// timestamp linearization paramaters
uint32_t phase_setpoint; // DMPLL phase setpoint (picoseconds)
uint32_t clock_period; // reference lock period in picoseconds
uint32_t t2_phase_transition; // approximate DMTD phase value (on slave port) at which RX timestamp (T2) counter transistion occurs (picoseconds)
uint32_t t4_phase_transition; // approximate phase value (on master port) at which RX timestamp (T4) counter transistion occurs (picoseconds)
uint8_t hw_addr[6];
int hw_index;
int32_t fiber_fix_alpha;
} hexp_port_state_t;
typedef struct {
int num_ports; /* Number of ports in the list */
int num_physical_ports; /* Number of physical ports compiled into the FPGA bitstream */
char port_names[HAL_MAX_PORTS][16];
} hexp_port_list_t;
typedef struct {
int timing_mode; /* Free-running Master/GM/BC */
int locked_port;
} hexp_timing_state_t;
/* Prototypes of functions that call on rpc */
extern int halexp_check_running(void);
extern int halexp_reset_port(const char *port_name);
extern int halexp_calibration_cmd(const char *port_name, int command,
int on_off);
extern int halexp_lock_cmd(const char *port_name, int command, int priority);
extern int halexp_query_ports(hexp_port_list_t * list);
extern int halexp_get_port_state(hexp_port_state_t * state,
const char *port_name);
extern int halexp_pps_cmd(int cmd, hexp_pps_params_t * params);
extern int halexp_get_timing_state(hexp_timing_state_t * state);
/* Export structures, shared by server and client for argument matching */
#ifdef HAL_EXPORT_STRUCTURES
//int halexp_check_running();
struct minipc_pd __rpcdef_check_running = {
.name = "check_running",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_END,
},
};
//int halexp_reset_port(const char *port_name);
struct minipc_pd __rpcdef_reset_port = {
.name = "reset_port",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_END,
},
};
//int halexp_calibration_cmd(const char *port_name, int command, int on_off);
struct minipc_pd __rpcdef_calibration_cmd = {
.name = "calibration_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_lock_cmd(const char *port_name, int command, int priority);
struct minipc_pd __rpcdef_lock_cmd = {
.name = "lock_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_query_ports(hexp_port_list_t *list);
struct minipc_pd __rpcdef_query_ports = {
.name = "query_ports",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_port_list_t),
.args = {
MINIPC_ARG_END,
},
};
//int halexp_get_port_state(hexp_port_state_t *state, const char *port_name);
struct minipc_pd __rpcdef_get_port_state = {
.name = "get_port_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_port_state_t),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_END,
},
};
//int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
struct minipc_pd __rpcdef_pps_cmd = {
.name = "pps_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_pps_params_t),
MINIPC_ARG_END,
},
};
struct minipc_pd __rpcdef_get_timing_state = {
.name = "get_timing_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_timing_state_t),
.args = {
MINIPC_ARG_END,
},
};
#endif /* HAL_EXPORT_STRUCTURES */
#endif
/*
* This includes stuff that is needed to link ppsi into wrpc-sw
*
* It is included by the command line (-include) like ptp-noposix's
* ptpd-wrappers.h is. It is a subset of that file, with only needed stuff
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdint.h>
#ifndef __IEEE_BIG_ENDIAN
#error "Not big endian, or unknown endianness"
#endif
static inline uint16_t ntohs(uint16_t x) {return x;}
static inline int usleep(useconds_t useconds)
{
while(useconds--)
asm volatile("nop");
return 0;
}
......@@ -21,6 +21,7 @@ int cmd_mode(const char *args[]);
int cmd_calib(const char *args[]);
int cmd_time(const char *args[]);
int cmd_ip(const char *args[]);
int cmd_verbose(const char *args[]);
int cmd_sdb(const char *args[]);
int cmd_mac(const char *args[]);
int cmd_init(const char *args[]);
......
......@@ -252,7 +252,7 @@ int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
from->mac[4],from->mac[5],from->mac[6],from->mac[7],
from->mac_dest[0],from->mac_dest[1],from->mac_dest[2],from->mac_dest[3],
from->mac_dest[4],from->mac_dest[5],from->mac_dest[6],from->mac_dest[7]);*/
return min(size, data_length);
return min(size - sizeof(struct ethhdr), data_length);
return 0;
}
......
#include <stdint.h>
#include <hal_exports.h>
#include <wrc_ptp.h>
#include <syscon.h>
#include <endpoint.h>
#include <softpll_ng.h>
#include <ptpd_netif.h>
/* Following code from ptp-noposix/libposix/freestanding-wrapper.c */
uint64_t ptpd_netif_get_msec_tics(void)
{
return timer_get_tics();
}
static int read_phase_val(hexp_port_state_t *state)
{
int32_t dmtd_phase;
if(spll_read_ptracker(0, &dmtd_phase, NULL))
{
state->phase_val = dmtd_phase;
state->phase_val_valid = 1;
}
else
{
state->phase_val = 0;
state->phase_val_valid = 0;
}
return 0;
}
extern int32_t cal_phase_transition;
extern int32_t sfp_alpha;
int halexp_get_port_state(hexp_port_state_t *state, const char *port_name)
{
state->valid = 1;
if(wrc_ptp_get_mode()==WRC_MODE_SLAVE)
state->mode = HEXP_PORT_MODE_WR_SLAVE;
else
state->mode = HEXP_PORT_MODE_WR_MASTER;
ep_get_deltas( &state->delta_tx, &state->delta_rx);
read_phase_val(state);
state->up = ep_link_up(NULL);
state->tx_calibrated = 1;
state->rx_calibrated = 1;
state->is_locked = spll_check_lock(0);
state->lock_priority = 0;
spll_get_phase_shift(0, NULL, (int32_t *)&state->phase_setpoint);
state->clock_period = 8000;
state->t2_phase_transition = cal_phase_transition;
state->t4_phase_transition = cal_phase_transition;
get_mac_addr(state->hw_addr);
state->hw_index = 0;
state->fiber_fix_alpha = sfp_alpha;
return 0;
}
int ptpd_netif_get_dmtd_phase(wr_socket_t *sock, int32_t *phase)
{
if(phase)
return spll_read_ptracker(0, phase, NULL);
return 0;
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2011,2012 CERN (www.cern.ch)
* Author: Aurelio Colosimo <aurelio@aureliocolosimo.it>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <inttypes.h>
#include <wrc.h>
#include <ppsi/ppsi.h>
#include <spec.h>
#include <wr-api.h>
#include <minic.h>
#include <softpll_ng.h>
#include <syscon.h>
#include <pps_gen.h>
#include <onewire.h>
#include <util.h>
#include "wrc_ptp.h"
#define UI_REFRESH_PERIOD TICS_PER_SECOND /* 1 sec */
struct ptpdexp_sync_state_t;
extern ptpdexp_sync_state_t cur_servo_state;
extern int wrc_man_phase;
void wrc_mon_gui(void)
{
static uint32_t last = 0;
hexp_port_state_t ps;
int tx, rx;
int aux_stat;
uint64_t sec;
uint32_t nsec;
if (timer_get_tics() - last < UI_REFRESH_PERIOD)
return;
last = timer_get_tics();
term_clear();
pcprintf(1, 1, C_BLUE, "WR PTP Core Sync Monitor v 1.0");
pcprintf(2, 1, C_GREY, "Esc = exit");
shw_pps_gen_get_time(&sec, &nsec);
cprintf(C_BLUE, "\n\nTAI Time: ");
cprintf(C_WHITE, "%s", format_time(sec));
/*show_ports */
halexp_get_port_state(&ps, NULL);
pcprintf(4, 1, C_BLUE, "\n\nLink status:");
pcprintf(6, 1, C_WHITE, "%s: ", "wru1");
if (ps.up)
cprintf(C_GREEN, "Link up ");
else
cprintf(C_RED, "Link down ");
if (ps.up) {
minic_get_stats(&tx, &rx);
cprintf(C_GREY, "(RX: %d, TX: %d), mode: ", rx, tx);
switch (ptp_mode) {
case WRC_MODE_GM:
case WRC_MODE_MASTER:
cprintf(C_WHITE, "WR Master ");
break;
case WRC_MODE_SLAVE:
cprintf(C_WHITE, "WR Slave ");
break;
default:
cprintf(C_RED, "WR Unknown ");
}
if (ps.is_locked)
cprintf(C_GREEN, "Locked ");
else
cprintf(C_RED, "NoLock ");
if (ps.rx_calibrated && ps.tx_calibrated)
cprintf(C_GREEN, "Calibrated ");
else
cprintf(C_RED, "Uncalibrated ");
/* show_servo */
cprintf(C_BLUE, "\n\nSynchronization status:\n\n");
if (!cur_servo_state.valid) {
cprintf(C_RED,
"Master mode or sync info not valid\n\n");
return;
}
cprintf(C_GREY, "Servo state: ");
cprintf(C_WHITE, "%s\n", cur_servo_state.slave_servo_state);
cprintf(C_GREY, "Phase tracking: ");
if (cur_servo_state.tracking_enabled)
cprintf(C_GREEN, "ON\n");
else
cprintf(C_RED, "OFF\n");
cprintf(C_GREY, "Synchronization source: ");
cprintf(C_WHITE, "%s\n", cur_servo_state.sync_source);
cprintf(C_GREY, "Aux clock status: ");
aux_stat = spll_get_aux_status(0);
if (aux_stat & SPLL_AUX_ENABLED)
cprintf(C_GREEN, "enabled");
if (aux_stat & SPLL_AUX_LOCKED)
cprintf(C_GREEN, ", locked");
mprintf("\n");
cprintf(C_BLUE, "\nTiming parameters:\n\n");
cprintf(C_GREY, "Round-trip time (mu): ");
cprintf(C_WHITE, "%9d ps\n", (int32_t) (cur_servo_state.mu));
cprintf(C_GREY, "Master-slave delay: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.delay_ms));
cprintf(C_GREY, "Master PHY delays: ");
cprintf(C_WHITE, "TX: %d ps, RX: %d ps\n",
(int32_t) cur_servo_state.delta_tx_m,
(int32_t) cur_servo_state.delta_rx_m);
cprintf(C_GREY, "Slave PHY delays: ");
cprintf(C_WHITE, "TX: %d ps, RX: %d ps\n",
(int32_t) cur_servo_state.delta_tx_s,
(int32_t) cur_servo_state.delta_rx_s);
cprintf(C_GREY, "Total link asymmetry: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.total_asymmetry));
cprintf(C_GREY, "Cable rtt delay: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.mu) -
(int32_t) cur_servo_state.delta_tx_m -
(int32_t) cur_servo_state.delta_rx_m -
(int32_t) cur_servo_state.delta_tx_s -
(int32_t) cur_servo_state.delta_rx_s);
cprintf(C_GREY, "Clock offset: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.cur_offset));
cprintf(C_GREY, "Phase setpoint: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.cur_setpoint));
cprintf(C_GREY, "Skew: ");
cprintf(C_WHITE, "%9d ps\n",
(int32_t) (cur_servo_state.cur_skew));
cprintf(C_GREY, "Manual phase adjustment: ");
cprintf(C_WHITE, "%9d ps\n", (int32_t) (wrc_man_phase));
cprintf(C_GREY, "Update counter: ");
cprintf(C_WHITE, "%9d \n",
(int32_t) (cur_servo_state.update_count));
}
pp_printf("--");
return;
}
int wrc_log_stats(uint8_t onetime)
{
static uint32_t last = 0;
hexp_port_state_t ps;
int tx, rx;
int aux_stat;
uint64_t sec;
uint32_t nsec;
int16_t brd_temp = 0;
int16_t brd_temp_frac = 0;
if (!onetime && timer_get_tics() - last < UI_REFRESH_PERIOD)
return 0;
last = timer_get_tics();
shw_pps_gen_get_time(&sec, &nsec);
halexp_get_port_state(&ps, NULL);
minic_get_stats(&tx, &rx);
pp_printf("lnk:%d rx:%d tx:%d ", ps.up, rx, tx);
pp_printf("lock:%d ", ps.is_locked ? 1 : 0);
pp_printf("sv:%d ", cur_servo_state.valid ? 1 : 0);
pp_printf("ss:'%s' ", cur_servo_state.slave_servo_state);
aux_stat = spll_get_aux_status(0);
pp_printf("aux:%x ", aux_stat);
pp_printf("sec:%d nsec:%d ", (uint32_t) sec, nsec); /* fixme: clock is not always 125 MHz */
pp_printf("mu:%d ", (int32_t) cur_servo_state.mu);
pp_printf("dms:%d ", (int32_t) cur_servo_state.delay_ms);
pp_printf("dtxm:%d drxm:%d ", (int32_t) cur_servo_state.delta_tx_m,
(int32_t) cur_servo_state.delta_rx_m);
pp_printf("dtxs:%d drxs:%d ", (int32_t) cur_servo_state.delta_tx_s,
(int32_t) cur_servo_state.delta_rx_s);
pp_printf("asym:%d ", (int32_t) (cur_servo_state.total_asymmetry));
pp_printf("crtt:%d ",
(int32_t) (cur_servo_state.mu) -
(int32_t) cur_servo_state.delta_tx_m -
(int32_t) cur_servo_state.delta_rx_m -
(int32_t) cur_servo_state.delta_tx_s -
(int32_t) cur_servo_state.delta_rx_s);
pp_printf("cko:%d ", (int32_t) (cur_servo_state.cur_offset));
pp_printf("setp:%d ", (int32_t) (cur_servo_state.cur_setpoint));
pp_printf("hd:%d md:%d ad:%d ", spll_get_dac(-1), spll_get_dac(0),
spll_get_dac(1));
pp_printf("ucnt:%d ", (int32_t) cur_servo_state.update_count);
own_readtemp(ONEWIRE_PORT, &brd_temp, &brd_temp_frac);
pp_printf("temp:%d.%02d C", brd_temp, brd_temp_frac);
pp_printf("\n");
return 0;
}
ppsi @ d3b860f2
Subproject commit d3b860f2d0ca04cd041f08858d0fd1c5ad0f4835
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2012 GSI (www.gsi.de)
* Author: Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
extern int pp_diag_verbosity;
int cmd_verbose(const char *args[])
{
int v;
v = args[0][0] - '0';
if (v < 0)
v = 0;
else if (v > 2)
v = 2;
pp_printf("PPSI verbosity set to %d\n", v);
pp_diag_verbosity = v;
return 0;
}
......@@ -60,6 +60,9 @@ static const struct shell_cmd cmds_list[] = {
{"init", cmd_init},
#ifdef CONFIG_ETHERBONE
{"ip", cmd_ip},
#endif
#if (defined CONFIG_PPSI) && (defined CONFIG_PPSI_RUNTIME_VERBOSITY)
{"verbose", cmd_verbose},
#endif
{"mac", cmd_mac},
{"sdb", cmd_sdb},
......
......@@ -15,3 +15,4 @@ obj-y += \
shell/cmd_init.o
obj-$(CONFIG_ETHERBONE) += shell/cmd_ip.o
obj-$(CONFIG_PPSI_RUNTIME_VERBOSITY) += shell/cmd_verbose.o
......@@ -24,7 +24,11 @@
#undef PACKED
#include "ptpd_netif.h"
#ifdef CONFIG_PPSI
#include <ppsi/ppsi.h>
#else
#include "ptpd.h"
#endif
#if 0 /* not used, currently */
static int get_bitslide(int ep)
......@@ -50,6 +54,70 @@ static void purge_socket(wr_socket_t *sock, char *buf)
update_rx_queues();
}
#ifdef CONFIG_PPSI
extern struct pp_instance ppi_static;
static struct pp_instance *ppi = &ppi_static;
static int meas_phase_range(wr_socket_t * sock, int phase_min, int phase_max,
int phase_step, struct meas_entry *results)
{
char buf[128];
TimeInternal ts_rx, ts_sync = {0,};
MsgHeader *mhdr;
int setpoint = phase_min, i = 0, phase;
mhdr = &ppi->msg_tmp_header;
spll_set_phase_shift(SPLL_ALL_CHANNELS, phase_min);
while (spll_shifter_busy(0)) ;
purge_socket(sock, buf);
i = 0;
while (setpoint <= phase_max) {
ptpd_netif_get_dmtd_phase(sock, &phase);
update_rx_queues();
int n = pp_recv_packet(ppi, buf, 128, &ts_rx);
if (n > 0) {
msg_unpack_header(ppi, buf);
if (mhdr->messageType == 0)
assign_TimeInternal(&ts_sync, &ts_rx);
else if (mhdr->messageType == 8 && ts_sync.correct) {
MsgFollowUp fup;
msg_unpack_follow_up(buf, &fup);
mprintf("Shift: %d/%dps [step %dps] \r",
setpoint, phase_max, phase_step);
results[i].phase = phase;
results[i].phase_sync = ts_sync.phase;
results[i].ahead = ts_sync.raw_ahead;
results[i].delta_ns =
fup.preciseOriginTimestamp.
nanosecondsField - ts_sync.nanoseconds;
results[i].delta_ns +=
(fup.preciseOriginTimestamp.secondsField.
lsb - ts_sync.seconds) * 1000000000;
setpoint += phase_step;
spll_set_phase_shift(0, setpoint);
while (spll_shifter_busy(0)) ;
purge_socket(sock, buf);
ts_sync.correct = 0;
i++;
}
}
}
mprintf("\n");
return i;
}
#else
static int meas_phase_range(wr_socket_t * sock, int phase_min, int phase_max,
int phase_step, struct meas_entry *results)
{
......@@ -105,6 +173,8 @@ static int meas_phase_range(wr_socket_t * sock, int phase_min, int phase_max,
return i;
}
#endif /* CONFIG_PPSI else CONFIG_PTPNOPOSIX*/
static int find_transition(struct meas_entry *results, int n, int positive)
{
int i;
......@@ -125,6 +195,13 @@ int measure_t24p(int *value)
int i, nr;
struct meas_entry results[128];
#ifdef CONFIG_PPSI
if (!NP(ppi)->inited) {
if (pp_net_init(ppi) < 0)
return -1;
NP(ppi)->inited = 1;
}
#endif
spll_enable_ptracker(0, 1);
sock_addr.family = PTPD_SOCK_RAW_ETHERNET; // socket type
......@@ -181,6 +258,11 @@ int measure_t24p(int *value)
mprintf("Verification... \n");
nr = meas_phase_range(sock, 0, 16000, 500, results);
#ifdef CONFIG_PPSI
pp_net_shutdown(ppi);
NP(ppi)->inited = 0;
#endif
for (i = 0; i < nr; i++)
mprintf("phase_dmtd: %d delta_ns: %d, phase_sync: %d\n",
results[i].phase, results[i].delta_ns,
......
......@@ -5,6 +5,7 @@
#define WRC_MODE_GM 1
#define WRC_MODE_MASTER 2
#define WRC_MODE_SLAVE 3
extern int ptp_mode;
int wrc_ptp_init();
int wrc_ptp_set_mode(int mode);
......
......@@ -58,7 +58,8 @@ static RunTimeOpts rtOpts = {
static PtpPortDS *ptpPortDS;
static PtpClockDS ptpClockDS;
static int ptp_enabled = 0, ptp_mode = WRC_MODE_UNKNOWN;
int ptp_mode = WRC_MODE_UNKNOWN;
static int ptp_enabled = 0;
int wrc_ptp_init()
{
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Aurelio Colosimo <aurelio@aureliocolosimo.it>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdio.h>
#include <inttypes.h>
#include <errno.h>
#include <wrc.h>
#include <minic.h>
#include <spec.h>
#include <ppsi/ppsi.h>
#include <wr-constants.h>
#include "syscon.h"
#include "endpoint.h"
#include "softpll_ng.h"
#include "wrc_ptp.h"
#include "pps_gen.h"
#include "uart.h"
int ptp_mode = WRC_MODE_UNKNOWN;
static int ptp_enabled = 0, ptp_forced_stop = 0;
struct pp_instance ppi_static; /* FIXME: no more static, because used in
tests/measure_t24p.c */
CONST_VERBOSITY int pp_diag_verbosity = CONFIG_PPSI_VERBOSITY;
/*ppi fields*/
static UInteger16 sent_seq_id[16];
static DSDefault defaultDS;
static DSCurrent currentDS;
static DSParent parentDS;
static DSPort portDS;
static DSTimeProperties timePropertiesDS;
static struct pp_net_path net_path;
static struct pp_servo servo;
static struct pp_frgn_master frgn_master;
static int delay_ms = PP_DEFAULT_NEXT_DELAY_MS;
static int start_tics = 0;
static int last_link_up = 0;
int wrc_ptp_init()
{
struct pp_instance *ppi = &ppi_static; /* no malloc, one instance */
sdb_find_devices();
uart_init();
pp_printf("Spec: starting. Compiled on " __DATE__ "\n");
ppi->sent_seq_id = sent_seq_id;
ppi->defaultDS = &defaultDS;
ppi->currentDS = &currentDS;
ppi->parentDS = &parentDS;
ppi->portDS = &portDS;
ppi->timePropertiesDS = &timePropertiesDS;
ppi->net_path = &net_path;
ppi->servo = &servo;
ppi->frgn_master = &frgn_master;
ppi->arch_data = NULL;
return 0;
}
#define LOCK_TIMEOUT_FM (4 * TICS_PER_SECOND)
#define LOCK_TIMEOUT_GM (60 * TICS_PER_SECOND)
int wrc_ptp_set_mode(int mode)
{
uint32_t start_tics, lock_timeout = 0;
struct pp_instance *ppi = &ppi_static;
ptp_mode = 0;
wrc_ptp_stop();
switch (mode) {
case WRC_MODE_GM:
/* FIXME multiport rtOpts.primarySource = TRUE; */
DSPOR(ppi)->wrConfig = WR_M_ONLY;
OPTS(ppi)->master_only = TRUE;
OPTS(ppi)->slave_only = FALSE;
spll_init(SPLL_MODE_GRAND_MASTER, 0, 1);
lock_timeout = LOCK_TIMEOUT_GM;
break;
case WRC_MODE_MASTER:
/* FIXME multiport rtOpts.primarySource = FALSE; */
DSPOR(ppi)->wrConfig = WR_M_ONLY;
OPTS(ppi)->master_only = TRUE;
OPTS(ppi)->slave_only = FALSE;
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
lock_timeout = LOCK_TIMEOUT_FM;
break;
case WRC_MODE_SLAVE:
/* FIXME multiport rtOpts.primarySource = FALSE; */
DSPOR(ppi)->wrConfig = WR_S_ONLY;
OPTS(ppi)->master_only = FALSE;
OPTS(ppi)->slave_only = TRUE;
spll_init(SPLL_MODE_SLAVE, 0, 1);
break;
}
start_tics = timer_get_tics();
pp_printf("Locking PLL");
shw_pps_gen_enable_output(0);
while (!spll_check_lock(0) && lock_timeout) {
timer_delay(TICS_PER_SECOND);
pp_printf(".");
if (timer_get_tics() - start_tics > lock_timeout) {
pp_printf("\nLock timeout.\n");
return -ETIMEDOUT;
} else if (uart_read_byte() == 27) {
pp_printf("\n");
return -EINTR;
}
}
if (mode == WRC_MODE_MASTER || mode == WRC_MODE_GM)
shw_pps_gen_enable_output(1);
pp_printf("\n");
ptp_mode = mode;
return 0;
}
int wrc_ptp_get_mode()
{
return ptp_mode;
}
int wrc_ptp_start()
{
struct pp_instance *ppi = &ppi_static;
pp_open_instance(ppi, 0 /* no opts */);
OPTS(ppi)->e2e_mode = 1;
/* Call the state machine. Being it in "Initializing" state, make
* ppsi initialize what is necessary */
delay_ms = pp_state_machine(ppi, NULL, 0);
start_tics = timer_get_tics();
DSPOR(ppi)->linkUP = FALSE;
wr_servo_reset();
ptp_enabled = 1;
return 0;
}
int wrc_ptp_stop()
{
ptp_enabled = 0;
wr_servo_reset();
pp_close_instance(&ppi_static);
return 0;
}
int wrc_ptp_update()
{
int i;
struct pp_instance *ppi = &ppi_static;
int now_link_up;
now_link_up = ep_link_up(NULL);
if (last_link_up != now_link_up) {
last_link_up = now_link_up;
if (ptp_enabled && (!now_link_up)) {
wrc_ptp_stop();
ptp_forced_stop = 1;
pp_printf("Link down: PTP stop\n");
}
else {
if (ptp_forced_stop) {
pp_printf("Link up: PTP start\n");
ptp_forced_stop = 0;
wrc_ptp_start();
}
}
}
if (ptp_enabled) {
static unsigned char packet[500];
/*
* We got a packet. If it's not ours, continue consuming
* the pending timeout
*/
i = spec_recv_packet(ppi, packet, sizeof(packet),
&ppi->last_rcv_time);
if ((!i) && (timer_get_tics() - start_tics < delay_ms))
return 0;
if (!i) {
/* Nothing received, but timeout elapsed */
start_tics = timer_get_tics();
delay_ms = pp_state_machine(ppi, NULL, 0);
return 0;
}
if (pp_diag_verbosity > 1) {
int j;
pp_printf("recvd: %i\n", i);
for (j = 0; j < i; j++) {
pp_printf("%02x ", packet[j]);
if( (j+1)%16==0 )
pp_printf("\n");
}
pp_printf("\n");
}
/* Warning: PP_ETHERTYPE is endian-agnostic by design */
delay_ms = pp_state_machine(ppi, packet, i);
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment