Commit e9d5e03d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

software: bugfixes in raw readout mode (enabled by default)

parent 48385a0a
......@@ -57,6 +57,9 @@
/* definitions for field: Disable Fine Part update in reg: Delay Control Register */
#define FD_DCR_NO_FINE WBGEN2_GEN_MASK(7, 1)
/* definitions for field: Disable Fine Part update in reg: Delay Control Register */
#define FD_DCR_FORCE_HI WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Fine Range Register */
/* definitions for register: Pulse start time / offset (MSB TAI seconds) */
......
......@@ -3,7 +3,7 @@
* File : fd_main_regs.h
* Author : auto-generated by wbgen2 from fd_main_wishbone_slave.wb
* Created : Mon May 21 20:09:50 2012
* Created : Mon Jun 4 13:42:20 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb
......@@ -135,7 +135,7 @@
/* definitions for field: PPS Calibration output enable in reg: Calibration register */
#define FD_CALR_CAL_PPS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Triggers calibration pulses in reg: Calibration register */
/* definitions for field: Produce DDMTD calibration pattern in reg: Calibration register */
#define FD_CALR_CAL_DMTD WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Enable pulse generation in reg: Calibration register */
......@@ -144,39 +144,27 @@
#define FD_CALR_PSEL_W(value) WBGEN2_GEN_WRITE(value, 3, 4)
#define FD_CALR_PSEL_R(reg) WBGEN2_GEN_READ(reg, 3, 4)
/* definitions for field: DMTD Feedback Channel Select in reg: Calibration register */
#define FD_CALR_DMTD_FBSEL WBGEN2_GEN_MASK(7, 1)
/* definitions for field: DMTD Tag in reg: Calibration register */
#define FD_CALR_DMTD_TAG_MASK WBGEN2_GEN_MASK(8, 23)
#define FD_CALR_DMTD_TAG_SHIFT 8
#define FD_CALR_DMTD_TAG_W(value) WBGEN2_GEN_WRITE(value, 8, 23)
#define FD_CALR_DMTD_TAG_R(reg) WBGEN2_GEN_READ(reg, 8, 23)
/* definitions for field: DMTD Tag Ready in reg: Calibration register */
#define FD_CALR_DMTD_TAG_RDY WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Softpll Register */
/* definitions for register: DMTD Input Tag Register */
/* definitions for field: Frequency/Phase tag in reg: Softpll Register */
#define FD_SPLLR_TAG_MASK WBGEN2_GEN_MASK(0, 20)
#define FD_SPLLR_TAG_SHIFT 0
#define FD_SPLLR_TAG_W(value) WBGEN2_GEN_WRITE(value, 0, 20)
#define FD_SPLLR_TAG_R(reg) WBGEN2_GEN_READ(reg, 0, 20)
/* definitions for field: DMTD Tag in reg: DMTD Input Tag Register */
#define FD_DMTR_IN_TAG_MASK WBGEN2_GEN_MASK(0, 31)
#define FD_DMTR_IN_TAG_SHIFT 0
#define FD_DMTR_IN_TAG_W(value) WBGEN2_GEN_WRITE(value, 0, 31)
#define FD_DMTR_IN_TAG_R(reg) WBGEN2_GEN_READ(reg, 0, 31)
/* definitions for field: Tag Ready in reg: Softpll Register */
#define FD_SPLLR_TAG_RDY WBGEN2_GEN_MASK(20, 1)
/* definitions for field: DMTD Tag Ready in reg: DMTD Input Tag Register */
#define FD_DMTR_IN_RDY WBGEN2_GEN_MASK(31, 1)
/* definitions for field: Freq/Phase mode select in reg: Softpll Register */
#define FD_SPLLR_MODE WBGEN2_GEN_MASK(21, 1)
/* definitions for register: DMTD Output Tag Register */
/* definitions for register: Softpll DAC Register */
/* definitions for field: DMTD Tag in reg: DMTD Output Tag Register */
#define FD_DMTR_OUT_TAG_MASK WBGEN2_GEN_MASK(0, 31)
#define FD_DMTR_OUT_TAG_SHIFT 0
#define FD_DMTR_OUT_TAG_W(value) WBGEN2_GEN_WRITE(value, 0, 31)
#define FD_DMTR_OUT_TAG_R(reg) WBGEN2_GEN_READ(reg, 0, 31)
/* definitions for field: DAC Value in reg: Softpll DAC Register */
#define FD_SDACR_DAC_VAL_MASK WBGEN2_GEN_MASK(0, 16)
#define FD_SDACR_DAC_VAL_SHIFT 0
#define FD_SDACR_DAC_VAL_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define FD_SDACR_DAC_VAL_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: DMTD Tag Ready in reg: DMTD Output Tag Register */
#define FD_DMTR_OUT_RDY WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Acam to Delay line fractional part Scale Factor Register */
......@@ -417,10 +405,10 @@
#define FD_REG_TDCSR 0x00000020
/* [0x24]: REG Calibration register */
#define FD_REG_CALR 0x00000024
/* [0x28]: REG Softpll Register */
#define FD_REG_SPLLR 0x00000028
/* [0x2c]: REG Softpll DAC Register */
#define FD_REG_SDACR 0x0000002c
/* [0x28]: REG DMTD Input Tag Register */
#define FD_REG_DMTR_IN 0x00000028
/* [0x2c]: REG DMTD Output Tag Register */
#define FD_REG_DMTR_OUT 0x0000002c
/* [0x30]: REG Acam to Delay line fractional part Scale Factor Register */
#define FD_REG_ADSFR 0x00000030
/* [0x34]: REG Acam Timestamp Merging Control Register */
......
......@@ -42,6 +42,7 @@ typedef struct {
int32_t start_offset;
int32_t subcycle_offset;
int32_t frac;
uint32_t tsbcr;
} fdelay_raw_time_t;
typedef struct
......@@ -128,4 +129,6 @@ void fdelay_set_user_offset(fdelay_device_t *dev,int input, int64_t offset);
int fdelay_get_time(fdelay_device_t *dev, fdelay_time_t *t);
int fdelay_set_time(fdelay_device_t *dev, const fdelay_time_t t);
int fdelay_dmtd_calibration(fdelay_device_t *dev);
#endif
......@@ -26,9 +26,6 @@
#include "fdelay_lib.h"
#include "fdelay_private.h"
#include "spll_defs.h"
#include "spll_common.h"
#include "spll_helper.h"
#include "onewire.h"
......@@ -299,13 +296,14 @@ static int sgpio_init(fdelay_device_t *dev)
if(mcp_read(dev, MCP_IPOL) != 0)
failed = 1;
fail(TEST_SPI, "Failed to access MCP23S17. Broken SPI connection?");
if(failed)
fail(TEST_SPI, "Failed to access MCP23S17. Broken SPI connection?");
return failed ? - 1: 0;
}
/* Sets the direction (0 = input, non-zero = output) of a particular MCP23S17 GPIO pin */
static void sgpio_set_dir(fdelay_device_t *dev, int pin, int dir)
void sgpio_set_dir(fdelay_device_t *dev, int pin, int dir)
{
uint8_t iodir = (MCP_IODIR) + (pin & 0x100 ? 1 : 0);
uint8_t x;
......@@ -318,7 +316,7 @@ static void sgpio_set_dir(fdelay_device_t *dev, int pin, int dir)
}
/* Sets the value on a given MCP23S17 GPIO pin */
static void sgpio_set_pin(fdelay_device_t *dev, int pin, int val)
void sgpio_set_pin(fdelay_device_t *dev, int pin, int val)
{
uint8_t gpio = (MCP_OLAT) + (pin & 0x100 ? 1 : 0);
uint8_t x;
......@@ -871,7 +869,7 @@ int fdelay_init(fdelay_device_t *dev)
dev->priv_fd = (void *) hw;
hw->raw_mode= 0;
hw->raw_mode = 1;
hw->base_addr = dev->base_addr;
hw->base_i2c = 0x100;
hw->base_onewire = dev->base_addr + 0x500;
......@@ -914,8 +912,8 @@ int fdelay_init(fdelay_device_t *dev)
hw->calib.frr_poly[1] = -29825595LL;
hw->calib.frr_poly[2] = 3801939743082LL;
hw->calib.tdc_zero_offset = 35600;
hw->calib.atmcr_val = 4 | (1500 << 4);
// hw->calib.atmcr_val = 2 | (1000 << 4);
// hw->calib.atmcr_val = 4 | (1500 << 4);
hw->calib.atmcr_val = 2 | (1000 << 4);
hw->calib.adsfr_val = 56648;
hw->calib.acam_start_offset = 10000;
for(i=0;i<4;i++)
......@@ -934,8 +932,6 @@ int fdelay_init(fdelay_device_t *dev)
if(ad9516_init(dev) < 0)
return -1;
if(ds18x_init(dev) < 0)
{
fail(TEST_SPI, "DS18x sensor not detected.");
......@@ -1053,6 +1049,7 @@ fdelay_time_t fdelay_from_picos(const uint64_t ps)
fdelay_time_t t;
uint64_t tmp = ps;
t.frac = (tmp % 8000ULL) * (uint64_t)(1<<FDELAY_FRAC_BITS) / 8000ULL;
tmp -= (tmp % 8000ULL);
tmp /= 8000ULL;
......@@ -1119,11 +1116,12 @@ static fdelay_time_t ts_add_ps(fdelay_time_t a, int64_t b)
return ts_add(a, fdelay_from_picos(b));
}
static int poll_rbuf(fdelay_device_t *dev)
static int poll_rbuf(fdelay_device_t *dev, uint32_t *o_tsbcr)
{
fd_decl_private(dev)
uint32_t tsbcr = fd_readl(FD_REG_TSBCR);
if(o_tsbcr)
*o_tsbcr= tsbcr;
// fprintf(stderr,"Count %d empty %d\n", FD_TSBCR_COUNT_R(tsbcr), tsbcr & FD_TSBCR_EMPTY ? 1 : 0);
if((tsbcr & FD_TSBCR_EMPTY) == 0)
......@@ -1164,6 +1162,14 @@ fdelay_time_t ts_normalize(fdelay_time_t denorm)
return denorm;
}
static int sign_extend(int n, int nbits)
{
if(n & (1<<(nbits-1)))
return n | (~((1<<nbits)-1));
else
return n;
}
/* as in VHDL */
void ts_postprocess(fdelay_device_t *dev, fdelay_time_t *t)
{
......@@ -1172,15 +1178,19 @@ void ts_postprocess(fdelay_device_t *dev, fdelay_time_t *t)
t->utc = t->raw.utc;
if (t->raw.start_offset <= FD_ATMCR_C_THR_R(hw->calib.atmcr_val)
&& (post_frac_start_adj > FD_ATMCR_F_THR_R(hw->calib.atmcr_val)))
int c_thr = FD_ATMCR_C_THR_R(hw->calib.atmcr_val);
int f_thr = FD_ATMCR_F_THR_R(hw->calib.atmcr_val);
// printf("CThr: %d FThr: %d\n", c_thr, f_thr);
if (t->raw.start_offset <= c_thr
&& (post_frac_start_adj > f_thr))
t->coarse = (t->raw.coarse-1) * 16;
else
t->coarse = (t->raw.coarse) * 16;
int64_t post_frac_multiplied = post_frac_start_adj * (int64_t)hw->calib.adsfr_val;
t->coarse += t->raw.subcycle_offset
t->coarse += sign_extend(t->raw.subcycle_offset, 5)
+ (post_frac_multiplied >> 24);
t->frac = (post_frac_multiplied >> 12) & 0xfff;
......@@ -1192,11 +1202,11 @@ void ts_postprocess(fdelay_device_t *dev, fdelay_time_t *t)
int fdelay_read(fdelay_device_t *dev, fdelay_time_t *timestamps, int how_many)
{
fd_decl_private(dev)
uint32_t tsbcr;
int n_read = 0;
// dbg("tsbcr %x\n", fd_readl(FD_REG_TSBCR));
while(poll_rbuf(dev))
while(poll_rbuf(dev, &tsbcr))
{
fdelay_time_t ts;
uint32_t seq_frac;
......@@ -1204,12 +1214,15 @@ int fdelay_read(fdelay_device_t *dev, fdelay_time_t *timestamps, int how_many)
if(hw->raw_mode)
{
fd_writel(FD_TSBR_ADVANCE_ADV, FD_REG_TSBR_ADVANCE);
uint32_t cyc, dbg;
ts.raw.utc = ((int64_t) (fd_readl(FD_REG_TSBR_SECH) & 0xff) << 32) | fd_readl(FD_REG_TSBR_SECL);
cyc = fd_readl(FD_REG_TSBR_CYCLES) & 0xfffffff;
ts.raw.coarse = cyc >> 4;
ts.raw.start_offset = cyc & 0xf;
dbg = fd_readl(FD_REG_TSBR_DEBUG);
seq_frac = fd_readl(FD_REG_TSBR_FID);
......@@ -1227,12 +1240,15 @@ int fdelay_read(fdelay_device_t *dev, fdelay_time_t *timestamps, int how_many)
} else {
fd_writel(FD_TSBR_ADVANCE_ADV, FD_REG_TSBR_ADVANCE);
ts.utc = ((int64_t) (fd_readl(FD_REG_TSBR_SECH) & 0xff) << 32) | fd_readl(FD_REG_TSBR_SECL);
ts.coarse = fd_readl(FD_REG_TSBR_CYCLES) & 0xfffffff;
// dbg("Coarse %d\n", ts.coarse);
seq_frac = fd_readl(FD_REG_TSBR_FID);
ts.frac = FD_TSBR_FID_FINE_R(seq_frac);
ts.seq_id = FD_TSBR_FID_SEQID_R(seq_frac);
ts.raw.tsbcr = tsbcr;
// ts.channel = FD_TSBR_FID_CHANNEL_R(seq_frac);
}
......@@ -1264,7 +1280,7 @@ int fdelay_configure_output(fdelay_device_t *dev, int channel, int enable, int64
delta = fdelay_from_picos(delta_ps);
printf("Start: %lld: %d:%d rep %d\n", start.utc, start.coarse, start.frac, rep_count);
// printf("Start: %lld: %d:%d rep %d\n", start.utc, start.coarse, start.frac, rep_count);
chan_writel(hw->frr_cur[channel-1], FD_REG_FRR);
......@@ -1316,11 +1332,14 @@ int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fd
end = ts_add_ps(t_start, hw->output_user_offset + width_ps - 4000);
delta = fdelay_from_picos(delta_ps);
#if 0
printf("Channel: %d\n",channel);
printf("TStart: %d: %d:%d rep %d\n", t_start.utc, t_start.coarse, t_start.frac, rep_count);
printf("Start: %d: %d:%d rep %d\n", start.utc, start.coarse, start.frac, rep_count);
printf("End: %d: %d:%d rep %d\n", end.utc, end.coarse, end.frac, rep_count);
printf("Delta: %d: %d:%d rep %d\n", delta.utc, delta.coarse, delta.frac, rep_count);
#endif
chan_writel(hw->frr_cur[channel-1], FD_REG_FRR);
......@@ -1455,28 +1474,3 @@ int fdelay_dbg_sync_lost(fdelay_device_t *dev)
return (fd_readl(FD_REG_EIC_ISR) & FD_EIC_ISR_SYNC_STATUS) ? 1 : 0;
}
# if 0
/* We might implement SPLL-based DMTD calibration, but not now - don't include in the driver */
int fd_update_spll(fdelay_device_t *dev)
{
struct spll_helper_state pll;
fd_decl_private(dev)
int i =0;
helper_start(dev, &pll);
fd_writel(FD_CALR_CAL_DMTD, FD_REG_CALR);
sgpio_set_pin(dev, SGPIO_TRIG_SEL, 0);
for(;;)
{
helper_update(&pll);
//if(pll.prelock.ld.locked)
// dbg("LOCK!");
}
}
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <getopt.h>
#include "spec/speclib.h"
#include "fdelay_lib.h"
void spec_writel(void *priv, uint32_t data, uint32_t addr)
{
*(volatile uint32_t *)(priv + addr) = data;
}
void loader_low_level(){}; /* fixme: include the kernel file */
uint32_t spec_readl(void *priv, uint32_t addr)
static void fd_spec_writel(void *priv, uint32_t data, uint32_t addr)
{
return *(volatile uint32_t *)(priv + addr);
spec_writel(priv, data, addr);
}
void *map_spec(int bus, int dev)
static uint32_t fd_spec_readl(void *priv, uint32_t addr)
{
char path[1024];
int fd;
void *ptr;
uint64_t base;
snprintf(path, sizeof(path), "/sys/bus/pci/drivers/spec/0000:%02x:%02x.0/resource", bus, dev);
FILE *f = fopen(path, "r");
fscanf(f, "0x%llx", &base);
printf("raw base addr: %llx\n", base);
fd = open("/dev/mem", O_SYNC | O_RDWR);
if(fd <= 0)
{
perror("open");
return NULL;
}
ptr = mmap(NULL, 0x100000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (void*)base);
if((int)ptr == -1)
{
perror("mmap");
close(fd);
return NULL;
}
return ptr;
return spec_readl(priv, addr);
}
int spec_fdelay_init(fdelay_device_t *dev, int pbus, int pdev)
int spec_fdelay_init_bd(fdelay_device_t *dev, int bus, int dev_fn, uint32_t base)
{
dev->priv_io = map_spec(pbus, pdev);
dev->priv_io = spec_open(bus, dev_fn);
if(!dev->priv_io)
{
fprintf(stderr,"Can't map the SPEC @ %x:%x\n", pbus, pdev);
fprintf(stderr,"Can't map the SPEC @ %x:%x\n", bus, dev_fn);
return -1;
}
dev->writel = spec_writel;
dev->readl = spec_readl;
dev->base_addr = 0x80000;
dev->writel = fd_spec_writel;
dev->readl = fd_spec_readl;
dev->base_addr = base;
spec_vuart_init(dev->priv_io, 0xe0500); /* for communication with WRCore during DMTD calibration */
if(fdelay_init(dev) < 0)
return -1;
return 0;
}
int spec_fdelay_init(fdelay_device_t *dev, int argc, char *argv[])
{
int bus = -1, dev_fn = -1, c;
uint32_t base = 0x80000;
while ((c = getopt (argc, argv, "b:d:f:")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'u':
sscanf(optarg, "%i", &base);
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] [-u Fine Delay base] [-k]\"\n", argv[0]);
fprintf(stderr,
"By default, the first available SPEC is used and the FD is assumed at 0x%x.\n", base);
return -1;
}
}
return spec_fdelay_init_bd(dev, bus, dev_fn, base);
}
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