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 @@ ...@@ -5,8 +5,19 @@
# Licence: GPL v2 or later. # Licence: GPL v2 or later.
# Website: http://www.ohwr.org # 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 LOGDIR=./log_fmcdelay1ns4cha
mkdir -p $LOGDIR mkdir -p $LOGDIR
sudo rm -fr $LOGDIR/pts* sudo rm -fr $LOGDIR/pts*
...@@ -41,7 +52,7 @@ do ...@@ -41,7 +52,7 @@ do
echo "Test series run $nb_test out of $nb_test_limit" echo "Test series run $nb_test out of $nb_test_limit"
echo " " 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" ] if [ "$nb_test" != "$nb_test_limit" ]
then then
......
No preview for this file type
...@@ -20,7 +20,15 @@ ...@@ -20,7 +20,15 @@
#define AR2_Disable(chan) (1<<(3+chan)) #define AR2_Disable(chan) (1<<(3+chan))
#define AR2_Adj(chan, value) (((value)&0xf)<<(12+4*(chan-7))) #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 #define AR3_Zero (0) // nothing interesting for the Fine Delay
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* File : fd_channel_regs.h * File : fd_channel_regs.h
* Author : auto-generated by wbgen2 from fd_channel_wishbone_slave.wb * 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 * Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
/* definitions for field: Disable Fine Part update in reg: Delay Control Register */ /* definitions for field: Disable Fine Part update in reg: Delay Control Register */
#define FD_DCR_NO_FINE WBGEN2_GEN_MASK(7, 1) #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) #define FD_DCR_FORCE_HI WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Fine Range Register */ /* definitions for register: Fine Range Register */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* File : fd_main_regs.h * File : fd_main_regs.h
* Author : auto-generated by wbgen2 from fd_main_wishbone_slave.wb * 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 * Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* definitions for field: PLL Locked in reg: Global Control Register */ /* definitions for field: PLL Locked in reg: Global Control Register */
#define FD_GCR_DDR_LOCKED WBGEN2_GEN_MASK(2, 1) #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) #define FD_GCR_FMC_PRESENT WBGEN2_GEN_MASK(3, 1)
/* definitions for register: Timing Control Register */ /* definitions for register: Timing Control Register */
...@@ -99,46 +99,46 @@ ...@@ -99,46 +99,46 @@
/* definitions for register: Time Register - sub-second 125 MHz clock cycles */ /* 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) #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) #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) #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) #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) #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) #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) #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) #define FD_TDCSR_ALUTRIG WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Calibration register */ /* 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) #define FD_CALR_CAL_PULSE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PPS Calibration output enable in reg: Calibration register */ /* definitions for field: PPS Calibration output enable in reg: Calibration register */
#define FD_CALR_CAL_PPS WBGEN2_GEN_MASK(1, 1) #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) #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_MASK WBGEN2_GEN_MASK(3, 4)
#define FD_CALR_PSEL_SHIFT 3 #define FD_CALR_PSEL_SHIFT 3
#define FD_CALR_PSEL_W(value) WBGEN2_GEN_WRITE(value, 3, 4) #define FD_CALR_PSEL_W(value) WBGEN2_GEN_WRITE(value, 3, 4)
...@@ -171,16 +171,16 @@ ...@@ -171,16 +171,16 @@
/* definitions for register: Acam Timestamp Merging Control Register */ /* definitions for register: Acam Timestamp Merging Control Register */
/* definitions for field: Wraparound Coarse Threshold in reg: 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_SHIFT 0
#define FD_ATMCR_C_THR_W(value) WBGEN2_GEN_WRITE(value, 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, 4) #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 */ /* 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_MASK WBGEN2_GEN_MASK(8, 23)
#define FD_ATMCR_F_THR_SHIFT 4 #define FD_ATMCR_F_THR_SHIFT 8
#define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 4, 23) #define FD_ATMCR_F_THR_W(value) WBGEN2_GEN_WRITE(value, 8, 23)
#define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 4, 23) #define FD_ATMCR_F_THR_R(reg) WBGEN2_GEN_READ(reg, 8, 23)
/* definitions for register: Acam Start Offset Register */ /* definitions for register: Acam Start Offset Register */
...@@ -399,9 +399,9 @@ ...@@ -399,9 +399,9 @@
#define FD_REG_TM_SECL 0x00000014 #define FD_REG_TM_SECL 0x00000014
/* [0x18]: REG Time Register - sub-second 125 MHz clock cycles */ /* [0x18]: REG Time Register - sub-second 125 MHz clock cycles */
#define FD_REG_TM_CYCLES 0x00000018 #define FD_REG_TM_CYCLES 0x00000018
/* [0x1c]: REG TDC Data Register */ /* [0x1c]: REG Host-driven TDC Data Register */
#define FD_REG_TDR 0x0000001c #define FD_REG_TDR 0x0000001c
/* [0x20]: REG TDC control/status reg */ /* [0x20]: REG Host-driven TDC Control/Status */
#define FD_REG_TDCSR 0x00000020 #define FD_REG_TDCSR 0x00000020
/* [0x24]: REG Calibration register */ /* [0x24]: REG Calibration register */
#define FD_REG_CALR 0x00000024 #define FD_REG_CALR 0x00000024
......
...@@ -40,22 +40,23 @@ typedef struct fdelay_device ...@@ -40,22 +40,23 @@ typedef struct fdelay_device
} fdelay_device_t; } fdelay_device_t;
typedef struct { typedef struct {
int64_t utc, utc_sh; int64_t utc;
int32_t coarse, coarse_sh; int32_t coarse;
int32_t start_offset; int32_t start_offset;
int32_t subcycle_offset; int32_t subcycle_offset;
int32_t frac; int32_t frac;
uint32_t tsbcr;
} fdelay_raw_time_t; } fdelay_raw_time_t;
typedef struct typedef struct
{ {
fdelay_raw_time_t raw;
int64_t utc; /* TAI seconds */ /* FIXME: replace all UTCs with TAIs or seconds for clarity */ int64_t utc; /* TAI seconds */ /* FIXME: replace all UTCs with TAIs or seconds for clarity */
int32_t coarse; /* 125 MHz counter cycles */ int32_t coarse; /* 125 MHz counter cycles */
int32_t frac; /* Fractional part (<8ns) */ int32_t frac; /* Fractional part (<8ns) */
uint16_t seq_id; /* Sequence ID to detect missed timestamps */ uint16_t seq_id; /* Sequence ID to detect missed timestamps */
int channel;
fdelay_raw_time_t raw;
} fdelay_time_t; } fdelay_time_t;
/* /*
...@@ -132,4 +133,7 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_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); 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 #endif
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
/* ACAM TDC operation modes */ /* ACAM TDC operation modes */
#define ACAM_RMODE 0 #define ACAM_RMODE 0
#define ACAM_IMODE 1 #define ACAM_IMODE 1
#define ACAM_GMODE 2
/* MCP23S17 register addresses (only ones which are used by the lib) */ /* MCP23S17 register addresses (only ones which are used by the lib) */
#define MCP_IODIR 0x0 #define MCP_IODIR 0x0
...@@ -60,27 +61,27 @@ ...@@ -60,27 +61,27 @@
/* Calibration eeprom I2C address */ /* Calibration eeprom I2C address */
#define EEPROM_ADDR 0x50 #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) #define EEPROM_CALIB_OFFSET (6*1024)
struct fd_calib { struct fd_calib {
int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */ int64_t frr_poly[3]; /* SY89295 delay/temp poly coeffs */
uint32_t magic; /* magic ID: 0xf19ede1a */ int32_t out_zero_offset[4]; /* Output zero offset, fixed point */
uint32_t zero_offset[4]; /* Output zero offset, fixed point */ int32_t tdc_zero_offset; /* Zero offset of the TDC, in ps */
uint32_t adsfr_val; /* ADSFR register value */ uint32_t vcxo_default_tune;
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;
}; };
struct fd_calib_on_eeprom { struct fd_calib_on_eeprom {
uint32_t magic; /* magic ID: 0xf19ede1a */
uint32_t hash; uint32_t hash;
uint16_t size; uint16_t size;
uint16_t version; uint16_t version;
uint32_t date;
struct fd_calib calib; struct fd_calib calib;
}; };
...@@ -102,7 +103,6 @@ struct fine_delay_hw ...@@ -102,7 +103,6 @@ struct fine_delay_hw
int raw_mode; int raw_mode;
int do_long_tests; int do_long_tests;
struct fd_calib calib; struct fd_calib calib;
int64_t input_user_offset, output_user_offset;
}; };
/* some useful access/declaration macros */ /* 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; ...@@ -41,6 +41,52 @@ uint32_t wait_promptTimeout;
/* WR core shell communication functions */ /* 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) static void shell_purge(fdelay_device_t *dev)
{ {
char c='\r'; char c='\r';
...@@ -56,68 +102,26 @@ static void shell_purge(fdelay_device_t *dev) ...@@ -56,68 +102,26 @@ static void shell_purge(fdelay_device_t *dev)
} }
} }
/* executes a shell command on the associated WR core */ /* 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 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, (char *)cmd, strlen(cmd));
spec_vuart_tx(dev->priv_io, "\r", 1); spec_vuart_tx(dev->priv_io, "\r", 1);
int64_t start_tics = get_tics(); wait_prompt(dev, retval);
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;
if(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); dbg("wr_core exec '%s', retval: '%s'\n", cmd, retval);
}
return 0; return 0;
} }
#define DMTD_N_AVGS 100 /* number of average samples */
#define DMTD_N_AVGS 10 /* number of average samples */ #define DELAY_SETPOINT 750000 /* test delay value */
#define DELAY_SETPOINT 500000 /* test delay value */
#define DMTD_PULSE_PERIOD 144 #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 */ #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 ...@@ -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); 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)*/ /* 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 /* Disable ALL outputs to prevent the calibration pulses from driving whatever
is connected to the board */ is connected to the board */
...@@ -213,7 +218,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s ...@@ -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 */ /* Get DMTD_N_AVGS samples to reduce error */
n_in = n_out = 0; n_in = n_out = 0;
int64_t ts = get_tics(); 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)) if(read_dmtd(dev, &ch_in, 0))
{ {
...@@ -227,7 +232,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s ...@@ -227,7 +232,7 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s
samples_out[n_out++] = ch_out.phase; samples_out[n_out++] = ch_out.phase;
} }
} }
if((get_tics()-ts) >= 1000000) if((get_tics()-ts) >= 10000000)
{ {
dbg("%s has timed out\n", __FUNCTION__); dbg("%s has timed out\n", __FUNCTION__);
return -1; return -1;
...@@ -255,11 +260,12 @@ int calibrate_channel(fdelay_device_t *dev, int channel, double *mean, double *s ...@@ -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; *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 */ /* Reset to normal trigger and disable input and output */
if(sgpio_set_pin(dev, SGPIO_TRIG_SEL, 1) < 0) if(sgpio_set_pin(dev, SGPIO_TRIG_SEL, 1) < 0)
return -1; return -1;
fdelay_configure_trigger(dev, 0, 0); fdelay_configure_trigger(dev, 0, 0);
fdelay_configure_output(dev, channel, 0, (int64_t)DELAY_SETPOINT, 200000LL, 0LL, 1);
return 0; return 0;
} }
...@@ -270,7 +276,8 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t ...@@ -270,7 +276,8 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
char c; char c;
int i, error = 0; int i, error = 0;
fd_decl_private(dev); fd_decl_private(dev);
wait_promptTimeout = *userTimeout;
int64_t base = 0, prev_tag = -1; int64_t base = 0, prev_tag = -1;
if(spec_load_lm32(dev->priv_io, filename, 0xc0000)) 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 ...@@ -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: */ /* Configure the WR core to produce a proper calibration clock: */
/* Disable PTP and enter free-running master mode */ /* 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; return -1;
if(wrc_shell_exec(dev, "mode master", resp, 5000000LL) < 0) if(wrc_shell_exec(dev, "mode master", resp) < 0)
return -1; 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 /* 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 */ 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; 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; return -1;
/* Wait until the PLL locks... */ /* Wait until the PLL locks... */
int64_t ts = get_tics(); int64_t ts = get_tics();
while(1) 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; return -1;
if(!strcmp(resp, "1")) if(!strcmp(resp, "1"))
break; break;
...@@ -318,17 +325,17 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t ...@@ -318,17 +325,17 @@ int fdelay_dmtd_calibration(fdelay_device_t *dev, const char *filename, uint32_t
for(i=1;i<=4;i++) 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) 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); dbg("Failed, DDMTD calibration failure for channel %d, DMTD Tag Ready flag is not coming high\n", i);
hw->calib.zero_offset[i-1] = 0; hw->calib.out_zero_offset[i-1] = 0;
error = 1; error = 1;
} }
else else
{ {
dbg("Channel %d: delay %.0f ps, std %.0f ps.\n", i, mean_out[i-1], std_out[i-1]); 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; 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_ ...@@ -151,6 +151,7 @@ int eeprom_write(fdelay_device_t *dev, uint8_t i2c_addr, uint32_t offset, uint8_
int i, busy; int i, busy;
for(i=0;i<size;i++) for(i=0;i<size;i++)
{ {
mi2c_start(dev); mi2c_start(dev);
if(mi2c_put_byte(dev, i2c_addr << 1) < 0) if(mi2c_put_byte(dev, i2c_addr << 1) < 0)
......
No preview for this file type
...@@ -28,6 +28,7 @@ struct spec_private { ...@@ -28,6 +28,7 @@ struct spec_private {
uint32_t vuart_base; 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. /* 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 */ If no cards have been detected, returns -1 */
static int spec_scan(int *bus, int *devfn) static int spec_scan(int *bus, int *devfn)
...@@ -119,12 +120,15 @@ void spec_close(void *card) ...@@ -119,12 +120,15 @@ void spec_close(void *card)
void spec_writel(void *card, uint32_t data, uint32_t addr) 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; struct spec_private *p = (struct spec_private *) card;
*(volatile uint32_t *) (p->bar0 + addr) = data; *(volatile uint32_t *) (p->bar0 + addr) = data;
} }
uint32_t spec_readl(void *card, uint32_t addr) uint32_t spec_readl(void *card, uint32_t addr)
{ {
// printf("Readl %x\n", addr);
struct spec_private *p = (struct spec_private *) card; struct spec_private *p = (struct spec_private *) card;
return *(volatile uint32_t *) (p->bar0 + addr); return *(volatile uint32_t *) (p->bar0 + addr);
} }
...@@ -199,6 +203,7 @@ int spec_load_bitstream(void *card, const char *filename) ...@@ -199,6 +203,7 @@ int spec_load_bitstream(void *card, const char *filename)
char *buf; char *buf;
size_t size; size_t size;
// printf("load-bitstream: %s\n", filename);
buf = load_binary_file(filename, &size); buf = load_binary_file(filename, &size);
if(!buf) if(!buf)
return -1; return -1;
......
/* /*
Register definitions for slave core: Simple Wishbone UART Register definitions for slave core: Simple Wishbone UART
* File : wb_uart.h * File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb * 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 * Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
...@@ -89,4 +90,5 @@ ...@@ -89,4 +90,5 @@
#define UART_REG_HOST_TDR 0x10 #define UART_REG_HOST_TDR 0x10
#define UART_REG_HOST_RDR 0x14 #define UART_REG_HOST_RDR 0x14
#endif #endif
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "spec/tools/speclib.h" #include "spec/tools/speclib.h"
#include "fdelay_lib.h" #include "fdelay_lib.h"
void printk(){}
static void fd_spec_writel(void *priv, uint32_t data, uint32_t addr) static void fd_spec_writel(void *priv, uint32_t data, uint32_t addr)
{ {
spec_writel(priv, data, 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): ...@@ -11,7 +11,13 @@ class fd_timestamp(Structure):
("coarse", c_ulong), ("coarse", c_ulong),
("frac", c_ulong), ("frac", c_ulong),
("seq_id", c_ushort), ("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): def nsecs(self):
return (float(self.frac) * 8000.0 / 4096.0 + float(self.coarse) * 8000.0) / 1000.0; return (float(self.frac) * 8000.0 / 4096.0 + float(self.coarse) * 8000.0) / 1000.0;
...@@ -25,6 +31,7 @@ class fd_timestamp(Structure): ...@@ -25,6 +31,7 @@ class fd_timestamp(Structure):
class FineDelay: class FineDelay:
BASE_ADDR = 0x80000 #0x84000 for zWR BASE_ADDR = 0x80000 #0x84000 for zWR
INIT_RAW_READOUT = 1
def __init__(self, mode, bus = -1): def __init__(self, mode, bus = -1):
# check if root # check if root
...@@ -80,6 +87,10 @@ class FineDelay: ...@@ -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)) 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): def conf_trigger(self, enable, termination):
self.fdelay.fdelay_configure_trigger(self.handle, c_int(enable), c_int(termination)) self.fdelay.fdelay_configure_trigger(self.handle, c_int(enable), c_int(termination))
...@@ -94,7 +105,7 @@ class FineDelay: ...@@ -94,7 +105,7 @@ class FineDelay:
def conf_pulsegen(self, channel, enable, t_start_utc, t_start_coarse, width, delta, count): 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)) 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, self.fdelay.fdelay_configure_pulse_gen(self.handle, c_int(channel), c_int(enable), t,
c_ulonglong(width), c_ulonglong(delta), c_int(count)) c_ulonglong(width), c_ulonglong(delta), c_int(count))
...@@ -106,6 +117,7 @@ class FineDelay: ...@@ -106,6 +117,7 @@ class FineDelay:
t = fd_timestamp() t = fd_timestamp()
self.fdelay.fdelay_get_time(self.handle, byref(t)) self.fdelay.fdelay_get_time(self.handle, byref(t))
self.return_value = t self.return_value = t
return t
def get_sync_status(self): def get_sync_status(self):
# fixme: new WR state machine # fixme: new WR state machine
...@@ -115,6 +127,7 @@ class FineDelay: ...@@ -115,6 +127,7 @@ class FineDelay:
buf = (fd_timestamp * 256)(); buf = (fd_timestamp * 256)();
ptr = pointer(buf) ptr = pointer(buf)
n = self.fdelay.fdelay_read(self.handle, ptr, 256) n = self.fdelay.fdelay_read(self.handle, ptr, 256)
# print("n %d" % n)
arr = []; arr = [];
for i in range(0,n): for i in range(0,n):
arr.append(buf[i]) arr.append(buf[i])
......
...@@ -39,7 +39,7 @@ class c_BoardInfoArea(Structure): ...@@ -39,7 +39,7 @@ class c_BoardInfoArea(Structure):
("fru_fid_data", c_char_p), ("fru_fid_data", c_char_p),
("typelen_end", c_ubyte), ("typelen_end", c_ubyte),
("pad_len", c_ubyte), ("pad_len", c_ubyte),
("checksum", c_ubyte), ("checksum", c_ubyte)
] ]
class c_DCLoadRecord(Structure): class c_DCLoadRecord(Structure):
...@@ -50,7 +50,7 @@ class c_DCLoadRecord(Structure): ...@@ -50,7 +50,7 @@ class c_DCLoadRecord(Structure):
("max_voltage", c_ushort), ("max_voltage", c_ushort),
("spec_ripple", c_ushort), ("spec_ripple", c_ushort),
("min_current", c_ushort), ("min_current", c_ushort),
("max_current", c_ushort), ("max_current", c_ushort)
] ]
class c_DCOutputRecord(Structure): class c_DCOutputRecord(Structure):
...@@ -61,14 +61,14 @@ class c_DCOutputRecord(Structure): ...@@ -61,14 +61,14 @@ class c_DCOutputRecord(Structure):
("max_pos_voltage_dev", c_ushort), ("max_pos_voltage_dev", c_ushort),
("ripple", c_ushort), ("ripple", c_ushort),
("min_current_draw", c_ushort), ("min_current_draw", c_ushort),
("max_current_draw", c_ushort), ("max_current_draw", c_ushort)
] ]
class c_InternalUseArea(Structure): class c_InternalUseArea(Structure):
_fields_ = [ _fields_ = [
("format", c_ubyte), ("format", c_ubyte),
("len", c_int), ("len", c_int),
("data", c_char_p), ("data", c_char_p)
] ]
class InternalUseArea: class InternalUseArea:
...@@ -105,8 +105,8 @@ class BoardInfoArea: ...@@ -105,8 +105,8 @@ class BoardInfoArea:
self.struct = c_BoardInfoArea() self.struct = c_BoardInfoArea()
self._as_parameter_ = byref(self.struct) self._as_parameter_ = byref(self.struct)
self.struct.format = 0x1 self.struct.format = 0x1
self.struct.area_len = 0 # English self.struct.area_len = 0
self.struct.language = 0 self.struct.language = 0 # English
self.set_manufacture_date(date) self.set_manufacture_date(date)
self.set_manufacturer(mfgr) self.set_manufacturer(mfgr)
self.set_product_name(product) self.set_product_name(product)
...@@ -122,23 +122,23 @@ class BoardInfoArea: ...@@ -122,23 +122,23 @@ class BoardInfoArea:
def set_manufacturer(self, data): def set_manufacturer(self, data):
self.struct.mfgr_data = c_char_p(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): def set_product_name(self, data):
self.struct.product_data = c_char_p(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): def set_serial_number(self, data):
self.struct.serial_data = c_char_p(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): def set_part_number(self, data):
self.struct.partnum_data = c_char_p(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): def set_fru_file_id(self, data):
self.struct.fru_fid_data = c_char_p(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: class DCLoadRecord:
...@@ -229,9 +229,8 @@ class c_FMCOEMData(Structure): ...@@ -229,9 +229,8 @@ class c_FMCOEMData(Structure):
("p1_b_nsig", c_ubyte), ("p1_b_nsig", c_ubyte),
("p2_a_nsig", c_ubyte), ("p2_a_nsig", c_ubyte),
("p2_b_nsig", c_ubyte), ("p2_b_nsig", c_ubyte),
("p1_gbt_ntran", c_ubyte), ("p1_p2_gbt_ntran", c_ubyte),
("p2_gbt_ntran", c_ubyte), ("max_clock", c_ubyte)
("max_clock", c_ubyte),
] ]
class c_OEMRecord(Structure): class c_OEMRecord(Structure):
...@@ -239,7 +238,7 @@ class c_OEMRecord(Structure): ...@@ -239,7 +238,7 @@ class c_OEMRecord(Structure):
("mfg_id0", c_ubyte), ("mfg_id0", c_ubyte),
("mfg_id1", c_ubyte), ("mfg_id1", c_ubyte),
("mfg_id2", c_ubyte), ("mfg_id2", c_ubyte),
("data", c_FMCOEMData), ("data", c_FMCOEMData)
] ]
...@@ -269,19 +268,20 @@ class OEMRecord: ...@@ -269,19 +268,20 @@ class OEMRecord:
self.set_max_clock(maxclk) self.set_max_clock(maxclk)
def set_module_size(self, val): def set_module_size(self, val):
self.struct.data.other &= ~(0x3) self.struct.data.other &= ~(0xc0)
self.struct.data.other |= val & 0x3 self.struct.data.other |= (val << 6) & 0xc0
def set_p1_connector_size(self, val): 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 &= ~(0x30)
self.struct.data.other |= (val << 4) & 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): 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): def set_nsignals(self, port, bank, num):
if (port == 1): if (port == 1):
...@@ -297,9 +297,11 @@ class OEMRecord: ...@@ -297,9 +297,11 @@ class OEMRecord:
def set_num_gbt_transceivers(self, port, num): def set_num_gbt_transceivers(self, port, num):
if (port == 1): 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): 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): def set_max_clock(self, clock):
self.struct.data.max_clock = clock self.struct.data.max_clock = clock
...@@ -311,13 +313,14 @@ def ipmi_open_file(name): ...@@ -311,13 +313,14 @@ def ipmi_open_file(name):
def ipmi_close_file(): def ipmi_close_file():
lib.ipmi_file_close() 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) lib.ipmi_set_board_info_area(bia)
for r in dcload: for r in dcload:
lib.ipmi_add_dc_load_record(r) lib.ipmi_add_dc_load_record(r)
for r in dcout: for r in dcout:
lib.ipmi_add_dc_output_record(r) lib.ipmi_add_dc_output_record(r)
lib.ipmi_set_oem_record(oem) lib.ipmi_set_oem_record(oem)
if iua != None:
lib.ipmi_set_internal_use_area(iua) lib.ipmi_set_internal_use_area(iua)
def ipmi_write(): def ipmi_write():
...@@ -331,3 +334,44 @@ def ipmi_get_internal_use_data(data): ...@@ -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))) d = c_void_p(lib.ipmi_get_internal_use_data(c_char_p(data), byref(l)))
q = cast(d, POINTER(l.value*c_ubyte)) q = cast(d, POINTER(l.value*c_ubyte))
return q.contents 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) ...@@ -43,11 +43,11 @@ uint8_t checksum(uint8_t *data, int len)
int board_info_area_get_size(uint8_t *pad) int board_info_area_get_size(uint8_t *pad)
{ {
int size = 13 + int size = 13 +
(bia->mfgr_typelen & 0x1f) + (bia->mfgr_typelen & 0x3f) +
(bia->product_typelen & 0x1f) + (bia->product_typelen & 0x3f) +
(bia->serial_typelen & 0x1f) + (bia->serial_typelen & 0x3f) +
(bia->partnum_typelen & 0x1f) + (bia->partnum_typelen & 0x3f) +
(bia->fru_fid_typelen & 0x1f); (bia->fru_fid_typelen & 0x3f);
if (size & 0x7) { if (size & 0x7) {
if (pad) { if (pad) {
*pad = 8 - (size & 0x7); *pad = 8 - (size & 0x7);
...@@ -126,26 +126,29 @@ int ipmi_board_info_area_write(void) ...@@ -126,26 +126,29 @@ int ipmi_board_info_area_write(void)
/* Write upto the mfgr_data */ /* Write upto the mfgr_data */
ret = fwrite(bia, 6, 1, f); 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_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->mfgr_data, len, 1, 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_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->product_data, len, 1, 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_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->serial_data, len, 1, f); ret = fwrite(bia->serial_data, len, 1, f);
len = bia->partnum_typelen & 0x1f; len = bia->partnum_typelen & 0x3f;
ret = fwrite(&bia->product_typelen, 1, sizeof(uint8_t), f); ret = fwrite(&bia->partnum_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->partnum_data, len, 1, 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_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->fru_fid_data, len, 1, 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 */ /* calculate checksum here */
checksum = 0; checksum = 0;
checksum += checksum +=
...@@ -162,23 +165,25 @@ int ipmi_board_info_area_write(void) ...@@ -162,23 +165,25 @@ int ipmi_board_info_area_write(void)
bia->fru_fid_typelen + bia->fru_fid_typelen +
bia->typelen_end; 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]; 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]; 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]; 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]; 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 += bia->fru_fid_data[i];
checksum = -checksum; checksum = -checksum;
checksum &= 0xff; checksum &= 0xff;
bia->checksum = checksum; bia->checksum = checksum;
bia->typelen_end = 0xc1;
ret = fwrite(&bia->typelen_end, 1, sizeof(uint8_t), f);
uint8_t nul = 0; uint8_t nul = 0;
board_info_area_get_size(&pad); board_info_area_get_size(&pad);
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
...@@ -203,14 +208,15 @@ int ipmi_dc_load_record_write(int end) ...@@ -203,14 +208,15 @@ int ipmi_dc_load_record_write(int end)
head.extra = 0x2; head.extra = 0x2;
if (end) if (end)
head.extra |= (1 << 7); head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_load_record); head.record_len = 13;
head.record_checksum = checksum((uint8_t *)t->rec, head.record_checksum = checksum((uint8_t *)t->rec,
sizeof(struct dc_load_record)); sizeof(struct dc_load_record));
head.header_checksum = checksum((uint8_t *)&head, head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1); sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f); 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; t = t->next;
} }
...@@ -232,14 +238,15 @@ int ipmi_dc_output_record_write(int end) ...@@ -232,14 +238,15 @@ int ipmi_dc_output_record_write(int end)
head.extra = 0x2; head.extra = 0x2;
if (end) if (end)
head.extra |= (1 << 7); head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_output_record); head.record_len = 13;
head.record_checksum = checksum((uint8_t *)t->rec, head.record_checksum = checksum((uint8_t *)t->rec,
sizeof(struct dc_output_record)); sizeof(struct dc_output_record));
head.header_checksum = checksum((uint8_t *)&head, head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1); sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f); 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; t = t->next;
} }
...@@ -254,10 +261,10 @@ int ipmi_oem_record_write(int end) ...@@ -254,10 +261,10 @@ int ipmi_oem_record_write(int end)
if (!oem || !f) if (!oem || !f)
return -1; return -1;
/* VITA ID: 0x0012a2 */ /* VITA ID: 0x0012a2 (LS Byte first) */
oem->mfg_id0 = 0x00; oem->mfg_id0 = 0xa2;
oem->mfg_id1 = 0x12; oem->mfg_id1 = 0x12;
oem->mfg_id2 = 0xa2; oem->mfg_id2 = 0x00;
head.record_typeid = 0xfa; /* OEM record type */ head.record_typeid = 0xfa; /* OEM record type */
head.extra = 0x2; head.extra = 0x2;
...@@ -282,12 +289,12 @@ int multirecord_area_get_size(int *diff) ...@@ -282,12 +289,12 @@ int multirecord_area_get_size(int *diff)
int sum = 0; int sum = 0;
while (l1) { while (l1) {
sum += sizeof(struct multirecord_header); sum += sizeof(struct multirecord_header);
sum += sizeof(struct dc_load_record); sum += 13;
l1 = l1->next; l1 = l1->next;
} }
while (l2) { while (l2) {
sum += sizeof(struct multirecord_header); sum += sizeof(struct multirecord_header);
sum += sizeof(struct dc_output_record); sum += 13;
l2 = l2->next; l2 = l2->next;
} }
sum += sizeof(struct multirecord_header) + sizeof(struct oem_record); sum += sizeof(struct multirecord_header) + sizeof(struct oem_record);
...@@ -308,22 +315,58 @@ int ipmi_write(void) ...@@ -308,22 +315,58 @@ int ipmi_write(void)
ch = malloc(sizeof(struct common_header)); ch = malloc(sizeof(struct common_header));
memset(ch, 0, 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; 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; 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(); 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(); ipmi_board_info_area_write();
// Write multi-record area
ipmi_dc_load_record_write(0); ipmi_dc_load_record_write(0);
ipmi_dc_output_record_write(0); ipmi_dc_output_record_write(0);
ipmi_oem_record_write(1); ipmi_oem_record_write(1);
// Padding after multi-record area
multirecord_area_get_size(&padlen); multirecord_area_get_size(&padlen);
if (padlen) { if (padlen) {
int i; int i;
for (i = 0; i < padlen; i++) for (i = 0; i < padlen; i++)
fwrite(&pad, 1, 1, f); fwrite(&pad, 1, 1, f);
} }
// Write Internal Use area, if exists
if (iua)
ipmi_internal_use_area_write(); ipmi_internal_use_area_write();
return 0; return 0;
......
...@@ -94,8 +94,7 @@ struct fmc_oem_data { ...@@ -94,8 +94,7 @@ struct fmc_oem_data {
uint8_t p1_b_nsig; uint8_t p1_b_nsig;
uint8_t p2_a_nsig; uint8_t p2_a_nsig;
uint8_t p2_b_nsig; uint8_t p2_b_nsig;
uint8_t p1_gbt_ntran; uint8_t p1_p2_gbt_ntran;
uint8_t p2_gbt_ntran;
uint8_t max_clock; 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 ...@@ -15,13 +15,14 @@ TEST_SENSOR, TEST_ACAM_IF, TEST_DELAY_LINE
""" """
def main (card=None, default_directory='.',suite=None): def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file # redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory) new_stderr = redirect_stderr(default_directory)
# initialize card with long tests # initialize card with long tests
card = init_card(new_stderr, default_directory, 2) card = init_card(new_stderr, default_directory, 2)
print("Dir %s" %default_directory)
# restore stderr and display debug information from file # restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory) restore_stderr(new_stderr, default_directory)
......
...@@ -105,7 +105,7 @@ def main (card=None, default_directory='.',suite=None): ...@@ -105,7 +105,7 @@ def main (card=None, default_directory='.',suite=None):
if(error[0] != 0): if(error[0] != 0):
print("One or both LEDs not switching ON. Check for soldering or connection problem, grounded control line") print("One or both LEDs not switching ON. Check for soldering or connection problem, grounded control line")
if(error[1] != 0): 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.') raise PtsError('An error occurred during LEDs test, check log for details.')
else: else:
print('LEDs are working ok.') print('LEDs are working ok.')
......
...@@ -6,35 +6,230 @@ ...@@ -6,35 +6,230 @@
# Licence: GPL v2 or later. # Licence: GPL v2 or later.
# Website: http://www.ohwr.org # Website: http://www.ohwr.org
import sys
import time
import string
import datetime
from ptsexcept import * from ptsexcept import *
from utilFunctions 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): def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file # redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory) new_stderr = redirect_stderr(default_directory)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py # initialize card without long tests
if (card == None):
card = init_card(new_stderr, default_directory, 0) card = init_card(new_stderr, default_directory, 0)
############################################################################ ############################################################################
# run DMTD calibration procedure # objects declaration
card.fdelay_dmtd_calibration(); 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) 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): # restart CNT-91
raise PtsCritical ('An error occurred during the DMTD calibration, check log for details') 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 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__' : if __name__ == '__main__' :
main() main()
#! /usr/bin/env python #! /usr/bin/env python
# coding: utf8 # coding: utf8
# Copyright INCAA Computers, 2012 # Copyright CERN 2013
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com> # Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
# Licence: GPL v2 or later. # Licence: GPL v2 or later.
# Website: http://www.ohwr.org # Website: http://www.ohwr.org
from ptsexcept import * from ptsexcept import *
from utilFunctions import * from utilFunctions import *
from PendulumCNT91 import *
import sys 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): def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file # redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory) new_stderr = redirect_stderr(default_directory)
# initialize card if running standalone (no long tests), use initialization test00 if run from pts.py red = redirect(0)
if (card == None):
# initialize card without long tests
card = init_card(new_stderr, default_directory, 0) card = init_card(new_stderr, default_directory, 0)
############################################################################ ############################################################################
# run testing EEPROM writing and reading (perform DMTD calibration if not run from PTS) # objects declaration
if(card.dmtd == 0): try:
# run DMTD calibration procedure meas = PendulumCNT91(PENDULUM)
card.fdelay_dmtd_calibration(); 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 # configure trigger (enable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.write_calibration_eeprom() 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 and display debug information from file
restore_stderr(new_stderr, default_directory) 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 return card
......
#! /usr/bin/env python #! /usr/bin/env python
# coding: utf8 # coding: utf8
# Copyright INCAA Computers, 2012 # Copyright CERN 2013
# Author: Bert Gooijer <bert.gooijer@incaacomputers.com> # Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
# Licence: GPL v2 or later. # Licence: GPL v2 or later.
# Website: http://www.ohwr.org # Website: http://www.ohwr.org
import sys
from ptsexcept import * from ptsexcept import *
from utilFunctions import * from utilFunctions import *
from PAGE.Agilent33250A import *
from PAGE.PulseWaveform import *
from PendulumCNT91 import *
import sys
import numpy
import time import time
import string 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" def gather_timestamps(card, count):
RS232_BAUD = 57600 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): def main (card=None, default_directory='.',suite=None):
# redirect stderr (all debug output) to file # redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory) new_stderr = redirect_stderr(default_directory)
# initialize card without long tests red = redirect(0)
card = init_card(new_stderr, default_directory, 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) sys.path.append(os.path.join(default_directory, 'usb_box'))
pulse = PulseWaveform() sys.path.append(os.path.join(default_directory, 'cp210x'))
# connect to AWG and test if available import calibr_box
idn = gen.connect() import find_usb_tty
if (len(idn) == 0):
restore_stderr(new_stderr, default_directory)
raise PtsError('AWG is not switched on or badly connected, aborting.')
else:
print idn
# initialize variables BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
error = [0, 0, 0, 0, 0, 0, 0, 0] BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
result = [0.0, 0.0, 0.0, 0.0] box_tty = find_usb_tty.CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
red = redirect(0) # print("Calibration Box device: %s" % box_tty[0])
box = calibr_box.CCalibr_box(box_tty[0])
# set pulse parameters box.select_trigger_loopback(1)
pulse.frequency = 500 box.select_output(1)
pulse.amplitude = 2.5
pulse.dc = 1.4 # 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)) # 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) card.conf_trigger(1, 1)
# set AWG and turn it ON ts = gather_timestamps(card, 10)
gen.play(pulse) tdc_start_offset = ts[0].raw_subcycle_offset;
gen.command("PULS:WIDT 0.0000005")
gen.command("PULS:TRAN 0.000000005") # print("StartOffs : %d" % tdc_start_offset)
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()
# disable trigger (disable, termination (0 = 2 kOhm, 1 = 50 Ohm)) # disable trigger (disable, termination (0 = 2 kOhm, 1 = 50 Ohm))
card.conf_trigger(0, 0) 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 # standard in/out redirection
redirect.InOut(red) # redirect.InOut(red)
# restore stderr and display debug information from file # restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory) 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__' : if __name__ == '__main__' :
main() main()
...@@ -13,7 +13,7 @@ from fmc_eeprom import * ...@@ -13,7 +13,7 @@ from fmc_eeprom import *
import sys, time 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): def main (card=None, serial=None, default_directory='.', suite=None):
...@@ -21,10 +21,6 @@ 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 # redirect stderr (all debug output) to file
new_stderr = redirect_stderr(default_directory) 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 # standard in/out temporary redirection for user question/answer
red = redirect(0) red = redirect(0)
redirect.InOut(red) redirect.InOut(red)
...@@ -42,7 +38,7 @@ def main (card=None, serial=None, default_directory='.', suite=None): ...@@ -42,7 +38,7 @@ def main (card=None, serial=None, default_directory='.', suite=None):
else: else:
serial_no = serial 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) 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) 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): ...@@ -55,12 +51,11 @@ def main (card=None, serial=None, default_directory='.', suite=None):
iua = InternalUseArea([]) iua = InternalUseArea([])
# Open, set, write, close! # 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_set(bia, dcload, dcout, oem, iua)
ipmi_write() ipmi_write()
ipmi_close_file() ipmi_close_file()
card.write_eeprom_from_file("ipmi_eeprom.bin", 0);
############################################################################ ############################################################################
# standard in/out redirection # standard in/out redirection
...@@ -69,11 +64,6 @@ def main (card=None, serial=None, default_directory='.', suite=None): ...@@ -69,11 +64,6 @@ def main (card=None, serial=None, default_directory='.', suite=None):
# restore stderr and display debug information from file # restore stderr and display debug information from file
restore_stderr(new_stderr, default_directory) 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 return card
if __name__ == '__main__' : 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 * ...@@ -9,6 +9,10 @@ from PendulumCNT91 import *
import sys import sys
import os import os
import struct
import jhash
""" """
functions for getting debug information from c library functions for getting debug information from c library
...@@ -101,8 +105,8 @@ def pendulum_init(meas): ...@@ -101,8 +105,8 @@ def pendulum_init(meas):
meas.write("MEAS:TINT?") meas.write("MEAS:TINT?")
# DC coupling # DC coupling
#meas.write("INP:COUP DC") meas.write("INP:COUP DC")
#meas.write("INP2:COUP DC") meas.write("INP2:COUP DC")
# Set impedance # Set impedance
meas.write("INP:IMP 1E6") meas.write("INP:IMP 1E6")
...@@ -113,7 +117,7 @@ def pendulum_init(meas): ...@@ -113,7 +117,7 @@ def pendulum_init(meas):
meas.write("INP2:LEV:AUTO OFF") meas.write("INP2:LEV:AUTO OFF")
# Set trigger level # Set trigger level
meas.write("INP:LEV 1.4") meas.write("INP:LEV 1.5")
meas.write("INP2:LEV 1.5") meas.write("INP2:LEV 1.5")
# Enable statistics # Enable statistics
...@@ -137,3 +141,66 @@ def pendulum_reset(meas): ...@@ -137,3 +141,66 @@ def pendulum_reset(meas):
# Make 500 measurements # Make 500 measurements
meas.write("CALC:AVER:COUN 500") 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" 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