Commit 3b3f81f6 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

File Delay PTS: a load of bug fixes, use new G-mode bitstream & updated calibration EEPROM layout

parent 42eb52c4
*.pyc
*.so
\ No newline at end of file
obj-m = cp210x.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
This diff is collapsed.
......@@ -5,8 +5,19 @@
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
sudo rmmod cp210x
sudo rmmod usbtmc
sudo rmmod spec
sudo insmod ./test/fmcdelay1ns4cha/lib/spec/kernel/spec.ko
sudo insmod ./cp210x-driver/cp210x.ko
cd usbdriver
sudo ./usbtmc_load
cd ..
LOGDIR=./log_fmcdelay1ns4cha
mkdir -p $LOGDIR
sudo rm -fr $LOGDIR/pts*
......@@ -41,7 +52,7 @@ do
echo "Test series run $nb_test out of $nb_test_limit"
echo " "
sudo ./ptsDelay.py -b FmcDelay1ns4cha -s $serial -e $extra_serial -t./test/fmcdelay1ns4cha/python -l $LOGDIR 00 01 02 03 04 05
sudo ./ptsDelay.py -b FmcDelay1ns4cha -s $serial -e $extra_serial -t./test/fmcdelay1ns4cha/python -l $LOGDIR 00 01 02 03 04 05 06
if [ "$nb_test" != "$nb_test_limit" ]
then
......
No preview for this file type
......@@ -20,7 +20,15 @@
#define AR2_Disable(chan) (1<<(3+chan))
#define AR2_Adj(chan, value) (((value)&0xf)<<(12+4*(chan-7)))
#define AR3_RaSpeed(num,val) (val << (num*2 + 21))
#define AR2_DelRise1(value) (((value)&0x3)<<(20))
#define AR2_DelFall1(value) (((value)&0x3)<<(22))
#define AR2_DelRise2(value) (((value)&0x3)<<(24))
#define AR2_DelFall2(value) (((value)&0x3)<<(26))
#define AR3_DelTx(chan, value) (((value)&0x3)<<(5 + (chan -1 ) * 2))
#define AR3_RaSpeed(chan, value) (((value)&0x3)<<(21 + (chan ) * 2))
#define AR4_RaSpeed(chan, value) (((value)&0x3)<<(10 + (chan-3) * 2))
#define AR3_Zero (0) // nothing interesting for the Fine Delay
......
......@@ -3,7 +3,7 @@
* File : fd_channel_regs.h
* Author : auto-generated by wbgen2 from fd_channel_wishbone_slave.wb
* Created : Wed Apr 11 11:05:22 2012
* Created : Fri Feb 15 12:07:17 2013
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb
......@@ -57,7 +57,7 @@
/* 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 */
/* definitions for field: Force Output High in reg: Delay Control Register */
#define FD_DCR_FORCE_HI WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Fine Range Register */
......
......@@ -3,7 +3,7 @@
* File : fd_main_regs.h
* Author : auto-generated by wbgen2 from fd_main_wishbone_slave.wb
* Created : Mon Jun 4 13:42:20 2012
* Created : Fri Feb 15 12:07:16 2013
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb
......@@ -64,7 +64,7 @@
/* definitions for field: PLL Locked in reg: Global Control Register */
#define FD_GCR_DDR_LOCKED WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Mezzanice Present in reg: Global Control Register */
/* definitions for field: Mezzanine Present in reg: Global Control Register */
#define FD_GCR_FMC_PRESENT WBGEN2_GEN_MASK(3, 1)
/* definitions for register: Timing Control Register */
......@@ -99,46 +99,46 @@
/* definitions for register: Time Register - sub-second 125 MHz clock cycles */
/* definitions for register: TDC Data Register */
/* definitions for register: Host-driven TDC Data Register */
/* definitions for register: TDC control/status reg */
/* definitions for register: Host-driven TDC Control/Status */
/* definitions for field: Start TDC write in reg: TDC control/status reg */
/* definitions for field: Write to TDC in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_WRITE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Start TDC read in reg: TDC control/status reg */
/* definitions for field: Read from TDC in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_READ WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Empty flag in reg: TDC control/status reg */
/* definitions for field: Empty flag in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_EMPTY WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Start enable in reg: TDC control/status reg */
/* definitions for field: Stop enable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_STOP_EN WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Start disable in reg: TDC control/status reg */
/* definitions for field: Start disable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_START_DIS WBGEN2_GEN_MASK(4, 1)
/* definitions for field: Stop enable in reg: TDC control/status reg */
/* definitions for field: Start enable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_START_EN WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Stop disable in reg: TDC control/status reg */
/* definitions for field: Stop disable in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_STOP_DIS WBGEN2_GEN_MASK(6, 1)
/* definitions for field: write 1: Pulse the Alutrigger line in reg: TDC control/status reg */
/* definitions for field: Pulse <code>Alutrigger</code> line in reg: Host-driven TDC Control/Status */
#define FD_TDCSR_ALUTRIG WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Calibration register */
/* definitions for field: Triggers calibration pulses in reg: Calibration register */
/* definitions for field: Generate calibration pulses (type 1 calibration) in reg: Calibration register */
#define FD_CALR_CAL_PULSE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PPS Calibration output enable in reg: Calibration register */
#define FD_CALR_CAL_PPS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Produce DDMTD calibration pattern in reg: Calibration register */
/* definitions for field: Produce DDMTD calibration pattern (type 2 calibration) in reg: Calibration register */
#define FD_CALR_CAL_DMTD WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Enable pulse generation in reg: Calibration register */
/* definitions for field: Calibration pulse output select/mask in reg: Calibration register */
#define FD_CALR_PSEL_MASK WBGEN2_GEN_MASK(3, 4)
#define FD_CALR_PSEL_SHIFT 3
#define FD_CALR_PSEL_W(value) WBGEN2_GEN_WRITE(value, 3, 4)
......@@ -171,16 +171,16 @@
/* definitions for register: Acam Timestamp Merging Control Register */
/* definitions for field: Wraparound Coarse Threshold in reg: Acam Timestamp Merging Control Register */
#define FD_ATMCR_C_THR_MASK WBGEN2_GEN_MASK(0, 4)
#define FD_ATMCR_C_THR_MASK WBGEN2_GEN_MASK(0, 8)
#define FD_ATMCR_C_THR_SHIFT 0
#define FD_ATMCR_C_THR_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define FD_ATMCR_C_THR_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
#define FD_ATMCR_C_THR_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define FD_ATMCR_C_THR_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: Wraparound Fine Threshold in reg: Acam Timestamp Merging Control Register */
#define FD_ATMCR_F_THR_MASK WBGEN2_GEN_MASK(4, 23)
#define FD_ATMCR_F_THR_SHIFT 4
#define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 4, 23)
#define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 4, 23)
#define FD_ATMCR_F_THR_MASK WBGEN2_GEN_MASK(8, 23)
#define FD_ATMCR_F_THR_SHIFT 8
#define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 8, 23)
#define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 8, 23)
/* definitions for register: Acam Start Offset Register */
......@@ -399,9 +399,9 @@
#define FD_REG_TM_SECL 0x00000014
/* [0x18]: REG Time Register - sub-second 125 MHz clock cycles */
#define FD_REG_TM_CYCLES 0x00000018
/* [0x1c]: REG TDC Data Register */
/* [0x1c]: REG Host-driven TDC Data Register */
#define FD_REG_TDR 0x0000001c
/* [0x20]: REG TDC control/status reg */
/* [0x20]: REG Host-driven TDC Control/Status */
#define FD_REG_TDCSR 0x00000020
/* [0x24]: REG Calibration register */
#define FD_REG_CALR 0x00000024
......
......@@ -40,22 +40,23 @@ typedef struct fdelay_device
} fdelay_device_t;
typedef struct {
int64_t utc, utc_sh;
int32_t coarse, coarse_sh;
int64_t utc;
int32_t coarse;
int32_t start_offset;
int32_t subcycle_offset;
int32_t frac;
uint32_t tsbcr;
} fdelay_raw_time_t;
typedef struct
{
fdelay_raw_time_t raw;
int64_t utc; /* TAI seconds */ /* FIXME: replace all UTCs with TAIs or seconds for clarity */
int32_t coarse; /* 125 MHz counter cycles */
int32_t frac; /* Fractional part (<8ns) */
uint16_t seq_id; /* Sequence ID to detect missed timestamps */
int channel;
fdelay_raw_time_t raw;
} fdelay_time_t;
/*
......@@ -132,4 +133,7 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
int fdelay_write_eeprom_from_file(fdelay_device_t *dev, const char *filename, uint32_t offset);
void fdelay_set_dac(fdelay_device_t *dev, int value);
#endif
......@@ -31,6 +31,7 @@
/* ACAM TDC operation modes */
#define ACAM_RMODE 0
#define ACAM_IMODE 1
#define ACAM_GMODE 2
/* MCP23S17 register addresses (only ones which are used by the lib) */
#define MCP_IODIR 0x0
......@@ -60,27 +61,27 @@
/* Calibration eeprom I2C address */
#define EEPROM_ADDR 0x50
/* Default TDC parameters. Formerly kept in the EEPROM, now hardcoded. */
#define FD_ATMCR_VALUE (26 | (1500 << 8))
#define FD_ASOR_VALUE 17000
#define FD_ADSFR_VALUE 84977
#define FD_ACAM_START_OFFSET_VALUE 10000
#define EEPROM_CALIB_OFFSET (6*1024)
struct fd_calib {
int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t zero_offset[4]; /* Output zero offset, fixed point */
uint32_t adsfr_val; /* ADSFR register value */
uint32_t acam_start_offset; /* ACAM Start offset value */
uint32_t atmcr_val; /* ATMCR register value */
uint32_t tdc_zero_offset; /* Zero offset of the TDC, in ps */
/* The user can add a signed offset, in picoseconds */
int32_t tdc_user_offset;
int32_t ch_user_offset[4];
int32_t tdc_flags;
int32_t out_zero_offset[4]; /* Output zero offset, fixed point */
int32_t tdc_zero_offset; /* Zero offset of the TDC, in ps */
uint32_t vcxo_default_tune;
};
struct fd_calib_on_eeprom {
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t hash;
uint16_t size;
uint16_t version;
uint32_t date;
struct fd_calib calib;
};
......@@ -102,7 +103,6 @@ struct fine_delay_hw
int raw_mode;
int do_long_tests;
struct fd_calib calib;
int64_t input_user_offset, output_user_offset;
};
/* some useful access/declaration macros */
......
/*
* Public header for the raw I/O interface for PCI or PCI express interfaces
*
* Copyright (C) 2010 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
#ifndef __RAWRABBIT_H__
#define __RAWRABBIT_H__
#include <linux/types.h>
#include <linux/ioctl.h>
#ifdef __KERNEL__ /* The initial part of the file is driver-internal stuff */
#include <linux/pci.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include <linux/wait.h>
#include <linux/completion.h>
struct rr_devsel;
struct rr_dev {
struct rr_devsel *devsel;
struct pci_driver *pci_driver;
struct pci_device_id *id_table;
struct pci_dev *pdev; /* non-null after pciprobe */
struct mutex mutex;
wait_queue_head_t q;
void *dmabuf;
char *fwname;
struct timespec irqtime;
unsigned long irqcount;
struct completion complete;
struct resource *area[3]; /* bar 0, 2, 4 */
void *remap[3]; /* ioremap of bar 0, 2, 4 */
unsigned long flags;
struct work_struct work;
const struct firmware *fw;
struct completion fw_load;
void (*load_program)(struct rr_dev *); /* lm32 */
int usecount;
#ifdef IS_SPEC_DEMO
struct miscdevice misc;
char miscname[32]; /* "spec-demo-<bus>-<slot> */
struct list_head list;
#endif
};
extern char *rr_fwname; /* module parameter. If "" then defaults apply */
#define RR_FLAG_REGISTERED 0x00000001
#define RR_FLAG_IRQDISABLE 0x00000002
#define RR_FLAG_IRQREQUEST 0x00000002
#define RR_PROBE_TIMEOUT (HZ) /* for pci_register_drv */
/* These two live in ./loader.c */
extern void rr_ask_firmware(struct rr_dev *dev);
extern void rr_load_firmware(struct work_struct *work);
/* And, for the spec only, this is in ./spec-loader.c */
extern void spec_ask_program(struct rr_dev *dev);
#endif /* __KERNEL__ */
/* By default, the driver registers for this vendor/devid */
#define RR_DEFAULT_VENDOR 0x1a39
#define RR_DEFAULT_DEVICE 0x0004
#define RR_DEFAULT_FWNAME "rrabbit-%P-%p@%b"
#define RR_MAX_FWNAME_SIZE 64
#define RR_DEFAULT_BUFSIZE (1<<20) /* 1MB */
#define RR_PLIST_SIZE 4096 /* no PAGE_SIZE in user space */
#define RR_PLIST_LEN (RR_PLIST_SIZE / sizeof(void *))
#define RR_MAX_BUFSIZE (RR_PLIST_SIZE * RR_PLIST_LEN)
/* This structure is used to select the device to be accessed, via ioctl */
struct rr_devsel {
__u16 vendor;
__u16 device;
__u16 subvendor; /* RR_DEVSEL_UNUSED to ignore subvendor/dev */
__u16 subdevice;
__u16 bus; /* RR_DEVSEL_UNUSED to ignore bus and devfn */
__u16 devfn;
};
#define RR_DEVSEL_UNUSED 0xffff
/* Offsets for BAR areas in llseek() and/or ioctl */
#define RR_BAR_0 0x00000000
#define RR_BAR_2 0x20000000
#define RR_BAR_4 0x40000000
#define RR_BAR_BUF 0xc0000000 /* The DMA buffer */
#define RR_IS_DMABUF(addr) ((addr) >= RR_BAR_BUF)
#define __RR_GET_BAR(x) ((x) >> 28)
#define __RR_SET_BAR(x) ((x) << 28)
#define __RR_GET_OFF(x) ((x) & 0x0fffffff)
static inline int rr_is_valid_bar(unsigned long address)
{
int bar = __RR_GET_BAR(address);
return bar == 0 || bar == 2 || bar == 4 || bar == 0x0c;
}
static inline int rr_is_dmabuf_bar(unsigned long address)
{
int bar = __RR_GET_BAR(address);
return bar == 0x0c;
}
struct rr_iocmd {
__u32 address; /* bar and offset */
__u32 datasize; /* 1 or 2 or 4 or 8 */
union {
__u8 data8;
__u16 data16;
__u32 data32;
__u64 data64;
};
};
/* ioctl commands */
#define __RR_IOC_MAGIC '4' /* random or so */
#define RR_DEVSEL _IOW(__RR_IOC_MAGIC, 0, struct rr_devsel)
#define RR_DEVGET _IOR(__RR_IOC_MAGIC, 1, struct rr_devsel)
#define RR_READ _IOWR(__RR_IOC_MAGIC, 2, struct rr_iocmd)
#define RR_WRITE _IOW(__RR_IOC_MAGIC, 3, struct rr_iocmd)
#define RR_IRQWAIT _IO(__RR_IOC_MAGIC, 4)
#define RR_IRQENA _IO(__RR_IOC_MAGIC, 5)
#define RR_GETDMASIZE _IO(__RR_IOC_MAGIC, 6)
/* #define RR_SETDMASIZE _IO(__RR_IOC_MAGIC, 7, unsigned long) */
#define RR_GETPLIST _IO(__RR_IOC_MAGIC, 8) /* returns a whole page */
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
/* Registers from the gennum header files */
enum {
GNGPIO_BASE = 0xA00,
GNGPIO_DIRECTION_MODE = GNGPIO_BASE + 0x4,
GNGPIO_OUTPUT_ENABLE = GNGPIO_BASE + 0x8,
GNGPIO_OUTPUT_VALUE = GNGPIO_BASE + 0xC,
GNGPIO_INPUT_VALUE = GNGPIO_BASE + 0x10,
FCL_BASE = 0xB00,
FCL_CTRL = FCL_BASE,
FCL_STATUS = FCL_BASE + 0x4,
FCL_IODATA_IN = FCL_BASE + 0x8,
FCL_IODATA_OUT = FCL_BASE + 0xC,
FCL_EN = FCL_BASE + 0x10,
FCL_TIMER_0 = FCL_BASE + 0x14,
FCL_TIMER_1 = FCL_BASE + 0x18,
FCL_CLK_DIV = FCL_BASE + 0x1C,
FCL_IRQ = FCL_BASE + 0x20,
FCL_TIMER_CTRL = FCL_BASE + 0x24,
FCL_IM = FCL_BASE + 0x28,
FCL_TIMER2_0 = FCL_BASE + 0x2C,
FCL_TIMER2_1 = FCL_BASE + 0x30,
FCL_DBG_STS = FCL_BASE + 0x34,
FCL_FIFO = 0xE00,
PCI_SYS_CFG_SYSTEM = 0x800
};
#endif /* __RAWRABBIT_H__ */
#ifndef __RR_IO_H
#define __RR_IO_H
#include <stdint.h>
#include <rawrabbit.h>
int rr_bind(int a_fd);
int rr_init(int bus, int devfn);
int rr_writel(uint32_t data, uint32_t addr);
uint32_t rr_readl(uint32_t addr);
int rr_load_bitstream(const void *data, int size8);
int rr_load_bitstream_from_file(const char *file_name);
#endif
......@@ -41,6 +41,52 @@ uint32_t wait_promptTimeout;
/* WR core shell communication functions */
/* Waits for a WR Core and returns the output of the previous command in rv */
static void wait_prompt(fdelay_device_t *dev, char *rv)
{
char buf[16384],c;
int pos = 0;
memset(buf, 0, sizeof(buf));
while(pos < sizeof(buf))
{
if(spec_vuart_rx(dev->priv_io, &c, 1) == 1)
{
buf[pos++] = c;
if(pos >= 5 && !strcmp(buf + pos - 5, "wrc# "))
{
int old_pos;
if(!rv)
return;
while(pos>0) if(buf[pos]=='\n'||buf[pos]=='\r')
break;
else
pos--;
pos-=2;
old_pos = pos;
while(pos>0) if(buf[pos]=='\n'||buf[pos]=='\r')
break;
else
pos--;
strncpy(rv, buf+pos+1, old_pos - pos);
rv[old_pos-pos]=0;
return;
}
}
}
dbg("Failure: shell buffer overflow.\n");
exit(1);
}
static void shell_purge(fdelay_device_t *dev)
{
char c='\r';
......@@ -56,68 +102,26 @@ static void shell_purge(fdelay_device_t *dev)
}
}
/* executes a shell command on the associated WR core */
static int wrc_shell_exec(fdelay_device_t *dev, const char *cmd, char *retval, int64_t timeout)
static int wrc_shell_exec(fdelay_device_t *dev, const char *cmd, char *retval)
{
char c;
char buf[16384];
int buf_pos = 0, i;
shell_purge(dev);
while(spec_vuart_rx(dev->priv_io, &c, 1) == 1);
spec_vuart_tx(dev->priv_io, (char *)cmd, strlen(cmd));
spec_vuart_tx(dev->priv_io, "\r", 1);
int64_t start_tics = get_tics();
for(;;)
{
if(spec_vuart_rx(dev->priv_io, &c, 1) == 1)
buf[buf_pos++] = c;
if(buf_pos >= sizeof(buf))
{
return -1;
}
if(get_tics() - start_tics > timeout)
break;
}
buf[buf_pos] = 0;
wait_prompt(dev, retval);
if(retval)
{
int p1 = -1,p2 = -1;
strcpy(retval, "");
/* fprintf(stderr,"BUF_DUMP:\n");
for(i=0;i<buf_pos;i++)
fprintf(stderr,"%d: '%c'\n", i, buf[i]);
fprintf(stderr,"END_BUF_DUMP\n");*/
for(i=buf_pos-1;i>=0; i--) if(buf[i] == '\n' || buf[i] == '\r')
{ p2 = i; break; }
i-=2;
for(;i>=0; i--) if(buf[i] == '\n' || buf[i] == '\r')
{ p1 = i; break; }
if(p1 + 1 == p2)
strcpy(retval, "");
else
strncpy(retval, buf+p1+1, p2-p1);
for(i=0;i<strlen(retval);i++)
if(retval[i] == '\n' || retval[i] == '\r')
retval[i] = 0;
dbg("wr_core exec '%s', retval: '%s'\n", cmd, retval);
}
return 0;
}
#define DMTD_N_AVGS 10 /* number of average samples */
#define DELAY_SETPOINT 500000 /* test delay value */
#define DMTD_N_AVGS 100 /* number of average samples */
#define DELAY_SETPOINT 750000 /* test delay value */
#define DMTD_PULSE_PERIOD 144
#define DMTD_OUTPUT_PERIOD (16384 * DMTD_PULSE_PERIOD / 2) /* period of the DDMTD output signal in 62.5 MHz clock cycles */
......@@ -177,9 +181,10 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
fd_writel(FD_CALR_PSEL_W(0), FD_REG_CALR);
/* Configure the output to introduce DELAY_SETPOINT delay (but with fixed offset set to 0)*/
hw->calib.zero_offset[channel-1] = 0;
hw->calib.out_zero_offset[channel-1] = 0;
hw->calib.tdc_zero_offset = 0;
fdelay_configure_output(dev, channel, 1, (int64_t)DELAY_SETPOINT, 200000LL, 0LL, 1);
fdelay_configure_output(dev, channel, 1, (int64_t)DELAY_SETPOINT, 300000LL, 0LL, 1);
/* Disable ALL outputs to prevent the calibration pulses from driving whatever
is connected to the board */
......@@ -213,7 +218,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
/* Get DMTD_N_AVGS samples to reduce error */
n_in = n_out = 0;
int64_t ts = get_tics();
while((n_in < DMTD_N_AVGS || n_out < DMTD_N_AVGS) && ((get_tics()-ts) < 1000000))
while((n_in < DMTD_N_AVGS || n_out < DMTD_N_AVGS) && ((get_tics()-ts) < 10000000))
{
if(read_dmtd(dev, &ch_in, 0))
{
......@@ -227,7 +232,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
samples_out[n_out++] = ch_out.phase;
}
}
if((get_tics()-ts) >= 1000000)
if((get_tics()-ts) >= 10000000)
{
dbg("%s has timed out\n", __FUNCTION__);
return -1;
......@@ -255,11 +260,12 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
*std = sqrt(s / (double)(DMTD_N_AVGS-1)) * scalefact;
fd_writel(FD_CALR_PSEL_W(0), FD_REG_CALR);
/* Reset to normal trigger and disable input and output */
if(sgpio_set_pin(dev, SGPIO_TRIG_SEL, 1) < 0)
return -1;
fdelay_configure_trigger(dev, 0, 0);
fdelay_configure_output(dev, channel, 0, (int64_t)DELAY_SETPOINT, 200000LL, 0LL, 1);
return 0;
}
......@@ -270,7 +276,8 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
char c;
int i, error = 0;
fd_decl_private(dev);
wait_promptTimeout = *userTimeout;
int64_t base = 0, prev_tag = -1;
if(spec_load_lm32(dev->priv_io, filename, 0xc0000))
......@@ -284,23 +291,23 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
/* Configure the WR core to produce a proper calibration clock: */
/* Disable PTP and enter free-running master mode */
if(wrc_shell_exec(dev, "ptp stop", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "ptp stop", resp) < 0)
return -1;
if(wrc_shell_exec(dev, "mode master", resp, 5000000LL) < 0)
if(wrc_shell_exec(dev, "mode master", resp) < 0)
return -1;
/* And lock the DMTD oscillator to the FMC clock instead of the SPEC 125 MHz oscillator. Set the FMC VCO DAC to 0
to have some headroom */
if(wrc_shell_exec(dev, "pll sdac 1 0", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll sdac 1 0", resp) < 0)
return -1;
if(wrc_shell_exec(dev, "pll init 2 1 1", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll init 2 1 1", resp) < 0)
return -1;
/* Wait until the PLL locks... */
int64_t ts = get_tics();
while(1)
{
if(wrc_shell_exec(dev, "pll cl 0", resp, 100000LL) < 0)
if(wrc_shell_exec(dev, "pll cl 0", resp) < 0)
return -1;
if(!strcmp(resp, "1"))
break;
......@@ -318,17 +325,17 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
for(i=1;i<=4;i++)
{
dbg("\n\nPerforming DDMTD delay calibration of channel %d\n", i);
dbg("\n\nPerforming DDMTD-based calibration of channel %d\n", i);
if(calibrate_channel(dev, i, &mean_out[i-1], &std_out[i-1]) < 0)
{
dbg("Failed, DMTD not possible for channel %d, DMTD Tag Ready flag is not coming high\n", i);
hw->calib.zero_offset[i-1] = 0;
dbg("Failed, DDMTD calibration failure for channel %d, DMTD Tag Ready flag is not coming high\n", i);
hw->calib.out_zero_offset[i-1] = 0;
error = 1;
}
else
{
dbg("Channel %d: delay %.0f ps, std %.0f ps.\n", i, mean_out[i-1], std_out[i-1]);
hw->calib.zero_offset[i-1] = mean_out[i-1] - 500000;
hw->calib.out_zero_offset[i-1] = mean_out[i-1] - DELAY_SETPOINT - hw->calib.tdc_zero_offset;
}
}
return error ? -1 : 0;
......
This diff is collapsed.
......@@ -151,6 +151,7 @@ int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_
int i, busy;
for(i=0;i<size;i++)
{
mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
......
No preview for this file type
......@@ -28,6 +28,7 @@ struct spec_private {
uint32_t vuart_base;
};
/* Checks if there's a SPEC card at bus/def_fn. If one (or both) parameters are < 0, takes first available card and returns 0.
If no cards have been detected, returns -1 */
static int spec_scan(int *bus, int *devfn)
......@@ -119,12 +120,15 @@ void spec_close(void *card)
void spec_writel(void *card, uint32_t data, uint32_t addr)
{
// printf("Writel %x %x\n", addr, data);
struct spec_private *p = (struct spec_private *) card;
*(volatile uint32_t *) (p->bar0 + addr) = data;
}
uint32_t spec_readl(void *card, uint32_t addr)
{
// printf("Readl %x\n", addr);
struct spec_private *p = (struct spec_private *) card;
return *(volatile uint32_t *) (p->bar0 + addr);
}
......@@ -199,6 +203,7 @@ int spec_load_bitstream(void *card, const char *filename)
char *buf;
size_t size;
// printf("load-bitstream: %s\n", filename);
buf = load_binary_file(filename, &size);
if(!buf)
return -1;
......
/*
Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Thu May 3 17:36:38 2012
* Created : Thu Aug 9 10:31:41 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
......@@ -89,4 +90,5 @@
#define UART_REG_HOST_TDR 0x10
#define UART_REG_HOST_RDR 0x14
#endif
......@@ -5,6 +5,8 @@
#include "spec/tools/speclib.h"
#include "fdelay_lib.h"
void printk(){}
static void fd_spec_writel(void *priv, uint32_t data, uint32_t addr)
{
spec_writel(priv, data, addr);
......
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 4/6/2012
# Import system modules
import sys
import time
import os
# Add common modules and libraries location to path
sys.path.append('usb_box')
sys.path.append('cp210x')
# Import specific modules
from calibr_box import *
from find_usb_tty import *
"""
test18: Test calibration box
"""
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
while True:
box.select_trigger_loopback(1)
time.sleep(1)
box.select_trigger_loopback(0)
time.sleep(1)
# -*- coding: utf-8 -*-
__author__ = "Johannes Hölzl <johannes.hoelzl@gmx.de>"
__license__ = "GNU LGPL"
This diff is collapsed.
# -*- coding: utf-8 -*-
# Copyright (c) 2007 Johannes Hölzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
import cp210x
from cp210x import from_binary, to_binary, iif, VALUES
__all__ = ['EEPROM', 'HexFileError']
POS_BAUDRATE_TABLE = 0x0000
POS_PART_NUMBER = 0x01FF
POS_PRODUCT_STRING = 0x0208
POS_SERIAL_NUMBER = 0x0307
POS_PRODUCT_ID = 0x0390
POS_VENDOR_ID = 0x0392
POS_VERSION = 0x0394
POS_CFG_ATTRIBUTES = 0x03A1
POS_MAX_POWER = 0x03A2
POS_VENDOR_STRING = 0x03C3
POS_LOCK_VALUE = 0x03FF
class HexFileError(StandardError):
pass
def checksum(line):
return sum(ord(c) for c in line) & 0xFF
def _int_value(position, size, read=lambda x:x, write=lambda x:x):
def get(self):
return read(from_binary(self.get(position, size)))
def set(self, value):
self.set(position, to_binary(write(value), size))
return property(get, set)
def _str_value(position, max_size):
def get(self):
size = from_binary(self.get(position, 1))
assert size <= (max_size + 2) and size >= 2
assert self.get(position + 1, 1) == '\x03', "Missing 0x03 at %04X" % (position + 1)
return self.get(position + 2, size - 2).decode('utf-16-le')
def set(self, value):
encoded = value.encode('utf-16-le')
assert len(encoded) <= max_size
self.set(position, chr(len(encoded) + 2) + '\x03' + encoded)
return property(get, set)
class EEPROM(object):
START_ADDRESS = 0x3600
def __init__(self, content=None):
if isinstance(content, str) or content is None:
assert content is None or len(content) == cp210x.SIZE_EEPROM
self.content = content
elif isinstance(content, cp210x.Cp210xProgrammer):
self.content = content.get_eeprom_content()
else:
self.parse_hex_file(content.read())
def write_to_cp210x(self, cp210xDevice):
cp210xDevice.set_eeprom_content(self.content)
def parse_hex_file(self, hex_content):
self.content = ''
address = self.START_ADDRESS
for tag in hex_content.split('\n'):
if not tag.startswith(':'):
raise HexFileError("Line doesn't start with ':'")
try:
content = tag[1:].decode('hex')
except TypeError:
raise HexFileError("Hex data expected")
if len(content) < 5:
raise HexFileError("Line to short")
if checksum(content) != 0:
raise HexFileError("Checksum error")
size = from_binary(content[0])
tag_address = from_binary(content[1:3], le=False)
tag_type = from_binary(content[3:4])
line = content[4:-1]
if tag_type == 0x00:
if tag_address != address:
raise HexFileError("Expected address %04X but found %04X"
% (address, tag_address))
self.content += line
address += len(line)
elif tag_type == 0x01:
if size != 0 or len(line) != 0:
raise HexFileError("Defekt end tag")
break
else:
raise HexFileError("Unknown tag type %02X" % tag_type)
def build_hex_file(self):
for tag_start in range(0, len(self.content), 0x10):
line = self.content[tag_start:tag_start+0x10]
address = self.START_ADDRESS + tag_start
tag = (to_binary(len(line), 1) +
to_binary(address, le=False) +
'\x00' +
line)
cs = checksum(tag)
if cs == 0:
tag += '\x00'
else:
tag += chr(0x100 - cs)
yield ":%s\n" % tag.encode('hex')
yield ":00000001FF\n"
def write_hex_file(self, f):
if isinstance(f, str):
f = file(f, 'wb')
do_close = True
else:
do_close = False
for line in self.build_hex_file():
f.write(line)
if do_close:
f.close()
def read_hex_file(self, f):
if isinstance(f, str):
f = file(f, 'rb')
do_close = True
else:
do_close = False
self.parse_hex_file(f.read())
if do_close:
f.close()
def get(self, pos, length):
return self.content[pos:pos+length]
def set(self, pos, data):
self.content = (self.content[:pos] +
data +
self.content[pos + len(data):])
def _get_baudrate_table(self):
dat = self.get(POS_BAUDRATE_TABLE, cp210x.SIZE_BAUDRATE_TABLE)
return [cp210x.parse_baudrate_cfg(dat[pos:pos+cp210x.SIZE_BAUDRATE_CFG])
for pos in range(0, cp210x.SIZE_BAUDRATE_TABLE,
cp210x.SIZE_BAUDRATE_CFG)]
def _set_baudrate_table(self, baudrates):
assert len(baudrates) == cp210x.SIZE_BAUDRATES
self.set(POS_BAUDRATE_TABLE,
''.join(cp210x.build_baudrate_cfg(*cfg) for cfg in baudrates))
baudrate_table = property(_get_baudrate_table, _set_baudrate_table)
product_string = _str_value(POS_PRODUCT_STRING, cp210x.SIZE_PRODUCT_STRING)
serial_number = _str_value(POS_SERIAL_NUMBER, cp210x.SIZE_SERIAL_NUMBER)
part_number = _int_value(POS_PART_NUMBER, 1)
product_id = _int_value(POS_PRODUCT_ID, 2)
vendor_id = _int_value(POS_VENDOR_ID, 2)
version = _int_value(POS_VERSION, 2,
cp210x.from_bcd2, cp210x.to_bcd2)
bus_powered = _int_value(POS_CFG_ATTRIBUTES, 1,
lambda a: bool(a & 0x40),
lambda a: iif(a, 0xC0, 0x80))
max_power = _int_value(POS_MAX_POWER, 1, lambda p: p*2, cp210x.to_div2)
vendor_string = _str_value(POS_VENDOR_STRING, cp210x.SIZE_VENDOR_STRING)
locked = _int_value(POS_LOCK_VALUE, 1,
lambda l: l == cp210x.LCK_LOCKED,
lambda b: iif(b, cp210x.LCK_LOCKED,
cp210x.LCK_UNLOCKED))
def get_values(self):
return dict((name, getattr(self, name)) for name, type in VALUES)
def set_values(self, values):
for name, value in values.items():
setattr(self, name, value)
# Python interface for "usb.h" version 0.1.4.4.4
#
# Copyright (c) 2005 Robert Hoelzl <robert.hoelzl@gmx.de>
# Copyright (c) 2007 Johannes Hoelzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
from ctypes import *
import sys
class LibUsbNotInstalled(OSError):
pass
try:
if sys.platform == 'darwin':
PATH_MAX = 1024
dll=cdll.LoadLibrary("libusb.dylib")
elif sys.platform == 'linux2':
PATH_MAX = 4096
dll=cdll.LoadLibrary("libusb.so")
else:
raise NotImplementedError("Platform %s not supported by usb.py" % sys.platform)
except OSError:
raise LibUsbNotInstalled()
# helper functions
def func(f, *args, **retval):
f.restype = retval.get('retval', None)
f.argtypes = args
if retval.has_key('rename'): globals()[retval['rename']] = f
else: globals()[f.__name__[4:]] = f
# constants
CLASS_PER_INTERFACE = 0
USB_CLASS_AUDIO = 1
CLASS_COMM = 2
CLASS_HID = 3
CLASS_PRINTER = 7
CLASS_PTP = 6
CLASS_MASS_STORAGE = 8
CLASS_HUB = 9
CLASS_DATA = 10
CLASS_VENDOR_SPEC = 0xff
DT_DEVICE = 0x01
DT_CONFIG = 0x02
DT_STRING = 0x03
DT_INTERFACE = 0x04
DT_ENDPOINT = 0x05
DT_HID = 0x21
DT_REPORT = 0x22
DT_PHYSICAL = 0x23
DT_HUB = 0x29
DT_DEVICE_SIZE = 18
DT_CONFIG_SIZE = 9
DT_INTERFACE_SIZE = 9
DT_ENDPOINT_SIZE = 7
DT_ENDPOINT_AUDIO_SIZE = 9 # Audio extension
DT_HUB_NONVAR_SIZE = 7
class descriptor_header(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8) ]
class string_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("wData", c_uint*1) ]
class hid_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bcdHID", c_uint16),
("bCountryCode", c_uint8),
("bNumDescriptors", c_uint8) ]
MAXENDPOINTS = 32
class endpoint_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bEndpointAddress", c_uint8),
("bmAttributes", c_uint8),
("wMaxPacketSize", c_uint16),
("bInterval", c_uint8),
("bRefresh", c_uint8),
("bSynchAddress", c_uint8),
("extra", POINTER(c_uint8)),
("extralen", c_int) ]
ENDPOINT_ADDRESS_MASK = 0x0f # in bEndpointAddress
ENDPOINT_DIR_MASK = 0x80
ENDPOINT_TYPE_MASK = 0x03 # in bmAttributes
ENDPOINT_TYPE_CONTROL = 0
ENDPOINT_TYPE_ISOCHRONOUS = 1
ENDPOINT_TYPE_BULK = 2
ENDPOINT_TYPE_INTERRUPT = 3
MAXINTERFACES = 32
class interface_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bInterfaceNumber", c_uint8),
("bAlternateSetting", c_uint8),
("bNumEndpoints", c_uint8),
("bInterfaceClass", c_uint8),
("bInterfaceSubClass", c_uint8),
("bInterfaceProtocol", c_uint8),
("iInterface", c_uint8),
("endpoint", POINTER(endpoint_descriptor)),
("extra", POINTER(c_uint8)),
("extralen", c_int) ]
MAXALTSETTING = 128 # Hard limit
class interface(Structure): _fields_ = [
("altsetting", POINTER(interface_descriptor)),
("num_altsetting", c_int) ]
MAXCONFIG = 8
class config_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("wTotalLength", c_uint16),
("bNumInterfaces", c_uint8),
("bConfigurationValue", c_uint8),
("iConfiguration", c_uint16),
("bmAttributes", c_uint8),
("MaxPower", c_uint8),
("interface", POINTER(interface)),
("extra", POINTER(c_uint8)), # Extra descriptors
("extralen", c_int) ]
class device_descriptor(Structure): _fields_ = [
("bLength", c_uint8),
("bDescriptorType", c_uint8),
("bcdUSB", c_uint16),
("bDeviceClass", c_uint8),
("bDeviceSubClass", c_uint8),
("bDeviceProtocol", c_uint8),
("bMaxPacketSize0", c_uint8),
("idVendor", c_uint16),
("idProduct", c_uint16),
("bcdDevice", c_uint16),
("iManufacturer", c_uint8),
("iProduct", c_uint8),
("iSerialNumber", c_uint8),
("bNumConfigurations", c_uint8) ]
class ctrl_setup(Structure): _fields_ = [
("bRequestType", c_uint8),
("bRequest", c_uint8),
("wValue", c_uint16),
("wIndex", c_uint16),
("wLength", c_uint16) ]
REQ_GET_STATUS = 0x00
REQ_CLEAR_FEATURE = 0x01
# 0x02 is reserved
REQ_SET_FEATURE = 0x03
# 0x04 is reserved
REQ_SET_ADDRESS = 0x05
REQ_GET_DESCRIPTOR = 0x06
REQ_SET_DESCRIPTOR = 0x07
REQ_GET_CONFIGURATION = 0x08
REQ_SET_CONFIGURATION = 0x09
REQ_GET_INTERFACE = 0x0A
REQ_SET_INTERFACE = 0x0B
REQ_SYNCH_FRAME = 0x0C
TYPE_STANDARD = (0x00 << 5)
TYPE_CLASS = (0x01 << 5)
TYPE_VENDOR = (0x02 << 5)
TYPE_RESERVED = (0x03 << 5)
RECIP_DEVICE = 0x00
RECIP_INTERFACE = 0x01
RECIP_ENDPOINT = 0x02
RECIP_OTHER = 0x03
ENDPOINT_IN = 0x80
ENDPOINT_OUT = 0x00
# Error codes
ERROR_BEGIN = 500000
#if 1
#define USB_LE16_TO_CPU(x) do { x = ((x & 0xff) << 8) | ((x & 0xff00) >> 8); } while(0)
#else
#define USB_LE16_TO_CPU(x)
#endif
device_p = POINTER("device")
bus_p = POINTER("bus")
class device(Structure): _fields_ = [
("next", device_p),
("prev", device_p),
("filename", c_char*(PATH_MAX + 1)),
("bus", bus_p),
("descriptor", device_descriptor),
("config", POINTER(config_descriptor)),
("dev", c_void_p), # Darwin support
("devnum", c_char),
("num_children", c_uint8),
("children", POINTER(device_p)) ]
SetPointerType(device_p, device)
class bus(Structure): _fields_ = [
("next", bus_p),
("prev", bus_p),
("dirname", c_char*(PATH_MAX + 1)),
("devices", device_p),
("location", c_uint),
("root_dev", device_p) ]
SetPointerType(bus_p, bus)
dev_handle_p = c_void_p
func(dll.usb_open, device_p, retval=dev_handle_p, rename="_open")
func(dll.usb_close, dev_handle_p, retval=c_int)
func(dll.usb_get_string, dev_handle_p, c_int, c_int, c_char_p, c_int, retval=c_int)
func(dll.usb_get_string_simple, dev_handle_p, c_int, c_char_p, c_int, retval=c_int)
func(dll.usb_get_descriptor_by_endpoint, dev_handle_p, c_int, c_uint8, c_uint8, c_void_p, c_int, retval=c_int)
func(dll.usb_get_descriptor, dev_handle_p, c_uint8, c_uint8, c_void_p, c_int, retval=c_int)
func(dll.usb_bulk_write, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_bulk_read, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_interrupt_write, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_interrupt_read, dev_handle_p, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_control_msg, dev_handle_p, c_int, c_int, c_int, c_int, c_char_p, c_int, c_int, retval=c_int)
func(dll.usb_set_configuration, dev_handle_p, c_int, retval=c_int)
func(dll.usb_claim_interface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_release_interface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_set_altinterface, dev_handle_p, c_int, retval=c_int)
func(dll.usb_resetep, dev_handle_p, c_uint16, retval=c_int)
func(dll.usb_clear_halt, dev_handle_p, c_uint16, retval=c_int)
func(dll.usb_reset, dev_handle_p, retval=c_int)
func(dll.usb_strerror, retval=c_char_p)
func(dll.usb_init)
func(dll.usb_set_debug, c_int)
func(dll.usb_find_busses, retval=c_int)
func(dll.usb_find_devices, retval=c_int)
func(dll.usb_device, dev_handle_p, retval=device_p, rename="get_device")
func(dll.usb_get_busses, retval=bus_p)
func(dll.usb_detach_kernel_driver_np, dev_handle_p, c_int, retval=c_int)
# workaround for bug in ctypes 0.9.6 (cannot create functions with c_void_p as retval)
def open(dev):
return cast(_open(dev), dev_handle_p)
# -*- coding: utf-8 -*-
# Copyright (c) 2007 Johannes Hölzl <johannes.hoelzl@gmx.de>
#
# This library is covered by the GNU LGPL, read LICENSE for details.
# For documentation of the baudrate table see:
#
# [AN205] Silicon Labs Application Note 205 Rev. 0.3
# http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Interface/en/an205.pdf
import re
from ConfigParser import ConfigParser
import cp210x
from cp210x import VALUES, SIZE_BAUDRATES
__all__ = ['read_file', 'write_file', 'update_values', 'PrescalerIsZero',
'ValuesFileError']
class ValuesError(StandardError):
pass
class PrescalerIsZero(ValuesError):
pass
class ValuesFileError(ValuesError):
pass
version_pattern = re.compile(r'^\s*(\d\d?)\.(\d\d?)\s*$')
def read_version(s):
match = version_pattern.match(s)
if match is None:
raise ValueError("Version does not match 'xx.yy'")
return (int(match.group(1)), int(match.group(2)))
def write_version(v):
return "%d.%02d" % v
def read_hex(s):
return int(s.strip(), 16)
def write_hex(num):
return "%04X" % num
def write_bool(b):
if b:
return 'yes'
else:
return 'no'
def read_bool(s):
s = s.strip().lower()
if s not in ['true', 'yes', 'false', 'no']:
raise ValueError("Boolean must be either 'true', 'yes', 'false' or 'no'.")
return s in ['true', 'yes']
def read_baudrate_info(s):
values = s.split(',')
if len(values) != 3:
raise ValueError("Baudrate info must be three comma-separated items")
try:
baudgen = read_hex(values[0])
except ValueError:
raise ValueError("The first baudrate info must be a hex-value")
try:
timer0 = read_hex(values[1])
except ValueError:
raise ValueError("The second baudrate info must be a hex-value")
try:
prescale = int(values[2])
except ValueError:
raise ValueError("The thirdbaudrate info must be a number")
return (baudgen, timer0, prescale)
TYPES = {
'boolean': (read_bool, write_bool),
'int': (int, str),
'id': (read_hex, write_hex),
'string': (str, str),
'version': (read_version, write_version),
}
def read_file(fp):
cp = ConfigParser()
if isinstance(fp, str):
cp.read([fp])
else:
cp.readfp(fp)
values = {}
for name, type in VALUES:
if name is 'baudrate_table':
continue
reader, _ = TYPES[type]
if cp.has_option('usb device', name):
try:
values[name] = reader(cp.get('usb device', name))
except ValueError, err:
raise ValuesFileError("Key '%s': %s" % (name, str(err)))
if cp.has_section('baudrate table'):
baudrate_table = []
for name, value in cp.items('baudrate table'):
try:
baudrate = int(name)
except ValueError:
raise ValuesFileError("Key names in 'baudrate table' must be"
" baudrate numbers.")
try:
baudrate_table.append(read_baudrate_info(value) + (baudrate, ))
except ValueError, err:
raise ValuesFileError("Wrong baudrate info %i: %s"
% (baudrate, str(err)))
baudrate_table.sort(key=(lambda i: i[3]), reverse=True)
values['baudrate_table'] = baudrate_table
return values
def write_file(fp, values):
fp.write("[usb device]\n")
for name, type in VALUES:
if name == 'baudrate_table':
continue
_, writer = TYPES[type]
if name in values:
fp.write("%s = %s\n" % (name, writer(values[name])))
if 'baudrate_table' in values:
fp.write("\n")
fp.write("[baudrate table]\n")
for (baudgen, timegen, prescaler,
baudrate) in sorted(values['baudrate_table'], key=(lambda i: i[3]),
reverse=True):
fp.write("%7d = %04X, %04X, %d # %s\n"
% (baudrate, baudgen, timegen, prescaler,
show_baudrate(baudgen, timegen, prescaler)))
def calc_baudrate(baudgen, timegen, prescaler):
# This formulas are from AN205 page 5.
if prescaler == 0:
raise PrescalerIsZero("Prescaler is 0")
baudrate = (24000000. / prescaler) / (0x10000 - baudgen)
return (baudrate, (0x10000 - timegen) * 2)
def show_baudrate(baudgen, timegen, prescaler):
try:
baudrate, timeout = calc_baudrate(baudgen, timegen, prescaler)
except PrescalerIsZero:
return "Wrong data, Prescaler is 0."
if timeout >= 1000:
timeout = "%1.3f ms" % (float(timeout) / 1000)
else:
timeout = "%d us" % timeout
if baudrate is None:
return ", %s" % (baudrate, timeout)
else:
return "%7.0f Baud, %s" % (baudrate, timeout)
def update_values(v, new, dev):
old_baudrate_table = v.get('baudrate_table')
new_baudrate_table = new.get('baudrate_table')
v.update(new)
# update baudrate table
# it is needed, that the baudrate table has 32 entries when it is written
# to the eeprom or device.
if ((old_baudrate_table is not None or new_baudrate_table is not None) and
(new_baudrate_table is None or
len(new_baudrate_table) < SIZE_BAUDRATES)):
if old_baudrate_table is not None:
if len(old_baudrate_table) < SIZE_BAUDRATES:
baudrate_table = old_baudrate_table
else:
baudrate_table = list(merge_baudrate_table(dev.baudrate_table,
old_baudrate_table))
else:
baudrate_table = dev.baudrate_table
if new_baudrate_table:
baudrate_table = list(merge_baudrate_table(baudrate_table,
new_baudrate_table))
v['baudrate_table'] = baudrate_table
def merge_baudrate_table(old, new):
for (old_info, (start, stop)) in zip(old, REQUEST_BAUDRATE_RANGES):
for baudgen, timer, prescaler, baudrate in new:
if ((start is None or baudrate <= start) and
baudrate >= stop):
yield (baudgen, timer, prescaler, baudrate)
break
else:
yield old_info
REQUEST_BAUDRATE_RANGES = [
# The table data is from AN205 Table 1 on page 1.
# Start End Default Baudrate
(None, 2457601), # Undefined
(2457600, 1474561), # Undefined
(1474560, 1053258), # Undefined
(1053257, 670255), # 921600
( 670254, 567139), # 576000
( 567138, 491521), # 500000
( 491520, 273067), # 460800
( 273066, 254235), # 256000
( 254234, 237833), # 250000
( 237832, 156869), # 230400
( 156868, 129348), # 153600
( 129347, 117029), # 128000
( 117028, 77609), # 115200
( 77608, 64112), # 76800
( 64111, 58054), # 64000
( 58053, 56281), # 57600
( 56280, 51559), # 56000
( 51558, 38602), # 51200
( 38601, 28913), # 38400
( 28912, 19251), # 28800
( 19250, 16063), # 19200
( 16062, 14429), # 16000
( 14428, 9613), # 14400
( 9612, 7208), # 9600
( 7207, 4804), # 7200
( 4803, 4001), # 4800
( 4000, 2401), # 4000
( 2400, 1801), # 2400
( 1800, 1201), # 1800
( 1200, 601), # 1200
( 600, 301), # 600
( 300, 57), # 300
]
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 4/6/2012
# Import system modules
import sys
import time
import os
# Import specific modules
from utilFunctions import *
e = FDCalibBlock()
e.save()
e.load()
\ No newline at end of file
......@@ -11,7 +11,13 @@ class fd_timestamp(Structure):
("coarse", c_ulong),
("frac", c_ulong),
("seq_id", c_ushort),
("channel", c_int)]
("channel", c_int),
("raw_utc", c_ulonglong),
("raw_coarse", c_ulong),
("raw_start_offset", c_long),
("raw_subcycle_offset", c_long),
("raw_frac", c_ulong)]
def nsecs(self):
return (float(self.frac) * 8000.0 / 4096.0 + float(self.coarse) * 8000.0) / 1000.0;
......@@ -25,6 +31,7 @@ class fd_timestamp(Structure):
class FineDelay:
BASE_ADDR = 0x80000 #0x84000 for zWR
INIT_RAW_READOUT = 1
def __init__(self, mode, bus = -1):
# check if root
......@@ -80,6 +87,10 @@ class FineDelay:
self.return_value = self.fdelay.fdelay_write_eeprom_from_file(self.handle, c_char_p(filename), c_uint32(offset))
def set_dac(self, value):
self.fdelay.fdelay_set_dac(self.handle, c_uint32(value))
def conf_trigger(self, enable, termination):
self.fdelay.fdelay_configure_trigger(self.handle, c_int(enable), c_int(termination))
......@@ -94,7 +105,7 @@ class FineDelay:
def conf_pulsegen(self, channel, enable, t_start_utc, t_start_coarse, width, delta, count):
t = fd_timestamp(utc = c_ulonglong(t_start_utc), coarse = c_ulong(t_start_coarse))
#print "channel:%d enable:%d start_t:%d width:%d delta:%d count:%d"%(channel, enable, t.utc, width, delta, count)
# print "channel:%d enable:%d start_t:%d width:%d delta:%d count:%d"%(channel, enable, t.utc, width, delta, count)
self.fdelay.fdelay_configure_pulse_gen(self.handle, c_int(channel), c_int(enable), t,
c_ulonglong(width), c_ulonglong(delta), c_int(count))
......@@ -106,6 +117,7 @@ class FineDelay:
t = fd_timestamp()
self.fdelay.fdelay_get_time(self.handle, byref(t))
self.return_value = t
return t
def get_sync_status(self):
# fixme: new WR state machine
......@@ -115,6 +127,7 @@ class FineDelay:
buf = (fd_timestamp * 256)();
ptr = pointer(buf)
n = self.fdelay.fdelay_read(self.handle, ptr, 256)
# print("n %d" % n)
arr = [];
for i in range(0,n):
arr.append(buf[i])
......
......@@ -39,7 +39,7 @@ class c_BoardInfoArea(Structure):
("fru_fid_data", c_char_p),
("typelen_end", c_ubyte),
("pad_len", c_ubyte),
("checksum", c_ubyte),
("checksum", c_ubyte)
]
class c_DCLoadRecord(Structure):
......@@ -50,7 +50,7 @@ class c_DCLoadRecord(Structure):
("max_voltage", c_ushort),
("spec_ripple", c_ushort),
("min_current", c_ushort),
("max_current", c_ushort),
("max_current", c_ushort)
]
class c_DCOutputRecord(Structure):
......@@ -61,14 +61,14 @@ class c_DCOutputRecord(Structure):
("max_pos_voltage_dev", c_ushort),
("ripple", c_ushort),
("min_current_draw", c_ushort),
("max_current_draw", c_ushort),
("max_current_draw", c_ushort)
]
class c_InternalUseArea(Structure):
_fields_ = [
("format", c_ubyte),
("len", c_int),
("data", c_char_p),
("data", c_char_p)
]
class InternalUseArea:
......@@ -105,8 +105,8 @@ class BoardInfoArea:
self.struct = c_BoardInfoArea()
self._as_parameter_ = byref(self.struct)
self.struct.format = 0x1
self.struct.area_len = 0 # English
self.struct.language = 0
self.struct.area_len = 0
self.struct.language = 0 # English
self.set_manufacture_date(date)
self.set_manufacturer(mfgr)
self.set_product_name(product)
......@@ -122,23 +122,23 @@ class BoardInfoArea:
def set_manufacturer(self, data):
self.struct.mfgr_data = c_char_p(data)
self.struct.mfgr_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
self.struct.mfgr_typelen = (len(bytearray(data)) & 0x3f) | (0x3 << 6)
def set_product_name(self, data):
self.struct.product_data = c_char_p(data)
self.struct.product_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
self.struct.product_typelen = (len(bytearray(data)) & 0x3f) | (0x3 << 6)
def set_serial_number(self, data):
self.struct.serial_data = c_char_p(data)
self.struct.serial_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
self.struct.serial_typelen = (len(bytearray(data)) & 0x3f) | (0x3 << 6)
def set_part_number(self, data):
self.struct.partnum_data = c_char_p(data)
self.struct.partnum_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
self.struct.partnum_typelen = (len(bytearray(data)) & 0x3f) | (0x3 << 6)
def set_fru_file_id(self, data):
self.struct.fru_fid_data = c_char_p(data)
self.struct.fru_fid_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
self.struct.fru_fid_typelen = (len(bytearray(data)) & 0x3f) | (0x3 << 6)
class DCLoadRecord:
......@@ -229,9 +229,8 @@ class c_FMCOEMData(Structure):
("p1_b_nsig", c_ubyte),
("p2_a_nsig", c_ubyte),
("p2_b_nsig", c_ubyte),
("p1_gbt_ntran", c_ubyte),
("p2_gbt_ntran", c_ubyte),
("max_clock", c_ubyte),
("p1_p2_gbt_ntran", c_ubyte),
("max_clock", c_ubyte)
]
class c_OEMRecord(Structure):
......@@ -239,7 +238,7 @@ class c_OEMRecord(Structure):
("mfg_id0", c_ubyte),
("mfg_id1", c_ubyte),
("mfg_id2", c_ubyte),
("data", c_FMCOEMData),
("data", c_FMCOEMData)
]
......@@ -269,19 +268,20 @@ class OEMRecord:
self.set_max_clock(maxclk)
def set_module_size(self, val):
self.struct.data.other &= ~(0x3)
self.struct.data.other |= val & 0x3
self.struct.data.other &= ~(0xc0)
self.struct.data.other |= (val << 6) & 0xc0
def set_p1_connector_size(self, val):
self.struct.data.other &= ~(0xc)
self.struct.data.other |= (val << 2) & 0xc
def set_p2_connector_size(self, val):
self.struct.data.other &= ~(0x30)
self.struct.data.other |= (val << 4) & 0x30
def set_p2_connector_size(self, val):
self.struct.data.other &= ~(0xc)
self.struct.data.other |= (val << 2) & 0xc
def set_clock_direction(self, val):
self.struct.data.other |= (val & 0x1) << 4
self.struct.data.other &= ~(0x2)
self.struct.data.other |= (val << 1) & 0x2
def set_nsignals(self, port, bank, num):
if (port == 1):
......@@ -297,9 +297,11 @@ class OEMRecord:
def set_num_gbt_transceivers(self, port, num):
if (port == 1):
self.struct.data.p1_gbt_ntran = num
self.struct.data.p1_p2_gbt_ntran &= ~(0xf0)
self.struct.data.p1_p2_gbt_ntran |= (num << 4) & 0xf0
elif (port == 2):
self.struct.data.p2_gbt_ntran = num
self.struct.data.p1_p2_gbt_ntran &= ~(0xf)
self.struct.data.p1_p2_gbt_ntran |= num & 0xf
def set_max_clock(self, clock):
self.struct.data.max_clock = clock
......@@ -311,13 +313,14 @@ def ipmi_open_file(name):
def ipmi_close_file():
lib.ipmi_file_close()
def ipmi_set(bia, dcload, dcout, oem, iua):
def ipmi_set(bia, dcload, dcout, oem, iua=None):
lib.ipmi_set_board_info_area(bia)
for r in dcload:
lib.ipmi_add_dc_load_record(r)
for r in dcout:
lib.ipmi_add_dc_output_record(r)
lib.ipmi_set_oem_record(oem)
if iua != None:
lib.ipmi_set_internal_use_area(iua)
def ipmi_write():
......@@ -331,3 +334,44 @@ def ipmi_get_internal_use_data(data):
d = c_void_p(lib.ipmi_get_internal_use_data(c_char_p(data), byref(l)))
q = cast(d, POINTER(l.value*c_ubyte))
return q.contents
def main():
bia = BoardInfoArea(12345678, "CERN", "ADC100M", "1234567890", "ADC100M", "abcde")
dcload0 = DCLoadRecord(0, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload1 = DCLoadRecord(1, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload2 = DCLoadRecord(2, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload3 = DCLoadRecord(3, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload4 = DCLoadRecord(4, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload5 = DCLoadRecord(5, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcload = [ dcload0, dcload1, dcload2, dcload3, dcload4, dcload5 ]
dcout0 = DCOutputRecord(0, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout1 = DCOutputRecord(1, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout2 = DCOutputRecord(2, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout3 = DCOutputRecord(3, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout4 = DCOutputRecord(4, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout5 = DCOutputRecord(5, 2.5, 2.4, 2.6, 0.0, 0, 4000)
dcout = [ dcout0, dcout1, dcout2, dcout3, dcout4, dcout5 ]
# oem = OEMRecord(single width, LPC, not fitted, mezz to carrier, 68, 0, 0, 0, 0, 0, 0)
oem = OEMRecord(0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0)
iudata = [0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 ]
iua = InternalUseArea(iudata)
# Open, set, write, close!
ipmi_open_file("test.out")
ipmi_set(bia, dcload, dcout, oem, iua)
ipmi_write()
ipmi_close_file()
test = open('test.out', 'r').read()
print ipmi_get_mfg_date(test)
d = ipmi_get_internal_use_data(test)
for v in d:
print hex(v)
if __name__ == "__main__":
main()
'''Original copyright notice:
By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. Its free.
'''
def rot(x,k):
return (((x)<<(k)) | ((x)>>(32-(k))))
def mix(a, b, c):
a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
a -= c; a &= 0xffffffff; a ^= rot(c,4); a &= 0xffffffff; c += b; c &= 0xffffffff
b -= a; b &= 0xffffffff; b ^= rot(a,6); b &= 0xffffffff; a += c; a &= 0xffffffff
c -= b; c &= 0xffffffff; c ^= rot(b,8); c &= 0xffffffff; b += a; b &= 0xffffffff
a -= c; a &= 0xffffffff; a ^= rot(c,16); a &= 0xffffffff; c += b; c &= 0xffffffff
b -= a; b &= 0xffffffff; b ^= rot(a,19); b &= 0xffffffff; a += c; a &= 0xffffffff
c -= b; c &= 0xffffffff; c ^= rot(b,4); c &= 0xffffffff; b += a; b &= 0xffffffff
return a, b, c
def final(a, b, c):
a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
c ^= b; c &= 0xffffffff; c -= rot(b,14); c &= 0xffffffff
a ^= c; a &= 0xffffffff; a -= rot(c,11); a &= 0xffffffff
b ^= a; b &= 0xffffffff; b -= rot(a,25); b &= 0xffffffff
c ^= b; c &= 0xffffffff; c -= rot(b,16); c &= 0xffffffff
a ^= c; a &= 0xffffffff; a -= rot(c,4); a &= 0xffffffff
b ^= a; b &= 0xffffffff; b -= rot(a,14); b &= 0xffffffff
c ^= b; c &= 0xffffffff; c -= rot(b,24); c &= 0xffffffff
return a, b, c
def hashlittle2(data, initval = 0, initval2 = 0):
length = lenpos = len(data)
a = b = c = (0xdeadbeef + (length) + initval)
c += initval2; c &= 0xffffffff
p = 0 # string offset
while lenpos > 12:
a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24)); a &= 0xffffffff
b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); b &= 0xffffffff
c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16) + (ord(data[p+11])<<24)); c &= 0xffffffff
a, b, c = mix(a, b, c)
p += 12
lenpos -= 12
if lenpos == 12: c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16) + (ord(data[p+11])<<24)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 11: c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 10: c += (ord(data[p+8]) + (ord(data[p+9])<<8)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 9: c += (ord(data[p+8])); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 8: b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 7: b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 6: b += ((ord(data[p+5])<<8) + ord(data[p+4])); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24))
if lenpos == 5: b += (ord(data[p+4])); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
if lenpos == 4: a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24))
if lenpos == 3: a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16))
if lenpos == 2: a += (ord(data[p+0]) + (ord(data[p+1])<<8))
if lenpos == 1: a += ord(data[p+0])
a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
if lenpos == 0: return c, b
a, b, c = final(a, b, c)
return c
......@@ -43,11 +43,11 @@ uint8_t checksum(uint8_t *data, int len)
int board_info_area_get_size(uint8_t *pad)
{
int size = 13 +
(bia->mfgr_typelen & 0x1f) +
(bia->product_typelen & 0x1f) +
(bia->serial_typelen & 0x1f) +
(bia->partnum_typelen & 0x1f) +
(bia->fru_fid_typelen & 0x1f);
(bia->mfgr_typelen & 0x3f) +
(bia->product_typelen & 0x3f) +
(bia->serial_typelen & 0x3f) +
(bia->partnum_typelen & 0x3f) +
(bia->fru_fid_typelen & 0x3f);
if (size & 0x7) {
if (pad) {
*pad = 8 - (size & 0x7);
......@@ -126,26 +126,29 @@ int ipmi_board_info_area_write(void)
/* Write upto the mfgr_data */
ret = fwrite(bia, 6, 1, f);
len = bia->mfgr_typelen & 0x1f;
len = bia->mfgr_typelen & 0x3f;
ret = fwrite(&bia->mfgr_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->mfgr_data, len, 1, f);
len = bia->product_typelen & 0x1f;
len = bia->product_typelen & 0x3f;
ret = fwrite(&bia->product_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->product_data, len, 1, f);
len = bia->serial_typelen & 0x1f;
len = bia->serial_typelen & 0x3f;
ret = fwrite(&bia->serial_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->serial_data, len, 1, f);
len = bia->partnum_typelen & 0x1f;
ret = fwrite(&bia->product_typelen, 1, sizeof(uint8_t), f);
len = bia->partnum_typelen & 0x3f;
ret = fwrite(&bia->partnum_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->partnum_data, len, 1, f);
len = bia->fru_fid_typelen & 0x1f;
len = bia->fru_fid_typelen & 0x3f;
ret = fwrite(&bia->fru_fid_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->fru_fid_data, len, 1, f);
bia->typelen_end = 0xc1;
ret = fwrite(&bia->typelen_end, 1, sizeof(uint8_t), f);
/* calculate checksum here */
checksum = 0;
checksum +=
......@@ -162,23 +165,25 @@ int ipmi_board_info_area_write(void)
bia->fru_fid_typelen +
bia->typelen_end;
for (i = 0; i < (bia->mfgr_typelen & 0x1f); i++)
for (i = 0; i < (bia->mfgr_typelen & 0x3f); i++)
checksum += bia->mfgr_data[i];
for (i = 0; i < (bia->product_typelen & 0x1f); i++)
for (i = 0; i < (bia->product_typelen & 0x3f); i++)
checksum += bia->product_data[i];
for (i = 0; i < (bia->serial_typelen & 0x1f); i++)
for (i = 0; i < (bia->serial_typelen & 0x3f); i++)
checksum += bia->serial_data[i];
for (i = 0; i < (bia->partnum_typelen & 0x1f); i++)
for (i = 0; i < (bia->partnum_typelen & 0x3f); i++)
checksum += bia->partnum_data[i];
for (i = 0; i < (bia->fru_fid_typelen & 0x1f); i++)
for (i = 0; i < (bia->fru_fid_typelen & 0x3f); i++)
checksum += bia->fru_fid_data[i];
checksum = -checksum;
checksum &= 0xff;
bia->checksum = checksum;
bia->typelen_end = 0xc1;
ret = fwrite(&bia->typelen_end, 1, sizeof(uint8_t), f);
uint8_t nul = 0;
board_info_area_get_size(&pad);
for (i = 0; i < pad; i++)
......@@ -203,14 +208,15 @@ int ipmi_dc_load_record_write(int end)
head.extra = 0x2;
if (end)
head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_load_record);
head.record_len = 13;
head.record_checksum = checksum((uint8_t *)t->rec,
sizeof(struct dc_load_record));
head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f);
ret = fwrite(t->rec, 1, sizeof(struct dc_load_record), f);
ret = fwrite(&t->rec->voltage_required, 1, 1, f);
ret = fwrite(&t->rec->nominal_voltage, 1, 12, f);
t = t->next;
}
......@@ -232,14 +238,15 @@ int ipmi_dc_output_record_write(int end)
head.extra = 0x2;
if (end)
head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_output_record);
head.record_len = 13;
head.record_checksum = checksum((uint8_t *)t->rec,
sizeof(struct dc_output_record));
head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f);
ret = fwrite(t->rec, 1, sizeof(struct dc_output_record), f);
ret = fwrite(&t->rec->output_info, 1, 1, f);
ret = fwrite(&t->rec->nominal_voltage, 1, 12, f);
t = t->next;
}
......@@ -254,10 +261,10 @@ int ipmi_oem_record_write(int end)
if (!oem || !f)
return -1;
/* VITA ID: 0x0012a2 */
oem->mfg_id0 = 0x00;
/* VITA ID: 0x0012a2 (LS Byte first) */
oem->mfg_id0 = 0xa2;
oem->mfg_id1 = 0x12;
oem->mfg_id2 = 0xa2;
oem->mfg_id2 = 0x00;
head.record_typeid = 0xfa; /* OEM record type */
head.extra = 0x2;
......@@ -282,12 +289,12 @@ int multirecord_area_get_size(int *diff)
int sum = 0;
while (l1) {
sum += sizeof(struct multirecord_header);
sum += sizeof(struct dc_load_record);
sum += 13;
l1 = l1->next;
}
while (l2) {
sum += sizeof(struct multirecord_header);
sum += sizeof(struct dc_output_record);
sum += 13;
l2 = l2->next;
}
sum += sizeof(struct multirecord_header) + sizeof(struct oem_record);
......@@ -308,22 +315,58 @@ int ipmi_write(void)
ch = malloc(sizeof(struct common_header));
memset(ch, 0, sizeof(struct common_header));
ch->board_area_off = sizeof(struct common_header)/8;
ch->format = 1; // Format version
/*
* IPMI areas arrangement in memory
*
* +------------------------------+
* | Common header |
* +------------------------------+
* | Board area |
* +------------------------------+
* | Multi-record area |
* | +------------------------+
* | | 3x DC load records |
* | +------------------------+
* | | 3x DC output records |
* | +------------------------+
* | | OEM record |
* +-----+------------------------+
* | Internal use area (optional) |
* +------------------------------+
*/
// Compute area offsets
ch->board_area_off = sizeof(struct common_header)/8; // always 1
ch->multirecord_off = (sizeof(struct common_header) + board_info_area_get_size(NULL))/8;
if (iua)
ch->internal_use_off = (sizeof(struct common_header) + board_info_area_get_size(NULL) + multirecord_area_get_size(NULL))/8;
bia->area_len = board_info_area_get_size(NULL);
else
ch->internal_use_off = 0;
// Write common heade
ipmi_common_header_write();
// Write board info area, padding (to 8 byte multiple) is done inside the write function
bia->area_len = board_info_area_get_size(NULL)/8;
ipmi_board_info_area_write();
// Write multi-record area
ipmi_dc_load_record_write(0);
ipmi_dc_output_record_write(0);
ipmi_oem_record_write(1);
// Padding after multi-record area
multirecord_area_get_size(&padlen);
if (padlen) {
int i;
for (i = 0; i < padlen; i++)
fwrite(&pad, 1, 1, f);
}
// Write Internal Use area, if exists
if (iua)
ipmi_internal_use_area_write();
return 0;
......
......@@ -94,8 +94,7 @@ struct fmc_oem_data {
uint8_t p1_b_nsig;
uint8_t p2_a_nsig;
uint8_t p2_b_nsig;
uint8_t p1_gbt_ntran;
uint8_t p2_gbt_ntran;
uint8_t p1_p2_gbt_ntran;
uint8_t max_clock;
};
......
# This is an example config file, that can be used to build a filesystem
# from this very directory. Please note that gensdbfs doesn't look for
# config files in subdirectories but only in the tol-level one.
.
vendor = 0x000000000000CE42
device = 0xf19ede1a
position = 0x100
IPMI-FRU
position = 0
calibration
maxsize = 0x6e
name
maxsize = 0x20
\ No newline at end of file
fdelay
\ No newline at end of file
......@@ -15,13 +15,14 @@ TEST_SENSOR, TEST_ACAM_IF, TEST_DELAY_LINE
"""
def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
# initialize card with long tests
card = init_card(new_stderr, default_directory, 2)
print("Dir %s" %default_directory)
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
......
......@@ -105,7 +105,7 @@ def main (card=None, default_directory='.',suite=None):
if(error[0] != 0):
print("One or both LEDs not switching ON. Check for soldering or connection problem, grounded control line")
if(error[1] != 0):
print("One or both LEDs not switching OFF. Check for short-cut.")
print("One or both LEDs not switching OFF. Check for short circuits.")
raise PtsError('An error occurred during LEDs test, check log for details.')
else:
print('LEDs are working ok.')
......
......@@ -6,35 +6,230 @@
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import sys
import time
import string
import datetime
from ptsexcept import *
from utilFunctions import *
from PAGE.Agilent33250A import *
from PAGE.PulseWaveform import *
from PendulumCNT91 import *
"""
test02: Perform DMTD calibration procedure for determining zero offsets
test02: Test and calibration of output channels using the CNT-91
"""
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
DELAY_SETPOINT = 1000000
CABLING_OFFSETS = [ 12297 - 500, 12248 - 500, 12220 - 500, 12212 - 500]
def hex_date():
now = datetime.datetime.now()
s="%x%x%x%x%x%x%x%x" % (
(now.year / 1000) % 10,
(now.year / 100) % 10,
(now.year / 10) % 10,
(now.year / 1) % 10,
(now.month / 10) % 10,
(now.month / 1) % 10,
(now.day / 10) % 10,
(now.day / 1) % 10)
return int(s, 16)
def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py
if (card == None):
# initialize card without long tests
card = init_card(new_stderr, default_directory, 0)
############################################################################
# run DMTD calibration procedure
card.fdelay_dmtd_calibration();
# objects declaration
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
restore_stderr(new_stderr, default_directory)
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
# restore stderr and display debug information from file
gen = Agilent33250A(device=USB_DEVICE, bauds=RS232_BAUD)
pulse = PulseWaveform()
# connect to AWG and test if available
idn = gen.connect()
if (len(idn) == 0):
restore_stderr(new_stderr, default_directory)
raise PtsError('AWG is not switched on or badly connected, aborting.')
else:
print idn
sys.path.append(os.path.join(default_directory, 'usb_box'))
sys.path.append(os.path.join(default_directory, 'cp210x'))
import calibr_box
import find_usb_tty
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
box_tty = find_usb_tty.CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
# print("Calibration Box device: %s" % box_tty[0])
box = calibr_box.CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
# initialize variables
error = [0, 0, 0, 0, 0, 0, 0, 0]
result = [0.0, 0.0, 0.0, 0.0]
red = redirect(0)
# set pulse parameters
pulse.frequency = 500
pulse.amplitude = 3.3
pulse.dc = 1.65
# configure trigger (enable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.conf_trigger(1, 1)
# set AWG and turn it ON
gen.play(pulse)
gen.command("PULS:WIDT 0.0000005")
gen.command("PULS:TRAN 0.000000005")
gen.output = True
# init CNT-91
pendulum_init(meas)
# standard in/out temporary redirection for user question/answer
# redirect.InOut(red)
############################################################################
# loop channels and check results
index = 1
while (index <= 4):
print("Calibrating output %d..." % index)
box.select_output(index)
box.select_trigger_loopback(0)
# enable output channel (time in ps) (channel, enable, delay(500ns-120s), width(200ns-1s))
card.conf_output(index, 1, DELAY_SETPOINT, 500000)
time.sleep(2)
if (card.get_return_value() == -1):
raise PtsCritical ('An error occurred during the DMTD calibration, check log for details')
# restart CNT-91
pendulum_reset(meas)
# read result and check
time.sleep(2)
meas.write("CALC:AVER:COUN:CURR?")
n = meas.read()
if (convertString(n) != 500):
error[index-1] += 1
redirect.InOut(red)
print "Channel %d is not switching on" %index
redirect.InOut(red)
# read data and store
meas.write("CALC:DATA?")
res = meas.read()
if (convertString(res) != 0):
result[index-1] = convertString(res)*1000000
# disable output channel
card.conf_output(index, 0, DELAY_SETPOINT, 500000)
# restart CNT-91
pendulum_reset(meas)
# read result and check
time.sleep(2)
meas.write("CALC:AVER:COUN:CURR?")
n = meas.read()
if (convertString(n) != 0):
error[index-1] += 1
redirect.InOut(red)
print "Channel %d is not switching off" %index
redirect.InOut(red)
index = index + 1
############################################################################
# disconnect AWG and CNT91
gen.output = False
gen.close()
meas.close()
# disable trigger (disable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.conf_trigger(0, 0)
# standard in/out redirection
# display measurements
print ("\nDelay time was set to %d picoseconds" % DELAY_SETPOINT)
for index in range (1,5):
print ("Measurement for channel %d is: %d picoseconds" % (index, result[index-1] * 1e6))
if(error[0] != 0):
print("Output enable line for channel 1 is not working OK, check for soldering or connection problem.")
if(error[1] != 0):
print("Output enable line for channel 2 is not working OK, check for soldering or connection problem.")
if(error[2] != 0):
print("Output enable line for channel 3 is not working OK, check for soldering or connection problem.")
if(error[3] != 0):
print("Output enable line for channel 4 is not working OK, check for soldering or connection problem.")
calib = FDCalibBlock()
# calib.load(os.path.join(default_directory,"sdbfs/calibration"))
calib.tdc_zero_offset = 127500
calib.date = hex_date()
for i in range (0, 4):
calib.out_zero_offset[i] = DELAY_SETPOINT + CABLING_OFFSETS[i-1] - int( result[i] * 1e6 ) - calib.tdc_zero_offset;
print("out_zero_offset[%d] = %d" % (i+1, calib.out_zero_offset[i]))
calib.save(os.path.join(default_directory,"sdbfs/calibration"))
# redirect.InOut(red)
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
return card
def convertString(string):
# Convert string to int or float
try:
#try int
ret = int(string)
except ValueError:
try:
# if not int try float
ret = float(string)
except ValueError:
# if not int or float, it's empty
ret = 0
return ret
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright INCAA Computers, 2012
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com>
# Copyright CERN 2013
# Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
from ptsexcept import *
from utilFunctions import *
from PendulumCNT91 import *
import sys
import time
import string
"""
test03: Test of writing calibration data and reading back for validation
test03: Frequency calibration of the card's internal VCTCXO.
"""
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def meas_output_freq(meas, card, dac_value):
# print("Setting DAC to %d" % dac_value)
card.set_dac(int(dac_value))
# print("DAC Set")
time.sleep(2)
# print("Measuring frequency...")
meas.write("INP2:IMP 50")
meas.write("INP2:COUP DC")
meas.write("INP2:LEV:AUTO OFF")
meas.write("INP2:LEV 1.5")
meas.write("CALC:AVER:STAT OFF")
meas.write("CALC:AVER:STAT ON")
meas.write("CALC:AVER:COUN 500")
meas.write("MEAS:FREQ? (@2)")
time.sleep(3)
n = meas.read()
return float(n)
def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py
if (card == None):
red = redirect(0)
# initialize card without long tests
card = init_card(new_stderr, default_directory, 0)
############################################################################
# run testing EEPROM writing and reading (perform DMTD calibration if not run from PTS)
if(card.dmtd == 0):
# run DMTD calibration procedure
card.fdelay_dmtd_calibration();
# objects declaration
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
restore_stderr(new_stderr, default_directory)
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
sys.path.append(os.path.join(default_directory, 'usb_box'))
sys.path.append(os.path.join(default_directory, 'cp210x'))
import calibr_box
import find_usb_tty
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
box_tty = find_usb_tty.CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
# print("Calibration Box device: %s" % box_tty[0])
box = calibr_box.CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(1)
# display debug information
show_stderr(default_directory)
# run eeprom writing procedure
card.write_calibration_eeprom()
# configure trigger (enable, termination (0 = 2 kOhm, 1 = 50 Ohm))
t0 = card.get_time()
card.conf_pulsegen(1, 1, t0.utc+2, 0, 500000, 1000000, -1)
time.sleep(3)
d_hi = 65535
d_lo = 0
f_goal=1e6
n_iter = 7
print("Calibrating VCTCXO frequency...")
for i in range(1, n_iter+1):
f_hi = meas_output_freq(meas, card, d_hi)
f_lo = meas_output_freq(meas, card, d_lo)
print("Iteration %d/%d: DAC hi %d ADC lo %d Freq hi %.8f MHz Freq lo %.8f MHz " % (i, n_iter, d_hi, d_lo, f_hi, f_lo))
if(f_hi == f_lo):
break
d_center = d_lo + (d_hi - d_lo) * ((f_goal - f_lo) / (f_hi - f_lo))
f_center = (f_hi + f_lo) / 2
# print("d_center %d" % d_center)
d_span = abs(d_hi - d_lo) / 8;
d_lo = int(d_center - d_span)
d_hi = int(d_center + d_span)
# print("DAC Value %d for freq %.8f MHz" % ( d_center, f_center))
print("DAC Value %d for frequency %.8f MHz [expected %.8f MHz]" % ( d_center, f_center, f_goal))
meas.close()
# disable trigger (disable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.conf_trigger(0, 0)
# standard in/out redirection
# redirect.InOut(red)
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
if (card.get_return_value() == -1):
raise PtsError ('An error occurred during writing the calibration EEPROM, check log for details')
############################################################################
calib = FDCalibBlock()
calib.load(os.path.join(default_directory,"sdbfs/calibration"))
calib.vcxo_default_tune = int(d_center)
calib.save(os.path.join(default_directory,"sdbfs/calibration"))
return card
......
#! /usr/bin/env python
# coding: utf8
# Copyright INCAA Computers, 2012
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com>
# Copyright CERN 2013
# Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import sys
from ptsexcept import *
from utilFunctions import *
from PAGE.Agilent33250A import *
from PAGE.PulseWaveform import *
from PendulumCNT91 import *
import sys
import numpy
import time
import string
"""
test04: Test of output enable lines and front panel signals with CNT-91 via USB
test04: Peforms TDC intrinsic jitter test.
"""
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def gather_timestamps(card, count):
n=0
rv=[]
while (n < count):
buf = card.read_ts()
n+=len(buf)
rv.extend(buf)
# print(len(rv))
# for t in rv:
# print(t)
# print(t.raw_frac, t.raw_subcycle_offset, t.raw_start_offset)
return rv
WORST_THRESHOLD = 8
STD_THRESHOLD = 1.7
def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
# initialize card without long tests
card = init_card(new_stderr, default_directory, 0)
red = redirect(0)
############################################################################
# objects declaration
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
restore_stderr(new_stderr, default_directory)
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
gen = Agilent33250A(device=USB_DEVICE, bauds=RS232_BAUD)
pulse = PulseWaveform()
sys.path.append(os.path.join(default_directory, 'usb_box'))
sys.path.append(os.path.join(default_directory, 'cp210x'))
# connect to AWG and test if available
idn = gen.connect()
if (len(idn) == 0):
restore_stderr(new_stderr, default_directory)
raise PtsError('AWG is not switched on or badly connected, aborting.')
else:
print idn
import calibr_box
import find_usb_tty
# initialize variables
error = [0, 0, 0, 0, 0, 0, 0, 0]
result = [0.0, 0.0, 0.0, 0.0]
red = redirect(0)
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
box_tty = find_usb_tty.CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
# print("Calibration Box device: %s" % box_tty[0])
box = calibr_box.CCalibr_box(box_tty[0])
# set pulse parameters
pulse.frequency = 500
pulse.amplitude = 2.5
pulse.dc = 1.4
box.select_trigger_loopback(1)
box.select_output(1)
# initialize card without long tests
card = init_card(new_stderr, default_directory, 1) # 1=RAW_READOUT mode
card.conf_trigger(0, 0)
card.conf_readout(0)
card.conf_readout(1)
# configure trigger (enable, termination (0 = 2 kOhm, 1 = 50 Ohm))
t0 = card.get_time()
card.conf_pulsegen(4, 1, t0.utc+2, 0, 50000000, 102400000, -1)
time.sleep(3)
card.conf_trigger(1, 1)
# set AWG and turn it ON
gen.play(pulse)
gen.command("PULS:WIDT 0.0000005")
gen.command("PULS:TRAN 0.000000005")
gen.output = True
# init CNT-91
pendulum_init(meas)
# standard in/out temporary redirection for user question/answer
redirect.InOut(red)
############################################################################
# loop channels and check results
index = 1
while (index <= 4):
# let user connect channel [index]
ask = "";
while (ask != "Y") :
print "-------------------------------------------------------------"
print "Connect channel %d to CNT-91 [y]" %index
ask = raw_input()
ask = ask.upper()
print " "
# enable output channel (time in ps) (channel, enable, delay(500ns-120s), width(200ns-1s))
# 10 microsec(-7ns extra cables - 350ps compensation test setup, 500 nanosec = 500000
card.conf_output(index, 1, (10000000-7000-350), 500000)
time.sleep(2)
# restart CNT-91
pendulum_reset(meas)
# read result and check
time.sleep(2)
meas.write("CALC:AVER:COUN:CURR?")
n = meas.read()
if (convertString(n) != 500):
error[index-1] += 1
redirect.InOut(red)
print "Channel %d is not switching on" %index
redirect.InOut(red)
# read data and store
meas.write("CALC:DATA?")
res = meas.read()
if (convertString(res) != 0):
result[index-1] = convertString(res)*1000000
# disable output channel
card.conf_output(index, 0, (10000000-7000-350), 500000)
# restart CNT-91
pendulum_reset(meas)
# read result and check
time.sleep(2)
meas.write("CALC:AVER:COUN:CURR?")
n = meas.read()
if (convertString(n) != 0):
error[index-1] += 1
redirect.InOut(red)
print "Channel %d is not switching off" %index
redirect.InOut(red)
index = index + 1
############################################################################
# disconnect AWG and CNT91
gen.output = False
gen.close()
meas.close()
ts = gather_timestamps(card, 10)
tdc_start_offset = ts[0].raw_subcycle_offset;
# print("StartOffs : %d" % tdc_start_offset)
# disable trigger (disable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.conf_trigger(0, 0)
t0 = card.get_time()
card.conf_readout(0)
card.conf_trigger(0, 1)
card.conf_pulsegen(4, 1, t0.utc+2, (tdc_start_offset + 45) , 50000000, 102400000, -1)
time.sleep(3)
card.conf_trigger(1, 1)
card.conf_readout(1)
ts = gather_timestamps(card, 200000)
fracs = map(lambda x : x.raw_frac, ts )
# print(fracs)
j_std = numpy.std(fracs)
j_min = min(fracs)
j_max = max(fracs)
j_mean = numpy.mean(fracs)
j_worst = max(abs(j_mean - j_min), abs(j_mean - j_max))
print("TDC Jitter statstics [1 unit = 40.5 ps]: ")
print("Worst case = %.2f [ max = %.2f ]" %( j_worst, WORST_THRESHOLD))
print("Std = %.2f [ max = %.2f ]" %(j_std, STD_THRESHOLD))
if(j_worst > WORST_THRESHOLD or j_std > STD_THRESHOLD):
print ("Test failure: jitter exceeds threshold. ")
raise PtsError("Test failure: jitter exceeds threshold. ")
else:
print ("Test OK: jitter within bounds. ")
# print(fracs)
# standard in/out redirection
redirect.InOut(red)
# redirect.InOut(red)
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
# display measurements
print "\nDelay time was set to 10 µsec"
index = 1
while (index <= 4):
print "Measurement for channel %d is: %.6f µsec" % (index, result[index-1])
if (abs(result[index-1] - 10) > 0.000500):
error[index+4 -1] += 1
index = index + 1
# check if an error occurred
if (error != [0]*8):
if(error[0] != 0):
print("Output enable line for channel 1 is not working OK, check for soldering or connection problem.")
if(error[1] != 0):
print("Output enable line for channel 2 is not working OK, check for soldering or connection problem.")
if(error[2] != 0):
print("Output enable line for channel 3 is not working OK, check for soldering or connection problem.")
if(error[3] != 0):
print("Output enable line for channel 4 is not working OK, check for soldering or connection problem.")
if(error[4] != 0):
print("Measured delay for channel 1 doesn't met the requirement of 500 ps accuracy")
if(error[5] != 0):
print("Measured delay for channel 2 doesn't met the requirement of 500 ps accuracy")
if(error[6] != 0):
print("Measured delay for channel 3 doesn't met the requirement of 500 ps accuracy")
if(error[7] != 0):
print("Measured delay for channel 4 doesn't met the requirement of 500 ps accuracy")
raise PtsError('An error occurred during the "output enable lines" and "front panel signals" test, check log for details.')
else:
print('Output enable lines and front panel signals are working ok.')
############################################################################
return card
def convertString(string):
# Convert string to int or float
try:
#try int
ret = int(string)
except ValueError:
try:
# if not int try float
ret = float(string)
except ValueError:
# if not int or float, it's empty
ret = 0
return ret
if __name__ == '__main__' :
main()
......@@ -13,7 +13,7 @@ from fmc_eeprom import *
import sys, time
"""
test05: Writes IPMI card information (serial number, production date, etc.) into EEPROM
test05: Prepares IPMI card information (serial number, production date, etc.)
"""
def main (card=None, serial=None, default_directory='.', suite=None):
......@@ -21,10 +21,6 @@ def main (card=None, serial=None, default_directory='.', suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py
if (card == None):
card = init_card(new_stderr, default_directory, 0)
# standard in/out temporary redirection for user question/answer
red = redirect(0)
redirect.InOut(red)
......@@ -42,7 +38,7 @@ def main (card=None, serial=None, default_directory='.', suite=None):
else:
serial_no = serial
bia = BoardInfoArea(int(time.time()), "INCAA Computers BV", "FmcDelay1ns4cha-v4", serial_no, "FmcDelay1ns4cha-v4", "")
bia = BoardInfoArea(int(time.time()), "INCAA Computers BV", "FmcDelay1ns4cha", serial_no, "EDA-02267-V5-2", "")
dcload0 = DCLoadRecord(0, 2.5, 2.4, 2.6, 0.02, 0, 200)
dcload1 = DCLoadRecord(1, 3.3, 3.2, 3.4, 0.02, 0, 2000)
......@@ -55,12 +51,11 @@ def main (card=None, serial=None, default_directory='.', suite=None):
iua = InternalUseArea([])
# Open, set, write, close!
ipmi_open_file("ipmi_eeprom.bin")
ipmi_open_file(os.path.join(default_directory, "sdbfs/IPMI-FRU"))
ipmi_set(bia, dcload, dcout, oem, iua)
ipmi_write()
ipmi_close_file()
card.write_eeprom_from_file("ipmi_eeprom.bin", 0);
############################################################################
# standard in/out redirection
......@@ -69,11 +64,6 @@ def main (card=None, serial=None, default_directory='.', suite=None):
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
if (card.get_return_value() == -1):
raise PtsError ('An error occurred during writing the EEPROM with IPMI information, check log for details')
############################################################################
return card
if __name__ == '__main__' :
......
#! /usr/bin/env python
# coding: utf8
# Copyright INCAA Computers, 2012
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
from ptsexcept import *
from utilFunctions import *
import sys
"""
test06: Writes and validates the card's EEPROM.
"""
def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory)
red = redirect(0)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py
if (card == None):
card = init_card(new_stderr, default_directory, 0)
print("Programming SDB filesystem into mezzanine's EEPROM...")
os.system("./%s/gensdbfs %s/sdbfs %s/fd-eeprom.bin" % (default_directory, default_directory, default_directory))
# run eeprom writing procedure
card.write_eeprom_from_file("%s/fd-eeprom.bin" % default_directory, 0)
if (card.get_return_value() == -1):
raise PtsError ('An error occurred during writing the calibration EEPROM, check log for details')
print("Programming OK.")
# restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory)
############################################################################
return card
if __name__ == '__main__' :
main()
#!/usr/bin/python
from fdelay_lib import FineDelay
import sys
import os
card = FineDelay(0, -1)
card.conf_trigger(1, 1)
card.conf_output(1, 1, 1000000, 300000)
t=card.get_time()
print(t.utc, t.coarse)
card.conf_pulsegen(2, 1, 2, 0, 300000, 256000*16, -1)
card.conf_pulsegen(3, 1, 2, 0, 300000, 256000*16, -1)
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import sys
import time
import os
import cp210x_gpio
"""
calibr_box: Access to calibration box via USB-UART bridge CP2103
"""
class CalibrBoxOperationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return ("Calibration box: %s" %(self.msg))
class CCalibr_box:
def __init__(self, device):
self.cp210x = cp210x_gpio.CCP210x(device)
# Select AWG as default output
# self.cp210x.gpio_get();
self.cp210x.gpio_set(0x0);
self.state = 0;
def select_output(self, out):
# print("Cur %x" % self.state)
self.state = self.state & 0x3;
if(out == 1):
self.state = self.state | ( 0xc );
elif(out == 2):
self.state = self.state | ( 0x8 );
elif(out == 3):
self.state = self.state | ( 0x4 );
elif(out == 4):
self.state = self.state | ( 0x0 );
else:
raise CalibrBoxOperationError("Invalid output selection!")
self.cp210x.gpio_set(self.state)
def select_trigger_loopback(self, tloop):
if(tloop):
self.state = self.state | 2;
else:
self.state = self.state & ~2;
self.cp210x.gpio_set(self.state)
#! /usr/bin/env python
# coding: utf8
import fcntl, struct, termios, os
import time
import array
import struct
from ctypes import *
class CCP210x:
def __init__(self, device):
self.fd = open(device, 'wb')
def gpio_set(self, mask):
# print("gpio_set %x" % mask)
f = array.array('L', [0])
f[0] = (mask << 8) | 0xff;
fcntl.ioctl(self.fd, 0x8001, f, 0)
def gpio_get(self):
f = array.array('L', [0])
ret = fcntl.ioctl(self.fd.fileno(), 0x8000, f, 1)
# print("gpio_get %x" % f[0])
return f[0]
# Create an object (the 0 is used to generate the name, eg. /dev/ttyUSB0
#gpio = cp210x_gpio(0)
# Infinite test loop
#while 1:
# # Pass the mask of the 4 bits as a hex number
# gpio.gpio_set(0xf)
# # Returns the states of the 4 bits as hex number
# print gpio.gpio_get()
# time.sleep(1)
# gpio.gpio_set(0x0)
# print gpio.gpio_get()
# time.sleep(1)
#! /usr/bin/env python
# coding: utf8
import glob
import os
import re
class CttyUSB:
def __init__(self):
pass
def find_usb_tty(self, vendor_id = None, product_id = None) :
tty_devs = []
for dn in glob.glob('/sys/bus/usb/devices/*') :
try :
vid = int(open(os.path.join(dn, "idVendor" )).read().strip(), 16)
pid = int(open(os.path.join(dn, "idProduct")).read().strip(), 16)
#print "dn:%s vid:%s pid:%s" % (dn,vid,pid)
if ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) :
dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*"))
for sdn in dns :
for fn in glob.glob(os.path.join(sdn, "*")) :
if re.search(r"\/ttyUSB[0-9]+$", fn) :
tty_devs.append("/dev/" + os.path.basename(fn))
pass
pass
pass
pass
except ( ValueError, TypeError, AttributeError, OSError, IOError ) :
pass
pass
return tty_devs
#print find_usb_tty()
#print find_usb_tty(0x10c4,0xea60)
#print find_usb_tty(0x0403,0x6001)
......@@ -9,6 +9,10 @@ from PendulumCNT91 import *
import sys
import os
import struct
import jhash
"""
functions for getting debug information from c library
......@@ -101,8 +105,8 @@ def pendulum_init(meas):
meas.write("MEAS:TINT?")
# DC coupling
#meas.write("INP:COUP DC")
#meas.write("INP2:COUP DC")
meas.write("INP:COUP DC")
meas.write("INP2:COUP DC")
# Set impedance
meas.write("INP:IMP 1E6")
......@@ -113,7 +117,7 @@ def pendulum_init(meas):
meas.write("INP2:LEV:AUTO OFF")
# Set trigger level
meas.write("INP:LEV 1.4")
meas.write("INP:LEV 1.5")
meas.write("INP2:LEV 1.5")
# Enable statistics
......@@ -137,3 +141,66 @@ def pendulum_reset(meas):
# Make 500 measurements
meas.write("CALC:AVER:COUN 500")
class FDCalibBlock:
def __init__(self):
self.frr_poly = [-165202, -29825595, 3801939743082]
self.tdc_zero_offset = 80000
self.out_zero_offset = [0, 0, 0, 0]
self.vcxo_default_tune = 32000
self.magic = 0xf19ede1a
self.version = 3
self.date = 0
self.size=64
def load(self, filename="sdbfs/calibration"):
f= open(filename,"rb")
self.packed= f.read(64)
f.close()
self.unpack()
# print("magic: %x" % self.magic)
# print("hash: %x" % self.hash)
# print("size: %d" % self.size)
# print("version: %d" % self.version)
# print("date: %x" % self.date)
# print("frr_poly: %d %d %d" %( self.frr_poly[0], self.frr_poly[1], self.frr_poly[2]))
# print("out_zero_offset: %d %d %d %d" %( self.out_zero_offset[0], self.out_zero_offset[1], self.out_zero_offset[2], self.out_zero_offset[3]))
# print("tdc_zero_offset: %d " %( self.tdc_zero_offset ))
# print("vcxo_default_tune: %d " %( self.vcxo_default_tune ))
sh = self.hash
self.hash = 0
self.pack()
sh_ver = jhash.hashlittle2(self.packed, 0, 0)
def unpack(self):
self.magic, self.hash, self.size, self.version, self.date, self.frr_poly[0], self.frr_poly[1], self.frr_poly[2], self.out_zero_offset[0], self.out_zero_offset[1], self.out_zero_offset[2], self.out_zero_offset[3], self.tdc_zero_offset, self.vcxo_default_tune = struct.unpack("!LLHHL3q4llL", self.packed)
def pack(self):
self.packed = struct.pack("!LLHHL3q4llL",
self.magic,
self.hash,
self.size,
self.version,
self.date,
self.frr_poly[0],
self.frr_poly[1],
self.frr_poly[2],
self.out_zero_offset[0],
self.out_zero_offset[1],
self.out_zero_offset[2],
self.out_zero_offset[3],
self.tdc_zero_offset,
self.vcxo_default_tune )
def save(self, filename="sdbfs/calibration"):
self.hash = 0
self.pack()
# print(self.packed, len(self.packed))
self.hash = jhash.hashlittle2(self.packed, 0, 0)
self.pack()
f= open(filename,"wb")
f.write(self.packed)
f.close()
#!/bin/sh
#!/bin/bash
module="usbtmc"
......
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