Commit 8044c8cc authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Adam Wujek

High accuracy implementation - First version

- Upgrade HAL to transmit the bit-slide to HA
- Upgrade wr_mon tool to displat HA servo data
- Upgrade wrs_dump_shmem to display the right data
Conflicts:
	userspace/tools/wr_mon.c
	userspace/tools/wrs_dump_shmem.c
parent cbd4366e
......@@ -39,6 +39,9 @@ typedef struct hal_port_calibration {
uint32_t delta_tx_phy;
uint32_t delta_rx_phy;
/* bit slide expresse in picos */
uint32_t bitslide_ps;
/* Current board routing delays (between the DDMTD inputs to
the PHY clock inputs/outputs), in picoseconds */
uint32_t delta_tx_board;
......
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
......@@ -76,10 +77,13 @@ void dump_one_field(void *addr, struct dump_info *info)
{
void *p = addr + info->offset;
struct pp_time *t = p;
RelativeDifference *rd=p;
Timestamp *ts=p;
TimeInterval *ti=p;
struct PortIdentity *pi = p;
struct ClockQuality *cq = p;
char format[16];
long nano, pico;
uint64_t sec, nano, pico;
int i;
printf(" %-30s ", info->name); /* name includes trailing ':' */
......@@ -108,6 +112,7 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_uint64_t:
printf("%lld\n", *(unsigned long long *)p);
break;
case dump_type_long_long:
case dump_type_Integer64:
printf("%lld\n", *(long long *)p);
break;
......@@ -146,14 +151,43 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_Integer16:
printf("%i\n", *(short *)p);
break;
#define TIME_FRACBITS 16
#define TIME_FRACMASK 0xFFFF
case dump_type_time:
nano = t->scaled_nsecs >> 16;
pico = t->scaled_nsecs & 0xffff;
pico = (pico * 1000) >> 16;
printf("correct %i: %10lli.%09li.%03li\n",
nano = t->scaled_nsecs >> TIME_FRACBITS;
pico = t->scaled_nsecs & TIME_FRACMASK;
pico = (pico * 1000) >> TIME_FRACBITS;
printf("correct %i: %10lli.%09"PRIu64".%03"PRIu64"\n",
!is_incorrect(t), t->secs, nano,pico);
break;
case dump_type_Timestamp:
sec=(ts->secondsField.msb << sizeof(ts->secondsField.msb)) + ts->secondsField.lsb;
printf("%10"PRIu64".%09"PRIu32".000\n",
sec, (uint32_t)ts->nanosecondsField);
break;
#define TIME_INTERVAL_FRACBITS 16
#define TIME_INTERVAL_FRACMASK 0xFFFF
case dump_type_TimeInterval:
nano = *ti >> TIME_INTERVAL_FRACBITS;
pico = *ti & TIME_INTERVAL_FRACMASK;
pico = (pico * 1000) >> TIME_INTERVAL_FRACBITS;
printf("%09"PRIu64".%03"PRIu64"\n", nano,pico);
break;
#define REL_DIFF_FRACBITS 62
#define REL_DIFF_FRACMASK 0x3fffffffffffffff
case dump_type_RelativeDifference:
nano = *rd >> REL_DIFF_FRACBITS;
pico = *rd & REL_DIFF_FRACMASK;
pico = (pico * 1000L) >> REL_DIFF_FRACBITS;
printf("%01"PRIu64".%03"PRIu64"\n", nano,pico);
break;
case dump_type_ip_address:
for (i = 0; i < 4; i++)
printf("%02x%c", ((unsigned char *)p)[i],
......@@ -305,6 +339,7 @@ void dump_one_field(void *addr, struct dump_info *info)
break;
}
}
void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
{
int i;
......
......@@ -28,7 +28,7 @@ int halexp_lock_cmd(const char *port_name, int command, int priority)
{
int rval;
pr_debug("halexp_lock_cmd: cmd=%d port=%s\n", command, port_name);
/* pr_debug("halexp_lock_cmd: cmd=%d port=%s\n", command, port_name); */
switch (command) {
case HEXP_LOCK_CMD_ENABLE_TRACKING:
......@@ -80,6 +80,7 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
{
int busy;
pr_debug("halexp_pps_cmd: cmd=%d\n", cmd);
switch (cmd) {
/* fixme: TODO: implement HEXP_PPSG_CMD_GET call */
......
......@@ -37,6 +37,14 @@
#define UPDATE_LINK_LEDS_PERIOD 500 /* ms */
#define UPDATE_SFP_DOM_PERIOD 1000 /* ms */
typedef struct {
struct pp_instance * ppi; /* pointer to the ppi instance */
struct pp_servo servo_snapshot; /* image of a the ppsi servo */
} inst_servo_t ;
static inst_servo_t servo;
struct pp_servo *ppsi_servo;
extern struct hal_shmem_header *hal_shmem;
extern struct wrs_shm_head *hal_shmem_hdr;
......@@ -56,8 +64,7 @@ static timeout_t update_sync_leds_tmo, update_link_leds_tmo;
static timeout_t update_sfp_dom_tmo;
static int hal_port_nports;
static struct wr_servo_state *ppsi_servo;
static struct wr_servo_state ppsi_servo_local;
static struct pp_globals *ppg;
static struct pp_instance *ppsi_instances;
static struct pp_instance ppsi_instances_local[PP_MAX_LINKS];
static struct wrs_shm_head *ppsi_head;
......@@ -426,14 +433,17 @@ static void hal_port_fsm(struct hal_port_state * p)
case HAL_PORT_STATE_RESET:
{
if (link_up) {
uint32_t bit_slide_steps;
p->calib.tx_calibrated = 1;
p->calib.rx_calibrated = 1;
/* FIXME: use proper register names */
pr_info("Bitslide: %d\n",
((pcs_readl(p, 16) >> 4) & 0x1f));
bit_slide_steps=(pcs_readl(p, 16) >> 4) & 0x1f;
p->calib.bitslide_ps=bit_slide_steps*800; /* 1 step = 800ps */
pr_info("Bitslide: %d\n",bit_slide_steps);
p->calib.delta_rx_phy =
p->calib.phy_rx_min +
((pcs_readl(p, 16) >> 4) & 0x1f) * 800;
p->calib.phy_rx_min + p->calib.bitslide_ps;
p->calib.delta_tx_phy = p->calib.phy_tx_min;
if (0)
......@@ -921,15 +931,19 @@ static void update_sync_leds(void)
int i;
static uint32_t update_count = 0;
static uint32_t since_last_servo_update = 0;
char *iface_name;
/* read servo */
if (read_servo())
return;
if (!strnlen(ppsi_servo_local.if_name, 16))
iface_name=servo.ppi->cfg.iface_name;
if (!strnlen(iface_name, 16))
return;
for (i = 0; i < HAL_MAX_PORTS; i++) {
int ledValue;
/* Check:
* --port in use
* --link is up
......@@ -939,53 +953,68 @@ static void update_sync_leds(void)
*/
if (ports[i].in_use
&& state_up(ports[i].state)
&& !strcmp(ppsi_servo_local.if_name, ports[i].name)) {
if (update_count == ppsi_servo_local.update_count) {
&& !strcmp(iface_name, ports[i].name)) {
if (update_count == servo.servo_snapshot.update_count) {
if (since_last_servo_update < 7)
since_last_servo_update++;
} else {
since_last_servo_update = 0;
update_count = ppsi_servo_local.update_count;
update_count = servo.servo_snapshot.update_count;
}
/* Check:
* --port in slave mode
* --servo is in track phase
* --servo is locked
* --not the standard PTP servo
* --servo is updating
*/
if (ports[i].mode == HEXP_PORT_MODE_WR_SLAVE
&& ppsi_servo_local.state == WR_TRACK_PHASE
ledValue=(ports[i].mode == HEXP_PORT_MODE_WR_SLAVE
&& servo.servo_snapshot.servo_locked
&& servo.ppi->protocol_extension != PPSI_EXT_NONE
&& since_last_servo_update < 7
) {
set_led_synced(i, 1);
} else {
set_led_synced(i, 0);
}
) ? 1 : 0;
set_led_synced(i, ledValue);
}
}
}
static int read_servo(void){
unsigned ii;
unsigned retries = 0;
/* read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
memcpy(&ppsi_servo_local, ppsi_servo, sizeof(*ppsi_servo));
retries++;
if (retries > 100)
return -1;
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
}
unsigned int i;
return 0;
if ( read_ppsi_instances() )
return -1;
bzero(&servo.servo_snapshot,sizeof(struct pp_servo));
for (i = 0; i < ppg->nlinks; i++) {
struct pp_instance *ppi = &ppsi_instances_local[i];
/* we are only interested on instances in SLAVE state */
if (ppi->state == PPS_SLAVE ) {
while (1) {
unsigned ii = wrs_shm_seqbegin(ppsi_head);
unsigned retries = 0;
memcpy(&servo.servo_snapshot, ppsi_servo, sizeof(struct pp_servo));
servo.ppi=ppi;
if (!wrs_shm_seqretry(ppsi_head, ii)) {
break; /* consistent read */
}
retries++;
if (retries > 100)
return -1;
}
return 0; /* We assume that we have only one servo */
}
}
return -1; /* No active servo found */
}
static int try_open_ppsi_shmem(void)
{
int ret;
struct pp_globals *ppg;
static int open_error;
if (ppsi_servo && ppsi_instances) {
......@@ -1021,8 +1050,8 @@ static int try_open_ppsi_shmem(void)
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
/* there is an assumption that there is only one servo in ppsi! */
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
/* ppsi-servo points to the common servo data */
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->servo);
if (!ppsi_servo) {
pr_error("Cannot follow ppsi_servo in shmem.\n");
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